{"model_name":"gpt-5.1-codex-max-xhigh","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nint n;\nvector<int> x, y;\nvector<long long> r;\nvector<Rect> rects;\n\ninline long long area(const Rect &rc) {\n    return 1LL * (rc.c - rc.a) * (rc.d - rc.b);\n}\n\ninline double compute_p_val(long long ri, long long s) {\n    double ratio = (ri < s) ? (double)ri / (double)s : (double)s / (double)ri;\n    double diff = 1.0 - ratio;\n    return 1.0 - diff * diff;\n}\n\n// Compute maximum expansion lengths in four directions for rectangle i\nvoid compute_max_expands(int i, int &left, int &right, int &up, int &down) {\n    const Rect &ri = rects[i];\n    left = ri.a;\n    right = 10000 - ri.c;\n    up = ri.b;\n    down = 10000 - ri.d;\n    for (int j = 0; j < n; j++) if (j != i) {\n        const Rect &rj = rects[j];\n        // vertical overlap (strict)\n        if (rj.b < ri.d && rj.d > ri.b) {\n            if (rj.c <= ri.a) {\n                int cand = ri.a - rj.c;\n                if (cand < left) left = cand;\n            }\n            if (rj.a >= ri.c) {\n                int cand = rj.a - ri.c;\n                if (cand < right) right = cand;\n            }\n        }\n        // horizontal overlap (strict)\n        if (rj.a < ri.c && rj.c > ri.a) {\n            if (rj.d <= ri.b) {\n                int cand = ri.b - rj.d;\n                if (cand < up) up = cand;\n            }\n            if (rj.b >= ri.d) {\n                int cand = rj.b - ri.d;\n                if (cand < down) down = cand;\n            }\n        }\n    }\n}\n\nstruct Move {\n    double diff;\n    int dir;\n    int len;\n};\n\nMove find_best_expand(int i) {\n    Move best{0.0, -1, 0};\n    const Rect &rc = rects[i];\n    long long s = area(rc);\n    long long ri_target = r[i];\n    if (s >= ri_target) return best;\n\n    int left, right, up, down;\n    compute_max_expands(i, left, right, up, down);\n    int maxLens[4] = {left, right, up, down};\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(ri_target, s);\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(ri_target - s) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(ri_target, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\nMove find_best_contract(int i) {\n    Move best{0.0, -1, 0};\n    const Rect &rc = rects[i];\n    long long s = area(rc);\n    long long ri_target = r[i];\n    if (s <= ri_target) return best;\n\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int maxLens[4] = {\n        rc.a - x[i],                // shrink left\n        rc.c - (x[i] + 1),          // shrink right\n        rc.b - y[i],                // shrink up\n        rc.d - (y[i] + 1)           // shrink down\n    };\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(ri_target, s);\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(s - ri_target) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(ri_target, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\ninline void apply_move(int i, const Move &mv, bool expand) {\n    if (mv.dir < 0 || mv.len <= 0) return;\n    Rect &rc = rects[i];\n    int l = mv.len;\n    if (expand) {\n        if (mv.dir == 0) rc.a -= l;\n        else if (mv.dir == 1) rc.c += l;\n        else if (mv.dir == 2) rc.b -= l;\n        else rc.d += l;\n    } else {\n        if (mv.dir == 0) rc.a += l;\n        else if (mv.dir == 1) rc.c -= l;\n        else if (mv.dir == 2) rc.b += l;\n        else rc.d -= l;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> n)) return 0;\n    x.resize(n);\n    y.resize(n);\n    r.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        int xi, yi;\n        long long ri;\n        cin >> xi >> yi >> ri;\n        x[i] = xi;\n        y[i] = yi;\n        r[i] = ri;\n        rects[i] = {xi, yi, xi + 1, yi + 1};\n    }\n\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return r[a] < r[b];\n    });\n\n    auto start_time = chrono::steady_clock::now();\n\n    // Initial greedy expansion for small rectangles first\n    for (int idx = 0; idx < n; idx++) {\n        int i = order[idx];\n        for (int iter = 0; iter < 1000; iter++) {\n            Move mv = find_best_expand(i);\n            if (mv.diff <= 1e-12) break;\n            apply_move(i, mv, true);\n        }\n    }\n\n    const double TIME_LIMIT = 4.9; // seconds\n    mt19937 rng(1234567);\n    uniform_int_distribution<int> dist(0, n - 1);\n    int iter = 0;\n    while (true) {\n        if ((iter & 0x3FF) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        int i = dist(rng);\n        long long s = area(rects[i]);\n        if (s < r[i]) {\n            Move mv = find_best_expand(i);\n            if (mv.diff > 1e-12) apply_move(i, mv, true);\n        } else if (s > r[i]) {\n            Move mv = find_best_contract(i);\n            if (mv.diff > 1e-12) apply_move(i, mv, false);\n        }\n        iter++;\n    }\n\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << ' ' << rects[i].b << ' ' << rects[i].c << ' ' << rects[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 50;\nconst int W = 50;\nconst int N = H * W;\n\nint Tcell[N];\nint Pcell[N];\n\nint nbCnt[N];\nint nbIdx[N][4];\nchar nbDir[N][4];\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nint startIdx;\nint tileCount;\n\nvector<int> visitedTile;\nint currentToken = 1;\n\nstruct XorShift {\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ULL) { x = seed; }\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int n) { return (int)(next() % n); }\n};\nXorShift rng;\n\nenum Mode { MIN_DEG = 0, MAX_DEG = 1, MAX_VALUE = 2 };\n\nstruct Param {\n    int avoidLevel; // -1 for no avoid, otherwise avoid deg<=avoidLevel if possible\n    Mode mode;\n    int randProb; // 0..1023\n};\n\nstruct Path {\n    string moves;\n    int score;\n    int len;\n};\n\ninline int compute_deg(int idx, int candTile) {\n    int deg = 0;\n    for (int k = 0; k < nbCnt[idx]; k++) {\n        int nb = nbIdx[idx][k];\n        int tid = Tcell[nb];\n        if (tid == candTile) continue;\n        if (visitedTile[tid] == currentToken) continue;\n        deg++;\n    }\n    return deg;\n}\n\nPath run_once(const Param &param) {\n    currentToken++;\n    if (currentToken == 0x3f3f3f3f) { // very unlikely; reset tokens to avoid overflow\n        currentToken = 1;\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n    }\n    visitedTile[Tcell[startIdx]] = currentToken;\n    int cur = startIdx;\n    int score = Pcell[cur];\n    vector<char> mv;\n    mv.reserve(tileCount);\n    while (true) {\n        int candIdxArr[4];\n        char candDirArr[4];\n        int cnum = 0;\n        for (int k = 0; k < nbCnt[cur]; k++) {\n            int nb = nbIdx[cur][k];\n            if (visitedTile[Tcell[nb]] == currentToken) continue;\n            candIdxArr[cnum] = nb;\n            candDirArr[cnum] = nbDir[cur][k];\n            cnum++;\n        }\n        if (cnum == 0) break;\n        int chosen = -1;\n        if (param.randProb > 0 && (int)(rng.next() & 1023) < param.randProb) {\n            chosen = rng.nextInt(cnum);\n        } else {\n            int degs[4];\n            bool filtered = false;\n            for (int i = 0; i < cnum; i++) {\n                degs[i] = compute_deg(candIdxArr[i], Tcell[candIdxArr[i]]);\n                if (param.avoidLevel >= 0 && degs[i] > param.avoidLevel) filtered = true;\n            }\n            if (param.mode == MIN_DEG) {\n                int bestDeg = 1e9, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (param.avoidLevel >= 0 && filtered && d <= param.avoidLevel) continue;\n                    if (d < bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int val = Pcell[candIdxArr[i]];\n                        if (val > bestVal) {\n                            bestVal = val;\n                            chosen = i;\n                        } else if (val == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else if (param.mode == MAX_DEG) {\n                int bestDeg = -1, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (param.avoidLevel >= 0 && filtered && d <= param.avoidLevel) continue;\n                    if (d > bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int val = Pcell[candIdxArr[i]];\n                        if (val > bestVal) {\n                            bestVal = val;\n                            chosen = i;\n                        } else if (val == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else { // MAX_VALUE\n                int bestVal = -1, bestDeg = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (param.avoidLevel >= 0 && filtered && d <= param.avoidLevel) continue;\n                    int val = Pcell[candIdxArr[i]];\n                    if (val > bestVal) {\n                        bestVal = val;\n                        bestDeg = d;\n                        chosen = i;\n                    } else if (val == bestVal) {\n                        if (d > bestDeg) {\n                            bestDeg = d;\n                            chosen = i;\n                        } else if (d == bestDeg && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            }\n        }\n        if (chosen == -1) chosen = rng.nextInt(cnum);\n        int nxt = candIdxArr[chosen];\n        visitedTile[Tcell[nxt]] = currentToken;\n        score += Pcell[nxt];\n        mv.push_back(candDirArr[chosen]);\n        cur = nxt;\n    }\n    Path res;\n    res.score = score;\n    res.len = (int)mv.size() + 1;\n    res.moves.assign(mv.begin(), mv.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    int maxTid = -1;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Tcell[idx] = x;\n            if (x > maxTid) maxTid = x;\n        }\n    }\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Pcell[idx] = x;\n        }\n    }\n    tileCount = maxTid + 1;\n    visitedTile.assign(tileCount, 0);\n    startIdx = si * W + sj;\n\n    // Precompute neighbors\n    for (int r = 0; r < H; r++) {\n        for (int c = 0; c < W; c++) {\n            int idx = r * W + c;\n            int cnt = 0;\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 >= H || nc < 0 || nc >= W) continue;\n                nbIdx[idx][cnt] = nr * W + nc;\n                nbDir[idx][cnt] = dch[d];\n                cnt++;\n            }\n            nbCnt[idx] = cnt;\n        }\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    rng = XorShift(seed);\n\n    vector<Param> params = {\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 30},\n        {1, MIN_DEG, 0},\n        {1, MIN_DEG, 50},\n        {0, MAX_DEG, 0},\n        {0, MAX_DEG, 50},\n        {0, MAX_VALUE, 0},\n        {0, MAX_VALUE, 50},\n        {0, MIN_DEG, 200},\n        {2, MIN_DEG, 0},\n    };\n\n    Path best;\n    best.score = -1;\n    best.len = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeLimit = startTime + chrono::milliseconds(1900);\n\n    int pidx = rng.nextInt((int)params.size());\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (now >= timeLimit) break;\n        const Param &param = params[pidx];\n        pidx++;\n        if (pidx >= (int)params.size()) pidx = 0;\n        Path curPath = run_once(param);\n        if (curPath.score > best.score || (curPath.score == best.score && curPath.len > best.len)) {\n            best = std::move(curPath);\n        }\n    }\n\n    cout << best.moves << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Neighbor {\n    int to;\n    int edge;\n    char dir;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int H = 30, W = 30;\n    const int N = H * W;\n    const int EH = H * (W - 1);\n    const int EV = (H - 1) * W;\n    const int E = EH + EV;\n\n    // edge index table\n    int h_idx[H][W - 1];\n    int v_idx[H - 1][W];\n    int idx = 0;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            h_idx[i][j] = idx++;\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            v_idx[i][j] = idx++;\n        }\n    }\n\n    vector<vector<Neighbor>> adj(N);\n    // horizontal edges\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            int e = h_idx[i][j];\n            int u = i * W + j;\n            int v = i * W + (j + 1);\n            adj[u].push_back({v, e, 'R'});\n            adj[v].push_back({u, e, 'L'});\n        }\n    }\n    // vertical edges\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            int e = v_idx[i][j];\n            int u = i * W + j;\n            int v = (i + 1) * W + j;\n            adj[u].push_back({v, e, 'D'});\n            adj[v].push_back({u, e, 'U'});\n        }\n    }\n\n    vector<double> w(E, 5000.0); // estimated weights\n    vector<int> cnt(E, 0);       // visit counts\n\n    const double BASE_LR = 0.3;\n    const int EXP_END = 300;\n    const double EXP_ST = 1200.0;\n\n    auto smooth_unvisited = [&]() {\n        // horizontal rows\n        for (int i = 0; i < H; i++) {\n            double sum = 0.0;\n            int c = 0;\n            for (int j = 0; j < W - 1; j++) {\n                int e = h_idx[i][j];\n                if (cnt[e] > 0) {\n                    sum += w[e];\n                    c++;\n                }\n            }\n            if (c > 0) {\n                double avg = sum / c;\n                for (int j = 0; j < W - 1; j++) {\n                    int e = h_idx[i][j];\n                    if (cnt[e] == 0) {\n                        w[e] = avg;\n                    }\n                }\n            }\n        }\n        // vertical columns\n        for (int j = 0; j < W; j++) {\n            double sum = 0.0;\n            int c = 0;\n            for (int i = 0; i < H - 1; i++) {\n                int e = v_idx[i][j];\n                if (cnt[e] > 0) {\n                    sum += w[e];\n                    c++;\n                }\n            }\n            if (c > 0) {\n                double avg = sum / c;\n                for (int i = 0; i < H - 1; i++) {\n                    int e = v_idx[i][j];\n                    if (cnt[e] == 0) {\n                        w[e] = avg;\n                    }\n                }\n            }\n        }\n    };\n\n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        int s = si * W + sj;\n        int t = ti * W + tj;\n\n        double explore_factor = (q < EXP_END) ? (double)(EXP_END - q) / EXP_END : 0.0;\n        double explore_bonus = EXP_ST * explore_factor;\n\n        // Dijkstra\n        const double INF = 1e100;\n        vector<double> dist(N, INF);\n        vector<int> prev(N, -1), prev_edge(N, -1);\n        vector<char> prev_dir(N, 0);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n        dist[s] = 0.0;\n        pq.push({0.0, s});\n        while (!pq.empty()) {\n            auto [d, v] = pq.top();\n            pq.pop();\n            if (d != dist[v]) continue;\n            if (v == t) break;\n            for (auto &nb : adj[v]) {\n                double cost = w[nb.edge] - explore_bonus / sqrt((double)cnt[nb.edge] + 1.0);\n                if (cost < 1.0) cost = 1.0;\n                double nd = d + cost;\n                if (nd < dist[nb.to]) {\n                    dist[nb.to] = nd;\n                    prev[nb.to] = v;\n                    prev_edge[nb.to] = nb.edge;\n                    prev_dir[nb.to] = nb.dir;\n                    pq.push({nd, nb.to});\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        vector<int> edges_seq;\n        int v = t;\n        while (v != s) {\n            int e = prev_edge[v];\n            char dir = prev_dir[v];\n            if (e < 0) break; // safety\n            path.push_back(dir);\n            edges_seq.push_back(e);\n            v = prev[v];\n        }\n        reverse(path.begin(), path.end());\n        reverse(edges_seq.begin(), edges_seq.end());\n\n        double pred_len = 0.0;\n        for (int e : edges_seq) pred_len += w[e];\n        int path_len_edges = (int)edges_seq.size();\n\n        cout << path << '\\n' << flush;\n\n        int obs_int;\n        if (!(cin >> obs_int)) break;\n        double obs_len = obs_int;\n        double error = obs_len - pred_len;\n\n        for (int e : edges_seq) {\n            double lr = BASE_LR / sqrt((double)cnt[e] + 1.0);\n            w[e] += lr * error / (double)path_len_edges;\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 9500.0) w[e] = 9500.0;\n            cnt[e]++;\n        }\n\n        if (q % 10 == 0) smooth_unvisited();\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    inline uint32_t next_u32() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return static_cast<uint32_t>(x);\n    }\n    inline int next_int(int n) { return static_cast<int>(next_u32() % n); }\n};\n\nconst int N = 20;\nconst int PL = 800; // number of placements per string (400 horiz + 400 vert)\n\nint M;\nvector<string> s;\nvector<int> lens;\nvector<vector<uint16_t>> cells;       // [i][pi*len + p] -> cell index\nvector<vector<uint8_t>> letters;      // [i][p] letter index 0..7\nvector<uint16_t*> cellPtrs;\nvector<uint8_t*> letterPtrs;\nvector<int> currPlacement;\n\nint counts[400][8];\nint totalCnt[400];\n\ninline void addPlacement(int si, int pi) {\n    int len = lens[si];\n    const uint16_t* cellsp = cellPtrs[si] + pi * len;\n    const uint8_t* lp = letterPtrs[si];\n    for (int p = 0; p < len; ++p) {\n        int cell = cellsp[p];\n        int li = lp[p];\n        ++counts[cell][li];\n        ++totalCnt[cell];\n    }\n}\ninline void removePlacement(int si, int pi) {\n    int len = lens[si];\n    const uint16_t* cellsp = cellPtrs[si] + pi * len;\n    const uint8_t* lp = letterPtrs[si];\n    for (int p = 0; p < len; ++p) {\n        int cell = cellsp[p];\n        int li = lp[p];\n        --counts[cell][li];\n        --totalCnt[cell];\n    }\n}\ninline int computeConf(int si) {\n    int len = lens[si];\n    const uint16_t* cellsp = cellPtrs[si] + currPlacement[si] * len;\n    const uint8_t* lp = letterPtrs[si];\n    int conf = 0;\n    for (int p = 0; p < len; ++p) {\n        int cell = cellsp[p];\n        int li = lp[p];\n        conf += totalCnt[cell] - counts[cell][li];\n    }\n    return conf;\n}\n\nvoid buildMatrix(vector<char>& mat, bool dotUnused) {\n    mat.resize(400);\n    for (int cell = 0; cell < 400; ++cell) {\n        if (totalCnt[cell] == 0) {\n            mat[cell] = dotUnused ? '.' : 'A';\n        } else {\n            int bestL = 0;\n            int bestC = counts[cell][0];\n            for (int l = 1; l < 8; ++l) {\n                if (counts[cell][l] > bestC) {\n                    bestC = counts[cell][l];\n                    bestL = l;\n                }\n            }\n            mat[cell] = static_cast<char>('A' + bestL);\n        }\n    }\n}\n\nint evaluateMatrix(const vector<char>& mat) {\n    int satisfied = 0;\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cellsp = cellPtrs[i];\n        const char* sp = s[i].c_str();\n        bool ok = false;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            bool comp = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cellsp[base + p];\n                if (mat[cell] != sp[p]) {\n                    comp = false;\n                    break;\n                }\n            }\n            if (comp) {\n                ok = true;\n                break;\n            }\n        }\n        if (ok) ++satisfied;\n    }\n    return satisfied;\n}\n\nvoid initState(XorShift64& rng) {\n    memset(counts, 0, sizeof(counts));\n    memset(totalCnt, 0, sizeof(totalCnt));\n    currPlacement.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int pi = rng.next_int(PL);\n        currPlacement[i] = pi;\n        addPlacement(i, pi);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    s.resize(M);\n    lens.resize(M);\n    letters.resize(M);\n    cells.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        lens[i] = static_cast<int>(s[i].size());\n        letters[i].resize(lens[i]);\n        for (int p = 0; p < lens[i]; ++p) {\n            letters[i][p] = static_cast<uint8_t>(s[i][p] - 'A');\n        }\n        cells[i].resize(PL * lens[i]);\n        int len = lens[i];\n        // horizontal placements 0..399\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int cc = (c + p) % N;\n                    cells[i][base + p] = static_cast<uint16_t>(r * N + cc);\n                }\n            }\n        }\n        // vertical placements 400..799\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = 400 + r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int rr = (r + p) % N;\n                    cells[i][base + p] = static_cast<uint16_t>(rr * N + c);\n                }\n            }\n        }\n    }\n    cellPtrs.resize(M);\n    letterPtrs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cellPtrs[i] = cells[i].data();\n        letterPtrs[i] = letters[i].data();\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    XorShift64 rng(seed);\n\n    vector<char> bestMat(400, 'A');\n    int bestSat = 0;\n    bool solved = false;\n\n    auto timeStart = chrono::steady_clock::now();\n    auto elapsedSec = [&]() -> double {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - timeStart).count();\n    };\n    const double TIME_LIMIT = 2.9;\n\n    initState(rng);\n    int runIter = 0;\n    int lastImp = 0;\n    long long bestConfRun = (1LL << 60);\n    const int stallLimit = 20000;\n    const int evalInterval = 2000;\n    vector<int> conflictIdx;\n    conflictIdx.reserve(M);\n\n    while (true) {\n        if (runIter % evalInterval == 0) {\n            if (elapsedSec() > TIME_LIMIT) break;\n            vector<char> mat;\n            buildMatrix(mat, false);\n            int c = evaluateMatrix(mat);\n            if (c > bestSat) {\n                bestSat = c;\n                bestMat = mat;\n                if (bestSat == M) {\n                    // we cannot be sure it's safe to put dots unless conflicts are zero\n                }\n            }\n        }\n        if (elapsedSec() > TIME_LIMIT) break;\n\n        // compute conflicts\n        conflictIdx.clear();\n        long long totalConf = 0;\n        int maxConf = -1;\n        int pickIdx = -1;\n        for (int i = 0; i < M; ++i) {\n            int conf = computeConf(i);\n            totalConf += conf;\n            if (conf > 0) {\n                conflictIdx.push_back(i);\n                if (conf > maxConf) {\n                    maxConf = conf;\n                    pickIdx = i;\n                }\n            }\n        }\n        if (conflictIdx.empty()) {\n            // found consistent assignment\n            vector<char> mat;\n            buildMatrix(mat, true); // use dots for unused\n            bestSat = M;\n            bestMat = mat;\n            solved = true;\n            break;\n        }\n        if (totalConf < bestConfRun) {\n            bestConfRun = totalConf;\n            lastImp = runIter;\n        }\n        if (runIter - lastImp > stallLimit) {\n            // restart\n            vector<char> mat;\n            buildMatrix(mat, false);\n            int c = evaluateMatrix(mat);\n            if (c > bestSat) {\n                bestSat = c;\n                bestMat = mat;\n            }\n            if (elapsedSec() > TIME_LIMIT) break;\n            initState(rng);\n            runIter = 0;\n            lastImp = 0;\n            bestConfRun = (1LL << 60);\n            continue;\n        }\n        int si = pickIdx;\n        if ((rng.next_u32() & 7) == 0) { // small probability choose random conflicting\n            si = conflictIdx[rng.next_int((int)conflictIdx.size())];\n        }\n        // adjust placement of si\n        removePlacement(si, currPlacement[si]);\n        int len = lens[si];\n        const uint8_t* lp = letterPtrs[si];\n        const uint16_t* cellspAll = cellPtrs[si];\n        int minScore = INT_MAX;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int score = 0;\n            for (int p = 0; p < len; ++p) {\n                int cell = cellspAll[base + p];\n                int li = lp[p];\n                score += totalCnt[cell] - counts[cell][li];\n            }\n            if (score < minScore) {\n                minScore = score;\n                bestPi = pi;\n                tie = 1;\n                if (score == 0) {\n                    // can't do better\n                    break;\n                }\n            } else if (score == minScore) {\n                ++tie;\n                if ((rng.next_u32() % tie) == 0) {\n                    bestPi = pi;\n                }\n            }\n        }\n        currPlacement[si] = bestPi;\n        addPlacement(si, bestPi);\n\n        ++runIter;\n    }\n\n    if (!solved) {\n        vector<char> mat;\n        buildMatrix(mat, false);\n        int c = evaluateMatrix(mat);\n        if (c > bestSat) {\n            bestSat = c;\n            bestMat = mat;\n        }\n    }\n\n    // output bestMat as 20 lines\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << bestMat[r * N + c];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\n\nusing namespace std;\nusing namespace atcoder;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int, int>> pos;\n    vector<int> w;\n    int R = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(grid[i][j] - '0');\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> edges;\n    edges.reserve(R * 2);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = id[i][j];\n            if (u == -1) continue;\n            if (i + 1 < N) {\n                int v = id[i + 1][j];\n                if (v != -1) edges.emplace_back(u, v, w[u] + w[v]);\n            }\n            if (j + 1 < N) {\n                int v = id[i][j + 1];\n                if (v != -1) edges.emplace_back(u, v, w[u] + w[v]);\n            }\n        }\n    }\n\n    sort(edges.begin(), edges.end(),\n         [](const auto &a, const auto &b) { return get<2>(a) < get<2>(b); });\n\n    dsu uf(R);\n    vector<vector<int>> tree(R);\n    int used = 0;\n    for (auto &e : edges) {\n        int u, v, wt;\n        tie(u, v, wt) = e;\n        if (uf.same(u, v)) continue;\n        uf.merge(u, v);\n        tree[u].push_back(v);\n        tree[v].push_back(u);\n        used++;\n        if (used == R - 1) break;\n    }\n\n    int start = id[si][sj];\n    string route;\n    route.reserve(2 * R + 5);\n\n    function<void(int, int)> dfs = [&](int u, int p) {\n        for (int v : tree[u]) {\n            if (v == p) continue;\n            auto [ui, uj] = pos[u];\n            auto [vi, vj] = pos[v];\n            char dir;\n            if (vi == ui + 1)\n                dir = 'D';\n            else if (vi == ui - 1)\n                dir = 'U';\n            else if (vj == uj + 1)\n                dir = 'R';\n            else\n                dir = 'L';\n            route.push_back(dir);\n            dfs(v, u);\n            // backtrack\n            if (dir == 'U')\n                route.push_back('D');\n            else if (dir == 'D')\n                route.push_back('U');\n            else if (dir == 'L')\n                route.push_back('R');\n            else\n                route.push_back('L' == dir ? 'R' : 'L');  // unreachable\n        }\n    };\n\n    dfs(start, -1);\n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct TaskCandidate {\n    int diff; // difficulty score (sum of d)\n    int id;\n    bool operator<(const TaskCandidate& other) const {\n        // max-heap by difficulty\n        if (diff != other.diff) return diff < other.diff;\n        return id > other.id;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> difficulty_sum(N, 0);\n    for (int i = 0; i < N; i++) {\n        int sum = 0;\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n            sum += d[i][k];\n        }\n        difficulty_sum[i] = sum;\n    }\n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n    }\n    priority_queue<TaskCandidate> ready_pq;\n    for (int i = 0; i < N; i++) {\n        if (indeg[i] == 0) {\n            ready_pq.push({difficulty_sum[i], i});\n        }\n    }\n    vector<int> task_status(N, 0); // 0 not started,1 working,2 done\n    vector<int> worker_status(M, -1); // task id or -1\n    vector<int> worker_start_day(M, -1);\n    vector<int> task_start_day(N, -1);\n\n    // skill estimates\n    vector<double> mean_d(K, 0.0);\n    for (int k = 0; k < K; k++) {\n        long long s = 0;\n        for (int i = 0; i < N; i++) s += d[i][k];\n        mean_d[k] = (double)s / N;\n    }\n    vector<vector<double>> s_hat(M, vector<double>(K, 0.0));\n    for (int j = 0; j < M; j++) {\n        for (int k = 0; k < K; k++) {\n            s_hat[j][k] = mean_d[k] * 1.5 + 1.0; // initial guess\n        }\n    }\n\n    int day = 1;\n    const int MAX_CANDIDATES = 200;\n    const double LR = 0.3;\n    while (true) {\n        // collect idle workers\n        vector<int> idle_workers;\n        for (int w = 0; w < M; w++) if (worker_status[w] == -1) idle_workers.push_back(w);\n\n        vector<pair<int,int>> assignments; // (worker, task)\n        if (!idle_workers.empty()) {\n            // extract some candidates from ready_pq\n            vector<int> candidates;\n            while (!ready_pq.empty() && (int)candidates.size() < MAX_CANDIDATES) {\n                int tid = ready_pq.top().id;\n                ready_pq.pop();\n                if (task_status[tid] == 0) {\n                    candidates.push_back(tid);\n                }\n            }\n            // compute best predicted time for each candidate\n            struct CandInfo {\n                int task;\n                double bestTime;\n            };\n            vector<CandInfo> infos;\n            infos.reserve(candidates.size());\n            for (int tid : candidates) {\n                double best = 1e18;\n                for (int w : idle_workers) {\n                    double pred = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[tid][k] - s_hat[w][k];\n                        if (diff > 0) pred += diff;\n                    }\n                    if (pred < 1.0) pred = 1.0;\n                    if (pred < best) best = pred;\n                }\n                infos.push_back({tid, best});\n            }\n            // sort tasks by longest predicted best time first (start long tasks early)\n            sort(infos.begin(), infos.end(), [](const CandInfo& a, const CandInfo& b){\n                if (a.bestTime != b.bestTime) return a.bestTime > b.bestTime;\n                return a.task < b.task;\n            });\n            vector<bool> assigned_task(N, false);\n            for (auto &ci : infos) {\n                if (idle_workers.empty()) break;\n                int tid = ci.task;\n                if (task_status[tid] != 0) continue;\n                // choose best worker for this task among idle\n                int best_w = -1;\n                double best_pred = 1e18;\n                int best_idx = -1;\n                for (int idx = 0; idx < (int)idle_workers.size(); idx++) {\n                    int w = idle_workers[idx];\n                    double pred = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[tid][k] - s_hat[w][k];\n                        if (diff > 0) pred += diff;\n                    }\n                    if (pred < 1.0) pred = 1.0;\n                    if (pred < best_pred) {\n                        best_pred = pred;\n                        best_w = w;\n                        best_idx = idx;\n                    }\n                }\n                if (best_w != -1) {\n                    assignments.push_back({best_w, tid});\n                    worker_status[best_w] = tid;\n                    worker_start_day[best_w] = day;\n                    task_status[tid] = 1;\n                    task_start_day[tid] = day;\n                    idle_workers.erase(idle_workers.begin() + best_idx);\n                    assigned_task[tid] = true;\n                }\n            }\n            // push back unassigned candidates\n            for (int tid : candidates) {\n                if (!assigned_task[tid]) {\n                    ready_pq.push({difficulty_sum[tid], tid});\n                }\n            }\n        }\n\n        // output assignments\n        cout << assignments.size();\n        for (auto &p : assignments) {\n            cout << \" \" << (p.first + 1) << \" \" << (p.second + 1);\n        }\n        cout << endl;\n        cout.flush();\n\n        // read feedback\n        int n;\n        if (!(cin >> n)) break;\n        if (n == -1) {\n            break;\n        }\n        vector<int> fs(n);\n        for (int i = 0; i < n; i++) cin >> fs[i];\n        for (int fidx = 0; fidx < n; fidx++) {\n            int w = fs[fidx] - 1;\n            int tid = worker_status[w];\n            if (tid < 0) continue;\n            int duration = day - worker_start_day[w] + 1;\n            task_status[tid] = 2;\n            // update skills\n            double w_obs = (double)duration;\n            double w_pred = 0.0;\n            int active = 0;\n            for (int k = 0; k < K; k++) {\n                double diff = d[tid][k] - s_hat[w][k];\n                if (diff > 0) {\n                    w_pred += diff;\n                    active++;\n                }\n            }\n            if (active == 0) active = K;\n            double delta = LR * (w_pred - w_obs) / active;\n            for (int k = 0; k < K; k++) {\n                if (active == K || d[tid][k] > s_hat[w][k]) {\n                    s_hat[w][k] += delta;\n                    if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                }\n            }\n            // update indegrees\n            for (int v : adj[tid]) {\n                indeg[v]--;\n                if (indeg[v] == 0 && task_status[v] == 0) {\n                    ready_pq.push({difficulty_sum[v], v});\n                }\n            }\n            worker_status[w] = -1;\n        }\n        day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int NORD = 1000;\nconst int CHOOSE = 50;\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst int TOP_M = 200;\nconst double TIME_LIMIT = 1.9; // seconds\n\nint ax[NORD], byy[NORD], cx[NORD], dy[NORD];\n\ninline int mdist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// subset has exactly 50 order ids (1-based)\nlong long compute_route(const array<int, CHOOSE>& subset,\n                        vector<pair<int,int>>* out_path = nullptr) {\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int delivered = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (out_path) {\n        out_path->clear();\n        out_path->reserve(CHOOSE*2 + 2);\n        out_path->push_back({curx, cury});\n    }\n    while (delivered < CHOOSE) {\n        int best = -1, bestd = INT_MAX, bestx = 0, besty = 0;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (status[i] == 2) continue;\n            int tx, ty;\n            if (status[i] == 0) {\n                int id = subset[i] - 1;\n                tx = ax[id]; ty = byy[id];\n            } else {\n                int id = subset[i] - 1;\n                tx = cx[id]; ty = dy[id];\n            }\n            int d = abs(curx - tx) + abs(cury - ty);\n            if (d < bestd) {\n                bestd = d; best = i; bestx = tx; besty = ty;\n            }\n        }\n        total += bestd;\n        curx = bestx; cury = besty;\n        if (out_path) out_path->push_back({curx, cury});\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; delivered++; }\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (out_path) out_path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    for (int i = 0; i < NORD; i++) {\n        if (!(cin >> ax[i] >> byy[i] >> cx[i] >> dy[i])) return 0;\n    }\n    vector<int> ids(NORD);\n    iota(ids.begin(), ids.end(), 0);\n    vector<long long> cost(NORD);\n    for (int i = 0; i < NORD; i++) {\n        cost[i] = mdist(DEPOT_X, DEPOT_Y, ax[i], byy[i]) +\n                  mdist(ax[i], byy[i], cx[i], dy[i]) +\n                  mdist(cx[i], dy[i], DEPOT_X, DEPOT_Y);\n    }\n    sort(ids.begin(), ids.end(), [&](int i, int j){ return cost[i] < cost[j]; });\n    int pool_size = min(TOP_M, NORD);\n    vector<int> pool(ids.begin(), ids.begin() + pool_size);\n\n    array<int, CHOOSE> best_subset;\n    for (int i = 0; i < CHOOSE; i++) best_subset[i] = ids[i] + 1; // 1-based\n    long long bestT = compute_route(best_subset);\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n\n    array<int, CHOOSE> cur_subset;\n    while (true) {\n        shuffle(pool.begin(), pool.end(), rng);\n        for (int i = 0; i < CHOOSE; i++) cur_subset[i] = pool[i] + 1;\n        long long curT = compute_route(cur_subset);\n        if (curT < bestT) {\n            bestT = curT;\n            best_subset = cur_subset;\n        }\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n    }\n\n    vector<pair<int,int>> path;\n    compute_route(best_subset, &path);\n\n    // Output\n    cout << CHOOSE;\n    for (int i = 0; i < CHOOSE; i++) {\n        cout << ' ' << best_subset[i];\n    }\n    cout << '\\n';\n    cout << path.size();\n    for (auto &p : path) {\n        cout << ' ' << p.first << ' ' << p.second;\n    }\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, sz;\n    DSU(int n_=0): n(n_), p(n_), sz(n_,1) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\n    bool merge(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b];\n        return true;\n    }\n};\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u,v;\n    int d; // rounded euclidean distance\n    bool in_mst=false;\n};\n\nvector<Edge> edges(M);\nvector<int> xs(N), ys(N);\n\n// low-link variables\nvector<int> tin, low;\nvector<char> vis;\nvector<char> is_bridge;\nvector<vector<pair<int,int>>> adjlist;\nint timer_dfs;\n\n// compute bridges on current alive graph\nvoid compute_bridges(const vector<char>& alive){\n    for(int i=0;i<N;i++) adjlist[i].clear();\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u = edges[id].u;\n        int v = edges[id].v;\n        adjlist[u].push_back({v,id});\n        adjlist[v].push_back({u,id});\n    }\n    fill(vis.begin(), vis.end(), 0);\n    fill(is_bridge.begin(), is_bridge.end(), 0);\n    timer_dfs = 0;\n    function<void(int,int)> dfs = [&](int v,int pe){\n        vis[v]=1;\n        tin[v]=low[v]=++timer_dfs;\n        for(auto [to,eid]: adjlist[v]){\n            if(eid==pe) continue;\n            if(vis[to]){\n                low[v]=min(low[v], tin[to]);\n            }else{\n                dfs(to,eid);\n                low[v]=min(low[v], low[to]);\n                if(low[to] > tin[v]){\n                    is_bridge[eid]=1;\n                }\n            }\n        }\n    };\n    for(int i=0;i<N;i++){\n        if(!vis[i]) dfs(i,-1);\n    }\n}\n\n// prepare out_count (edges leaving each component of dsu) while scanning alive edges\nvoid compute_out_count(const vector<char>& alive, DSU &dsu, vector<int>& out_cnt){\n    fill(out_cnt.begin(), out_cnt.end(), 0);\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        int ru=dsu.find(u), rv=dsu.find(v);\n        if(ru==rv) continue;\n        out_cnt[ru]++;\n        out_cnt[rv]++;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    // read coordinates\n    for(int i=0;i<N;i++){\n        if(!(cin>>xs[i]>>ys[i])) return 0;\n    }\n    // read edges\n    for(int i=0;i<M;i++){\n        int u,v;\n        cin>>u>>v;\n        edges[i].u=u;\n        edges[i].v=v;\n        long dx = xs[u]-xs[v];\n        long dy = ys[u]-ys[v];\n        edges[i].d = (int)llround(sqrt((double)(dx*dx + dy*dy)));\n    }\n\n    // compute MST on lower bounds d\n    vector<int> idx(M);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int a,int b){\n        if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n        return a < b;\n    });\n    DSU dsu_tmp(N);\n    int cnt=0;\n    for(int id: idx){\n        if(dsu_tmp.merge(edges[id].u, edges[id].v)){\n            edges[id].in_mst = true;\n            if(++cnt == N-1) break;\n        }\n    }\n\n    // initialize structures\n    vector<char> alive(M, 1);\n    DSU dsu_conn(N);\n    int comp_cnt = N;\n\n    tin.assign(N,0);\n    low.assign(N,0);\n    vis.assign(N,0);\n    is_bridge.assign(M,0);\n    adjlist.assign(N, {});\n    vector<int> out_cnt(N,0);\n\n    const double MST_START = 1.55;\n    const double MST_END   = 1.9;\n    const double OTH_START = 1.35;\n    const double OTH_END   = 1.6;\n    const double CYCLE_THR = 1.03;\n    const double GAMMA     = 0.5; // use sqrt of progress\n\n    for(int i=0;i<M;i++){\n        int l;\n        if(!(cin>>l)) break;\n        double r = (double)l / (double)edges[i].d;\n\n        // recompute bridges and out_count\n        compute_bridges(alive);\n        compute_out_count(alive, dsu_conn, out_cnt);\n\n        bool accept = false;\n        if(is_bridge[i]){\n            accept = true;\n        }else{\n            int ru = dsu_conn.find(edges[i].u);\n            int rv = dsu_conn.find(edges[i].v);\n            if(ru != rv){\n                double p = (double)i / (double)M;\n                double f = sqrt(p); // p^0.5\n                double thr;\n                if(edges[i].in_mst){\n                    thr = MST_START + (MST_END - MST_START) * f;\n                }else{\n                    thr = OTH_START + (OTH_END - OTH_START) * f;\n                }\n                int k = min(out_cnt[ru], out_cnt[rv]);\n                if(k <= 2) thr += 0.30;\n                else if(k <= 4) thr += 0.15;\n                else if(k <= 6) thr += 0.07;\n                if(thr > 2.8) thr = 2.8;\n                if(r <= thr) accept = true;\n            }else{\n                // forms cycle in accepted forest\n                if(comp_cnt > 1 && r <= CYCLE_THR) accept = true;\n                else accept = false;\n            }\n        }\n\n        if(accept){\n            if(dsu_conn.merge(edges[i].u, edges[i].v)){\n                comp_cnt--;\n            }\n            // alive stays true\n        }else{\n            alive[i] = 0; // remove edge\n        }\n\n        cout << (accept ? 1 : 0) << '\\n';\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet {\n    int x, y, t;\n};\n\nint N, M;\nvector<Pet> pets;\nvector<int> hx, hy;\nvector<vector<bool>> wall(31, vector<bool>(31, false));\n\nint r1, r2, c1, c2; // region\nint colWallCol, rowWallRow;\nint builderCol, builderRow;\nchar colDir, rowDir;\nint entryWallX, entryWallY;\npair<int,int> entryDest;\nvector<pair<int,int>> stations;\nint T_close;\n\nint encode(int x,int y){ return x*64 + y; }\n\nint dist_point_to_rect(int px,int py,int r1,int r2,int c1,int c2){\n    int dx=0, dy=0;\n    if(px < r1) dx = r1 - px;\n    else if(px > r2) dx = px - r2;\n    if(py < c1) dy = c1 - py;\n    else if(py > c2) dy = py - c2;\n    return dx + dy;\n}\n\nbool can_build(int wx,int wy, const vector<Pet>& pets, const vector<int>& hx, const vector<int>& hy){\n    if(wx < 1 || wx > 30 || wy < 1 || wy > 30) return false;\n    for(const auto& p : pets){\n        if(abs(p.x - wx) + abs(p.y - wy) <= 1) return false;\n    }\n    for(size_t i=0;i<hx.size();i++){\n        if(hx[i]==wx && hy[i]==wy) return false;\n    }\n    return true;\n}\n\n// BFS from target to all cells, choose move from (sx,sy) toward target\nchar bfs_move(int sx,int sy,int tx,int ty,bool regionOnly,\n              const vector<vector<bool>>& wall,\n              const unordered_set<int>& buildTargets,\n              int r1,int r2,int c1,int c2){\n    if(tx<1||tx>30||ty<1||ty>30) return '.';\n    auto blocked = [&](int x,int y)->bool{\n        if(x<1 || x>30 || y<1 || y>30) return true;\n        if(regionOnly && (x<r1 || x>r2 || y<c1 || y>c2)) return true;\n        if(wall[x][y]) return true;\n        if(buildTargets.find(encode(x,y)) != buildTargets.end()) return true;\n        return false;\n    };\n    if(blocked(tx,ty)) return '.';\n    static int dist[31][31];\n    for(int i=1;i<=30;i++) for(int j=1;j<=30;j++) dist[i][j] = -1;\n    queue<pair<int,int>> q;\n    dist[tx][ty]=0;\n    q.push({tx,ty});\n    int dxs[4]={-1,1,0,0};\n    int dys[4]={0,0,-1,1};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        int nd = dist[x][y]+1;\n        for(int dir=0;dir<4;dir++){\n            int nx = x + dxs[dir];\n            int ny = y + dys[dir];\n            if(blocked(nx,ny)) continue;\n            if(dist[nx][ny]==-1){\n                dist[nx][ny]=nd;\n                q.push({nx,ny});\n            }\n        }\n    }\n    if(dist[sx][sy]==-1 || dist[sx][sy]==0) return '.';\n    char dirc[4]={'U','D','L','R'};\n    for(int dir=0;dir<4;dir++){\n        int nx = sx + dxs[dir];\n        int ny = sy + dys[dir];\n        if(nx<1||nx>30||ny<1||ny>30) continue;\n        if(regionOnly && (nx<r1||nx>r2||ny<c1||ny>c2)) continue;\n        if(blocked(nx,ny)) continue;\n        if(dist[nx][ny] == dist[sx][sy]-1){\n            return dirc[dir];\n        }\n    }\n    return '.';\n}\n\nvoid select_region(const vector<int>& initHx, const vector<int>& initHy){\n    int maxK = 8;\n    int minK = 3;\n    double bestScore = -1e18;\n    int bestCorner=0,bestK=minK;\n    int bestR1=1,bestR2=minK,bestC1=1,bestC2=minK;\n    int bestMinDist = -1;\n    int bestMaxHDist = 1;\n    for(int corner=0; corner<4; corner++){\n        for(int k=maxK; k>=minK; k--){\n            int rr1,rr2,cc1,cc2;\n            switch(corner){\n                case 0: rr1=1; rr2=k; cc1=1; cc2=k; break; // TL\n                case 1: rr1=1; rr2=k; cc1=30-k+1; cc2=30; break; // TR\n                case 2: rr1=30-k+1; rr2=30; cc1=1; cc2=k; break; // BL\n                case 3: rr1=30-k+1; rr2=30; cc1=30-k+1; cc2=30; break; // BR\n            }\n            int petCount=0;\n            int minDistPets=1000;\n            for(const auto& p: pets){\n                if(rr1<=p.x && p.x<=rr2 && cc1<=p.y && p.y<=cc2) petCount++;\n                int d = dist_point_to_rect(p.x,p.y,rr1,rr2,cc1,cc2);\n                if(d < minDistPets) minDistPets = d;\n            }\n            if(pets.empty()) minDistPets = 1000;\n            int maxHDist=0;\n            for(size_t i=0;i<initHx.size();i++){\n                int d = dist_point_to_rect(initHx[i], initHy[i], rr1, rr2, cc1, cc2);\n                if(d > maxHDist) maxHDist = d;\n            }\n            double score_est = (double)(k*k) * pow(0.5, petCount) / (maxHDist + 1);\n            if(score_est > bestScore + 1e-9 ||\n               (abs(score_est - bestScore) < 1e-9 && minDistPets > bestMinDist)){\n                bestScore = score_est;\n                bestCorner = corner;\n                bestK = k;\n                bestR1=rr1; bestR2=rr2; bestC1=cc1; bestC2=cc2;\n                bestMinDist = minDistPets;\n                bestMaxHDist = maxHDist;\n            }\n        }\n    }\n    r1=bestR1; r2=bestR2; c1=bestC1; c2=bestC2;\n    // set walls directions\n    if(c1==1){\n        colWallCol = c2+1; colDir='r'; builderCol = c2;\n    }else{\n        colWallCol = c1-1; colDir='l'; builderCol = c1;\n    }\n    if(r1==1){\n        rowWallRow = r2+1; rowDir='d'; builderRow = r2;\n    }else{\n        rowWallRow = r1-1; rowDir='u'; builderRow = r1;\n    }\n    entryWallX = rowWallRow;\n    entryWallY = (c1 + c2) / 2;\n    entryDest = {builderRow, entryWallY};\n    // stations\n    stations.clear();\n    for(int r=r1; r<=r2; r++) stations.push_back({r, builderCol});\n    for(int c=c1; c<=c2; c++) stations.push_back({builderRow, c});\n    // closing time threshold\n    T_close = min(100, bestMaxHDist + 5);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N;\n    pets.resize(N);\n    for(int i=0;i<N;i++){\n        cin >> pets[i].x >> pets[i].y >> pets[i].t;\n    }\n    cin >> M;\n    hx.resize(M);\n    hy.resize(M);\n    for(int i=0;i<M;i++){\n        cin >> hx[i] >> hy[i];\n    }\n    vector<int> initHx = hx, initHy = hy;\n    select_region(initHx, initHy);\n\n    vector<pair<int,int>> colWalls;\n    for(int r=r1; r<=r2; r++) colWalls.push_back({r, colWallCol});\n    vector<pair<int,int>> rowWalls;\n    for(int c=c1; c<=c2; c++) rowWalls.push_back({rowWallRow, c});\n\n    for(int turn=0; turn<300; turn++){\n        bool col_complete=true, row_complete=true;\n        for(auto &p: colWalls){\n            if(!wall[p.first][p.second]){ col_complete=false; break; }\n        }\n        for(auto &p: rowWalls){\n            if(!wall[p.first][p.second]){ row_complete=false; break; }\n        }\n        bool all_inside=true;\n        for(int i=0;i<M;i++){\n            if(!(r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2)){\n                all_inside=false; break;\n            }\n        }\n        bool close_condition = all_inside || turn >= T_close;\n        unordered_set<int> buildTargets;\n        string actions(M, '.');\n\n        // Pass 1: building attempts\n        for(int i=0;i<M;i++){\n            if(actions[i] != '.') continue;\n            // col boundary build\n            if(!col_complete){\n                if(hx[i]>=r1 && hx[i]<=r2 && hy[i]==builderCol){\n                    int wx = hx[i];\n                    int wy = (colDir=='r') ? hy[i]+1 : hy[i]-1;\n                    int key = encode(wx, wy);\n                    if(wx>=1 && wx<=30 && wy>=1 && wy<=30 &&\n                       !wall[wx][wy] && buildTargets.find(key)==buildTargets.end() &&\n                       can_build(wx,wy,pets,hx,hy)){\n                        actions[i] = colDir; // already lowercase\n                        buildTargets.insert(key);\n                        continue;\n                    }\n                }\n            }\n            // row boundary build\n            if(!row_complete){\n                if(hx[i]==builderRow && hy[i]>=c1 && hy[i]<=c2){\n                    int wx = (rowDir=='d') ? hx[i]+1 : hx[i]-1;\n                    int wy = hy[i];\n                    bool isEntry = (wx==entryWallX && wy==entryWallY);\n                    if((!isEntry) || close_condition){\n                        int key = encode(wx, wy);\n                        if(wx>=1 && wx<=30 && wy>=1 && wy<=30 &&\n                           !wall[wx][wy] && buildTargets.find(key)==buildTargets.end() &&\n                           can_build(wx,wy,pets,hx,hy)){\n                            actions[i] = rowDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Pass 2: movement\n        for(int i=0;i<M;i++){\n            if(actions[i] != '.') continue;\n            bool inside = (r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2);\n            pair<int,int> target = inside ? stations[i % stations.size()] : entryDest;\n            bool regionOnly = inside;\n            char mv = bfs_move(hx[i], hy[i], target.first, target.second, regionOnly, wall, buildTargets, r1, r2, c1, c2);\n            actions[i] = mv;\n        }\n\n        cout << actions << \"\\n\";\n        cout.flush();\n\n        // Read pet movements\n        for(int i=0;i<N;i++){\n            string s; cin >> s;\n            if(s==\".\") continue;\n            for(char ch: s){\n                if(ch=='U') pets[i].x--;\n                else if(ch=='D') pets[i].x++;\n                else if(ch=='L') pets[i].y--;\n                else if(ch=='R') pets[i].y++;\n            }\n        }\n\n        // Apply builds\n        for(int key : buildTargets){\n            int wx = key/64;\n            int wy = key%64;\n            if(wx>=1 && wx<=30 && wy>=1 && wy<=30){\n                wall[wx][wy]=true;\n            }\n        }\n        // Apply human moves\n        for(int i=0;i<M;i++){\n            char ac = actions[i];\n            if(ac=='U') hx[i]--;\n            else if(ac=='D') hx[i]++;\n            else if(ac=='L') hy[i]--;\n            else if(ac=='R') hy[i]++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int DIRS = 4;\nconst int INF = 1e9;\nconst double TIME_LIMIT = 1.9;\n\nint startId, targetId;\ndouble p_forget, q_exec;\nint moveTbl[N][DIRS]; // neighbor when trying to move (stays if wall)\nint weightArr[200];   // reward weight for each step\ndouble dist1[N], dist2pow[N];\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> uni01(0.0, 1.0);\n\ninline int idx(int i, int j) { return i * W + j; }\n\nvoid build_moves(const vector<string> &h, const vector<string> &v) {\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int id = idx(i, j);\n            // Up\n            if (i == 0 || v[i - 1][j] == '1')\n                moveTbl[id][0] = id;\n            else\n                moveTbl[id][0] = idx(i - 1, j);\n            // Down\n            if (i == H - 1 || v[i][j] == '1')\n                moveTbl[id][1] = id;\n            else\n                moveTbl[id][1] = idx(i + 1, j);\n            // Left\n            if (j == 0 || h[i][j - 1] == '1')\n                moveTbl[id][2] = id;\n            else\n                moveTbl[id][2] = idx(i, j - 1);\n            // Right\n            if (j == W - 1 || h[i][j] == '1')\n                moveTbl[id][3] = id;\n            else\n                moveTbl[id][3] = idx(i, j + 1);\n        }\n    }\n}\n\nvector<int> bfs_path(bool monotone_only) {\n    vector<int> prev(N, -1), prevDir(N, -1);\n    vector<char> vis(N, 0);\n    queue<int> q;\n    vis[startId] = 1;\n    q.push(startId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        if (u == targetId) break;\n        for (int dir = 0; dir < DIRS; dir++) {\n            if (monotone_only && !(dir == 1 || dir == 3)) continue; // only D or R\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (!vis[nb]) {\n                vis[nb] = 1;\n                prev[nb] = u;\n                prevDir[nb] = dir;\n                q.push(nb);\n            }\n        }\n    }\n    if (!vis[targetId]) return {};\n    vector<int> path;\n    int cur = targetId;\n    while (cur != startId) {\n        int d = prevDir[cur];\n        path.push_back(d);\n        cur = prev[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid compute_dist() {\n    vector<int> dist(N, INF);\n    queue<int> q;\n    dist[targetId] = 0;\n    q.push(targetId);\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        int du = dist[u];\n        for (int dir = 0; dir < DIRS; dir++) {\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (dist[nb] == INF) {\n                dist[nb] = du + 1;\n                q.push(nb);\n            }\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        dist1[i] = (double)dist[i];\n        dist2pow[i] = dist1[i] * dist1[i];\n    }\n}\n\ndouble eval_seq(const vector<int> &seq) {\n    static double buf1[N], buf2[N];\n    double *cur = buf1, *nxt = buf2;\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double res = 0.0;\n    int L = seq.size();\n    for (int step = 0; step < L; step++) {\n        int dir = seq[step];\n        double rw = weightArr[step];\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][dir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                res += mv * rw;\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return res;\n}\n\ninline int argmin_scores(const double sc[4]) {\n    // tie-break order prefers Down(1), Right(3), Left(2), Up(0)\n    static const int order[4] = {1, 3, 2, 0};\n    int best = order[0];\n    double bestv = sc[best];\n    for (int k = 1; k < 4; k++) {\n        int d = order[k];\n        double v = sc[d];\n        if (v < bestv) {\n            bestv = v;\n            best = d;\n        }\n    }\n    return best;\n}\n\nvoid generate_seq(double eps, const double *distArr, double &bestScore, vector<int> &bestSeq) {\n    static int seq[200];\n    static double buf1[N], buf2[N];\n    double *cur = buf1, *nxt = buf2;\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double res = 0.0;\n    for (int step = 0; step < 200; step++) {\n        double s0 = 0, s1 = 0, s2 = 0, s3 = 0;\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            s0 += pu * distArr[moveTbl[u][0]];\n            s1 += pu * distArr[moveTbl[u][1]];\n            s2 += pu * distArr[moveTbl[u][2]];\n            s3 += pu * distArr[moveTbl[u][3]];\n        }\n        double scores[4] = {s0, s1, s2, s3};\n        int dir = argmin_scores(scores);\n        if (eps > 0.0) {\n            double r = uni01(rng);\n            if (r < eps) {\n                dir = (int)(rng() & 3ULL);\n            }\n        }\n        seq[step] = dir;\n        double rw = weightArr[step];\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][dir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                res += mv * rw;\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    if (res > bestScore) {\n        bestScore = res;\n        bestSeq.assign(seq, seq + 200);\n    }\n}\n\nvoid add_repeat_each(const vector<int> &path, double &bestScore, vector<int> &bestSeq) {\n    int len = (int)path.size();\n    if (len == 0) return;\n    int maxr = 200 / len;\n    for (int r = 1; r <= maxr; r++) {\n        vector<int> seq;\n        seq.reserve(200);\n        for (int d : path) {\n            for (int k = 0; k < r; k++) seq.push_back(d);\n        }\n        if ((int)seq.size() < 200) seq.resize(200, path.back());\n        double sc = eval_seq(seq);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestSeq = seq;\n        }\n    }\n    // repeating whole path to fill 200\n    vector<int> seq;\n    seq.reserve(200);\n    while ((int)seq.size() + len <= 200) {\n        seq.insert(seq.end(), path.begin(), path.end());\n    }\n    if ((int)seq.size() < 200) {\n        int need = 200 - (int)seq.size();\n        int take = min(need, len);\n        seq.insert(seq.end(), path.begin(), path.begin() + take);\n    }\n    double sc = eval_seq(seq);\n    if (sc > bestScore) {\n        bestScore = sc;\n        bestSeq = seq;\n    }\n}\n\nvoid add_ratio_candidates(int dv, int dh, double &bestScore, vector<int> &bestSeq) {\n    if (dv + dh == 0) return;\n    int nD = (int)round(200.0 * dv / (dv + dh));\n    nD = max(0, min(200, nD));\n    int nR = 200 - nD;\n    // D then R\n    vector<int> seq;\n    seq.reserve(200);\n    seq.insert(seq.end(), nD, 1);\n    seq.insert(seq.end(), nR, 3);\n    double sc = eval_seq(seq);\n    if (sc > bestScore) { bestScore = sc; bestSeq = seq; }\n    // R then D\n    seq.clear();\n    seq.insert(seq.end(), nR, 3);\n    seq.insert(seq.end(), nD, 1);\n    sc = eval_seq(seq);\n    if (sc > bestScore) { bestScore = sc; bestSeq = seq; }\n    // proportional random order\n    seq.clear();\n    int remD = nD, remR = nR;\n    for (int i = 0; i < 200; i++) {\n        if (remD == 0) {\n            seq.push_back(3); remR--;\n        } else if (remR == 0) {\n            seq.push_back(1); remD--;\n        } else {\n            double probD = (double)remD / (remD + remR);\n            double r = uni01(rng);\n            if (r < probD) { seq.push_back(1); remD--; }\n            else { seq.push_back(3); remR--; }\n        }\n    }\n    sc = eval_seq(seq);\n    if (sc > bestScore) { bestScore = sc; bestSeq = seq; }\n    // alternating DR\n    seq.clear();\n    for (int i = 0; i < 200; i++) seq.push_back((i % 2 == 0) ? 1 : 3);\n    sc = eval_seq(seq);\n    if (sc > bestScore) { bestScore = sc; bestSeq = seq; }\n    // alternating RD\n    seq.clear();\n    for (int i = 0; i < 200; i++) seq.push_back((i % 2 == 0) ? 3 : 1);\n    sc = eval_seq(seq);\n    if (sc > bestScore) { bestScore = sc; bestSeq = seq; }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj, ti, tj;\n    if (!(cin >> si >> sj >> ti >> tj >> p_forget)) return 0;\n    startId = idx(si, sj);\n    targetId = idx(ti, tj);\n    q_exec = 1.0 - p_forget;\n    vector<string> h(H), v(H - 1);\n    for (int i = 0; i < H; i++) cin >> h[i];\n    for (int i = 0; i < H - 1; i++) cin >> v[i];\n    for (int i = 0; i < 200; i++) weightArr[i] = 400 - i;\n    auto time_start = chrono::steady_clock::now();\n\n    build_moves(h, v);\n    compute_dist();\n    vector<int> shortest = bfs_path(false);\n    vector<int> monotone = bfs_path(true);\n\n    double bestScore = -1.0;\n    vector<int> bestSeq;\n\n    // Deterministic greedy with dist and dist^2\n    generate_seq(0.0, dist1, bestScore, bestSeq);\n    generate_seq(0.0, dist2pow, bestScore, bestSeq);\n\n    // Path-based candidates\n    add_repeat_each(shortest, bestScore, bestSeq);\n    add_repeat_each(monotone, bestScore, bestSeq);\n\n    // Ratio-based candidates\n    int dv = ti - si;\n    int dh = tj - sj;\n    add_ratio_candidates(dv, dh, bestScore, bestSeq);\n\n    // Random search\n    int iter = 0;\n    while (true) {\n        if ((iter & 31) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        double eps = uni01(rng) * uni01(rng) * 0.3; // bias towards small\n        const double *distArr = (rng() % 5 == 0) ? dist2pow : dist1; // occasionally use squared\n        generate_seq(eps, distArr, bestScore, bestSeq);\n        iter++;\n    }\n\n    // Output best sequence\n    string out;\n    out.reserve(bestSeq.size());\n    for (int d : bestSeq) {\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        out.push_back(c);\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// weights for the heuristic score\nconst int MATCH_REWARD = 3;\nconst int MISMATCH_PENALTY = 2;\nconst int BOUNDARY_PENALTY = 3;\nconst int PAIR_MATCH_REWARD = 5;\nconst int PAIR_MISMATCH_PENALTY = 4;\n\nint baseType[N][N];\nint rotCnt[N][N];\nint curType[N][N];\n\nint toMap[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};\nint usedMask[8];\nint rotMap[8][4];\nvector<array<int, 2>> pairsOfType[8];\n\ninline int apply_rot(int b, int r) {\n    return rotMap[b][r];\n}\ninline bool uses(int t, int dir) {\n    return (usedMask[t] >> dir) & 1;\n}\n\n// edge contribution for edge from (i,j) in direction dir\ninline int edge_contrib(int i, int j, int dir) {\n    int t = curType[i][j];\n    bool a = uses(t, dir);\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n        return a ? -BOUNDARY_PENALTY : 0;\n    }\n    bool b = uses(curType[ni][nj], dir ^ 2);\n    if (a && b) return MATCH_REWARD;\n    else if (a || b) return -MISMATCH_PENALTY;\n    else return 0;\n}\n\ninline int compute_tile_pair(int i, int j) {\n    int t = curType[i][j];\n    int res = 0;\n    for (auto &pr : pairsOfType[t]) {\n        int a = pr[0], b = pr[1];\n        bool ma = false, mb = false;\n        int ni = i + di[a], nj = j + dj[a];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            ma = uses(curType[ni][nj], a ^ 2);\n        }\n        ni = i + di[b]; nj = j + dj[b];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            mb = uses(curType[ni][nj], b ^ 2);\n        }\n        if (ma && mb) res += PAIR_MATCH_REWARD;\n        else if (ma || mb) res -= PAIR_MISMATCH_PENALTY;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    // precompute used masks and rotation maps and pairs\n    for (int t = 0; t < 8; t++) {\n        int m = 0;\n        for (int d = 0; d < 4; d++) if (toMap[t][d] != -1) m |= (1 << d);\n        usedMask[t] = m;\n    }\n    int nextType[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int b = 0; b < 8; b++) {\n        rotMap[b][0] = b;\n        for (int r = 1; r < 4; r++) {\n            rotMap[b][r] = nextType[rotMap[b][r - 1]];\n        }\n    }\n    for (int t = 0; t < 8; t++) {\n        pairsOfType[t].clear();\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 != -1 && d < d2) pairsOfType[t].push_back({d, d2});\n        }\n    }\n\n    // read input\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) {\n            baseType[i][j] = s[j] - '0';\n        }\n    }\n\n    // initial rotations: try to minimize boundary usage\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int bestR = 0, bestPen = 100;\n            for (int r = 0; r < 4; r++) {\n                int t = apply_rot(baseType[i][j], r);\n                int pen = 0;\n                if (i == 0 && uses(t, 1)) pen++;\n                if (i == N - 1 && uses(t, 3)) pen++;\n                if (j == 0 && uses(t, 0)) pen++;\n                if (j == N - 1 && uses(t, 2)) pen++;\n                if (pen < bestPen) {\n                    bestPen = pen;\n                    bestR = r;\n                }\n            }\n            rotCnt[i][j] = bestR;\n            curType[i][j] = apply_rot(baseType[i][j], bestR);\n        }\n    }\n\n    int edgeScore = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            edgeScore += edge_contrib(i, j, 2);\n            edgeScore += edge_contrib(i, j, 3);\n            if (j == 0) edgeScore += edge_contrib(i, j, 0);\n            if (i == 0) edgeScore += edge_contrib(i, j, 1);\n        }\n    }\n    int pairScore = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pairScore += compute_tile_pair(i, j);\n        }\n    }\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 1.9;\n    double T0 = 5.0, T1 = 0.1;\n    double temp = T0;\n    int iter = 0;\n    while (true) {\n        iter++;\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n            if (elapsed > timeLimit) break;\n            double progress = elapsed / timeLimit;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int newRot = rng() & 3;\n        if (newRot == rotCnt[i][j]) continue;\n        int newType = apply_rot(baseType[i][j], newRot);\n        int oldType = curType[i][j];\n\n        int oldEdges = edge_contrib(i, j, 0) + edge_contrib(i, j, 1) + edge_contrib(i, j, 2) + edge_contrib(i, j, 3);\n        int oldPairs = 0;\n        vector<pair<int, int>> impacted;\n        impacted.reserve(5);\n        impacted.emplace_back(i, j);\n        if (i > 0) impacted.emplace_back(i - 1, j);\n        if (i + 1 < N) impacted.emplace_back(i + 1, j);\n        if (j > 0) impacted.emplace_back(i, j - 1);\n        if (j + 1 < N) impacted.emplace_back(i, j + 1);\n        for (auto &p : impacted) oldPairs += compute_tile_pair(p.first, p.second);\n\n        curType[i][j] = newType;\n        int newEdges = edge_contrib(i, j, 0) + edge_contrib(i, j, 1) + edge_contrib(i, j, 2) + edge_contrib(i, j, 3);\n        int newPairs = 0;\n        for (auto &p : impacted) newPairs += compute_tile_pair(p.first, p.second);\n\n        int delta = (newEdges - oldEdges) + (newPairs - oldPairs);\n\n        if (delta >= 0) {\n            rotCnt[i][j] = newRot;\n            edgeScore += (newEdges - oldEdges);\n            pairScore += (newPairs - oldPairs);\n            // curType already set\n        } else {\n            double prob = exp(double(delta) / temp);\n            double rnd = (double)rng() / (double)rng.max();\n            if (rnd < prob) {\n                rotCnt[i][j] = newRot;\n                edgeScore += (newEdges - oldEdges);\n                pairScore += (newPairs - oldPairs);\n            } else {\n                curType[i][j] = oldType; // revert\n            }\n        }\n    }\n\n    // output rotations\n    string out;\n    out.reserve(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            out.push_back(char('0' + (rotCnt[i][j] & 3)));\n        }\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N;\n    int Tlim;\n    int NN;\n    vector<int> init_board;\n    int init_zero;\n    int full_size;\n    vector<vector<pair<char,int>>> moves_from; // possible moves for each position\n    mt19937 rng;\n    double EPS = 0.2; // probability of random move\n\n    Solver() {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    }\n\n    int hexval(char c){\n        if('0'<=c && c<='9') return c-'0';\n        return 10 + (c-'a');\n    }\n\n    // compute size of largest component that is a tree\n    int compute_tree_size(const vector<int>& b){\n        static vector<char> vis;\n        if((int)vis.size()!=NN) vis.assign(NN,0);\n        else fill(vis.begin(), vis.end(), 0);\n        int max_tree = 0;\n        vector<int> q;\n        q.reserve(NN);\n        for(int idx=0; idx<NN; idx++){\n            if(b[idx]==0 || vis[idx]) continue;\n            q.clear();\n            vis[idx]=1;\n            q.push_back(idx);\n            for(int qi=0; qi<(int)q.size(); qi++){\n                int u = q[qi];\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                // up\n                if(t & 2){\n                    if(r>0){\n                        int v = u - N;\n                        if(b[v]!=0 && (b[v] & 8) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n                // down\n                if(t & 8){\n                    if(r+1<N){\n                        int v = u + N;\n                        if(b[v]!=0 && (b[v] & 2) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n                // left\n                if(t & 1){\n                    if(c>0){\n                        int v = u - 1;\n                        if(b[v]!=0 && (b[v] & 4) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n                // right\n                if(t & 4){\n                    if(c+1<N){\n                        int v = u + 1;\n                        if(b[v]!=0 && (b[v] & 1) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n            }\n            // count edges in this component (undirected) using right/down to avoid double count\n            int edges = 0;\n            for(int u : q){\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(c+1<N){\n                    int v = u + 1;\n                    if(b[v]!=0 && (t & 4) && (b[v] & 1)){\n                        edges++;\n                    }\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(b[v]!=0 && (t & 8) && (b[v] & 2)){\n                        edges++;\n                    }\n                }\n            }\n            int vcnt = (int)q.size();\n            if(edges == vcnt - 1){\n                if(vcnt > max_tree) max_tree = vcnt;\n            }\n        }\n        return max_tree;\n    }\n\n    char inverse_move(char c){\n        if(c=='U') return 'D';\n        if(c=='D') return 'U';\n        if(c=='L') return 'R';\n        if(c=='R') return 'L';\n        return '?';\n    }\n\n    pair<int,string> walk(const chrono::steady_clock::time_point& end_time, int max_steps){\n        vector<int> board = init_board;\n        int zero = init_zero;\n        string moves;\n        moves.reserve(max_steps);\n        string best_seq;\n        int curr_S = compute_tree_size(board);\n        int best_S = curr_S;\n        if(best_S == full_size){\n            // already perfect\n            return {best_S, best_seq};\n        }\n        char prev_move = '?';\n        uniform_real_distribution<double> dist01(0.0,1.0);\n        for(int step=0; step<max_steps; step++){\n            if(chrono::steady_clock::now() > end_time) break;\n            const auto& opts_all = moves_from[zero];\n            vector<pair<char,int>> opts;\n            opts.reserve(4);\n            char inv = inverse_move(prev_move);\n            for(auto &p: opts_all){\n                if(inv==p.first && (int)opts_all.size()>1) continue; // avoid immediate backtrack if possible\n                opts.push_back(p);\n            }\n            if(opts.empty()){\n                opts = opts_all;\n            }\n            char chosen_move;\n            int chosen_delta;\n            int chosen_score;\n            double rnd = dist01(rng);\n            if(rnd < EPS){\n                // random move\n                uniform_int_distribution<int> dist(0, (int)opts.size()-1);\n                int k = dist(rng);\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                curr_S = compute_tree_size(board);\n                chosen_score = curr_S;\n            }else{\n                int best_neighbor = -1;\n                vector<int> best_idx;\n                best_idx.reserve(4);\n                for(int i=0;i<(int)opts.size();i++){\n                    int d = opts[i].second;\n                    swap(board[zero], board[zero+d]);\n                    int s = compute_tree_size(board);\n                    swap(board[zero], board[zero+d]);\n                    if(s > best_neighbor){\n                        best_neighbor = s;\n                        best_idx.clear();\n                        best_idx.push_back(i);\n                    }else if(s == best_neighbor){\n                        best_idx.push_back(i);\n                    }\n                }\n                uniform_int_distribution<int> dist(0, (int)best_idx.size()-1);\n                int k = best_idx[dist(rng)];\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                chosen_score = best_neighbor;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                curr_S = chosen_score;\n            }\n            moves.push_back(chosen_move);\n            prev_move = chosen_move;\n            if(curr_S > best_S){\n                best_S = curr_S;\n                best_seq = moves;\n                if(best_S == full_size){\n                    break;\n                }\n            }\n        }\n        return {best_S, best_seq};\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin >> N >> Tlim;\n        NN = N*N;\n        init_board.resize(NN);\n        for(int i=0;i<N;i++){\n            string s; cin >> s;\n            for(int j=0;j<N;j++){\n                int v = hexval(s[j]);\n                init_board[i*N + j] = v;\n                if(v==0){\n                    init_zero = i*N + j;\n                }\n            }\n        }\n        full_size = NN - 1;\n        // precompute moves from each position\n        moves_from.resize(NN);\n        for(int pos=0; pos<NN; pos++){\n            int r = pos / N;\n            int c = pos - r*N;\n            if(r>0) moves_from[pos].push_back({'U', -N});\n            if(r+1<N) moves_from[pos].push_back({'D', N});\n            if(c>0) moves_from[pos].push_back({'L', -1});\n            if(c+1<N) moves_from[pos].push_back({'R', 1});\n        }\n\n        int init_S = compute_tree_size(init_board);\n        int best_global_S = init_S;\n        string best_global_seq; // empty means no move\n        // time management\n        auto start_time = chrono::steady_clock::now();\n        auto end_time = start_time + chrono::milliseconds(2800); // safety margin\n        // at least one walk\n        while(true){\n            auto now = chrono::steady_clock::now();\n            if(now > end_time) break;\n            auto res = walk(end_time, Tlim);\n            int s = res.first;\n            string seq = res.second;\n            if(s > best_global_S){\n                best_global_S = s;\n                best_global_seq = seq;\n            }else if(s == best_global_S && s == full_size){\n                if(best_global_seq.empty() || seq.size() < best_global_seq.size()){\n                    best_global_seq = seq;\n                }\n            }\n            // if already perfect with zero moves, can break\n            if(best_global_S == full_size && best_global_seq.size()==0) break;\n        }\n\n        cout << best_global_seq << \"\\n\";\n    }\n};\n\nint main(){\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n    vector<int> a(11, 0);\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    vector<pair<int, int>> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].first >> pts[i].second;\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 2.8; // seconds\n\n    int best_obj = -1;\n    vector<int> best_vx, best_vy;\n\n    auto evaluate = [&](int V, int H, int offx, int offy, int stepX, int stepY) {\n        vector<int> vx(V), vy(H);\n        for (int i = 0; i < V; i++) vx[i] = -10000 + offx + stepX * (i + 1);\n        for (int j = 0; j < H; j++) vy[j] = -10000 + offy + stepY * (j + 1);\n\n        vector<int> cnt((V + 1) * (H + 1), 0);\n        for (auto &p : pts) {\n            int x = p.first, y = p.second;\n            if (V > 0 && binary_search(vx.begin(), vx.end(), x)) continue;\n            if (H > 0 && binary_search(vy.begin(), vy.end(), y)) continue;\n            int c = (V > 0) ? (int)(upper_bound(vx.begin(), vx.end(), x) - vx.begin()) : 0;\n            int r = (H > 0) ? (int)(upper_bound(vy.begin(), vy.end(), y) - vy.begin()) : 0;\n            cnt[c * (H + 1) + r]++;\n        }\n        array<int, 11> b{};\n        for (int v : cnt) {\n            if (v > 0 && v <= 10) b[v]++;\n        }\n        int obj = 0;\n        for (int d = 1; d <= 10; d++) obj += min(a[d], b[d]);\n        if (obj > best_obj) {\n            best_obj = obj;\n            best_vx.swap(vx);\n            best_vy.swap(vy);\n        }\n    };\n\n    // candidate counts\n    vector<int> cands = {10, 15, 20, 25, 30, 35, 40, 45, 50};\n    int iter_per = 40;\n\n    // informed target around lambda ~4\n    int target = (int)(sqrt(max(1.0, (double)N / 4.0)) - 1.0);\n    for (int t = target - 5; t <= target + 5; t += 2) {\n        if (t >= 1 && t <= 50) cands.push_back(t);\n    }\n\n    // remove duplicates\n    sort(cands.begin(), cands.end());\n    cands.erase(unique(cands.begin(), cands.end()), cands.end());\n\n    for (int c : cands) {\n        if (2 * c > K) continue;\n        int stepX = max(1, 20000 / (c + 1));\n        int stepY = stepX;\n        for (int it = 0; it < iter_per; it++) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n            int offx = (stepX > 1) ? (int)(rng() % stepX) : 0;\n            int offy = (stepY > 1) ? (int)(rng() % stepY) : 0;\n            evaluate(c, c, offx, offy, stepX, stepY);\n        }\n    }\n\n    // random search\n    while (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < TIME_LIMIT) {\n        int maxL = min(50, K);\n        int V = (int)(rng() % (maxL + 1)); // 0..maxL\n        int Hmax = min(maxL, K - V);\n        if (Hmax < 0) continue;\n        int H = (int)(rng() % (Hmax + 1));\n        if (V + H == 0) continue;\n        if (V + H > K) continue;\n        int stepX = (V > 0) ? max(1, 20000 / (V + 1)) : 1;\n        int stepY = (H > 0) ? max(1, 20000 / (H + 1)) : 1;\n        int offx = (V > 0 && stepX > 1) ? (int)(rng() % stepX) : 0;\n        int offy = (H > 0 && stepY > 1) ? (int)(rng() % stepY) : 0;\n        evaluate(V, H, offx, offy, stepX, stepY);\n    }\n\n    int k = (int)best_vx.size() + (int)best_vy.size();\n    cout << k << \"\\n\";\n    const int BIG = 1000000000;\n    for (int c : best_vx) {\n        cout << c << \" \" << -BIG << \" \" << c << \" \" << BIG << \"\\n\";\n    }\n    for (int y : best_vy) {\n        cout << -BIG << \" \" << y << \" \" << BIG << \" \" << y << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeIndex {\n    int N;\n    int H, V, D1, D2, E;\n    EdgeIndex(int N_) : N(N_) {\n        H = (N - 1) * N;\n        V = H;\n        D1 = (N - 1) * (N - 1);\n        D2 = D1;\n        E = H + V + D1 + D2;\n    }\n    inline int horizId(int x, int y) const { // between (x,y)-(x+1,y)\n        return x + y * (N - 1);\n    }\n    inline int vertId(int x, int y) const { // between (x,y)-(x,y+1)\n        return H + x * (N - 1) + y;\n    }\n    inline int diag1Id(int x, int y) const { // slope 1 between (x,y)-(x+1,y+1)\n        return H + V + x * (N - 1) + y;\n    }\n    inline int diag2Id(int x, int y) const { // slope -1 between (x,y)-(x+1,y-1), y>=1\n        return H + V + D1 + x * (N - 1) + (y - 1);\n    }\n    inline int id(int x1, int y1, int x2, int y2) const {\n        int dx = x2 - x1;\n        int dy = y2 - y1;\n        if (abs(dx) + abs(dy) == 1) { // axis neighbor\n            if (dy == 0) {\n                int x = min(x1, x2), y = y1;\n                return horizId(x, y);\n            } else {\n                int y = min(y1, y2), x = x1;\n                return vertId(x, y);\n            }\n        } else if (abs(dx) == 1 && abs(dy) == 1) { // diagonal neighbor\n            if (dx == dy) { // slope 1\n                int x = min(x1, x2), y = min(y1, y2);\n                return diag1Id(x, y);\n            } else { // slope -1\n                int x = min(x1, x2), y = max(y1, y2);\n                return diag2Id(x, y);\n            }\n        }\n        return -1; // not an allowed edge\n    }\n};\n\nstruct Cand {\n    uint8_t type; // 0: square, 1: diamond\n    uint8_t miss; // missing corner index 0..3\n    uint16_t a, b; // anchor (square) or center (diamond)\n    int w; // weight of missing point\n};\n\nstruct CompWeight {\n    bool operator()(const Cand &a, const Cand &b) const {\n        return a.w < b.w; // max-heap\n    }\n};\n\nclass Pool {\n    int mode; // 0 weight,1 fifo,2 random\n    priority_queue<Cand, vector<Cand>, CompWeight> pq;\n    deque<Cand> dq;\n    vector<Cand> vec;\n    mt19937 rng;\npublic:\n    Pool(int m, uint32_t seed) : mode(m), rng(seed) {}\n    void push(const Cand &c) {\n        if (mode == 0) pq.push(c);\n        else if (mode == 1) dq.push_back(c);\n        else vec.push_back(c);\n    }\n    bool empty() const {\n        if (mode == 0) return pq.empty();\n        if (mode == 1) return dq.empty();\n        return vec.empty();\n    }\n    Cand pop() {\n        if (mode == 0) {\n            Cand c = pq.top(); pq.pop(); return c;\n        } else if (mode == 1) {\n            Cand c = dq.front(); dq.pop_front(); return c;\n        } else {\n            int idx = (int)(rng() % vec.size());\n            Cand c = vec[idx];\n            vec[idx] = vec.back();\n            vec.pop_back();\n            return c;\n        }\n    }\n};\n\nstruct Result {\n    long long totalWeight;\n    vector<array<int,8>> ops;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> initialDots(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initialDots[i] = {x, y};\n    }\n    EdgeIndex EI(N);\n    int NN = N * N;\n    vector<int> weight(NN);\n    int c = (N - 1) / 2;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            int dx = x - c, dy = y - c;\n            weight[x * N + y] = dx * dx + dy * dy + 1;\n        }\n    }\n    vector<char> initialHasDot(NN, 0);\n    long long initSum = 0;\n    for (auto &p : initialDots) {\n        int id = p.first * N + p.second;\n        if (!initialHasDot[id]) {\n            initialHasDot[id] = 1;\n            initSum += weight[id];\n        }\n    }\n\n    auto simulate = [&](int mode, uint32_t seed)->Result {\n        vector<char> hasDot = initialHasDot;\n        vector<char> used(EI.E, 0);\n        long long total = initSum;\n        vector<array<int,8>> ops;\n        Pool pool(mode, seed);\n\n        auto evalSquare = [&](int ax, int ay) {\n            int x = ax, y = ay;\n            int id0 = (x) * N + y;\n            int id1 = (x + 1) * N + y;\n            int id2 = (x + 1) * N + (y + 1);\n            int id3 = (x) * N + (y + 1);\n            int cnt = hasDot[id0] + hasDot[id1] + hasDot[id2] + hasDot[id3];\n            if (cnt != 3) return;\n            int miss = -1;\n            if (!hasDot[id0]) miss = 0;\n            else if (!hasDot[id1]) miss = 1;\n            else if (!hasDot[id2]) miss = 2;\n            else if (!hasDot[id3]) miss = 3;\n            else return;\n            int e0 = EI.id(x, y, x + 1, y);\n            int e1 = EI.id(x + 1, y, x + 1, y + 1);\n            int e2 = EI.id(x + 1, y + 1, x, y + 1);\n            int e3 = EI.id(x, y + 1, x, y);\n            if (used[e0] || used[e1] || used[e2] || used[e3]) return;\n            int mid;\n            if (miss == 0) mid = id0;\n            else if (miss == 1) mid = id1;\n            else if (miss == 2) mid = id2;\n            else mid = id3;\n            Cand cand{0, (uint8_t)miss, (uint16_t)ax, (uint16_t)ay, weight[mid]};\n            pool.push(cand);\n        };\n        auto evalDiamond = [&](int cx, int cy) {\n            int id0 = (cx + 1) * N + cy;     // right\n            int id1 = (cx) * N + (cy + 1);   // up\n            int id2 = (cx - 1) * N + cy;     // left\n            int id3 = (cx) * N + (cy - 1);   // down\n            int cnt = hasDot[id0] + hasDot[id1] + hasDot[id2] + hasDot[id3];\n            if (cnt != 3) return;\n            int miss = -1;\n            if (!hasDot[id0]) miss = 0;\n            else if (!hasDot[id1]) miss = 1;\n            else if (!hasDot[id2]) miss = 2;\n            else if (!hasDot[id3]) miss = 3;\n            else return;\n            int e0 = EI.id(cx + 1, cy, cx, cy + 1);\n            int e1 = EI.id(cx, cy + 1, cx - 1, cy);\n            int e2 = EI.id(cx - 1, cy, cx, cy - 1);\n            int e3 = EI.id(cx, cy - 1, cx + 1, cy);\n            if (used[e0] || used[e1] || used[e2] || used[e3]) return;\n            int mid;\n            if (miss == 0) mid = id0;\n            else if (miss == 1) mid = id1;\n            else if (miss == 2) mid = id2;\n            else mid = id3;\n            Cand cand{1, (uint8_t)miss, (uint16_t)cx, (uint16_t)cy, weight[mid]};\n            pool.push(cand);\n        };\n\n        // initial scan\n        for (int ax = 0; ax < N - 1; ax++) {\n            for (int ay = 0; ay < N - 1; ay++) {\n                evalSquare(ax, ay);\n            }\n        }\n        for (int cx = 1; cx < N - 1; cx++) {\n            for (int cy = 1; cy < N - 1; cy++) {\n                evalDiamond(cx, cy);\n            }\n        }\n\n        auto addNeighbors = [&](int x, int y) {\n            for (int dx = -1; dx <= 0; dx++) {\n                for (int dy = -1; dy <= 0; dy++) {\n                    int ax = x + dx;\n                    int ay = y + dy;\n                    if (0 <= ax && ax < N - 1 && 0 <= ay && ay < N - 1) {\n                        evalSquare(ax, ay);\n                    }\n                }\n            }\n            int cx, cy;\n            cx = x + 1; cy = y;\n            if (1 <= cx && cx <= N - 2 && 1 <= cy && cy <= N - 2) evalDiamond(cx, cy);\n            cx = x - 1; cy = y;\n            if (1 <= cx && cx <= N - 2 && 1 <= cy && cy <= N - 2) evalDiamond(cx, cy);\n            cx = x; cy = y + 1;\n            if (1 <= cx && cx <= N - 2 && 1 <= cy && cy <= N - 2) evalDiamond(cx, cy);\n            cx = x; cy = y - 1;\n            if (1 <= cx && cx <= N - 2 && 1 <= cy && cy <= N - 2) evalDiamond(cx, cy);\n        };\n\n        while (!pool.empty()) {\n            Cand cand = pool.pop();\n            if (cand.type == 0) {\n                int ax = cand.a, ay = cand.b;\n                int x0 = ax, y0 = ay;\n                int id[4] = {\n                    (x0) * N + y0,\n                    (x0 + 1) * N + y0,\n                    (x0 + 1) * N + (y0 + 1),\n                    (x0) * N + (y0 + 1)\n                };\n                if (hasDot[id[cand.miss]]) continue;\n                int cnt = hasDot[id[0]] + hasDot[id[1]] + hasDot[id[2]] + hasDot[id[3]];\n                if (cnt != 3) continue;\n                // check other three present\n                bool ok = true;\n                for (int k = 0; k < 4; k++) {\n                    if (k == cand.miss) continue;\n                    if (!hasDot[id[k]]) { ok = false; break; }\n                }\n                if (!ok) continue;\n                int e0 = EI.id(x0, y0, x0 + 1, y0);\n                int e1 = EI.id(x0 + 1, y0, x0 + 1, y0 + 1);\n                int e2 = EI.id(x0 + 1, y0 + 1, x0, y0 + 1);\n                int e3 = EI.id(x0, y0 + 1, x0, y0);\n                if (used[e0] || used[e1] || used[e2] || used[e3]) continue;\n                // perform\n                int mx = (cand.miss == 0 || cand.miss == 3) ? x0 : x0 + 1;\n                int my = (cand.miss == 0 || cand.miss == 1) ? y0 : y0 + 1;\n                hasDot[id[cand.miss]] = 1;\n                total += weight[id[cand.miss]];\n                used[e0] = used[e1] = used[e2] = used[e3] = 1;\n                array<int,8> op;\n                int order[4] = {0,1,2,3};\n                for (int i = 0; i < 4; i++) {\n                    int idx = (cand.miss + i) % 4;\n                    int ox, oy;\n                    if (idx == 0) { ox = x0; oy = y0; }\n                    else if (idx == 1) { ox = x0 + 1; oy = y0; }\n                    else if (idx == 2) { ox = x0 + 1; oy = y0 + 1; }\n                    else { ox = x0; oy = y0 + 1; }\n                    op[2 * i] = ox;\n                    op[2 * i + 1] = oy;\n                }\n                ops.push_back(op);\n                addNeighbors(mx, my);\n            } else {\n                int cx = cand.a, cy = cand.b;\n                int id[4] = {\n                    (cx + 1) * N + cy,\n                    (cx) * N + (cy + 1),\n                    (cx - 1) * N + cy,\n                    (cx) * N + (cy - 1)\n                };\n                if (hasDot[id[cand.miss]]) continue;\n                int cnt = hasDot[id[0]] + hasDot[id[1]] + hasDot[id[2]] + hasDot[id[3]];\n                if (cnt != 3) continue;\n                bool ok = true;\n                for (int k = 0; k < 4; k++) {\n                    if (k == cand.miss) continue;\n                    if (!hasDot[id[k]]) { ok = false; break; }\n                }\n                if (!ok) continue;\n                int e0 = EI.id(cx + 1, cy, cx, cy + 1);\n                int e1 = EI.id(cx, cy + 1, cx - 1, cy);\n                int e2 = EI.id(cx - 1, cy, cx, cy - 1);\n                int e3 = EI.id(cx, cy - 1, cx + 1, cy);\n                if (used[e0] || used[e1] || used[e2] || used[e3]) continue;\n                int mx, my;\n                if (cand.miss == 0) { mx = cx + 1; my = cy; }\n                else if (cand.miss == 1) { mx = cx; my = cy + 1; }\n                else if (cand.miss == 2) { mx = cx - 1; my = cy; }\n                else { mx = cx; my = cy - 1; }\n                hasDot[id[cand.miss]] = 1;\n                total += weight[id[cand.miss]];\n                used[e0] = used[e1] = used[e2] = used[e3] = 1;\n                array<int,8> op;\n                for (int i = 0; i < 4; i++) {\n                    int idx = (cand.miss + i) % 4;\n                    int ox, oy;\n                    if (idx == 0) { ox = cx + 1; oy = cy; }\n                    else if (idx == 1) { ox = cx; oy = cy + 1; }\n                    else if (idx == 2) { ox = cx - 1; oy = cy; }\n                    else { ox = cx; oy = cy - 1; }\n                    op[2 * i] = ox;\n                    op[2 * i + 1] = oy;\n                }\n                ops.push_back(op);\n                addNeighbors(mx, my);\n            }\n        }\n        return {total, std::move(ops)};\n    };\n\n    // generate seeds\n    uint64_t seedBase = 1234567;\n    seedBase = seedBase * 1000003 + N;\n    seedBase = seedBase * 1000003 + M;\n    for (auto &p : initialDots) {\n        seedBase ^= (uint64_t)(p.first + 1) * 10007 + (uint64_t)(p.second + 1) * 1000003 + 12345;\n        seedBase = seedBase * 1000003 + 1;\n    }\n\n    vector<pair<int,uint32_t>> configs;\n    configs.push_back({0, (uint32_t)(seedBase & 0xffffffffu)}); // weight\n    configs.push_back({1, (uint32_t)((seedBase + 1013904223) & 0xffffffffu)}); // fifo\n    int randomTrials = 4;\n    for (int i = 0; i < randomTrials; i++) {\n        configs.push_back({2, (uint32_t)((seedBase + 1812433253ull * (i+1)) & 0xffffffffu)});\n    }\n\n    Result best{initSum, {}};\n    for (auto &cfg : configs) {\n        Result res = simulate(cfg.first, cfg.second);\n        if (res.totalWeight > best.totalWeight) {\n            best = std::move(res);\n        }\n    }\n\n    cout << best.ops.size() << \"\\n\";\n    for (auto &op : best.ops) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Board = array<array<int, 10>, 10>;\n\n// simulate tilting the board to one direction\nBoard tiltBoard(const Board &b, int dir) {\n    Board res;\n    for (auto &row : res) row.fill(0);\n    if (dir == 0) {  // F : up\n        for (int c = 0; c < 10; c++) {\n            int pos = 0;\n            for (int r = 0; r < 10; r++) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 1) {  // B : down\n        for (int c = 0; c < 10; c++) {\n            int pos = 9;\n            for (int r = 9; r >= 0; r--) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 2) {  // L : left\n        for (int r = 0; r < 10; r++) {\n            int pos = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else {  // R : right\n        for (int r = 0; r < 10; r++) {\n            int pos = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    }\n    return res;\n}\n\n// compute sum of squared component sizes (numerator of the objective)\nint scoreBoard(const Board &b) {\n    bool vis[10][10] = {};\n    int dr[4] = {-1, 1, 0, 0};\n    int dc[4] = {0, 0, -1, 1};\n    int score = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            if (b[r][c] == 0 || vis[r][c]) continue;\n            int col = b[r][c];\n            queue<pair<int, int>> q;\n            q.push({r, c});\n            vis[r][c] = true;\n            int sz = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front();\n                q.pop();\n                sz++;\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dr[k], ny = y + dc[k];\n                    if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;\n                    if (vis[nx][ny]) continue;\n                    if (b[nx][ny] != col) continue;\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n            score += sz * sz;\n        }\n    }\n    return score;\n}\n\n// sum of Manhattan distances to assigned targets (used for tie-breaking)\nint distSum(const Board &b, const array<pair<int, int>, 4> &target) {\n    int sum = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            int col = b[r][c];\n            if (col == 0) continue;\n            auto [tr, tc] = target[col];\n            sum += abs(r - tr) + abs(c - tc);\n        }\n    }\n    return sum;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n\n    Board cur;\n    for (auto &row : cur) row.fill(0);\n\n    // assign target corners for each flavor (1..3)\n    array<pair<int, int>, 4> target;\n    target[0] = {0, 0};\n    target[1] = {0, 0};  // flavor 1 -> top-left\n    target[2] = {0, 9};  // flavor 2 -> top-right\n    target[3] = {9, 0};  // flavor 3 -> bottom-left\n\n    const char dirChar[4] = {'F', 'B', 'L', 'R'};\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        if (!(cin >> p)) break;\n\n        // place the new candy at the p-th empty cell (row-major order)\n        int cnt = 0;\n        int pr = -1, pc = -1;\n        for (int r = 0; r < 10; r++) {\n            for (int c = 0; c < 10; c++) {\n                if (cur[r][c] == 0) {\n                    cnt++;\n                    if (cnt == p) {\n                        pr = r;\n                        pc = c;\n                        goto placed;\n                    }\n                }\n            }\n        }\n    placed:\n        if (pr == -1) {\n            pr = 0;\n            pc = 0;\n        }\n        cur[pr][pc] = flavors[t];\n\n        int bestDir = 0;\n        pair<int, int> bestVal = make_pair(-1000000000, -1000000000);\n        Board bestBoard;\n\n        for (int dir = 0; dir < 4; dir++) {\n            Board nb = tiltBoard(cur, dir);\n            int sc = scoreBoard(nb);\n            int dsum = distSum(nb, target);\n            pair<int, int> val = make_pair(sc, -dsum);\n            if (val > bestVal) {\n                bestVal = val;\n                bestDir = dir;\n                bestBoard = nb;\n            }\n        }\n\n        // output chosen direction\n        cout << dirChar[bestDir] << '\\n' << flush;\n\n        // update current board\n        cur = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GraphData {\n    int N;\n    vector<vector<uint8_t>> adj; // NxN\n    vector<int> deg, f1, f2, tri;\n    vector<int> sortedDeg;\n};\n\nvoid compute_features(GraphData &g){\n    int N = g.N;\n    g.deg.assign(N,0);\n    g.f1.assign(N,0);\n    g.f2.assign(N,0);\n    g.tri.assign(N,0);\n    // degree\n    for(int i=0;i<N;i++){\n        int d=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) d++;\n        g.deg[i]=d;\n    }\n    // f1\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.deg[j];\n        g.f1[i]=s;\n    }\n    // f2\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.f1[j];\n        g.f2[i]=s;\n    }\n    // triangles per vertex (naive)\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++) if(g.adj[i][j]){\n            for(int k=j+1;k<N;k++) if(g.adj[i][k] && g.adj[j][k]){\n                g.tri[i]++; g.tri[j]++; g.tri[k]++;\n            }\n        }\n    }\n    g.sortedDeg = g.deg;\n    sort(g.sortedDeg.begin(), g.sortedDeg.end());\n}\n\n// Hungarian algorithm for minimum cost assignment\nvector<int> hungarian(const vector<vector<double>> &a){\n    int n = (int)a.size();\n    int m = n;\n    const double INF = 1e18;\n    vector<double> u(n+1), v(m+1);\n    vector<int> p(m+1), way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;\n        int j0=0;\n        vector<double> minv(m+1, INF);\n        vector<char> used(m+1, false);\n        do{\n            used[j0]=true;\n            int i0 = p[j0];\n            double delta = INF;\n            int j1 = 0;\n            for(int j=1;j<=m;j++) if(!used[j]){\n                double cur = a[i0-1][j-1] - u[i0] - v[j];\n                if(cur < minv[j]){\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if(minv[j] < delta){\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for(int j=0;j<=m;j++){\n                if(used[j]){\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                }else{\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        }while(p[j0]!=0);\n        // augmenting\n        do{\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        }while(j0);\n    }\n    vector<int> assignment(n, -1); // row -> col\n    for(int j=1;j<=m;j++){\n        if(p[j]>0 && p[j]<=n) assignment[p[j]-1] = j-1;\n    }\n    return assignment;\n}\n\nint degree_distance(const vector<int>& a, const vector<int>& b){\n    int n=a.size();\n    int s=0;\n    for(int i=0;i<n;i++) s += abs(a[i]-b[i]);\n    return s;\n}\n\nint compute_mismatch(const vector<vector<uint8_t>>& H, const vector<vector<uint8_t>>& G, const vector<int>& assign, int bestLimit){\n    int n = assign.size();\n    int mism=0;\n    for(int i=0;i<n;i++){\n        int gi = assign[i];\n        for(int j=i+1;j<n;j++){\n            int gj = assign[j];\n            if(H[i][j] != G[gi][gj]) mism++;\n        }\n        if(mism >= bestLimit) return mism;\n    }\n    return mism;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n    // decide N\n    int N = 25 + int(60.0*eps + 0.5);\n    if(M > 80) N += 5;\n    else if(M > 50) N += 2;\n    if(M < 30) N -= 3;\n    if(eps > 0.30) N += 4;\n    N = max(4, min(100, N));\n    int Kcap = 30;\n    int K = min(M, max(5, min(Kcap, (int)(eps*75.0)+5)));\n    // generate graphs\n    mt19937 rng(1234567);\n    vector<GraphData> graphs(M);\n    for(int k=0;k<M;k++){\n        GraphData g;\n        g.N = N;\n        g.adj.assign(N, vector<uint8_t>(N,0));\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                bool e = (rng() & 1);\n                g.adj[i][j]=g.adj[j][i]= e;\n            }\n        }\n        compute_features(g);\n        graphs[k]=move(g);\n    }\n    // output graphs\n    cout<<N<<\"\\n\";\n    int E = N*(N-1)/2;\n    string line;\n    line.reserve(E);\n    for(int k=0;k<M;k++){\n        line.clear();\n        line.reserve(E);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                line.push_back(graphs[k].adj[i][j] ? '1' : '0');\n            }\n        }\n        cout<<line<<\"\\n\";\n    }\n    cout.flush();\n    // process queries\n    vector<vector<uint8_t>> HAdj(N, vector<uint8_t>(N,0));\n    GraphData HG;\n    HG.N = N;\n    for(int qi=0; qi<100; qi++){\n        string hstr;\n        if(!(cin>>hstr)) break;\n        // build adjacency\n        int idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                char c = hstr[idx++];\n                uint8_t v = (c=='1');\n                HAdj[i][j]=HAdj[j][i]=v;\n            }\n        }\n        HG.adj = HAdj;\n        compute_features(HG);\n        // distances for pruning\n        vector<pair<int,int>> distIdx;\n        distIdx.reserve(M);\n        for(int k=0;k<M;k++){\n            int d = degree_distance(HG.sortedDeg, graphs[k].sortedDeg);\n            distIdx.emplace_back(d, k);\n        }\n        nth_element(distIdx.begin(), distIdx.begin()+K, distIdx.end(),\n                    [](auto &a, auto &b){ return a.first < b.first; });\n        distIdx.resize(K);\n        sort(distIdx.begin(), distIdx.end()); // optional\n        int bestMismatch = N*N; // upper bound\n        int bestIdx = distIdx[0].second;\n        // precompute weight factors\n        double s = 1.0 - 2.0*eps;\n        if(s < 0.05) s = 0.05;\n        double w1 = s;\n        double w2 = s*s;\n        double w3 = s;\n        double invN = 1.0 / (double)N;\n        double invNN = 1.0 / ((double)N*(double)N);\n        // candidate evaluation\n        vector<vector<double>> cost(N, vector<double>(N));\n        for(auto &dk : distIdx){\n            int k = dk.second;\n            // build cost matrix\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    double c = abs(HG.deg[i] - graphs[k].deg[j]);\n                    c += w1 * (double)abs(HG.f1[i] - graphs[k].f1[j]) * invN;\n                    c += w2 * (double)abs(HG.f2[i] - graphs[k].f2[j]) * invNN;\n                    c += w3 * (double)abs(HG.tri[i] - graphs[k].tri[j]) * invN;\n                    cost[i][j]=c;\n                }\n            }\n            vector<int> assign = hungarian(cost); // H row -> G col\n            int mism = compute_mismatch(HAdj, graphs[k].adj, assign, bestMismatch);\n            if(mism < bestMismatch){\n                bestMismatch = mism;\n                bestIdx = k;\n            }\n        }\n        cout<<bestIdx<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\n// Dijkstra that skips one edge\nlong long dijkstra_skip(int s, int t, int skip_id,\n                        const vector<vector<Adj>> &adj,\n                        vector<long long> &dist) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        if (u == t) break;\n        for (auto &e : adj[u]) {\n            if (e.id == skip_id) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n    return dist[t];\n}\n\n// Dijkstra that records one parent edge (shortest path tree)\nvoid dijkstra_parent(int s, const vector<vector<Adj>> &adj,\n                     vector<long long> &dist, vector<int> &parent) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    fill(parent.begin(), parent.end(), -1);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                parent[e.to] = e.id;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u;\n        --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    // read coordinates (not used)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<long long> dist(N);\n    vector<long long> altDiff(M);\n    for (int i = 0; i < M; i++) {\n        auto &e = edges[i];\n        long long alt = dijkstra_skip(e.u, e.v, i, adj, dist);\n        if (alt >= (1LL << 59)) {\n            altDiff[i] = 0;  // fallback\n        } else {\n            altDiff[i] = alt - e.w;\n            if (altDiff[i] < 0) altDiff[i] = 0;\n        }\n    }\n\n    int S = min(N, 30);\n    vector<int> sources;\n    int step = max(1, N / S);\n    for (int i = 0; i < N && (int)sources.size() < S; i += step) {\n        sources.push_back(i);\n    }\n    while ((int)sources.size() < S) sources.push_back((int)sources.size());\n    vector<int> centrality(M, 0);\n    vector<int> parent(N);\n    for (int s : sources) {\n        dijkstra_parent(s, adj, dist, parent);\n        for (int v = 0; v < N; v++) {\n            if (v == s) continue;\n            int pe = parent[v];\n            if (pe >= 0) centrality[pe]++;\n        }\n    }\n\n    vector<long double> importance(M);\n    long double sumImp = 0;\n    for (int i = 0; i < M; i++) {\n        long double imp = (long double)altDiff[i] * ((long double)centrality[i] + 1.0L);\n        importance[i] = imp;\n        sumImp += imp;\n    }\n    long double avgImp = sumImp / (long double)max(1, M);\n    long double alpha = avgImp * 0.5L;\n    if (alpha < 1e-6) alpha = 1.0L;\n\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (importance[a] == importance[b]) return a < b;\n        return importance[a] > importance[b];\n    });\n\n    vector<int> answer(M, 0);\n    vector<long double> dayLoad(D, 0.0L);\n    vector<int> dayCount(D, 0);\n    vector<vector<uint16_t>> vtxCount(N, vector<uint16_t>(D, 0));\n\n    auto chooseDay = [&](int u, int v) -> int {\n        long double bestCost = 1e100;\n        int bestDay = -1;\n        for (int d = 0; d < D; d++) {\n            if (dayCount[d] >= K) continue;\n            int s1 = (int)vtxCount[u][d] + (int)vtxCount[v][d];\n            long double cost = dayLoad[d] + alpha * (long double)s1;\n            if (cost < bestCost - 1e-9L) {\n                bestCost = cost;\n                bestDay = d;\n            } else if (fabsl(cost - bestCost) <= 1e-9L) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay] ||\n                    (dayCount[d] == dayCount[bestDay] && d < bestDay)) {\n                    bestDay = d;\n                }\n            }\n        }\n        if (bestDay == -1) {\n            // should not happen, but fallback\n            for (int d = 0; d < D; d++) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay]) bestDay = d;\n            }\n        }\n        return bestDay;\n    };\n\n    // initial assignment\n    for (int eid : order) {\n        int u = edges[eid].u;\n        int v = edges[eid].v;\n        int d = chooseDay(u, v);\n        answer[eid] = d + 1;\n        dayLoad[d] += importance[eid];\n        dayCount[d]++;\n        vtxCount[u][d]++;\n        vtxCount[v][d]++;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int improvePasses = 1;\n    for (int pass = 0; pass < improvePasses; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.5) break;  // time guard\n        for (int eid : order) {\n            int curr = answer[eid] - 1;\n            int u = edges[eid].u;\n            int v = edges[eid].v;\n            long double imp = importance[eid];\n            // remove\n            dayLoad[curr] -= imp;\n            dayCount[curr]--;\n            vtxCount[u][curr]--;\n            vtxCount[v][curr]--;\n            // choose best day again\n            int nd = chooseDay(u, v);\n            answer[eid] = nd + 1;\n            dayLoad[nd] += imp;\n            dayCount[nd]++;\n            vtxCount[u][nd]++;\n            vtxCount[v][nd]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << answer[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Positions {\n    vector<tuple<int,int,int>> pos; // (x,y,z)\n};\n\nPositions build_positions(const vector<string>& f, const vector<string>& r, int D){\n    Positions res;\n    for(int z=0; z<D; z++){\n        vector<int> Fx, Ry;\n        for(int x=0; x<D; x++) if(f[z][x]=='1') Fx.push_back(x);\n        for(int y=0; y<D; y++) if(r[z][y]=='1') Ry.push_back(y);\n        if(Fx.empty() || Ry.empty()) continue; // should not happen per constraints\n        if((int)Fx.size() >= (int)Ry.size()){\n            int ry = Ry.size();\n            for(int i=0;i<ry;i++){\n                res.pos.emplace_back(Fx[i], Ry[i], z);\n            }\n            for(int j=ry;j<(int)Fx.size();j++){\n                res.pos.emplace_back(Fx[j], Ry[0], z);\n            }\n        }else{\n            int fx = Fx.size();\n            for(int i=0;i<fx;i++){\n                res.pos.emplace_back(Fx[i], Ry[i], z);\n            }\n            for(int j=fx;j<(int)Ry.size();j++){\n                res.pos.emplace_back(Fx[0], Ry[j], z);\n            }\n        }\n    }\n    return res;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if(!(cin>>D)) return 0;\n    vector<string> f[2], r[2];\n    for(int i=0;i<2;i++){\n        f[i].resize(D);\n        for(int z=0; z<D; z++) cin>>f[i][z];\n        r[i].resize(D);\n        for(int z=0; z<D; z++) cin>>r[i][z];\n    }\n\n    Positions P1 = build_positions(f[0], r[0], D);\n    Positions P2 = build_positions(f[1], r[1], D);\n    int N1 = (int)P1.pos.size();\n    int N2 = (int)P2.pos.size();\n    int k = min(N1, N2);\n    int n = max(N1, N2);\n\n    vector<int> out1(D*D*D, 0), out2(D*D*D, 0);\n\n    auto idx = [D](int x,int y,int z)->int{\n        return x*D*D + y*D + z;\n    };\n\n    // shared blocks\n    for(int i=0;i<k;i++){\n        int id = i+1;\n        auto [x1,y1,z1] = P1.pos[i];\n        auto [x2,y2,z2] = P2.pos[i];\n        out1[idx(x1,y1,z1)] = id;\n        out2[idx(x2,y2,z2)] = id;\n    }\n    int id = k+1;\n    if(N1 > k){\n        for(int i=k; i<N1; i++){\n            auto [x,y,z] = P1.pos[i];\n            out1[idx(x,y,z)] = id;\n            id++;\n        }\n    }\n    if(N2 > k){\n        for(int i=k; i<N2; i++){\n            auto [x,y,z] = P2.pos[i];\n            out2[idx(x,y,z)] = id;\n            id++;\n        }\n    }\n    // Sanity: id-1 should equal n\n    // Output\n    cout << n << \"\\n\";\n    for(int i=0;i<D*D*D;i++){\n        if(i) cout << ' ';\n        cout << out1[i];\n    }\n    cout << \"\\n\";\n    for(int i=0;i<D*D*D;i++){\n        if(i) cout << ' ';\n        cout << out2[i];\n    }\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeAdj {\n    int to;\n    int id;\n    long long w;\n};\n\nstruct DSU {\n    vector<int> p;\n    DSU(int n) : p(n, -1) {}\n    int find(int x) {\n        if (p[x] < 0) return x;\n        return p[x] = find(p[x]);\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (p[a] > p[b]) swap(a, b);\n        p[a] += p[b];\n        p[b] = a;\n        return true;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    long long cost;\n};\n\nint ceil_sqrt_ll(long long x) {\n    if (x <= 0) return 0;\n    int r = (int)std::sqrt((long double)x);\n    while (1LL * r * r < x) r++;\n    while (r > 0 && 1LL * (r - 1) * (r - 1) >= x) r--;\n    return r;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<long long> W(M);\n    vector<vector<EdgeAdj>> g(N);\n    for (int j = 0; j < M; j++) {\n        int u, v;\n        long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        U[j] = u; V[j] = v; W[j] = w;\n        g[u].push_back({v, j, w});\n        g[v].push_back({u, j, w});\n    }\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n\n    const int LIMIT = 5000;\n    const int LIMIT2 = LIMIT * LIMIT;\n\n    // precompute squared distances and within lists\n    vector<vector<int>> dist2(N, vector<int>(K));\n    vector<vector<int>> within(N);\n    for (int i = 0; i < N; i++) {\n        within[i].reserve(K / 4);\n        for (int k = 0; k < K; k++) {\n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            long long d2 = dx * dx + dy * dy;\n            dist2[i][k] = (int)d2;\n            if (d2 <= LIMIT2) within[i].push_back(k);\n        }\n    }\n\n    // greedy selection to cover all residents\n    vector<char> selected(N, false);\n    vector<char> covered(K, false);\n    int uncovered = K;\n    selected[0] = true; // include root\n    while (uncovered > 0) {\n        int best = -1;\n        int bestCount = 0;\n        for (int i = 0; i < N; i++) {\n            if (selected[i]) continue;\n            int cnt = 0;\n            for (int idx : within[i]) if (!covered[idx]) cnt++;\n            if (cnt > bestCount) {\n                bestCount = cnt;\n                best = i;\n            }\n        }\n        if (best == -1 || bestCount == 0) break;\n        selected[best] = true;\n        for (int idx : within[best]) {\n            if (!covered[idx]) {\n                covered[idx] = true;\n                uncovered--;\n            }\n        }\n    }\n    if (uncovered > 0) {\n        // fallback: cover remaining\n        for (int k = 0; k < K && uncovered > 0; k++) {\n            if (covered[k]) continue;\n            int bestv = -1;\n            int bestd = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                int d = dist2[i][k];\n                if (d <= LIMIT2 && d < bestd) {\n                    bestd = d;\n                    bestv = i;\n                }\n            }\n            if (bestv == -1) {\n                for (int i = 0; i < N; i++) {\n                    int d = dist2[i][k];\n                    if (d < bestd) {\n                        bestd = d;\n                        bestv = i;\n                    }\n                }\n            }\n            if (!selected[bestv]) selected[bestv] = true;\n            for (int idx : within[bestv]) {\n                if (!covered[idx]) {\n                    covered[idx] = true;\n                    uncovered--;\n                }\n            }\n        }\n    }\n\n    // remove redundant selected nodes\n    vector<int> coverCount(K, 0);\n    for (int k = 0; k < K; k++) {\n        int cnt = 0;\n        for (int i = 0; i < N; i++) {\n            if (selected[i] && dist2[i][k] <= LIMIT2) cnt++;\n        }\n        coverCount[k] = cnt;\n    }\n    for (int i = 1; i < N; i++) { // keep root\n        if (!selected[i]) continue;\n        bool redundant = true;\n        for (int k = 0; k < K; k++) {\n            if (dist2[i][k] <= LIMIT2 && coverCount[k] <= 1) {\n                redundant = false;\n                break;\n            }\n        }\n        if (redundant) {\n            selected[i] = false;\n            for (int k = 0; k < K; k++) {\n                if (dist2[i][k] <= LIMIT2) coverCount[k]--;\n            }\n        }\n    }\n\n    // compute all-pairs shortest paths (distMat) and parentEdge for path reconstruction\n    const long long INFLL = (1LL << 60);\n    vector<vector<long long>> distMat(N, vector<long long>(N, INFLL));\n    vector<vector<int>> parentEdge(N, vector<int>(N, -1));\n    using PLLI = pair<long long, int>;\n    for (int s = 0; s < N; s++) {\n        vector<long long> d(N, INFLL);\n        vector<int> p(N, -1);\n        d[s] = 0;\n        priority_queue<PLLI, vector<PLLI>, greater<PLLI>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cd, v] = pq.top();\n            pq.pop();\n            if (cd != d[v]) continue;\n            for (auto &e : g[v]) {\n                long long nd = cd + e.w;\n                if (nd < d[e.to]) {\n                    d[e.to] = nd;\n                    p[e.to] = e.id;\n                    pq.push({nd, e.to});\n                }\n            }\n        }\n        distMat[s] = move(d);\n        parentEdge[s] = move(p);\n    }\n\n    // prepare allowed node lists\n    vector<int> allowedSel;\n    allowedSel.reserve(N);\n    for (int i = 0; i < N; i++) if (selected[i]) allowedSel.push_back(i);\n    vector<int> allowedAll(N);\n    iota(allowedAll.begin(), allowedAll.end(), 0);\n\n    // augmented allowed based on threshold\n    int TH = 3500;\n    int TH2 = TH * TH;\n    vector<char> allowFlag(N, false);\n    for (int v : allowedSel) allowFlag[v] = true;\n    for (int k = 0; k < K; k++) {\n        int bestd = INT_MAX;\n        for (int v : allowedSel) {\n            int d = dist2[v][k];\n            if (d < bestd) bestd = d;\n        }\n        if (bestd > TH2) {\n            int bestv = -1;\n            int bestdv = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                int d = dist2[i][k];\n                if (d < bestdv) {\n                    bestdv = d;\n                    bestv = i;\n                }\n            }\n            if (bestv != -1) allowFlag[bestv] = true;\n        }\n    }\n    vector<int> allowedAug;\n    for (int i = 0; i < N; i++) if (allowFlag[i]) allowedAug.push_back(i);\n\n    auto prune_edges = [&](const vector<int> &Pvec, vector<int> &Bvec) {\n        vector<int> deg(N, 0);\n        vector<vector<int>> inc(N);\n        for (int e = 0; e < M; e++) {\n            if (Bvec[e]) {\n                int a = U[e], b = V[e];\n                deg[a]++; deg[b]++;\n                inc[a].push_back(e);\n                inc[b].push_back(e);\n            }\n        }\n        auto isBroadcast = [&](int v) -> bool {\n            return Pvec[v] > 0 || v == 0;\n        };\n        queue<int> q;\n        vector<char> inq(N, false);\n        for (int i = 0; i < N; i++) {\n            if (!isBroadcast(i) && deg[i] == 1) {\n                q.push(i);\n                inq[i] = true;\n            }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (isBroadcast(v) || deg[v] != 1) continue;\n            int eActive = -1;\n            for (int eid : inc[v]) {\n                if (Bvec[eid]) { eActive = eid; break; }\n            }\n            if (eActive == -1) continue;\n            Bvec[eActive] = 0;\n            int nei = (U[eActive] == v ? V[eActive] : U[eActive]);\n            deg[v]--;\n            deg[nei]--;\n            if (!isBroadcast(nei) && deg[nei] == 1 && !inq[nei]) {\n                q.push(nei);\n                inq[nei] = true;\n            }\n        }\n    };\n\n    auto build_solution = [&](const vector<int> &allowed) -> Solution {\n        vector<int> maxd2(N, -1);\n        for (int k = 0; k < K; k++) {\n            int best = -1;\n            int bestd = INT_MAX;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d <= LIMIT2 && d < bestd) {\n                    bestd = d;\n                    best = v;\n                }\n            }\n            if (best == -1) { // fallback to nearest allowed\n                for (int v : allowed) {\n                    int d = dist2[v][k];\n                    if (d < bestd) {\n                        bestd = d;\n                        best = v;\n                    }\n                }\n            }\n            if (best == -1) continue;\n            if (dist2[best][k] > maxd2[best]) maxd2[best] = dist2[best][k];\n        }\n        vector<int> P(N, 0);\n        vector<int> terminals;\n        terminals.push_back(0);\n        for (int i = 0; i < N; i++) {\n            if (maxd2[i] >= 0) {\n                int r = ceil_sqrt_ll(maxd2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n                if (i != 0 && r > 0) terminals.push_back(i);\n            }\n        }\n        vector<int> Bvec(M, 0);\n        int T = (int)terminals.size();\n        if (T > 1) {\n            vector<tuple<long long, int, int>> edges;\n            edges.reserve(T * (T - 1) / 2);\n            for (int i = 0; i < T; i++) {\n                int u = terminals[i];\n                for (int j = i + 1; j < T; j++) {\n                    int v = terminals[j];\n                    edges.emplace_back(distMat[u][v], u, v);\n                }\n            }\n            sort(edges.begin(), edges.end(),\n                 [](const auto &a, const auto &b) { return get<0>(a) < get<0>(b); });\n            DSU dsu(N);\n            int added = 0;\n            for (auto &ed : edges) {\n                long long w;\n                int u, v;\n                tie(w, u, v) = ed;\n                if (dsu.unite(u, v)) {\n                    int cur = v;\n                    while (cur != u) {\n                        int e = parentEdge[u][cur];\n                        if (e == -1) break;\n                        Bvec[e] = 1;\n                        cur = (U[e] == cur ? V[e] : U[e]);\n                    }\n                    added++;\n                    if (added == T - 1) break;\n                }\n            }\n        }\n        prune_edges(P, Bvec);\n        long long costP = 0;\n        for (int i = 0; i < N; i++) costP += 1LL * P[i] * P[i];\n        long long costE = 0;\n        for (int e = 0; e < M; e++) if (Bvec[e]) costE += W[e];\n        Solution sol{P, Bvec, costP + costE};\n        return sol;\n    };\n\n    Solution bestSol;\n    bestSol.cost = (1LL << 62);\n\n    Solution sol1 = build_solution(allowedSel);\n    if (sol1.cost < bestSol.cost) bestSol = sol1;\n    Solution sol2 = build_solution(allowedAug);\n    if (sol2.cost < bestSol.cost) bestSol = sol2;\n    Solution sol3 = build_solution(allowedAll);\n    if (sol3.cost < bestSol.cost) bestSol = sol3;\n\n    // output\n    for (int i = 0; i < N; i++) {\n        cout << bestSol.P[i] << (i + 1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (bestSol.B[j] ? 1 : 0) << (j + 1 == M ? '\\n' : ' ');\n    }\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int TOT = N * (N + 1) / 2; // 465\n    vector<int> val(TOT);\n    // read input\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int v;\n            if (!(cin >> v)) return 0;\n            int id = x * (x + 1) / 2 + y;\n            val[id] = v;\n        }\n    }\n    // precompute coordinates, parents, children\n    vector<int> xs(TOT), ys(TOT);\n    vector<vector<int>> parents(TOT), children(TOT);\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int id = x * (x + 1) / 2 + y;\n            xs[id] = x;\n            ys[id] = y;\n            // parents\n            if (x > 0) {\n                if (y > 0) {\n                    int pid = (x - 1) * x / 2 + (y - 1);\n                    parents[id].push_back(pid);\n                }\n                if (y < x) {\n                    int pid = (x - 1) * x / 2 + y;\n                    parents[id].push_back(pid);\n                }\n            }\n            // children\n            if (x + 1 < N) {\n                int cid1 = (x + 1) * (x + 2) / 2 + y;\n                int cid2 = cid1 + 1;\n                children[id].push_back(cid1);\n                children[id].push_back(cid2);\n            }\n        }\n    }\n\n    const int LIMIT = 10000;\n    vector<array<int, 4>> moves;\n    moves.reserve(LIMIT);\n\n    deque<int> q;\n    vector<char> inq(TOT, 0);\n    auto pushNode = [&](int id) {\n        if (!inq[id]) {\n            q.push_back(id);\n            inq[id] = 1;\n        }\n    };\n    // initialize queue with all non-leaf nodes\n    for (int id = 0; id < TOT; id++) {\n        if (!children[id].empty()) pushNode(id);\n    }\n\n    // main relaxation using min-child swap\n    while (!q.empty() && (int)moves.size() < LIMIT) {\n        int u = q.front();\n        q.pop_front();\n        inq[u] = 0;\n        if (children[u].empty()) continue;\n        int v = children[u][0];\n        if (children[u].size() == 2) {\n            int c2 = children[u][1];\n            if (val[c2] < val[v]) v = c2;\n        }\n        if (val[u] > val[v]) {\n            // perform swap\n            swap(val[u], val[v]);\n            moves.push_back({xs[u], ys[u], xs[v], ys[v]});\n            if ((int)moves.size() >= LIMIT) break;\n            // enqueue affected nodes\n            pushNode(u);\n            pushNode(v);\n            for (int p : parents[u]) pushNode(p);\n            // parents of v need not be pushed because v increased, but harmless\n        }\n    }\n\n    // fallback bubble pass if we still have budget and there are violations\n    auto computeE = [&]() -> int {\n        int e = 0;\n        for (int id = 0; id < TOT; id++) {\n            for (int c : children[id]) {\n                if (val[id] > val[c]) e++;\n            }\n        }\n        return e;\n    };\n\n    if ((int)moves.size() < LIMIT) {\n        int E = computeE();\n        if (E > 0) {\n            bool changed = true;\n            while (changed && (int)moves.size() < LIMIT) {\n                changed = false;\n                for (int id = 0; id < TOT; id++) {\n                    for (int c : children[id]) {\n                        if (val[id] > val[c]) {\n                            swap(val[id], val[c]);\n                            moves.push_back({xs[id], ys[id], xs[c], ys[c]});\n                            changed = true;\n                            if ((int)moves.size() >= LIMIT) break;\n                        }\n                    }\n                    if ((int)moves.size() >= LIMIT) break;\n                }\n            }\n        }\n    }\n\n    // output\n    cout << moves.size() << \"\\n\";\n    for (auto &op : moves) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    const int er = 0, ec = (D - 1) / 2; // entrance\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; k++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    int dr[4] = {1, -1, 0, 0};\n    int dc[4] = {0, 0, 1, -1};\n\n    // distance from entrance\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[er][ec] = 0;\n    q.push({er, ec});\n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (dist[nr][nc] != -1) continue;\n            dist[nr][nc] = dist[r][c] + 1;\n            q.push({nr, nc});\n        }\n    }\n\n    // list of container cells sorted by distance\n    vector<pair<int, int>> cells;\n    cells.reserve(D * D);\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (obstacle[i][j]) continue;\n        if (i == er && j == ec) continue;\n        cells.push_back({i, j});\n    }\n    sort(cells.begin(), cells.end(), [&](auto a, auto b) {\n        int da = dist[a.first][a.second], db = dist[b.first][b.second];\n        if (da != db) return da < db;\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    int K = (int)cells.size(); // number of containers\n    vector<int> idx_of(D * D, -1);\n    for (int idx = 0; idx < K; idx++) {\n        idx_of[cells[idx].first * D + cells[idx].second] = idx;\n    }\n\n    vector<vector<bool>> filled(D, vector<bool>(D, false));\n    vector<vector<int>> label_grid(D, vector<int>(D, -1));\n    int empties_count = K;\n\n    auto is_safe = [&](int r, int c) -> bool {\n        filled[r][c] = true;\n        int need = empties_count - 1;\n        int cnt = 0;\n        bool vis[9][9] = {};\n        queue<pair<int, int>> qq;\n        qq.push({er, ec});\n        vis[er][ec] = true;\n        while (!qq.empty()) {\n            auto [cr, cc] = qq.front();\n            qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int nr = cr + dr[k], nc = cc + dc[k];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (filled[nr][nc]) continue;\n                if (vis[nr][nc]) continue;\n                vis[nr][nc] = true;\n                if (!(nr == er && nc == ec)) cnt++;\n                qq.push({nr, nc});\n            }\n        }\n        filled[r][c] = false;\n        return cnt == need;\n    };\n\n    // placement phase\n    for (int step = 0; step < K; step++) {\n        int t;\n        cin >> t;\n        int target = t;\n        int best_idx = -1;\n        for (int offset = 0; offset < K; offset++) {\n            vector<int> candidates;\n            if (offset == 0) {\n                candidates.push_back(target);\n            } else {\n                if (t < K / 2) {\n                    if (target - offset >= 0) candidates.push_back(target - offset);\n                    if (target + offset < K) candidates.push_back(target + offset);\n                } else {\n                    if (target + offset < K) candidates.push_back(target + offset);\n                    if (target - offset >= 0) candidates.push_back(target - offset);\n                }\n            }\n            bool found = false;\n            for (int idx : candidates) {\n                if (idx < 0 || idx >= K) continue;\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    best_idx = idx;\n                    found = true;\n                    break;\n                }\n            }\n            if (found) break;\n        }\n        if (best_idx == -1) {\n            // fallback\n            for (int idx = 0; idx < K; idx++) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    best_idx = idx;\n                    break;\n                }\n            }\n        }\n        auto [pr, pc] = cells[best_idx];\n        filled[pr][pc] = true;\n        label_grid[pr][pc] = t;\n        empties_count--;\n        cout << pr << \" \" << pc << '\\n';\n        cout.flush();\n    }\n\n    // retrieval phase\n    vector<vector<bool>> present(D, vector<bool>(D, false));\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (label_grid[i][j] != -1) present[i][j] = true;\n    }\n    using Node = tuple<int, int, int, int>; // label, idx, r, c\n    struct Comp {\n        bool operator()(const Node &a, const Node &b) const {\n            if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n            return get<1>(a) > get<1>(b);\n        }\n    };\n    priority_queue<Node, vector<Node>, Comp> pq;\n    auto push_cell = [&](int r, int c) {\n        if (r < 0 || r >= D || c < 0 || c >= D) return;\n        if (obstacle[r][c]) return;\n        if (present[r][c]) {\n            int idx = idx_of[r * D + c];\n            pq.emplace(label_grid[r][c], idx, r, c);\n        }\n    };\n    push_cell(er + 1, ec);\n    push_cell(er - 1, ec);\n    push_cell(er, ec + 1);\n    push_cell(er, ec - 1);\n\n    int removed = 0;\n    while (removed < K) {\n        if (pq.empty()) {\n            // find any frontier cell\n            bool pushed = false;\n            for (int i = 0; i < D && !pushed; i++) for (int j = 0; j < D && !pushed; j++) {\n                if (present[i][j]) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dr[k], nj = j + dc[k];\n                        if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                        if (obstacle[ni][nj]) continue;\n                        if (!present[ni][nj] || (ni == er && nj == ec)) {\n                            int idx = idx_of[i * D + j];\n                            pq.emplace(label_grid[i][j], idx, i, j);\n                            pushed = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        auto [lab, idx, r, c] = pq.top();\n        pq.pop();\n        if (!present[r][c]) continue;\n        present[r][c] = false;\n        removed++;\n        cout << r << \" \" << c << '\\n';\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            push_cell(nr, nc);\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> g(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> g[i][j];\n        }\n    }\n    int C = m + 1; // colors 0..m\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto addEdge = [&](int a, int b) {\n        if (a == b) return;\n        adjCnt[a][b]++;\n        adjCnt[b][a]++;\n    };\n    // sizes\n    vector<int> sz(C, 0);\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) sz[g[i][j]]++;\n    // internal edges\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int a = g[i][j];\n            if (i + 1 < n) {\n                int b = g[i + 1][j];\n                addEdge(a, b);\n            }\n            if (j + 1 < n) {\n                int b = g[i][j + 1];\n                addEdge(a, b);\n            }\n            // outside edges\n            if (i == 0) addEdge(0, a);\n            if (i == n - 1) addEdge(0, a);\n            if (j == 0) addEdge(0, a);\n            if (j == n - 1) addEdge(0, a);\n        }\n    }\n    vector<vector<char>> adjOrig(C, vector<char>(C, 0));\n    for (int i = 0; i < C; i++) {\n        for (int j = 0; j < C; j++) {\n            if (adjCnt[i][j] > 0) adjOrig[i][j] = 1;\n        }\n    }\n    vector<char> boundary(C, 0);\n    for (int c = 1; c <= m; c++) {\n        if (adjOrig[0][c]) boundary[c] = 1;\n    }\n\n    // visited for BFS\n    vector<int> vis(n * n, 0);\n    int curMark = 1;\n    auto isAdjZero = [&](int i, int j) -> bool {\n        if (i == 0 || i == n - 1 || j == 0 || j == n - 1) return true;\n        if (g[i - 1][j] == 0) return true;\n        if (g[i + 1][j] == 0) return true;\n        if (g[i][j - 1] == 0) return true;\n        if (g[i][j + 1] == 0) return true;\n        return false;\n    };\n\n    // connectivity check excluding cell (ci,cj) of color col\n    auto connectedAfterRemoval = [&](int ci, int cj, int col) -> bool {\n        if (sz[col] <= 1) return false;\n        int start = -1;\n        // try neighbors first\n        if (ci > 0 && g[ci - 1][cj] == col) start = (ci - 1) * n + cj;\n        else if (ci + 1 < n && g[ci + 1][cj] == col) start = (ci + 1) * n + cj;\n        else if (cj > 0 && g[ci][cj - 1] == col) start = ci * n + (cj - 1);\n        else if (cj + 1 < n && g[ci][cj + 1] == col) start = ci * n + (cj + 1);\n        if (start == -1) {\n            for (int idx = 0; idx < n * n; idx++) {\n                if (idx == ci * n + cj) continue;\n                int r = idx / n, c = idx % n;\n                if (g[r][c] == col) { start = idx; break; }\n            }\n        }\n        if (start == -1) return false; // should not happen\n        curMark++;\n        queue<int> q;\n        q.push(start);\n        vis[start] = curMark;\n        int count = 1;\n        const int dr[4] = {1, -1, 0, 0};\n        const int dc[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int r = v / n, c = v % n;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n                if (nr == ci && nc == cj) continue; // removed cell\n                if (g[nr][nc] != col) continue;\n                int idx = nr * n + nc;\n                if (vis[idx] == curMark) continue;\n                vis[idx] = curMark;\n                q.push(idx);\n                count++;\n            }\n        }\n        return count == sz[col] - 1;\n    };\n\n    static int remEdgesStatic[205]; // enough for m<=200\n    // main removal loop\n    while (true) {\n        bool removed = false;\n        for (int i = 0; i < n && !removed; i++) {\n            for (int j = 0; j < n && !removed; j++) {\n                int c = g[i][j];\n                if (c == 0) continue;\n                if (!boundary[c]) continue; // only remove boundary colors\n                if (!isAdjZero(i, j)) continue;\n                if (sz[c] <= 1) continue;\n                int num0 = 0;\n                int numSame = 0;\n                vector<int> touched;\n                bool bad = false;\n                const int dr[4] = {1, -1, 0, 0};\n                const int dc[4] = {0, 0, 1, -1};\n                for (int k = 0; k < 4; k++) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                        num0++;\n                        continue;\n                    }\n                    int d = g[ni][nj];\n                    if (d == 0) {\n                        num0++;\n                    } else if (d == c) {\n                        numSame++;\n                    } else {\n                        if (remEdgesStatic[d] == 0) touched.push_back(d);\n                        remEdgesStatic[d]++;\n                        if (!boundary[d]) { // would create adjacency to non-boundary color\n                            bad = true;\n                            break;\n                        }\n                    }\n                }\n                if (bad) {\n                    for (int d : touched) remEdgesStatic[d] = 0;\n                    continue;\n                }\n                bool ok = true;\n                for (int d : touched) {\n                    if (adjOrig[c][d]) {\n                        if (adjCnt[c][d] - remEdgesStatic[d] <= 0) { ok = false; break; }\n                    }\n                }\n                if (ok) {\n                    int predicted0c = adjCnt[0][c] - num0 + numSame;\n                    if (predicted0c <= 0) ok = false;\n                }\n                if (ok) {\n                    if (!connectedAfterRemoval(i, j, c)) ok = false;\n                }\n                for (int d : touched) remEdgesStatic[d] = 0;\n                if (!ok) continue;\n\n                // perform removal\n                for (int k = 0; k < 4; k++) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                        adjCnt[0][c]--; adjCnt[c][0]--;\n                    } else {\n                        int d = g[ni][nj];\n                        if (d == c) {\n                            adjCnt[0][c]++; adjCnt[c][0]++;\n                        } else if (d == 0) {\n                            adjCnt[0][c]--; adjCnt[c][0]--;\n                        } else {\n                            adjCnt[c][d]--; adjCnt[d][c]--;\n                            adjCnt[0][d]++; adjCnt[d][0]++;\n                        }\n                    }\n                }\n                g[i][j] = 0;\n                sz[c]--;\n                removed = true;\n            }\n        }\n        if (!removed) break;\n    }\n\n    // output\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j) cout << ' ';\n            cout << g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    // generate all pairs\n    vector<pair<int,int>> pairs;\n    pairs.reserve(N*(N-1)/2);\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            pairs.emplace_back(i,j);\n        }\n    }\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(pairs.begin(), pairs.end(), rng);\n    int pidx = 0, plen = (int)pairs.size();\n\n    vector<double> wins(N, 0.0);\n    vector<int> comps(N, 0);\n    string resp;\n\n    for (int q = 0; q < Q; q++) {\n        auto pr = pairs[pidx];\n        pidx++;\n        if (pidx >= plen) pidx = 0;\n        int a = pr.first, b = pr.second;\n        // output query: compare singletons a vs b\n        cout << 1 << \" \" << 1 << \" \" << a << \" \" << b << \"\\n\";\n        cout.flush();\n        if (!(cin >> resp)) return 0;\n        char c = resp[0];\n        comps[a]++; comps[b]++;\n        if (c == '>') {\n            wins[a] += 1.0;\n        } else if (c == '<') {\n            wins[b] += 1.0;\n        } else { // '='\n            wins[a] += 0.5;\n            wins[b] += 0.5;\n        }\n    }\n\n    double lambda = 1e-5;\n    double M = 100000.0 * N / D;\n    double ex = exp(-lambda * M);\n\n    vector<double> west(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        double p;\n        if (comps[i] == 0) {\n            p = 0.5;\n        } else {\n            p = (wins[i] + 1.0) / (comps[i] + 2.0); // Laplace smoothing\n        }\n        if (p <= 1e-9) p = 1e-9;\n        if (p >= 1 - 1e-9) p = 1 - 1e-9;\n        double w = -log(1.0 - p * (1.0 - ex)) / lambda;\n        if (w > M) w = M;\n        west[i] = w;\n    }\n\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return west[a] > west[b];\n    });\n\n    vector<double> sum(D, 0.0);\n    vector<int> assign(N, 0);\n    for (int idx : order) {\n        int best = 0;\n        double bestsum = sum[0];\n        for (int d = 1; d < D; d++) {\n            if (sum[d] < bestsum) {\n                bestsum = sum[d];\n                best = d;\n            }\n        }\n        assign[idx] = best;\n        sum[best] += west[idx];\n    }\n\n    auto rangeVal = [&](const vector<double>& s)->double{\n        auto mm = minmax_element(s.begin(), s.end());\n        return *mm.second - *mm.first;\n    };\n    double bestRange = rangeVal(sum);\n    const int ITER = 20000;\n    for (int it = 0; it < ITER; it++) {\n        int i = rng() % N;\n        int j = rng() % N;\n        if (assign[i] == assign[j]) continue;\n        int ai = assign[i], aj = assign[j];\n        double newSi = sum[ai] - west[i] + west[j];\n        double newSj = sum[aj] - west[j] + west[i];\n        double mn = 1e100, mx = -1e100;\n        for (int d = 0; d < D; d++) {\n            double val = sum[d];\n            if (d == ai) val = newSi;\n            else if (d == aj) val = newSj;\n            if (val < mn) mn = val;\n            if (val > mx) mx = val;\n        }\n        double newRange = mx - mn;\n        if (newRange < bestRange) {\n            bestRange = newRange;\n            assign[i] = aj;\n            assign[j] = ai;\n            sum[ai] = newSi;\n            sum[aj] = newSj;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << assign[i];\n    }\n    cout << \"\\n\";\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF_INT = 1e9;\nconst int N_CONST = 200;\nconst int M_CONST = 10;\nconst int BUCKET_SIZE = 20; // n/m fixed\n\nstruct Param {\n    int block_threshold; // if number of boxes above >= threshold -> move as a block\n    int indiv_mode;      // 0: patience(top>=x), 1: bucket, 2: largestTop, 3: minHeight\n    int block_mode;      // 0: minHeight, 1: largestTop, 2: bucket\n    bool random_tie;\n};\n\nstruct Result {\n    int cost;\n    int op_count;\n    vector<pair<int,int>> ops;\n    bool success;\n};\n\ndouble TIME_LIMIT = 1.9; // seconds\nchrono::steady_clock::time_point g_start;\n\ndouble elapsed_sec() {\n    return chrono::duration<double>(chrono::steady_clock::now() - g_start).count();\n}\n\n// select destination stack for individual move of box x from src\nint select_dest_individual(int x, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.indiv_mode == 2) { // largestTop\n        int best = -1;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.indiv_mode == 1) { // bucket preference\n        int target = (x - 1) / BUCKET_SIZE;\n        if (target != src) {\n            if (st[target].empty() || st[target].back() >= x) {\n                return target;\n            }\n        }\n    }\n    if (p.indiv_mode == 3) { // minHeight\n        int best = -1;\n        int bestSz = INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int sz = (int)st[i].size();\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n                bestSz = sz; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // patience mode\n    int bestTop = INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top >= x) {\n            if (top < bestTop) {\n                bestTop = top;\n                cand.clear();\n                cand.push_back(i);\n            } else if (top == bestTop) {\n                cand.push_back(i);\n            }\n        }\n    }\n    if (!cand.empty()) {\n        if (p.random_tie && cand.size() > 1) {\n            uniform_int_distribution<int> dist(0, (int)cand.size()-1);\n            return cand[dist(rng)];\n        } else {\n            int best = cand[0];\n            int bestSz = (int)st[best].size();\n            for (int idx = 1; idx < (int)cand.size(); idx++) {\n                int i = cand[idx];\n                int sz = (int)st[i].size();\n                if (sz < bestSz) { bestSz = sz; best = i; }\n            }\n            return best;\n        }\n    }\n    // no top>=x, choose largest top\n    bestTop = -INF_INT;\n    cand.clear();\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) {\n            bestTop = top;\n            cand.clear();\n            cand.push_back(i);\n        } else if (top == bestTop) cand.push_back(i);\n    }\n    if (p.random_tie && cand.size() > 1) {\n        uniform_int_distribution<int> dist(0, (int)cand.size()-1);\n        return cand[dist(rng)];\n    } else {\n        int best = cand[0];\n        int bestSz = (int)st[best].size();\n        for (int idx = 1; idx < (int)cand.size(); idx++) {\n            int i = cand[idx];\n            int sz = (int)st[i].size();\n            if (sz < bestSz) { bestSz = sz; best = i; }\n        }\n        return best;\n    }\n}\n\n// select destination stack for block move (representative value rep, from src)\nint select_dest_block(int rep, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.block_mode == 2) { // bucket\n        int t = (rep - 1) / BUCKET_SIZE;\n        if (t != src) return t;\n        // else fall through to minHeight\n    }\n    if (p.block_mode == 1) { // largestTop\n        int best = -1;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // minHeight\n    int best = -1;\n    int bestSz = INF_INT;\n    int bestTop = -INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int sz = (int)st[i].size();\n        if (sz < bestSz) {\n            bestSz = sz;\n            cand.clear();\n            cand.push_back(i);\n        } else if (sz == bestSz) cand.push_back(i);\n    }\n    if (cand.size() == 1) return cand[0];\n    // tie-breaker: larger top\n    bestTop = -INF_INT;\n    best = cand[0];\n    for (int idx = 0; idx < (int)cand.size(); idx++) {\n        int i = cand[idx];\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) { bestTop = top; best = i; }\n    }\n    return best;\n}\n\nResult simulate(const vector<vector<int>>& init, const Param& p, uint64_t seed, bool record_ops, int best_cost_so_far) {\n    mt19937 rng(seed);\n    vector<vector<int>> st = init;\n    vector<int> pos(N_CONST + 1, -1);\n    int m = (int)st.size();\n    for (int i = 0; i < m; i++) {\n        for (int v : st[i]) pos[v] = i;\n    }\n    int energy = 0;\n    int op_cnt = 0;\n    vector<pair<int,int>> ops;\n    ops.reserve(3000);\n    for (int cur = 1; cur <= N_CONST; cur++) {\n        while (true) {\n            int s = pos[cur];\n            if (s < 0) return {INF_INT, op_cnt, ops, false}; // shouldn't happen\n            if (!st[s].empty() && st[s].back() == cur) {\n                st[s].pop_back();\n                pos[cur] = -1;\n                op_cnt++;\n                if (record_ops) ops.emplace_back(cur, 0);\n                break;\n            } else {\n                // compute boxes above cur\n                int d = 0;\n                for (int idx = (int)st[s].size() - 1; idx >= 0; idx--) {\n                    if (st[s][idx] == cur) break;\n                    d++;\n                }\n                bool did_block = false;\n                if (d > 0 && d >= p.block_threshold) {\n                    did_block = true;\n                    int k = d;\n                    int v = st[s][(int)st[s].size() - k]; // bottom of block (just above cur)\n                    int dest = select_dest_block(v, s, st, p, rng);\n                    // move block\n                    int start_idx = (int)st[s].size() - k;\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        int val = st[s][idx];\n                        st[dest].push_back(val);\n                        pos[val] = dest;\n                    }\n                    st[s].resize(start_idx);\n                    energy += k + 1;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(v, dest + 1);\n                }\n                if (!did_block) {\n                    int x = st[s].back();\n                    int dest = select_dest_individual(x, s, st, p, rng);\n                    st[s].pop_back();\n                    st[dest].push_back(x);\n                    pos[x] = dest;\n                    energy += 2;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(x, dest + 1);\n                }\n                if (op_cnt > 5000) return {INF_INT, op_cnt, ops, false};\n                if (!record_ops && energy >= best_cost_so_far) {\n                    return {INF_INT, op_cnt, ops, false};\n                }\n            }\n        }\n    }\n    return {energy, op_cnt, ops, true};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> init(m);\n    for (int i = 0; i < m; i++) {\n        init[i].reserve(n / m);\n        for (int j = 0; j < n / m; j++) {\n            int v; cin >> v;\n            init[i].push_back(v);\n        }\n    }\n\n    g_start = chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Param> base_params;\n    // block_threshold, indiv_mode, block_mode\n    base_params.push_back({1000, 0, 0, false}); // patience\n    base_params.push_back({1000, 1, 0, false}); // bucket\n    base_params.push_back({1000, 2, 0, false}); // largestTop\n    base_params.push_back({1000, 3, 0, false}); // minHeight\n    base_params.push_back({6, 0, 0, false});\n    base_params.push_back({4, 0, 0, false});\n    base_params.push_back({4, 1, 0, false});\n    base_params.push_back({4, 3, 0, false});\n    base_params.push_back({3, 0, 0, false});\n    base_params.push_back({2, 0, 0, false});\n    base_params.push_back({2, 1, 0, false});\n    base_params.push_back({2, 3, 0, false});\n    base_params.push_back({1, 0, 0, false});\n    base_params.push_back({1, 0, 1, false});\n    base_params.push_back({3, 0, 1, false});\n\n    int best_cost = INF_INT;\n    vector<pair<int,int>> best_ops;\n\n    for (const auto& p : base_params) {\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n        if (elapsed_sec() > TIME_LIMIT) break;\n    }\n\n    // random exploration with random tie-breaking\n    while (elapsed_sec() < TIME_LIMIT) {\n        Param p = base_params[rng() % base_params.size()];\n        p.random_tie = true;\n        // slight random tweak of threshold\n        int delta = (int)(rng() % 3) - 1; // -1,0,1\n        int th = max(1, p.block_threshold + delta);\n        if (p.block_threshold >= 1000) th = 1000;\n        p.block_threshold = th;\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    if (best_ops.empty()) {\n        // fallback trivial plan\n        Param p{1000, 3, 0, false}; // individual minHeight\n        Result r = simulate(init, p, 123456789, true, INF_INT);\n        best_ops.swap(r.ops);\n    }\n\n    for (auto &op : best_ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hwall, vwall;\nvector<vector<int>> adj;\n\n// convert (i,j) to node id\ninline int id(int i, int j) { return i * N + j; }\n\n// direction character from node a to adjacent node b\nchar dirChar(int a, int b) {\n    int ai = a / N, aj = a % N;\n    int bi = b / N, bj = b % N;\n    if (bi == ai + 1) return 'D';\n    if (bi == ai - 1) return 'U';\n    if (bj == aj + 1) return 'R';\n    if (bj == aj - 1) return 'L';\n    return '?';\n}\n\n// shortest path between s and t (inclusive) as list of node ids\nvector<int> shortest_path(int s, int t) {\n    int V = N * N;\n    vector<int> dist(V, -1), par(V, -1);\n    queue<int> q;\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == t) break;\n        for (int nb : adj[v]) {\n            if (dist[nb] == -1) {\n                dist[nb] = dist[v] + 1;\n                par[nb] = v;\n                q.push(nb);\n            }\n        }\n    }\n    vector<int> path;\n    if (dist[t] == -1) return path;\n    int cur = t;\n    while (cur != -1) {\n        path.push_back(cur);\n        if (cur == s) break;\n        cur = par[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// greedy route builder\nstruct RouteInfo {\n    string moves;\n    int visitedCount;\n    int endPos;\n};\n\nRouteInfo build_greedy() {\n    int V = N * N;\n    vector<char> visited(V, 0);\n    int cur = 0;\n    visited[cur] = 1;\n    int visitedCnt = 1;\n    string res;\n    res.reserve(V * 3);\n\n    auto count_unvis_nei = [&](int node, const vector<char>& vis) {\n        int c = 0;\n        for (int nb : adj[node]) if (!vis[nb]) c++;\n        return c;\n    };\n\n    while (visitedCnt < V) {\n        // choose adjacent unvisited if exists\n        int bestNb = -1;\n        int bestScore = -1;\n        int bestPref = -1;\n        int ci = cur / N, cj = cur % N;\n        for (int nb : adj[cur]) {\n            if (visited[nb]) continue;\n            int score = count_unvis_nei(nb, visited);\n            int pref = 0;\n            int ni = nb / N, nj = nb % N;\n            if (ci % 2 == 0) { // even row prefer right then down then left then up\n                if (ni == ci && nj == cj + 1) pref = 3;\n                else if (ni == ci + 1 && nj == cj) pref = 2;\n                else if (ni == ci && nj == cj - 1) pref = 1;\n                else pref = 0;\n            } else { // odd row prefer left then down then right then up\n                if (ni == ci && nj == cj - 1) pref = 3;\n                else if (ni == ci + 1 && nj == cj) pref = 2;\n                else if (ni == ci && nj == cj + 1) pref = 1;\n                else pref = 0;\n            }\n            if (score > bestScore || (score == bestScore && pref > bestPref)) {\n                bestScore = score;\n                bestPref = pref;\n                bestNb = nb;\n            }\n        }\n        if (bestNb != -1) {\n            res.push_back(dirChar(cur, bestNb));\n            cur = bestNb;\n            if (!visited[cur]) {\n                visited[cur] = 1;\n                visitedCnt++;\n            }\n            continue;\n        }\n\n        // no unvisited neighbor -> BFS to nearest unvisited\n        vector<int> dist(V, -1), par(V, -1);\n        queue<int> q;\n        q.push(cur);\n        dist[cur] = 0;\n        int foundDist = -1;\n        vector<int> candidates;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int dv = dist[v];\n            if (foundDist != -1 && dv > foundDist) break;\n            if (!visited[v] && v != cur) {\n                foundDist = dv;\n                candidates.push_back(v);\n                continue;\n            }\n            for (int nb : adj[v]) {\n                if (dist[nb] == -1) {\n                    dist[nb] = dv + 1;\n                    par[nb] = v;\n                    q.push(nb);\n                }\n            }\n        }\n        if (foundDist == -1) break; // should not happen\n\n        int target = candidates[0];\n        int bestF = -1;\n        for (int v : candidates) {\n            int f = count_unvis_nei(v, visited);\n            if (f > bestF) {\n                bestF = f;\n                target = v;\n            }\n        }\n        // reconstruct path cur -> target using par\n        vector<int> path;\n        int x = target;\n        while (true) {\n            path.push_back(x);\n            if (x == cur) break;\n            x = par[x];\n        }\n        reverse(path.begin(), path.end());\n        for (int idx = 1; idx < (int)path.size(); idx++) {\n            int prev = path[idx - 1];\n            int nxt = path[idx];\n            res.push_back(dirChar(prev, nxt));\n            cur = nxt;\n            if (!visited[cur]) {\n                visited[cur] = 1;\n                visitedCnt++;\n            }\n        }\n    }\n\n    // return to start\n    if (cur != 0) {\n        vector<int> path = shortest_path(cur, 0);\n        for (int idx = 1; idx < (int)path.size(); idx++) {\n            res.push_back(dirChar(path[idx - 1], path[idx]));\n        }\n        cur = 0;\n    }\n\n    return {res, visitedCnt, cur};\n}\n\n// DFS fallback route (Euler tour of spanning tree)\nstring build_dfs_route() {\n    string res;\n    vector<vector<char>> vis(N, vector<char>(N, 0));\n    int di[4] = {0, 1, 0, -1};\n    int dj[4] = {1, 0, -1, 0};\n    char dc[4] = {'R', 'D', 'L', 'U'};\n    function<void(int, int)> dfs = [&](int i, int j) {\n        vis[i][j] = 1;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) { // right\n                wall = (vwall[i][j] == '1');\n            } else if (dir == 2) { // left\n                wall = (vwall[i][j - 1] == '1');\n            } else if (dir == 1) { // down\n                wall = (hwall[i][j] == '1');\n            } else { // up\n                wall = (hwall[i - 1][j] == '1');\n            }\n            if (wall) continue;\n            if (!vis[ni][nj]) {\n                res.push_back(dc[dir]);\n                dfs(ni, nj);\n                res.push_back(dc[(dir + 2) % 4]);\n            }\n        }\n    };\n    dfs(0, 0);\n    return res;\n}\n\n// simulate route to count visited cells and end position\npair<int, int> simulate_route(const string& moves) {\n    int V = N * N;\n    vector<char> vis(V, 0);\n    int pos = 0;\n    vis[pos] = 1;\n    int cnt = 1;\n    for (char c : moves) {\n        int i = pos / N, j = pos % N;\n        if (c == 'U') i--;\n        else if (c == 'D') i++;\n        else if (c == 'L') j--;\n        else if (c == 'R') j++;\n        pos = id(i, j);\n        if (!vis[pos]) {\n            vis[pos] = 1;\n            cnt++;\n        }\n    }\n    return {cnt, pos};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; i++) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; i++) cin >> vwall[i];\n    vector<vector<int>> dval(N, vector<int>(N));\n    long long sumD = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> dval[i][j];\n            sumD += dval[i][j];\n        }\n    }\n\n    // build adjacency\n    int V = N * N;\n    adj.assign(V, {});\n    auto add_edge = [&](int i1, int j1, int i2, int j2) {\n        int a = id(i1, j1);\n        int b = id(i2, j2);\n        adj[a].push_back(b);\n        adj[b].push_back(a);\n    };\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i + 1 < N && hwall[i][j] == '0') add_edge(i, j, i + 1, j);\n            if (j + 1 < N && vwall[i][j] == '0') add_edge(i, j, i, j + 1);\n        }\n    }\n\n    RouteInfo info = build_greedy();\n    string route = info.moves;\n\n    auto sim = simulate_route(route);\n    if ((int)route.size() > 100000 || sim.first < V || sim.second != 0) {\n        route = build_dfs_route();\n    }\n\n    cout << route << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n\n    // Greedy shortest common superstring\n    auto overlap = [](const string &a, const string &b) {\n        int maxk = min(a.size(), b.size());\n        for (int k = maxk; k >= 1; k--) {\n            bool ok = true;\n            for (int t = 0; t < k; t++) {\n                if (a[a.size() - k + t] != b[t]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return k;\n        }\n        return 0;\n    };\n\n    vector<string> v = words;\n    while (v.size() > 1) {\n        int n = (int)v.size();\n        int best_i = 0, best_j = 1, best_o = -1;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) if (i != j) {\n                int o = overlap(v[i], v[j]);\n                if (o > best_o) {\n                    best_o = o;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        string merged = v[best_i] + v[best_j].substr(best_o);\n        vector<string> nv;\n        nv.reserve(n - 1);\n        for (int idx = 0; idx < n; idx++) {\n            if (idx == best_i || idx == best_j) continue;\n            nv.push_back(std::move(v[idx]));\n        }\n        nv.push_back(std::move(merged));\n        v.swap(nv);\n    }\n    string S = v[0];\n    int L = (int)S.size();\n\n    // Positions of each letter\n    vector<pair<int,int>> posList[26];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            posList[grid[i][j]-'A'].push_back({i,j});\n        }\n    }\n\n    const int INF = 1e9;\n    vector<vector<int>> dp(L);\n    vector<vector<int>> pre(L);\n\n    for (int k = 0; k < L; k++) {\n        int c = S[k]-'A';\n        int m = posList[c].size();\n        dp[k].assign(m, INF);\n        pre[k].assign(m, -1);\n        if (k == 0) {\n            for (int idx = 0; idx < m; idx++) {\n                auto [i,j] = posList[c][idx];\n                dp[k][idx] = abs(i - si) + abs(j - sj) + 1;\n            }\n        } else {\n            int pc = S[k-1]-'A';\n            int pm = posList[pc].size();\n            for (int idx = 0; idx < m; idx++) {\n                auto [ci,cj] = posList[c][idx];\n                int bestCost = INF;\n                int bestPrev = -1;\n                for (int pid = 0; pid < pm; pid++) {\n                    auto [pi,pj] = posList[pc][pid];\n                    int cand = dp[k-1][pid] + abs(pi - ci) + abs(pj - cj) + 1;\n                    if (cand < bestCost) {\n                        bestCost = cand;\n                        bestPrev = pid;\n                    }\n                }\n                dp[k][idx] = bestCost;\n                pre[k][idx] = bestPrev;\n            }\n        }\n    }\n\n    int endIdx = 0;\n    int best = INF;\n    for (int idx = 0; idx < (int)dp[L-1].size(); idx++) {\n        if (dp[L-1][idx] < best) {\n            best = dp[L-1][idx];\n            endIdx = idx;\n        }\n    }\n\n    vector<pair<int,int>> path(L);\n    int idx = endIdx;\n    for (int k = L-1; k >= 0; k--) {\n        int c = S[k]-'A';\n        path[k] = posList[c][idx];\n        idx = pre[k][idx];\n    }\n\n    for (auto &p : path) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // Read shapes (not used in this naive solution)\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int t = 0; t < d; t++) {\n            int i, j; cin >> i >> j;\n            // ignore\n        }\n    }\n\n    vector<vector<int>> val(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int resp; \n            if (!(cin >> resp)) return 0;\n            val[i][j] = resp;\n        }\n    }\n\n    vector<pair<int,int>> oil;\n    oil.reserve(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (val[i][j] > 0) oil.emplace_back(i, j);\n        }\n    }\n\n    cout << \"a \" << oil.size();\n    for (auto &p : oil) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    cout.flush();\n\n    int verdict;\n    cin >> verdict; // 1 if correct, 0 otherwise\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0;\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++) cin >> a[d][k];\n    }\n    // requests sorted descending for each day\n    vector<vector<int>> req_desc(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        req_desc[d] = a[d];\n        sort(req_desc[d].begin(), req_desc[d].end(), greater<int>());\n    }\n    // r_by_rank[i][d] = i-th largest request of day d, then sort descending over days\n    vector<vector<int>> r_by_rank(N, vector<int>(D));\n    for (int i = 0; i < N; i++) {\n        for (int d = 0; d < D; d++) {\n            r_by_rank[i][d] = req_desc[d][i];\n        }\n        sort(r_by_rank[i].begin(), r_by_rank[i].end(), greater<int>());\n    }\n\n    // greedy allocation of 1e6 area units\n    const int TOTAL = W * W; // 1_000_000\n    vector<int> c(N, 0);           // capacities in unit area\n    vector<int> benefit(N);        // number of days with request > c_i\n    vector<int> thresh(N);         // current smallest value still > c_i\n    priority_queue<pair<int, int>> pq; // (benefit, index)\n    for (int i = 0; i < N; i++) {\n        benefit[i] = D;\n        thresh[i] = (benefit[i] > 0 ? r_by_rank[i][benefit[i] - 1] : -1);\n        pq.push({benefit[i], i});\n    }\n    for (int step = 0; step < TOTAL; step++) {\n        auto [b, i] = pq.top();\n        pq.pop();\n        if (b != benefit[i]) {\n            pq.push({benefit[i], i});\n            step--;\n            continue;\n        }\n        c[i]++;\n        while (benefit[i] > 0 && c[i] >= thresh[i]) {\n            benefit[i]--;\n            if (benefit[i] > 0)\n                thresh[i] = r_by_rank[i][benefit[i] - 1];\n        }\n        pq.push({benefit[i], i});\n    }\n\n    // convert to units of 1000 (row heights)\n    vector<int> units(N);\n    int sum_units = 0;\n    for (int i = 0; i < N; i++) {\n        units[i] = c[i] / 1000; // floor\n        sum_units += units[i];\n    }\n    int leftover_units = W - sum_units; // W=1000\n    // ensure each rectangle has at least height 1\n    vector<int> idx_order(N);\n    iota(idx_order.begin(), idx_order.end(), 0);\n    for (int i = 0; i < N; i++) {\n        if (units[i] == 0) {\n            units[i] = 1;\n            leftover_units--;\n        }\n    }\n    if (leftover_units < 0) {\n        int need = -leftover_units;\n        // reduce from largest units (>1)\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int p, int q) { return units[p] > units[q]; });\n        for (int idx : order) {\n            if (need == 0) break;\n            if (units[idx] > 1) {\n                int dec = min(units[idx] - 1, need);\n                units[idx] -= dec;\n                need -= dec;\n            }\n        }\n        leftover_units = 0;\n    }\n\n    auto benefit_add = [&](int idx, int cap_units) -> long long {\n        int cap = cap_units * 1000;\n        long long before = 0, after = 0;\n        for (int v : r_by_rank[idx]) {\n            if (v > cap) before += v - cap;\n            if (v > cap + 1000) after += v - (cap + 1000);\n        }\n        return before - after; // deficiency reduction by adding 1000 area\n    };\n\n    // distribute leftover units greedily\n    for (int t = 0; t < leftover_units; t++) {\n        long long best = -1;\n        int bi = 0;\n        for (int i = 0; i < N; i++) {\n            long long b = benefit_add(i, units[i]);\n            if (b > best) {\n                best = b;\n                bi = i;\n            }\n        }\n        units[bi] += 1;\n    }\n    // ensure total units = W\n    int total_units = 0;\n    for (int u : units) total_units += u;\n    if (total_units != W) {\n        units[0] += W - total_units;\n    }\n\n    // capacities in area\n    vector<int> caps(N);\n    for (int i = 0; i < N; i++) caps[i] = units[i] * 1000;\n    sort(caps.begin(), caps.end(), greater<int>());\n    vector<int> heights(N);\n    int sum_h = 0;\n    for (int i = 0; i < N; i++) {\n        heights[i] = caps[i] / 1000;\n        sum_h += heights[i];\n    }\n    if (sum_h != W) heights[0] += W - sum_h;\n\n    // precompute stripes coordinates\n    vector<array<int, 4>> stripes(N);\n    int y = 0;\n    for (int i = 0; i < N; i++) {\n        int h = heights[i];\n        if (h <= 0) h = 1;\n        stripes[i] = {y, 0, y + h, W};\n        y += h;\n    }\n    if (y < W) stripes.back()[2] += W - y;\n\n    // output for each day\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> reqs;\n        reqs.reserve(N);\n        for (int k = 0; k < N; k++) reqs.push_back({a[d][k], k});\n        sort(reqs.begin(), reqs.end(), [&](auto &p1, auto &p2) {\n            if (p1.first != p2.first) return p1.first > p2.first;\n            return p1.second < p2.second;\n        });\n        vector<array<int, 4>> out(N);\n        for (int i = 0; i < N; i++) {\n            int idx = reqs[i].second;\n            out[idx] = stripes[i];\n        }\n        for (int k = 0; k < N; k++) {\n            auto &r = out[k];\n            cout << r[0] << \" \" << r[1] << \" \" << r[2] << \" \" << r[3] << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353LL;\n\nstruct OpInfo {\n    int m, p, q;\n    array<int, 9> idx;\n    array<int, 9> inc;\n};\n\nuint64_t rng_state;\ninline uint64_t rng64() {\n    rng_state ^= rng_state << 7;\n    rng_state ^= rng_state >> 9;\n    return rng_state;\n}\ninline int rand_int(int n) {\n    return int(rng64() % n);\n}\ninline double rand_double() {\n    // use 53 bits for double\n    return (rng64() >> 11) * (1.0 / 9007199254740992.0);\n}\n\ninline ll add_mod_fast(ll x, int inc) {\n    x += inc;\n    if (x >= MOD) x -= MOD;\n    return x;\n}\ninline ll adjust_mod(ll x) {\n    if (x >= MOD) x -= MOD;\n    else if (x < 0) x += MOD;\n    return x;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    rng_state = chrono::high_resolution_clock::now().time_since_epoch().count();\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<ll> base(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            ll v;\n            cin >> v;\n            base[i * N + j] = v;\n        }\n    }\n    vector<vector<vector<int>>> s(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int v;\n                cin >> v;\n                s[m][i][j] = v;\n            }\n        }\n    }\n\n    // Precompute all possible operations\n    vector<OpInfo> opsInfo;\n    opsInfo.reserve(M * (N - 2) * (N - 2));\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                OpInfo op;\n                op.m = m; op.p = p; op.q = q;\n                int t = 0;\n                for (int di = 0; di < 3; di++) {\n                    for (int dj = 0; dj < 3; dj++) {\n                        op.idx[t] = (p + di) * N + (q + dj);\n                        op.inc[t] = s[m][di][dj];\n                        t++;\n                    }\n                }\n                opsInfo.push_back(op);\n            }\n        }\n    }\n    int totalOps = (int)opsInfo.size(); // should be 980\n\n    // Initial board remainders\n    vector<ll> modv(N * N);\n    ll score = 0;\n    for (int i = 0; i < N * N; i++) {\n        modv[i] = base[i] % MOD;\n        score += modv[i];\n    }\n\n    vector<int> curOps;\n    curOps.reserve(K);\n\n    auto greedy_fill = [&](vector<ll>& modvRef, ll& scoreRef, vector<int>& opsVec, int maxAdd) {\n        for (int step = 0; step < maxAdd; step++) {\n            ll best_delta = 0;\n            int best_id = -1;\n            for (int opId = 0; opId < totalOps; opId++) {\n                const auto& op = opsInfo[opId];\n                ll delta = 0;\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modvRef[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    delta += nv - modvRef[pos];\n                }\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_id = opId;\n                }\n            }\n            if (best_delta > 0 && best_id != -1) {\n                const auto& op = opsInfo[best_id];\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modvRef[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    scoreRef += nv - modvRef[pos];\n                    modvRef[pos] = nv;\n                }\n                opsVec.push_back(best_id);\n            } else {\n                break;\n            }\n        }\n    };\n\n    // Initial greedy solution\n    greedy_fill(modv, score, curOps, K);\n\n    vector<int> bestOps = curOps;\n    ll bestScore = score;\n\n    // Simulated Annealing\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9; // seconds\n    const double T0 = 1e8;\n    const double T1 = 1e5;\n    double temp = T0;\n    int iter = 0;\n    const int CHECK_INTERVAL = 1024;\n    while (true) {\n        if ((iter & (CHECK_INTERVAL - 1)) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n            if (elapsed > TIME_LIMIT) break;\n            double progress = elapsed / TIME_LIMIT;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        iter++;\n        int L = (int)curOps.size();\n        int moveType;\n        uint64_t rstate = rng64();\n        if (L == 0) {\n            moveType = 1; // insert\n        } else if (L == K) {\n            moveType = (rstate & 15) ? 0 : 2; // mostly replace\n        } else {\n            int v = (int)(rstate % 100);\n            if (v < 70) moveType = 0;      // replace\n            else if (v < 85) moveType = 1; // insert\n            else moveType = 2;             // delete\n        }\n\n        if (moveType == 0) {\n            // replace\n            if (L == 0) continue;\n            int idx = (int)(rstate % L);\n            int oldOpId = curOps[idx];\n            int newOpId = rand_int(totalOps);\n            if (newOpId == oldOpId) continue;\n            const auto& oldOp = opsInfo[oldOpId];\n            const auto& newOp = opsInfo[newOpId];\n            int idxs[18];\n            ll deltaAdd[18];\n            ll newMods[18];\n            int cnt = 0;\n            auto add_delta = [&](int pos, ll d) {\n                for (int t = 0; t < cnt; t++) {\n                    if (idxs[t] == pos) {\n                        deltaAdd[t] += d;\n                        return;\n                    }\n                }\n                idxs[cnt] = pos;\n                deltaAdd[cnt] = d;\n                cnt++;\n            };\n            for (int t = 0; t < 9; t++) add_delta(oldOp.idx[t], - (ll)oldOp.inc[t]);\n            for (int t = 0; t < 9; t++) add_delta(newOp.idx[t], (ll)newOp.inc[t]);\n            ll deltaScore = 0;\n            for (int t = 0; t < cnt; t++) {\n                int pos = idxs[t];\n                ll nm = modv[pos] + deltaAdd[t];\n                if (nm >= MOD) nm -= MOD;\n                else if (nm < 0) nm += MOD;\n                deltaScore += nm - modv[pos];\n                newMods[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < cnt; t++) {\n                    modv[idxs[t]] = newMods[t];\n                }\n                curOps[idx] = newOpId;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else if (moveType == 1) {\n            // insert\n            if (L >= K) continue;\n            int newOpId = (int)(rstate % totalOps);\n            const auto& op = opsInfo[newOpId];\n            ll deltaScore = 0;\n            ll newModsArr[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nm = modv[pos] + op.inc[t];\n                if (nm >= MOD) nm -= MOD;\n                deltaScore += nm - modv[pos];\n                newModsArr[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < 9; t++) {\n                    modv[op.idx[t]] = newModsArr[t];\n                }\n                curOps.push_back(newOpId);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else {\n            // delete\n            if (L == 0) continue;\n            int idx = (int)(rstate % L);\n            int oldOpId = curOps[idx];\n            const auto& op = opsInfo[oldOpId];\n            ll deltaScore = 0;\n            ll newModsArr[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nm = modv[pos] - op.inc[t];\n                if (nm < 0) nm += MOD;\n                deltaScore += nm - modv[pos];\n                newModsArr[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < 9; t++) {\n                    modv[op.idx[t]] = newModsArr[t];\n                }\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        }\n    }\n\n    // Reconstruct best state and final greedy extension\n    vector<ll> modv_best(N * N);\n    for (int i = 0; i < N * N; i++) modv_best[i] = base[i] % MOD;\n    ll score_best = 0;\n    for (int i = 0; i < N * N; i++) score_best += modv_best[i];\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        for (int t = 0; t < 9; t++) {\n            int pos = op.idx[t];\n            ll nv = modv_best[pos] + op.inc[t];\n            if (nv >= MOD) nv -= MOD;\n            score_best += nv - modv_best[pos];\n            modv_best[pos] = nv;\n        }\n    }\n    greedy_fill(modv_best, score_best, bestOps, K - (int)bestOps.size());\n\n    // Output\n    cout << bestOps.size() << \"\\n\";\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;\n    int hold;   // -1 if not holding\n    bool alive;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\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++) cin >> A[i][j];\n    }\n    int base = N + 1;               // pointers 0..N\n    int totalStates = 1;\n    for (int i = 0; i < N; i++) totalStates *= base; // (N+1)^N\n\n    auto encode = [&](const vector<int>& p) -> int {\n        int code = 0;\n        for (int i = 0; i < N; i++) code = code * base + p[i];\n        return code;\n    };\n    auto decode = [&](int code) -> vector<int> {\n        vector<int> p(N);\n        for (int i = N - 1; i >= 0; i--) {\n            p[i] = code % base;\n            code /= base;\n        }\n        return p;\n    };\n\n    const int INF = 1e9;\n    vector<int> dp(totalStates, INF);\n    vector<int> parent(totalStates, -1);\n    vector<int> choice(totalStates, -1);\n\n    dp[0] = 0; // state with all pointers 0\n\n    // DP over states in increasing total picked\n    for (int total = 0; total <= N * N; total++) {\n        for (int code = 0; code < totalStates; code++) {\n            int curCost = dp[code];\n            if (curCost == INF) continue;\n            vector<int> p = decode(code);\n            int sum = 0;\n            for (int v : p) sum += v;\n            if (sum != total) continue;\n            for (int s = 0; s < N; s++) {\n                if (p[s] >= N) continue;\n                int cid = A[s][p[s]];\n                int destRow = cid / N;\n                int cnt = 0;\n                // count previously dispatched larger ids of same dest row\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < p[i]; j++) {\n                        int cid2 = A[i][j];\n                        if (cid2 / N == destRow && cid2 > cid) cnt++;\n                    }\n                }\n                p[s]++;\n                int nextCode = encode(p);\n                p[s]--;\n                int newCost = curCost + cnt;\n                if (newCost < dp[nextCode]) {\n                    dp[nextCode] = newCost;\n                    parent[nextCode] = code;\n                    choice[nextCode] = s;\n                }\n            }\n        }\n    }\n\n    // reconstruct optimal task sequence (sources)\n    vector<int> seq_sources;\n    vector<int> full(N, N);\n    int fullCode = encode(full);\n    int cur = fullCode;\n    while (cur != 0) {\n        int s = choice[cur];\n        seq_sources.push_back(s);\n        cur = parent[cur];\n    }\n    reverse(seq_sources.begin(), seq_sources.end());\n\n    struct Task { int src; int cid; };\n    vector<Task> tasks;\n    vector<int> ptr(N, 0);\n    for (int s : seq_sources) {\n        tasks.push_back({s, A[s][ptr[s]]});\n        ptr[s]++;\n    }\n\n    // simulation to generate actions\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<Crane> cranes(N);\n    for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n    vector<int> idxSpawn(N, 0);\n    int dispatched = 0;\n    int task_idx = 0;\n    int turn = 0;\n    int totalContainers = N * N;\n    vector<string> ops(N);\n\n    const int TURN_LIMIT = 10000;\n    while (true) {\n        if (dispatched == totalContainers && cranes[0].hold == -1) break;\n        if (turn >= TURN_LIMIT) break;\n\n        // Step 1: spawn containers at receiving gates\n        for (int i = 0; i < N; i++) {\n            if (idxSpawn[i] >= N) continue;\n            if (grid[i][0] != -1) continue;\n            bool blocked = false;\n            for (int k = 0; k < N; k++) {\n                if (!cranes[k].alive) continue;\n                if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) {\n                    blocked = true;\n                    break;\n                }\n            }\n            if (!blocked) {\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n        }\n\n        vector<char> act(N, '.');\n        // small cranes bomb on turn 0, then idle\n        for (int i = 1; i < N; i++) {\n            act[i] = (turn == 0 ? 'B' : '.');\n        }\n\n        // decide action for large crane (index 0)\n        char a0 = '.';\n        Crane &lc = cranes[0];\n        if (lc.hold == -1) {\n            if (task_idx >= (int)tasks.size()) {\n                a0 = '.';\n            } else {\n                int sr = tasks[task_idx].src;\n                if (lc.r < sr) a0 = 'D';\n                else if (lc.r > sr) a0 = 'U';\n                else if (lc.c > 0) a0 = 'L';\n                else {\n                    if (grid[lc.r][lc.c] != -1) a0 = 'P';\n                    else a0 = '.';\n                }\n            }\n        } else { // carrying\n            int destRow = lc.hold / N;\n            if (lc.c < N - 1) a0 = 'R';\n            else if (lc.r < destRow) a0 = 'D';\n            else if (lc.r > destRow) a0 = 'U';\n            else {\n                if (grid[lc.r][lc.c] == -1) a0 = 'Q';\n                else a0 = '.';\n            }\n        }\n        act[0] = a0;\n\n        // append actions\n        for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n        // Step 2: execute actions\n        vector<pair<int,int>> newpos(N);\n        for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n        for (int i = 0; i < N; i++) {\n            if (!cranes[i].alive) continue;\n            char ac = act[i];\n            if (ac == 'U') newpos[i].first--;\n            else if (ac == 'D') newpos[i].first++;\n            else if (ac == 'L') newpos[i].second--;\n            else if (ac == 'R') newpos[i].second++;\n        }\n        // update cranes\n        for (int i = 0; i < N; i++) {\n            if (!cranes[i].alive) continue;\n            char ac = act[i];\n            if (ac == 'B') {\n                cranes[i].alive = false;\n                continue;\n            }\n            if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                cranes[i].r = newpos[i].first;\n                cranes[i].c = newpos[i].second;\n            } else if (ac == 'P') {\n                int r = cranes[i].r, c = cranes[i].c;\n                if (cranes[i].hold == -1 && grid[r][c] != -1) {\n                    cranes[i].hold = grid[r][c];\n                    grid[r][c] = -1;\n                }\n            } else if (ac == 'Q') {\n                int r = cranes[i].r, c = cranes[i].c;\n                if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                    grid[r][c] = cranes[i].hold;\n                    cranes[i].hold = -1;\n                    if (i == 0) task_idx++;\n                }\n            }\n        }\n\n        // Step 3: dispatch at gates\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N - 1] != -1) {\n                grid[i][N - 1] = -1;\n                dispatched++;\n            }\n        }\n        turn++;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << ops[i] << \"\\n\";\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing pii = pair<int,int>;\n\nstruct Plan {\n    vector<pii> path; // excludes (0,0)\n    ll R;\n    ll cost;\n    pii endpos;\n};\n\n// build path that ends at (0,1)\nvector<pii> build_pathA(int N){\n    vector<pii> p;\n    // first column downward (excluding start)\n    for(int r=1;r<N;r++) p.push_back({r,0});\n    // rows from bottom to top, skipping column 0\n    for(int r=N-1;r>=0;r--){\n        if(r%2==1){\n            for(int c=1;c<N;c++) p.push_back({r,c}); // left->right\n        }else{\n            for(int c=N-1;c>=1;c--) p.push_back({r,c}); // right->left\n        }\n    }\n    return p;\n}\n\n// build path that ends at (1,0)\nvector<pii> build_pathB(int N){\n    vector<pii> p;\n    // first row to the right (excluding start)\n    for(int c=1;c<N;c++) p.push_back({0,c});\n    // columns from right to left, skipping row 0\n    for(int c=N-1;c>=0;c--){\n        int offset = (N-1 - c);\n        if(offset%2==0){\n            for(int r=1;r<N;r++) p.push_back({r,c}); // top -> bottom\n        }else{\n            for(int r=N-1;r>=1;r--) p.push_back({r,c}); // bottom -> top\n        }\n    }\n    return p;\n}\n\nll simulate_cost(const vector<pii>& path, const vector<vector<int>>& h, ll& outR, pii& endpos){\n    int N = h.size();\n    ll pref=0;\n    ll minPref=0;\n    for(auto &co:path){\n        pref += h[co.first][co.second];\n        if(pref < minPref) minPref = pref;\n    }\n    ll R = -minPref;\n    outR = R;\n    ll cost=0;\n    ll load = R;\n    if(R>0) cost += R; // initial borrow\n    int cr=0, cc=0;\n    for(auto &co:path){\n        // move (adjacent)\n        cost += 100 + load;\n        int val = h[co.first][co.second];\n        cost += llabs((ll)val);\n        load += val;\n        cr = co.first; cc = co.second;\n    }\n    endpos = {cr,cc};\n    int dist = abs(cr) + abs(cc); // to (0,0)\n    cost += (ll)dist * (100 + load);\n    // final adjust start\n    cost += llabs(load); // load should equal R - h[0][0]\n    return cost;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cin>>h[i][j];\n        }\n    }\n\n    vector<pii> pathA = build_pathA(N);\n    vector<pii> pathB = build_pathB(N);\n    ll R1,R2;\n    pii end1,end2;\n    ll cost1 = simulate_cost(pathA, h, R1, end1);\n    ll cost2 = simulate_cost(pathB, h, R2, end2);\n\n    vector<pii> path = cost1 <= cost2 ? pathA : pathB;\n    ll R = cost1 <= cost2 ? R1 : R2;\n    pii endpos = cost1 <= cost2 ? end1 : end2;\n\n    vector<string> ops;\n    ll load = 0;\n    vector<vector<int>> g = h;\n\n    // initial borrow\n    if(R > 0){\n        ops.push_back(\"+\" + to_string(R));\n        load += R;\n        g[0][0] -= (int)R;\n    }\n\n    int cr=0, cc=0;\n    for(auto &co: path){\n        int nr = co.first, nc = co.second;\n        // move (adjacent)\n        if(nr == cr+1) ops.push_back(\"D\");\n        else if(nr == cr-1) ops.push_back(\"U\");\n        else if(nc == cc+1) ops.push_back(\"R\");\n        else if(nc == cc-1) ops.push_back(\"L\");\n        else {\n            // fallback: Manhattan path (should not happen)\n            while(cr < nr){ ops.push_back(\"D\"); cr++; }\n            while(cr > nr){ ops.push_back(\"U\"); cr--; }\n            while(cc < nc){ ops.push_back(\"R\"); cc++; }\n            while(cc > nc){ ops.push_back(\"L\"); cc--; }\n        }\n        cr = nr; cc = nc;\n        int val = g[cr][cc];\n        if(val > 0){\n            ops.push_back(\"+\" + to_string(val));\n            load += val;\n            g[cr][cc] = 0;\n        }else if(val < 0){\n            ops.push_back(\"-\" + to_string(-val));\n            load -= -val;\n            g[cr][cc] = 0;\n        } // if zero, skip\n    }\n\n    // return to start (0,0)\n    while(cr > 0){ ops.push_back(\"U\"); cr--; }\n    while(cc > 0){ ops.push_back(\"L\"); cc--; }\n\n    // final adjust start\n    int sval = g[0][0];\n    if(sval > 0){\n        ops.push_back(\"+\" + to_string(sval));\n        load += sval;\n        g[0][0] = 0;\n    }else if(sval < 0){\n        ops.push_back(\"-\" + to_string(-sval));\n        load -= -sval;\n        g[0][0] = 0;\n    }\n\n    // output operations\n    for(auto &s: ops){\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int SEED_COUNT = 2 * N * (N - 1); // 60 when N=6\n    vector<array<int, 15>> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; i++) {\n        for (int j = 0; j < M; j++) cin >> seeds[i][j];\n    }\n\n    // precompute center for distance\n    double cx = (N - 1) / 2.0;\n    double cy = (N - 1) / 2.0;\n\n    for (int turn = 0; turn < T; turn++) {\n        // compute values\n        vector<int> val(SEED_COUNT, 0);\n        for (int i = 0; i < SEED_COUNT; i++) {\n            int s = 0;\n            for (int l = 0; l < M; l++) s += seeds[i][l];\n            val[i] = s;\n        }\n        // best seed\n        int best_id = 0;\n        for (int i = 1; i < SEED_COUNT; i++) {\n            if (val[i] > val[best_id]) best_id = i;\n        }\n        // champions per attribute\n        vector<int> champion(M, 0);\n        vector<int> champCount(SEED_COUNT, 0);\n        for (int l = 0; l < M; l++) {\n            int cid = 0;\n            for (int i = 1; i < SEED_COUNT; i++) {\n                if (seeds[i][l] > seeds[cid][l] ||\n                    (seeds[i][l] == seeds[cid][l] && val[i] > val[cid])) {\n                    cid = i;\n                }\n            }\n            champion[l] = cid;\n            champCount[cid]++;\n        }\n        // improvers relative to best\n        struct Imp {\n            int imp;\n            int id;\n        };\n        vector<Imp> improvers;\n        improvers.reserve(SEED_COUNT);\n        for (int i = 0; i < SEED_COUNT; i++) if (i != best_id) {\n            int cmax = 0;\n            for (int l = 0; l < M; l++) {\n                cmax += max(seeds[best_id][l], seeds[i][l]);\n            }\n            improvers.push_back({cmax - val[best_id], i});\n        }\n        sort(improvers.begin(), improvers.end(), [&](const Imp &a, const Imp &b) {\n            if (a.imp != b.imp) return a.imp > b.imp;\n            return val[a.id] > val[b.id];\n        });\n        const int K_IMP = 8; // number of improvers to select\n\n        // selection of seeds to plant\n        vector<char> used(SEED_COUNT, 0);\n        vector<int> selected;\n        auto add_sel = [&](int id) {\n            if (!used[id]) {\n                used[id] = 1;\n                selected.push_back(id);\n            }\n        };\n        add_sel(best_id);\n        for (int l = 0; l < M; l++) add_sel(champion[l]);\n        for (int k = 0; k < (int)improvers.size() && k < K_IMP; k++) add_sel(improvers[k].id);\n\n        // fill with top value seeds\n        vector<int> order(SEED_COUNT);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return val[a] > val[b];\n        });\n        for (int id : order) {\n            if ((int)selected.size() >= N * N) break;\n            add_sel(id);\n        }\n\n        // trim if somehow over\n        if ((int)selected.size() > N * N) {\n            vector<char> essential(SEED_COUNT, 0);\n            essential[best_id] = 1;\n            for (int l = 0; l < M; l++) essential[champion[l]] = 1;\n            vector<int> removable;\n            for (int id : selected) if (!essential[id]) removable.push_back(id);\n            sort(removable.begin(), removable.end(), [&](int a, int b) {\n                return val[a] < val[b]; // remove lowest value first\n            });\n            int idx = 0;\n            while ((int)selected.size() > N * N && idx < (int)removable.size()) {\n                used[removable[idx]] = 0;\n                idx++;\n                selected.pop_back(); // will rebuild below\n            }\n            selected.clear();\n            for (int i = 0; i < SEED_COUNT; i++) if (used[i]) selected.push_back(i);\n        }\n\n        // placement grid\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<char> placed(SEED_COUNT, 0);\n\n        int ci = N / 2 - 1; // 2 for N=6\n        int cj = N / 2 - 1; // 2\n        grid[ci][cj] = best_id;\n        placed[best_id] = 1;\n\n        // pick neighbor improvers to place around best\n        vector<int> neighborSeeds;\n        for (int k = 0; k < (int)improvers.size() && (int)neighborSeeds.size() < 4; k++) {\n            int id = improvers[k].id;\n            if (used[id] && !placed[id]) {\n                neighborSeeds.push_back(id);\n            }\n        }\n        // fill remaining neighbor slots with highest value remaining\n        for (int id : order) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            if (used[id] && !placed[id]) neighborSeeds.push_back(id);\n        }\n        vector<pair<int, int>> neighborPos;\n        if (cj - 1 >= 0) neighborPos.push_back({ci, cj - 1});\n        if (cj + 1 < N) neighborPos.push_back({ci, cj + 1});\n        if (ci - 1 >= 0) neighborPos.push_back({ci - 1, cj});\n        if (ci + 1 < N) neighborPos.push_back({ci + 1, cj});\n        for (int idx = 0; idx < (int)neighborPos.size() && idx < (int)neighborSeeds.size(); idx++) {\n            auto [ri, rj] = neighborPos[idx];\n            grid[ri][rj] = neighborSeeds[idx];\n            placed[neighborSeeds[idx]] = 1;\n        }\n\n        // build remaining seed list: champions first then others\n        vector<int> remChamp, remOthers;\n        for (int id : selected) {\n            if (placed[id]) continue;\n            if (champCount[id] > 0) remChamp.push_back(id);\n            else remOthers.push_back(id);\n        }\n        sort(remChamp.begin(), remChamp.end(), [&](int a, int b) {\n            if (champCount[a] != champCount[b]) return champCount[a] > champCount[b];\n            return val[a] > val[b];\n        });\n        sort(remOthers.begin(), remOthers.end(), [&](int a, int b) {\n            return val[a] > val[b];\n        });\n        vector<int> placementOrder;\n        placementOrder.insert(placementOrder.end(), remChamp.begin(), remChamp.end());\n        placementOrder.insert(placementOrder.end(), remOthers.begin(), remOthers.end());\n\n        // build coordinate list of empty cells sorted by distance to center\n        struct CoordInfo {\n            double dist;\n            int deg;\n            int i, j;\n        };\n        vector<CoordInfo> coords;\n        int di[4] = {-1, 1, 0, 0};\n        int dj[4] = {0, 0, -1, 1};\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != -1) continue;\n                int deg = 0;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (0 <= ni && ni < N && 0 <= nj && nj < N) deg++;\n                }\n                double dist = fabs(i - cx) + fabs(j - cy);\n                coords.push_back({dist, deg, i, j});\n            }\n        }\n        sort(coords.begin(), coords.end(), [&](const CoordInfo &a, const CoordInfo &b) {\n            if (a.dist != b.dist) return a.dist < b.dist;\n            if (a.deg != b.deg) return a.deg > b.deg;\n            if (a.i != b.i) return a.i < b.i;\n            return a.j < b.j;\n        });\n\n        for (int idx = 0; idx < (int)placementOrder.size() && idx < (int)coords.size(); idx++) {\n            int id = placementOrder[idx];\n            auto c = coords[idx];\n            grid[c.i][c.j] = id;\n            placed[id] = 1;\n        }\n\n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j) cout << ' ';\n                cout << grid[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next generation seeds\n        if (turn != T - 1) {\n            for (int i = 0; i < SEED_COUNT; i++) {\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i][j];\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    vector<Pos> sources, targets;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1' && t[i][j] == '0') sources.push_back({i, j});\n            else if (s[i][j] == '0' && t[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n\n    int num = (int)sources.size(); // should equal targets.size()\n\n    // design arm: just root (which is also fingertip)\n    cout << 1 << \"\\n\";\n    if (num == 0) { // already satisfied\n        cout << 0 << \" \" << 0 << \"\\n\";\n        return 0;\n    }\n\n    // occupancy grid\n    vector<vector<int>> occ(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) occ[i][j] = (s[i][j] == '1');\n\n    // choose starting source near centroid\n    double cx = 0.0, cy = 0.0;\n    for (auto &p : sources) { cx += p.x; cy += p.y; }\n    cx /= num; cy /= num;\n    double bestDist = 1e18;\n    int startIdx = 0;\n    for (int i = 0; i < num; i++) {\n        double d = fabs((double)sources[i].x - cx) + fabs((double)sources[i].y - cy);\n        if (d < bestDist) {\n            bestDist = d;\n            startIdx = i;\n        }\n    }\n\n    Pos cur = sources[startIdx];\n    cout << cur.x << \" \" << cur.y << \"\\n\"; // initial root position\n\n    vector<bool> usedS(num, false), usedT(num, false);\n    usedS[startIdx] = true;\n    int remainingS = num - 1;\n    bool hold = false;\n\n    auto manh = [](const Pos &a, const Pos &b) -> int {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    };\n\n    vector<string> cmds;\n\n    auto moveWithAction = [&](const Pos &dest, bool doAction, bool pick) {\n        int dx = dest.x - cur.x;\n        int dy = dest.y - cur.y;\n        // move along x\n        if (dx < 0) {\n            for (int k = 0; k < -dx; k++) {\n                char act = (doAction && k == -dx - 1 && dy == 0) ? 'P' : '.';\n                cmds.push_back(string() + 'U' + act);\n            }\n        } else if (dx > 0) {\n            for (int k = 0; k < dx; k++) {\n                char act = (doAction && k == dx - 1 && dy == 0) ? 'P' : '.';\n                cmds.push_back(string() + 'D' + act);\n            }\n        }\n        // move along y\n        if (dy < 0) {\n            for (int k = 0; k < -dy; k++) {\n                char act = (doAction && k == -dy - 1) ? 'P' : '.';\n                cmds.push_back(string() + 'L' + act);\n            }\n        } else if (dy > 0) {\n            for (int k = 0; k < dy; k++) {\n                char act = (doAction && k == dy - 1) ? 'P' : '.';\n                cmds.push_back(string() + 'R' + act);\n            }\n        }\n        if (dx == 0 && dy == 0) {\n            char act = doAction ? 'P' : '.';\n            cmds.push_back(string() + '.' + act);\n        }\n        cur = dest;\n        if (doAction) {\n            if (pick) {\n                hold = true;\n                occ[cur.x][cur.y] = 0;\n            } else {\n                hold = false;\n                occ[cur.x][cur.y] = 1;\n            }\n        }\n    };\n\n    // pick first source (already at cur)\n    moveWithAction(cur, true, true);\n    // choose nearest target for first source\n    int bestTi = -1, bestd = 1e9;\n    for (int j = 0; j < num; j++) if (!usedT[j]) {\n        int d = manh(cur, targets[j]);\n        if (d < bestd) {\n            bestd = d;\n            bestTi = j;\n        }\n    }\n    usedT[bestTi] = true;\n    moveWithAction(targets[bestTi], true, false);\n\n    while (remainingS > 0) {\n        // choose nearest unused source to current position\n        int bestSi = -1; bestd = 1e9;\n        for (int i = 0; i < num; i++) if (!usedS[i]) {\n            int d = manh(cur, sources[i]);\n            if (d < bestd) {\n                bestd = d;\n                bestSi = i;\n            }\n        }\n        usedS[bestSi] = true;\n        remainingS--;\n\n        // move to source and pick\n        moveWithAction(sources[bestSi], true, true);\n\n        // choose nearest unused target to this source\n        bestTi = -1; bestd = 1e9;\n        for (int j = 0; j < num; j++) if (!usedT[j]) {\n            int d = manh(sources[bestSi], targets[j]);\n            if (d < bestd) {\n                bestd = d;\n                bestTi = j;\n            }\n        }\n        usedT[bestTi] = true;\n        // move to target and place\n        moveWithAction(targets[bestTi], true, false);\n    }\n\n    for (auto &cmd : cmds) {\n        cout << cmd << \"\\n\";\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect{\n    int x1, x2, y1, y2;\n};\nconst int LIM = 100000;\n\nstruct Evaluator {\n    int tot;\n    vector<int> xs, ys, ws;\n    Evaluator(const vector<int>& _xs, const vector<int>& _ys, const vector<int>& _ws)\n        : tot((int)_xs.size()), xs(_xs), ys(_ys), ws(_ws) {}\n    inline int eval(const Rect& r) const {\n        int s = 0;\n        int x1 = r.x1, x2 = r.x2, y1 = r.y1, y2 = r.y2;\n        for (int i = 0; i < tot; i++) {\n            int x = xs[i];\n            if (x < x1 || x > x2) continue;\n            int y = ys[i];\n            if (y < y1 || y > y2) continue;\n            s += ws[i];\n        }\n        return s;\n    }\n};\n\ninline Rect normalize(Rect r){\n    if(r.x1 > r.x2) swap(r.x1, r.x2);\n    if(r.y1 > r.y2) swap(r.y1, r.y2);\n    r.x1 = max(0, min(LIM, r.x1));\n    r.x2 = max(0, min(LIM, r.x2));\n    r.y1 = max(0, min(LIM, r.y1));\n    r.y2 = max(0, min(LIM, r.y2));\n    if(r.x1 == r.x2){\n        if(r.x2 < LIM) r.x2++;\n        else if(r.x1 > 0) r.x1--;\n        else r.x2 = r.x1 + 1;\n    }\n    if(r.y1 == r.y2){\n        if(r.y2 < LIM) r.y2++;\n        else if(r.y1 > 0) r.y1--;\n        else r.y2 = r.y1 + 1;\n    }\n    return r;\n}\n\nRect bestGridRect(int G, const vector<int>& xs, const vector<int>& ys, const vector<int>& ws){\n    int cell = (LIM + G - 1) / G;\n    vector<vector<int>> diff(G, vector<int>(G, 0));\n    int tot = (int)xs.size();\n    for(int i = 0; i < tot; i++){\n        int cx = xs[i] / cell; if(cx >= G) cx = G-1;\n        int cy = ys[i] / cell; if(cy >= G) cy = G-1;\n        diff[cy][cx] += ws[i];\n    }\n    int best = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n    vector<int> col(G);\n    for(int top = 0; top < G; top++){\n        fill(col.begin(), col.end(), 0);\n        for(int bottom = top; bottom < G; bottom++){\n            for(int x = 0; x < G; x++) col[x] += diff[bottom][x];\n            int cur = 0, start = 0;\n            int bestSum = -1e9, bestL = 0, bestR = 0;\n            for(int x = 0; x < G; x++){\n                if(cur <= 0){\n                    cur = col[x];\n                    start = x;\n                }else{\n                    cur += col[x];\n                }\n                if(cur > bestSum){\n                    bestSum = cur;\n                    bestL = start;\n                    bestR = x;\n                }\n            }\n            if(bestSum > best){\n                best = bestSum;\n                int x1 = bestL * cell;\n                int x2 = min(LIM, (bestR + 1) * cell);\n                int y1 = top * cell;\n                int y2 = min(LIM, (bottom + 1) * cell);\n                bestRect = normalize({x1, x2, y1, y2});\n            }\n        }\n    }\n    return bestRect;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin >> N)) return 0;\n    const int TOT = 2 * N;\n    vector<int> xs(TOT), ys(TOT), ws(TOT);\n    for(int i = 0; i < TOT; i++){\n        int x, y;\n        cin >> x >> y;\n        xs[i] = x;\n        ys[i] = y;\n        ws[i] = (i < N) ? 1 : -1;\n    }\n    Evaluator eval(xs, ys, ws);\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    // bounding box of mackerels\n    int minMx = LIM, maxMx = 0, minMy = LIM, maxMy = 0;\n    for(int i = 0; i < N; i++){\n        minMx = min(minMx, xs[i]);\n        maxMx = max(maxMx, xs[i]);\n        minMy = min(minMy, ys[i]);\n        maxMy = max(maxMy, ys[i]);\n    }\n    Rect bestRect = normalize({minMx, maxMx, minMy, maxMy});\n    int bestScore = eval.eval(bestRect);\n    auto consider = [&](const Rect& r){\n        Rect nr = normalize(r);\n        int sc = eval.eval(nr);\n        if(sc > bestScore){\n            bestScore = sc;\n            bestRect = nr;\n        }\n    };\n    // coarse grid search\n    vector<int> Gs = {10, 20, 30, 40};\n    for(int g : Gs){\n        Rect r = bestGridRect(g, xs, ys, ws);\n        consider(r);\n    }\n    // random search\n    vector<int> sizes = {500, 800, 1000, 1200, 1500, 2000, 2500, 3000, 4000, 5000, 6000, 8000, 10000, 12000, 15000, 20000, 25000};\n    auto startTime = chrono::steady_clock::now();\n    const double RAND_TIME = 1.5; // seconds\n    int iter = 0;\n    while(true){\n        iter++;\n        int t = rng() % 3;\n        if(t == 0){\n            int idx = rng() % N;\n            int w = sizes[rng() % sizes.size()];\n            int h = sizes[rng() % sizes.size()];\n            Rect r{xs[idx] - w, xs[idx] + w, ys[idx] - h, ys[idx] + h};\n            consider(r);\n        }else if(t == 1){\n            int i = rng() % TOT;\n            int j = rng() % TOT;\n            int x1 = min(xs[i], xs[j]);\n            int x2 = max(xs[i], xs[j]);\n            int y1 = min(ys[i], ys[j]);\n            int y2 = max(ys[i], ys[j]);\n            int marg = sizes[rng() % sizes.size()] / 2;\n            Rect r{x1 - marg, x2 + marg, y1 - marg, y2 + marg};\n            consider(r);\n        }else{\n            Rect r = bestRect;\n            int delta = sizes[rng() % sizes.size()] / 2 + 1;\n            int dx1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dx2 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy2 = (int)(rng() % (2 * delta + 1)) - delta;\n            r.x1 += dx1; r.x2 += dx2; r.y1 += dy1; r.y2 += dy2;\n            consider(r);\n        }\n        if((iter & 31) == 0){\n            double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - startTime).count();\n            if(elapsed > RAND_TIME) break;\n        }\n    }\n    // hill climbing around bestRect\n    vector<int> steps = {20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50};\n    Rect cur = bestRect;\n    for(int step : steps){\n        bool improved = true;\n        while(improved){\n            improved = false;\n            // left, right, bottom, top edges\n            // 0:x1,1:x2,2:y1,3:y2\n            for(int edge = 0; edge < 4; edge++){\n                for(int dir = -1; dir <= 1; dir += 2){\n                    Rect r = cur;\n                    if(edge == 0) r.x1 += dir * step;\n                    else if(edge == 1) r.x2 += dir * step;\n                    else if(edge == 2) r.y1 += dir * step;\n                    else r.y2 += dir * step;\n                    r = normalize(r);\n                    int sc = eval.eval(r);\n                    if(sc > bestScore){\n                        bestScore = sc;\n                        bestRect = cur = r;\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n    // output rectangle\n    cout << 4 << \"\\n\";\n    cout << bestRect.x1 << \" \" << bestRect.y1 << \"\\n\";\n    cout << bestRect.x2 << \" \" << bestRect.y1 << \"\\n\";\n    cout << bestRect.x2 << \" \" << bestRect.y2 << \"\\n\";\n    cout << bestRect.x1 << \" \" << bestRect.y2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Command {\n    int p;\n    int r;\n    char d;\n    int b;\n};\n\nstruct Candidate {\n    vector<Command> cmds;\n    long long estScore;\n};\n\n// simulate placement given commands and original (planned) widths/heights\npair<long long, long long> simulate(const vector<Command>& cmds,\n                                    const vector<long long>& w_plan,\n                                    const vector<long long>& h_plan) {\n    int N = (int)w_plan.size();\n    vector<long long> x(N, 0), y(N, 0), ww(N, 0), hh(N, 0);\n    vector<char> placed(N, 0);\n    long long W = 0, H = 0;\n    for (const auto& cmd : cmds) {\n        int i = cmd.p;\n        long long w = (cmd.r == 0 ? w_plan[i] : h_plan[i]);\n        long long h = (cmd.r == 0 ? h_plan[i] : w_plan[i]);\n        long long xi, yi;\n        if (cmd.d == 'U') {\n            xi = (cmd.b == -1) ? 0LL : x[cmd.b] + ww[cmd.b];\n            yi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long l1 = xi, r1 = xi + w;\n                long long l2 = x[j], r2 = x[j] + ww[j];\n                if (max(l1, l2) < min(r1, r2)) {\n                    yi = max(yi, y[j] + hh[j]);\n                }\n            }\n        } else { // 'L'\n            yi = (cmd.b == -1) ? 0LL : y[cmd.b] + hh[cmd.b];\n            xi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long t1 = yi, b1 = yi + h;\n                long long t2 = y[j], b2 = y[j] + hh[j];\n                if (max(t1, t2) < min(b1, b2)) {\n                    xi = max(xi, x[j] + ww[j]);\n                }\n            }\n        }\n        x[i] = xi; y[i] = yi; ww[i] = w; hh[i] = h; placed[i] = 1;\n        W = max(W, xi + w);\n        H = max(H, yi + h);\n    }\n    return {W, H};\n}\n\nvector<int> dp_partition(const vector<long long>& w, const vector<long long>& h_eff, long long Wlim) {\n    int N = (int)w.size();\n    const long long INF = (1LL<<60);\n    vector<long long> dp(N+1, INF);\n    vector<int> prv(N+1, -1);\n    dp[0] = 0;\n    for (int i = 0; i < N; i++) {\n        long long width = 0;\n        long long height = 0;\n        for (int j = i; j >= 0; j--) {\n            width += w[j];\n            if (width > Wlim) break;\n            height = max(height, h_eff[j]);\n            if (dp[j] + height < dp[i+1]) {\n                dp[i+1] = dp[j] + height;\n                prv[i+1] = j;\n            }\n        }\n    }\n    return prv;\n}\n\nvector<pair<int,int>> reconstruct_rows(const vector<int>& prv) {\n    vector<pair<int,int>> rows;\n    int idx = (int)prv.size() - 1;\n    while (idx > 0) {\n        int j = prv[idx];\n        if (j < 0) break;\n        rows.push_back({j, idx});\n        idx = j;\n    }\n    reverse(rows.begin(), rows.end());\n    return rows;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n    // clamp observed to plausible range for planning\n    vector<long long> w_plan(N), h_plan(N);\n    for (int i = 0; i < N; i++) {\n        long long w = w_obs[i];\n        long long h = h_obs[i];\n        if (w < 1) w = 1;\n        if (h < 1) h = 1;\n        if (w > 100000) w = 100000;\n        if (h > 100000) h = 100000;\n        w_plan[i] = w;\n        h_plan[i] = h;\n    }\n\n    vector<vector<int>> r_versions;\n    // orientation to minimize height\n    vector<int> r_minH(N);\n    for (int i = 0; i < N; i++) {\n        r_minH[i] = (w_plan[i] < h_plan[i]) ? 1 : 0;\n    }\n    r_versions.push_back(r_minH);\n    // orientation to minimize width\n    vector<int> r_minW(N);\n    for (int i = 0; i < N; i++) {\n        r_minW[i] = (w_plan[i] > h_plan[i]) ? 1 : 0;\n    }\n    r_versions.push_back(r_minW);\n    // unrotated\n    vector<int> r_none(N, 0);\n    r_versions.push_back(r_none);\n\n    vector<long long> margin_list;\n    margin_list.push_back(0);\n    margin_list.push_back(sigma / 2);\n    margin_list.push_back(sigma);\n    sort(margin_list.begin(), margin_list.end());\n    margin_list.erase(unique(margin_list.begin(), margin_list.end()), margin_list.end());\n\n    vector<Candidate> candidates;\n\n    for (auto &r_choice : r_versions) {\n        vector<long long> w_rot(N), h_rot(N);\n        long long sumW = 0, maxW = 0;\n        for (int i = 0; i < N; i++) {\n            long long w = (r_choice[i] == 0 ? w_plan[i] : h_plan[i]);\n            long long h = (r_choice[i] == 0 ? h_plan[i] : w_plan[i]);\n            w_rot[i] = w;\n            h_rot[i] = h;\n            sumW += w;\n            if (w > maxW) maxW = w;\n        }\n        // generate Wlim list\n        set<long long> Wset;\n        Wset.insert(maxW);\n        Wset.insert(sumW);\n        int Rmax = min(10, N);\n        for (int R = 2; R <= Rmax; R++) {\n            long long W = (sumW + R - 1) / R;\n            if (W < maxW) W = maxW;\n            Wset.insert(W);\n        }\n        int K = 6;\n        for (int k = 0; k < K; k++) {\n            double ratio = (K == 1) ? 0.0 : (double)k / (double)(K - 1);\n            double val = (double)maxW * pow((double)sumW / (double)maxW, ratio);\n            long long W = (long long)(val + 0.5);\n            if (W < maxW) W = maxW;\n            if (W > sumW) W = sumW;\n            Wset.insert(W);\n        }\n        vector<long long> Wlims(Wset.begin(), Wset.end());\n\n        for (long long margin : margin_list) {\n            vector<long long> h_eff(N);\n            for (int i = 0; i < N; i++) h_eff[i] = h_rot[i] + margin;\n            for (long long Wlim : Wlims) {\n                vector<int> prv = dp_partition(w_rot, h_eff, Wlim);\n                vector<pair<int,int>> rows = reconstruct_rows(prv);\n                if (rows.empty()) continue;\n                // ref indices\n                vector<int> ref_idx(rows.size());\n                for (size_t ri = 0; ri < rows.size(); ri++) {\n                    int l = rows[ri].first;\n                    int r = rows[ri].second;\n                    long long besth = -1;\n                    int idx = l;\n                    for (int i = l; i < r; i++) {\n                        if (h_eff[i] > besth || (h_eff[i] == besth && i > idx)) {\n                            besth = h_eff[i];\n                            idx = i;\n                        }\n                    }\n                    ref_idx[ri] = idx;\n                }\n                vector<Command> cmds;\n                for (size_t ri = 0; ri < rows.size(); ri++) {\n                    int b = (ri == 0) ? -1 : ref_idx[ri - 1];\n                    int l = rows[ri].first;\n                    int r = rows[ri].second;\n                    for (int i = l; i < r; i++) {\n                        cmds.push_back({i, r_choice[i], 'L', b});\n                    }\n                }\n                auto est = simulate(cmds, w_plan, h_plan);\n                Candidate cand;\n                cand.cmds = move(cmds);\n                cand.estScore = est.first + est.second;\n                candidates.push_back(move(cand));\n            }\n        }\n    }\n    // Vertical stack candidate using minWidth orientation\n    {\n        vector<int> r_choice = r_minW;\n        vector<Command> cmds;\n        for (int i = 0; i < N; i++) {\n            cmds.push_back({i, r_choice[i], 'U', -1});\n        }\n        auto est = simulate(cmds, w_plan, h_plan);\n        Candidate cand{cmds, est.first + est.second};\n        candidates.push_back(move(cand));\n    }\n\n    if (candidates.empty()) {\n        // fallback: simple row with no rotation\n        vector<Command> cmds;\n        for (int i = 0; i < N; i++) cmds.push_back({i, 0, 'L', -1});\n        auto est = simulate(cmds, w_plan, h_plan);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n        return a.estScore < b.estScore;\n    });\n\n    int distinct_out = min((int)candidates.size(), T);\n    vector<vector<Command>> outputs;\n    for (int i = 0; i < distinct_out; i++) outputs.push_back(candidates[i].cmds);\n    while ((int)outputs.size() < T) {\n        outputs.push_back(outputs[0]); // repeat best\n    }\n\n    for (int t = 0; t < T; t++) {\n        const auto& cmds = outputs[t];\n        cout << cmds.size() << \"\\n\";\n        for (auto &cmd : cmds) {\n            cout << cmd.p << \" \" << cmd.r << \" \" << cmd.d << \" \" << cmd.b << \"\\n\";\n        }\n        cout.flush();\n        long long Wm, Hm;\n        if (!(cin >> Wm >> Hm)) break;\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    vector<int> parent;\n    long long score;\n};\n\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n\n    // Precompute all-pairs shortest paths (unweighted BFS from each node)\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    for (int s = 0; s < N; s++) {\n        auto &drow = dist[s];\n        queue<int> q;\n        drow[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            int nd = drow[u] + 1;\n            for (int v : adj[u]) {\n                if (drow[v] == INF) {\n                    drow[v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Eccentricity\n    vector<int> ecc(N, 0);\n    for (int i = 0; i < N; i++) {\n        int mx = 0;\n        for (int j = 0; j < N; j++) {\n            if (dist[i][j] > mx) mx = dist[i][j];\n        }\n        ecc[i] = mx;\n    }\n\n    auto add_seed = [&](int v, vector<int> &seeds, vector<char> &seen) {\n        if (!seen[v]) {\n            seen[v] = 1;\n            seeds.push_back(v);\n        }\n    };\n\n    vector<int> seeds;\n    vector<char> seen_seed(N, 0);\n    // low A seeds\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (A[i] != A[j]) return A[i] < A[j];\n        return i < j;\n    });\n    int kLow = min(8, N);\n    for (int i = 0; i < kLow; i++) add_seed(idx[i], seeds, seen_seed);\n\n    // min eccentricity seed (graph center)\n    int cen = 0;\n    for (int i = 1; i < N; i++) {\n        if (ecc[i] < ecc[cen] || (ecc[i] == ecc[cen] && A[i] < A[cen])) cen = i;\n    }\n    add_seed(cen, seeds, seen_seed);\n\n    // closest to geometric center (500,500)\n    long long bestd = (long long)(x[0] - 500) * (x[0] - 500) + (long long)(y[0] - 500) * (y[0] - 500);\n    int centerCoord = 0;\n    for (int i = 1; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) + (long long)(y[i] - 500) * (y[i] - 500);\n        if (d < bestd) {\n            bestd = d;\n            centerCoord = i;\n        }\n    }\n    add_seed(centerCoord, seeds, seen_seed);\n\n    // farthest from center\n    long long maxd = bestd;\n    int farCoord = centerCoord;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) + (long long)(y[i] - 500) * (y[i] - 500);\n        if (d > maxd) {\n            maxd = d;\n            farCoord = i;\n        }\n    }\n    add_seed(farCoord, seeds, seen_seed);\n\n    auto prune_roots = [&](vector<int> &roots) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int idx_r = 0; idx_r < (int)roots.size(); idx_r++) {\n                vector<int> tmp(N, INF);\n                for (int j = 0; j < (int)roots.size(); j++) {\n                    if (j == idx_r) continue;\n                    int r = roots[j];\n                    for (int i = 0; i < N; i++) {\n                        int d = dist[r][i];\n                        if (d < tmp[i]) tmp[i] = d;\n                    }\n                }\n                int mx = *max_element(tmp.begin(), tmp.end());\n                if (mx <= H) {\n                    roots.erase(roots.begin() + idx_r);\n                    changed = true;\n                    break;\n                }\n            }\n        }\n    };\n\n    auto select_roots_farthest = [&](int seed) {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> minDist = dist[seed];\n        while (true) {\n            int farNode = -1, farDist = -1, farA = 1e9;\n            for (int i = 0; i < N; i++) {\n                if (minDist[i] > farDist || (minDist[i] == farDist && A[i] < farA)) {\n                    farDist = minDist[i];\n                    farNode = i;\n                    farA = A[i];\n                }\n            }\n            if (farDist <= H) break;\n            roots.push_back(farNode);\n            for (int i = 0; i < N; i++) {\n                int d = dist[farNode][i];\n                if (d < minDist[i]) minDist[i] = d;\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_cover_greedy = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        while (remaining > 0) {\n            int best = -1, bestCnt = -1, bestA = 1e9;\n            for (int c = 0; c < N; c++) {\n                int cnt = 0;\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[c][i] <= H) cnt++;\n                }\n                if (cnt > bestCnt || (cnt == bestCnt && A[c] < bestA)) {\n                    bestCnt = cnt;\n                    best = c;\n                    bestA = A[c];\n                }\n            }\n            if (best == -1) break; // should not happen\n            roots.push_back(best);\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[best][i] <= H) {\n                    covered[i] = 1;\n                    remaining--;\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto build_solution = [&](const vector<int> &roots) -> Solution {\n        vector<int> parent(N, -2);\n        vector<int> depth(N, INF);\n        queue<int> q;\n        for (int r : roots) {\n            parent[r] = -1;\n            depth[r] = 0;\n            q.push(r);\n        }\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            if (depth[u] >= H) continue;\n            int nd = depth[u] + 1;\n            for (int v : adj[u]) {\n                if (depth[v] > nd) {\n                    depth[v] = nd;\n                    parent[v] = u;\n                    q.push(v);\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            if (depth[i] == INF) {\n                parent[i] = -1;\n                depth[i] = 0;\n            }\n        }\n\n        // Leaf reparenting to increase depth\n        vector<int> childCnt(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) childCnt[parent[v]]++;\n        }\n        bool changed = true;\n        int iter = 0;\n        while (changed && iter < H * 2 + 5) {\n            changed = false;\n            iter++;\n            for (int v = 0; v < N; v++) {\n                if (childCnt[v] == 0) {\n                    int bestDepth = depth[v];\n                    int bestPar = -1;\n                    for (int u : adj[v]) {\n                        int nd = depth[u] + 1;\n                        if (nd <= H && nd > bestDepth) {\n                            bestDepth = nd;\n                            bestPar = u;\n                        }\n                    }\n                    if (bestPar != -1 && parent[v] != bestPar) {\n                        int oldp = parent[v];\n                        if (oldp != -1) childCnt[oldp]--;\n                        parent[v] = bestPar;\n                        childCnt[bestPar]++;\n                        depth[v] = bestDepth;\n                        changed = true;\n                    }\n                }\n            }\n        }\n\n        // Recompute depths from parents to ensure consistency\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) children[parent[v]].push_back(v);\n        }\n        fill(depth.begin(), depth.end(), -1);\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        // Fix any unreachable nodes\n        for (int v = 0; v < N; v++) {\n            if (depth[v] == -1) {\n                parent[v] = -1;\n            }\n        }\n        // Recompute again after fixing roots\n        children.assign(N, {});\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) children[parent[v]].push_back(v);\n        }\n        fill(depth.begin(), depth.end(), -1);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        // Clamp depths > H by making roots (safety)\n        for (int v = 0; v < N; v++) {\n            if (depth[v] > H) {\n                parent[v] = -1;\n                depth[v] = 0;\n            }\n        }\n\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0) d = H;\n            score += 1LL * (d + 1) * A[v];\n        }\n        Solution sol{parent, score};\n        return sol;\n    };\n\n    long long bestScore = -1;\n    vector<int> bestParent(N, -1);\n\n    // Farthest-first candidates\n    for (int seed : seeds) {\n        vector<int> roots = select_roots_farthest(seed);\n        Solution sol = build_solution(roots);\n        if (sol.score > bestScore) {\n            bestScore = sol.score;\n            bestParent = move(sol.parent);\n        }\n    }\n    // Coverage-greedy candidate\n    vector<int> roots_cov = select_roots_cover_greedy();\n    Solution sol_cov = build_solution(roots_cov);\n    if (sol_cov.score > bestScore) {\n        bestScore = sol_cov.score;\n        bestParent = move(sol_cov.parent);\n    }\n\n    // Output best parent array\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N;\n    vector<string> g;                 // initial board\n    vector<pair<int,int>> oniList;    // positions of oni\n    vector<int> upM, downM, leftM, rightM;\n\n    Solver(int n, const vector<string>& board): N(n), g(board) {\n        compute_margins();\n        extract_oni();\n    }\n\n    void compute_margins() {\n        upM.assign(N, N);\n        downM.assign(N, N);\n        leftM.assign(N, N);\n        rightM.assign(N, N);\n        // columns\n        for (int j = 0; j < N; j++) {\n            for (int i = 0; i < N; i++) {\n                if (g[i][j] == 'o') { upM[j] = i; break; }\n            }\n            for (int i = N-1; i >= 0; i--) {\n                if (g[i][j] == 'o') { downM[j] = N-1 - i; break; }\n            }\n        }\n        // rows\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (g[i][j] == 'o') { leftM[i] = j; break; }\n            }\n            for (int j = N-1; j >= 0; j--) {\n                if (g[i][j] == 'o') { rightM[i] = N-1 - j; break; }\n            }\n        }\n    }\n\n    void extract_oni() {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (g[i][j] == 'x') oniList.emplace_back(i,j);\n            }\n        }\n    }\n\n    bool allCovered(const vector<int>& upL, const vector<int>& downL,\n                    const vector<int>& leftL, const vector<int>& rightL) {\n        for (auto [r,c] : oniList) {\n            if (r < upL[c]) continue;\n            if (r >= N - downL[c]) continue;\n            if (c < leftL[r]) continue;\n            if (c >= N - rightL[r]) continue;\n            return false;\n        }\n        return true;\n    }\n\n    void solve() {\n        // Best solution storage\n        vector<int> bestUp, bestDown, bestLeft, bestRight;\n        long bestCost = (1LL<<60);\n\n        int RUNS = 1; // deterministic; can increase to try random variations\n        mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n        for (int run = 0; run < RUNS; run++) {\n            vector<int> upLen(N,0), downLen(N,0), leftLen(N,0), rightLen(N,0);\n            vector<string> b = g; // board of uncovered oni\n            int uncov = (int)oniList.size();\n\n            auto better = [&](int gain, int delta, int bgain, int bdelta, char bdir, char candir)->bool{\n                long lhs = 1LL * gain * bdelta;\n                long rhs = 1LL * bgain * delta;\n                if (lhs != rhs) return lhs > rhs;\n                if (gain != bgain) return gain > bgain;\n                if (delta != bdelta) return delta < bdelta;\n                auto prio = [&](char d)->int{\n                    if (d=='U') return 0;\n                    if (d=='D') return 1;\n                    if (d=='L') return 2;\n                    return 3; // 'R'\n                };\n                return prio(candir) < prio(bdir);\n            };\n\n            while (uncov > 0) {\n                int bestGain = 0, bestDelta = 1, bestTarget = 0, bestLine = -1;\n                char bestDir = '?';\n\n                // Up columns\n                for (int j = 0; j < N; j++) {\n                    int L = upLen[j], M = upM[j];\n                    if (L >= M) continue;\n                    int pref = 0;\n                    for (int s = L+1; s <= M; s++) {\n                        if (b[s-1][j] == 'x') pref++;\n                        if (pref == 0) continue;\n                        int delta = s - L;\n                        if (better(pref, delta, bestGain, bestDelta, bestDir, 'U')) {\n                            bestGain = pref; bestDelta = delta;\n                            bestDir = 'U'; bestLine = j; bestTarget = s;\n                        }\n                    }\n                }\n                // Down columns\n                for (int j = 0; j < N; j++) {\n                    int L = downLen[j], M = downM[j];\n                    if (L >= M) continue;\n                    int pref = 0;\n                    for (int s = L+1; s <= M; s++) {\n                        if (b[N - s][j] == 'x') pref++;\n                        if (pref == 0) continue;\n                        int delta = s - L;\n                        if (better(pref, delta, bestGain, bestDelta, bestDir, 'D')) {\n                            bestGain = pref; bestDelta = delta;\n                            bestDir = 'D'; bestLine = j; bestTarget = s;\n                        }\n                    }\n                }\n                // Left rows\n                for (int i = 0; i < N; i++) {\n                    int L = leftLen[i], M = leftM[i];\n                    if (L >= M) continue;\n                    int pref = 0;\n                    for (int s = L+1; s <= M; s++) {\n                        if (b[i][s-1] == 'x') pref++;\n                        if (pref == 0) continue;\n                        int delta = s - L;\n                        if (better(pref, delta, bestGain, bestDelta, bestDir, 'L')) {\n                            bestGain = pref; bestDelta = delta;\n                            bestDir = 'L'; bestLine = i; bestTarget = s;\n                        }\n                    }\n                }\n                // Right rows\n                for (int i = 0; i < N; i++) {\n                    int L = rightLen[i], M = rightM[i];\n                    if (L >= M) continue;\n                    int pref = 0;\n                    for (int s = L+1; s <= M; s++) {\n                        if (b[i][N - s] == 'x') pref++;\n                        if (pref == 0) continue;\n                        int delta = s - L;\n                        if (better(pref, delta, bestGain, bestDelta, bestDir, 'R')) {\n                            bestGain = pref; bestDelta = delta;\n                            bestDir = 'R'; bestLine = i; bestTarget = s;\n                        }\n                    }\n                }\n\n                if (bestGain == 0) break; // should not happen\n\n                // Apply extension\n                if (bestDir == 'U') {\n                    int j = bestLine;\n                    int oldL = upLen[j], newL = bestTarget;\n                    for (int r = oldL; r < newL; r++) {\n                        if (b[r][j] == 'x') { b[r][j] = '.'; uncov--; }\n                    }\n                    upLen[j] = newL;\n                } else if (bestDir == 'D') {\n                    int j = bestLine;\n                    int oldL = downLen[j], newL = bestTarget;\n                    for (int r = N - newL; r < N - oldL; r++) {\n                        if (b[r][j] == 'x') { b[r][j] = '.'; uncov--; }\n                    }\n                    downLen[j] = newL;\n                } else if (bestDir == 'L') {\n                    int i = bestLine;\n                    int oldL = leftLen[i], newL = bestTarget;\n                    for (int c = oldL; c < newL; c++) {\n                        if (b[i][c] == 'x') { b[i][c] = '.'; uncov--; }\n                    }\n                    leftLen[i] = newL;\n                } else if (bestDir == 'R') {\n                    int i = bestLine;\n                    int oldL = rightLen[i], newL = bestTarget;\n                    for (int c = N - newL; c < N - oldL; c++) {\n                        if (b[i][c] == 'x') { b[i][c] = '.'; uncov--; }\n                    }\n                    rightLen[i] = newL;\n                }\n            } // greedy loop\n\n            // Reduction step\n            bool changed = true;\n            while (changed) {\n                changed = false;\n                for (int j = 0; j < N; j++) {\n                    while (upLen[j] > 0) {\n                        upLen[j]--;\n                        if (allCovered(upLen, downLen, leftLen, rightLen)) { changed = true; continue; }\n                        upLen[j]++; break;\n                    }\n                }\n                for (int j = 0; j < N; j++) {\n                    while (downLen[j] > 0) {\n                        downLen[j]--;\n                        if (allCovered(upLen, downLen, leftLen, rightLen)) { changed = true; continue; }\n                        downLen[j]++; break;\n                    }\n                }\n                for (int i = 0; i < N; i++) {\n                    while (leftLen[i] > 0) {\n                        leftLen[i]--;\n                        if (allCovered(upLen, downLen, leftLen, rightLen)) { changed = true; continue; }\n                        leftLen[i]++; break;\n                    }\n                }\n                for (int i = 0; i < N; i++) {\n                    while (rightLen[i] > 0) {\n                        rightLen[i]--;\n                        if (allCovered(upLen, downLen, leftLen, rightLen)) { changed = true; continue; }\n                        rightLen[i]++; break;\n                    }\n                }\n            }\n\n            long cost = 0;\n            for (int v: upLen) cost += 2LL * v;\n            for (int v: downLen) cost += 2LL * v;\n            for (int v: leftLen) cost += 2LL * v;\n            for (int v: rightLen) cost += 2LL * v;\n\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestUp = move(upLen);\n                bestDown = move(downLen);\n                bestLeft = move(leftLen);\n                bestRight = move(rightLen);\n            }\n        } // runs\n\n        // Generate operations from best lengths\n        vector<pair<char,int>> ops;\n        auto add_ops = [&](char dir, int line, int len){\n            for (int k = 0; k < len; k++) ops.emplace_back(dir, line);\n        };\n        for (int j = 0; j < N; j++) {\n            int len = bestUp[j];\n            add_ops('U', j, len);\n            add_ops('D', j, len);\n        }\n        for (int j = 0; j < N; j++) {\n            int len = bestDown[j];\n            add_ops('D', j, len);\n            add_ops('U', j, len);\n        }\n        for (int i = 0; i < N; i++) {\n            int len = bestLeft[i];\n            add_ops('L', i, len);\n            add_ops('R', i, len);\n        }\n        for (int i = 0; i < N; i++) {\n            int len = bestRight[i];\n            add_ops('R', i, len);\n            add_ops('L', i, len);\n        }\n\n        // Output\n        for (auto &op : ops) {\n            cout << op.first << \" \" << op.second << \"\\n\";\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    Solver solver(N, board);\n    solver.solve();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift {\n    using result_type = uint64_t;\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return UINT64_MAX; }\n    result_type operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint64_t next() { return (*this)(); }\n    int next_int(int l, int r) { return l + (int)(next() % (uint64_t)(r - l + 1)); }\n};\n\nint N, Ltot;\nvector<int> T;\nvector<double> desiredEdges;\nXorShift rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\nint rand_by_target(const vector<long long>& prefix) {\n    uint64_t r = rng.next() % (uint64_t)Ltot;\n    int idx = int(lower_bound(prefix.begin(), prefix.end(), (long long)r + 1) - prefix.begin());\n    if (idx >= (int)prefix.size()) idx = (int)prefix.size() - 1;\n    return idx;\n}\n\n// compute indegree distribution summing to edges=2*N\nvoid compute_degrees(int minMode, vector<int>& deg) {\n    int edges = 2 * N;\n    deg.assign(N, 0);\n    int minSum = 0;\n    for (int i = 0; i < N; i++) {\n        int minv = 0;\n        if (minMode == 1) {\n            if (T[i] > 0) minv = 1;\n        } else if (minMode == 2) {\n            minv = 1;\n        }\n        deg[i] = minv;\n        minSum += minv;\n    }\n    int R = edges - minSum;\n    static double quota[105];\n    double quotaSum = 0.0;\n    for (int i = 0; i < N; i++) {\n        double q = desiredEdges[i] - deg[i];\n        if (q < 0) q = 0;\n        quota[i] = q;\n        quotaSum += q;\n    }\n    static pair<double, int> fracs[105];\n    int sumDeg = minSum;\n    if (quotaSum > 1e-9) {\n        double scale = (double)R / quotaSum;\n        for (int i = 0; i < N; i++) {\n            double v = quota[i] * scale;\n            int add = (int)v;\n            deg[i] += add;\n            sumDeg += add;\n            fracs[i] = make_pair(v - add, i);\n        }\n    } else {\n        for (int i = 0; i < N; i++) fracs[i] = make_pair(0.0, i);\n    }\n    int leftover = edges - sumDeg;\n    // shuffle fracs for random tie-breaking\n    for (int i = N - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(fracs[i], fracs[j]);\n    }\n    sort(fracs, fracs + N, [](const pair<double, int>& a, const pair<double, int>& b) {\n        return a.first > b.first;\n    });\n    for (int k = 0; k < leftover; k++) {\n        deg[fracs[k].second]++;\n    }\n}\n\n// simulate plan, return error, fill cnt array\nlong long simulate(const vector<int>& a, const vector<int>& b, int* cnt) {\n    for (int i = 0; i < N; i++) cnt[i] = 0;\n    int cur = 0;\n    for (int step = 0; step < Ltot; step++) {\n        int c = ++cnt[cur];\n        cur = (c & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) {\n        err += llabs((long long)cnt[i] - (long long)T[i]);\n    }\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> Ltot)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    desiredEdges.resize(N);\n    for (int i = 0; i < N; i++) {\n        desiredEdges[i] = (double)T[i] * (2.0 * N) / (double)Ltot;\n    }\n    vector<long long> prefix(N);\n    long long acc = 0;\n    for (int i = 0; i < N; i++) {\n        acc += T[i];\n        prefix[i] = acc;\n    }\n\n    vector<int> bestA(N), bestB(N);\n    vector<int> candA(N), candB(N);\n    int cntArr[105];\n    int bestCnt[105];\n\n    // initial candidate using apportionment minMode 0\n    vector<int> deg(N);\n    compute_degrees(0, deg);\n    vector<int> slots;\n    slots.reserve(2 * N);\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n    }\n    while ((int)slots.size() < 2 * N) slots.push_back(rng.next_int(0, N - 1));\n    while ((int)slots.size() > 2 * N) slots.pop_back();\n    for (int i = (int)slots.size() - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(slots[i], slots[j]);\n    }\n    for (int i = 0; i < N; i++) {\n        candA[i] = slots[2 * i];\n        candB[i] = slots[2 * i + 1];\n    }\n    long long bestErr = simulate(candA, candB, cntArr);\n    bestA = candA;\n    bestB = candB;\n    for (int i = 0; i < N; i++) bestCnt[i] = cntArr[i];\n\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9; // seconds\n    int iter = 0;\n    while (true) {\n        iter++;\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        int mode = (int)(rng.next() % 12);\n        if (bestErr >= (long long)1e18) mode = 0; // ensure some candidate\n        if (mode < 5) { // apportionment minMode 0\n            compute_degrees(0, deg);\n            slots.clear();\n            for (int i = 0; i < N; i++) {\n                for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n            }\n            while ((int)slots.size() < 2 * N) slots.push_back(rng.next_int(0, N - 1));\n            while ((int)slots.size() > 2 * N) slots.pop_back();\n            for (int i = (int)slots.size() - 1; i > 0; --i) {\n                int j = rng.next() % (uint64_t)(i + 1);\n                swap(slots[i], slots[j]);\n            }\n            for (int i = 0; i < N; i++) {\n                candA[i] = slots[2 * i];\n                candB[i] = slots[2 * i + 1];\n            }\n        } else if (mode < 8) { // apportionment minMode 1\n            compute_degrees(1, deg);\n            slots.clear();\n            for (int i = 0; i < N; i++) {\n                for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n            }\n            while ((int)slots.size() < 2 * N) slots.push_back(rng.next_int(0, N - 1));\n            while ((int)slots.size() > 2 * N) slots.pop_back();\n            for (int i = (int)slots.size() - 1; i > 0; --i) {\n                int j = rng.next() % (uint64_t)(i + 1);\n                swap(slots[i], slots[j]);\n            }\n            for (int i = 0; i < N; i++) {\n                candA[i] = slots[2 * i];\n                candB[i] = slots[2 * i + 1];\n            }\n        } else if (mode == 8) { // apportionment minMode 2\n            compute_degrees(2, deg);\n            slots.clear();\n            for (int i = 0; i < N; i++) {\n                for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n            }\n            while ((int)slots.size() < 2 * N) slots.push_back(rng.next_int(0, N - 1));\n            while ((int)slots.size() > 2 * N) slots.pop_back();\n            for (int i = (int)slots.size() - 1; i > 0; --i) {\n                int j = rng.next() % (uint64_t)(i + 1);\n                swap(slots[i], slots[j]);\n            }\n            for (int i = 0; i < N; i++) {\n                candA[i] = slots[2 * i];\n                candB[i] = slots[2 * i + 1];\n            }\n        } else if (mode == 9) { // weighted by target for both edges\n            for (int i = 0; i < N; i++) {\n                candA[i] = rand_by_target(prefix);\n                candB[i] = rand_by_target(prefix);\n            }\n        } else if (mode == 10) { // cycle + weighted\n            for (int i = 0; i < N; i++) {\n                candA[i] = (i + 1) % N;\n                candB[i] = rand_by_target(prefix);\n            }\n        } else { // mutation based on best\n            if (bestErr >= (long long)1e18) {\n                mode = 0;\n                continue;\n            }\n            candA = bestA;\n            candB = bestB;\n            // compute surplus/deficit\n            long long totalPos = 0, totalNeg = 0;\n            static long long diff[105];\n            for (int i = 0; i < N; i++) {\n                diff[i] = (long long)bestCnt[i] - (long long)T[i];\n                if (diff[i] < 0) totalPos += -diff[i];\n                else totalNeg += diff[i];\n            }\n            int changes = 1 + (rng.next() % 2); // 1 or 2 changes\n            for (int c = 0; c < changes; c++) {\n                int under = -1, over = -1;\n                if (totalPos > 0) {\n                    uint64_t r = rng.next() % (uint64_t)totalPos;\n                    long long accp = 0;\n                    for (int i = 0; i < N; i++) {\n                        if (diff[i] < 0) {\n                            accp += -diff[i];\n                            if (accp > (long long)r) {\n                                under = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n                if (totalNeg > 0) {\n                    uint64_t r = rng.next() % (uint64_t)totalNeg;\n                    long long accn = 0;\n                    for (int i = 0; i < N; i++) {\n                        if (diff[i] > 0) {\n                            accn += diff[i];\n                            if (accn > (long long)r) {\n                                over = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n                if (under == -1) under = rng.next_int(0, N - 1);\n                if (over == -1) over = rng.next_int(0, N - 1);\n                int sFound = -1;\n                int edgeIdx = 0;\n                int start = rng.next_int(0, N - 1);\n                for (int k = 0; k < N; k++) {\n                    int i = (start + k) % N;\n                    if (candA[i] == over) {\n                        sFound = i;\n                        edgeIdx = 0;\n                        break;\n                    }\n                    if (candB[i] == over) {\n                        sFound = i;\n                        edgeIdx = 1;\n                        break;\n                    }\n                }\n                if (sFound == -1) {\n                    sFound = rng.next_int(0, N - 1);\n                    edgeIdx = rng.next_int(0, 1);\n                }\n                if (edgeIdx == 0)\n                    candA[sFound] = under;\n                else\n                    candB[sFound] = under;\n            }\n        }\n\n        long long err = simulate(candA, candB, cntArr);\n        if (err < bestErr) {\n            bestErr = err;\n            bestA = candA;\n            bestB = candB;\n            for (int i = 0; i < N; i++) bestCnt[i] = cntArr[i];\n        }\n    }\n\n    // output best plan\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << ' ' << bestB[i] << '\\n';\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// \u30d2\u30eb\u30d9\u30eb\u30c8\u66f2\u7dda\u306e\u30aa\u30fc\u30c0\u30fc\u3092\u8a08\u7b97\u3059\u308b\nuint64_t hilbertOrder(int x, int y, int order_bits, int max_coord) {\n    uint64_t d = 0;\n    for (int s = order_bits - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        d <<= 2;\n        d |= (uint64_t)((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) {\n                x = max_coord - x;\n                y = max_coord - y;\n            }\n            int t = x;\n            x = y;\n            y = t;\n        }\n    }\n    return d;\n}\n\n// \u4e0e\u3048\u3089\u308c\u305f\u30ce\u30fc\u30c9\u96c6\u5408\u306b\u5bfe\u3057\u3066\u4e88\u6e2c\u5ea7\u6a19\u3067 Prim \u306e MST \u3092\u69cb\u7bc9\u3057\uff0c\n// \u30b3\u30b9\u30c8\u3068\u8fba\u96c6\u5408\u3092\u8fd4\u3059\npair<double, vector<pair<int, int>>> primMST(const vector<int>& nodes,\n                                             const vector<double>& px,\n                                             const vector<double>& py) {\n    int n = nodes.size();\n    if (n <= 1) return {0.0, {}};\n    vector<double> minD(n, 1e100);\n    vector<int> parent(n, -1);\n    vector<char> used(n, 0);\n    minD[0] = 0.0;\n    double cost = 0.0;\n    for (int iter = 0; iter < n; ++iter) {\n        int v = -1;\n        double best = 1e100;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        cost += minD[v];\n        int idv = nodes[v];\n        double xv = px[idv], yv = py[idv];\n        for (int i = 0; i < n; ++i) if (!used[i]) {\n            int idu = nodes[i];\n            double dx = xv - px[idu];\n            double dy = yv - py[idu];\n            double dist = std::sqrt(dx * dx + dy * dy);\n            if (dist < minD[i]) {\n                minD[i] = dist;\n                parent[i] = v;\n            }\n        }\n    }\n    vector<pair<int, int>> edges;\n    edges.reserve(n - 1);\n    for (int i = 1; i < n; ++i) {\n        edges.emplace_back(nodes[i], nodes[parent[i]]);\n    }\n    return {cost, edges};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) {\n        return 0;\n    }\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    // \u4e88\u6e2c\u5ea7\u6a19\uff08\u77e9\u5f62\u306e\u4e2d\u5fc3\uff09\n    vector<double> px(N), py(N);\n    for (int i = 0; i < N; ++i) {\n        px[i] = (lx[i] + rx[i]) * 0.5;\n        py[i] = (ly[i] + ry[i]) * 0.5;\n    }\n\n    const int order_bits = 15;                // 2^15 = 32768 > 10000\n    const int max_coord = (1 << order_bits) - 1;\n\n    vector<vector<int>> candidates;\n\n    // Hilbert \u306e\u30d0\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\n    for (int variant = 0; variant < 5; ++variant) {\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            int x = (int)px[i];\n            int y = (int)py[i];\n            switch (variant) {\n                case 0: break;                           // \u901a\u5e38\n                case 1: x = max_coord - x; break;        // x \u53cd\u8ee2\n                case 2: y = max_coord - y; break;        // y \u53cd\u8ee2\n                case 3: x = max_coord - x; y = max_coord - y; break; // \u4e21\u65b9\u53cd\u8ee2\n                case 4: { int t = x; x = y; y = t; } break;          // \u4ea4\u63db\n            }\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b) {\n            return a.first < b.first;\n        });\n        vector<int> order;\n        order.reserve(N);\n        for (auto& p : keys) order.push_back(p.second);\n        candidates.push_back(move(order));\n    }\n\n    // \u5358\u7d14\u306a\u5ea7\u6a19\u30bd\u30fc\u30c8\u306e\u30d0\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (px[a] == px[b]) return py[a] < py[b];\n            return px[a] < px[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (py[a] == py[b]) return px[a] < px[b];\n            return py[a] < py[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] + py[a];\n            double vb = px[b] + py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] - py[a];\n            double vb = px[b] - py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n\n    // \u5019\u88dc\u9806\u5e8f\u306e\u4e2d\u304b\u3089\u4e88\u6e2c\u30b3\u30b9\u30c8\u304c\u6700\u5c0f\u306e\u3082\u306e\u3092\u9078\u3076\n    auto evalCost = [&](const vector<int>& order) -> double {\n        double total = 0.0;\n        int pos = 0;\n        for (int k = 0; k < M; ++k) {\n            int g = G[k];\n            vector<int> group;\n            group.reserve(g);\n            for (int t = 0; t < g; ++t) group.push_back(order[pos + t]);\n            pos += g;\n            auto res = primMST(group, px, py);\n            total += res.first;\n        }\n        return total;\n    };\n\n    double bestCost = 1e100;\n    int bestIdx = 0;\n    for (int idx = 0; idx < (int)candidates.size(); ++idx) {\n        double c = evalCost(candidates[idx]);\n        if (c < bestCost) {\n            bestCost = c;\n            bestIdx = idx;\n        }\n    }\n\n    const vector<int>& bestOrder = candidates[bestIdx];\n\n    // \u9078\u3093\u3060\u9806\u5e8f\u3067\u30b0\u30eb\u30fc\u30d7\u5206\u3051\u3057 MST \u3092\u8a08\u7b97\n    vector<vector<int>> groups(M);\n    vector<vector<pair<int, int>>> edges(M);\n    int pos = 0;\n    for (int k = 0; k < M; ++k) {\n        int g = G[k];\n        groups[k].reserve(g);\n        for (int t = 0; t < g; ++t) groups[k].push_back(bestOrder[pos + t]);\n        pos += g;\n        auto res = primMST(groups[k], px, py);\n        edges[k] = move(res.second);\n    }\n\n    // \u51fa\u529b\uff08\u30af\u30a8\u30ea\u306f\u884c\u308f\u306a\u3044\uff09\n    cout << \"!\\n\";\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < (int)groups[k].size(); ++i) {\n            if (i) cout << ' ';\n            cout << groups[k][i];\n        }\n        cout << '\\n';\n        for (auto& e : edges[k]) {\n            cout << e.first << ' ' << e.second << '\\n';\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<int> is(M), js(M);\n    for (int k = 0; k < M; k++) cin >> is[k] >> js[k];\n\n    vector<pair<char, char>> actions;\n    int sr = is[0], sc = js[0];\n\n    const vector<int> dr = {-1, 1, 0, 0};\n    const vector<int> dc = {0, 0, -1, 1};\n    const vector<char> dirChar = {'U', 'D', 'L', 'R'};\n\n    auto bfs = [&](int tr, int tc) {\n        int SZ = N * N;\n        vector<int> dist(SZ, INT_MAX), prev(SZ, -1);\n        vector<char> prevAct(SZ), prevDir(SZ);\n        queue<int> q;\n        int sidx = sr * N + sc;\n        int gidx = tr * N + tc;\n        dist[sidx] = 0;\n        q.push(sidx);\n        while (!q.empty()) {\n            int v = q.front();\n            q.pop();\n            if (v == gidx) break;\n            int r = v / N, c = v % N;\n            // Move actions\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                int ni = nr * N + nc;\n                if (dist[ni] > dist[v] + 1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'M';\n                    prevDir[ni] = dirChar[k];\n                    q.push(ni);\n                }\n            }\n            // Slide actions\n            if (r > 0) {\n                int ni = c;\n                if (dist[ni] > dist[v] + 1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'S';\n                    prevDir[ni] = 'U';\n                    q.push(ni);\n                }\n            }\n            if (r < N - 1) {\n                int ni = (N - 1) * N + c;\n                if (dist[ni] > dist[v] + 1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'S';\n                    prevDir[ni] = 'D';\n                    q.push(ni);\n                }\n            }\n            if (c > 0) {\n                int ni = r * N;\n                if (dist[ni] > dist[v] + 1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'S';\n                    prevDir[ni] = 'L';\n                    q.push(ni);\n                }\n            }\n            if (c < N - 1) {\n                int ni = r * N + (N - 1);\n                if (dist[ni] > dist[v] + 1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'S';\n                    prevDir[ni] = 'R';\n                    q.push(ni);\n                }\n            }\n        }\n        vector<pair<char, char>> path;\n        int cur = gidx;\n        if (dist[cur] == INT_MAX) return path;  // unreachable, shouldn't happen\n        while (cur != sidx) {\n            path.push_back({prevAct[cur], prevDir[cur]});\n            cur = prev[cur];\n        }\n        reverse(path.begin(), path.end());\n        sr = tr;\n        sc = tc;\n        return path;\n    };\n\n    for (int k = 1; k < M; k++) {\n        auto path = bfs(is[k], js[k]);\n        actions.insert(actions.end(), path.begin(), path.end());\n    }\n\n    for (auto &p : actions) {\n        cout << p.first << ' ' << p.second << '\\n';\n    }\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nstruct Move {\n    double diff;\n    int dir;\n    int len;\n    Move(double _d = 0.0, int _dir = -1, int _len = 0) : diff(_d), dir(_dir), len(_len) {}\n};\n\nint n;\nvector<int> x_coord, y_coord;\nvector<long long> r_target;\nvector<Rect> rects;\n\ninline long long area(const Rect &rc) {\n    return 1LL * (rc.c - rc.a) * (rc.d - rc.b);\n}\n\ninline double compute_p_val(long long ri, long long s) {\n    double mn = (double)min(ri, s);\n    double mx = (double)max(ri, s);\n    double diff = 1.0 - mn / mx;\n    return 1.0 - diff * diff;\n}\n\n// compute maximum expandable length in 4 directions without overlap\nvoid compute_max_expands(int idx, int &left, int &right, int &up, int &down) {\n    const Rect &ri = rects[idx];\n    left = ri.a;\n    right = 10000 - ri.c;\n    up = ri.b;\n    down = 10000 - ri.d;\n    for (int j = 0; j < n; j++) if (j != idx) {\n        const Rect &rj = rects[j];\n        // vertical overlap\n        if (rj.b < ri.d && rj.d > ri.b) {\n            if (rj.c <= ri.a) {\n                int cand = ri.a - rj.c;\n                if (cand < left) left = cand;\n            }\n            if (rj.a >= ri.c) {\n                int cand = rj.a - ri.c;\n                if (cand < right) right = cand;\n            }\n        }\n        // horizontal overlap\n        if (rj.a < ri.c && rj.c > ri.a) {\n            if (rj.d <= ri.b) {\n                int cand = ri.b - rj.d;\n                if (cand < up) up = cand;\n            }\n            if (rj.b >= ri.d) {\n                int cand = rj.b - ri.d;\n                if (cand < down) down = cand;\n            }\n        }\n    }\n}\n\nMove find_best_expand(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s >= rt) return best;\n\n    int left, right, up, down;\n    compute_max_expands(idx, left, right, up, down);\n    int maxLens[4] = {left, right, up, down};\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(rt - s) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\nMove find_best_contract(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s <= rt) return best;\n\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int maxLens[4] = {\n        min(x_coord[idx] - rc.a, w - 1),                // shrink left\n        min(rc.c - (x_coord[idx] + 1), w - 1),          // shrink right\n        min(y_coord[idx] - rc.b, h - 1),                // shrink up\n        min(rc.d - (y_coord[idx] + 1), h - 1)           // shrink down\n    };\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(s - rt) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\ninline void apply_move(int idx, const Move &mv, bool expand) {\n    if (mv.dir < 0 || mv.len <= 0) return;\n    Rect &rc = rects[idx];\n    int l = mv.len;\n    if (expand) {\n        if (mv.dir == 0) rc.a -= l;\n        else if (mv.dir == 1) rc.c += l;\n        else if (mv.dir == 2) rc.b -= l;\n        else rc.d += l;\n    } else {\n        if (mv.dir == 0) rc.a += l;\n        else if (mv.dir == 1) rc.c -= l;\n        else if (mv.dir == 2) rc.b += l;\n        else rc.d -= l;\n    }\n}\n\n// Adjust shared vertical edge between two rectangles with same height, rect L on left of R\nbool adjust_vertical_edge(int L, int R) {\n    Rect &A = rects[L];\n    Rect &B = rects[R];\n    int H = A.d - A.b;\n    if (H <= 0) return false;\n    long long sA0 = 1LL * (A.c - A.a) * H;\n    long long sB0 = 1LL * (B.c - B.a) * H;\n    int x0 = A.c; // shared edge\n    int low = max(A.a + 1, x_coord[L] + 1);\n    int high = min(B.c - 1, x_coord[R]);\n    if (low > high) return false;\n\n    auto eval = [&](int xx) -> double {\n        if (xx < low || xx > high) return -1e30;\n        long long sA = sA0 + 1LL * (xx - x0) * H;\n        long long sB = sB0 - 1LL * (xx - x0) * H;\n        double pA = compute_p_val(r_target[L], sA);\n        double pB = compute_p_val(r_target[R], sB);\n        return pA + pB;\n    };\n\n    double cur = eval(x0);\n    double bestVal = cur;\n    int bestX = x0;\n    vector<int> cand;\n    cand.reserve(8);\n    cand.push_back(low);\n    cand.push_back(high);\n    double tA = x0 + (double)(r_target[L] - sA0) / (double)H;\n    double tB = x0 - (double)(r_target[R] - sB0) / (double)H;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA);  if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB);  if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int xx : cand) {\n        double val = eval(xx);\n        if (val > bestVal + EPS) {\n            bestVal = val;\n            bestX = xx;\n        }\n    }\n    if (bestX != x0) {\n        int dx = bestX - x0;\n        A.c += dx;\n        B.a += dx;\n        return true;\n    }\n    return false;\n}\n\n// Adjust shared horizontal edge between two rectangles with same width, rect U below D\nbool adjust_horizontal_edge(int U, int D) {\n    Rect &A = rects[U]; // lower\n    Rect &B = rects[D]; // upper\n    int W = A.c - A.a;\n    if (W <= 0) return false;\n    long long sA0 = 1LL * (A.d - A.b) * W;\n    long long sB0 = 1LL * (B.d - B.b) * W;\n    int y0 = A.d; // shared edge\n    int low = max(A.b + 1, y_coord[U] + 1);\n    int high = min(B.d - 1, y_coord[D]);\n    if (low > high) return false;\n\n    auto eval = [&](int yy) -> double {\n        if (yy < low || yy > high) return -1e30;\n        long long sA = sA0 + 1LL * (yy - y0) * W;\n        long long sB = sB0 - 1LL * (yy - y0) * W;\n        double pA = compute_p_val(r_target[U], sA);\n        double pB = compute_p_val(r_target[D], sB);\n        return pA + pB;\n    };\n\n    double cur = eval(y0);\n    double bestVal = cur;\n    int bestY = y0;\n    vector<int> cand;\n    cand.reserve(8);\n    cand.push_back(low);\n    cand.push_back(high);\n    double tA = y0 + (double)(r_target[U] - sA0) / (double)W;\n    double tB = y0 - (double)(r_target[D] - sB0) / (double)W;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA);  if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB);  if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int yy : cand) {\n        double val = eval(yy);\n        if (val > bestVal + EPS) {\n            bestVal = val;\n            bestY = yy;\n        }\n    }\n    if (bestY != y0) {\n        int dy = bestY - y0;\n        A.d += dy;\n        B.b += dy;\n        return true;\n    }\n    return false;\n}\n\ndouble compute_total_score() {\n    double tot = 0.0;\n    for (int i = 0; i < n; i++) {\n        tot += compute_p_val(r_target[i], area(rects[i]));\n    }\n    return tot;\n}\n\nvoid greedy_expand(const vector<int>& order) {\n    const double EPS = 1e-12;\n    for (int idx : order) {\n        for (int iter = 0; iter < 1000; iter++) {\n            Move mv = find_best_expand(idx);\n            if (mv.diff > EPS) {\n                apply_move(idx, mv, true);\n            } else break;\n        }\n    }\n}\n\nvoid improve_solution(chrono::steady_clock::time_point start_time, double TIME_LIMIT) {\n    const double EPS = 1e-12;\n    for (int outer = 0; outer < 20; outer++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        // single-rectangle improvement pass\n        for (int i = 0; i < n; i++) {\n            elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n            long long s = area(rects[i]);\n            Move mv;\n            if (s < r_target[i]) mv = find_best_expand(i);\n            else if (s > r_target[i]) mv = find_best_contract(i);\n            if (mv.diff > EPS) {\n                apply_move(i, mv, s < r_target[i]);\n                improved = true;\n            }\n        }\n        elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        // pair edge adjustments\n        bool pair_improved = false;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                // vertical adjacency with same height\n                if (rects[i].b == rects[j].b && rects[i].d == rects[j].d) {\n                    if (rects[i].c == rects[j].a) {\n                        if (adjust_vertical_edge(i, j)) { pair_improved = true; }\n                    } else if (rects[j].c == rects[i].a) {\n                        if (adjust_vertical_edge(j, i)) { pair_improved = true; }\n                    }\n                }\n                // horizontal adjacency with same width\n                if (rects[i].a == rects[j].a && rects[i].c == rects[j].c) {\n                    if (rects[i].d == rects[j].b) {\n                        if (adjust_horizontal_edge(i, j)) { pair_improved = true; }\n                    } else if (rects[j].d == rects[i].b) {\n                        if (adjust_horizontal_edge(j, i)) { pair_improved = true; }\n                    }\n                }\n            }\n            elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        if (pair_improved) improved = true;\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> n)) return 0;\n    x_coord.resize(n);\n    y_coord.resize(n);\n    r_target.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        int xi, yi;\n        long long ri;\n        cin >> xi >> yi >> ri;\n        x_coord[i] = xi;\n        y_coord[i] = yi;\n        r_target[i] = ri;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.9;\n\n    // prepare different orders\n    vector<int> order_asc(n), order_desc(n);\n    iota(order_asc.begin(), order_asc.end(), 0);\n    sort(order_asc.begin(), order_asc.end(), [&](int a, int b) {\n        return r_target[a] < r_target[b];\n    });\n    order_desc = order_asc;\n    reverse(order_desc.begin(), order_desc.end());\n\n    vector<Rect> best_rects;\n    double best_score = -1.0;\n\n    vector<vector<int>> orders = {order_desc, order_asc};\n\n    for (size_t oi = 0; oi < orders.size(); oi++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT * 0.9 && best_score >= 0.0) break; // leave time\n        // initialize rects to 1x1 at anchor\n        for (int i = 0; i < n; i++) {\n            rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n        }\n        greedy_expand(orders[oi]);\n        improve_solution(start_time, TIME_LIMIT);\n        double score = compute_total_score();\n        if (score > best_score) {\n            best_score = score;\n            best_rects = rects;\n        }\n    }\n\n    if (!best_rects.empty()) rects = best_rects;\n\n    // output\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << ' ' << rects[i].b << ' ' << rects[i].c << ' ' << rects[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 50;\nconst int W = 50;\nconst int N = H * W;\n\nint Tcell[N];\nint Pcell[N];\n\nint nbCnt[N];\nint nbIdx[N][4];\nchar nbDir[N][4];\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nint startIdx;\nint tileCount;\n\nvector<int> visitedTile;\nint currentToken = 1;\n\nstruct XorShift {\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ULL) { x = seed; }\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int n) { return (int)(next() % n); }\n};\nXorShift rng;\n\nenum Mode { MIN_DEG = 0, MAX_DEG = 1, MAX_VALUE = 2 };\n\nstruct Param {\n    int avoidLevel; // -1 for no avoid, otherwise avoid deg<=avoidLevel if possible\n    Mode mode;\n    int randProb; // 0..1023\n};\n\nstruct Path {\n    string moves;\n    int score;\n    int len;\n};\n\ninline int compute_deg(int idx, int candTile) {\n    int deg = 0;\n    for (int k = 0; k < nbCnt[idx]; k++) {\n        int nb = nbIdx[idx][k];\n        int tid = Tcell[nb];\n        if (tid == candTile) continue;\n        if (visitedTile[tid] == currentToken) continue;\n        deg++;\n    }\n    return deg;\n}\n\nPath run_once(const Param &param) {\n    currentToken++;\n    if (currentToken == 0x3f3f3f3f) { // very unlikely; reset tokens to avoid overflow\n        currentToken = 1;\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n    }\n    visitedTile[Tcell[startIdx]] = currentToken;\n    int cur = startIdx;\n    int score = Pcell[cur];\n    vector<char> mv;\n    mv.reserve(tileCount);\n    while (true) {\n        int candIdxArr[4];\n        char candDirArr[4];\n        int cnum = 0;\n        for (int k = 0; k < nbCnt[cur]; k++) {\n            int nb = nbIdx[cur][k];\n            if (visitedTile[Tcell[nb]] == currentToken) continue;\n            candIdxArr[cnum] = nb;\n            candDirArr[cnum] = nbDir[cur][k];\n            cnum++;\n        }\n        if (cnum == 0) break;\n        int chosen = -1;\n        if (param.randProb > 0 && (int)(rng.next() & 1023) < param.randProb) {\n            chosen = rng.nextInt(cnum);\n        } else {\n            int degs[4];\n            bool filtered = false;\n            for (int i = 0; i < cnum; i++) {\n                degs[i] = compute_deg(candIdxArr[i], Tcell[candIdxArr[i]]);\n                if (param.avoidLevel >= 0 && degs[i] > param.avoidLevel) filtered = true;\n            }\n            if (param.mode == MIN_DEG) {\n                int bestDeg = 1e9, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (param.avoidLevel >= 0 && filtered && d <= param.avoidLevel) continue;\n                    if (d < bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int val = Pcell[candIdxArr[i]];\n                        if (val > bestVal) {\n                            bestVal = val;\n                            chosen = i;\n                        } else if (val == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else if (param.mode == MAX_DEG) {\n                int bestDeg = -1, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (param.avoidLevel >= 0 && filtered && d <= param.avoidLevel) continue;\n                    if (d > bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int val = Pcell[candIdxArr[i]];\n                        if (val > bestVal) {\n                            bestVal = val;\n                            chosen = i;\n                        } else if (val == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else { // MAX_VALUE\n                int bestVal = -1, bestDeg = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (param.avoidLevel >= 0 && filtered && d <= param.avoidLevel) continue;\n                    int val = Pcell[candIdxArr[i]];\n                    if (val > bestVal) {\n                        bestVal = val;\n                        bestDeg = d;\n                        chosen = i;\n                    } else if (val == bestVal) {\n                        if (d > bestDeg) {\n                            bestDeg = d;\n                            chosen = i;\n                        } else if (d == bestDeg && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            }\n        }\n        if (chosen == -1) chosen = rng.nextInt(cnum);\n        int nxt = candIdxArr[chosen];\n        visitedTile[Tcell[nxt]] = currentToken;\n        score += Pcell[nxt];\n        mv.push_back(candDirArr[chosen]);\n        cur = nxt;\n    }\n    Path res;\n    res.score = score;\n    res.len = (int)mv.size() + 1;\n    res.moves.assign(mv.begin(), mv.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    int maxTid = -1;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Tcell[idx] = x;\n            if (x > maxTid) maxTid = x;\n        }\n    }\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Pcell[idx] = x;\n        }\n    }\n    tileCount = maxTid + 1;\n    visitedTile.assign(tileCount, 0);\n    startIdx = si * W + sj;\n\n    // Precompute neighbors\n    for (int r = 0; r < H; r++) {\n        for (int c = 0; c < W; c++) {\n            int idx = r * W + c;\n            int cnt = 0;\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 >= H || nc < 0 || nc >= W) continue;\n                nbIdx[idx][cnt] = nr * W + nc;\n                nbDir[idx][cnt] = dch[d];\n                cnt++;\n            }\n            nbCnt[idx] = cnt;\n        }\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    rng = XorShift(seed);\n\n    vector<Param> params = {\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 30},\n        {1, MIN_DEG, 0},\n        {1, MIN_DEG, 50},\n        {0, MAX_DEG, 0},\n        {0, MAX_DEG, 50},\n        {0, MAX_VALUE, 0},\n        {0, MAX_VALUE, 50},\n        {0, MIN_DEG, 200},\n        {2, MIN_DEG, 0},\n    };\n\n    Path best;\n    best.score = -1;\n    best.len = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeLimit = startTime + chrono::milliseconds(1900);\n\n    int pidx = rng.nextInt((int)params.size());\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        if (now >= timeLimit) break;\n        const Param &param = params[pidx];\n        pidx++;\n        if (pidx >= (int)params.size()) pidx = 0;\n        Path curPath = run_once(param);\n        if (curPath.score > best.score || (curPath.score == best.score && curPath.len > best.len)) {\n            best = std::move(curPath);\n        }\n    }\n\n    cout << best.moves << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Neighbor {\n    int to;\n    int edge;\n    char dir;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int H = 30, W = 30;\n    const int N = H * W;\n    const int EH = H * (W - 1);\n    const int EV = (H - 1) * W;\n    const int E = EH + EV;\n\n    // edge index tables\n    int h_idx[H][W - 1];\n    int v_idx[H - 1][W];\n    int idx = 0;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            h_idx[i][j] = idx++;\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            v_idx[i][j] = idx++;\n        }\n    }\n\n    vector<vector<Neighbor>> adj(N);\n    // horizontal edges\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            int e = h_idx[i][j];\n            int u = i * W + j;\n            int v = i * W + (j + 1);\n            adj[u].push_back({v, e, 'R'});\n            adj[v].push_back({u, e, 'L'});\n        }\n    }\n    // vertical edges\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            int e = v_idx[i][j];\n            int u = i * W + j;\n            int v = (i + 1) * W + j;\n            adj[u].push_back({v, e, 'D'});\n            adj[v].push_back({u, e, 'U'});\n        }\n    }\n\n    vector<double> w(E, 5000.0); // estimated weights\n    vector<int> cnt(E, 0);       // usage counts\n\n    // segmentation and means\n    vector<int> rowSplit(H, -1), colSplit(W, -1);\n    vector<double> rowMeanAll(H, 5000.0), rowMeanL(H, 5000.0), rowMeanR(H, 5000.0);\n    vector<double> colMeanAll(W, 5000.0), colMeanT(W, 5000.0), colMeanB(W, 5000.0);\n\n    auto recompute_means_and_splits = [&](int qidx) {\n        double gSumH = 0.0, gSumV = 0.0;\n        int gCntH = 0, gCntV = 0;\n        for (int e = 0; e < EH; e++) if (cnt[e] > 0) { gSumH += w[e]; gCntH++; }\n        for (int e = EH; e < E; e++) if (cnt[e] > 0) { gSumV += w[e]; gCntV++; }\n        double gMeanH = gCntH ? gSumH / gCntH : 5000.0;\n        double gMeanV = gCntV ? gSumV / gCntV : 5000.0;\n\n        // rows (horizontal edges)\n        for (int i = 0; i < H; i++) {\n            vector<double> ps(W, 0.0);\n            vector<int> pc(W, 0);\n            for (int j = 0; j < W - 1; j++) {\n                ps[j + 1] = ps[j];\n                pc[j + 1] = pc[j];\n                int e = h_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[j + 1] += w[e];\n                    pc[j + 1] += 1;\n                }\n            }\n            double totalSum = ps[W - 1];\n            int totalCnt = pc[W - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanH;\n            rowMeanAll[i] = meanAll;\n            rowMeanL[i] = rowMeanR[i] = meanAll;\n            rowSplit[i] = -1;\n            if (totalCnt >= 6 && qidx >= 80) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int x = 1; x < W - 1; x++) { // split between x-1 and x (edges index <x vs >=x)\n                    int lc = pc[x];\n                    int rc = totalCnt - lc;\n                    if (lc >= 2 && rc >= 2) {\n                        double ls = ps[x];\n                        double rs = totalSum - ls;\n                        double lm = ls / lc;\n                        double rm = rs / rc;\n                        double diff = fabs(lm - rm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = x;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 500.0) {\n                    rowSplit[i] = bestSplit;\n                    int lc = pc[bestSplit];\n                    int rc = totalCnt - lc;\n                    double ls = ps[bestSplit];\n                    double rs = totalSum - ls;\n                    rowMeanL[i] = lc ? ls / lc : meanAll;\n                    rowMeanR[i] = rc ? rs / rc : meanAll;\n                }\n            }\n        }\n\n        // columns (vertical edges)\n        for (int j = 0; j < W; j++) {\n            vector<double> ps(H, 0.0);\n            vector<int> pc(H, 0);\n            for (int i = 0; i < H - 1; i++) {\n                ps[i + 1] = ps[i];\n                pc[i + 1] = pc[i];\n                int e = v_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[i + 1] += w[e];\n                    pc[i + 1] += 1;\n                }\n            }\n            double totalSum = ps[H - 1];\n            int totalCnt = pc[H - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanV;\n            colMeanAll[j] = meanAll;\n            colMeanT[j] = colMeanB[j] = meanAll;\n            colSplit[j] = -1;\n            if (totalCnt >= 6 && qidx >= 80) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int y = 1; y < H - 1; y++) {\n                    int tc = pc[y];\n                    int bc = totalCnt - tc;\n                    if (tc >= 2 && bc >= 2) {\n                        double ts = ps[y];\n                        double bs = totalSum - ts;\n                        double tm = ts / tc;\n                        double bm = bs / bc;\n                        double diff = fabs(tm - bm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = y;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 500.0) {\n                    colSplit[j] = bestSplit;\n                    int tc = pc[bestSplit];\n                    int bc = totalCnt - tc;\n                    double ts = ps[bestSplit];\n                    double bs = totalSum - ts;\n                    colMeanT[j] = tc ? ts / tc : meanAll;\n                    colMeanB[j] = bc ? bs / bc : meanAll;\n                }\n            }\n        }\n    };\n\n    auto smooth_unvisited = [&]() {\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W - 1; j++) {\n                int e = h_idx[i][j];\n                if (cnt[e] == 0) {\n                    if (rowSplit[i] == -1) {\n                        w[e] = rowMeanAll[i];\n                    } else {\n                        if (j < rowSplit[i]) w[e] = rowMeanL[i];\n                        else w[e] = rowMeanR[i];\n                    }\n                }\n            }\n        }\n        for (int j = 0; j < W; j++) {\n            for (int i = 0; i < H - 1; i++) {\n                int e = v_idx[i][j];\n                if (cnt[e] == 0) {\n                    if (colSplit[j] == -1) {\n                        w[e] = colMeanAll[j];\n                    } else {\n                        if (i < colSplit[j]) w[e] = colMeanT[j];\n                        else w[e] = colMeanB[j];\n                    }\n                }\n            }\n        }\n    };\n\n    const int EXP_END = 250;\n    const double EXP_BONUS = 2500.0;\n\n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        int s = si * W + sj;\n        int t = ti * W + tj;\n\n        // recompute means/splits and smooth periodically\n        if (q == 0 || q % 25 == 0) {\n            recompute_means_and_splits(q);\n            smooth_unvisited();\n        }\n\n        double explore_factor = (q < EXP_END) ? (double)(EXP_END - q) / EXP_END : 0.0;\n\n        const double INF = 1e100;\n        vector<double> dist(N, INF);\n        vector<int> prev_v(N, -1), prev_edge(N, -1);\n        vector<char> prev_dir(N, 0);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n        dist[s] = 0.0;\n        pq.push({0.0, s});\n        while (!pq.empty()) {\n            auto [d, v] = pq.top();\n            pq.pop();\n            if (d != dist[v]) continue;\n            if (v == t) break;\n            for (auto &nb : adj[v]) {\n                double cost = w[nb.edge];\n                if (explore_factor > 0.0) {\n                    cost -= EXP_BONUS * explore_factor / sqrt((double)cnt[nb.edge] + 1.0);\n                }\n                if (cost < 1.0) cost = 1.0;\n                double nd = d + cost;\n                if (nd < dist[nb.to]) {\n                    dist[nb.to] = nd;\n                    prev_v[nb.to] = v;\n                    prev_edge[nb.to] = nb.edge;\n                    prev_dir[nb.to] = nb.dir;\n                    pq.push({nd, nb.to});\n                }\n            }\n        }\n\n        string path;\n        vector<int> edges_seq;\n        double pred_len = 0.0;\n        int v = t;\n        while (v != s && v != -1) {\n            int e = prev_edge[v];\n            char dir = prev_dir[v];\n            if (e < 0) break;\n            path.push_back(dir);\n            edges_seq.push_back(e);\n            pred_len += w[e];\n            v = prev_v[v];\n        }\n        reverse(path.begin(), path.end());\n        reverse(edges_seq.begin(), edges_seq.end());\n\n        cout << path << '\\n' << flush;\n\n        int obs_int;\n        if (!(cin >> obs_int)) break;\n        double obs_len = obs_int;\n        if (pred_len < 1e-6) pred_len = (double)path.size() * 5000.0; // fallback\n        double error = obs_len - pred_len;\n\n        double base_lr = (q < 200) ? 0.6 : 0.35;\n        if (q > 700) base_lr *= 0.7;\n\n        double denom = pred_len;\n        if (denom < 1.0) denom = 1.0;\n        for (int e : edges_seq) {\n            double share = w[e] / denom;\n            double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n            w[e] += lr * error * share;\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 9500.0) w[e] = 9500.0;\n            cnt[e]++;\n        }\n\n        if (q % 50 == 49) { // occasional smoothing for remaining unvisited edges\n            recompute_means_and_splits(q);\n            smooth_unvisited();\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// XorShift RNG\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    inline uint32_t next_u32() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return static_cast<uint32_t>(x);\n    }\n    inline int next_int(int n) { return static_cast<int>(next_u32() % n); }\n};\n\n// Constants\nconst int N = 20;\nconst int CELLS = N * N;   // 400\nconst int PL = 800;        // placements per string (400 horiz + 400 vert)\n\nint M;\nvector<string> s;\nvector<int> lens;\nvector<vector<uint8_t>> letters;          // s[i] as 0..7\nvector<vector<uint16_t>> cells;           // placements cells\nvector<uint16_t*> cellPtrs;\nvector<uint8_t*> letterPtrs;\n\n// counts for current placement assignment\nstatic int counts[CELLS][8];\nstatic int totalCnt[CELLS];\nvector<int> currPlacement;\n\n// add/remove placement to counts\ninline void addPlacement(int si, int pi) {\n    int len = lens[si];\n    const uint16_t* cp = cellPtrs[si] + pi * len;\n    const uint8_t* lp = letterPtrs[si];\n    for (int p = 0; p < len; ++p) {\n        int cell = cp[p];\n        int li = lp[p];\n        ++counts[cell][li];\n        ++totalCnt[cell];\n    }\n}\ninline void removePlacement(int si, int pi) {\n    int len = lens[si];\n    const uint16_t* cp = cellPtrs[si] + pi * len;\n    const uint8_t* lp = letterPtrs[si];\n    for (int p = 0; p < len; ++p) {\n        int cell = cp[p];\n        int li = lp[p];\n        --counts[cell][li];\n        --totalCnt[cell];\n    }\n}\n\n// conflict of string si with current counts\ninline int computeConf(int si) {\n    int len = lens[si];\n    const uint16_t* cp = cellPtrs[si] + currPlacement[si] * len;\n    const uint8_t* lp = letterPtrs[si];\n    int conf = 0;\n    for (int p = 0; p < len; ++p) {\n        int cell = cp[p];\n        int li = lp[p];\n        conf += totalCnt[cell] - counts[cell][li];\n    }\n    return conf;\n}\n\n// build majority matrix from counts\nvoid buildMatrix(vector<char>& mat, bool dotUnused) {\n    mat.resize(CELLS);\n    for (int cell = 0; cell < CELLS; ++cell) {\n        if (totalCnt[cell] == 0) {\n            mat[cell] = dotUnused ? '.' : 'A';\n        } else {\n            int bestL = 0;\n            int bestC = counts[cell][0];\n            for (int l = 1; l < 8; ++l) {\n                if (counts[cell][l] > bestC) {\n                    bestC = counts[cell][l];\n                    bestL = l;\n                }\n            }\n            mat[cell] = static_cast<char>('A' + bestL);\n        }\n    }\n}\n\n// evaluate how many strings are subsequences of matrix mat\nint evaluateMatrix(const vector<char>& mat) {\n    int satisfied = 0;\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cp = cellPtrs[i];\n        const char* sp = s[i].c_str();\n        bool ok = false;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            bool comp = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                if (mat[cell] != sp[p]) {\n                    comp = false;\n                    break;\n                }\n            }\n            if (comp) {\n                ok = true;\n                break;\n            }\n        }\n        if (ok) ++satisfied;\n    }\n    return satisfied;\n}\n\n// greedy construction trial with given order of string indices\nvoid greedyTrial(const vector<int>& order, XorShift64& rng, vector<char>& outMat, int& placedCount, int& coverage) {\n    vector<char> mat(CELLS, '.');\n    placedCount = 0;\n    for (int idx : order) {\n        int len = lens[idx];\n        const uint16_t* cp = cellPtrs[idx];\n        const char* sp = s[idx].c_str();\n        int bestMatch = -1;\n        int bestPi = -1;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            bool ok = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char mc = mat[cell];\n                char sc = sp[p];\n                if (mc == sc) {\n                    ++matches;\n                } else if (mc == '.') {\n                    // ok\n                } else {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        if (bestPi >= 0) {\n            ++placedCount;\n            int base = bestPi * len;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char sc = sp[p];\n                if (mat[cell] == '.') mat[cell] = sc;\n            }\n        }\n    }\n    coverage = evaluateMatrix(mat);\n    outMat.swap(mat);\n}\n\n// initialize placements from a given matrix by choosing placement with maximum matches\nvoid initPlacementsFromMatrix(const vector<char>& mat) {\n    memset(counts, 0, sizeof(counts));\n    memset(totalCnt, 0, sizeof(totalCnt));\n    currPlacement.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cp = cellPtrs[i];\n        const char* sp = s[i].c_str();\n        int bestMatch = -1;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                if (mat[cell] == sp[p]) ++matches;\n            }\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rand() % tie == 0) bestPi = pi;\n            }\n        }\n        currPlacement[i] = bestPi;\n        addPlacement(i, bestPi);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    s.resize(M);\n    lens.resize(M);\n    letters.resize(M);\n    cells.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        lens[i] = (int)s[i].size();\n        letters[i].resize(lens[i]);\n        for (int p = 0; p < lens[i]; ++p) letters[i][p] = (uint8_t)(s[i][p] - 'A');\n        cells[i].resize(PL * lens[i]);\n        int len = lens[i];\n        // horizontal placements 0..399\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int cc = (c + p) % N;\n                    cells[i][base + p] = (uint16_t)(r * N + cc);\n                }\n            }\n        }\n        // vertical placements 400..799\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = 400 + r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int rr = (r + p) % N;\n                    cells[i][base + p] = (uint16_t)(rr * N + c);\n                }\n            }\n        }\n    }\n    cellPtrs.resize(M);\n    letterPtrs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cellPtrs[i] = cells[i].data();\n        letterPtrs[i] = letters[i].data();\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    XorShift64 rng(seed);\n\n    auto timeStart = chrono::steady_clock::now();\n    auto elapsedSec = [&]() -> double {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - timeStart).count();\n    };\n    const double TIME_LIMIT = 2.9;\n    const double GREEDY_TIME = 1.2; // time budget for greedy trials\n\n    vector<char> bestMat(CELLS, 'A');\n    int bestSat = 0;\n\n    // Prepare length-descending order\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (lens[a] != lens[b]) return lens[a] > lens[b];\n        return a < b;\n    });\n\n    // Run one deterministic trial\n    vector<char> mat;\n    int placed = 0, cov = 0;\n    greedyTrial(order, rng, mat, placed, cov);\n    if (cov > bestSat) {\n        bestSat = cov;\n        bestMat = mat;\n    }\n\n    // Greedy trials with random orders until time budget\n    vector<int> randOrder(M);\n    iota(randOrder.begin(), randOrder.end(), 0);\n    while (elapsedSec() < GREEDY_TIME) {\n        // random shuffle\n        for (int i = M - 1; i > 0; --i) {\n            int j = rng.next_int(i + 1);\n            swap(randOrder[i], randOrder[j]);\n        }\n        greedyTrial(randOrder, rng, mat, placed, cov);\n        if (cov > bestSat) {\n            bestSat = cov;\n            bestMat = mat;\n        }\n    }\n\n    // Initialize placements from bestMat\n    initPlacementsFromMatrix(bestMat);\n\n    // Local search\n    int evalInterval = 500;\n    int iter = 0;\n    while (true) {\n        if (iter % evalInterval == 0) {\n            vector<char> curMat;\n            buildMatrix(curMat, false);\n            int c = evaluateMatrix(curMat);\n            if (c > bestSat) {\n                bestSat = c;\n                bestMat = curMat;\n            }\n            if (elapsedSec() > TIME_LIMIT) break;\n        }\n        if (elapsedSec() > TIME_LIMIT) break;\n\n        // compute conflicts\n        int maxConf = -1;\n        vector<int> conflictIdx;\n        conflictIdx.reserve(M);\n        for (int i = 0; i < M; ++i) {\n            int conf = computeConf(i);\n            if (conf > 0) conflictIdx.push_back(i);\n            if (conf > maxConf) maxConf = conf;\n        }\n        if (conflictIdx.empty()) {\n            // Consistent assignment\n            vector<char> curMat;\n            buildMatrix(curMat, true); // use dots for unused\n            int c = evaluateMatrix(curMat); // should be M\n            if (c > bestSat) {\n                bestSat = c;\n                bestMat = curMat;\n            }\n            break;\n        }\n\n        int si = conflictIdx[rng.next_int((int)conflictIdx.size())];\n\n        // adjust placement of si\n        removePlacement(si, currPlacement[si]);\n        int len = lens[si];\n        const uint8_t* lp = letterPtrs[si];\n        const uint16_t* cp = cellPtrs[si];\n        int minScore = INT_MAX;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int score = 0;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                int li = lp[p];\n                score += totalCnt[cell] - counts[cell][li];\n            }\n            if (score < minScore) {\n                minScore = score;\n                bestPi = pi;\n                tie = 1;\n            } else if (score == minScore) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        // occasional random move\n        if ((rng.next_u32() & 255) == 0) {\n            bestPi = rng.next_int(PL);\n        }\n        currPlacement[si] = bestPi;\n        addPlacement(si, bestPi);\n\n        ++iter;\n    }\n\n    // Final evaluation\n    vector<char> finalMat;\n    buildMatrix(finalMat, false);\n    int cfin = evaluateMatrix(finalMat);\n    if (cfin > bestSat) {\n        bestSat = cfin;\n        bestMat = finalMat;\n    }\n\n    // Output bestMat\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << bestMat[r * N + c];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int, int>> pos;\n    vector<int> w;\n    int R = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(grid[i][j] - '0');\n            }\n        }\n    }\n\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n\n    // adjacency (cost to move to neighbor = w[neighbor])\n    vector<vector<pair<int, int>>> adj(R);\n    int dx[4] = {-1, 1, 0, 0};\n    int dy[4] = {0, 0, -1, 1};\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (id[i][j] == -1) continue;\n            int u = id[i][j];\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (0 <= ni && ni < N && 0 <= nj && nj < N && id[ni][nj] != -1) {\n                    int v = id[ni][nj];\n                    adj[u].push_back({v, w[v]});\n                }\n            }\n        }\n    }\n\n    // row segments\n    vector<int> row_id(R, -1);\n    vector<vector<int>> row_nodes;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (id[i][j] != -1) {\n                int sid = (int)row_nodes.size();\n                vector<int> seg;\n                while (j < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    row_id[u] = sid;\n                    seg.push_back(u);\n                    j++;\n                }\n                row_nodes.push_back(move(seg));\n            } else {\n                j++;\n            }\n        }\n    }\n\n    // column segments\n    vector<int> col_id(R, -1);\n    vector<vector<int>> col_nodes;\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (id[i][j] != -1) {\n                int sid = (int)col_nodes.size();\n                vector<int> seg;\n                while (i < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    col_id[u] = sid;\n                    seg.push_back(u);\n                    i++;\n                }\n                col_nodes.push_back(move(seg));\n            } else {\n                i++;\n            }\n        }\n    }\n\n    vector<int> uncoveredRow(row_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) uncoveredRow[i] = (int)row_nodes[i].size();\n    vector<int> uncoveredCol(col_nodes.size());\n    for (size_t i = 0; i < col_nodes.size(); i++) uncoveredCol[i] = (int)col_nodes[i].size();\n\n    vector<char> covered(R, 0);\n    int coveredCount = 0;\n    auto coverFrom = [&](int u) {\n        int rid = row_id[u];\n        for (int v : row_nodes[rid]) {\n            if (!covered[v]) {\n                covered[v] = 1;\n                coveredCount++;\n                uncoveredRow[row_id[v]]--;\n                uncoveredCol[col_id[v]]--;\n            }\n        }\n        int cid = col_id[u];\n        for (int v : col_nodes[cid]) {\n            if (!covered[v]) {\n                covered[v] = 1;\n                coveredCount++;\n                uncoveredRow[row_id[v]]--;\n                uncoveredCol[col_id[v]]--;\n            }\n        }\n    };\n\n    int start = id[si][sj];\n    int current = start;\n    coverFrom(current);\n\n    string route;\n    route.reserve(100000);\n\n    const int ITER_LIMIT = 400;\n    int iter = 0;\n    while (coveredCount < R && iter < ITER_LIMIT) {\n        iter++;\n        const int INF = 1e9;\n        vector<int> dist(R, INF), prev(R, -1);\n        using P = pair<int, int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[current] = 0;\n        pq.push({0, current});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            for (auto &e : adj[u]) {\n                int v = e.first, c = e.second;\n                int nd = d + c;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    pq.push({nd, v});\n                }\n            }\n        }\n\n        int best = -1;\n        double bestScore = -1.0;\n        int bestGain = 0, bestDist = INF;\n        for (int u = 0; u < R; u++) {\n            int gain = uncoveredRow[row_id[u]] + uncoveredCol[col_id[u]];\n            if (!covered[u]) gain -= 1;\n            if (gain <= 0) continue;\n            int d = dist[u];\n            if (d >= INF) continue;\n            double score = (double)gain / (d + 1);\n            if (score > bestScore || (score == bestScore && (gain > bestGain || (gain == bestGain && d < bestDist)))) {\n                bestScore = score;\n                bestGain = gain;\n                bestDist = d;\n                best = u;\n            }\n        }\n        if (best == -1) break;\n\n        vector<int> path;\n        int v = best;\n        while (true) {\n            path.push_back(v);\n            if (v == current) break;\n            v = prev[v];\n            if (v == -1) {\n                path.clear();\n                break;\n            }\n        }\n        if (path.empty()) break;\n        reverse(path.begin(), path.end());\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v2 = path[k];\n            auto [ui, uj] = pos[u];\n            auto [vi, vj] = pos[v2];\n            if (vi == ui - 1)\n                route.push_back('U');\n            else if (vi == ui + 1)\n                route.push_back('D');\n            else if (vj == uj - 1)\n                route.push_back('L');\n            else\n                route.push_back('R');\n            coverFrom(v2);\n        }\n        current = best;\n    }\n\n    auto shortest_path = [&](int src, int tgt) {\n        const int INF = 1e9;\n        vector<int> dist(R, INF), prev(R, -1);\n        using P = pair<int, int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[src] = 0;\n        pq.push({0, src});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            if (u == tgt) break;\n            for (auto &e : adj[u]) {\n                int v = e.first, c = e.second;\n                int nd = d + c;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        vector<int> path;\n        if (dist[tgt] == INF) return path;\n        int v = tgt;\n        while (true) {\n            path.push_back(v);\n            if (v == src) break;\n            v = prev[v];\n            if (v == -1) {\n                path.clear();\n                break;\n            }\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n\n    if (coveredCount < R) {\n        // move back to start if needed\n        if (current != start) {\n            auto path = shortest_path(current, start);\n            for (size_t k = 1; k < path.size(); k++) {\n                int u = path[k - 1], v = path[k];\n                auto [ui, uj] = pos[u];\n                auto [vi, vj] = pos[v];\n                if (vi == ui - 1)\n                    route.push_back('U');\n                else if (vi == ui + 1)\n                    route.push_back('D');\n                else if (vj == uj - 1)\n                    route.push_back('L');\n                else\n                    route.push_back('R');\n                coverFrom(v);\n            }\n        }\n        vector<int> vis(R, 0);\n        function<void(int)> dfs = [&](int u) {\n            vis[u] = 1;\n            for (auto &e : adj[u]) {\n                int v = e.first;\n                if (vis[v]) continue;\n                auto [ui, uj] = pos[u];\n                auto [vi, vj] = pos[v];\n                if (vi == ui - 1)\n                    route.push_back('U');\n                else if (vi == ui + 1)\n                    route.push_back('D');\n                else if (vj == uj - 1)\n                    route.push_back('L');\n                else\n                    route.push_back('R');\n                coverFrom(v);\n                dfs(v);\n                if (vi == ui - 1)\n                    route.push_back('D');\n                else if (vi == ui + 1)\n                    route.push_back('U');\n                else if (vj == uj - 1)\n                    route.push_back('R');\n                else\n                    route.push_back('L');\n            }\n        };\n        dfs(start);\n        current = start;\n    } else {\n        if (current != start) {\n            auto path = shortest_path(current, start);\n            for (size_t k = 1; k < path.size(); k++) {\n                int u = path[k - 1], v = path[k];\n                auto [ui, uj] = pos[u];\n                auto [vi, vj] = pos[v];\n                if (vi == ui - 1)\n                    route.push_back('U');\n                else if (vi == ui + 1)\n                    route.push_back('D');\n                else if (vj == uj - 1)\n                    route.push_back('L');\n                else\n                    route.push_back('R');\n            }\n            current = start;\n        }\n    }\n\n    cout << route << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct TaskCandidate {\n    int diff; // difficulty score (sum of d)\n    int id;\n    bool operator<(const TaskCandidate& other) const {\n        // max-heap by difficulty\n        if (diff != other.diff) return diff < other.diff;\n        return id > other.id;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> difficulty_sum(N, 0);\n    for (int i = 0; i < N; i++) {\n        int sum = 0;\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n            sum += d[i][k];\n        }\n        difficulty_sum[i] = sum;\n    }\n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n    }\n    priority_queue<TaskCandidate> ready_pq;\n    for (int i = 0; i < N; i++) {\n        if (indeg[i] == 0) {\n            ready_pq.push({difficulty_sum[i], i});\n        }\n    }\n    vector<int> task_status(N, 0); // 0 not started,1 working,2 done\n    vector<int> worker_status(M, -1); // task id or -1\n    vector<int> worker_start_day(M, -1);\n    vector<int> task_start_day(N, -1);\n\n    // skill estimates\n    vector<double> mean_d(K, 0.0);\n    for (int k = 0; k < K; k++) {\n        long long s = 0;\n        for (int i = 0; i < N; i++) s += d[i][k];\n        mean_d[k] = (double)s / N;\n    }\n    vector<vector<double>> s_hat(M, vector<double>(K, 0.0));\n    for (int j = 0; j < M; j++) {\n        for (int k = 0; k < K; k++) {\n            s_hat[j][k] = mean_d[k] * 1.5 + 1.0; // initial guess\n        }\n    }\n\n    int day = 1;\n    const int MAX_CANDIDATES = 200;\n    const double LR = 0.3;\n    while (true) {\n        // collect idle workers\n        vector<int> idle_workers;\n        for (int w = 0; w < M; w++) if (worker_status[w] == -1) idle_workers.push_back(w);\n\n        vector<pair<int,int>> assignments; // (worker, task)\n        if (!idle_workers.empty()) {\n            // extract some candidates from ready_pq\n            vector<int> candidates;\n            while (!ready_pq.empty() && (int)candidates.size() < MAX_CANDIDATES) {\n                int tid = ready_pq.top().id;\n                ready_pq.pop();\n                if (task_status[tid] == 0) {\n                    candidates.push_back(tid);\n                }\n            }\n            // compute best predicted time for each candidate\n            struct CandInfo {\n                int task;\n                double bestTime;\n            };\n            vector<CandInfo> infos;\n            infos.reserve(candidates.size());\n            for (int tid : candidates) {\n                double best = 1e18;\n                for (int w : idle_workers) {\n                    double pred = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[tid][k] - s_hat[w][k];\n                        if (diff > 0) pred += diff;\n                    }\n                    if (pred < 1.0) pred = 1.0;\n                    if (pred < best) best = pred;\n                }\n                infos.push_back({tid, best});\n            }\n            // sort tasks by longest predicted best time first (start long tasks early)\n            sort(infos.begin(), infos.end(), [](const CandInfo& a, const CandInfo& b){\n                if (a.bestTime != b.bestTime) return a.bestTime > b.bestTime;\n                return a.task < b.task;\n            });\n            vector<bool> assigned_task(N, false);\n            for (auto &ci : infos) {\n                if (idle_workers.empty()) break;\n                int tid = ci.task;\n                if (task_status[tid] != 0) continue;\n                // choose best worker for this task among idle\n                int best_w = -1;\n                double best_pred = 1e18;\n                int best_idx = -1;\n                for (int idx = 0; idx < (int)idle_workers.size(); idx++) {\n                    int w = idle_workers[idx];\n                    double pred = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[tid][k] - s_hat[w][k];\n                        if (diff > 0) pred += diff;\n                    }\n                    if (pred < 1.0) pred = 1.0;\n                    if (pred < best_pred) {\n                        best_pred = pred;\n                        best_w = w;\n                        best_idx = idx;\n                    }\n                }\n                if (best_w != -1) {\n                    assignments.push_back({best_w, tid});\n                    worker_status[best_w] = tid;\n                    worker_start_day[best_w] = day;\n                    task_status[tid] = 1;\n                    task_start_day[tid] = day;\n                    idle_workers.erase(idle_workers.begin() + best_idx);\n                    assigned_task[tid] = true;\n                }\n            }\n            // push back unassigned candidates\n            for (int tid : candidates) {\n                if (!assigned_task[tid]) {\n                    ready_pq.push({difficulty_sum[tid], tid});\n                }\n            }\n        }\n\n        // output assignments\n        cout << assignments.size();\n        for (auto &p : assignments) {\n            cout << \" \" << (p.first + 1) << \" \" << (p.second + 1);\n        }\n        cout << endl;\n        cout.flush();\n\n        // read feedback\n        int n;\n        if (!(cin >> n)) break;\n        if (n == -1) {\n            break;\n        }\n        vector<int> fs(n);\n        for (int i = 0; i < n; i++) cin >> fs[i];\n        for (int fidx = 0; fidx < n; fidx++) {\n            int w = fs[fidx] - 1;\n            int tid = worker_status[w];\n            if (tid < 0) continue;\n            int duration = day - worker_start_day[w] + 1;\n            task_status[tid] = 2;\n            // update skills\n            double w_obs = (double)duration;\n            double w_pred = 0.0;\n            int active = 0;\n            for (int k = 0; k < K; k++) {\n                double diff = d[tid][k] - s_hat[w][k];\n                if (diff > 0) {\n                    w_pred += diff;\n                    active++;\n                }\n            }\n            if (active == 0) active = K;\n            double delta = LR * (w_pred - w_obs) / active;\n            for (int k = 0; k < K; k++) {\n                if (active == K || d[tid][k] > s_hat[w][k]) {\n                    s_hat[w][k] += delta;\n                    if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                }\n            }\n            // update indegrees\n            for (int v : adj[tid]) {\n                indeg[v]--;\n                if (indeg[v] == 0 && task_status[v] == 0) {\n                    ready_pq.push({difficulty_sum[v], v});\n                }\n            }\n            worker_status[w] = -1;\n        }\n        day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int NORD = 1000;\nconst int CHOOSE = 50;\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst double GLOBAL_TIME_LIMIT = 1.90; // seconds\n\nint ax[NORD], byy[NORD], cx[NORD], dy[NORD];\ndouble midx[NORD], midy[NORD];\n\ninline int mdist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Greedy nearest feasible neighbor route (used in search)\nlong long route_nearest(const int* subset, int k, vector<pair<int,int>>* path = nullptr) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < k; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int done = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (path) {\n        path->clear();\n        path->reserve(k * 2 + 2);\n        path->push_back({curx, cury});\n    }\n    while (done < k) {\n        int best = -1;\n        int bestd = INT_MAX;\n        int tx = 0, ty = 0;\n        for (int i = 0; i < k; i++) {\n            if (status[i] == 2) continue;\n            int x = (status[i] == 0 ? px[i] : qx[i]);\n            int y = (status[i] == 0 ? py[i] : qy[i]);\n            int d = abs(curx - x) + abs(cury - y);\n            if (d < bestd) {\n                bestd = d;\n                best = i;\n                tx = x;\n                ty = y;\n            }\n        }\n        total += bestd;\n        curx = tx; cury = ty;\n        if (path) path->push_back({curx, cury});\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; done++; }\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (path) path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\n// Pick nearest pickup, deliver immediately\nlong long route_immediate(const int* subset, int k, vector<pair<int,int>>* path = nullptr) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < k; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool rem[CHOOSE];\n    memset(rem, 1, sizeof(bool) * k);\n    int remaining = k;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (path) {\n        path->clear();\n        path->reserve(k * 2 + 2);\n        path->push_back({curx, cury});\n    }\n    while (remaining > 0) {\n        int best = -1;\n        int bestd = INT_MAX;\n        for (int i = 0; i < k; i++) {\n            if (!rem[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) {\n                bestd = d;\n                best = i;\n            }\n        }\n        total += bestd;\n        curx = px[best]; cury = py[best];\n        if (path) path->push_back({curx, cury});\n        int d2 = abs(curx - qx[best]) + abs(cury - qy[best]);\n        total += d2;\n        curx = qx[best]; cury = qy[best];\n        if (path) path->push_back({curx, cury});\n        rem[best] = false;\n        remaining--;\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (path) path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\n// Pick all by NN then deliver all by NN\nlong long route_pick_then_drop(const int* subset, int k, vector<pair<int,int>>* path = nullptr) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < k; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool picked[CHOOSE];\n    bool deliv[CHOOSE];\n    memset(picked, 0, sizeof(picked));\n    memset(deliv, 0, sizeof(deliv));\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (path) {\n        path->clear();\n        path->reserve(k * 2 + 2);\n        path->push_back({curx, cury});\n    }\n    int pcnt = 0, dcnt = 0;\n    while (pcnt < k) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < k; i++) {\n            if (picked[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) {\n                bestd = d; best = i;\n            }\n        }\n        total += bestd;\n        curx = px[best]; cury = py[best];\n        if (path) path->push_back({curx, cury});\n        picked[best] = true; pcnt++;\n    }\n    while (dcnt < k) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < k; i++) {\n            if (deliv[i]) continue;\n            int d = abs(curx - qx[i]) + abs(cury - qy[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        total += bestd;\n        curx = qx[best]; cury = qy[best];\n        if (path) path->push_back({curx, cury});\n        deliv[best] = true; dcnt++;\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (path) path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < NORD; i++) {\n        if (!(cin >> ax[i] >> byy[i] >> cx[i] >> dy[i])) return 0;\n        midx[i] = 0.5 * (ax[i] + cx[i]);\n        midy[i] = 0.5 * (byy[i] + dy[i]);\n    }\n\n    auto start_all = chrono::steady_clock::now();\n\n    // baseline cost\n    vector<long long> cost(NORD);\n    for (int i = 0; i < NORD; i++) {\n        cost[i] = mdist(DEPOT_X, DEPOT_Y, ax[i], byy[i]) +\n                  mdist(ax[i], byy[i], cx[i], dy[i]) +\n                  mdist(cx[i], dy[i], DEPOT_X, DEPOT_Y);\n    }\n    vector<int> order_ids(NORD);\n    iota(order_ids.begin(), order_ids.end(), 0);\n    sort(order_ids.begin(), order_ids.end(), [&](int i, int j){ return cost[i] < cost[j]; });\n\n    array<int, CHOOSE> bestSubset;\n    for (int i = 0; i < CHOOSE; i++) bestSubset[i] = order_ids[i];\n    long long bestT = route_nearest(bestSubset.data(), CHOOSE);\n\n    // Cluster-based initial solutions\n    vector<pair<double,double>> seedPoints;\n    for (int gx = 0; gx <= 800; gx += 200) {\n        for (int gy = 0; gy <= 800; gy += 200) {\n            seedPoints.emplace_back(gx, gy);\n        }\n    }\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distCoord(0, 800);\n    int randomSeeds = 40;\n    for (int i = 0; i < randomSeeds; i++) {\n        seedPoints.emplace_back(distCoord(rng), distCoord(rng));\n    }\n\n    vector<int> ids(NORD);\n    iota(ids.begin(), ids.end(), 0);\n\n    for (auto &sp : seedPoints) {\n        double sx = sp.first, sy = sp.second;\n        sort(ids.begin(), ids.end(), [&](int i, int j) {\n            double dx1 = midx[i] - sx, dy1 = midy[i] - sy;\n            double dx2 = midx[j] - sx, dy2 = midy[j] - sy;\n            return dx1*dx1 + dy1*dy1 < dx2*dx2 + dy2*dy2;\n        });\n        array<int, CHOOSE> cand;\n        for (int i = 0; i < CHOOSE; i++) cand[i] = ids[i];\n        long long t = route_nearest(cand.data(), CHOOSE);\n        if (t < bestT) {\n            bestT = t;\n            bestSubset = cand;\n        }\n    }\n\n    array<int, CHOOSE> curSubset = bestSubset;\n    long long curT = bestT;\n\n    // Build outList\n    vector<int> outList;\n    outList.reserve(NORD - CHOOSE);\n    vector<char> inSel(NORD, 0);\n    for (int i = 0; i < CHOOSE; i++) inSel[curSubset[i]] = 1;\n    for (int i = 0; i < NORD; i++) if (!inSel[i]) outList.push_back(i);\n\n    auto now = chrono::steady_clock::now();\n    double elapsed = chrono::duration<double>(now - start_all).count();\n    double time_left = GLOBAL_TIME_LIMIT - elapsed;\n    if (time_left > 0.05) {\n        auto end_time = now + chrono::duration<double>(time_left);\n        uniform_int_distribution<int> distIn(0, CHOOSE-1);\n        uniform_real_distribution<double> distReal(0.0, 1.0);\n        int outSize = NORD - CHOOSE;\n        uniform_int_distribution<int> distOut(0, outSize-1);\n        double startTemp = 3000.0, endTemp = 30.0;\n        double temp = startTemp;\n        long long iter = 0;\n        while (true) {\n            if ((iter & 0x3FF) == 0) {\n                now = chrono::steady_clock::now();\n                if (now >= end_time) break;\n                double progress = chrono::duration<double>(now - start_all).count() / GLOBAL_TIME_LIMIT;\n                if (progress > 1.0) progress = 1.0;\n                temp = startTemp * pow(endTemp / startTemp, progress);\n            }\n            iter++;\n            int idxIn = distIn(rng);\n            int idxOut = distOut(rng);\n            int oldIn = curSubset[idxIn];\n            int newIn = outList[idxOut];\n            curSubset[idxIn] = newIn;\n            long long newT = route_nearest(curSubset.data(), CHOOSE);\n            bool accept = false;\n            if (newT < curT) {\n                accept = true;\n            } else {\n                double diff = double(curT - newT);\n                double prob = exp(diff / temp);\n                if (distReal(rng) < prob) accept = true;\n            }\n            if (accept) {\n                curT = newT;\n                outList[idxOut] = oldIn;\n                if (newT < bestT) {\n                    bestT = newT;\n                    bestSubset = curSubset;\n                }\n            } else {\n                curSubset[idxIn] = oldIn; // revert\n            }\n        }\n    }\n\n    // Build final route using the best of several heuristics\n    vector<pair<int,int>> bestPath, tmpPath;\n    long long bestRouteCost = (1LL << 60);\n    long long t1 = route_nearest(bestSubset.data(), CHOOSE, &tmpPath);\n    if (t1 < bestRouteCost) {\n        bestRouteCost = t1;\n        bestPath = tmpPath;\n    }\n    long long t2 = route_immediate(bestSubset.data(), CHOOSE, &tmpPath);\n    if (t2 < bestRouteCost) {\n        bestRouteCost = t2;\n        bestPath = tmpPath;\n    }\n    long long t3 = route_pick_then_drop(bestSubset.data(), CHOOSE, &tmpPath);\n    if (t3 < bestRouteCost) {\n        bestRouteCost = t3;\n        bestPath = tmpPath;\n    }\n\n    // Output\n    cout << CHOOSE;\n    for (int i = 0; i < CHOOSE; i++) {\n        cout << ' ' << (bestSubset[i] + 1); // convert to 1-based\n    }\n    cout << '\\n';\n    cout << bestPath.size();\n    for (auto &p : bestPath) {\n        cout << ' ' << p.first << ' ' << p.second;\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, sz;\n    DSU(int n_=0): n(n_), p(n_), sz(n_,1) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\n    bool merge(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b];\n        return true;\n    }\n};\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u,v;\n    int d; // rounded euclidean distance\n    bool in_mst=false;\n};\n\nvector<Edge> edges(M);\nvector<int> xs(N), ys(N);\n\n// low-link variables\nvector<int> tin, low;\nvector<char> vis;\nvector<char> is_bridge;\nvector<vector<pair<int,int>>> adjlist;\nint timer_dfs;\n\n// compute bridges on current alive graph\nvoid compute_bridges(const vector<char>& alive){\n    for(int i=0;i<N;i++) adjlist[i].clear();\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u = edges[id].u;\n        int v = edges[id].v;\n        adjlist[u].push_back({v,id});\n        adjlist[v].push_back({u,id});\n    }\n    fill(vis.begin(), vis.end(), 0);\n    fill(is_bridge.begin(), is_bridge.end(), 0);\n    timer_dfs = 0;\n    function<void(int,int)> dfs = [&](int v,int pe){\n        vis[v]=1;\n        tin[v]=low[v]=++timer_dfs;\n        for(auto [to,eid]: adjlist[v]){\n            if(eid==pe) continue;\n            if(vis[to]){\n                low[v]=min(low[v], tin[to]);\n            }else{\n                dfs(to,eid);\n                low[v]=min(low[v], low[to]);\n                if(low[to] > tin[v]){\n                    is_bridge[eid]=1;\n                }\n            }\n        }\n    };\n    for(int i=0;i<N;i++){\n        if(!vis[i]) dfs(i,-1);\n    }\n}\n\n// prepare out_count (edges leaving each component of dsu) while scanning alive edges\nvoid compute_out_count(const vector<char>& alive, DSU &dsu, vector<int>& out_cnt){\n    fill(out_cnt.begin(), out_cnt.end(), 0);\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        int ru=dsu.find(u), rv=dsu.find(v);\n        if(ru==rv) continue;\n        out_cnt[ru]++;\n        out_cnt[rv]++;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    // read coordinates\n    for(int i=0;i<N;i++){\n        if(!(cin>>xs[i]>>ys[i])) return 0;\n    }\n    // read edges\n    for(int i=0;i<M;i++){\n        int u,v;\n        cin>>u>>v;\n        edges[i].u=u;\n        edges[i].v=v;\n        long dx = xs[u]-xs[v];\n        long dy = ys[u]-ys[v];\n        edges[i].d = (int)llround(sqrt((double)(dx*dx + dy*dy)));\n    }\n\n    // compute MST on lower bounds d\n    vector<int> idx(M);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int a,int b){\n        if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n        return a < b;\n    });\n    DSU dsu_tmp(N);\n    int cnt=0;\n    for(int id: idx){\n        if(dsu_tmp.merge(edges[id].u, edges[id].v)){\n            edges[id].in_mst = true;\n            if(++cnt == N-1) break;\n        }\n    }\n\n    // initialize structures\n    vector<char> alive(M, 1);\n    DSU dsu_conn(N);\n    int comp_cnt = N;\n\n    tin.assign(N,0);\n    low.assign(N,0);\n    vis.assign(N,0);\n    is_bridge.assign(M,0);\n    adjlist.assign(N, {});\n    vector<int> out_cnt(N,0);\n\n    const double MST_START = 1.55;\n    const double MST_END   = 1.9;\n    const double OTH_START = 1.35;\n    const double OTH_END   = 1.6;\n    const double CYCLE_THR = 1.03;\n    const double GAMMA     = 0.5; // use sqrt of progress\n\n    for(int i=0;i<M;i++){\n        int l;\n        if(!(cin>>l)) break;\n        double r = (double)l / (double)edges[i].d;\n\n        // recompute bridges and out_count\n        compute_bridges(alive);\n        compute_out_count(alive, dsu_conn, out_cnt);\n\n        bool accept = false;\n        if(is_bridge[i]){\n            accept = true;\n        }else{\n            int ru = dsu_conn.find(edges[i].u);\n            int rv = dsu_conn.find(edges[i].v);\n            if(ru != rv){\n                double p = (double)i / (double)M;\n                double f = sqrt(p); // p^0.5\n                double thr;\n                if(edges[i].in_mst){\n                    thr = MST_START + (MST_END - MST_START) * f;\n                }else{\n                    thr = OTH_START + (OTH_END - OTH_START) * f;\n                }\n                int k = min(out_cnt[ru], out_cnt[rv]);\n                if(k <= 2) thr += 0.30;\n                else if(k <= 4) thr += 0.15;\n                else if(k <= 6) thr += 0.07;\n                if(thr > 2.8) thr = 2.8;\n                if(r <= thr) accept = true;\n            }else{\n                // forms cycle in accepted forest\n                if(comp_cnt > 1 && r <= CYCLE_THR) accept = true;\n                else accept = false;\n            }\n        }\n\n        if(accept){\n            if(dsu_conn.merge(edges[i].u, edges[i].v)){\n                comp_cnt--;\n            }\n            // alive stays true\n        }else{\n            alive[i] = 0; // remove edge\n        }\n\n        cout << (accept ? 1 : 0) << '\\n';\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet { int x,y,t; };\nint N,M;\nvector<Pet> pets;\nvector<int> hx,hy;\nvector<vector<bool>> wall(31, vector<bool>(31,false));\n\nint r1,r2,c1,c2;\nint colWallCol,rowWallRow;\nint builderCol,builderRow;\nchar colDir,rowDir;\nint entryWallX, entryWallY;\npair<int,int> entryDest;\nint T_close;\n\n// encode for sets\nint encode(int x,int y){ return x*64 + y; }\n\nint dist_point_to_rect(int px,int py,int r1,int r2,int c1,int c2){\n    int dx=0,dy=0;\n    if(px<r1) dx=r1-px;\n    else if(px>r2) dx=px-r2;\n    if(py<c1) dy=c1-py;\n    else if(py>c2) dy=py-c2;\n    return dx+dy;\n}\n\nbool can_build(int wx,int wy,const vector<Pet>& pets,const vector<int>& hx,const vector<int>& hy){\n    if(wx<1 || wx>30 || wy<1 || wy>30) return false;\n    for(auto &p: pets){\n        if(p.x==wx && p.y==wy) return false;\n        if(abs(p.x-wx)+abs(p.y-wy)<=1) return false;\n    }\n    for(size_t i=0;i<hx.size();i++){\n        if(hx[i]==wx && hy[i]==wy) return false;\n    }\n    return true;\n}\n\nchar bfs_move(int sx,int sy,int tx,int ty,bool regionOnly,\n              const unordered_set<int>& buildTargets){\n    auto blocked = [&](int x,int y)->bool{\n        if(x<1 || x>30 || y<1 || y>30) return true;\n        if(regionOnly && (x<r1 || x>r2 || y<c1 || y>c2)) return true;\n        if(wall[x][y]) return true;\n        if(buildTargets.find(encode(x,y))!=buildTargets.end()) return true;\n        return false;\n    };\n    if(blocked(tx,ty)) return '.';\n    static int dist[31][31];\n    for(int i=1;i<=30;i++) for(int j=1;j<=30;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[tx][ty]=0;\n    q.push({tx,ty});\n    int dxs[4]={-1,1,0,0};\n    int dys[4]={0,0,-1,1};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        int nd=dist[x][y]+1;\n        for(int d=0;d<4;d++){\n            int nx=x+dxs[d], ny=y+dys[d];\n            if(blocked(nx,ny)) continue;\n            if(dist[nx][ny]==-1){\n                dist[nx][ny]=nd;\n                q.push({nx,ny});\n            }\n        }\n    }\n    if(dist[sx][sy]<=0) return '.';\n    char dirc[4]={'U','D','L','R'};\n    for(int d=0;d<4;d++){\n        int nx=sx+dxs[d], ny=sy+dys[d];\n        if(nx<1||nx>30||ny<1||ny>30) continue;\n        if(regionOnly && (nx<r1||nx>r2||ny<c1||ny>c2)) continue;\n        if(blocked(nx,ny)) continue;\n        if(dist[nx][ny]==dist[sx][sy]-1) return dirc[d];\n    }\n    return '.';\n}\n\nvoid select_region(const vector<int>& initHx,const vector<int>& initHy){\n    double bestScore=-1e18;\n    int bestR1=1,bestR2=5,bestC1=1,bestC2=5;\n    for(int k=15;k>=5;k--){\n        for(int corner=0;corner<4;corner++){\n            int rr1,rr2,cc1,cc2;\n            switch(corner){\n                case 0: rr1=1; rr2=k; cc1=1; cc2=k; break;\n                case 1: rr1=1; rr2=k; cc1=30-k+1; cc2=30; break;\n                case 2: rr1=30-k+1; rr2=30; cc1=1; cc2=k; break;\n                default: rr1=30-k+1; rr2=30; cc1=30-k+1; cc2=30; break;\n            }\n            int inside=0;\n            int minDistPet=1000;\n            for(auto &p: pets){\n                if(rr1<=p.x && p.x<=rr2 && cc1<=p.y && p.y<=cc2) inside++;\n                int d=dist_point_to_rect(p.x,p.y,rr1,rr2,cc1,cc2);\n                minDistPet=min(minDistPet,d);\n            }\n            if(pets.empty()) minDistPet=100;\n            int maxHD=0;\n            int midc=(cc1+cc2)/2;\n            int entryR = (rr1==1)? rr2 : rr1;\n            int entryC = midc;\n            for(size_t i=0;i<initHx.size();i++){\n                int d=abs(initHx[i]-entryR)+abs(initHy[i]-entryC);\n                maxHD=max(maxHD,d);\n            }\n            double area=k*k;\n            double score=area - inside*200.0 - maxHD*3.0 + minDistPet*2.0;\n            if(inside==0) score+=5000.0;\n            if(score>bestScore){\n                bestScore=score;\n                bestR1=rr1; bestR2=rr2; bestC1=cc1; bestC2=cc2;\n            }\n        }\n    }\n    r1=bestR1; r2=bestR2; c1=bestC1; c2=bestC2;\n    // dirs and builders\n    if(c1==1){ colWallCol=c2+1; colDir='r'; builderCol=c2; }\n    else { colWallCol=c1-1; colDir='l'; builderCol=c1; }\n    if(r1==1){ rowWallRow=r2+1; rowDir='d'; builderRow=r2; }\n    else { rowWallRow=r1-1; rowDir='u'; builderRow=r1; }\n    entryWallX=rowWallRow;\n    entryWallY=(c1+c2)/2;\n    entryDest={builderRow, entryWallY};\n    // T_close based on distances\n    int maxHD=0;\n    for(size_t i=0;i<initHx.size();i++){\n        int d=abs(initHx[i]-entryDest.first)+abs(initHy[i]-entryDest.second);\n        maxHD=max(maxHD,d);\n    }\n    T_close=min(40, maxHD + (c2-c1+1) + 5);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N;\n    pets.resize(N);\n    for(int i=0;i<N;i++) cin>>pets[i].x>>pets[i].y>>pets[i].t;\n    cin>>M;\n    hx.resize(M); hy.resize(M);\n    for(int i=0;i<M;i++) cin>>hx[i]>>hy[i];\n    vector<int> initHx=hx, initHy=hy;\n    select_region(initHx, initHy);\n\n    vector<pair<int,int>> colCells, rowCells;\n    for(int r=r1;r<=r2;r++) colCells.push_back({r,colWallCol});\n    for(int c=c1;c<=c2;c++) rowCells.push_back({rowWallRow,c});\n\n    for(int turn=0;turn<300;turn++){\n        // compute missing cells\n        vector<int> colMissingRows;\n        for(auto &p: colCells){\n            if(!wall[p.first][p.second]) colMissingRows.push_back(p.first);\n        }\n        vector<int> rowMissingCols;\n        bool close_condition=false;\n        bool all_inside=true;\n        for(int i=0;i<M;i++){\n            if(!(r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2)){\n                all_inside=false; break;\n            }\n        }\n        if(all_inside || turn>=T_close) close_condition=true;\n        for(auto &p: rowCells){\n            if(p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) rowMissingCols.push_back(p.second);\n        }\n\n        unordered_set<int> buildTargets;\n        string actions(M,'.');\n\n        // build if possible\n        for(int i=0;i<M;i++){\n            if(r1<=hx[i] && hx[i]<=r2 && hy[i]==builderCol){\n                if(!colMissingRows.empty()){\n                    if(!wall[hx[i]][colWallCol]){\n                        int wx=hx[i], wy=colWallCol;\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=colDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n            if(hx[i]==builderRow && hy[i]>=c1 && hy[i]<=c2){\n                if(!rowMissingCols.empty()){\n                    if(!(entryWallX==rowWallRow && entryWallY==hy[i] && !close_condition)){\n                        if(!wall[rowWallRow][hy[i]]){\n                            int wx=rowWallRow, wy=hy[i];\n                            int key=encode(wx,wy);\n                            if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                                actions[i]=rowDir;\n                                buildTargets.insert(key);\n                                continue;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // move humans\n        for(int i=0;i<M;i++){\n            if(actions[i]!='.') continue;\n            bool inside = (r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2);\n            if(!inside){\n                // move to entry\n                char mv=bfs_move(hx[i],hy[i],entryDest.first,entryDest.second,false,buildTargets);\n                actions[i]=mv;\n            }else{\n                if(!colMissingRows.empty()){\n                    // target nearest missing row\n                    int bestd=1e9, targRow=colMissingRows[0];\n                    for(int rr: colMissingRows){\n                        int d=abs(rr-hx[i])+abs(builderCol-hy[i]);\n                        if(d<bestd){bestd=d; targRow=rr;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],targRow,builderCol,true,buildTargets);\n                    actions[i]=mv;\n                }else if(!rowMissingCols.empty()){\n                    int bestd=1e9, targCol=rowMissingCols[0];\n                    for(int cc: rowMissingCols){\n                        int d=abs(builderRow-hx[i])+abs(cc-hy[i]);\n                        if(d<bestd){bestd=d; targCol=cc;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],builderRow,targCol,true,buildTargets);\n                    actions[i]=mv;\n                }else{\n                    actions[i]='.'; // stay\n                }\n            }\n        }\n\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // read pet moves\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            if(s==\".\") continue;\n            for(char ch: s){\n                if(ch=='U') pets[i].x--;\n                else if(ch=='D') pets[i].x++;\n                else if(ch=='L') pets[i].y--;\n                else if(ch=='R') pets[i].y++;\n            }\n        }\n        // apply builds\n        for(int key: buildTargets){\n            int wx=key/64, wy=key%64;\n            if(wx>=1 && wx<=30 && wy>=1 && wy<=30) wall[wx][wy]=true;\n        }\n        // move humans\n        for(int i=0;i<M;i++){\n            char ac=actions[i];\n            if(ac=='U') hx[i]--;\n            else if(ac=='D') hx[i]++;\n            else if(ac=='L') hy[i]--;\n            else if(ac=='R') hy[i]++;\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int DIRS = 4;\nconst int L = 200;\nconst double TIME_LIMIT = 1.95;\n\nint startId, targetId;\ndouble p_forget, q_exec;\n\nint moveTbl[N][DIRS];\ndouble weightArr[L];\ndouble weight_q[L];\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> uni01(0.0, 1.0);\n\ninline int idx(int i, int j) { return i * W + j; }\n\nvoid build_moves(const vector<string> &h, const vector<string> &v) {\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int id = idx(i, j);\n            // Up\n            if (i == 0 || v[i - 1][j] == '1')\n                moveTbl[id][0] = id;\n            else\n                moveTbl[id][0] = idx(i - 1, j);\n            // Down\n            if (i == H - 1 || v[i][j] == '1')\n                moveTbl[id][1] = id;\n            else\n                moveTbl[id][1] = idx(i + 1, j);\n            // Left\n            if (j == 0 || h[i][j - 1] == '1')\n                moveTbl[id][2] = id;\n            else\n                moveTbl[id][2] = idx(i, j - 1);\n            // Right\n            if (j == W - 1 || h[i][j] == '1')\n                moveTbl[id][3] = id;\n            else\n                moveTbl[id][3] = idx(i, j + 1);\n        }\n    }\n}\n\nvector<int> bfs_path(bool monotone_only) {\n    vector<int> prev(N, -1), prevDir(N, -1);\n    vector<char> vis(N, 0);\n    queue<int> q;\n    vis[startId] = 1;\n    q.push(startId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        if (u == targetId) break;\n        for (int dir = 0; dir < DIRS; dir++) {\n            if (monotone_only && !(dir == 1 || dir == 3)) continue; // only D or R\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (!vis[nb]) {\n                vis[nb] = 1;\n                prev[nb] = u;\n                prevDir[nb] = dir;\n                q.push(nb);\n            }\n        }\n    }\n    if (!vis[targetId]) return {};\n    vector<int> path;\n    int cur = targetId;\n    while (cur != startId) {\n        int d = prevDir[cur];\n        path.push_back(d);\n        cur = prev[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid compute_distances(vector<double> &dist1, vector<double> &dist2) {\n    dist1.assign(N, 1e9);\n    queue<int> q;\n    dist1[targetId] = 0;\n    q.push(targetId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        double du = dist1[u];\n        for (int dir = 0; dir < DIRS; dir++) {\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (dist1[nb] > du + 1) {\n                dist1[nb] = du + 1;\n                q.push(nb);\n            }\n        }\n    }\n    dist2.resize(N);\n    for (int i = 0; i < N; i++) dist2[i] = dist1[i] * dist1[i];\n}\n\nvector<int> greedy_seq(const vector<double> &dist, double eps) {\n    vector<double> cur(N, 0.0), nxt(N, 0.0);\n    cur[startId] = 1.0;\n    vector<int> seq(L);\n    static const int tieOrd[4] = {1, 3, 2, 0};\n    for (int t = 0; t < L; t++) {\n        double bestVal = 1e100;\n        int bestDir = 0;\n        double scores[4] = {0, 0, 0, 0};\n        for (int dir = 0; dir < DIRS; dir++) {\n            double s = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                s += pu * dist[nb];\n            }\n            scores[dir] = s;\n        }\n        bestDir = tieOrd[0];\n        bestVal = scores[bestDir];\n        for (int k = 1; k < 4; k++) {\n            int d = tieOrd[k];\n            double v = scores[d];\n            if (v < bestVal) {\n                bestVal = v;\n                bestDir = d;\n            }\n        }\n        if (eps > 0.0) {\n            double r = uni01(rng);\n            if (r < eps) {\n                bestDir = rng() & 3ULL;\n            }\n        }\n        seq[t] = bestDir;\n        fill(nxt.begin(), nxt.end(), 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb != targetId) nxt[nb] += mv;\n            nxt[u] += pu * p_forget;\n        }\n        cur.swap(nxt);\n    }\n    return seq;\n}\n\nvector<int> repeat_path_seed(const vector<int> &path, int r) {\n    vector<int> seq;\n    if (path.empty()) return seq;\n    seq.reserve(L);\n    for (int d : path) {\n        for (int k = 0; k < r && (int)seq.size() < L; k++) seq.push_back(d);\n        if ((int)seq.size() >= L) break;\n    }\n    while ((int)seq.size() < L) {\n        for (int d : path) {\n            if ((int)seq.size() >= L) break;\n            seq.push_back(d);\n        }\n    }\n    if ((int)seq.size() > L) seq.resize(L);\n    return seq;\n}\n\nvector<int> ratio_seed(int dv, int dh) {\n    vector<int> seq;\n    seq.reserve(L);\n    int total = max(1, dv + dh);\n    int nD = (int)round((double)L * dv / total);\n    nD = max(0, min(L, nD));\n    int nR = L - nD;\n    int cD = 0, cR = 0;\n    while ((int)seq.size() < L) {\n        double pd = (nD - cD);\n        double pr = (nR - cR);\n        if (pd <= 0) {\n            seq.push_back(3);\n            cR++;\n        } else if (pr <= 0) {\n            seq.push_back(1);\n            cD++;\n        } else {\n            double probD = pd / (pd + pr);\n            if (uni01(rng) < probD) {\n                seq.push_back(1);\n                cD++;\n            } else {\n                seq.push_back(3);\n                cR++;\n            }\n        }\n    }\n    return seq;\n}\n\ndouble eval_seq(const vector<int> &seq) {\n    static double cur[N], nxt[N];\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double score = 0.0;\n    for (int t = 0; t < L; t++) {\n        int dir = seq[t];\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][dir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\nstatic double backVal[L + 1][N];\n\nvoid compute_backward(const vector<int> &seq) {\n    for (int u = 0; u < N; u++) backVal[L][u] = 0.0;\n    for (int t = L - 1; t >= 0; t--) {\n        int dir = seq[t];\n        double wq = weight_q[t];\n        for (int u = 0; u < N; u++) {\n            int nb = moveTbl[u][dir];\n            double val = p_forget * backVal[t + 1][u];\n            if (nb == targetId) {\n                val += wq;\n            } else {\n                val += q_exec * backVal[t + 1][nb];\n            }\n            backVal[t][u] = val;\n        }\n    }\n}\n\ndouble build_new_seq(vector<int> &outSeq) {\n    static double curDist[N], nextDist[N];\n    fill(curDist, curDist + N, 0.0);\n    curDist[startId] = 1.0;\n    double score = 0.0;\n    static const int tieOrd[4] = {1, 3, 2, 0};\n    for (int t = 0; t < L; t++) {\n        double stay = 0.0;\n        for (int u = 0; u < N; u++) {\n            stay += curDist[u] * backVal[t + 1][u];\n        }\n        stay *= p_forget;\n        double bestVal = -1e100;\n        int bestDir = tieOrd[0];\n        for (int ki = 0; ki < 4; ki++) {\n            int dir = tieOrd[ki];\n            double sum = stay;\n            const double *backNext = backVal[t + 1];\n            for (int u = 0; u < N; u++) {\n                double pu = curDist[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                if (nb == targetId) sum += pu * weight_q[t];\n                else sum += pu * q_exec * backNext[nb];\n            }\n            if (sum > bestVal) {\n                bestVal = sum;\n                bestDir = dir;\n            }\n        }\n        outSeq[t] = bestDir;\n        fill(nextDist, nextDist + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = curDist[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nextDist[nb] += mv;\n            }\n            nextDist[u] += pu * p_forget;\n        }\n        swap(curDist, nextDist);\n    }\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj, ti, tj;\n    if (!(cin >> si >> sj >> ti >> tj >> p_forget)) return 0;\n    startId = idx(si, sj);\n    targetId = idx(ti, tj);\n    q_exec = 1.0 - p_forget;\n    vector<string> h(H), v(H - 1);\n    for (int i = 0; i < H; i++) cin >> h[i];\n    for (int i = 0; i < H - 1; i++) cin >> v[i];\n    for (int t = 0; t < L; t++) {\n        weightArr[t] = 400.0 - t;\n        weight_q[t] = weightArr[t] * q_exec;\n    }\n    auto time_start = chrono::steady_clock::now();\n    double time_limit = TIME_LIMIT;\n\n    build_moves(h, v);\n    vector<double> dist1, dist2;\n    compute_distances(dist1, dist2);\n    vector<int> shortest = bfs_path(false);\n    vector<int> monotone = bfs_path(true);\n\n    vector<vector<int>> seeds;\n    seeds.push_back(greedy_seq(dist1, 0.0));\n    seeds.push_back(greedy_seq(dist2, 0.0));\n    seeds.push_back(greedy_seq(dist1, 0.1));\n    seeds.push_back(greedy_seq(dist1, 0.3));\n    int rep_suggest = max(1, min(8, (int)ceil(log(0.1) / log(max(0.05, p_forget))))); // target ~90% success\n    if (!shortest.empty()) seeds.push_back(repeat_path_seed(shortest, rep_suggest));\n    if (!monotone.empty()) seeds.push_back(repeat_path_seed(monotone, rep_suggest));\n    seeds.push_back(ratio_seed(ti - si, tj - sj));\n\n    vector<pair<double, vector<int>>> seedScores;\n    seedScores.reserve(seeds.size());\n    for (auto &s : seeds) {\n        if ((int)s.size() != L) continue;\n        double sc = eval_seq(s);\n        seedScores.emplace_back(sc, s);\n    }\n    if (seedScores.empty()) return 0;\n    sort(seedScores.begin(), seedScores.end(),\n         [](const auto &a, const auto &b) { return a.first > b.first; });\n\n    double bestScore = -1.0;\n    vector<int> bestSeq;\n    int topK = min(4, (int)seedScores.size());\n    for (int i = 0; i < topK; i++) {\n        vector<int> seq = seedScores[i].second;\n        double curScore = seedScores[i].first;\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > time_limit) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 200) break;\n        }\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > time_limit) break;\n    }\n\n    // Random restarts if time remains\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > time_limit) break;\n        double eps = uni01(rng) * uni01(rng) * 0.5;\n        vector<int> seq = greedy_seq(dist1, eps);\n        double curScore = eval_seq(seq);\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > time_limit) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 50) break;\n        }\n    }\n\n    string out;\n    out.reserve(L);\n    for (int d : bestSeq) {\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        out.push_back(c);\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// weights for the heuristic score\nconst int MATCH_REWARD = 3;\nconst int MISMATCH_PENALTY = 2;\nconst int BOUNDARY_PENALTY = 3;\nconst int PAIR_MATCH_REWARD = 5;\nconst int PAIR_MISMATCH_PENALTY = 4;\n\nint baseType[N][N];\nint rotCnt[N][N];\nint curType[N][N];\n\nint toMap[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};\nint usedMask[8];\nint rotMap[8][4];\nvector<array<int, 2>> pairsOfType[8];\n\ninline int apply_rot(int b, int r) {\n    return rotMap[b][r];\n}\ninline bool uses(int t, int dir) {\n    return (usedMask[t] >> dir) & 1;\n}\n\n// edge contribution for edge from (i,j) in direction dir\ninline int edge_contrib(int i, int j, int dir) {\n    int t = curType[i][j];\n    bool a = uses(t, dir);\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n        return a ? -BOUNDARY_PENALTY : 0;\n    }\n    bool b = uses(curType[ni][nj], dir ^ 2);\n    if (a && b) return MATCH_REWARD;\n    else if (a || b) return -MISMATCH_PENALTY;\n    else return 0;\n}\n\ninline int compute_tile_pair(int i, int j) {\n    int t = curType[i][j];\n    int res = 0;\n    for (auto &pr : pairsOfType[t]) {\n        int a = pr[0], b = pr[1];\n        bool ma = false, mb = false;\n        int ni = i + di[a], nj = j + dj[a];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            ma = uses(curType[ni][nj], a ^ 2);\n        }\n        ni = i + di[b]; nj = j + dj[b];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            mb = uses(curType[ni][nj], b ^ 2);\n        }\n        if (ma && mb) res += PAIR_MATCH_REWARD;\n        else if (ma || mb) res -= PAIR_MISMATCH_PENALTY;\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    // precompute used masks and rotation maps and pairs\n    for (int t = 0; t < 8; t++) {\n        int m = 0;\n        for (int d = 0; d < 4; d++) if (toMap[t][d] != -1) m |= (1 << d);\n        usedMask[t] = m;\n    }\n    int nextType[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int b = 0; b < 8; b++) {\n        rotMap[b][0] = b;\n        for (int r = 1; r < 4; r++) {\n            rotMap[b][r] = nextType[rotMap[b][r - 1]];\n        }\n    }\n    for (int t = 0; t < 8; t++) {\n        pairsOfType[t].clear();\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 != -1 && d < d2) pairsOfType[t].push_back({d, d2});\n        }\n    }\n\n    // read input\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) {\n            baseType[i][j] = s[j] - '0';\n        }\n    }\n\n    // initial rotations: try to minimize boundary usage\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int bestR = 0, bestPen = 100;\n            for (int r = 0; r < 4; r++) {\n                int t = apply_rot(baseType[i][j], r);\n                int pen = 0;\n                if (i == 0 && uses(t, 1)) pen++;\n                if (i == N - 1 && uses(t, 3)) pen++;\n                if (j == 0 && uses(t, 0)) pen++;\n                if (j == N - 1 && uses(t, 2)) pen++;\n                if (pen < bestPen) {\n                    bestPen = pen;\n                    bestR = r;\n                }\n            }\n            rotCnt[i][j] = bestR;\n            curType[i][j] = apply_rot(baseType[i][j], bestR);\n        }\n    }\n\n    int edgeScore = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            edgeScore += edge_contrib(i, j, 2);\n            edgeScore += edge_contrib(i, j, 3);\n            if (j == 0) edgeScore += edge_contrib(i, j, 0);\n            if (i == 0) edgeScore += edge_contrib(i, j, 1);\n        }\n    }\n    int pairScore = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pairScore += compute_tile_pair(i, j);\n        }\n    }\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 1.9;\n    double T0 = 5.0, T1 = 0.1;\n    double temp = T0;\n    int iter = 0;\n    while (true) {\n        iter++;\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n            if (elapsed > timeLimit) break;\n            double progress = elapsed / timeLimit;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int newRot = rng() & 3;\n        if (newRot == rotCnt[i][j]) continue;\n        int newType = apply_rot(baseType[i][j], newRot);\n        int oldType = curType[i][j];\n\n        int oldEdges = edge_contrib(i, j, 0) + edge_contrib(i, j, 1) + edge_contrib(i, j, 2) + edge_contrib(i, j, 3);\n        int oldPairs = 0;\n        vector<pair<int, int>> impacted;\n        impacted.reserve(5);\n        impacted.emplace_back(i, j);\n        if (i > 0) impacted.emplace_back(i - 1, j);\n        if (i + 1 < N) impacted.emplace_back(i + 1, j);\n        if (j > 0) impacted.emplace_back(i, j - 1);\n        if (j + 1 < N) impacted.emplace_back(i, j + 1);\n        for (auto &p : impacted) oldPairs += compute_tile_pair(p.first, p.second);\n\n        curType[i][j] = newType;\n        int newEdges = edge_contrib(i, j, 0) + edge_contrib(i, j, 1) + edge_contrib(i, j, 2) + edge_contrib(i, j, 3);\n        int newPairs = 0;\n        for (auto &p : impacted) newPairs += compute_tile_pair(p.first, p.second);\n\n        int delta = (newEdges - oldEdges) + (newPairs - oldPairs);\n\n        if (delta >= 0) {\n            rotCnt[i][j] = newRot;\n            edgeScore += (newEdges - oldEdges);\n            pairScore += (newPairs - oldPairs);\n            // curType already set\n        } else {\n            double prob = exp(double(delta) / temp);\n            double rnd = (double)rng() / (double)rng.max();\n            if (rnd < prob) {\n                rotCnt[i][j] = newRot;\n                edgeScore += (newEdges - oldEdges);\n                pairScore += (newPairs - oldPairs);\n            } else {\n                curType[i][j] = oldType; // revert\n            }\n        }\n    }\n\n    // output rotations\n    string out;\n    out.reserve(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            out.push_back(char('0' + (rotCnt[i][j] & 3)));\n        }\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N;\n    int Tlim;\n    int NN;\n    vector<int> init_board;\n    int init_zero;\n    int full_size;\n    vector<vector<pair<char,int>>> moves_from; // possible moves for each position\n    mt19937 rng;\n    double EPS = 0.2; // probability of random move\n\n    Solver() {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    }\n\n    int hexval(char c){\n        if('0'<=c && c<='9') return c-'0';\n        return 10 + (c-'a');\n    }\n\n    // compute size of largest component that is a tree\n    int compute_tree_size(const vector<int>& b){\n        static vector<char> vis;\n        if((int)vis.size()!=NN) vis.assign(NN,0);\n        else fill(vis.begin(), vis.end(), 0);\n        int max_tree = 0;\n        vector<int> q;\n        q.reserve(NN);\n        for(int idx=0; idx<NN; idx++){\n            if(b[idx]==0 || vis[idx]) continue;\n            q.clear();\n            vis[idx]=1;\n            q.push_back(idx);\n            for(int qi=0; qi<(int)q.size(); qi++){\n                int u = q[qi];\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                // up\n                if(t & 2){\n                    if(r>0){\n                        int v = u - N;\n                        if(b[v]!=0 && (b[v] & 8) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n                // down\n                if(t & 8){\n                    if(r+1<N){\n                        int v = u + N;\n                        if(b[v]!=0 && (b[v] & 2) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n                // left\n                if(t & 1){\n                    if(c>0){\n                        int v = u - 1;\n                        if(b[v]!=0 && (b[v] & 4) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n                // right\n                if(t & 4){\n                    if(c+1<N){\n                        int v = u + 1;\n                        if(b[v]!=0 && (b[v] & 1) && !vis[v]){\n                            vis[v]=1;\n                            q.push_back(v);\n                        }\n                    }\n                }\n            }\n            // count edges in this component (undirected) using right/down to avoid double count\n            int edges = 0;\n            for(int u : q){\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(c+1<N){\n                    int v = u + 1;\n                    if(b[v]!=0 && (t & 4) && (b[v] & 1)){\n                        edges++;\n                    }\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(b[v]!=0 && (t & 8) && (b[v] & 2)){\n                        edges++;\n                    }\n                }\n            }\n            int vcnt = (int)q.size();\n            if(edges == vcnt - 1){\n                if(vcnt > max_tree) max_tree = vcnt;\n            }\n        }\n        return max_tree;\n    }\n\n    char inverse_move(char c){\n        if(c=='U') return 'D';\n        if(c=='D') return 'U';\n        if(c=='L') return 'R';\n        if(c=='R') return 'L';\n        return '?';\n    }\n\n    pair<int,string> walk(const chrono::steady_clock::time_point& end_time, int max_steps){\n        vector<int> board = init_board;\n        int zero = init_zero;\n        string moves;\n        moves.reserve(max_steps);\n        string best_seq;\n        int curr_S = compute_tree_size(board);\n        int best_S = curr_S;\n        if(best_S == full_size){\n            // already perfect\n            return {best_S, best_seq};\n        }\n        char prev_move = '?';\n        uniform_real_distribution<double> dist01(0.0,1.0);\n        for(int step=0; step<max_steps; step++){\n            if(chrono::steady_clock::now() > end_time) break;\n            const auto& opts_all = moves_from[zero];\n            vector<pair<char,int>> opts;\n            opts.reserve(4);\n            char inv = inverse_move(prev_move);\n            for(auto &p: opts_all){\n                if(inv==p.first && (int)opts_all.size()>1) continue; // avoid immediate backtrack if possible\n                opts.push_back(p);\n            }\n            if(opts.empty()){\n                opts = opts_all;\n            }\n            char chosen_move;\n            int chosen_delta;\n            int chosen_score;\n            double rnd = dist01(rng);\n            if(rnd < EPS){\n                // random move\n                uniform_int_distribution<int> dist(0, (int)opts.size()-1);\n                int k = dist(rng);\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                curr_S = compute_tree_size(board);\n                chosen_score = curr_S;\n            }else{\n                int best_neighbor = -1;\n                vector<int> best_idx;\n                best_idx.reserve(4);\n                for(int i=0;i<(int)opts.size();i++){\n                    int d = opts[i].second;\n                    swap(board[zero], board[zero+d]);\n                    int s = compute_tree_size(board);\n                    swap(board[zero], board[zero+d]);\n                    if(s > best_neighbor){\n                        best_neighbor = s;\n                        best_idx.clear();\n                        best_idx.push_back(i);\n                    }else if(s == best_neighbor){\n                        best_idx.push_back(i);\n                    }\n                }\n                uniform_int_distribution<int> dist(0, (int)best_idx.size()-1);\n                int k = best_idx[dist(rng)];\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                chosen_score = best_neighbor;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                curr_S = chosen_score;\n            }\n            moves.push_back(chosen_move);\n            prev_move = chosen_move;\n            if(curr_S > best_S){\n                best_S = curr_S;\n                best_seq = moves;\n                if(best_S == full_size){\n                    break;\n                }\n            }\n        }\n        return {best_S, best_seq};\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin >> N >> Tlim;\n        NN = N*N;\n        init_board.resize(NN);\n        for(int i=0;i<N;i++){\n            string s; cin >> s;\n            for(int j=0;j<N;j++){\n                int v = hexval(s[j]);\n                init_board[i*N + j] = v;\n                if(v==0){\n                    init_zero = i*N + j;\n                }\n            }\n        }\n        full_size = NN - 1;\n        // precompute moves from each position\n        moves_from.resize(NN);\n        for(int pos=0; pos<NN; pos++){\n            int r = pos / N;\n            int c = pos - r*N;\n            if(r>0) moves_from[pos].push_back({'U', -N});\n            if(r+1<N) moves_from[pos].push_back({'D', N});\n            if(c>0) moves_from[pos].push_back({'L', -1});\n            if(c+1<N) moves_from[pos].push_back({'R', 1});\n        }\n\n        int init_S = compute_tree_size(init_board);\n        int best_global_S = init_S;\n        string best_global_seq; // empty means no move\n        // time management\n        auto start_time = chrono::steady_clock::now();\n        auto end_time = start_time + chrono::milliseconds(2800); // safety margin\n        // at least one walk\n        while(true){\n            auto now = chrono::steady_clock::now();\n            if(now > end_time) break;\n            auto res = walk(end_time, Tlim);\n            int s = res.first;\n            string seq = res.second;\n            if(s > best_global_S){\n                best_global_S = s;\n                best_global_seq = seq;\n            }else if(s == best_global_S && s == full_size){\n                if(best_global_seq.empty() || seq.size() < best_global_seq.size()){\n                    best_global_seq = seq;\n                }\n            }\n            // if already perfect with zero moves, can break\n            if(best_global_S == full_size && best_global_seq.size()==0) break;\n        }\n\n        cout << best_global_seq << \"\\n\";\n    }\n};\n\nint main(){\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct BestSolution {\n    int obj = -1;\n    int V = 0, H = 0;\n    int stepX = 0, stepY = 0;\n    int offx = 0, offy = 0;\n    vector<int> vx, vy;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if (!(cin >> N >> K)) return 0;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    vector<pair<int,int>> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].first >> pts[i].second;\n\n    const int R = 10000;\n    const int BIG = 1000000000;\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 2.95;\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    // Precompute factorials\n    vector<double> fact(11,1.0);\n    for(int i=1;i<=10;i++) fact[i]=fact[i-1]*i;\n\n    auto elapsed = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-start_time).count();\n    };\n\n    BestSolution best;\n\n    auto evaluate = [&](int V, int H, int stepX, int offx, int stepY, int offy) {\n        int cells = (V+1)*(H+1);\n        vector<int> cnt(cells,0);\n        int baseX = -R + offx + stepX; // position of first vertical line\n        int baseY = -R + offy + stepY; // position of first horizontal line\n\n        for (auto &p : pts) {\n            int x = p.first;\n            int y = p.second;\n            int cidx = 0, ridx = 0;\n            if (V > 0) {\n                int diffx = x - baseX;\n                if (diffx >= 0) {\n                    int q = diffx / stepX;\n                    if (q < V && diffx % stepX == 0) continue; // on vertical line\n                    cidx = q + 1;\n                    if (cidx > V) cidx = V;\n                } else {\n                    cidx = 0;\n                }\n            }\n            if (H > 0) {\n                int diffy = y - baseY;\n                if (diffy >= 0) {\n                    int qy = diffy / stepY;\n                    if (qy < H && diffy % stepY == 0) continue; // on horizontal line\n                    ridx = qy + 1;\n                    if (ridx > H) ridx = H;\n                } else {\n                    ridx = 0;\n                }\n            }\n            cnt[cidx * (H + 1) + ridx] ++;\n        }\n        array<int,11> b{};\n        for (int v : cnt) {\n            if (v >= 1 && v <= 10) b[v]++;\n        }\n        int obj = 0;\n        for (int d = 1; d <= 10; d++) obj += min(a[d], b[d]);\n        if (obj > best.obj) {\n            best.obj = obj;\n            best.V = V; best.H = H;\n            best.stepX = stepX; best.stepY = stepY;\n            best.offx = offx; best.offy = offy;\n            best.vx.resize(V);\n            best.vy.resize(H);\n            for (int i = 0; i < V; i++) {\n                best.vx[i] = -R + offx + stepX * (i + 1);\n            }\n            for (int j = 0; j < H; j++) {\n                best.vy[j] = -R + offy + stepY * (j + 1);\n            }\n        }\n    };\n\n    auto gen_offsets = [&](int step, bool useX)->vector<int>{\n        vector<int> offs;\n        if (step <= 0) {\n            offs.push_back(0);\n            return offs;\n        }\n        offs.push_back(0);\n        offs.push_back(step/2);\n        offs.push_back(step/3);\n        offs.push_back(step*2/3);\n        for (int i = 0; i < 5; i++) {\n            offs.push_back((int)(rng() % step));\n        }\n        int sample = min(N, 30);\n        for (int i = 0; i < sample; i++) {\n            int idx = rng() % N;\n            int coord = useX ? pts[idx].first : pts[idx].second;\n            int val = (coord + R) % step;\n            offs.push_back(val);\n            offs.push_back((val + step/2) % step);\n        }\n        sort(offs.begin(), offs.end());\n        offs.erase(unique(offs.begin(), offs.end()), offs.end());\n        int maxOff = 12;\n        if ((int)offs.size() > maxOff) {\n            shuffle(offs.begin(), offs.end(), rng);\n            offs.resize(maxOff);\n        }\n        return offs;\n    };\n\n    // Generate candidate (V,H) pairs\n    vector<pair<int,int>> pairs;\n    auto addPair = [&](int v, int h){\n        if (v < 0 || h < 0) return;\n        if (v + h > K) return;\n        if (v > 100 || h > 100) return;\n        pairs.emplace_back(v,h);\n    };\n\n    // lambdas candidates based on expected matching\n    vector<pair<double,double>> lambdaScore;\n    for (double lam = 1.0; lam <= 6.01; lam += 0.5) {\n        double cells = (double)N / lam;\n        double eexp = exp(-lam);\n        double sum = 0.0;\n        for (int d = 1; d <= 10; d++) {\n            double pd = pow(lam, d) * eexp / fact[d];\n            double bd = cells * pd;\n            sum += min((double)a[d], bd);\n        }\n        lambdaScore.emplace_back(-sum, lam); // negative for sort ascending\n    }\n    sort(lambdaScore.begin(), lambdaScore.end());\n    int take = 5;\n    for (int i = 0; i < (int)lambdaScore.size() && i < take; i++) {\n        double lam = lambdaScore[i].second;\n        double cells = (double)N / lam;\n        double root = sqrt(max(1.0, cells));\n        for (int dv = -1; dv <= 1; dv++) {\n            int v = (int)root + dv - 1;\n            v = max(0, v);\n            addPair(v, v);\n            addPair(v, v+1);\n            addPair(v+1, v);\n        }\n    }\n    // fixed candidates\n    vector<int> fixed = {8,12,16,20,24,28,32,36,40,44,48,52};\n    for (int v : fixed) {\n        if (2*v <= K) addPair(v,v);\n    }\n\n    // deduplicate pairs\n    sort(pairs.begin(), pairs.end());\n    pairs.erase(unique(pairs.begin(), pairs.end()), pairs.end());\n\n    for (auto &pr : pairs) {\n        if (elapsed() > TIME_LIMIT) break;\n        int V = pr.first;\n        int H = pr.second;\n        int stepX = (V>=0)? max(1, 20000 / (V + 1)) : 20000;\n        int stepY = (H>=0)? max(1, 20000 / (H + 1)) : 20000;\n        vector<int> offsX = gen_offsets(stepX, true);\n        vector<int> offsY = gen_offsets(stepY, false);\n        for (int ox : offsX) {\n            if (elapsed() > TIME_LIMIT) break;\n            for (int oy : offsY) {\n                if (elapsed() > TIME_LIMIT) break;\n                evaluate(V, H, stepX, ox, stepY, oy);\n            }\n        }\n    }\n\n    // If time remains, random search a bit\n    while (elapsed() < TIME_LIMIT) {\n        int V = (int)(rng() % 51); // 0..50\n        int H = (int)(rng() % (51));\n        if (V + H > K) continue;\n        int stepX = max(1, 20000 / (V + 1));\n        int stepY = max(1, 20000 / (H + 1));\n        int offx = (stepX > 0) ? (int)(rng() % stepX) : 0;\n        int offy = (stepY > 0) ? (int)(rng() % stepY) : 0;\n        evaluate(V, H, stepX, offx, stepY, offy);\n    }\n\n    int k = (int)best.vx.size() + (int)best.vy.size();\n    cout << k << \"\\n\";\n    for (int x : best.vx) {\n        cout << x << \" \" << -BIG << \" \" << x << \" \" << BIG << \"\\n\";\n    }\n    for (int y : best.vy) {\n        cout << -BIG << \" \" << y << \" \" << BIG << \" \" << y << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeIndex {\n    int N;\n    int H, V, D1, D2, E;\n    EdgeIndex(int N_) : N(N_) {\n        H = (N - 1) * N;\n        V = H;\n        D1 = (N - 1) * (N - 1);\n        D2 = D1;\n        E = H + V + D1 + D2;\n    }\n    inline int horizId(int x, int y) const { // between (x,y)-(x+1,y)\n        return x + y * (N - 1);\n    }\n    inline int vertId(int x, int y) const { // between (x,y)-(x,y+1)\n        return H + x * (N - 1) + y;\n    }\n    inline int diag1Id(int x, int y) const { // slope +1 between (x,y)-(x+1,y+1)\n        return H + V + x * (N - 1) + y;\n    }\n    inline int diag2Id(int x, int y) const { // slope -1 between (x,y)-(x+1,y-1), y>=1\n        return H + V + D1 + x * (N - 1) + (y - 1);\n    }\n    inline int id(int x1, int y1, int x2, int y2) const {\n        int dx = x2 - x1;\n        int dy = y2 - y1;\n        if (abs(dx) + abs(dy) == 1) { // axis neighbor\n            if (dy == 0) {\n                int x = min(x1, x2), y = y1;\n                return horizId(x, y);\n            } else {\n                int y = min(y1, y2), x = x1;\n                return vertId(x, y);\n            }\n        } else if (abs(dx) == 1 && abs(dy) == 1) { // diagonal neighbor\n            if (dx == dy) { // slope +1\n                int x = min(x1, x2), y = min(y1, y2);\n                return diag1Id(x, y);\n            } else { // slope -1\n                int x = min(x1, x2), y = max(y1, y2);\n                return diag2Id(x, y);\n            }\n        }\n        return -1; // invalid\n    }\n};\n\nstruct Cand {\n    uint8_t type; //0 axis-aligned rectangle,1 diamond\n    uint8_t miss; //missing corner index\n    uint8_t dx, dy; //for axis: side lengths; for diamond: dx=radius, dy unused\n    uint16_t x0, y0; //axis: bottom-left; diamond: center\n    int w; //weight of missing point\n};\n\nstruct CompWeight {\n    bool operator()(const Cand &a, const Cand &b) const {\n        return a.w < b.w;\n    }\n};\n\nclass Pool {\n    int mode; //0 weight,1 fifo,2 random\n    priority_queue<Cand, vector<Cand>, CompWeight> pq;\n    deque<Cand> dq;\n    vector<Cand> vec;\n    mt19937 rng;\npublic:\n    Pool(int m, uint32_t seed) : mode(m), rng(seed) {}\n    void push(const Cand &c) {\n        if (mode == 0) pq.push(c);\n        else if (mode == 1) dq.push_back(c);\n        else vec.push_back(c);\n    }\n    bool empty() const {\n        if (mode == 0) return pq.empty();\n        if (mode == 1) return dq.empty();\n        return vec.empty();\n    }\n    Cand pop() {\n        if (mode == 0) { Cand c = pq.top(); pq.pop(); return c; }\n        if (mode == 1) { Cand c = dq.front(); dq.pop_front(); return c; }\n        int idx = (int)(rng() % vec.size());\n        Cand c = vec[idx];\n        vec[idx] = vec.back();\n        vec.pop_back();\n        return c;\n    }\n};\n\nstruct Result {\n    long long totalWeight;\n    vector<array<int,8>> ops;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> initialDots(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initialDots[i] = {x, y};\n    }\n    EdgeIndex EI(N);\n    int NN = N * N;\n    vector<int> weight(NN);\n    int c = (N - 1) / 2;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            int dx = x - c, dy = y - c;\n            weight[x * N + y] = dx * dx + dy * dy + 1;\n        }\n    }\n    vector<char> initialHasDot(NN, 0);\n    long long initSum = 0;\n    for (auto &p : initialDots) {\n        int id = p.first * N + p.second;\n        if (!initialHasDot[id]) {\n            initialHasDot[id] = 1;\n            initSum += weight[id];\n        }\n    }\n\n    struct Config { int mode; int maxA; int maxD; uint32_t seed; };\n    uint64_t seedBase = 1234567;\n    seedBase = seedBase * 1000003 + N;\n    seedBase = seedBase * 1000003 + M;\n    for (auto &p : initialDots) {\n        seedBase ^= (uint64_t)(p.first + 1) * 10007 + (uint64_t)(p.second + 1) * 1000003 + 12345;\n        seedBase = seedBase * 1000003 + 1;\n    }\n    vector<Config> configs;\n    configs.push_back({0, 3, 2, (uint32_t)(seedBase & 0xffffffffu)});\n    configs.push_back({1, 3, 2, (uint32_t)((seedBase + 1013904223u) & 0xffffffffu)});\n    configs.push_back({0, 4, 3, (uint32_t)((seedBase + 0x9e3779b9u) & 0xffffffffu)});\n    int randomTrials = 3;\n    for (int i = 0; i < randomTrials; i++) {\n        configs.push_back({2, 3, 2, (uint32_t)((seedBase + 1812433253ull * (i+1)) & 0xffffffffu)});\n    }\n\n    auto simulate = [&](const Config &cfg)->Result {\n        vector<char> hasDot = initialHasDot;\n        vector<char> used(EI.E, 0);\n        long long total = initSum;\n        vector<array<int,8>> ops;\n        Pool pool(cfg.mode, cfg.seed);\n\n        auto evalRect = [&](int x0, int y0, int dx, int dy) {\n            int x1 = x0 + dx;\n            int y1 = y0 + dy;\n            if (x0 < 0 || y0 < 0 || x1 >= N || y1 >= N) return;\n            int cid[4] = {\n                x0 * N + y0,\n                x1 * N + y0,\n                x1 * N + y1,\n                x0 * N + y1\n            };\n            int cnt = hasDot[cid[0]] + hasDot[cid[1]] + hasDot[cid[2]] + hasDot[cid[3]];\n            if (cnt != 3) return;\n            int miss = 0;\n            if (!hasDot[cid[0]]) miss = 0;\n            else if (!hasDot[cid[1]]) miss = 1;\n            else if (!hasDot[cid[2]]) miss = 2;\n            else miss = 3;\n            // check edges unused\n            for (int i = 0; i < dx; i++) {\n                int e1 = EI.horizId(x0 + i, y0);\n                int e2 = EI.horizId(x0 + i, y1);\n                if (used[e1] || used[e2]) return;\n            }\n            for (int j = 0; j < dy; j++) {\n                int e1 = EI.vertId(x0, y0 + j);\n                int e2 = EI.vertId(x1, y0 + j);\n                if (used[e1] || used[e2]) return;\n            }\n            // perimeter dots (excluding corners)\n            if (dx > 1) {\n                for (int i = 1; i < dx; i++) {\n                    if (hasDot[(x0 + i) * N + y0]) return;\n                    if (hasDot[(x0 + i) * N + y1]) return;\n                }\n            }\n            if (dy > 1) {\n                for (int j = 1; j < dy; j++) {\n                    if (hasDot[x0 * N + (y0 + j)]) return;\n                    if (hasDot[x1 * N + (y0 + j)]) return;\n                }\n            }\n            Cand cnd;\n            cnd.type = 0;\n            cnd.miss = (uint8_t)miss;\n            cnd.dx = (uint8_t)dx;\n            cnd.dy = (uint8_t)dy;\n            cnd.x0 = (uint16_t)x0;\n            cnd.y0 = (uint16_t)y0;\n            cnd.w = weight[cid[miss]];\n            pool.push(cnd);\n        };\n\n        auto evalDiamond = [&](int cx, int cy, int r) {\n            if (cx - r < 0 || cx + r >= N || cy - r < 0 || cy + r >= N) return;\n            int cid[4] = {\n                (cx + r) * N + cy,\n                cx * N + (cy + r),\n                (cx - r) * N + cy,\n                cx * N + (cy - r)\n            };\n            int cnt = hasDot[cid[0]] + hasDot[cid[1]] + hasDot[cid[2]] + hasDot[cid[3]];\n            if (cnt != 3) return;\n            int miss = 0;\n            if (!hasDot[cid[0]]) miss = 0;\n            else if (!hasDot[cid[1]]) miss = 1;\n            else if (!hasDot[cid[2]]) miss = 2;\n            else miss = 3;\n            // edges unused\n            for (int t = 0; t < r; t++) {\n                int x, y, e;\n                x = cx + r - t; y = cy + t;\n                e = EI.id(x, y, x - 1, y + 1);\n                if (used[e]) return;\n                x = cx - t; y = cy + r - t;\n                e = EI.id(x, y, x - 1, y - 1);\n                if (used[e]) return;\n                x = cx - r + t; y = cy - t;\n                e = EI.id(x, y, x + 1, y - 1);\n                if (used[e]) return;\n                x = cx + t; y = cy - r + t;\n                e = EI.id(x, y, x + 1, y + 1);\n                if (used[e]) return;\n            }\n            // perimeter dots (excluding corners)\n            for (int t = 1; t < r; t++) {\n                if (hasDot[(cx + r - t) * N + (cy + t)]) return;\n                if (hasDot[(cx - t) * N + (cy + r - t)]) return;\n                if (hasDot[(cx - r + t) * N + (cy - t)]) return;\n                if (hasDot[(cx + t) * N + (cy - r + t)]) return;\n            }\n            Cand cnd;\n            cnd.type = 1;\n            cnd.miss = (uint8_t)miss;\n            cnd.dx = (uint8_t)r;\n            cnd.dy = 0;\n            cnd.x0 = (uint16_t)cx;\n            cnd.y0 = (uint16_t)cy;\n            cnd.w = weight[cid[miss]];\n            pool.push(cnd);\n        };\n\n        auto addAllFromPoint = [&](int x, int y) {\n            // axis rectangles\n            for (int dx = 1; dx <= cfg.maxA; dx++) {\n                for (int dy = 1; dy <= cfg.maxA; dy++) {\n                    evalRect(x, y, dx, dy);             // new dot at bottom-left\n                    evalRect(x - dx, y, dx, dy);        // new dot at bottom-right\n                    evalRect(x, y - dy, dx, dy);        // new dot at top-left\n                    evalRect(x - dx, y - dy, dx, dy);   // new dot at top-right\n                }\n            }\n            // diamonds\n            for (int r = 1; r <= cfg.maxD; r++) {\n                evalDiamond(x - r, y, r); // new dot as right corner\n                evalDiamond(x, y - r, r); // as up\n                evalDiamond(x + r, y, r); // as left\n                evalDiamond(x, y + r, r); // as down\n            }\n        };\n\n        // initial candidates\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (hasDot[x * N + y]) addAllFromPoint(x, y);\n            }\n        }\n\n        auto tryApplyRect = [&](const Cand &cnd)->bool {\n            int x0 = cnd.x0, y0 = cnd.y0;\n            int dx = cnd.dx, dy = cnd.dy;\n            int x1 = x0 + dx, y1 = y0 + dy;\n            if (x0 < 0 || y0 < 0 || x1 >= N || y1 >= N) return false;\n            int cid[4] = {\n                x0 * N + y0,\n                x1 * N + y0,\n                x1 * N + y1,\n                x0 * N + y1\n            };\n            if (hasDot[cid[cnd.miss]]) return false;\n            for (int k = 0; k < 4; k++) {\n                if (k == cnd.miss) continue;\n                if (!hasDot[cid[k]]) return false;\n            }\n            for (int i = 0; i < dx; i++) {\n                int e1 = EI.horizId(x0 + i, y0);\n                int e2 = EI.horizId(x0 + i, y1);\n                if (used[e1] || used[e2]) return false;\n            }\n            for (int j = 0; j < dy; j++) {\n                int e1 = EI.vertId(x0, y0 + j);\n                int e2 = EI.vertId(x1, y0 + j);\n                if (used[e1] || used[e2]) return false;\n            }\n            if (dx > 1) {\n                for (int i = 1; i < dx; i++) {\n                    if (hasDot[(x0 + i) * N + y0]) return false;\n                    if (hasDot[(x0 + i) * N + y1]) return false;\n                }\n            }\n            if (dy > 1) {\n                for (int j = 1; j < dy; j++) {\n                    if (hasDot[x0 * N + (y0 + j)]) return false;\n                    if (hasDot[x1 * N + (y0 + j)]) return false;\n                }\n            }\n            // apply\n            hasDot[cid[cnd.miss]] = 1;\n            total += weight[cid[cnd.miss]];\n            for (int i = 0; i < dx; i++) {\n                used[EI.horizId(x0 + i, y0)] = 1;\n                used[EI.horizId(x0 + i, y1)] = 1;\n            }\n            for (int j = 0; j < dy; j++) {\n                used[EI.vertId(x0, y0 + j)] = 1;\n                used[EI.vertId(x1, y0 + j)] = 1;\n            }\n            array<int,8> op;\n            for (int t = 0; t < 4; t++) {\n                int idx = (cnd.miss + t) % 4;\n                int ox, oy;\n                if (idx == 0) { ox = x0; oy = y0; }\n                else if (idx == 1) { ox = x1; oy = y0; }\n                else if (idx == 2) { ox = x1; oy = y1; }\n                else { ox = x0; oy = y1; }\n                op[2 * t] = ox;\n                op[2 * t + 1] = oy;\n            }\n            ops.push_back(op);\n            addAllFromPoint((cnd.miss==0||cnd.miss==3)?x0:x1, (cnd.miss==0||cnd.miss==1)?y0:y1);\n            return true;\n        };\n\n        auto tryApplyDiamond = [&](const Cand &cnd)->bool {\n            int cx = cnd.x0, cy = cnd.y0, r = cnd.dx;\n            if (cx - r < 0 || cx + r >= N || cy - r < 0 || cy + r >= N) return false;\n            int cid[4] = {\n                (cx + r) * N + cy,\n                cx * N + (cy + r),\n                (cx - r) * N + cy,\n                cx * N + (cy - r)\n            };\n            if (hasDot[cid[cnd.miss]]) return false;\n            for (int k = 0; k < 4; k++) {\n                if (k == cnd.miss) continue;\n                if (!hasDot[cid[k]]) return false;\n            }\n            for (int t = 0; t < r; t++) {\n                int x, y, e;\n                x = cx + r - t; y = cy + t;\n                e = EI.id(x, y, x - 1, y + 1);\n                if (used[e]) return false;\n                x = cx - t; y = cy + r - t;\n                e = EI.id(x, y, x - 1, y - 1);\n                if (used[e]) return false;\n                x = cx - r + t; y = cy - t;\n                e = EI.id(x, y, x + 1, y - 1);\n                if (used[e]) return false;\n                x = cx + t; y = cy - r + t;\n                e = EI.id(x, y, x + 1, y + 1);\n                if (used[e]) return false;\n            }\n            for (int t = 1; t < r; t++) {\n                if (hasDot[(cx + r - t) * N + (cy + t)]) return false;\n                if (hasDot[(cx - t) * N + (cy + r - t)]) return false;\n                if (hasDot[(cx - r + t) * N + (cy - t)]) return false;\n                if (hasDot[(cx + t) * N + (cy - r + t)]) return false;\n            }\n            hasDot[cid[cnd.miss]] = 1;\n            total += weight[cid[cnd.miss]];\n            for (int t = 0; t < r; t++) {\n                int x, y, e;\n                x = cx + r - t; y = cy + t;\n                used[EI.id(x, y, x - 1, y + 1)] = 1;\n                x = cx - t; y = cy + r - t;\n                used[EI.id(x, y, x - 1, y - 1)] = 1;\n                x = cx - r + t; y = cy - t;\n                used[EI.id(x, y, x + 1, y - 1)] = 1;\n                x = cx + t; y = cy - r + t;\n                used[EI.id(x, y, x + 1, y + 1)] = 1;\n            }\n            array<int,8> op;\n            for (int t = 0; t < 4; t++) {\n                int idx = (cnd.miss + t) % 4;\n                int ox, oy;\n                if (idx == 0) { ox = cx + r; oy = cy; }\n                else if (idx == 1) { ox = cx; oy = cy + r; }\n                else if (idx == 2) { ox = cx - r; oy = cy; }\n                else { ox = cx; oy = cy - r; }\n                op[2 * t] = ox;\n                op[2 * t + 1] = oy;\n            }\n            int mx, my;\n            if (cnd.miss == 0) { mx = cx + r; my = cy; }\n            else if (cnd.miss == 1) { mx = cx; my = cy + r; }\n            else if (cnd.miss == 2) { mx = cx - r; my = cy; }\n            else { mx = cx; my = cy - r; }\n            ops.push_back(op);\n            addAllFromPoint(mx, my);\n            return true;\n        };\n\n        while (!pool.empty()) {\n            Cand cand = pool.pop();\n            if (cand.type == 0) {\n                tryApplyRect(cand);\n            } else {\n                tryApplyDiamond(cand);\n            }\n        }\n        return {total, std::move(ops)};\n    };\n\n    Result best{initSum, {}};\n    for (auto &cfg : configs) {\n        Result res = simulate(cfg);\n        if (res.totalWeight > best.totalWeight) best = std::move(res);\n    }\n\n    cout << best.ops.size() << \"\\n\";\n    for (auto &op : best.ops) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Board = array<array<int, 10>, 10>;\n\n// simulate tilting the board to one direction\nBoard tiltBoard(const Board &b, int dir) {\n    Board res;\n    for (auto &row : res) row.fill(0);\n    if (dir == 0) {  // F : up\n        for (int c = 0; c < 10; c++) {\n            int pos = 0;\n            for (int r = 0; r < 10; r++) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 1) {  // B : down\n        for (int c = 0; c < 10; c++) {\n            int pos = 9;\n            for (int r = 9; r >= 0; r--) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 2) {  // L : left\n        for (int r = 0; r < 10; r++) {\n            int pos = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else {  // R : right\n        for (int r = 0; r < 10; r++) {\n            int pos = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    }\n    return res;\n}\n\n// compute sum of squared component sizes (numerator of the objective)\nint scoreBoard(const Board &b) {\n    bool vis[10][10] = {};\n    int dr[4] = {-1, 1, 0, 0};\n    int dc[4] = {0, 0, -1, 1};\n    int score = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            if (b[r][c] == 0 || vis[r][c]) continue;\n            int col = b[r][c];\n            queue<pair<int, int>> q;\n            q.push({r, c});\n            vis[r][c] = true;\n            int sz = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front();\n                q.pop();\n                sz++;\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dr[k], ny = y + dc[k];\n                    if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;\n                    if (vis[nx][ny]) continue;\n                    if (b[nx][ny] != col) continue;\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n            score += sz * sz;\n        }\n    }\n    return score;\n}\n\n// sum of Manhattan distances to assigned targets (used for tie-breaking)\nint distSum(const Board &b, const array<pair<int, int>, 4> &target) {\n    int sum = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            int col = b[r][c];\n            if (col == 0) continue;\n            auto [tr, tc] = target[col];\n            sum += abs(r - tr) + abs(c - tc);\n        }\n    }\n    return sum;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavors[i])) return 0;\n    }\n\n    Board cur;\n    for (auto &row : cur) row.fill(0);\n\n    // assign target corners for each flavor (1..3)\n    array<pair<int, int>, 4> target;\n    target[0] = {0, 0};\n    target[1] = {0, 0};  // flavor 1 -> top-left\n    target[2] = {0, 9};  // flavor 2 -> top-right\n    target[3] = {9, 0};  // flavor 3 -> bottom-left\n\n    const char dirChar[4] = {'F', 'B', 'L', 'R'};\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        if (!(cin >> p)) break;\n\n        // place the new candy at the p-th empty cell (row-major order)\n        int cnt = 0;\n        int pr = -1, pc = -1;\n        for (int r = 0; r < 10; r++) {\n            for (int c = 0; c < 10; c++) {\n                if (cur[r][c] == 0) {\n                    cnt++;\n                    if (cnt == p) {\n                        pr = r;\n                        pc = c;\n                        goto placed;\n                    }\n                }\n            }\n        }\n    placed:\n        if (pr == -1) {\n            pr = 0;\n            pc = 0;\n        }\n        cur[pr][pc] = flavors[t];\n\n        int bestDir = 0;\n        pair<int, int> bestVal = make_pair(-1000000000, -1000000000);\n        Board bestBoard;\n\n        for (int dir = 0; dir < 4; dir++) {\n            Board nb = tiltBoard(cur, dir);\n            int sc = scoreBoard(nb);\n            int dsum = distSum(nb, target);\n            pair<int, int> val = make_pair(sc, -dsum);\n            if (val > bestVal) {\n                bestVal = val;\n                bestDir = dir;\n                bestBoard = nb;\n            }\n        }\n\n        // output chosen direction\n        cout << dirChar[bestDir] << '\\n' << flush;\n\n        // update current board\n        cur = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GraphData {\n    int N;\n    vector<vector<uint8_t>> adj; // NxN\n    vector<int> deg, f1, f2, tri;\n    vector<int> sortedDeg;\n};\n\nvoid compute_features(GraphData &g){\n    int N = g.N;\n    g.deg.assign(N,0);\n    g.f1.assign(N,0);\n    g.f2.assign(N,0);\n    g.tri.assign(N,0);\n    // degree\n    for(int i=0;i<N;i++){\n        int d=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) d++;\n        g.deg[i]=d;\n    }\n    // f1\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.deg[j];\n        g.f1[i]=s;\n    }\n    // f2\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.f1[j];\n        g.f2[i]=s;\n    }\n    // triangles per vertex (naive)\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++) if(g.adj[i][j]){\n            for(int k=j+1;k<N;k++) if(g.adj[i][k] && g.adj[j][k]){\n                g.tri[i]++; g.tri[j]++; g.tri[k]++;\n            }\n        }\n    }\n    g.sortedDeg = g.deg;\n    sort(g.sortedDeg.begin(), g.sortedDeg.end());\n}\n\n// Hungarian algorithm for minimum cost assignment\nvector<int> hungarian(const vector<vector<double>> &a){\n    int n = (int)a.size();\n    int m = n;\n    const double INF = 1e18;\n    vector<double> u(n+1), v(m+1);\n    vector<int> p(m+1), way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;\n        int j0=0;\n        vector<double> minv(m+1, INF);\n        vector<char> used(m+1, false);\n        do{\n            used[j0]=true;\n            int i0 = p[j0];\n            double delta = INF;\n            int j1 = 0;\n            for(int j=1;j<=m;j++) if(!used[j]){\n                double cur = a[i0-1][j-1] - u[i0] - v[j];\n                if(cur < minv[j]){\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if(minv[j] < delta){\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for(int j=0;j<=m;j++){\n                if(used[j]){\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                }else{\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        }while(p[j0]!=0);\n        // augmenting\n        do{\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        }while(j0);\n    }\n    vector<int> assignment(n, -1); // row -> col\n    for(int j=1;j<=m;j++){\n        if(p[j]>0 && p[j]<=n) assignment[p[j]-1] = j-1;\n    }\n    return assignment;\n}\n\nint degree_distance(const vector<int>& a, const vector<int>& b){\n    int n=a.size();\n    int s=0;\n    for(int i=0;i<n;i++) s += abs(a[i]-b[i]);\n    return s;\n}\n\nint compute_mismatch(const vector<vector<uint8_t>>& H, const vector<vector<uint8_t>>& G, const vector<int>& assign, int bestLimit){\n    int n = assign.size();\n    int mism=0;\n    for(int i=0;i<n;i++){\n        int gi = assign[i];\n        for(int j=i+1;j<n;j++){\n            int gj = assign[j];\n            if(H[i][j] != G[gi][gj]) mism++;\n        }\n        if(mism >= bestLimit) return mism;\n    }\n    return mism;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n    // decide N\n    int N = 25 + int(60.0*eps + 0.5);\n    if(M > 80) N += 5;\n    else if(M > 50) N += 2;\n    if(M < 30) N -= 3;\n    if(eps > 0.30) N += 4;\n    N = max(4, min(100, N));\n    int Kcap = 30;\n    int K = min(M, max(5, min(Kcap, (int)(eps*75.0)+5)));\n    // generate graphs\n    mt19937 rng(1234567);\n    vector<GraphData> graphs(M);\n    for(int k=0;k<M;k++){\n        GraphData g;\n        g.N = N;\n        g.adj.assign(N, vector<uint8_t>(N,0));\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                bool e = (rng() & 1);\n                g.adj[i][j]=g.adj[j][i]= e;\n            }\n        }\n        compute_features(g);\n        graphs[k]=move(g);\n    }\n    // output graphs\n    cout<<N<<\"\\n\";\n    int E = N*(N-1)/2;\n    string line;\n    line.reserve(E);\n    for(int k=0;k<M;k++){\n        line.clear();\n        line.reserve(E);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                line.push_back(graphs[k].adj[i][j] ? '1' : '0');\n            }\n        }\n        cout<<line<<\"\\n\";\n    }\n    cout.flush();\n    // process queries\n    vector<vector<uint8_t>> HAdj(N, vector<uint8_t>(N,0));\n    GraphData HG;\n    HG.N = N;\n    for(int qi=0; qi<100; qi++){\n        string hstr;\n        if(!(cin>>hstr)) break;\n        // build adjacency\n        int idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                char c = hstr[idx++];\n                uint8_t v = (c=='1');\n                HAdj[i][j]=HAdj[j][i]=v;\n            }\n        }\n        HG.adj = HAdj;\n        compute_features(HG);\n        // distances for pruning\n        vector<pair<int,int>> distIdx;\n        distIdx.reserve(M);\n        for(int k=0;k<M;k++){\n            int d = degree_distance(HG.sortedDeg, graphs[k].sortedDeg);\n            distIdx.emplace_back(d, k);\n        }\n        nth_element(distIdx.begin(), distIdx.begin()+K, distIdx.end(),\n                    [](auto &a, auto &b){ return a.first < b.first; });\n        distIdx.resize(K);\n        sort(distIdx.begin(), distIdx.end()); // optional\n        int bestMismatch = N*N; // upper bound\n        int bestIdx = distIdx[0].second;\n        // precompute weight factors\n        double s = 1.0 - 2.0*eps;\n        if(s < 0.05) s = 0.05;\n        double w1 = s;\n        double w2 = s*s;\n        double w3 = s;\n        double invN = 1.0 / (double)N;\n        double invNN = 1.0 / ((double)N*(double)N);\n        // candidate evaluation\n        vector<vector<double>> cost(N, vector<double>(N));\n        for(auto &dk : distIdx){\n            int k = dk.second;\n            // build cost matrix\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    double c = abs(HG.deg[i] - graphs[k].deg[j]);\n                    c += w1 * (double)abs(HG.f1[i] - graphs[k].f1[j]) * invN;\n                    c += w2 * (double)abs(HG.f2[i] - graphs[k].f2[j]) * invNN;\n                    c += w3 * (double)abs(HG.tri[i] - graphs[k].tri[j]) * invN;\n                    cost[i][j]=c;\n                }\n            }\n            vector<int> assign = hungarian(cost); // H row -> G col\n            int mism = compute_mismatch(HAdj, graphs[k].adj, assign, bestMismatch);\n            if(mism < bestMismatch){\n                bestMismatch = mism;\n                bestIdx = k;\n            }\n        }\n        cout<<bestIdx<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\n// Dijkstra that skips one edge\nlong long dijkstra_skip(int s, int t, int skip_id,\n                        const vector<vector<Adj>> &adj,\n                        vector<long long> &dist) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        if (u == t) break;\n        for (auto &e : adj[u]) {\n            if (e.id == skip_id) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n    return dist[t];\n}\n\n// Dijkstra that records one parent edge (shortest path tree)\nvoid dijkstra_parent(int s, const vector<vector<Adj>> &adj,\n                     vector<long long> &dist, vector<int> &parent) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    fill(parent.begin(), parent.end(), -1);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                parent[e.to] = e.id;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u;\n        --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    // read coordinates (not used)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<long long> dist(N);\n    vector<long long> altDiff(M);\n    for (int i = 0; i < M; i++) {\n        auto &e = edges[i];\n        long long alt = dijkstra_skip(e.u, e.v, i, adj, dist);\n        if (alt >= (1LL << 59)) {\n            altDiff[i] = 0;  // fallback\n        } else {\n            altDiff[i] = alt - e.w;\n            if (altDiff[i] < 0) altDiff[i] = 0;\n        }\n    }\n\n    int S = min(N, 30);\n    vector<int> sources;\n    int step = max(1, N / S);\n    for (int i = 0; i < N && (int)sources.size() < S; i += step) {\n        sources.push_back(i);\n    }\n    while ((int)sources.size() < S) sources.push_back((int)sources.size());\n    vector<int> centrality(M, 0);\n    vector<int> parent(N);\n    for (int s : sources) {\n        dijkstra_parent(s, adj, dist, parent);\n        for (int v = 0; v < N; v++) {\n            if (v == s) continue;\n            int pe = parent[v];\n            if (pe >= 0) centrality[pe]++;\n        }\n    }\n\n    vector<long double> importance(M);\n    long double sumImp = 0;\n    for (int i = 0; i < M; i++) {\n        long double imp = (long double)altDiff[i] * ((long double)centrality[i] + 1.0L);\n        importance[i] = imp;\n        sumImp += imp;\n    }\n    long double avgImp = sumImp / (long double)max(1, M);\n    long double alpha = avgImp * 0.5L;\n    if (alpha < 1e-6) alpha = 1.0L;\n\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (importance[a] == importance[b]) return a < b;\n        return importance[a] > importance[b];\n    });\n\n    vector<int> answer(M, 0);\n    vector<long double> dayLoad(D, 0.0L);\n    vector<int> dayCount(D, 0);\n    vector<vector<uint16_t>> vtxCount(N, vector<uint16_t>(D, 0));\n\n    auto chooseDay = [&](int u, int v) -> int {\n        long double bestCost = 1e100;\n        int bestDay = -1;\n        for (int d = 0; d < D; d++) {\n            if (dayCount[d] >= K) continue;\n            int s1 = (int)vtxCount[u][d] + (int)vtxCount[v][d];\n            long double cost = dayLoad[d] + alpha * (long double)s1;\n            if (cost < bestCost - 1e-9L) {\n                bestCost = cost;\n                bestDay = d;\n            } else if (fabsl(cost - bestCost) <= 1e-9L) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay] ||\n                    (dayCount[d] == dayCount[bestDay] && d < bestDay)) {\n                    bestDay = d;\n                }\n            }\n        }\n        if (bestDay == -1) {\n            // should not happen, but fallback\n            for (int d = 0; d < D; d++) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay]) bestDay = d;\n            }\n        }\n        return bestDay;\n    };\n\n    // initial assignment\n    for (int eid : order) {\n        int u = edges[eid].u;\n        int v = edges[eid].v;\n        int d = chooseDay(u, v);\n        answer[eid] = d + 1;\n        dayLoad[d] += importance[eid];\n        dayCount[d]++;\n        vtxCount[u][d]++;\n        vtxCount[v][d]++;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int improvePasses = 1;\n    for (int pass = 0; pass < improvePasses; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.5) break;  // time guard\n        for (int eid : order) {\n            int curr = answer[eid] - 1;\n            int u = edges[eid].u;\n            int v = edges[eid].v;\n            long double imp = importance[eid];\n            // remove\n            dayLoad[curr] -= imp;\n            dayCount[curr]--;\n            vtxCount[u][curr]--;\n            vtxCount[v][curr]--;\n            // choose best day again\n            int nd = chooseDay(u, v);\n            answer[eid] = nd + 1;\n            dayLoad[nd] += imp;\n            dayCount[nd]++;\n            vtxCount[u][nd]++;\n            vtxCount[v][nd]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << answer[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    vector<pair<int,int>> doms; // pairs of indices\n    vector<int> monos;          // single indices\n    vector<char> occ;           // occupancy grid\n};\n\nstruct Solver {\n    int D;\n    vector<string> f[2], r[2];\n    inline int idx(int x,int y,int z) const { return (x*D + y)*D + z; }\n    void build_allowed(const vector<string>& fmat, const vector<string>& rmat, vector<char>& allowed){\n        int V = D*D*D;\n        allowed.assign(V, 0);\n        for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n            if(fmat[z][x]=='1' && rmat[z][y]=='1') allowed[idx(x,y,z)] = 1;\n        }\n    }\n    Placement build_initial(const vector<string>& fmat, const vector<string>& rmat){\n        int V = D*D*D;\n        Placement P;\n        P.occ.assign(V, 0);\n        vector<char> used(V, 0);\n        // step 1: initial cubes\n        for(int z=0; z<D; z++){\n            vector<int> xs, ys;\n            for(int x=0;x<D;x++) if(fmat[z][x]=='1') xs.push_back(x);\n            for(int y=0;y<D;y++) if(rmat[z][y]=='1') ys.push_back(y);\n            if(xs.empty() || ys.empty()) continue;\n            if(xs.size() >= ys.size()){\n                int y0 = ys[0];\n                for(int i=0;i<(int)xs.size();i++){\n                    int y = (i<(int)ys.size()) ? ys[i] : y0;\n                    P.occ[idx(xs[i], y, z)] = 1;\n                }\n            }else{\n                int x0 = xs[0];\n                for(int i=0;i<(int)ys.size();i++){\n                    int x = (i<(int)xs.size()) ? xs[i] : x0;\n                    P.occ[idx(x, ys[i], z)] = 1;\n                }\n            }\n        }\n        // pairing along x\n        for(int z=0; z<D; z++){\n            for(int y=0; y<D; y++){\n                int x=0;\n                while(x < D-1){\n                    int id1 = idx(x,y,z);\n                    int id2 = idx(x+1,y,z);\n                    if(P.occ[id1] && !used[id1] && P.occ[id2] && !used[id2]){\n                        used[id1]=used[id2]=1;\n                        P.doms.push_back({id1,id2});\n                        x += 2;\n                    }else x++;\n                }\n            }\n        }\n        // pairing along y\n        for(int z=0; z<D; z++){\n            for(int x=0; x<D; x++){\n                int y=0;\n                while(y < D-1){\n                    int id1 = idx(x,y,z);\n                    int id2 = idx(x,y+1,z);\n                    if(P.occ[id1] && !used[id1] && P.occ[id2] && !used[id2]){\n                        used[id1]=used[id2]=1;\n                        P.doms.push_back({id1,id2});\n                        y += 2;\n                    }else y++;\n                }\n            }\n        }\n        // pairing along z\n        for(int x=0; x<D; x++){\n            for(int y=0; y<D; y++){\n                int z=0;\n                while(z < D-1){\n                    int id1 = idx(x,y,z);\n                    int id2 = idx(x,y,z+1);\n                    if(P.occ[id1] && !used[id1] && P.occ[id2] && !used[id2]){\n                        used[id1]=used[id2]=1;\n                        P.doms.push_back({id1,id2});\n                        z += 2;\n                    }else z++;\n                }\n            }\n        }\n        // remaining monos\n        for(int i=0;i<V;i++){\n            if(P.occ[i] && !used[i]){\n                used[i]=1;\n                P.monos.push_back(i);\n            }\n        }\n        return P;\n    }\n\n    void augment(Placement& P, int targetDom, int targetMono, const vector<char>& allowed){\n        int V = D*D*D;\n        // place additional dominos\n        while((int)P.doms.size() < targetDom){\n            bool placed=false;\n            for(int x=0;x<D && !placed;x++){\n                for(int y=0;y<D && !placed;y++){\n                    for(int z=0;z<D && !placed;z++){\n                        int id1 = idx(x,y,z);\n                        if(P.occ[id1] || !allowed[id1]) continue;\n                        // try neighbors\n                        if(x+1 < D){\n                            int id2 = idx(x+1,y,z);\n                            if(!P.occ[id2] && allowed[id2]){\n                                P.occ[id1]=P.occ[id2]=1;\n                                P.doms.push_back({id1,id2});\n                                placed=true; break;\n                            }\n                        }\n                        if(y+1 < D){\n                            int id2 = idx(x,y+1,z);\n                            if(!P.occ[id2] && allowed[id2]){\n                                P.occ[id1]=P.occ[id2]=1;\n                                P.doms.push_back({id1,id2});\n                                placed=true; break;\n                            }\n                        }\n                        if(z+1 < D){\n                            int id2 = idx(x,y,z+1);\n                            if(!P.occ[id2] && allowed[id2]){\n                                P.occ[id1]=P.occ[id2]=1;\n                                P.doms.push_back({id1,id2});\n                                placed=true; break;\n                            }\n                        }\n                    }\n                }\n            }\n            if(!placed) break; // no more space\n        }\n        // place additional monos\n        while((int)P.monos.size() < targetMono){\n            bool placed=false;\n            for(int x=0;x<D && !placed;x++){\n                for(int y=0;y<D && !placed;y++){\n                    for(int z=0;z<D && !placed;z++){\n                        int id1 = idx(x,y,z);\n                        if(!P.occ[id1] && allowed[id1]){\n                            P.occ[id1]=1;\n                            P.monos.push_back(id1);\n                            placed=true; break;\n                        }\n                    }\n                }\n            }\n            if(!placed) break;\n        }\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin >> D;\n        for(int s=0;s<2;s++){\n            f[s].resize(D);\n            for(int i=0;i<D;i++) cin >> f[s][i];\n            r[s].resize(D);\n            for(int i=0;i<D;i++) cin >> r[s][i];\n        }\n        vector<char> allowed[2];\n        build_allowed(f[0], r[0], allowed[0]);\n        build_allowed(f[1], r[1], allowed[1]);\n        Placement P0 = build_initial(f[0], r[0]);\n        Placement P1 = build_initial(f[1], r[1]);\n        int targetDom = max((int)P0.doms.size(), (int)P1.doms.size());\n        int targetMono = max((int)P0.monos.size(), (int)P1.monos.size());\n        augment(P0, targetDom, targetMono, allowed[0]);\n        augment(P1, targetDom, targetMono, allowed[1]);\n        int ndom = targetDom;\n        int nmono = targetMono;\n        int n = ndom + nmono;\n        int V = D*D*D;\n        vector<int> out[2];\n        out[0].assign(V, 0);\n        out[1].assign(V, 0);\n        // assign IDs\n        for(int i=0;i<(int)P0.doms.size();i++){\n            int id = i+1;\n            out[0][P0.doms[i].first] = id;\n            out[0][P0.doms[i].second] = id;\n        }\n        for(int i=0;i<(int)P1.doms.size();i++){\n            int id = i+1;\n            out[1][P1.doms[i].first] = id;\n            out[1][P1.doms[i].second] = id;\n        }\n        for(int i=0;i<(int)P0.monos.size();i++){\n            int id = ndom + i + 1;\n            out[0][P0.monos[i]] = id;\n        }\n        for(int i=0;i<(int)P1.monos.size();i++){\n            int id = ndom + i + 1;\n            out[1][P1.monos[i]] = id;\n        }\n        cout << n << \"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout << ' ';\n            cout << out[0][i];\n        }\n        cout << \"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout << ' ';\n            cout << out[1][i];\n        }\n        cout << \"\\n\";\n    }\n};\n\nint main(){\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeAdj {\n    int to;\n    int id;\n    long long w;\n};\nstruct DSU {\n    vector<int> p;\n    DSU(int n) : p(n, -1) {}\n    int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (p[a] > p[b]) swap(a, b);\n        p[a] += p[b];\n        p[b] = a;\n        return true;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    long long cost;\n    int covered;\n};\n\nint ceil_sqrt_ll(long long x) {\n    if (x <= 0) return 0;\n    long long r = (long long)std::sqrt((long double)x);\n    while (r * r < x) ++r;\n    while ((r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\n\nconst int LIMIT = 5000;\nconst long long INFLL = (1LL << 60);\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<long long> W(M);\n    vector<vector<EdgeAdj>> g(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        U[j] = u; V[j] = v; W[j] = w;\n        g[u].push_back({v, j, w});\n        g[v].push_back({u, j, w});\n    }\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n\n    const int LIMIT2 = LIMIT * LIMIT;\n\n    // dist2 and within\n    vector<vector<int>> dist2(N, vector<int>(K));\n    vector<vector<int>> within(N);\n    for (int i = 0; i < N; i++) {\n        within[i].reserve(K / 4);\n        for (int k = 0; k < K; k++) {\n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            long long d2 = dx * dx + dy * dy;\n            dist2[i][k] = (int)d2;\n            if (d2 <= LIMIT2) within[i].push_back(k);\n        }\n    }\n\n    // all pairs shortest path via Dijkstra\n    vector<vector<long long>> distMat(N, vector<long long>(N, INFLL));\n    vector<vector<int>> parentEdge(N, vector<int>(N, -1));\n    using PLLI = pair<long long, int>;\n    for (int s = 0; s < N; s++) {\n        vector<long long> d(N, INFLL);\n        vector<int> p(N, -1);\n        d[s] = 0;\n        priority_queue<PLLI, vector<PLLI>, greater<PLLI>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cd, v] = pq.top();\n            pq.pop();\n            if (cd != d[v]) continue;\n            for (auto &e : g[v]) {\n                long long nd = cd + e.w;\n                if (nd < d[e.to]) {\n                    d[e.to] = nd;\n                    p[e.to] = e.id;\n                    pq.push({nd, e.to});\n                }\n            }\n        }\n        distMat[s] = move(d);\n        parentEdge[s] = move(p);\n    }\n\n    // MST of full graph\n    struct EItem { long long w; int id; };\n    vector<EItem> edgeList;\n    edgeList.reserve(M);\n    for (int i = 0; i < M; i++) edgeList.push_back({W[i], i});\n    sort(edgeList.begin(), edgeList.end(), [](const EItem &a, const EItem &b){ return a.w < b.w; });\n    DSU dsuFull(N);\n    vector<int> mstFullEdges;\n    mstFullEdges.reserve(N - 1);\n    for (auto &e : edgeList) {\n        int id = e.id;\n        int u = U[id], v = V[id];\n        if (dsuFull.unite(u, v)) {\n            mstFullEdges.push_back(id);\n            if ((int)mstFullEdges.size() == N - 1) break;\n        }\n    }\n\n    auto prune_edges = [&](const vector<int> &Pvec, vector<int> &Bvec) {\n        vector<int> deg(N, 0);\n        vector<vector<int>> inc(N);\n        for (int e = 0; e < M; e++) if (Bvec[e]) {\n            int a = U[e], b = V[e];\n            deg[a]++; deg[b]++;\n            inc[a].push_back(e);\n            inc[b].push_back(e);\n        }\n        auto isTerminal = [&](int v)->bool {\n            return Pvec[v] > 0 || v == 0;\n        };\n        queue<int> q;\n        vector<char> inq(N, false);\n        for (int i = 0; i < N; i++) {\n            if (!isTerminal(i) && deg[i] == 1) { q.push(i); inq[i] = true; }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (isTerminal(v) || deg[v] != 1) continue;\n            int eActive = -1;\n            for (int eid : inc[v]) if (Bvec[eid]) { eActive = eid; break; }\n            if (eActive == -1) continue;\n            Bvec[eActive] = 0;\n            int nei = (U[eActive] == v ? V[eActive] : U[eActive]);\n            deg[v]--; deg[nei]--;\n            if (!isTerminal(nei) && deg[nei] == 1 && !inq[nei]) { q.push(nei); inq[nei] = true; }\n        }\n    };\n\n    auto ensure_coverage = [&](vector<int> allowed, const vector<char> &banned = {}) {\n        vector<char> inAllowed(N, false);\n        for (int v : allowed) inAllowed[v] = true;\n        vector<char> cov(K, false);\n        int uncovered = K;\n        for (int v : allowed) {\n            for (int k : within[v]) {\n                if (!cov[k]) { cov[k] = true; uncovered--; }\n            }\n        }\n        while (uncovered > 0) {\n            int target = -1;\n            for (int k = 0; k < K; k++) if (!cov[k]) { target = k; break; }\n            if (target == -1) break;\n            int best = -1;\n            int bestd = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                if (!banned.empty() && banned[i]) continue;\n                int d = dist2[i][target];\n                if (d <= LIMIT2 && d < bestd) {\n                    bestd = d; best = i;\n                }\n            }\n            if (best == -1) break;\n            if (!inAllowed[best]) {\n                inAllowed[best] = true;\n                allowed.push_back(best);\n                for (int k : within[best]) {\n                    if (!cov[k]) { cov[k] = true; uncovered--; }\n                }\n            } else {\n                break;\n            }\n        }\n        return allowed;\n    };\n\n    auto build_solution = [&](const vector<int> &allowed) -> Solution {\n        vector<int> Pmax(N, -1);\n        for (int k = 0; k < K; k++) {\n            int best = -1;\n            int bestd = INT_MAX;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < bestd) { bestd = d; best = v; }\n            }\n            if (best == -1) continue;\n            if (bestd > LIMIT2) {\n                // cannot cover\n            }\n            if (bestd > Pmax[best]) Pmax[best] = bestd;\n        }\n        vector<int> P(N, 0);\n        vector<int> terminals;\n        terminals.push_back(0);\n        for (int i = 0; i < N; i++) {\n            if (Pmax[i] >= 0) {\n                int r = ceil_sqrt_ll(Pmax[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n                if (i != 0 && r > 0) terminals.push_back(i);\n            }\n        }\n        // coverage check\n        vector<char> covered(K, false);\n        int covcnt = 0;\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (int k = 0; k < K; k++) {\n                if (!covered[k] && dist2[i][k] <= r2) {\n                    covered[k] = true; covcnt++;\n                }\n            }\n        }\n        if (covcnt < K) {\n            return Solution{P, vector<int>(M, 0), (long long)4e18, covcnt};\n        }\n        long long costP = 0;\n        for (int i = 0; i < N; i++) costP += 1LL * P[i] * P[i];\n\n        // Tree method 1: metric MST\n        vector<int> B1(M, 0);\n        if ((int)terminals.size() > 1) {\n            vector<tuple<long long, int, int>> edges;\n            int T = terminals.size();\n            edges.reserve(T * (T - 1) / 2);\n            for (int i = 0; i < T; i++) {\n                int u = terminals[i];\n                for (int j = i + 1; j < T; j++) {\n                    int v = terminals[j];\n                    edges.emplace_back(distMat[u][v], u, v);\n                }\n            }\n            sort(edges.begin(), edges.end(),\n                 [](const auto &a, const auto &b){ return get<0>(a) < get<0>(b); });\n            DSU dsu(N);\n            int added = 0;\n            for (auto &ed : edges) {\n                long long w; int u, v;\n                tie(w, u, v) = ed;\n                if (dsu.unite(u, v)) {\n                    int cur = v;\n                    while (cur != u) {\n                        int e = parentEdge[u][cur];\n                        if (e == -1) break;\n                        B1[e] = 1;\n                        cur = (U[e] == cur ? V[e] : U[e]);\n                    }\n                    if (++added == T - 1) break;\n                }\n            }\n        }\n        prune_edges(P, B1);\n        long long costE1 = 0;\n        for (int e = 0; e < M; e++) if (B1[e]) costE1 += W[e];\n\n        // Tree method 2: MST of full graph pruned\n        vector<int> B2(M, 0);\n        for (int eid : mstFullEdges) B2[eid] = 1;\n        prune_edges(P, B2);\n        long long costE2 = 0;\n        for (int e = 0; e < M; e++) if (B2[e]) costE2 += W[e];\n\n        long long total1 = costP + costE1;\n        long long total2 = costP + costE2;\n        if (total1 <= total2) {\n            return Solution{P, B1, total1, covcnt};\n        } else {\n            return Solution{P, B2, total2, covcnt};\n        }\n    };\n\n    // Greedy coverage selection\n    auto greedy_cover = [&]() {\n        vector<char> covered(K, false);\n        int uncovered = K;\n        vector<char> sel(N, false);\n        sel[0] = true;\n        while (uncovered > 0) {\n            int best = -1;\n            int bestCnt = 0;\n            for (int i = 0; i < N; i++) {\n                if (sel[i]) continue;\n                int cnt = 0;\n                for (int k : within[i]) if (!covered[k]) cnt++;\n                if (cnt > bestCnt) { bestCnt = cnt; best = i; }\n            }\n            if (best == -1 || bestCnt == 0) break;\n            sel[best] = true;\n            for (int k : within[best]) if (!covered[k]) { covered[k] = true; uncovered--; }\n        }\n        // remove redundant\n        vector<int> coverCount(K, 0);\n        for (int k = 0; k < K; k++) {\n            int cnt = 0;\n            for (int i = 0; i < N; i++) {\n                if (sel[i] && dist2[i][k] <= LIMIT2) cnt++;\n            }\n            coverCount[k] = cnt;\n        }\n        for (int i = 1; i < N; i++) if (sel[i]) {\n            bool red = true;\n            for (int k = 0; k < K; k++) {\n                if (dist2[i][k] <= LIMIT2 && coverCount[k] <= 1) { red = false; break; }\n            }\n            if (red) {\n                sel[i] = false;\n                for (int k = 0; k < K; k++) if (dist2[i][k] <= LIMIT2) coverCount[k]--;\n            }\n        }\n        vector<int> res;\n        for (int i = 0; i < N; i++) if (sel[i]) res.push_back(i);\n        return res;\n    };\n\n    auto greedy_eff = [&]() {\n        vector<char> covered(K, false);\n        int uncovered = K;\n        vector<char> sel(N, false);\n        sel[0] = true;\n        while (uncovered > 0) {\n            int best = -1;\n            double bestScore = -1.0;\n            int bestCnt = 0;\n            for (int i = 0; i < N; i++) {\n                if (sel[i]) continue;\n                int cnt = 0;\n                for (int k : within[i]) if (!covered[k]) cnt++;\n                if (cnt == 0) continue;\n                double score = (double)cnt / (1.0 + distMat[0][i]);\n                if (score > bestScore) {\n                    bestScore = score;\n                    best = i;\n                    bestCnt = cnt;\n                }\n            }\n            if (best == -1 || bestCnt == 0) break;\n            sel[best] = true;\n            for (int k : within[best]) if (!covered[k]) { covered[k] = true; uncovered--; }\n        }\n        vector<int> res;\n        for (int i = 0; i < N; i++) if (sel[i]) res.push_back(i);\n        return res;\n    };\n\n    vector<vector<int>> allowedSets;\n    vector<int> selCover = greedy_cover();\n    allowedSets.push_back(selCover);\n    // augmented\n    int TH = 3500, TH2 = TH * TH;\n    vector<char> allowFlag(N, false);\n    for (int v : selCover) allowFlag[v] = true;\n    for (int k = 0; k < K; k++) {\n        int bestd = INT_MAX;\n        for (int v : selCover) {\n            int d = dist2[v][k];\n            if (d < bestd) bestd = d;\n        }\n        if (bestd > TH2) {\n            int bestv = -1; int bestdv = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                int d = dist2[i][k];\n                if (d < bestdv) { bestdv = d; bestv = i; }\n            }\n            if (bestv != -1) allowFlag[bestv] = true;\n        }\n    }\n    vector<int> aug;\n    for (int i = 0; i < N; i++) if (allowFlag[i]) aug.push_back(i);\n    allowedSets.push_back(aug);\n\n    vector<int> effSet = greedy_eff();\n    allowedSets.push_back(effSet);\n\n    vector<int> allSet(N);\n    iota(allSet.begin(), allSet.end(), 0);\n    allowedSets.push_back(allSet);\n\n    // ensure coverage for sets\n    for (auto &vec : allowedSets) {\n        vec = ensure_coverage(vec);\n    }\n\n    Solution bestSol;\n    bestSol.cost = (long long)4e18;\n    bestSol.covered = 0;\n    for (auto &vec : allowedSets) {\n        Solution sol = build_solution(vec);\n        if (sol.covered == K && sol.cost < bestSol.cost) bestSol = sol;\n    }\n\n    // Removal search on used nodes\n    vector<int> used;\n    for (int i = 1; i < N; i++) if (bestSol.P.size() == (size_t)N && bestSol.P[i] > 0) used.push_back(i);\n    vector<char> banned(N, false);\n    for (int v : used) {\n        fill(banned.begin(), banned.end(), false);\n        banned[v] = true;\n        vector<int> allowed = allSet;\n        // remove v\n        allowed.erase(remove(allowed.begin(), allowed.end(), v), allowed.end());\n        allowed = ensure_coverage(allowed, banned);\n        Solution sol = build_solution(allowed);\n        if (sol.covered == K && sol.cost < bestSol.cost) {\n            bestSol = sol;\n        }\n    }\n\n    // Random search with time budget\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    auto startTime = chrono::steady_clock::now();\n    double TIME_LIMIT = 1.85;\n    uniform_real_distribution<double> probDist(0.2, 0.6);\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        double p = probDist(rng);\n        vector<int> allowed;\n        allowed.push_back(0);\n        for (int i = 1; i < N; i++) {\n            double r = std::generate_canonical<double, 10>(rng);\n            if (r < p) allowed.push_back(i);\n        }\n        allowed = ensure_coverage(allowed);\n        Solution sol = build_solution(allowed);\n        if (sol.covered == K && sol.cost < bestSol.cost) {\n            bestSol = sol;\n        }\n    }\n\n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        cout << bestSol.P[i] << (i + 1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (bestSol.B[j] ? 1 : 0) << (j + 1 == M ? '\\n' : ' ');\n    }\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int TOT = N * (N + 1) / 2; // 465\n    vector<int> val(TOT);\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int v;\n            if (!(cin >> v)) return 0;\n            int id = x * (x + 1) / 2 + y;\n            val[id] = v;\n        }\n    }\n    // coordinate lookup\n    vector<int> xs(TOT), ys(TOT);\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int id = x * (x + 1) / 2 + y;\n            xs[id] = x;\n            ys[id] = y;\n        }\n    }\n    // children arrays (-1 if leaf)\n    vector<int> ch1(TOT, -1), ch2(TOT, -1);\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            int id = x * (x + 1) / 2 + y;\n            int c = (x + 1) * (x + 2) / 2 + y;\n            ch1[id] = c;\n            ch2[id] = c + 1;\n        }\n    }\n\n    const int LIMIT = 10000;\n    vector<array<int, 4>> moves;\n    moves.reserve(5000);\n\n    // bottom-up heapify (Floyd) on this binary tree\n    int last_internal = TOT - N - 1; // index of last internal node\n    for (int i = last_internal; i >= 0; i--) {\n        int cur = i;\n        while (ch1[cur] != -1) {\n            int c = ch1[cur];\n            if (val[ch2[cur]] < val[c]) c = ch2[cur];\n            if (val[cur] <= val[c]) break;\n            swap(val[cur], val[c]);\n            moves.push_back({xs[cur], ys[cur], xs[c], ys[c]});\n            cur = c;\n            if ((int)moves.size() >= LIMIT) break;\n        }\n        if ((int)moves.size() >= LIMIT) break;\n    }\n\n    // output\n    cout << moves.size() << \"\\n\";\n    for (auto &op : moves) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    const int er = 0, ec = (D - 1) / 2; // entrance\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; k++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    int dr[4] = {1, -1, 0, 0};\n    int dc[4] = {0, 0, 1, -1};\n\n    // distance from entrance\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist[er][ec] = 0;\n    q.push({er, ec});\n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (dist[nr][nc] != -1) continue;\n            dist[nr][nc] = dist[r][c] + 1;\n            q.push({nr, nc});\n        }\n    }\n\n    // list of container cells sorted by distance\n    vector<pair<int, int>> cells;\n    cells.reserve(D * D);\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (obstacle[i][j]) continue;\n        if (i == er && j == ec) continue;\n        cells.push_back({i, j});\n    }\n    sort(cells.begin(), cells.end(), [&](auto a, auto b) {\n        int da = dist[a.first][a.second], db = dist[b.first][b.second];\n        if (da != db) return da < db;\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    int K = (int)cells.size(); // number of containers\n    vector<int> idx_of(D * D, -1);\n    for (int idx = 0; idx < K; idx++) {\n        idx_of[cells[idx].first * D + cells[idx].second] = idx;\n    }\n\n    vector<vector<bool>> filled(D, vector<bool>(D, false));\n    vector<vector<int>> label_grid(D, vector<int>(D, -1));\n    int empties_count = K;\n\n    auto is_safe = [&](int r, int c) -> bool {\n        filled[r][c] = true;\n        int need = empties_count - 1;\n        int cnt = 0;\n        bool vis[9][9] = {};\n        queue<pair<int, int>> qq;\n        qq.push({er, ec});\n        vis[er][ec] = true;\n        while (!qq.empty()) {\n            auto [cr, cc] = qq.front();\n            qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int nr = cr + dr[k], nc = cc + dc[k];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (filled[nr][nc]) continue;\n                if (vis[nr][nc]) continue;\n                vis[nr][nc] = true;\n                if (!(nr == er && nc == ec)) cnt++;\n                qq.push({nr, nc});\n            }\n        }\n        filled[r][c] = false;\n        return cnt == need;\n    };\n\n    // placement phase\n    for (int step = 0; step < K; step++) {\n        int t;\n        cin >> t;\n        int target = t;\n        int best_idx = -1;\n        for (int offset = 0; offset < K; offset++) {\n            vector<int> candidates;\n            if (offset == 0) {\n                candidates.push_back(target);\n            } else {\n                if (t < K / 2) {\n                    if (target - offset >= 0) candidates.push_back(target - offset);\n                    if (target + offset < K) candidates.push_back(target + offset);\n                } else {\n                    if (target + offset < K) candidates.push_back(target + offset);\n                    if (target - offset >= 0) candidates.push_back(target - offset);\n                }\n            }\n            bool found = false;\n            for (int idx : candidates) {\n                if (idx < 0 || idx >= K) continue;\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    best_idx = idx;\n                    found = true;\n                    break;\n                }\n            }\n            if (found) break;\n        }\n        if (best_idx == -1) {\n            // fallback\n            for (int idx = 0; idx < K; idx++) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    best_idx = idx;\n                    break;\n                }\n            }\n        }\n        auto [pr, pc] = cells[best_idx];\n        filled[pr][pc] = true;\n        label_grid[pr][pc] = t;\n        empties_count--;\n        cout << pr << \" \" << pc << '\\n';\n        cout.flush();\n    }\n\n    // retrieval phase\n    vector<vector<bool>> present(D, vector<bool>(D, false));\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (label_grid[i][j] != -1) present[i][j] = true;\n    }\n    using Node = tuple<int, int, int, int>; // label, idx, r, c\n    struct Comp {\n        bool operator()(const Node &a, const Node &b) const {\n            if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n            return get<1>(a) > get<1>(b);\n        }\n    };\n    priority_queue<Node, vector<Node>, Comp> pq;\n    auto push_cell = [&](int r, int c) {\n        if (r < 0 || r >= D || c < 0 || c >= D) return;\n        if (obstacle[r][c]) return;\n        if (present[r][c]) {\n            int idx = idx_of[r * D + c];\n            pq.emplace(label_grid[r][c], idx, r, c);\n        }\n    };\n    push_cell(er + 1, ec);\n    push_cell(er - 1, ec);\n    push_cell(er, ec + 1);\n    push_cell(er, ec - 1);\n\n    int removed = 0;\n    while (removed < K) {\n        if (pq.empty()) {\n            // find any frontier cell\n            bool pushed = false;\n            for (int i = 0; i < D && !pushed; i++) for (int j = 0; j < D && !pushed; j++) {\n                if (present[i][j]) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dr[k], nj = j + dc[k];\n                        if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                        if (obstacle[ni][nj]) continue;\n                        if (!present[ni][nj] || (ni == er && nj == ec)) {\n                            int idx = idx_of[i * D + j];\n                            pq.emplace(label_grid[i][j], idx, i, j);\n                            pushed = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        auto [lab, idx, r, c] = pq.top();\n        pq.pop();\n        if (!present[r][c]) continue;\n        present[r][c] = false;\n        removed++;\n        cout << r << \" \" << c << '\\n';\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            push_cell(nr, nc);\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> g(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> g[i][j];\n        }\n    }\n    int C = m + 1; // colors 0..m\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto addEdge = [&](int a, int b) {\n        if (a == b) return;\n        adjCnt[a][b]++;\n        adjCnt[b][a]++;\n    };\n    // sizes\n    vector<int> sz(C, 0);\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) sz[g[i][j]]++;\n    // internal edges\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int a = g[i][j];\n            if (i + 1 < n) {\n                int b = g[i + 1][j];\n                addEdge(a, b);\n            }\n            if (j + 1 < n) {\n                int b = g[i][j + 1];\n                addEdge(a, b);\n            }\n            // outside edges\n            if (i == 0) addEdge(0, a);\n            if (i == n - 1) addEdge(0, a);\n            if (j == 0) addEdge(0, a);\n            if (j == n - 1) addEdge(0, a);\n        }\n    }\n    vector<vector<char>> adjOrig(C, vector<char>(C, 0));\n    for (int i = 0; i < C; i++) {\n        for (int j = 0; j < C; j++) {\n            if (adjCnt[i][j] > 0) adjOrig[i][j] = 1;\n        }\n    }\n    vector<char> boundary(C, 0);\n    for (int c = 1; c <= m; c++) {\n        if (adjOrig[0][c]) boundary[c] = 1;\n    }\n\n    // visited for BFS\n    vector<int> vis(n * n, 0);\n    int curMark = 1;\n    auto isAdjZero = [&](int i, int j) -> bool {\n        if (i == 0 || i == n - 1 || j == 0 || j == n - 1) return true;\n        if (g[i - 1][j] == 0) return true;\n        if (g[i + 1][j] == 0) return true;\n        if (g[i][j - 1] == 0) return true;\n        if (g[i][j + 1] == 0) return true;\n        return false;\n    };\n\n    // connectivity check excluding cell (ci,cj) of color col\n    auto connectedAfterRemoval = [&](int ci, int cj, int col) -> bool {\n        if (sz[col] <= 1) return false;\n        int start = -1;\n        // try neighbors first\n        if (ci > 0 && g[ci - 1][cj] == col) start = (ci - 1) * n + cj;\n        else if (ci + 1 < n && g[ci + 1][cj] == col) start = (ci + 1) * n + cj;\n        else if (cj > 0 && g[ci][cj - 1] == col) start = ci * n + (cj - 1);\n        else if (cj + 1 < n && g[ci][cj + 1] == col) start = ci * n + (cj + 1);\n        if (start == -1) {\n            for (int idx = 0; idx < n * n; idx++) {\n                if (idx == ci * n + cj) continue;\n                int r = idx / n, c = idx % n;\n                if (g[r][c] == col) { start = idx; break; }\n            }\n        }\n        if (start == -1) return false; // should not happen\n        curMark++;\n        queue<int> q;\n        q.push(start);\n        vis[start] = curMark;\n        int count = 1;\n        const int dr[4] = {1, -1, 0, 0};\n        const int dc[4] = {0, 0, 1, -1};\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int r = v / n, c = v % n;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n                if (nr == ci && nc == cj) continue; // removed cell\n                if (g[nr][nc] != col) continue;\n                int idx = nr * n + nc;\n                if (vis[idx] == curMark) continue;\n                vis[idx] = curMark;\n                q.push(idx);\n                count++;\n            }\n        }\n        return count == sz[col] - 1;\n    };\n\n    static int remEdgesStatic[205]; // enough for m<=200\n    // main removal loop\n    while (true) {\n        bool removed = false;\n        for (int i = 0; i < n && !removed; i++) {\n            for (int j = 0; j < n && !removed; j++) {\n                int c = g[i][j];\n                if (c == 0) continue;\n                if (!boundary[c]) continue; // only remove boundary colors\n                if (!isAdjZero(i, j)) continue;\n                if (sz[c] <= 1) continue;\n                int num0 = 0;\n                int numSame = 0;\n                vector<int> touched;\n                bool bad = false;\n                const int dr[4] = {1, -1, 0, 0};\n                const int dc[4] = {0, 0, 1, -1};\n                for (int k = 0; k < 4; k++) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                        num0++;\n                        continue;\n                    }\n                    int d = g[ni][nj];\n                    if (d == 0) {\n                        num0++;\n                    } else if (d == c) {\n                        numSame++;\n                    } else {\n                        if (remEdgesStatic[d] == 0) touched.push_back(d);\n                        remEdgesStatic[d]++;\n                        if (!boundary[d]) { // would create adjacency to non-boundary color\n                            bad = true;\n                            break;\n                        }\n                    }\n                }\n                if (bad) {\n                    for (int d : touched) remEdgesStatic[d] = 0;\n                    continue;\n                }\n                bool ok = true;\n                for (int d : touched) {\n                    if (adjOrig[c][d]) {\n                        if (adjCnt[c][d] - remEdgesStatic[d] <= 0) { ok = false; break; }\n                    }\n                }\n                if (ok) {\n                    int predicted0c = adjCnt[0][c] - num0 + numSame;\n                    if (predicted0c <= 0) ok = false;\n                }\n                if (ok) {\n                    if (!connectedAfterRemoval(i, j, c)) ok = false;\n                }\n                for (int d : touched) remEdgesStatic[d] = 0;\n                if (!ok) continue;\n\n                // perform removal\n                for (int k = 0; k < 4; k++) {\n                    int ni = i + dr[k], nj = j + dc[k];\n                    if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                        adjCnt[0][c]--; adjCnt[c][0]--;\n                    } else {\n                        int d = g[ni][nj];\n                        if (d == c) {\n                            adjCnt[0][c]++; adjCnt[c][0]++;\n                        } else if (d == 0) {\n                            adjCnt[0][c]--; adjCnt[c][0]--;\n                        } else {\n                            adjCnt[c][d]--; adjCnt[d][c]--;\n                            adjCnt[0][d]++; adjCnt[d][0]++;\n                        }\n                    }\n                }\n                g[i][j] = 0;\n                sz[c]--;\n                removed = true;\n            }\n        }\n        if (!removed) break;\n    }\n\n    // output\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j) cout << ' ';\n            cout << g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if(!(cin >> N >> D >> Q)) return 0;\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<double> score(N, 0.0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n\n    int used = 0;\n    string res;\n\n    // Swiss-like tournament\n    while(used < Q){\n        shuffle(order.begin(), order.end(), rng);\n        stable_sort(order.begin(), order.end(), [&](int a, int b){\n            if (score[a] != score[b]) return score[a] > score[b];\n            return a < b;\n        });\n        for(int idx = 0; idx + 1 < N && used < Q; idx += 2){\n            int a = order[idx], b = order[idx+1];\n            cout << 1 << \" \" << 1 << \" \" << a << \" \" << b << \"\\n\";\n            cout.flush();\n            if(!(cin >> res)) return 0;\n            char c = res[0];\n            if(c == '>') score[a] += 1.0;\n            else if(c == '<') score[b] += 1.0;\n            else { score[a] += 0.5; score[b] += 0.5; }\n            used++;\n        }\n    }\n\n    // Final ranking by score\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), rng); // random tie-break\n    stable_sort(idx.begin(), idx.end(), [&](int a, int b){\n        if (score[a] != score[b]) return score[a] > score[b];\n        return a < b;\n    });\n    vector<int> rank(N);\n    for(int pos = 0; pos < N; pos++) rank[idx[pos]] = pos;\n\n    double lambda = 1e-5;\n    double M = 100000.0 * N / D;\n    double ex = exp(-lambda * M);\n\n    vector<double> west(N);\n    for(int i = 0; i < N; i++){\n        double p = (N - rank[i] - 0.5) / N; // quantile estimate\n        if(p <= 1e-9) p = 1e-9;\n        if(p >= 1 - 1e-9) p = 1 - 1e-9;\n        double w = -log(1.0 - p * (1.0 - ex)) / lambda;\n        if(w > M) w = M;\n        west[i] = w;\n    }\n\n    // Initial greedy assignment\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b){\n        return west[a] > west[b];\n    });\n    vector<double> sum(D, 0.0);\n    vector<int> assign(N, 0);\n    for(int id : ord){\n        int best = 0;\n        double bestsum = sum[0];\n        for(int d = 1; d < D; d++){\n            if(sum[d] < bestsum){\n                bestsum = sum[d];\n                best = d;\n            }\n        }\n        assign[id] = best;\n        sum[best] += west[id];\n    }\n\n    double total = 0.0;\n    for(double w: west) total += w;\n    double mean = total / D;\n    double curVar = 0.0;\n    for(int d = 0; d < D; d++){\n        double diff = sum[d] - mean;\n        curVar += diff * diff;\n    }\n\n    // Local search (move and swap) to minimize variance\n    int ITER = 200000;\n    for(int it = 0; it < ITER; it++){\n        if((rng() & 1) == 0){\n            // move\n            int i = rng() % N;\n            int gi = assign[i];\n            int gj = rng() % D;\n            if(gi == gj) continue;\n            double w = west[i];\n            double si = sum[gi], sj = sum[gj];\n            double nsi = si - w, nsj = sj + w;\n            double newVar = curVar\n                - (si - mean) * (si - mean) - (sj - mean) * (sj - mean)\n                + (nsi - mean) * (nsi - mean) + (nsj - mean) * (nsj - mean);\n            if(newVar < curVar){\n                curVar = newVar;\n                assign[i] = gj;\n                sum[gi] = nsi;\n                sum[gj] = nsj;\n            }\n        }else{\n            // swap\n            int i = rng() % N;\n            int j = rng() % N;\n            if(assign[i] == assign[j]) continue;\n            int gi = assign[i], gj = assign[j];\n            double wi = west[i], wj = west[j];\n            double si = sum[gi], sj = sum[gj];\n            double nsi = si - wi + wj;\n            double nsj = sj - wj + wi;\n            double newVar = curVar\n                - (si - mean) * (si - mean) - (sj - mean) * (sj - mean)\n                + (nsi - mean) * (nsi - mean) + (nsj - mean) * (nsj - mean);\n            if(newVar < curVar){\n                curVar = newVar;\n                swap(assign[i], assign[j]);\n                sum[gi] = nsi;\n                sum[gj] = nsj;\n            }\n        }\n    }\n\n    for(int i = 0; i < N; i++){\n        if(i) cout << ' ';\n        cout << assign[i];\n    }\n    cout << \"\\n\";\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF_INT = 1e9;\nconst int N_CONST = 200;\nconst int M_CONST = 10;\nconst int BUCKET_SIZE = 20; // n/m fixed\n\nstruct Param {\n    int block_threshold; // if number of boxes above >= threshold -> move as a block\n    int indiv_mode;      // 0: patience(top>=x), 1: bucket, 2: largestTop, 3: minHeight\n    int block_mode;      // 0: minHeight, 1: largestTop, 2: bucket\n    bool random_tie;\n};\n\nstruct Result {\n    int cost;\n    int op_count;\n    vector<pair<int,int>> ops;\n    bool success;\n};\n\ndouble TIME_LIMIT = 1.9; // seconds\nchrono::steady_clock::time_point g_start;\n\ndouble elapsed_sec() {\n    return chrono::duration<double>(chrono::steady_clock::now() - g_start).count();\n}\n\n// select destination stack for individual move of box x from src\nint select_dest_individual(int x, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.indiv_mode == 2) { // largestTop\n        int best = -1;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.indiv_mode == 1) { // bucket preference\n        int target = (x - 1) / BUCKET_SIZE;\n        if (target != src) {\n            if (st[target].empty() || st[target].back() >= x) {\n                return target;\n            }\n        }\n    }\n    if (p.indiv_mode == 3) { // minHeight\n        int best = -1;\n        int bestSz = INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int sz = (int)st[i].size();\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n                bestSz = sz; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // patience mode\n    int bestTop = INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top >= x) {\n            if (top < bestTop) {\n                bestTop = top;\n                cand.clear();\n                cand.push_back(i);\n            } else if (top == bestTop) {\n                cand.push_back(i);\n            }\n        }\n    }\n    if (!cand.empty()) {\n        if (p.random_tie && cand.size() > 1) {\n            uniform_int_distribution<int> dist(0, (int)cand.size()-1);\n            return cand[dist(rng)];\n        } else {\n            int best = cand[0];\n            int bestSz = (int)st[best].size();\n            for (int idx = 1; idx < (int)cand.size(); idx++) {\n                int i = cand[idx];\n                int sz = (int)st[i].size();\n                if (sz < bestSz) { bestSz = sz; best = i; }\n            }\n            return best;\n        }\n    }\n    // no top>=x, choose largest top\n    bestTop = -INF_INT;\n    cand.clear();\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) {\n            bestTop = top;\n            cand.clear();\n            cand.push_back(i);\n        } else if (top == bestTop) cand.push_back(i);\n    }\n    if (p.random_tie && cand.size() > 1) {\n        uniform_int_distribution<int> dist(0, (int)cand.size()-1);\n        return cand[dist(rng)];\n    } else {\n        int best = cand[0];\n        int bestSz = (int)st[best].size();\n        for (int idx = 1; idx < (int)cand.size(); idx++) {\n            int i = cand[idx];\n            int sz = (int)st[i].size();\n            if (sz < bestSz) { bestSz = sz; best = i; }\n        }\n        return best;\n    }\n}\n\n// select destination stack for block move (representative value rep, from src)\nint select_dest_block(int rep, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.block_mode == 2) { // bucket\n        int t = (rep - 1) / BUCKET_SIZE;\n        if (t != src) return t;\n        // else fall through to minHeight\n    }\n    if (p.block_mode == 1) { // largestTop\n        int best = -1;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // minHeight\n    int best = -1;\n    int bestSz = INF_INT;\n    int bestTop = -INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int sz = (int)st[i].size();\n        if (sz < bestSz) {\n            bestSz = sz;\n            cand.clear();\n            cand.push_back(i);\n        } else if (sz == bestSz) cand.push_back(i);\n    }\n    if (cand.size() == 1) return cand[0];\n    // tie-breaker: larger top\n    bestTop = -INF_INT;\n    best = cand[0];\n    for (int idx = 0; idx < (int)cand.size(); idx++) {\n        int i = cand[idx];\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) { bestTop = top; best = i; }\n    }\n    return best;\n}\n\nResult simulate(const vector<vector<int>>& init, const Param& p, uint64_t seed, bool record_ops, int best_cost_so_far) {\n    mt19937 rng(seed);\n    vector<vector<int>> st = init;\n    vector<int> pos(N_CONST + 1, -1);\n    int m = (int)st.size();\n    for (int i = 0; i < m; i++) {\n        for (int v : st[i]) pos[v] = i;\n    }\n    int energy = 0;\n    int op_cnt = 0;\n    vector<pair<int,int>> ops;\n    ops.reserve(3000);\n    for (int cur = 1; cur <= N_CONST; cur++) {\n        while (true) {\n            int s = pos[cur];\n            if (s < 0) return {INF_INT, op_cnt, ops, false}; // shouldn't happen\n            if (!st[s].empty() && st[s].back() == cur) {\n                st[s].pop_back();\n                pos[cur] = -1;\n                op_cnt++;\n                if (record_ops) ops.emplace_back(cur, 0);\n                break;\n            } else {\n                // compute boxes above cur\n                int d = 0;\n                for (int idx = (int)st[s].size() - 1; idx >= 0; idx--) {\n                    if (st[s][idx] == cur) break;\n                    d++;\n                }\n                bool did_block = false;\n                if (d > 0 && d >= p.block_threshold) {\n                    did_block = true;\n                    int k = d;\n                    int v = st[s][(int)st[s].size() - k]; // bottom of block (just above cur)\n                    int dest = select_dest_block(v, s, st, p, rng);\n                    // move block\n                    int start_idx = (int)st[s].size() - k;\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        int val = st[s][idx];\n                        st[dest].push_back(val);\n                        pos[val] = dest;\n                    }\n                    st[s].resize(start_idx);\n                    energy += k + 1;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(v, dest + 1);\n                }\n                if (!did_block) {\n                    int x = st[s].back();\n                    int dest = select_dest_individual(x, s, st, p, rng);\n                    st[s].pop_back();\n                    st[dest].push_back(x);\n                    pos[x] = dest;\n                    energy += 2;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(x, dest + 1);\n                }\n                if (op_cnt > 5000) return {INF_INT, op_cnt, ops, false};\n                if (!record_ops && energy >= best_cost_so_far) {\n                    return {INF_INT, op_cnt, ops, false};\n                }\n            }\n        }\n    }\n    return {energy, op_cnt, ops, true};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> init(m);\n    for (int i = 0; i < m; i++) {\n        init[i].reserve(n / m);\n        for (int j = 0; j < n / m; j++) {\n            int v; cin >> v;\n            init[i].push_back(v);\n        }\n    }\n\n    g_start = chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Param> base_params;\n    // block_threshold, indiv_mode, block_mode\n    base_params.push_back({1000, 0, 0, false}); // patience\n    base_params.push_back({1000, 1, 0, false}); // bucket\n    base_params.push_back({1000, 2, 0, false}); // largestTop\n    base_params.push_back({1000, 3, 0, false}); // minHeight\n    base_params.push_back({6, 0, 0, false});\n    base_params.push_back({4, 0, 0, false});\n    base_params.push_back({4, 1, 0, false});\n    base_params.push_back({4, 3, 0, false});\n    base_params.push_back({3, 0, 0, false});\n    base_params.push_back({2, 0, 0, false});\n    base_params.push_back({2, 1, 0, false});\n    base_params.push_back({2, 3, 0, false});\n    base_params.push_back({1, 0, 0, false});\n    base_params.push_back({1, 0, 1, false});\n    base_params.push_back({3, 0, 1, false});\n\n    int best_cost = INF_INT;\n    vector<pair<int,int>> best_ops;\n\n    for (const auto& p : base_params) {\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n        if (elapsed_sec() > TIME_LIMIT) break;\n    }\n\n    // random exploration with random tie-breaking\n    while (elapsed_sec() < TIME_LIMIT) {\n        Param p = base_params[rng() % base_params.size()];\n        p.random_tie = true;\n        // slight random tweak of threshold\n        int delta = (int)(rng() % 3) - 1; // -1,0,1\n        int th = max(1, p.block_threshold + delta);\n        if (p.block_threshold >= 1000) th = 1000;\n        p.block_threshold = th;\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    if (best_ops.empty()) {\n        // fallback trivial plan\n        Param p{1000, 3, 0, false}; // individual minHeight\n        Result r = simulate(init, p, 123456789, true, INF_INT);\n        best_ops.swap(r.ops);\n    }\n\n    for (auto &op : best_ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hwall, vwall;\nvector<int> dflat;\nvector<vector<int>> adj;\n\ninline int id(int i, int j) { return i * N + j; }\n\nchar dirChar(int a, int b) {\n    int ai = a / N, aj = a % N;\n    int bi = b / N, bj = b % N;\n    if (bi == ai + 1) return 'D';\n    if (bi == ai - 1) return 'U';\n    if (bj == aj + 1) return 'R';\n    if (bj == aj - 1) return 'L';\n    return '?';\n}\n\nstruct BFSSolver {\n    int V;\n    const vector<vector<int>> &adj;\n    vector<int> dist;\n    vector<int> par;\n    BFSSolver(int V, const vector<vector<int>> &adj) : V(V), adj(adj), dist(V), par(V) {}\n    vector<int> get_path(int s, int t) {\n        if (s == t) return {s};\n        for (int nb : adj[s]) if (nb == t) return {s, t};\n        fill(dist.begin(), dist.end(), -1);\n        queue<int> q;\n        dist[s] = 0;\n        par[s] = -1;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int nb : adj[v]) {\n                if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    par[nb] = v;\n                    if (nb == t) {\n                        while (!q.empty()) q.pop();\n                        break;\n                    }\n                    q.push(nb);\n                }\n            }\n        }\n        if (dist[t] == -1) return {};\n        vector<int> path;\n        int cur = t;\n        while (cur != -1) {\n            path.push_back(cur);\n            if (cur == s) break;\n            cur = par[cur];\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    }\n};\n\nstring build_route_from_order(const vector<int> &order, BFSSolver &solver) {\n    string res;\n    int cur = order[0];\n    for (int idx = 1; idx < (int)order.size(); idx++) {\n        int target = order[idx];\n        vector<int> path = solver.get_path(cur, target);\n        if (path.empty()) return \"\";\n        for (int k = 1; k < (int)path.size(); k++) {\n            res.push_back(dirChar(path[k - 1], path[k]));\n        }\n        cur = target;\n        if ((int)res.size() > 100000) return \"\";\n    }\n    vector<int> path = solver.get_path(cur, order[0]);\n    if (path.empty()) return \"\";\n    for (int k = 1; k < (int)path.size(); k++) {\n        res.push_back(dirChar(path[k - 1], path[k]));\n    }\n    return res;\n}\n\nstring build_dfs_route() {\n    string res;\n    vector<vector<char>> vis(N, vector<char>(N, 0));\n    int di[4] = {0, 1, 0, -1};\n    int dj[4] = {1, 0, -1, 0};\n    char dc[4] = {'R', 'D', 'L', 'U'};\n    function<void(int, int)> dfs = [&](int i, int j) {\n        vis[i][j] = 1;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) { // right\n                wall = (vwall[i][j] == '1');\n            } else if (dir == 2) { // left\n                wall = (vwall[i][j - 1] == '1');\n            } else if (dir == 1) { // down\n                wall = (hwall[i][j] == '1');\n            } else { // up\n                wall = (hwall[i - 1][j] == '1');\n            }\n            if (wall) continue;\n            if (!vis[ni][nj]) {\n                res.push_back(dc[dir]);\n                dfs(ni, nj);\n                res.push_back(dc[(dir + 2) % 4]);\n            }\n        }\n    };\n    dfs(0, 0);\n    return res;\n}\n\n// greedy nearest-unvisited path\nstring build_greedy_nearest(BFSSolver &solver) {\n    int V = N * N;\n    vector<char> vis(V, 0);\n    int cur = 0;\n    vis[cur] = 1;\n    int visitedCnt = 1;\n    string res;\n    res.reserve(V * 2);\n    vector<int> dist(V), par(V);\n    while (visitedCnt < V) {\n        // BFS to nearest unvisited\n        fill(dist.begin(), dist.end(), -1);\n        queue<int> q;\n        dist[cur] = 0;\n        par[cur] = -1;\n        q.push(cur);\n        int target = -1;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (!vis[v]) { target = v; break; }\n            for (int nb : adj[v]) {\n                if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    par[nb] = v;\n                    q.push(nb);\n                }\n            }\n        }\n        if (target == -1) break;\n        vector<int> path;\n        int x = target;\n        while (x != -1) {\n            path.push_back(x);\n            if (x == cur) break;\n            x = par[x];\n        }\n        reverse(path.begin(), path.end());\n        for (int idx = 1; idx < (int)path.size(); idx++) {\n            res.push_back(dirChar(path[idx - 1], path[idx]));\n            cur = path[idx];\n            if (!vis[cur]) {\n                vis[cur] = 1;\n                visitedCnt++;\n            }\n        }\n        if ((int)res.size() > 100000) return \"\";\n    }\n    vector<int> path = solver.get_path(cur, 0);\n    if (path.empty()) return \"\";\n    for (int idx = 1; idx < (int)path.size(); idx++) {\n        res.push_back(dirChar(path[idx - 1], path[idx]));\n    }\n    return res;\n}\n\nconst long double INF = 1e100;\n\nlong double compute_average(const string &route) {\n    int V = N * N;\n    int L = (int)route.size();\n    if (L == 0) return INF;\n    vector<vector<int>> times(V);\n    times.reserve(V);\n    int pi = 0, pj = 0;\n    for (int t = 0; t < L; t++) {\n        char c = route[t];\n        int ni = pi, nj = pj;\n        if (c == 'U') {\n            ni--;\n            if (ni < 0) return INF;\n            if (hwall[ni][nj] == '1') return INF;\n        } else if (c == 'D') {\n            if (pi >= N - 1) return INF;\n            if (hwall[pi][pj] == '1') return INF;\n            ni++;\n        } else if (c == 'L') {\n            if (pj <= 0) return INF;\n            if (vwall[pi][pj - 1] == '1') return INF;\n            nj--;\n        } else if (c == 'R') {\n            if (pj >= N - 1) return INF;\n            if (vwall[pi][pj] == '1') return INF;\n            nj++;\n        } else {\n            return INF;\n        }\n        pi = ni; pj = nj;\n        int pos = pi * N + pj;\n        times[pos].push_back(t);\n    }\n    if (pi != 0 || pj != 0) return INF;\n    long double total = 0;\n    for (int v = 0; v < V; v++) {\n        auto &vec = times[v];\n        if (vec.empty()) return INF;\n        int k = vec.size();\n        for (int idx = 0; idx < k; idx++) {\n            int t1 = vec[idx];\n            int t2 = (idx + 1 < k) ? vec[idx + 1] : vec[0] + L;\n            int len = t2 - t1;\n            total += (long double)dflat[v] * ((long double)len * (len - 1) / 2.0);\n        }\n    }\n    return total / (long double)L;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N)) return 0;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; i++) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; i++) cin >> vwall[i];\n    dflat.resize(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int x; cin >> x;\n            dflat[id(i, j)] = x;\n        }\n    }\n    int V = N * N;\n    adj.assign(V, {});\n    auto add_edge = [&](int i1, int j1, int i2, int j2) {\n        int a = id(i1, j1), b = id(i2, j2);\n        adj[a].push_back(b);\n        adj[b].push_back(a);\n    };\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i + 1 < N && hwall[i][j] == '0') add_edge(i, j, i + 1, j);\n            if (j + 1 < N && vwall[i][j] == '0') add_edge(i, j, i, j + 1);\n        }\n    }\n    BFSSolver solver(V, adj);\n\n    string bestRoute;\n    long double bestAvg = INF;\n\n    // row snake\n    {\n        vector<int> order;\n        order.reserve(V);\n        for (int i = 0; i < N; i++) {\n            if (i % 2 == 0) {\n                for (int j = 0; j < N; j++) order.push_back(id(i, j));\n            } else {\n                for (int j = N - 1; j >= 0; j--) order.push_back(id(i, j));\n            }\n        }\n        string route = build_route_from_order(order, solver);\n        if (!route.empty() && route.size() <= 100000) {\n            long double avg = compute_average(route);\n            if (avg < bestAvg) {\n                bestAvg = avg;\n                bestRoute = route;\n            }\n        }\n    }\n    // column snake\n    {\n        vector<int> order;\n        order.reserve(V);\n        for (int j = 0; j < N; j++) {\n            if (j % 2 == 0) {\n                for (int i = 0; i < N; i++) order.push_back(id(i, j));\n            } else {\n                for (int i = N - 1; i >= 0; i--) order.push_back(id(i, j));\n            }\n        }\n        string route = build_route_from_order(order, solver);\n        if (!route.empty() && route.size() <= 100000) {\n            long double avg = compute_average(route);\n            if (avg < bestAvg) {\n                bestAvg = avg;\n                bestRoute = route;\n            }\n        }\n    }\n    // BFS order\n    {\n        vector<int> order;\n        order.reserve(V);\n        vector<char> vis(V, 0);\n        queue<int> q;\n        q.push(0);\n        vis[0] = 1;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            order.push_back(v);\n            for (int nb : adj[v]) if (!vis[nb]) { vis[nb] = 1; q.push(nb); }\n        }\n        string route = build_route_from_order(order, solver);\n        if (!route.empty() && route.size() <= 100000) {\n            long double avg = compute_average(route);\n            if (avg < bestAvg) {\n                bestAvg = avg;\n                bestRoute = route;\n            }\n        }\n    }\n    // greedy nearest\n    {\n        string route = build_greedy_nearest(solver);\n        if (!route.empty() && route.size() <= 100000) {\n            long double avg = compute_average(route);\n            if (avg < bestAvg) {\n                bestAvg = avg;\n                bestRoute = route;\n            }\n        }\n    }\n    // DFS fallback\n    {\n        string route = build_dfs_route();\n        if (!route.empty() && route.size() <= 100000) {\n            long double avg = compute_average(route);\n            if (avg < bestAvg || bestRoute.empty()) {\n                bestAvg = avg;\n                bestRoute = route;\n            }\n        }\n    }\n\n    cout << bestRoute << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n\n    // Greedy shortest common superstring\n    auto overlap = [](const string &a, const string &b) {\n        int maxk = min(a.size(), b.size());\n        for (int k = maxk; k >= 1; k--) {\n            bool ok = true;\n            for (int t = 0; t < k; t++) {\n                if (a[a.size() - k + t] != b[t]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return k;\n        }\n        return 0;\n    };\n\n    vector<string> v = words;\n    while (v.size() > 1) {\n        int n = (int)v.size();\n        int best_i = 0, best_j = 1, best_o = -1;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) if (i != j) {\n                int o = overlap(v[i], v[j]);\n                if (o > best_o) {\n                    best_o = o;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        string merged = v[best_i] + v[best_j].substr(best_o);\n        vector<string> nv;\n        nv.reserve(n - 1);\n        for (int idx = 0; idx < n; idx++) {\n            if (idx == best_i || idx == best_j) continue;\n            nv.push_back(std::move(v[idx]));\n        }\n        nv.push_back(std::move(merged));\n        v.swap(nv);\n    }\n    string S = v[0];\n    int L = (int)S.size();\n\n    // Positions of each letter\n    vector<pair<int,int>> posList[26];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            posList[grid[i][j]-'A'].push_back({i,j});\n        }\n    }\n\n    const int INF = 1e9;\n    vector<vector<int>> dp(L);\n    vector<vector<int>> pre(L);\n\n    for (int k = 0; k < L; k++) {\n        int c = S[k]-'A';\n        int m = posList[c].size();\n        dp[k].assign(m, INF);\n        pre[k].assign(m, -1);\n        if (k == 0) {\n            for (int idx = 0; idx < m; idx++) {\n                auto [i,j] = posList[c][idx];\n                dp[k][idx] = abs(i - si) + abs(j - sj) + 1;\n            }\n        } else {\n            int pc = S[k-1]-'A';\n            int pm = posList[pc].size();\n            for (int idx = 0; idx < m; idx++) {\n                auto [ci,cj] = posList[c][idx];\n                int bestCost = INF;\n                int bestPrev = -1;\n                for (int pid = 0; pid < pm; pid++) {\n                    auto [pi,pj] = posList[pc][pid];\n                    int cand = dp[k-1][pid] + abs(pi - ci) + abs(pj - cj) + 1;\n                    if (cand < bestCost) {\n                        bestCost = cand;\n                        bestPrev = pid;\n                    }\n                }\n                dp[k][idx] = bestCost;\n                pre[k][idx] = bestPrev;\n            }\n        }\n    }\n\n    int endIdx = 0;\n    int best = INF;\n    for (int idx = 0; idx < (int)dp[L-1].size(); idx++) {\n        if (dp[L-1][idx] < best) {\n            best = dp[L-1][idx];\n            endIdx = idx;\n        }\n    }\n\n    vector<pair<int,int>> path(L);\n    int idx = endIdx;\n    for (int k = L-1; k >= 0; k--) {\n        int c = S[k]-'A';\n        path[k] = posList[c][idx];\n        idx = pre[k][idx];\n    }\n\n    for (auto &p : path) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    // Read shapes (not used in this naive solution)\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int t = 0; t < d; t++) {\n            int i, j; cin >> i >> j;\n            // ignore\n        }\n    }\n\n    vector<vector<int>> val(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int resp; \n            if (!(cin >> resp)) return 0;\n            val[i][j] = resp;\n        }\n    }\n\n    vector<pair<int,int>> oil;\n    oil.reserve(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (val[i][j] > 0) oil.emplace_back(i, j);\n        }\n    }\n\n    cout << \"a \" << oil.size();\n    for (auto &p : oil) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    cout.flush();\n\n    int verdict;\n    cin >> verdict; // 1 if correct, 0 otherwise\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Calculate marginal benefit of adding one more row to stripe idx\nint calc_benefit(int idx, int height, const vector<vector<int>> &r_by_rank, int W) {\n    int cap = height * W;\n    int benefit = 0;\n    for (int req : r_by_rank[idx]) {\n        if (req > cap) {\n            int diff = req - cap;\n            if (diff >= W) benefit += W;\n            else benefit += diff; // req is between cap and cap+W\n        }\n    }\n    return benefit;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0; // W is always 1000\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++) cin >> a[d][k];\n    }\n\n    // requests sorted descending for each day\n    vector<vector<int>> req_desc(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        req_desc[d] = a[d];\n        sort(req_desc[d].begin(), req_desc[d].end(), greater<int>());\n    }\n\n    // r_by_rank[i][d] = i-th largest request of day d\n    vector<vector<int>> r_by_rank(N, vector<int>(D));\n    for (int i = 0; i < N; i++) {\n        for (int d = 0; d < D; d++) {\n            r_by_rank[i][d] = req_desc[d][i];\n        }\n    }\n\n    // Greedily allocate row heights to stripes (width = W) to minimize total deficit\n    vector<int> heights(N, 1); // at least 1 row for each rectangle\n    struct Item {\n        int ben;\n        int idx;\n    };\n    auto cmp = [](const Item &p, const Item &q) {\n        if (p.ben != q.ben) return p.ben < q.ben;\n        return p.idx > q.idx;\n    };\n    priority_queue<Item, vector<Item>, decltype(cmp)> pq(cmp);\n\n    for (int i = 0; i < N; i++) {\n        int b = calc_benefit(i, heights[i], r_by_rank, W);\n        pq.push({b, i});\n    }\n\n    int extra_rows = W - N; // rows left after giving 1 row to each\n    for (int t = 0; t < extra_rows; t++) {\n        Item it = pq.top();\n        pq.pop();\n        int i = it.idx;\n        heights[i] += 1;\n        int b = calc_benefit(i, heights[i], r_by_rank, W);\n        pq.push({b, i});\n    }\n\n    // Sort heights descending to pair largest requests with largest rectangles\n    sort(heights.begin(), heights.end(), greater<int>());\n\n    // Build stripe rectangles covering full width\n    vector<array<int, 4>> stripes(N);\n    int y = 0;\n    for (int i = 0; i < N; i++) {\n        int h = heights[i];\n        stripes[i] = {y, 0, y + h, W};\n        y += h;\n    }\n    // Adjust last stripe to reach exactly W if needed (safety)\n    if (y != W && N > 0) {\n        stripes.back()[2] += (W - y);\n    }\n\n    // Output for each day: assign largest request to largest stripe\n    for (int d = 0; d < D; d++) {\n        vector<pair<int, int>> reqs;\n        reqs.reserve(N);\n        for (int k = 0; k < N; k++) {\n            reqs.emplace_back(a[d][k], k); // original index\n        }\n        sort(reqs.begin(), reqs.end(), [&](const auto &p, const auto &q) {\n            if (p.first != q.first) return p.first > q.first;\n            return p.second < q.second;\n        });\n        vector<array<int, 4>> out(N);\n        for (int i = 0; i < N; i++) {\n            int idx = reqs[i].second;\n            out[idx] = stripes[i];\n        }\n        for (int k = 0; k < N; k++) {\n            auto &r = out[k];\n            cout << r[0] << \" \" << r[1] << \" \" << r[2] << \" \" << r[3] << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353LL;\n\nstruct OpInfo {\n    int m, p, q;\n    array<int, 9> idx;\n    array<int, 9> inc;\n};\n\nuint64_t rng_state;\ninline uint64_t rng64() {\n    rng_state ^= rng_state << 7;\n    rng_state ^= rng_state >> 9;\n    return rng_state;\n}\ninline int rand_int(int n) {\n    return int(rng64() % n);\n}\ninline double rand_double() {\n    // use 53 bits for double\n    return (rng64() >> 11) * (1.0 / 9007199254740992.0);\n}\n\ninline ll add_mod_fast(ll x, int inc) {\n    x += inc;\n    if (x >= MOD) x -= MOD;\n    return x;\n}\ninline ll adjust_mod(ll x) {\n    if (x >= MOD) x -= MOD;\n    else if (x < 0) x += MOD;\n    return x;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    rng_state = chrono::high_resolution_clock::now().time_since_epoch().count();\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<ll> base(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            ll v;\n            cin >> v;\n            base[i * N + j] = v;\n        }\n    }\n    vector<vector<vector<int>>> s(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int v;\n                cin >> v;\n                s[m][i][j] = v;\n            }\n        }\n    }\n\n    // Precompute all possible operations\n    vector<OpInfo> opsInfo;\n    opsInfo.reserve(M * (N - 2) * (N - 2));\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                OpInfo op;\n                op.m = m; op.p = p; op.q = q;\n                int t = 0;\n                for (int di = 0; di < 3; di++) {\n                    for (int dj = 0; dj < 3; dj++) {\n                        op.idx[t] = (p + di) * N + (q + dj);\n                        op.inc[t] = s[m][di][dj];\n                        t++;\n                    }\n                }\n                opsInfo.push_back(op);\n            }\n        }\n    }\n    int totalOps = (int)opsInfo.size(); // should be 980\n\n    // Initial board remainders\n    vector<ll> modv(N * N);\n    ll score = 0;\n    for (int i = 0; i < N * N; i++) {\n        modv[i] = base[i] % MOD;\n        score += modv[i];\n    }\n\n    vector<int> curOps;\n    curOps.reserve(K);\n\n    auto greedy_fill = [&](vector<ll>& modvRef, ll& scoreRef, vector<int>& opsVec, int maxAdd) {\n        for (int step = 0; step < maxAdd; step++) {\n            ll best_delta = 0;\n            int best_id = -1;\n            for (int opId = 0; opId < totalOps; opId++) {\n                const auto& op = opsInfo[opId];\n                ll delta = 0;\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modvRef[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    delta += nv - modvRef[pos];\n                }\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_id = opId;\n                }\n            }\n            if (best_delta > 0 && best_id != -1) {\n                const auto& op = opsInfo[best_id];\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modvRef[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    scoreRef += nv - modvRef[pos];\n                    modvRef[pos] = nv;\n                }\n                opsVec.push_back(best_id);\n            } else {\n                break;\n            }\n        }\n    };\n\n    // Initial greedy solution\n    greedy_fill(modv, score, curOps, K);\n\n    vector<int> bestOps = curOps;\n    ll bestScore = score;\n\n    // Simulated Annealing\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9; // seconds\n    const double T0 = 1e8;\n    const double T1 = 1e5;\n    double temp = T0;\n    int iter = 0;\n    const int CHECK_INTERVAL = 1024;\n    while (true) {\n        if ((iter & (CHECK_INTERVAL - 1)) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n            if (elapsed > TIME_LIMIT) break;\n            double progress = elapsed / TIME_LIMIT;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        iter++;\n        int L = (int)curOps.size();\n        int moveType;\n        uint64_t rstate = rng64();\n        if (L == 0) {\n            moveType = 1; // insert\n        } else if (L == K) {\n            moveType = (rstate & 15) ? 0 : 2; // mostly replace\n        } else {\n            int v = (int)(rstate % 100);\n            if (v < 70) moveType = 0;      // replace\n            else if (v < 85) moveType = 1; // insert\n            else moveType = 2;             // delete\n        }\n\n        if (moveType == 0) {\n            // replace\n            if (L == 0) continue;\n            int idx = (int)(rstate % L);\n            int oldOpId = curOps[idx];\n            int newOpId = rand_int(totalOps);\n            if (newOpId == oldOpId) continue;\n            const auto& oldOp = opsInfo[oldOpId];\n            const auto& newOp = opsInfo[newOpId];\n            int idxs[18];\n            ll deltaAdd[18];\n            ll newMods[18];\n            int cnt = 0;\n            auto add_delta = [&](int pos, ll d) {\n                for (int t = 0; t < cnt; t++) {\n                    if (idxs[t] == pos) {\n                        deltaAdd[t] += d;\n                        return;\n                    }\n                }\n                idxs[cnt] = pos;\n                deltaAdd[cnt] = d;\n                cnt++;\n            };\n            for (int t = 0; t < 9; t++) add_delta(oldOp.idx[t], - (ll)oldOp.inc[t]);\n            for (int t = 0; t < 9; t++) add_delta(newOp.idx[t], (ll)newOp.inc[t]);\n            ll deltaScore = 0;\n            for (int t = 0; t < cnt; t++) {\n                int pos = idxs[t];\n                ll nm = modv[pos] + deltaAdd[t];\n                if (nm >= MOD) nm -= MOD;\n                else if (nm < 0) nm += MOD;\n                deltaScore += nm - modv[pos];\n                newMods[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < cnt; t++) {\n                    modv[idxs[t]] = newMods[t];\n                }\n                curOps[idx] = newOpId;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else if (moveType == 1) {\n            // insert\n            if (L >= K) continue;\n            int newOpId = (int)(rstate % totalOps);\n            const auto& op = opsInfo[newOpId];\n            ll deltaScore = 0;\n            ll newModsArr[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nm = modv[pos] + op.inc[t];\n                if (nm >= MOD) nm -= MOD;\n                deltaScore += nm - modv[pos];\n                newModsArr[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < 9; t++) {\n                    modv[op.idx[t]] = newModsArr[t];\n                }\n                curOps.push_back(newOpId);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else {\n            // delete\n            if (L == 0) continue;\n            int idx = (int)(rstate % L);\n            int oldOpId = curOps[idx];\n            const auto& op = opsInfo[oldOpId];\n            ll deltaScore = 0;\n            ll newModsArr[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nm = modv[pos] - op.inc[t];\n                if (nm < 0) nm += MOD;\n                deltaScore += nm - modv[pos];\n                newModsArr[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < 9; t++) {\n                    modv[op.idx[t]] = newModsArr[t];\n                }\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        }\n    }\n\n    // Reconstruct best state and final greedy extension\n    vector<ll> modv_best(N * N);\n    for (int i = 0; i < N * N; i++) modv_best[i] = base[i] % MOD;\n    ll score_best = 0;\n    for (int i = 0; i < N * N; i++) score_best += modv_best[i];\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        for (int t = 0; t < 9; t++) {\n            int pos = op.idx[t];\n            ll nv = modv_best[pos] + op.inc[t];\n            if (nv >= MOD) nv -= MOD;\n            score_best += nv - modv_best[pos];\n            modv_best[pos] = nv;\n        }\n    }\n    greedy_fill(modv_best, score_best, bestOps, K - (int)bestOps.size());\n\n    // Output\n    cout << bestOps.size() << \"\\n\";\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;\n    int hold;   // -1 if not holding\n    bool alive;\n};\n\nstruct Task {\n    int src;\n    int cid;\n};\n\nstruct Candidate {\n    vector<string> ops;\n    long long score;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n\n    const int base = N + 1;              // 6\n    int totalStates = 1;\n    for (int i = 0; i < N; i++) totalStates *= base; // 6^5 = 7776\n    const int POS = N + 1;               // 0..4 rows, 5=start\n\n    // precompute powers\n    vector<int> powBase(N);\n    powBase[N - 1] = 1;\n    for (int k = N - 2; k >= 0; k--) powBase[k] = powBase[k + 1] * base;\n    // powBase[idx] corresponds to base^(N-1-idx)\n\n    // precompute pointer vectors and sums\n    vector<array<int, 5>> pvec(totalStates);\n    vector<int> sumPtr(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        int tmp = code;\n        int sum = 0;\n        array<int, 5> p{};\n        for (int i = N - 1; i >= 0; i--) {\n            p[i] = tmp % base;\n            tmp /= base;\n            sum += p[i];\n        }\n        pvec[code] = p;\n        sumPtr[code] = sum;\n    }\n    // codes grouped by sum\n    vector<vector<int>> codesBySum(N * N + 1);\n    for (int code = 0; code < totalStates; code++) {\n        codesBySum[sumPtr[code]].push_back(code);\n    }\n\n    // precompute dest rows\n    vector<vector<int>> destRow(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) destRow[i][j] = A[i][j] / N;\n\n    // precompute invAdd for each state and source\n    vector<array<int, 5>> invAddTable(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        const auto &p = pvec[code];\n        for (int s = 0; s < N; s++) {\n            if (p[s] >= N) {\n                invAddTable[code][s] = 0;\n                continue;\n            }\n            int cid = A[s][p[s]];\n            int dr = cid / N;\n            int cnt = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < p[i]; j++) {\n                    int cid2 = A[i][j];\n                    if (cid2 / N == dr && cid2 > cid) cnt++;\n                }\n            }\n            invAddTable[code][s] = cnt;\n        }\n    }\n\n    auto plan = [&](int weight) -> Candidate {\n        const int INF = 1e9;\n        int dpSize = totalStates * POS;\n        vector<int> dp(dpSize, INF);\n        vector<int> parent(dpSize, -1);\n        vector<int> parentSrc(dpSize, -1);\n        int startIdx = 0 * POS + N;\n        dp[startIdx] = 0;\n\n        for (int total = 0; total <= N * N; total++) {\n            for (int code : codesBySum[total]) {\n                for (int pos = 0; pos < POS; pos++) {\n                    int idx = code * POS + pos;\n                    int curCost = dp[idx];\n                    if (curCost == INF) continue;\n                    const auto &p = pvec[code];\n                    for (int s = 0; s < N; s++) {\n                        if (p[s] >= N) continue;\n                        int cid = A[s][p[s]];\n                        int dr = destRow[s][p[s]];\n                        int dist1;\n                        if (pos == N) dist1 = abs(s - 0);\n                        else dist1 = 4 + abs(pos - dr + dr - dr + (pos - s)) - abs(pos - dr) + abs(pos - s); // incorrect\n                    }\n                }\n            }\n        }\n\n        // The above block had an error due to an overcomplicated expression.\n        // Recompute correctly.\n        fill(dp.begin(), dp.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        fill(parentSrc.begin(), parentSrc.end(), -1);\n        dp[startIdx] = 0;\n\n        for (int total = 0; total <= N * N; total++) {\n            for (int code : codesBySum[total]) {\n                const auto &p = pvec[code];\n                for (int pos = 0; pos < POS; pos++) {\n                    int idx = code * POS + pos;\n                    int curCost = dp[idx];\n                    if (curCost == INF) continue;\n                    for (int s = 0; s < N; s++) {\n                        if (p[s] >= N) continue;\n                        int cid = A[s][p[s]];\n                        int dr = destRow[s][p[s]];\n                        int dist1 = (pos == N) ? abs(0 - s) : 4 + abs(pos - s);\n                        int dist2 = 4 + abs(s - dr);\n                        int moveCost = dist1 + dist2 + 2; // pick and drop\n                        int invAdd = invAddTable[code][s];\n                        int nextCode = code + powBase[s]; // increase p[s] by 1\n                        int nextPos = dr;\n                        int nextIdx = nextCode * POS + nextPos;\n                        int newCost = curCost + moveCost + weight * invAdd;\n                        if (newCost < dp[nextIdx]) {\n                            dp[nextIdx] = newCost;\n                            parent[nextIdx] = idx;\n                            parentSrc[nextIdx] = s;\n                        }\n                    }\n                }\n            }\n        }\n\n        // full code\n        int fullCode = 0;\n        for (int i = 0; i < N; i++) fullCode = fullCode * base + N;\n        int bestPos = 0;\n        int bestIdx = fullCode * POS;\n        int bestCost = dp[bestIdx];\n        for (int pos = 1; pos < POS; pos++) {\n            int idx = fullCode * POS + pos;\n            if (dp[idx] < bestCost) {\n                bestCost = dp[idx];\n                bestIdx = idx;\n                bestPos = pos;\n            }\n        }\n\n        // reconstruct sequence of sources\n        vector<int> seqSources;\n        int curIdx = bestIdx;\n        while (curIdx != startIdx) {\n            int s = parentSrc[curIdx];\n            seqSources.push_back(s);\n            curIdx = parent[curIdx];\n        }\n        reverse(seqSources.begin(), seqSources.end());\n\n        // build tasks\n        vector<int> ptr(N, 0);\n        vector<Task> tasks;\n        tasks.reserve(N * N);\n        for (int s : seqSources) {\n            tasks.push_back({s, A[s][ptr[s]]});\n            ptr[s]++;\n        }\n\n        // simulation\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        int dispatched = 0;\n        int task_idx = 0;\n        int turn = 0;\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        const int TURN_LIMIT = 10000;\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn step\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) {\n                        blocked = true;\n                        break;\n                    }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            // large crane action\n            Crane &lc = cranes[0];\n            char a0 = '.';\n            if (lc.hold == -1) {\n                if (task_idx < (int)tasks.size()) {\n                    int sr = tasks[task_idx].src;\n                    if (lc.r < sr) a0 = 'D';\n                    else if (lc.r > sr) a0 = 'U';\n                    else if (lc.c > 0) a0 = 'L';\n                    else {\n                        if (grid[lc.r][lc.c] != -1) a0 = 'P';\n                        else a0 = '.';\n                    }\n                } else {\n                    a0 = '.';\n                }\n            } else {\n                int destR = lc.hold / N;\n                if (lc.c < N - 1) a0 = 'R';\n                else if (lc.r < destR) a0 = 'D';\n                else if (lc.r > destR) a0 = 'U';\n                else {\n                    if (grid[lc.r][lc.c] == -1) a0 = 'Q';\n                    else a0 = '.';\n                }\n            }\n            act[0] = a0;\n\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            // compute new positions\n            vector<pair<int, int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            // execute actions\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') {\n                    cranes[i].alive = false;\n                    continue;\n                }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) {\n                        cranes[i].hold = grid[r][c];\n                        grid[r][c] = -1;\n                    }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                        if (i == 0) task_idx++;\n                    }\n                }\n            }\n\n            // dispatch step\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn;\n        long long M1 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                for (int k = j + 1; k < len; k++) {\n                    if (seq[j] > seq[k]) M1++;\n                }\n            }\n        }\n        long long score = M0 + 100LL * M1;\n        Candidate cand{ops, score};\n        return cand;\n    };\n\n    vector<int> weights = {100, 130, 80, 160};\n    Candidate best;\n    best.score = (1LL << 60);\n    for (int w : weights) {\n        Candidate cand = plan(w);\n        if (cand.score < best.score) best = cand;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best.ops[i] << \"\\n\";\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing pii = pair<int,int>;\n\nstruct Plan {\n    vector<pii> path; // excludes (0,0)\n    ll R;\n    ll cost;\n    pii endpos;\n};\n\n// build path that ends at (0,1)\nvector<pii> build_pathA(int N){\n    vector<pii> p;\n    // first column downward (excluding start)\n    for(int r=1;r<N;r++) p.push_back({r,0});\n    // rows from bottom to top, skipping column 0\n    for(int r=N-1;r>=0;r--){\n        if(r%2==1){\n            for(int c=1;c<N;c++) p.push_back({r,c}); // left->right\n        }else{\n            for(int c=N-1;c>=1;c--) p.push_back({r,c}); // right->left\n        }\n    }\n    return p;\n}\n\n// build path that ends at (1,0)\nvector<pii> build_pathB(int N){\n    vector<pii> p;\n    // first row to the right (excluding start)\n    for(int c=1;c<N;c++) p.push_back({0,c});\n    // columns from right to left, skipping row 0\n    for(int c=N-1;c>=0;c--){\n        int offset = (N-1 - c);\n        if(offset%2==0){\n            for(int r=1;r<N;r++) p.push_back({r,c}); // top -> bottom\n        }else{\n            for(int r=N-1;r>=1;r--) p.push_back({r,c}); // bottom -> top\n        }\n    }\n    return p;\n}\n\nll simulate_cost(const vector<pii>& path, const vector<vector<int>>& h, ll& outR, pii& endpos){\n    int N = h.size();\n    ll pref=0;\n    ll minPref=0;\n    for(auto &co:path){\n        pref += h[co.first][co.second];\n        if(pref < minPref) minPref = pref;\n    }\n    ll R = -minPref;\n    outR = R;\n    ll cost=0;\n    ll load = R;\n    if(R>0) cost += R; // initial borrow\n    int cr=0, cc=0;\n    for(auto &co:path){\n        // move (adjacent)\n        cost += 100 + load;\n        int val = h[co.first][co.second];\n        cost += llabs((ll)val);\n        load += val;\n        cr = co.first; cc = co.second;\n    }\n    endpos = {cr,cc};\n    int dist = abs(cr) + abs(cc); // to (0,0)\n    cost += (ll)dist * (100 + load);\n    // final adjust start\n    cost += llabs(load); // load should equal R - h[0][0]\n    return cost;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cin>>h[i][j];\n        }\n    }\n\n    vector<pii> pathA = build_pathA(N);\n    vector<pii> pathB = build_pathB(N);\n    ll R1,R2;\n    pii end1,end2;\n    ll cost1 = simulate_cost(pathA, h, R1, end1);\n    ll cost2 = simulate_cost(pathB, h, R2, end2);\n\n    vector<pii> path = cost1 <= cost2 ? pathA : pathB;\n    ll R = cost1 <= cost2 ? R1 : R2;\n    pii endpos = cost1 <= cost2 ? end1 : end2;\n\n    vector<string> ops;\n    ll load = 0;\n    vector<vector<int>> g = h;\n\n    // initial borrow\n    if(R > 0){\n        ops.push_back(\"+\" + to_string(R));\n        load += R;\n        g[0][0] -= (int)R;\n    }\n\n    int cr=0, cc=0;\n    for(auto &co: path){\n        int nr = co.first, nc = co.second;\n        // move (adjacent)\n        if(nr == cr+1) ops.push_back(\"D\");\n        else if(nr == cr-1) ops.push_back(\"U\");\n        else if(nc == cc+1) ops.push_back(\"R\");\n        else if(nc == cc-1) ops.push_back(\"L\");\n        else {\n            // fallback: Manhattan path (should not happen)\n            while(cr < nr){ ops.push_back(\"D\"); cr++; }\n            while(cr > nr){ ops.push_back(\"U\"); cr--; }\n            while(cc < nc){ ops.push_back(\"R\"); cc++; }\n            while(cc > nc){ ops.push_back(\"L\"); cc--; }\n        }\n        cr = nr; cc = nc;\n        int val = g[cr][cc];\n        if(val > 0){\n            ops.push_back(\"+\" + to_string(val));\n            load += val;\n            g[cr][cc] = 0;\n        }else if(val < 0){\n            ops.push_back(\"-\" + to_string(-val));\n            load -= -val;\n            g[cr][cc] = 0;\n        } // if zero, skip\n    }\n\n    // return to start (0,0)\n    while(cr > 0){ ops.push_back(\"U\"); cr--; }\n    while(cc > 0){ ops.push_back(\"L\"); cc--; }\n\n    // final adjust start\n    int sval = g[0][0];\n    if(sval > 0){\n        ops.push_back(\"+\" + to_string(sval));\n        load += sval;\n        g[0][0] = 0;\n    }else if(sval < 0){\n        ops.push_back(\"-\" + to_string(-sval));\n        load -= -sval;\n        g[0][0] = 0;\n    }\n\n    // output operations\n    for(auto &s: ops){\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int SEED_COUNT = 2 * N * (N - 1); // 60 when N=6\n    vector<array<int, 15>> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; i++) {\n        for (int j = 0; j < M; j++) cin >> seeds[i][j];\n    }\n\n    // precompute center for distance\n    double cx = (N - 1) / 2.0;\n    double cy = (N - 1) / 2.0;\n\n    for (int turn = 0; turn < T; turn++) {\n        // compute values\n        vector<int> val(SEED_COUNT, 0);\n        for (int i = 0; i < SEED_COUNT; i++) {\n            int s = 0;\n            for (int l = 0; l < M; l++) s += seeds[i][l];\n            val[i] = s;\n        }\n        // best seed\n        int best_id = 0;\n        for (int i = 1; i < SEED_COUNT; i++) {\n            if (val[i] > val[best_id]) best_id = i;\n        }\n        // champions per attribute\n        vector<int> champion(M, 0);\n        vector<int> champCount(SEED_COUNT, 0);\n        for (int l = 0; l < M; l++) {\n            int cid = 0;\n            for (int i = 1; i < SEED_COUNT; i++) {\n                if (seeds[i][l] > seeds[cid][l] ||\n                    (seeds[i][l] == seeds[cid][l] && val[i] > val[cid])) {\n                    cid = i;\n                }\n            }\n            champion[l] = cid;\n            champCount[cid]++;\n        }\n        // improvers relative to best\n        struct Imp {\n            int imp;\n            int id;\n        };\n        vector<Imp> improvers;\n        improvers.reserve(SEED_COUNT);\n        for (int i = 0; i < SEED_COUNT; i++) if (i != best_id) {\n            int cmax = 0;\n            for (int l = 0; l < M; l++) {\n                cmax += max(seeds[best_id][l], seeds[i][l]);\n            }\n            improvers.push_back({cmax - val[best_id], i});\n        }\n        sort(improvers.begin(), improvers.end(), [&](const Imp &a, const Imp &b) {\n            if (a.imp != b.imp) return a.imp > b.imp;\n            return val[a.id] > val[b.id];\n        });\n        const int K_IMP = 8; // number of improvers to select\n\n        // selection of seeds to plant\n        vector<char> used(SEED_COUNT, 0);\n        vector<int> selected;\n        auto add_sel = [&](int id) {\n            if (!used[id]) {\n                used[id] = 1;\n                selected.push_back(id);\n            }\n        };\n        add_sel(best_id);\n        for (int l = 0; l < M; l++) add_sel(champion[l]);\n        for (int k = 0; k < (int)improvers.size() && k < K_IMP; k++) add_sel(improvers[k].id);\n\n        // fill with top value seeds\n        vector<int> order(SEED_COUNT);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return val[a] > val[b];\n        });\n        for (int id : order) {\n            if ((int)selected.size() >= N * N) break;\n            add_sel(id);\n        }\n\n        // trim if somehow over\n        if ((int)selected.size() > N * N) {\n            vector<char> essential(SEED_COUNT, 0);\n            essential[best_id] = 1;\n            for (int l = 0; l < M; l++) essential[champion[l]] = 1;\n            vector<int> removable;\n            for (int id : selected) if (!essential[id]) removable.push_back(id);\n            sort(removable.begin(), removable.end(), [&](int a, int b) {\n                return val[a] < val[b]; // remove lowest value first\n            });\n            int idx = 0;\n            while ((int)selected.size() > N * N && idx < (int)removable.size()) {\n                used[removable[idx]] = 0;\n                idx++;\n                selected.pop_back(); // will rebuild below\n            }\n            selected.clear();\n            for (int i = 0; i < SEED_COUNT; i++) if (used[i]) selected.push_back(i);\n        }\n\n        // placement grid\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<char> placed(SEED_COUNT, 0);\n\n        int ci = N / 2 - 1; // 2 for N=6\n        int cj = N / 2 - 1; // 2\n        grid[ci][cj] = best_id;\n        placed[best_id] = 1;\n\n        // pick neighbor improvers to place around best\n        vector<int> neighborSeeds;\n        for (int k = 0; k < (int)improvers.size() && (int)neighborSeeds.size() < 4; k++) {\n            int id = improvers[k].id;\n            if (used[id] && !placed[id]) {\n                neighborSeeds.push_back(id);\n            }\n        }\n        // fill remaining neighbor slots with highest value remaining\n        for (int id : order) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            if (used[id] && !placed[id]) neighborSeeds.push_back(id);\n        }\n        vector<pair<int, int>> neighborPos;\n        if (cj - 1 >= 0) neighborPos.push_back({ci, cj - 1});\n        if (cj + 1 < N) neighborPos.push_back({ci, cj + 1});\n        if (ci - 1 >= 0) neighborPos.push_back({ci - 1, cj});\n        if (ci + 1 < N) neighborPos.push_back({ci + 1, cj});\n        for (int idx = 0; idx < (int)neighborPos.size() && idx < (int)neighborSeeds.size(); idx++) {\n            auto [ri, rj] = neighborPos[idx];\n            grid[ri][rj] = neighborSeeds[idx];\n            placed[neighborSeeds[idx]] = 1;\n        }\n\n        // build remaining seed list: champions first then others\n        vector<int> remChamp, remOthers;\n        for (int id : selected) {\n            if (placed[id]) continue;\n            if (champCount[id] > 0) remChamp.push_back(id);\n            else remOthers.push_back(id);\n        }\n        sort(remChamp.begin(), remChamp.end(), [&](int a, int b) {\n            if (champCount[a] != champCount[b]) return champCount[a] > champCount[b];\n            return val[a] > val[b];\n        });\n        sort(remOthers.begin(), remOthers.end(), [&](int a, int b) {\n            return val[a] > val[b];\n        });\n        vector<int> placementOrder;\n        placementOrder.insert(placementOrder.end(), remChamp.begin(), remChamp.end());\n        placementOrder.insert(placementOrder.end(), remOthers.begin(), remOthers.end());\n\n        // build coordinate list of empty cells sorted by distance to center\n        struct CoordInfo {\n            double dist;\n            int deg;\n            int i, j;\n        };\n        vector<CoordInfo> coords;\n        int di[4] = {-1, 1, 0, 0};\n        int dj[4] = {0, 0, -1, 1};\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != -1) continue;\n                int deg = 0;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (0 <= ni && ni < N && 0 <= nj && nj < N) deg++;\n                }\n                double dist = fabs(i - cx) + fabs(j - cy);\n                coords.push_back({dist, deg, i, j});\n            }\n        }\n        sort(coords.begin(), coords.end(), [&](const CoordInfo &a, const CoordInfo &b) {\n            if (a.dist != b.dist) return a.dist < b.dist;\n            if (a.deg != b.deg) return a.deg > b.deg;\n            if (a.i != b.i) return a.i < b.i;\n            return a.j < b.j;\n        });\n\n        for (int idx = 0; idx < (int)placementOrder.size() && idx < (int)coords.size(); idx++) {\n            int id = placementOrder[idx];\n            auto c = coords[idx];\n            grid[c.i][c.j] = id;\n            placed[id] = 1;\n        }\n\n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j) cout << ' ';\n                cout << grid[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next generation seeds\n        if (turn != T - 1) {\n            for (int i = 0; i < SEED_COUNT; i++) {\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i][j];\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\n\nint manhattan(const Pos &a, const Pos &b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Hungarian algorithm for square cost matrix (1-indexed internally)\nvector<int> hungarian(const vector<vector<int>> &cost) {\n    int n = (int)cost.size();\n    const int INF = 1e9;\n    vector<int> u(n + 1), v(n + 1), p(n + 1), way(n + 1);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(n + 1, INF);\n        vector<char> used(n + 1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= n; j++) if (!used[j]) {\n                int cur = cost[i0 - 1][j - 1] - u[i0] - v[j];\n                if (cur < minv[j]) {\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if (minv[j] < delta) {\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for (int j = 0; j <= n; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        // augmenting\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    vector<int> matchS(n, -1); // for each row (source) assigned column (target)\n    for (int j = 1; j <= n; j++) {\n        if (p[j] != 0) {\n            matchS[p[j] - 1] = j - 1;\n        }\n    }\n    return matchS;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    vector<Pos> sources, targets;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1' && t[i][j] == '0') sources.push_back({i, j});\n            else if (s[i][j] == '0' && t[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n    int n = (int)sources.size(); // number of tasks\n    // Output tree design: single vertex (root is fingertip)\n    cout << 1 << \"\\n\";\n    // no edges\n    if (n == 0) {\n        cout << 0 << \" \" << 0 << \"\\n\";\n        return 0;\n    }\n\n    // Build cost matrix and compute minimum cost matching\n    vector<vector<int>> cost(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cost[i][j] = manhattan(sources[i], targets[j]);\n        }\n    }\n    vector<int> matchS = hungarian(cost); // matchS[i] = target index for source i\n\n    // Greedy sequence minimizing transition distances\n    vector<int> seq;\n    seq.reserve(n);\n    vector<char> used(n, false);\n    Pos curPos = {N / 2, N / 2};\n    for (int cnt = 0; cnt < n; cnt++) {\n        int best = -1;\n        int bestd = INT_MAX;\n        int bestintr = INT_MAX;\n        for (int i = 0; i < n; i++) if (!used[i]) {\n            int d = manhattan(curPos, sources[i]);\n            int intr = cost[i][matchS[i]];\n            if (d < bestd || (d == bestd && intr < bestintr)) {\n                bestd = d;\n                bestintr = intr;\n                best = i;\n            }\n        }\n        used[best] = true;\n        seq.push_back(best);\n        curPos = targets[matchS[best]]; // after finishing this task\n    }\n\n    // Local improvement by random swaps on transition cost\n    auto transition_cost = [&](const vector<int> &order) -> long long {\n        long long res = 0;\n        for (int i = 1; i < (int)order.size(); i++) {\n            res += manhattan(targets[matchS[order[i - 1]]], sources[order[i]]);\n        }\n        return res;\n    };\n    auto edge_cost = [&](const vector<int> &order, int pos) -> int {\n        if (pos <= 0) return 0;\n        return manhattan(targets[matchS[order[pos - 1]]], sources[order[pos]]);\n    };\n\n    long long transCost = transition_cost(seq);\n    mt19937 rng((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n    int iterMax = min(80000, n * 300);\n    for (int iter = 0; iter < iterMax; iter++) {\n        int i = uniform_int_distribution<int>(0, n - 1)(rng);\n        int j = uniform_int_distribution<int>(0, n - 1)(rng);\n        if (i == j) continue;\n        if (i > j) swap(i, j);\n        // positions that may change incoming edges: i, i+1, j, j+1\n        vector<int> posList;\n        posList.push_back(i);\n        if (i + 1 < n) posList.push_back(i + 1);\n        if (j != i) {\n            posList.push_back(j);\n            if (j + 1 < n) posList.push_back(j + 1);\n        }\n        sort(posList.begin(), posList.end());\n        posList.erase(unique(posList.begin(), posList.end()), posList.end());\n        long long before = 0;\n        for (int p : posList) before += edge_cost(seq, p);\n        swap(seq[i], seq[j]);\n        long long after = 0;\n        for (int p : posList) after += edge_cost(seq, p);\n        long long delta = after - before;\n        if (delta < 0) {\n            transCost += delta;\n        } else {\n            swap(seq[i], seq[j]); // revert\n        }\n    }\n\n    // Initial position is the source of the first task\n    Pos root = sources[seq[0]];\n    cout << root.x << \" \" << root.y << \"\\n\";\n\n    vector<string> cmds;\n    cmds.reserve((size_t)(transCost + n * 2 + 10));\n\n    Pos cur = root;\n\n    auto moveTo = [&](const Pos &dest, bool act) {\n        int dx = dest.x - cur.x;\n        int dy = dest.y - cur.y;\n        int stepsX = abs(dx), stepsY = abs(dy);\n        if (stepsX > 0) {\n            char mv = (dx > 0) ? 'D' : 'U';\n            for (int k = 1; k <= stepsX; k++) {\n                bool isLast = act && (stepsY == 0) && (k == stepsX);\n                string s;\n                s.push_back(mv);\n                s.push_back(isLast ? 'P' : '.');\n                cmds.push_back(std::move(s));\n            }\n        }\n        if (stepsY > 0) {\n            char mv = (dy > 0) ? 'R' : 'L';\n            for (int k = 1; k <= stepsY; k++) {\n                bool isLast = act && (k == stepsY);\n                string s;\n                s.push_back(mv);\n                s.push_back(isLast ? 'P' : '.');\n                cmds.push_back(std::move(s));\n            }\n        }\n        if (stepsX == 0 && stepsY == 0) {\n            string s;\n            s.push_back('.');\n            s.push_back(act ? 'P' : '.');\n            cmds.push_back(std::move(s));\n        }\n        cur = dest;\n    };\n\n    // Perform tasks in sequence\n    // First task: pick at source\n    moveTo(sources[seq[0]], true);\n    // drop at target\n    moveTo(targets[matchS[seq[0]]], true);\n    for (int idx = 1; idx < n; idx++) {\n        int task = seq[idx];\n        moveTo(sources[task], true);               // pick\n        moveTo(targets[matchS[task]], true);       // drop\n    }\n\n    for (auto &c : cmds) {\n        cout << c << \"\\n\";\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x1, x2, y1, y2;\n};\n\nconst int LIM = 100000;\n\ninline Rect normalize(Rect r) {\n    if (r.x1 > r.x2) swap(r.x1, r.x2);\n    if (r.y1 > r.y2) swap(r.y1, r.y2);\n    r.x1 = max(0, min(LIM, r.x1));\n    r.x2 = max(0, min(LIM, r.x2));\n    r.y1 = max(0, min(LIM, r.y1));\n    r.y2 = max(0, min(LIM, r.y2));\n    if (r.x1 == r.x2) {\n        if (r.x2 < LIM) r.x2++;\n        else if (r.x1 > 0) r.x1--;\n        else r.x2 = r.x1 + 1;\n    }\n    if (r.y1 == r.y2) {\n        if (r.y2 < LIM) r.y2++;\n        else if (r.y1 > 0) r.y1--;\n        else r.y2 = r.y1 + 1;\n    }\n    return r;\n}\n\nstruct Evaluator {\n    int tot;\n    const vector<int> &xs, &ys, &ws;\n    Evaluator(const vector<int>& _xs, const vector<int>& _ys, const vector<int>& _ws)\n        : tot((int)_xs.size()), xs(_xs), ys(_ys), ws(_ws) {}\n    inline int evalRect(const Rect& r) const {\n        int s = 0;\n        int x1 = r.x1, x2 = r.x2, y1 = r.y1, y2 = r.y2;\n        for (int i = 0; i < tot; i++) {\n            int x = xs[i];\n            if (x < x1 || x > x2) continue;\n            int y = ys[i];\n            if (y < y1 || y > y2) continue;\n            s += ws[i];\n        }\n        return s;\n    }\n};\n\nRect bestGridRect(int G, const vector<int>& xs, const vector<int>& ys, const vector<int>& ws) {\n    int cell = (LIM + G - 1) / G;\n    vector<vector<int>> diff(G, vector<int>(G, 0));\n    int tot = (int)xs.size();\n    for (int i = 0; i < tot; i++) {\n        int cx = xs[i] / cell; if (cx >= G) cx = G - 1;\n        int cy = ys[i] / cell; if (cy >= G) cy = G - 1;\n        diff[cy][cx] += ws[i];\n    }\n    int best = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n    vector<int> col(G);\n    for (int top = 0; top < G; top++) {\n        fill(col.begin(), col.end(), 0);\n        for (int bottom = top; bottom < G; bottom++) {\n            for (int x = 0; x < G; x++) col[x] += diff[bottom][x];\n            int cur = 0, start = 0;\n            int bestSum = -1e9, bestL = 0, bestR = 0;\n            for (int x = 0; x < G; x++) {\n                if (cur <= 0) {\n                    cur = col[x];\n                    start = x;\n                } else {\n                    cur += col[x];\n                }\n                if (cur > bestSum) {\n                    bestSum = cur;\n                    bestL = start;\n                    bestR = x;\n                }\n            }\n            if (bestSum > best) {\n                best = bestSum;\n                int x1 = bestL * cell;\n                int x2 = min(LIM, (bestR + 1) * cell);\n                int y1 = top * cell;\n                int y2 = min(LIM, (bottom + 1) * cell);\n                bestRect = normalize({x1, x2, y1, y2});\n            }\n        }\n    }\n    return bestRect;\n}\n\nstruct Candidate {\n    int score;\n    Rect rect;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    int TOT = 2 * N;\n    vector<int> xs(TOT), ys(TOT), ws(TOT);\n    for (int i = 0; i < TOT; i++) {\n        int x, y;\n        cin >> x >> y;\n        xs[i] = x;\n        ys[i] = y;\n        ws[i] = (i < N) ? 1 : -1;\n    }\n    Evaluator eval(xs, ys, ws);\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    auto startTime = chrono::steady_clock::now();\n\n    int bestScore = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n\n    vector<Candidate> candList;\n    auto addCandidate = [&](int sc, const Rect& r) {\n        // check duplicates\n        for (auto &c : candList) {\n            if (c.rect.x1 == r.x1 && c.rect.x2 == r.x2 && c.rect.y1 == r.y1 && c.rect.y2 == r.y2) {\n                if (sc > c.score) c.score = sc;\n                return;\n            }\n        }\n        candList.push_back({sc, r});\n        sort(candList.begin(), candList.end(), [](const Candidate& a, const Candidate& b) {\n            return a.score > b.score;\n        });\n        if ((int)candList.size() > 40) candList.resize(40);\n    };\n\n    auto consider = [&](const Rect& r) {\n        Rect nr = normalize(r);\n        int sc = eval.evalRect(nr);\n        addCandidate(sc, nr);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRect = nr;\n        }\n    };\n\n    // bounding box of mackerels\n    int minMx = LIM, maxMx = 0, minMy = LIM, maxMy = 0;\n    for (int i = 0; i < N; i++) {\n        minMx = min(minMx, xs[i]);\n        maxMx = max(maxMx, xs[i]);\n        minMy = min(minMy, ys[i]);\n        maxMy = max(maxMy, ys[i]);\n    }\n    consider({minMx, maxMx, minMy, maxMy});\n\n    // grid search\n    vector<int> Gs = {8, 12, 16, 20, 25, 30, 40, 50};\n    for (int g : Gs) {\n        Rect r = bestGridRect(g, xs, ys, ws);\n        consider(r);\n    }\n\n    // random search\n    vector<int> sizes = {200, 300, 500, 800, 1000, 1200, 1500, 2000, 2500, 3000, 4000, 5000, 6000, 8000, 10000, 12000, 15000, 20000, 25000};\n    const double RAND_TIME = 1.1; // seconds\n    int iter = 0;\n    while (true) {\n        iter++;\n        int t = rng() % 4;\n        if (t == 0) {\n            int idx = rng() % N;\n            int w = sizes[rng() % sizes.size()];\n            int h = sizes[rng() % sizes.size()];\n            Rect r{xs[idx] - w, xs[idx] + w, ys[idx] - h, ys[idx] + h};\n            consider(r);\n        } else if (t == 1) {\n            int i = rng() % TOT;\n            int j = rng() % TOT;\n            int x1 = min(xs[i], xs[j]);\n            int x2 = max(xs[i], xs[j]);\n            int y1 = min(ys[i], ys[j]);\n            int y2 = max(ys[i], ys[j]);\n            int marg = sizes[rng() % sizes.size()] / 2;\n            Rect r{x1 - marg, x2 + marg, y1 - marg, y2 + marg};\n            consider(r);\n        } else if (t == 2) {\n            Rect r = bestRect;\n            int delta = sizes[rng() % sizes.size()] / 2 + 1;\n            int dx1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dx2 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy2 = (int)(rng() % (2 * delta + 1)) - delta;\n            r.x1 += dx1; r.x2 += dx2; r.y1 += dy1; r.y2 += dy2;\n            consider(r);\n        } else {\n            // random thin rectangle\n            int idx = rng() % TOT;\n            int w = sizes[rng() % sizes.size()] / 4 + 1;\n            Rect r{xs[idx] - w, xs[idx] + w, 0, LIM};\n            consider(r);\n            r = {0, LIM, ys[idx] - w, ys[idx] + w};\n            consider(r);\n        }\n        if ((iter & 31) == 0) {\n            double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - startTime).count();\n            if (elapsed > RAND_TIME) break;\n        }\n    }\n\n    // hill climbing around bestRect\n    vector<int> steps = {20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50};\n    Rect cur = bestRect;\n    for (int step : steps) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int edge = 0; edge < 4; edge++) {\n                for (int dir = -1; dir <= 1; dir += 2) {\n                    Rect r = cur;\n                    if (edge == 0) r.x1 += dir * step;\n                    else if (edge == 1) r.x2 += dir * step;\n                    else if (edge == 2) r.y1 += dir * step;\n                    else r.y2 += dir * step;\n                    r = normalize(r);\n                    int sc = eval.evalRect(r);\n                    addCandidate(sc, r);\n                    if (sc > bestScore) {\n                        bestScore = sc;\n                        bestRect = cur = r;\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // evaluate pair connections\n    int bestPairScore = bestScore;\n    Rect bestA = bestRect, bestB = bestRect;\n    bool usePair = false;\n    bool horiz = true;\n    int corridorC = 0;\n    // only top K candidates\n    int K = min<int>(candList.size(), 25);\n    for (int i = 0; i < K; i++) for (int j = i + 1; j < K; j++) {\n        Rect A = candList[i].rect;\n        Rect B = candList[j].rect;\n        // horizontal connection: disjoint in x with y-overlap length>=1\n        if (A.x2 < B.x1 || B.x2 < A.x1) {\n            Rect L = A, R = B;\n            if (B.x2 < A.x1) { L = B; R = A; }\n            int ovL = max(L.y1, R.y1);\n            int ovH = min(L.y2, R.y2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int y1 = c, y2 = c + 1;\n                    int x1 = L.x2, x2 = R.x1;\n                    if (x1 > x2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= L.x1 && x <= L.x2 && y >= L.y1 && y <= L.y2) inside = true;\n                        else if (x >= R.x1 && x <= R.x2 && y >= R.y1 && y <= R.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = L;\n                        bestB = R;\n                        horiz = true;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n        // vertical connection: disjoint in y with x-overlap length>=1\n        if (A.y2 < B.y1 || B.y2 < A.y1) {\n            Rect Lw = A, Up = B;\n            if (B.y2 < A.y1) { Lw = B; Up = A; }\n            int ovL = max(Lw.x1, Up.x1);\n            int ovH = min(Lw.x2, Up.x2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int x1 = c, x2 = c + 1;\n                    int y1 = Lw.y2, y2 = Up.y1;\n                    if (y1 > y2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= Lw.x1 && x <= Lw.x2 && y >= Lw.y1 && y <= Lw.y2) inside = true;\n                        else if (x >= Up.x1 && x <= Up.x2 && y >= Up.y1 && y <= Up.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = Lw;\n                        bestB = Up;\n                        horiz = false;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int,int>> poly;\n    if (usePair) {\n        if (horiz) {\n            Rect L = bestA, R = bestB;\n            int c = corridorC;\n            int ch = 1;\n            vector<pair<int,int>> tmp = {\n                {L.x1, L.y1},\n                {L.x2, L.y1},\n                {L.x2, c},\n                {R.x1, c},\n                {R.x1, R.y1},\n                {R.x2, R.y1},\n                {R.x2, R.y2},\n                {R.x1, R.y2},\n                {R.x1, c + ch},\n                {L.x2, c + ch},\n                {L.x2, L.y2},\n                {L.x1, L.y2}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        } else {\n            Rect Lw = bestA, Up = bestB;\n            int c = corridorC;\n            int cw = 1;\n            vector<pair<int,int>> tmp = {\n                {Lw.x1, Lw.y1},\n                {Lw.x1, Lw.y2},\n                {c, Lw.y2},\n                {c, Up.y1},\n                {Up.x1, Up.y1},\n                {Up.x1, Up.y2},\n                {Up.x2, Up.y2},\n                {Up.x2, Up.y1},\n                {c + cw, Up.y1},\n                {c + cw, Lw.y2},\n                {Lw.x2, Lw.y2},\n                {Lw.x2, Lw.y1}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        }\n    } else {\n        poly = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n    }\n    // compress consecutive duplicates\n    vector<pair<int,int>> comp;\n    comp.reserve(poly.size());\n    for (auto &p : poly) {\n        if (comp.empty() || comp.back() != p) comp.push_back(p);\n    }\n    if (comp.size() >= 2 && comp.front() == comp.back()) comp.pop_back();\n    // check distinct\n    bool okDistinct = true;\n    {\n        unordered_set<long long> st;\n        st.reserve(comp.size() * 2);\n        for (auto &p : comp) {\n            long long key = ((long long)p.first << 32) ^ (unsigned)p.second;\n            if (st.find(key) != st.end()) {\n                okDistinct = false;\n                break;\n            }\n            st.insert(key);\n        }\n    }\n    long long perim = 0;\n    int m = (int)comp.size();\n    for (int i = 0; i < m; i++) {\n        auto [x1, y1] = comp[i];\n        auto [x2, y2] = comp[(i + 1) % m];\n        perim += llabs(x1 - x2) + llabs(y1 - y2);\n    }\n    if (!okDistinct || perim > 400000 || m < 4) {\n        comp = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n        m = 4;\n    }\n    cout << comp.size() << \"\\n\";\n    for (auto &p : comp) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Command {\n    int p;\n    int r;\n    char d;\n    int b;\n};\n\nstruct Candidate {\n    vector<Command> cmds;\n    long long estScore;\n};\n\n// simulate placement given commands and estimated widths/heights\npair<long long, long long> simulate(const vector<Command>& cmds,\n                                    const vector<long long>& w_est,\n                                    const vector<long long>& h_est) {\n    int N = (int)w_est.size();\n    vector<long long> x(N, 0), y(N, 0), ww(N, 0), hh(N, 0);\n    vector<char> placed(N, 0);\n    long long W = 0, H = 0;\n    for (const auto& cmd : cmds) {\n        int i = cmd.p;\n        long long w = (cmd.r == 0 ? w_est[i] : h_est[i]);\n        long long h = (cmd.r == 0 ? h_est[i] : w_est[i]);\n        long long xi, yi;\n        if (cmd.d == 'U') {\n            xi = (cmd.b == -1) ? 0LL : x[cmd.b] + ww[cmd.b];\n            yi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long l1 = xi, r1 = xi + w;\n                long long l2 = x[j], r2 = x[j] + ww[j];\n                if (max(l1, l2) < min(r1, r2)) {\n                    yi = max(yi, y[j] + hh[j]);\n                }\n            }\n        } else { // 'L'\n            yi = (cmd.b == -1) ? 0LL : y[cmd.b] + hh[cmd.b];\n            xi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long t1 = yi, b1 = yi + h;\n                long long t2 = y[j], b2 = y[j] + hh[j];\n                if (max(t1, t2) < min(b1, b2)) {\n                    xi = max(xi, x[j] + ww[j]);\n                }\n            }\n        }\n        x[i] = xi; y[i] = yi; ww[i] = w; hh[i] = h; placed[i] = 1;\n        W = max(W, xi + w);\n        H = max(H, yi + h);\n    }\n    return {W, H};\n}\n\nvector<int> dp_partition(const vector<long long>& w, const vector<long long>& h_eff, long long Wlim) {\n    int N = (int)w.size();\n    const long long INF = (1LL << 60);\n    vector<long long> dp(N + 1, INF);\n    vector<int> prv(N + 1, -1);\n    dp[0] = 0;\n    for (int i = 0; i < N; i++) {\n        long long width = 0;\n        long long height = 0;\n        for (int j = i; j >= 0; j--) {\n            width += w[j];\n            if (width > Wlim) break;\n            height = max(height, h_eff[j]);\n            if (dp[j] + height < dp[i + 1]) {\n                dp[i + 1] = dp[j] + height;\n                prv[i + 1] = j;\n            }\n        }\n    }\n    if (dp[N] >= INF / 2) prv.clear();\n    return prv;\n}\n\nvector<pair<int,int>> reconstruct_rows(const vector<int>& prv) {\n    vector<pair<int,int>> rows;\n    if (prv.empty()) return rows;\n    int idx = (int)prv.size() - 1;\n    while (idx > 0) {\n        int j = prv[idx];\n        if (j < 0) { rows.clear(); return rows; }\n        rows.push_back({j, idx});\n        idx = j;\n    }\n    reverse(rows.begin(), rows.end());\n    return rows;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // build orientation patterns\n    vector<vector<int>> orientations;\n    auto add_ori = [&](const vector<int>& o) {\n        for (auto &v : orientations) {\n            if (v == o) return;\n        }\n        orientations.push_back(o);\n    };\n    vector<int> ori_none(N, 0);\n    add_ori(ori_none);\n    vector<int> ori_minH(N), ori_minW(N);\n    for (int i = 0; i < N; i++) {\n        ori_minH[i] = (w_obs[i] < h_obs[i]) ? 1 : 0;\n        ori_minW[i] = (w_obs[i] > h_obs[i]) ? 1 : 0;\n    }\n    add_ori(ori_minH);\n    add_ori(ori_minW);\n    // lambda thresholds\n    vector<double> lambdas = {0.8, 1.0, 1.2};\n    for (double lam : lambdas) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            o[i] = ((double)w_obs[i] > lam * (double)h_obs[i]) ? 1 : 0;\n        }\n        add_ori(o);\n    }\n    // orientations adapted to some width limits\n    auto build_width_candidates_base = [&](const vector<long long>& w, const vector<long long>& h) {\n        long long sumW = 0, maxW = 0;\n        long double area = 0;\n        for (int i = 0; i < N; i++) {\n            sumW += w[i];\n            maxW = max(maxW, w[i]);\n            area += (long double)w[i] * (long double)h[i];\n        }\n        long long sqrtA = (long long)(sqrt(area) + 0.5);\n        set<long long> s;\n        s.insert(maxW);\n        s.insert(sumW);\n        s.insert(sqrtA);\n        int Kpart = min(8, N);\n        for (int k = 2; k <= Kpart; k++) {\n            s.insert((sumW + k - 1) / k);\n        }\n        int Kgeo = 8;\n        if (maxW > 0) {\n            long double ratio = (long double)sumW / (long double)maxW;\n            for (int k = 0; k < Kgeo; k++) {\n                long double val = (long double)maxW * pow(ratio, (long double)k / (long double)(Kgeo - 1));\n                long long W = (long long)(val + 0.5);\n                W = max(W, maxW);\n                W = min(W, sumW);\n                s.insert(W);\n            }\n        }\n        vector<long long> res(s.begin(), s.end());\n        return res;\n    };\n    vector<long long> base_w = w_obs, base_h = h_obs;\n    vector<long long> w_candidates_base = build_width_candidates_base(base_w, base_h);\n    for (long long Wlim : w_candidates_base) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            bool fit0 = w_obs[i] <= Wlim;\n            bool fitR = h_obs[i] <= Wlim;\n            if (fit0 && fitR) {\n                o[i] = (h_obs[i] > w_obs[i]) ? 1 : 0;\n            } else if (fit0) {\n                o[i] = 0;\n            } else if (fitR) {\n                o[i] = 1;\n            } else {\n                o[i] = 0;\n            }\n        }\n        add_ori(o);\n    }\n\n    vector<Candidate> candidates;\n    vector<long long> margins = {0}; // could add small margin if desired\n\n    auto build_candidates_for_orientation = [&](const vector<int>& r_choice) {\n        vector<long long> w_rot(N), h_rot(N);\n        long long sumW = 0, maxW = 0;\n        long long sumH = 0, maxH = 0;\n        long double area = 0;\n        for (int i = 0; i < N; i++) {\n            long long w = (r_choice[i] == 0 ? w_obs[i] : h_obs[i]);\n            long long h = (r_choice[i] == 0 ? h_obs[i] : w_obs[i]);\n            w_rot[i] = w; h_rot[i] = h;\n            sumW += w; sumH += h;\n            maxW = max(maxW, w);\n            maxH = max(maxH, h);\n            area += (long double)w * (long double)h;\n        }\n        long long sqrtA = (long long)(sqrt(area) + 0.5);\n\n        auto build_limits = [&](long long sumV, long long maxV, long long sqrtA) {\n            set<long long> s;\n            s.insert(maxV);\n            s.insert(sumV);\n            s.insert(sqrtA);\n            int Kpart = min(10, N);\n            for (int k = 2; k <= Kpart; k++) {\n                s.insert((sumV + k - 1) / k);\n            }\n            int Kgeo = 10;\n            if (maxV > 0) {\n                long double ratio = (long double)sumV / (long double)maxV;\n                for (int k = 0; k < Kgeo; k++) {\n                    long double val = (long double)maxV * pow(ratio, (long double)k / (long double)(Kgeo - 1));\n                    long long V = (long long)(val + 0.5);\n                    V = max(V, maxV);\n                    V = min(V, sumV);\n                    s.insert(V);\n                }\n            }\n            vector<long long> res(s.begin(), s.end());\n            return res;\n        };\n\n        vector<long long> Wlims = build_limits(sumW, maxW, sqrtA);\n        vector<long long> Hlims = build_limits(sumH, maxH, sqrtA);\n\n        // row packings\n        for (long long margin : margins) {\n            vector<long long> h_eff(N);\n            for (int i = 0; i < N; i++) h_eff[i] = h_rot[i] + margin;\n            for (long long Wlim : Wlims) {\n                if (Wlim < maxW) continue;\n                vector<int> prv = dp_partition(w_rot, h_eff, Wlim);\n                if (prv.empty()) continue;\n                vector<pair<int,int>> rows = reconstruct_rows(prv);\n                if (rows.empty()) continue;\n                vector<int> ref_idx(rows.size());\n                for (size_t ri = 0; ri < rows.size(); ri++) {\n                    int l = rows[ri].first;\n                    int r = rows[ri].second;\n                    long long besth = -1;\n                    int idx = l;\n                    for (int i = l; i < r; i++) {\n                        if (h_eff[i] > besth || (h_eff[i] == besth && i > idx)) {\n                            besth = h_eff[i];\n                            idx = i;\n                        }\n                    }\n                    ref_idx[ri] = idx;\n                }\n                vector<Command> cmds;\n                cmds.reserve(N);\n                for (size_t ri = 0; ri < rows.size(); ri++) {\n                    int b = (ri == 0) ? -1 : ref_idx[ri - 1];\n                    int l = rows[ri].first;\n                    int r = rows[ri].second;\n                    for (int i = l; i < r; i++) {\n                        cmds.push_back({i, r_choice[i], 'L', b});\n                    }\n                }\n                auto est = simulate(cmds, w_obs, h_obs);\n                Candidate cand{cmds, est.first + est.second};\n                candidates.push_back(move(cand));\n            }\n        }\n\n        // column packings\n        for (long long margin : margins) {\n            vector<long long> h_eff_col(N);\n            for (int i = 0; i < N; i++) h_eff_col[i] = w_rot[i] + margin; // heights become widths\n            for (long long Hlim : Hlims) {\n                if (Hlim < maxH) continue;\n                vector<int> prv = dp_partition(h_rot, h_eff_col, Hlim); // widths -> h_rot, heights -> w_rot\n                if (prv.empty()) continue;\n                vector<pair<int,int>> cols = reconstruct_rows(prv);\n                if (cols.empty()) continue;\n                vector<int> ref_idx(cols.size());\n                for (size_t ci = 0; ci < cols.size(); ci++) {\n                    int l = cols[ci].first;\n                    int r = cols[ci].second;\n                    long long bestw = -1;\n                    int idx = l;\n                    for (int i = l; i < r; i++) {\n                        if (w_rot[i] > bestw || (w_rot[i] == bestw && i > idx)) {\n                            bestw = w_rot[i];\n                            idx = i;\n                        }\n                    }\n                    ref_idx[ci] = idx;\n                }\n                vector<Command> cmds;\n                cmds.reserve(N);\n                for (size_t ci = 0; ci < cols.size(); ci++) {\n                    int b = (ci == 0) ? -1 : ref_idx[ci - 1];\n                    int l = cols[ci].first;\n                    int r = cols[ci].second;\n                    for (int i = l; i < r; i++) {\n                        cmds.push_back({i, r_choice[i], 'U', b});\n                    }\n                }\n                auto est = simulate(cmds, w_obs, h_obs);\n                Candidate cand{cmds, est.first + est.second};\n                candidates.push_back(move(cand));\n            }\n        }\n    };\n\n    for (auto &ori : orientations) {\n        build_candidates_for_orientation(ori);\n    }\n\n    // fallback simple packings\n    {\n        vector<Command> cmds;\n        cmds.reserve(N);\n        for (int i = 0; i < N; i++) cmds.push_back({i, ori_minH[i], 'L', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n    {\n        vector<Command> cmds;\n        cmds.reserve(N);\n        for (int i = 0; i < N; i++) cmds.push_back({i, ori_minW[i], 'U', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    if (candidates.empty()) {\n        vector<Command> cmds;\n        for (int i = 0; i < N; i++) cmds.push_back({i, 0, 'L', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n        return a.estScore < b.estScore;\n    });\n\n    vector<vector<Command>> outputs;\n    int useCnt = min((int)candidates.size(), T);\n    for (int i = 0; i < useCnt; i++) outputs.push_back(candidates[i].cmds);\n    while ((int)outputs.size() < T) outputs.push_back(outputs[0]);\n\n    for (int t = 0; t < T; t++) {\n        const auto& cmds = outputs[t];\n        cout << cmds.size() << \"\\n\";\n        for (auto &cmd : cmds) {\n            cout << cmd.p << \" \" << cmd.r << \" \" << cmd.d << \" \" << cmd.b << \"\\n\";\n        }\n        cout.flush();\n        long long Wm, Hm;\n        if (!(cin >> Wm >> Hm)) break;\n        // ignore measurements in this heuristic\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    vector<int> parent;\n    long long score;\n};\n\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n\n    auto start_time = chrono::steady_clock::now();\n    auto elapsed_ms = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(\n                   chrono::steady_clock::now() - start_time)\n            .count();\n    };\n    const long long TIME_LIMIT = 1900; // ms\n\n    // Precompute all-pairs shortest distances\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    queue<int> q;\n    for (int s = 0; s < N; s++) {\n        auto &drow = dist[s];\n        drow[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            int nd = drow[u] + 1;\n            for (int v : adj[u]) {\n                if (drow[v] == INF) {\n                    drow[v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Eccentricity\n    vector<int> ecc(N, 0);\n    for (int i = 0; i < N; i++) {\n        int mx = 0;\n        for (int j = 0; j < N; j++) {\n            if (dist[i][j] > mx) mx = dist[i][j];\n        }\n        ecc[i] = mx;\n    }\n\n    // Neighbor ordering (descending A)\n    vector<vector<int>> adj_sorted(N);\n    for (int u = 0; u < N; u++) {\n        adj_sorted[u] = adj[u];\n        sort(adj_sorted[u].begin(), adj_sorted[u].end(), [&](int a, int b) {\n            if (A[a] != A[b]) return A[a] > A[b];\n            return a < b;\n        });\n    }\n\n    // Seed selection\n    vector<int> seeds;\n    vector<char> seen_seed(N, 0);\n    auto add_seed = [&](int v) {\n        if (!seen_seed[v]) {\n            seen_seed[v] = 1;\n            seeds.push_back(v);\n        }\n    };\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (A[i] != A[j]) return A[i] < A[j];\n        return i < j;\n    });\n    int kLow = min(15, N);\n    for (int i = 0; i < kLow; i++) add_seed(idx[i]);\n\n    int cen = 0;\n    for (int i = 1; i < N; i++) {\n        if (ecc[i] < ecc[cen] || (ecc[i] == ecc[cen] && A[i] < A[cen]))\n            cen = i;\n    }\n    add_seed(cen);\n\n    long long bestd = (long long)(x[0] - 500) * (x[0] - 500) +\n                      (long long)(y[0] - 500) * (y[0] - 500);\n    int centerCoord = 0;\n    for (int i = 1; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d < bestd) {\n            bestd = d;\n            centerCoord = i;\n        }\n    }\n    add_seed(centerCoord);\n\n    long long maxd = bestd;\n    int farCoord = centerCoord;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d > maxd) {\n            maxd = d;\n            farCoord = i;\n        }\n    }\n    add_seed(farCoord);\n\n    // Random seeds\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> uid(0, N - 1);\n    for (int i = 0; i < 20; i++) {\n        add_seed(uid(rng));\n    }\n\n    auto prune_roots = [&](vector<int> &roots) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int idx_r = 0; idx_r < (int)roots.size(); idx_r++) {\n                vector<int> tmp(N, INF);\n                for (int j = 0; j < (int)roots.size(); j++) {\n                    if (j == idx_r) continue;\n                    int r = roots[j];\n                    for (int i = 0; i < N; i++) {\n                        int d = dist[r][i];\n                        if (d < tmp[i]) tmp[i] = d;\n                    }\n                }\n                int mx = *max_element(tmp.begin(), tmp.end());\n                if (mx <= H) {\n                    roots.erase(roots.begin() + idx_r);\n                    changed = true;\n                    break;\n                }\n            }\n        }\n    };\n\n    auto select_roots_farthest = [&](int seed) {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> minDist = dist[seed];\n        while (true) {\n            int farNode = -1, farDist = -1, farA = 1e9;\n            for (int i = 0; i < N; i++) {\n                if (minDist[i] > farDist ||\n                    (minDist[i] == farDist && A[i] < farA)) {\n                    farDist = minDist[i];\n                    farNode = i;\n                    farA = A[i];\n                }\n            }\n            if (farDist <= H) break;\n            roots.push_back(farNode);\n            for (int i = 0; i < N; i++) {\n                int d = dist[farNode][i];\n                if (d < minDist[i]) minDist[i] = d;\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_cover_greedy = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        while (remaining > 0) {\n            int best = -1, bestCnt = -1, bestA = 1e9;\n            for (int c = 0; c < N; c++) {\n                int cnt = 0;\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[c][i] <= H) cnt++;\n                }\n                if (cnt > bestCnt || (cnt == bestCnt && A[c] < bestA)) {\n                    bestCnt = cnt;\n                    best = c;\n                    bestA = A[c];\n                }\n            }\n            if (best == -1) break;\n            roots.push_back(best);\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[best][i] <= H) {\n                    covered[i] = 1;\n                    remaining--;\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto finalize_and_score = [&](vector<int> &parent) -> Solution {\n        vector<vector<int>> children(N);\n        vector<int> depth(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        // Fix unreachable or over height\n        bool changed = true;\n        int iter = 0;\n        while (changed && iter < 3) {\n            changed = false;\n            iter++;\n            for (int v = 0; v < N; v++) {\n                if (depth[v] == -1 || depth[v] > H) {\n                    parent[v] = -1;\n                    changed = true;\n                }\n            }\n            if (changed) {\n                children.assign(N, {});\n                depth.assign(N, -1);\n                for (int v = 0; v < N; v++) {\n                    int p = parent[v];\n                    if (p >= 0) children[p].push_back(v);\n                }\n                for (int v = 0; v < N; v++) {\n                    if (parent[v] == -1) {\n                        depth[v] = 0;\n                        qq.push(v);\n                    }\n                }\n                while (!qq.empty()) {\n                    int u = qq.front();\n                    qq.pop();\n                    for (int c : children[u]) {\n                        depth[c] = depth[u] + 1;\n                        qq.push(c);\n                    }\n                }\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0) d = H;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    auto leaf_reparent = [&](vector<int> &parent, vector<int> &depth) {\n        vector<int> childCnt(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) childCnt[parent[v]]++;\n        }\n        bool changed = true;\n        int iter = 0;\n        while (changed && iter < H * 2 + 5) {\n            changed = false;\n            iter++;\n            for (int v = 0; v < N; v++) {\n                if (childCnt[v] == 0) {\n                    int bestDepth = depth[v];\n                    int bestPar = -1;\n                    for (int u : adj[v]) {\n                        int nd = depth[u] + 1;\n                        if (nd <= H && nd > bestDepth) {\n                            bestDepth = nd;\n                            bestPar = u;\n                        }\n                    }\n                    if (bestPar != -1 && parent[v] != bestPar) {\n                        int oldp = parent[v];\n                        if (oldp != -1) childCnt[oldp]--;\n                        parent[v] = bestPar;\n                        childCnt[bestPar]++;\n                        depth[v] = bestDepth;\n                        changed = true;\n                    }\n                }\n            }\n        }\n    };\n\n    auto build_solution = [&](const vector<int> &roots, bool useDFS,\n                              int orderMode) -> Solution {\n        vector<int> parent(N, -2), depth(N, INF);\n        vector<char> visited(N, 0);\n        vector<int> root_order = roots;\n        if (orderMode == 0) {\n            sort(root_order.begin(), root_order.end(),\n                 [&](int a, int b) { return A[a] < A[b]; });\n        } else if (orderMode == 1) {\n            sort(root_order.begin(), root_order.end(),\n                 [&](int a, int b) { return A[a] > A[b]; });\n        } else if (orderMode == 2) {\n            shuffle(root_order.begin(), root_order.end(), rng);\n        }\n        if (useDFS) {\n            for (int r : root_order) {\n                if (visited[r]) continue;\n                parent[r] = -1;\n                depth[r] = 0;\n                visited[r] = 1;\n                vector<pair<int, int>> st;\n                st.reserve(N);\n                st.push_back({r, 0});\n                while (!st.empty()) {\n                    int u = st.back().first;\n                    int &idx = st.back().second;\n                    if (depth[u] == H) {\n                        st.pop_back();\n                        continue;\n                    }\n                    if (idx >= (int)adj_sorted[u].size()) {\n                        st.pop_back();\n                        continue;\n                    }\n                    int v = adj_sorted[u][idx++];\n                    if (visited[v]) continue;\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    visited[v] = 1;\n                    st.push_back({v, 0});\n                }\n            }\n            // Cover any remaining unvisited nodes\n            for (int i = 0; i < N; i++) {\n                if (visited[i]) continue;\n                parent[i] = -1;\n                depth[i] = 0;\n                visited[i] = 1;\n                vector<pair<int, int>> st;\n                st.reserve(N);\n                st.push_back({i, 0});\n                while (!st.empty()) {\n                    int u = st.back().first;\n                    int &idx = st.back().second;\n                    if (depth[u] == H) {\n                        st.pop_back();\n                        continue;\n                    }\n                    if (idx >= (int)adj_sorted[u].size()) {\n                        st.pop_back();\n                        continue;\n                    }\n                    int v = adj_sorted[u][idx++];\n                    if (visited[v]) continue;\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    visited[v] = 1;\n                    st.push_back({v, 0});\n                }\n            }\n        } else {\n            queue<int> q2;\n            for (int r : roots) {\n                if (depth[r] == INF) {\n                    depth[r] = 0;\n                    parent[r] = -1;\n                    q2.push(r);\n                }\n            }\n            while (!q2.empty()) {\n                int u = q2.front();\n                q2.pop();\n                int nd = depth[u] + 1;\n                if (nd > H) continue;\n                for (int v : adj[u]) {\n                    if (depth[v] == INF) {\n                        depth[v] = nd;\n                        parent[v] = u;\n                        q2.push(v);\n                    }\n                }\n            }\n            for (int i = 0; i < N; i++) {\n                if (depth[i] == INF) {\n                    parent[i] = -1;\n                    depth[i] = 0;\n                }\n            }\n        }\n\n        leaf_reparent(parent, depth);\n        Solution sol = finalize_and_score(parent);\n        return sol;\n    };\n\n    long long bestScore = -1;\n    vector<int> bestParent(N, -1);\n\n    vector<vector<int>> rootSets;\n    for (int sd : seeds) {\n        rootSets.push_back(select_roots_farthest(sd));\n    }\n    rootSets.push_back(select_roots_cover_greedy());\n\n    for (size_t ri = 0; ri < rootSets.size(); ri++) {\n        if (elapsed_ms() > TIME_LIMIT) break;\n        const auto &roots = rootSets[ri];\n        Solution sol_bfs = build_solution(roots, false, 0);\n        if (sol_bfs.score > bestScore) {\n            bestScore = sol_bfs.score;\n            bestParent = sol_bfs.parent;\n        }\n        Solution sol_dfs1 = build_solution(roots, true, 0);\n        if (sol_dfs1.score > bestScore) {\n            bestScore = sol_dfs1.score;\n            bestParent = sol_dfs1.parent;\n        }\n        if (elapsed_ms() > TIME_LIMIT) break;\n        Solution sol_dfs2 = build_solution(roots, true, 1);\n        if (sol_dfs2.score > bestScore) {\n            bestScore = sol_dfs2.score;\n            bestParent = sol_dfs2.parent;\n        }\n        // One random root order DFS for diversity\n        Solution sol_dfs3 = build_solution(roots, true, 2);\n        if (sol_dfs3.score > bestScore) {\n            bestScore = sol_dfs3.score;\n            bestParent = sol_dfs3.parent;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option {\n    int line; // 0..4N-1\n    int len;  // 1..N\n};\n\nstruct Solver {\n    static const int N = 20;\n    vector<string> board;\n    vector<int> upLim, downLim, leftLim, rightLim;\n    vector<pair<int,int>> oni;               // positions of oni\n    vector<vector<Option>> opts;             // options for each oni\n    int M;                                   // #oni\n\n    // state\n    vector<array<int, N+1>> cnt; // cnt[line][len]\n    vector<int> maxLen;          // max len per line\n    vector<int> assign;          // chosen option index per oni\n    long cost;                   // 2 * sum(maxLen)\n\n    mt19937 rng;\n\n    Solver(const vector<string>& g): board(g) {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n        compute_limits();\n        collect_oni();\n        build_options();\n    }\n\n    void compute_limits() {\n        upLim.assign(N, N);\n        downLim.assign(N, N);\n        leftLim.assign(N, N);\n        rightLim.assign(N, N);\n        // columns\n        for (int j = 0; j < N; j++) {\n            for (int i = 0; i < N; i++) {\n                if (board[i][j] == 'o') { upLim[j] = i; break; }\n            }\n            for (int i = N-1; i >= 0; i--) {\n                if (board[i][j] == 'o') { downLim[j] = N-1 - i; break; }\n            }\n        }\n        // rows\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'o') { leftLim[i] = j; break; }\n            }\n            for (int j = N-1; j >= 0; j--) {\n                if (board[i][j] == 'o') { rightLim[i] = N-1 - j; break; }\n            }\n        }\n    }\n\n    void collect_oni() {\n        oni.clear();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') oni.emplace_back(i,j);\n            }\n        }\n        M = (int)oni.size();\n    }\n\n    void build_options() {\n        opts.assign(M, {});\n        for (int idx = 0; idx < M; idx++) {\n            auto [r,c] = oni[idx];\n            // Up\n            if (r+1 <= upLim[c]) {\n                opts[idx].push_back({c, r+1});\n            }\n            // Down\n            if (N - r <= downLim[c]) {\n                opts[idx].push_back({N + c, N - r});\n            }\n            // Left\n            if (c+1 <= leftLim[r]) {\n                opts[idx].push_back({2*N + r, c+1});\n            }\n            // Right\n            if (N - c <= rightLim[r]) {\n                opts[idx].push_back({3*N + r, N - c});\n            }\n            if (opts[idx].empty()) {\n                // Should not happen\n                opts[idx].push_back({c, r+1}); // dummy\n            }\n        }\n    }\n\n    void rebuild_from_assign() {\n        cnt.assign(4*N, {});\n        maxLen.assign(4*N, 0);\n        cost = 0;\n        for (int i = 0; i < M; i++) {\n            int optIdx = assign[i];\n            const Option &op = opts[i][optIdx];\n            cnt[op.line][op.len] ++;\n            if (op.len > maxLen[op.line]) maxLen[op.line] = op.len;\n        }\n        for (int l = 0; l < 4*N; l++) {\n            cost += 2LL * maxLen[l];\n        }\n    }\n\n    // helpers for delta computation\n    int newMaxAfterRemoval(int line, int len) const {\n        int oldMax = maxLen[line];\n        if (len < oldMax) return oldMax;\n        if (cnt[line][len] >= 2) return oldMax;\n        // len == oldMax and will be removed\n        for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) return l;\n        return 0;\n    }\n\n    int computeDelta(int i, int newOpt) const {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return 0;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        if (cur.line == nxt.line) {\n            int line = cur.line;\n            int oldMax = maxLen[line];\n            int newMax = oldMax;\n            if (cur.len == oldMax && cnt[line][cur.len] == 1) {\n                newMax = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[line][l] > 0) {newMax=l; break;}\n            }\n            if (nxt.len > newMax) newMax = nxt.len;\n            return 2 * (newMax - oldMax);\n        } else {\n            int oldMaxA = maxLen[cur.line];\n            int oldMaxB = maxLen[nxt.line];\n            int newMaxA = oldMaxA;\n            if (cur.len == oldMaxA && cnt[cur.line][cur.len] == 1) {\n                newMaxA = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[cur.line][l] > 0) {newMaxA=l; break;}\n            }\n            int newMaxB = (nxt.len > oldMaxB) ? nxt.len : oldMaxB;\n            return 2 * ((newMaxA - oldMaxA) + (newMaxB - oldMaxB));\n        }\n    }\n\n    void remove_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]--;\n        if (len == oldMax && cnt[line][len] == 0) {\n            int m = 0;\n            for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) {m = l; break;}\n            maxLen[line] = m;\n        }\n        cost += 2LL * maxLen[line];\n    }\n\n    void add_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]++;\n        if (len > oldMax) maxLen[line] = len;\n        cost += 2LL * maxLen[line];\n    }\n\n    void applyMove(int i, int newOpt) {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        remove_assignment(cur.line, cur.len);\n        add_assignment(nxt.line, nxt.len);\n        assign[i] = newOpt;\n    }\n\n    void hillClimb() {\n        while (true) {\n            int bestDelta = 0;\n            int bestI = -1;\n            int bestOpt = -1;\n            for (int i = 0; i < M; i++) {\n                int curOpt = assign[i];\n                for (int k = 0; k < (int)opts[i].size(); k++) {\n                    if (k == curOpt) continue;\n                    int delta = computeDelta(i, k);\n                    if (delta < bestDelta) {\n                        bestDelta = delta;\n                        bestI = i;\n                        bestOpt = k;\n                    }\n                }\n            }\n            if (bestDelta < 0) {\n                applyMove(bestI, bestOpt);\n            } else break;\n        }\n    }\n\n    void simulatedAnnealing(int ITER, double T0, double T1) {\n        vector<int> bestAssignLocal = assign;\n        long bestCostLocal = cost;\n        uniform_real_distribution<double> dist01(0.0, 1.0);\n        for (int it = 0; it < ITER; it++) {\n            double T = T0 + (T1 - T0) * (double)it / (double)ITER;\n            int i = rng() % M;\n            if (opts[i].size() <= 1) continue;\n            int newOpt = rng() % opts[i].size();\n            if (newOpt == assign[i]) continue;\n            int delta = computeDelta(i, newOpt);\n            if (delta <= 0 || exp(-delta / T) > dist01(rng)) {\n                applyMove(i, newOpt);\n                if (cost < bestCostLocal) {\n                    bestCostLocal = cost;\n                    bestAssignLocal = assign;\n                }\n            }\n        }\n        assign = bestAssignLocal;\n        rebuild_from_assign();\n    }\n\n    // Large neighborhood search: reassign a subset exhaustively\n    bool lns_once(int k) {\n        if (M == 0) return false;\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        // sort by current required length descending\n        sort(idx.begin(), idx.end(), [&](int a, int b){\n            int lena = opts[a][assign[a]].len;\n            int lenb = opts[b][assign[b]].len;\n            return lena > lenb;\n        });\n        int candSize = min(M, 10);\n        if (candSize < k) k = candSize;\n        if (k == 0) return false;\n        // choose first candSize then shuffle\n        vector<int> cands(idx.begin(), idx.begin() + candSize);\n        shuffle(cands.begin(), cands.end(), rng);\n        vector<int> subset(cands.begin(), cands.begin() + k);\n\n        vector<int> backupAssign = assign;\n        long originalCost = cost;\n\n        // remove subset assignments\n        for (int id : subset) {\n            const Option &op = opts[id][assign[id]];\n            remove_assignment(op.line, op.len);\n            assign[id] = -1;\n        }\n        long baseCost = cost;\n\n        vector<int> bestChoices(k, 0);\n        long bestCost = (1LL<<60);\n\n        function<void(int)> dfs = [&](int depth){\n            if (depth == k) {\n                if (cost < bestCost) {\n                    bestCost = cost;\n                    for (int t = 0; t < k; t++) {\n                        bestChoices[t] = assign[subset[t]];\n                    }\n                }\n                return;\n            }\n            int oniId = subset[depth];\n            for (int optIdx = 0; optIdx < (int)opts[oniId].size(); optIdx++) {\n                const Option &op = opts[oniId][optIdx];\n                add_assignment(op.line, op.len);\n                assign[oniId] = optIdx;\n                dfs(depth+1);\n                remove_assignment(op.line, op.len);\n                assign[oniId] = -1;\n            }\n        };\n        dfs(0);\n\n        // restore assignment based on result\n        if (bestCost < originalCost) {\n            assign = backupAssign;\n            for (int t = 0; t < k; t++) {\n                assign[subset[t]] = bestChoices[t];\n            }\n            rebuild_from_assign();\n            return true;\n        } else {\n            assign = backupAssign;\n            rebuild_from_assign();\n            return false;\n        }\n    }\n\n    void solve() {\n        int NUM_SEEDS = 8;\n        int SA_ITER = 40000;\n        double T0 = 5.0, T1 = 0.1;\n        int LNS_TRIES = 60;\n        int LNS_K = 5;\n\n        long globalBestCost = (1LL<<60);\n        vector<int> globalBestAssign;\n        vector<int> globalBestMaxLen;\n\n        uniform_int_distribution<int> seedDist(0, 1e9);\n\n        for (int seed = 0; seed < NUM_SEEDS; seed++) {\n            // initial assignment\n            assign.assign(M, 0);\n            for (int i = 0; i < M; i++) {\n                if (seed == 0) {\n                    // choose minimal len (tie random)\n                    int bestLen = 1e9;\n                    vector<int> cand;\n                    for (int k = 0; k < (int)opts[i].size(); k++) {\n                        int len = opts[i][k].len;\n                        if (len < bestLen) {\n                            bestLen = len;\n                            cand.clear();\n                            cand.push_back(k);\n                        } else if (len == bestLen) {\n                            cand.push_back(k);\n                        }\n                    }\n                    assign[i] = cand[rng() % cand.size()];\n                } else {\n                    assign[i] = rng() % opts[i].size();\n                }\n            }\n            rebuild_from_assign();\n            hillClimb();\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n\n            simulatedAnnealing(SA_ITER, T0, T1);\n            hillClimb();\n\n            bool improved = true;\n            int tries = 0;\n            while (improved && tries < LNS_TRIES) {\n                improved = lns_once(LNS_K);\n                tries++;\n            }\n\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n        }\n\n        // use global best\n        assign = globalBestAssign;\n        maxLen = globalBestMaxLen;\n        // output operations\n        vector<pair<char,int>> ops;\n        auto add_ops = [&](char dir, int idx, int len){\n            for (int k = 0; k < len; k++) ops.emplace_back(dir, idx);\n        };\n        // Up then Down for up lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[j];\n            if (len > 0) {\n                add_ops('U', j, len);\n                add_ops('D', j, len);\n            }\n        }\n        // Down then Up for down lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[N + j];\n            if (len > 0) {\n                add_ops('D', j, len);\n                add_ops('U', j, len);\n            }\n        }\n        // Left then Right\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[2*N + i];\n            if (len > 0) {\n                add_ops('L', i, len);\n                add_ops('R', i, len);\n            }\n        }\n        // Right then Left\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[3*N + i];\n            if (len > 0) {\n                add_ops('R', i, len);\n                add_ops('L', i, len);\n            }\n        }\n\n        for (auto &op : ops) {\n            cout << op.first << \" \" << op.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n;\n    if (!(cin >> n)) return 0;\n    vector<string> g(n);\n    for (int i = 0; i < n; i++) cin >> g[i];\n    Solver solver(g);\n    solver.solve();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift {\n    using result_type = uint64_t;\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return UINT64_MAX; }\n    result_type operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint64_t next() { return (*this)(); }\n    int next_int(int l, int r) { return l + (int)(next() % (uint64_t)(r - l + 1)); }\n};\n\nint N, Ltot;\nvector<int> T;\nvector<double> desiredEdges;\nvector<long long> prefixT;\nXorShift rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\nint rand_by_target() {\n    uint64_t r = rng.next() % (uint64_t)Ltot;\n    int idx = int(lower_bound(prefixT.begin(), prefixT.end(), (long long)r + 1) - prefixT.begin());\n    if (idx >= N) idx = N - 1;\n    return idx;\n}\n\n// compute indegree distribution summing to edges=2*N\nvoid compute_degrees(int minMode, vector<int>& deg) {\n    int edges = 2 * N;\n    deg.assign(N, 0);\n    int minSum = 0;\n    for (int i = 0; i < N; i++) {\n        int minv = 0;\n        if (minMode == 1) {\n            if (T[i] > 0) minv = 1;\n        } else if (minMode == 2) {\n            minv = 1;\n        }\n        deg[i] = minv;\n        minSum += minv;\n    }\n    int R = edges - minSum;\n    static double quota[105];\n    double quotaSum = 0.0;\n    for (int i = 0; i < N; i++) {\n        double q = desiredEdges[i] - deg[i];\n        if (q < 0) q = 0;\n        quota[i] = q;\n        quotaSum += q;\n    }\n    static pair<double, int> fracs[105];\n    int sumDeg = minSum;\n    if (quotaSum > 1e-9) {\n        double scale = (double)R / quotaSum;\n        for (int i = 0; i < N; i++) {\n            double v = quota[i] * scale;\n            int add = (int)v;\n            deg[i] += add;\n            sumDeg += add;\n            fracs[i] = make_pair(v - add, i);\n        }\n    } else {\n        for (int i = 0; i < N; i++) fracs[i] = make_pair(0.0, i);\n    }\n    int leftover = edges - sumDeg;\n    // shuffle fracs for random tie-breaking\n    for (int i = N - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(fracs[i], fracs[j]);\n    }\n    sort(fracs, fracs + N, [](const pair<double, int>& a, const pair<double, int>& b) {\n        return a.first > b.first;\n    });\n    for (int k = 0; k < leftover; k++) {\n        deg[fracs[k].second]++;\n    }\n}\n\n// simulate plan exactly, optional output counts\nlong long simulate(const vector<int>& a, const vector<int>& b, vector<int>* outCnt = nullptr) {\n    static int cnt[105];\n    for (int i = 0; i < N; i++) cnt[i] = 0;\n    int cur = 0;\n    for (int step = 0; step < Ltot; step++) {\n        int c = ++cnt[cur];\n        cur = (c & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)cnt[i] - (long long)T[i];\n        err += d >= 0 ? d : -d;\n    }\n    if (outCnt) outCnt->assign(cnt, cnt + N);\n    return err;\n}\n\n// approximate stationary distribution via power iteration, return approximate error\ndouble approx_error(const vector<int>& a, const vector<int>& b, vector<double>* outCounts = nullptr) {\n    static double d0[105], d1[105];\n    double inv = 1.0 / N;\n    for (int i = 0; i < N; i++) d0[i] = inv;\n    double* cur = d0;\n    double* nxt = d1;\n    const int ITER = 50;\n    for (int it = 0; it < ITER; it++) {\n        for (int j = 0; j < N; j++) nxt[j] = 0.0;\n        for (int i = 0; i < N; i++) {\n            double v = cur[i];\n            int ai = a[i], bi = b[i];\n            if (ai == bi) {\n                nxt[ai] += v;\n            } else {\n                double h = 0.5 * v;\n                nxt[ai] += h;\n                nxt[bi] += h;\n            }\n        }\n        swap(cur, nxt);\n    }\n    double err = 0.0;\n    if (outCounts) outCounts->assign(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        double c = cur[i] * Ltot;\n        if (outCounts) (*outCounts)[i] = c;\n        err += fabs(c - (double)T[i]);\n    }\n    return err;\n}\n\nstruct Candidate {\n    double approxErr;\n    vector<int> a, b;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> Ltot)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    desiredEdges.resize(N);\n    for (int i = 0; i < N; i++) {\n        desiredEdges[i] = (double)T[i] * (2.0 * N) / (double)Ltot;\n    }\n    prefixT.resize(N);\n    long long acc = 0;\n    for (int i = 0; i < N; i++) {\n        acc += T[i];\n        prefixT[i] = acc;\n    }\n    // top target nodes\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return T[i] > T[j]; });\n    int top1 = idx[0], top2 = idx[1];\n\n    vector<int> bestA(N), bestB(N);\n    long long bestActualErr = (1LL << 60);\n    vector<int> bestActualCnt(N);\n\n    vector<int> candA(N), candB(N);\n    vector<int> deg;\n    vector<int> slots;\n\n    // initial candidate using target distribution rows\n    for (int i = 0; i < N; i++) {\n        candA[i] = rand_by_target();\n        candB[i] = rand_by_target();\n    }\n    double candApprox = approx_error(candA, candB);\n    bestA = candA;\n    bestB = candB;\n\n    vector<double> bestApproxCounts;\n    double bestApproxErr = candApprox;\n    approx_error(bestA, bestB, &bestApproxCounts);\n    // top candidates list\n    const int TOPK = 12;\n    vector<Candidate> topList;\n    topList.push_back({candApprox, bestA, bestB});\n\n    auto updateTop = [&](const vector<int>& a, const vector<int>& b, double err) {\n        topList.push_back({err, a, b});\n        nth_element(topList.begin(), topList.begin() + min(TOPK, (int)topList.size()) - 1, topList.end(),\n                    [](const Candidate& x, const Candidate& y) { return x.approxErr < y.approxErr; });\n        if ((int)topList.size() > TOPK) topList.resize(TOPK);\n    };\n\n    // main loop\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.82;\n    int iter = 0;\n    while (true) {\n        iter++;\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > TIME_LIMIT) break;\n        int mode = rng.next_int(0, 9);\n        switch (mode) {\n            case 0: { // rows by target distribution\n                for (int i = 0; i < N; i++) {\n                    candA[i] = rand_by_target();\n                    candB[i] = rand_by_target();\n                }\n                break;\n            }\n            case 1: { // apportionment min0\n                compute_degrees(0, deg);\n                slots.clear();\n                for (int i = 0; i < N; i++) for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n                while ((int)slots.size() < 2 * N) slots.push_back(rand_by_target());\n                while ((int)slots.size() > 2 * N) slots.pop_back();\n                for (int i = (int)slots.size() - 1; i > 0; --i) {\n                    int j = rng.next() % (uint64_t)(i + 1);\n                    swap(slots[i], slots[j]);\n                }\n                for (int i = 0; i < N; i++) {\n                    candA[i] = slots[2 * i];\n                    candB[i] = slots[2 * i + 1];\n                }\n                break;\n            }\n            case 2: { // apportionment min1\n                compute_degrees(1, deg);\n                slots.clear();\n                for (int i = 0; i < N; i++) for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n                while ((int)slots.size() < 2 * N) slots.push_back(rand_by_target());\n                while ((int)slots.size() > 2 * N) slots.pop_back();\n                for (int i = (int)slots.size() - 1; i > 0; --i) {\n                    int j = rng.next() % (uint64_t)(i + 1);\n                    swap(slots[i], slots[j]);\n                }\n                for (int i = 0; i < N; i++) {\n                    candA[i] = slots[2 * i];\n                    candB[i] = slots[2 * i + 1];\n                }\n                break;\n            }\n            case 3: { // apportionment min2\n                compute_degrees(2, deg);\n                slots.clear();\n                for (int i = 0; i < N; i++) for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n                while ((int)slots.size() < 2 * N) slots.push_back(rand_by_target());\n                while ((int)slots.size() > 2 * N) slots.pop_back();\n                for (int i = (int)slots.size() - 1; i > 0; --i) {\n                    int j = rng.next() % (uint64_t)(i + 1);\n                    swap(slots[i], slots[j]);\n                }\n                for (int i = 0; i < N; i++) {\n                    candA[i] = slots[2 * i];\n                    candB[i] = slots[2 * i + 1];\n                }\n                break;\n            }\n            case 4: { // cycle + target\n                for (int i = 0; i < N; i++) {\n                    candA[i] = (i + 1) % N;\n                    candB[i] = rand_by_target();\n                }\n                break;\n            }\n            case 5: { // both edges same sampled by target\n                for (int i = 0; i < N; i++) {\n                    int v = rand_by_target();\n                    candA[i] = v;\n                    candB[i] = v;\n                }\n                break;\n            }\n            case 6: { // self-loop top nodes\n                for (int i = 0; i < N; i++) {\n                    if (i < 10 || T[i] == 0) {\n                        candA[idx[i]] = idx[i];\n                        candB[idx[i]] = idx[i];\n                    }\n                }\n                for (int i = 0; i < N; i++) {\n                    if (candA[i] != i || candB[i] != i) {\n                        candA[i] = rand_by_target();\n                        candB[i] = rand_by_target();\n                    }\n                }\n                break;\n            }\n            case 7: { // uniform random edges\n                for (int i = 0; i < N; i++) {\n                    candA[i] = rng.next_int(0, N - 1);\n                    candB[i] = rng.next_int(0, N - 1);\n                }\n                break;\n            }\n            case 8: { // two top nodes\n                for (int i = 0; i < N; i++) {\n                    candA[i] = top1;\n                    candB[i] = top2;\n                }\n                break;\n            }\n            case 9: { // mutation from best approx\n                if (bestApproxErr < 1e18) {\n                    candA = bestA;\n                    candB = bestB;\n                    // compute diff using bestApproxCounts\n                    double totalPos = 0, totalNeg = 0;\n                    static double diff[105];\n                    for (int i = 0; i < N; i++) {\n                        diff[i] = bestApproxCounts[i] - (double)T[i];\n                        if (diff[i] > 0) totalPos += diff[i];\n                        else totalNeg += -diff[i];\n                    }\n                    int changes = 1 + (rng.next() & 1);\n                    for (int c = 0; c < changes; c++) {\n                        int under = rng.next_int(0, N - 1);\n                        int over = rng.next_int(0, N - 1);\n                        if (totalNeg > 1e-9) {\n                            double r = (double)(rng.next()) / (double)UINT64_MAX * totalNeg;\n                            double accn = 0;\n                            for (int i = 0; i < N; i++) {\n                                if (diff[i] < 0) {\n                                    accn += -diff[i];\n                                    if (accn >= r) {\n                                        under = i;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                        if (totalPos > 1e-9) {\n                            double r = (double)(rng.next()) / (double)UINT64_MAX * totalPos;\n                            double accp = 0;\n                            for (int i = 0; i < N; i++) {\n                                if (diff[i] > 0) {\n                                    accp += diff[i];\n                                    if (accp >= r) {\n                                        over = i;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                        int sFound = -1, edgeIdx = 0;\n                        int start = rng.next_int(0, N - 1);\n                        for (int k = 0; k < N; k++) {\n                            int i = (start + k) % N;\n                            if (candA[i] == over) {\n                                sFound = i;\n                                edgeIdx = 0;\n                                break;\n                            }\n                            if (candB[i] == over) {\n                                sFound = i;\n                                edgeIdx = 1;\n                                break;\n                            }\n                        }\n                        if (sFound == -1) {\n                            sFound = rng.next_int(0, N - 1);\n                            edgeIdx = rng.next_int(0, 1);\n                        }\n                        if (edgeIdx == 0) candA[sFound] = under;\n                        else candB[sFound] = under;\n                    }\n                } else {\n                    for (int i = 0; i < N; i++) {\n                        candA[i] = rand_by_target();\n                        candB[i] = rand_by_target();\n                    }\n                }\n                break;\n            }\n        } // end switch\n        double aerr = approx_error(candA, candB);\n        updateTop(candA, candB, aerr);\n        if (aerr < bestApproxErr) {\n            bestApproxErr = aerr;\n            bestA = candA;\n            bestB = candB;\n            approx_error(bestA, bestB, &bestApproxCounts);\n        }\n    }\n\n    // evaluate actual for top candidates\n    for (auto& c : topList) {\n        vector<int> cnt;\n        long long e = simulate(c.a, c.b, &cnt);\n        if (e < bestActualErr) {\n            bestActualErr = e;\n            bestA = c.a;\n            bestB = c.b;\n            bestActualCnt = cnt;\n        }\n    }\n\n    // output best plan\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << ' ' << bestB[i] << '\\n';\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// \u4e71\u6570\u751f\u6210\uff08XorShift\uff09\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    inline uint64_t rng() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int randint(int l, int r) { // [l, r)\n        return (int)(rng() % (uint64_t)(r - l)) + l;\n    }\n    inline double rand01() {\n        return (double)(rng() & 0xFFFFFFFFULL) / 4294967296.0;\n    }\n} xor128;\n\n// \u30d2\u30eb\u30d9\u30eb\u30c8\u66f2\u7dda\u30aa\u30fc\u30c0\u30fc\nuint64_t hilbertOrder(int x, int y, int order_bits, int max_coord) {\n    uint64_t d = 0;\n    for (int s = order_bits - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        d <<= 2;\n        d |= (uint64_t)((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) {\n                x = max_coord - x;\n                y = max_coord - y;\n            }\n            int t = x;\n            x = y;\n            y = t;\n        }\n    }\n    return d;\n}\n\n// Prim \u306b\u3088\u308b MST \u30b3\u30b9\u30c8\u8a08\u7b97\uff08\u5ea7\u6a19\u306f\u4e88\u6e2c\u5024\uff09\ndouble primCost(const vector<int>& nodes, const vector<double>& px, const vector<double>& py) {\n    int n = (int)nodes.size();\n    if (n <= 1) return 0.0;\n    vector<double> minD(n, 1e100);\n    vector<char> used(n, 0);\n    minD[0] = 0.0;\n    double cost = 0.0;\n    for (int iter = 0; iter < n; ++iter) {\n        int v = -1;\n        double best = 1e100;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        cost += minD[v];\n        int idv = nodes[v];\n        double xv = px[idv], yv = py[idv];\n        for (int i = 0; i < n; ++i) if (!used[i]) {\n            int idu = nodes[i];\n            double dx = xv - px[idu];\n            double dy = yv - py[idu];\n            double dist = std::sqrt(dx * dx + dy * dy);\n            if (dist < minD[i]) {\n                minD[i] = dist;\n            }\n        }\n    }\n    return cost;\n}\n\n// Prim \u306b\u3088\u308b MST \u8fba\u53d6\u5f97\uff08\u4e88\u6e2c\u5ea7\u6a19\u3092\u4f7f\u3046\uff09\nvector<pair<int, int>> primEdges(const vector<int>& nodes, const vector<double>& px, const vector<double>& py) {\n    int n = (int)nodes.size();\n    if (n <= 1) return {};\n    vector<double> minD(n, 1e100);\n    vector<int> parent(n, -1);\n    vector<char> used(n, 0);\n    minD[0] = 0.0;\n    for (int iter = 0; iter < n; ++iter) {\n        int v = -1;\n        double best = 1e100;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        int idv = nodes[v];\n        double xv = px[idv], yv = py[idv];\n        for (int i = 0; i < n; ++i) if (!used[i]) {\n            int idu = nodes[i];\n            double dx = xv - px[idu];\n            double dy = yv - py[idu];\n            double dist = std::sqrt(dx * dx + dy * dy);\n            if (dist < minD[i]) {\n                minD[i] = dist;\n                parent[i] = v;\n            }\n        }\n    }\n    vector<pair<int, int>> edges;\n    edges.reserve(n - 1);\n    for (int i = 1; i < n; ++i) {\n        edges.emplace_back(nodes[i], nodes[parent[i]]);\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    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n\n    vector<double> px(N), py(N);\n    for (int i = 0; i < N; ++i) {\n        px[i] = (lx[i] + rx[i]) * 0.5;\n        py[i] = (ly[i] + ry[i]) * 0.5;\n    }\n\n    const int order_bits = 15;\n    const int max_coord = (1 << order_bits) - 1;\n\n    vector<vector<int>> candidates;\n\n    // Hilbert variants\n    for (int variant = 0; variant < 5; ++variant) {\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            int x = (int)px[i];\n            int y = (int)py[i];\n            switch (variant) {\n                case 0: break;\n                case 1: x = max_coord - x; break;\n                case 2: y = max_coord - y; break;\n                case 3: x = max_coord - x; y = max_coord - y; break;\n                case 4: { int t = x; x = y; y = t; } break;\n            }\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b) { return a.first < b.first; });\n        vector<int> order;\n        order.reserve(N);\n        for (auto& p : keys) order.push_back(p.second);\n        candidates.push_back(move(order));\n    }\n    // Simple sorts\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (px[a] == px[b]) return py[a] < py[b];\n            return px[a] < px[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (py[a] == py[b]) return px[a] < px[b];\n            return py[a] < py[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] + py[a];\n            double vb = px[b] + py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] - py[a];\n            double vb = px[b] - py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n\n    // Evaluate candidates using predicted MST costs\n    auto evalCost = [&](const vector<int>& order) -> double {\n        double total = 0.0;\n        int pos = 0;\n        for (int k = 0; k < M; ++k) {\n            int g = G[k];\n            vector<int> group;\n            group.reserve(g);\n            for (int t = 0; t < g; ++t) group.push_back(order[pos + t]);\n            pos += g;\n            total += primCost(group, px, py);\n        }\n        return total;\n    };\n\n    double bestInitCost = 1e100;\n    int bestIdx = 0;\n    for (int idx = 0; idx < (int)candidates.size(); ++idx) {\n        double c = evalCost(candidates[idx]);\n        if (c < bestInitCost) {\n            bestInitCost = c;\n            bestIdx = idx;\n        }\n    }\n    const vector<int>& bestOrder = candidates[bestIdx];\n\n    // \u521d\u671f\u30b0\u30eb\u30fc\u30d7\u5272\u5f53\uff08\u9806\u5e8f\u306e\u9023\u7d9a\u533a\u9593\uff09\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int k = 0; k < M; ++k) {\n        int g = G[k];\n        groups[k].reserve(g);\n        for (int t = 0; t < g; ++t) groups[k].push_back(bestOrder[pos + t]);\n        pos += g;\n    }\n\n    // \u6240\u5c5e\u914d\u5217\n    vector<int> belong(N, -1);\n    for (int k = 0; k < M; ++k) {\n        for (int v : groups[k]) belong[v] = k;\n    }\n\n    // \u5404\u30b0\u30eb\u30fc\u30d7\u306e\u4e88\u6e2c\u30b3\u30b9\u30c8\n    vector<double> groupCost(M, 0.0);\n    double totalCost = 0.0;\n    for (int k = 0; k < M; ++k) {\n        double c = primCost(groups[k], px, py);\n        groupCost[k] = c;\n        totalCost += c;\n    }\n\n    // \u5c71\u767b\u308a\uff08\u30e9\u30f3\u30c0\u30e0\u30b9\u30ef\u30c3\u30d7\u3067\u6539\u5584\uff09\n    vector<vector<int>> bestGroups = groups;\n    double bestCost = totalCost;\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 0.8; // \u79d2\n\n    int maxGroupSize = *max_element(G.begin(), G.end());\n    if (maxGroupSize > 200) timeLimit = 0.3; // \u5927\u304d\u3044\u5834\u5408\u306f\u77ed\u7e2e\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > timeLimit) break;\n\n        if (M <= 1) break;\n        int ga = xor128.randint(0, M);\n        int gb = xor128.randint(0, M);\n        if (ga == gb) continue;\n        if (groups[ga].empty() || groups[gb].empty()) continue;\n        int ia = xor128.randint(0, (int)groups[ga].size());\n        int ib = xor128.randint(0, (int)groups[gb].size());\n        int va = groups[ga][ia];\n        int vb = groups[gb][ib];\n\n        // swap\n        groups[ga][ia] = vb;\n        groups[gb][ib] = va;\n\n        double oldSum = groupCost[ga] + groupCost[gb];\n        double newCostA = primCost(groups[ga], px, py);\n        double newCostB = primCost(groups[gb], px, py);\n        double newSum = newCostA + newCostB;\n\n        if (newSum < oldSum) {\n            // accept\n            groupCost[ga] = newCostA;\n            groupCost[gb] = newCostB;\n            totalCost += (newSum - oldSum);\n            belong[va] = gb;\n            belong[vb] = ga;\n            if (totalCost < bestCost) {\n                bestCost = totalCost;\n                bestGroups = groups;\n            }\n        } else {\n            // reject, revert\n            groups[ga][ia] = va;\n            groups[gb][ib] = vb;\n        }\n    }\n\n    // best assignment\n    groups.swap(bestGroups);\n\n    // \u30af\u30a8\u30ea\u3092\u4f7f\u7528\u3057\u3066\u5c0f\u3055\u3044\u30b0\u30eb\u30fc\u30d7\u306e\u771f\u306e MST \u8fba\u3092\u53d6\u5f97\n    vector<vector<pair<int, int>>> edges(M);\n    int queries_used = 0;\n    for (int k = 0; k < M; ++k) {\n        int sz = (int)groups[k].size();\n        if (sz >= 2 && sz <= L && queries_used < Q) {\n            cout << \"? \" << sz;\n            for (int v : groups[k]) cout << ' ' << v;\n            cout << endl;\n            queries_used++;\n            edges[k].clear();\n            for (int i = 0; i < sz - 1; ++i) {\n                int a, b;\n                if (!(cin >> a >> b)) {\n                    return 0;\n                }\n                edges[k].emplace_back(a, b);\n            }\n        }\n    }\n\n    // \u6b8b\u308a\u306e\u30b0\u30eb\u30fc\u30d7\u306f\u4e88\u6e2c\u5ea7\u6a19\u3067 MST \u8fba\u3092\u69cb\u7bc9\n    for (int k = 0; k < M; ++k) {\n        if (!edges[k].empty() || groups[k].size() <= 1) continue;\n        edges[k] = primEdges(groups[k], px, py);\n    }\n\n    // \u51fa\u529b\n    cout << \"!\\n\";\n    for (int k = 0; k < M; ++k) {\n        int sz = (int)groups[k].size();\n        for (int i = 0; i < sz; ++i) {\n            if (i) cout << ' ';\n            cout << groups[k][i];\n        }\n        cout << '\\n';\n        for (auto &e : edges[k]) {\n            cout << e.first << ' ' << e.second << '\\n';\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1e9;\n\nint N, M;\nvector<int> idxs; // linear indices of positions P[k]\nvector<pair<int, int>> pos; // coordinates of positions P[k]\nvector<int> dr = {-1, 1, 0, 0};\nvector<int> dc = {0, 0, -1, 1};\nvector<char> dirChar = {'U', 'D', 'L', 'R'};\n\n// slide from (r,c) in dir until before a block/boundary\ninline int slide_stop(int r, int c, int dir, const vector<char> &blocked) {\n    int nr = r, nc = c;\n    while (true) {\n        int tr = nr + dr[dir], tc = nc + dc[dir];\n        if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n        if (blocked[tr * N + tc]) break;\n        nr = tr; nc = tc;\n    }\n    return nr * N + nc;\n}\n\n// shortest distance between s and g with moves/slides, static blocks\nint dist_between(int s, int g, const vector<char> &blocked) {\n    if (blocked[s] || blocked[g]) return INF;\n    static vector<int> dist;\n    static queue<int> q;\n    dist.assign(N * N, -1);\n    while (!q.empty()) q.pop();\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == g) return dist[v];\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = dist[v] + 1;\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = dist[v] + 1;\n                q.push(sid);\n            }\n        }\n    }\n    return INF;\n}\n\n// reconstruct path actions between s and g with static blocks\nvector<pair<char, char>> path_between(int s, int g, const vector<char> &blocked) {\n    vector<int> dist(N * N, -1), prev(N * N, -1);\n    vector<char> prevAct(N * N), prevDir(N * N);\n    queue<int> q;\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (v == g) break;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'M';\n                    prevDir[ni] = dirChar[dir];\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = dist[v] + 1;\n                prev[sid] = v;\n                prevAct[sid] = 'S';\n                prevDir[sid] = dirChar[dir];\n                q.push(sid);\n            }\n        }\n    }\n    vector<pair<char, char>> actions;\n    if (dist[g] == -1) return actions;\n    int cur = g;\n    while (cur != s) {\n        actions.push_back({prevAct[cur], prevDir[cur]});\n        cur = prev[cur];\n    }\n    reverse(actions.begin(), actions.end());\n    return actions;\n}\n\n// compute remaining cost from index t (position idxs[t]) to end with current blocks\nint remaining_cost(int t, const vector<char> &blocked) {\n    int sum = 0;\n    for (int k = t; k < M - 1; k++) {\n        int d = dist_between(idxs[k], idxs[k + 1], blocked);\n        if (d >= INF / 2) return INF;\n        sum += d;\n    }\n    return sum;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> M)) return 0;\n    pos.resize(M);\n    idxs.resize(M);\n    for (int k = 0; k < M; k++) {\n        int r, c;\n        cin >> r >> c;\n        pos[k] = {r, c};\n        idxs[k] = r * N + c;\n    }\n\n    vector<char> blocked(N * N, false);\n    vector<char> isFuture(N * N, false);\n    for (int k = 1; k < M; k++) {\n        isFuture[idxs[k]] = true;\n    }\n\n    vector<pair<char, char>> actions;\n\n    for (int t = 0; t < M - 1; t++) {\n        // current position idxs[t] is considered visited\n        isFuture[idxs[t]] = false;\n\n        // greedy toggle (place/remove) blocks adjacent to current position if beneficial\n        int rem0 = remaining_cost(t, blocked);\n        while (true) {\n            int bestDir = -1;\n            bool bestPlace = false; // true if place, false if remove\n            int bestRem = rem0;\n            int bestGain = 0;\n            int r0 = pos[t].first, c0 = pos[t].second;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r0 + dr[dir], nc = c0 + dc[dir];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                int nidx = nr * N + nc;\n                if (isFuture[nidx]) continue; // don't toggle future target cells\n                if (!blocked[nidx]) {\n                    // consider placing\n                    blocked[nidx] = true;\n                    int rem1 = remaining_cost(t, blocked);\n                    blocked[nidx] = false;\n                    if (rem1 < INF) {\n                        int gain = rem0 - (rem1 + 1);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = true;\n                            bestRem = rem1;\n                        }\n                    }\n                } else {\n                    // consider removing\n                    blocked[nidx] = false;\n                    int rem1 = remaining_cost(t, blocked);\n                    blocked[nidx] = true;\n                    if (rem1 < INF) {\n                        int gain = rem0 - (rem1 + 1);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = false;\n                            bestRem = rem1;\n                        }\n                    }\n                }\n            }\n            if (bestGain > 0 && bestDir != -1) {\n                int nr = r0 + dr[bestDir], nc = c0 + dc[bestDir];\n                int nidx = nr * N + nc;\n                blocked[nidx] = bestPlace;\n                actions.push_back({'A', dirChar[bestDir]});\n                rem0 = bestRem;\n            } else {\n                break;\n            }\n        }\n\n        // move to next target with current blocks\n        auto path = path_between(idxs[t], idxs[t + 1], blocked);\n        actions.insert(actions.end(), path.begin(), path.end());\n    }\n\n    // output actions\n    for (auto &p : actions) {\n        cout << p.first << ' ' << p.second << '\\n';\n    }\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nstruct Move {\n    double diff;\n    int dir;\n    int len;\n    Move(double _d = 0.0, int _dir = -1, int _len = 0) : diff(_d), dir(_dir), len(_len) {}\n};\n\nint n;\nvector<int> x_coord, y_coord;\nvector<long long> r_target;\nvector<Rect> rects;\n\ninline long long area(const Rect &rc) {\n    return 1LL * (rc.c - rc.a) * (rc.d - rc.b);\n}\n\ninline double compute_p_val(long long ri, long long s) {\n    double mn = (double)min(ri, s);\n    double mx = (double)max(ri, s);\n    double diff = 1.0 - mn / mx;\n    return 1.0 - diff * diff;\n}\n\n// compute maximum expandable length in 4 directions without overlap\nvoid compute_max_expands(int idx, int &left, int &right, int &up, int &down) {\n    const Rect &ri = rects[idx];\n    left = ri.a;\n    right = 10000 - ri.c;\n    up = ri.b;\n    down = 10000 - ri.d;\n    for (int j = 0; j < n; j++) if (j != idx) {\n        const Rect &rj = rects[j];\n        // vertical overlap\n        if (rj.b < ri.d && rj.d > ri.b) {\n            if (rj.c <= ri.a) {\n                int cand = ri.a - rj.c;\n                if (cand < left) left = cand;\n            }\n            if (rj.a >= ri.c) {\n                int cand = rj.a - ri.c;\n                if (cand < right) right = cand;\n            }\n        }\n        // horizontal overlap\n        if (rj.a < ri.c && rj.c > ri.a) {\n            if (rj.d <= ri.b) {\n                int cand = ri.b - rj.d;\n                if (cand < up) up = cand;\n            }\n            if (rj.b >= ri.d) {\n                int cand = rj.b - ri.d;\n                if (cand < down) down = cand;\n            }\n        }\n    }\n}\n\nMove find_best_expand(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s >= rt) return best;\n\n    int left, right, up, down;\n    compute_max_expands(idx, left, right, up, down);\n    int maxLens[4] = {left, right, up, down};\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(rt - s) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\nMove find_best_contract(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s <= rt) return best;\n\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int maxLens[4] = {\n        min(x_coord[idx] - rc.a, w - 1),                // shrink left\n        min(rc.c - (x_coord[idx] + 1), w - 1),          // shrink right\n        min(y_coord[idx] - rc.b, h - 1),                // shrink up\n        min(rc.d - (y_coord[idx] + 1), h - 1)           // shrink down\n    };\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(s - rt) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\ninline void apply_move(int idx, const Move &mv, bool expand) {\n    if (mv.dir < 0 || mv.len <= 0) return;\n    Rect &rc = rects[idx];\n    int l = mv.len;\n    if (expand) {\n        if (mv.dir == 0) rc.a -= l;\n        else if (mv.dir == 1) rc.c += l;\n        else if (mv.dir == 2) rc.b -= l;\n        else rc.d += l;\n    } else {\n        if (mv.dir == 0) rc.a += l;\n        else if (mv.dir == 1) rc.c -= l;\n        else if (mv.dir == 2) rc.b += l;\n        else rc.d -= l;\n    }\n}\n\n// Adjust shared vertical edge between two rectangles with same height, rect L on left of R\nbool adjust_vertical_edge(int L, int R) {\n    Rect &A = rects[L];\n    Rect &B = rects[R];\n    int H = A.d - A.b;\n    if (H <= 0) return false;\n    long long sA0 = 1LL * (A.c - A.a) * H;\n    long long sB0 = 1LL * (B.c - B.a) * H;\n    int x0 = A.c; // shared edge\n    int low = max(A.a + 1, x_coord[L] + 1);\n    int high = min(B.c - 1, x_coord[R]);\n    if (low > high) return false;\n\n    auto eval = [&](int xx) -> double {\n        if (xx < low || xx > high) return -1e30;\n        long long sA = sA0 + 1LL * (xx - x0) * H;\n        long long sB = sB0 - 1LL * (xx - x0) * H;\n        double pA = compute_p_val(r_target[L], sA);\n        double pB = compute_p_val(r_target[R], sB);\n        return pA + pB;\n    };\n\n    double cur = eval(x0);\n    double bestVal = cur;\n    int bestX = x0;\n    vector<int> cand;\n    cand.reserve(8);\n    cand.push_back(low);\n    cand.push_back(high);\n    double tA = x0 + (double)(r_target[L] - sA0) / (double)H;\n    double tB = x0 - (double)(r_target[R] - sB0) / (double)H;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA);  if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB);  if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int xx : cand) {\n        double val = eval(xx);\n        if (val > bestVal + EPS) {\n            bestVal = val;\n            bestX = xx;\n        }\n    }\n    if (bestX != x0) {\n        int dx = bestX - x0;\n        A.c += dx;\n        B.a += dx;\n        return true;\n    }\n    return false;\n}\n\n// Adjust shared horizontal edge between two rectangles with same width, rect U below D\nbool adjust_horizontal_edge(int U, int D) {\n    Rect &A = rects[U]; // lower\n    Rect &B = rects[D]; // upper\n    int W = A.c - A.a;\n    if (W <= 0) return false;\n    long long sA0 = 1LL * (A.d - A.b) * W;\n    long long sB0 = 1LL * (B.d - B.b) * W;\n    int y0 = A.d; // shared edge\n    int low = max(A.b + 1, y_coord[U] + 1);\n    int high = min(B.d - 1, y_coord[D]);\n    if (low > high) return false;\n\n    auto eval = [&](int yy) -> double {\n        if (yy < low || yy > high) return -1e30;\n        long long sA = sA0 + 1LL * (yy - y0) * W;\n        long long sB = sB0 - 1LL * (yy - y0) * W;\n        double pA = compute_p_val(r_target[U], sA);\n        double pB = compute_p_val(r_target[D], sB);\n        return pA + pB;\n    };\n\n    double cur = eval(y0);\n    double bestVal = cur;\n    int bestY = y0;\n    vector<int> cand;\n    cand.reserve(8);\n    cand.push_back(low);\n    cand.push_back(high);\n    double tA = y0 + (double)(r_target[U] - sA0) / (double)W;\n    double tB = y0 - (double)(r_target[D] - sB0) / (double)W;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA);  if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB);  if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int yy : cand) {\n        double val = eval(yy);\n        if (val > bestVal + EPS) {\n            bestVal = val;\n            bestY = yy;\n        }\n    }\n    if (bestY != y0) {\n        int dy = bestY - y0;\n        A.d += dy;\n        B.b += dy;\n        return true;\n    }\n    return false;\n}\n\ndouble compute_total_score() {\n    double tot = 0.0;\n    for (int i = 0; i < n; i++) {\n        tot += compute_p_val(r_target[i], area(rects[i]));\n    }\n    return tot;\n}\n\nvoid greedy_expand(const vector<int>& order) {\n    const double EPS = 1e-12;\n    for (int idx : order) {\n        for (int iter = 0; iter < 1000; iter++) {\n            Move mv = find_best_expand(idx);\n            if (mv.diff > EPS) {\n                apply_move(idx, mv, true);\n            } else break;\n        }\n    }\n}\n\nvoid improve_solution_loop(int max_outer, chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    const double EPS = 1e-12;\n    vector<int> idxs(n);\n    for (int outer = 0; outer < max_outer; outer++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        iota(idxs.begin(), idxs.end(), 0);\n        shuffle(idxs.begin(), idxs.end(), rng);\n        for (int id : idxs) {\n            double bestDiff = 0.0;\n            bool doExpand = false;\n            Move mvE = find_best_expand(id);\n            if (mvE.diff > bestDiff) {\n                bestDiff = mvE.diff;\n                doExpand = true;\n            }\n            Move mvC = find_best_contract(id);\n            if (mvC.diff > bestDiff) {\n                bestDiff = mvC.diff;\n                doExpand = false;\n            }\n            if (bestDiff > EPS) {\n                if (doExpand) apply_move(id, mvE, true);\n                else apply_move(id, mvC, false);\n                improved = true;\n            }\n        }\n        elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool pair_improved = false;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (rects[i].b == rects[j].b && rects[i].d == rects[j].d) {\n                    if (rects[i].c == rects[j].a) {\n                        if (adjust_vertical_edge(i, j)) pair_improved = true;\n                    } else if (rects[j].c == rects[i].a) {\n                        if (adjust_vertical_edge(j, i)) pair_improved = true;\n                    }\n                }\n                if (rects[i].a == rects[j].a && rects[i].c == rects[j].c) {\n                    if (rects[i].d == rects[j].b) {\n                        if (adjust_horizontal_edge(i, j)) pair_improved = true;\n                    } else if (rects[j].d == rects[i].b) {\n                        if (adjust_horizontal_edge(j, i)) pair_improved = true;\n                    }\n                }\n            }\n            elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        if (pair_improved) improved = true;\n        if (!improved) break;\n    }\n}\n\nvoid compute_max_contracts(int idx, int maxLens[4]) {\n    Rect &rc = rects[idx];\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    maxLens[0] = min(x_coord[idx] - rc.a, w - 1);\n    maxLens[1] = min(rc.c - (x_coord[idx] + 1), w - 1);\n    maxLens[2] = min(y_coord[idx] - rc.b, h - 1);\n    maxLens[3] = min(rc.d - (y_coord[idx] + 1), h - 1);\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n}\n\nvoid simulated_annealing(chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    double duration = TIME_LIMIT - elapsed - 0.05;\n    if (duration <= 0) return;\n    double sa_start = elapsed;\n    double sa_end = sa_start + duration;\n\n    double cur_score = compute_total_score();\n    double best_score = cur_score;\n    vector<Rect> best_rects = rects;\n\n    const double T0 = 0.5, T1 = 0.02;\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    uniform_int_distribution<int> dist_rect(0, n - 1);\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        if ((iter & 0x3FF) == 0) {\n            double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (now > sa_end) break;\n        }\n        double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double t = (now - sa_start) / duration;\n        if (t < 0) t = 0; if (t > 1) t = 1;\n        double temp = T0 + (T1 - T0) * t;\n\n        int i = dist_rect(rng);\n        Rect &rc = rects[i];\n        long long s = area(rc);\n        long long rt = r_target[i];\n        double p_cur = compute_p_val(rt, s);\n\n        bool choose_expand;\n        if (s < rt) {\n            choose_expand = (urd(rng) < 0.75);\n        } else if (s > rt) {\n            choose_expand = (urd(rng) < 0.25);\n        } else {\n            choose_expand = (urd(rng) < 0.5);\n        }\n\n        if (choose_expand) {\n            int left, right, up, down;\n            compute_max_expands(i, left, right, up, down);\n            int maxLens[4] = {left, right, up, down};\n            int w = rc.c - rc.a;\n            int h = rc.d - rc.b;\n            int deltas[4] = {h, h, w, w};\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) if (maxLens[d] > 0) dirs.push_back(d);\n            if (dirs.empty()) continue;\n            int dir = dirs[rng() % dirs.size()];\n            int maxLen = maxLens[dir];\n            int delta = deltas[dir];\n            if (delta <= 0) continue;\n            double len_target = (rt > s) ? (double)(rt - s) / (double)delta : 1.0;\n            int l = (int)round(len_target);\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            int tweak = (int)(urd(rng) * 5.0) - 2; // -2..2\n            l += tweak;\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            bool accept = diff >= 0 || urd(rng) < exp(diff / temp);\n            if (accept) {\n                if (dir == 0) rc.a -= l;\n                else if (dir == 1) rc.c += l;\n                else if (dir == 2) rc.b -= l;\n                else rc.d += l;\n                cur_score += diff;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_rects = rects;\n                }\n            }\n        } else {\n            int w = rc.c - rc.a;\n            int h = rc.d - rc.b;\n            if (w <= 1 && h <= 1) continue;\n            int maxLens[4];\n            compute_max_contracts(i, maxLens);\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) if (maxLens[d] > 0) dirs.push_back(d);\n            if (dirs.empty()) continue;\n            int dir = dirs[rng() % dirs.size()];\n            int maxLen = maxLens[dir];\n            int delta = (dir < 2) ? h : w;\n            if (delta <= 0) continue;\n            double len_target = (s > rt) ? (double)(s - rt) / (double)delta : 1.0;\n            int l = (int)round(len_target);\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            int tweak = (int)(urd(rng) * 5.0) - 2;\n            l += tweak;\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            bool accept = diff >= 0 || urd(rng) < exp(diff / temp);\n            if (accept) {\n                if (dir == 0) rc.a += l;\n                else if (dir == 1) rc.c -= l;\n                else if (dir == 2) rc.b += l;\n                else rc.d -= l;\n                cur_score += diff;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_rects = rects;\n                }\n            }\n        }\n    }\n    rects = best_rects;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> n)) return 0;\n    x_coord.resize(n);\n    y_coord.resize(n);\n    r_target.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        int xi, yi;\n        long long ri;\n        cin >> xi >> yi >> ri;\n        x_coord[i] = xi;\n        y_coord[i] = yi;\n        r_target[i] = ri;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.9;\n    mt19937 rng(1234567);\n\n    vector<vector<int>> base_orders;\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return r_target[a] > r_target[b]; });\n    base_orders.push_back(order); // descending\n    sort(order.begin(), order.end(), [&](int a, int b) { return r_target[a] < r_target[b]; });\n    base_orders.push_back(order); // ascending\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (x_coord[a] != x_coord[b]) return x_coord[a] < x_coord[b];\n        return y_coord[a] < y_coord[b];\n    });\n    base_orders.push_back(order); // by x\n\n    double best_score = -1.0;\n    vector<Rect> best_rects;\n\n    auto elapsed = [&]() -> double {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    auto run_candidate = [&](const vector<int> &ord, int outer_limit, double time_cut)->void{\n        for (int i = 0; i < n; i++) {\n            rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n        }\n        greedy_expand(ord);\n        improve_solution_loop(outer_limit, start_time, time_cut, rng);\n        double sc = compute_total_score();\n        if (sc > best_score) {\n            best_score = sc;\n            best_rects = rects;\n        }\n    };\n\n    // Try base orders\n    for (auto &ord : base_orders) {\n        if (elapsed() > TIME_LIMIT * 0.4) break;\n        run_candidate(ord, 8, TIME_LIMIT * 0.6);\n    }\n\n    // Random restarts\n    while (elapsed() < TIME_LIMIT * 0.45) {\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        run_candidate(order, 6, TIME_LIMIT * 0.55);\n    }\n\n    if (!best_rects.empty()) rects = best_rects;\n    else {\n        for (int i = 0; i < n; i++) rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n    }\n\n    // Deep improvement\n    improve_solution_loop(25, start_time, TIME_LIMIT * 0.8, rng);\n    // Another greedy fill with descending order\n    sort(order.begin(), order.end(), [&](int a, int b){ return r_target[a] > r_target[b]; });\n    greedy_expand(order);\n    improve_solution_loop(10, start_time, TIME_LIMIT * 0.85, rng);\n\n    // Simulated annealing with remaining time\n    simulated_annealing(start_time, TIME_LIMIT, rng);\n\n    // Final polish\n    improve_solution_loop(5, start_time, TIME_LIMIT, rng);\n\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << ' ' << rects[i].b << ' ' << rects[i].c << ' ' << rects[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 50;\nconst int W = 50;\nconst int N = H * W;\n\nint Tcell[N];\nint Pcell[N];\n\nint nbCnt[N];\nint nbIdx[N][4];\nchar nbDir[N][4];\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nint startIdx;\nint tileCount;\n\nvector<int> visitedTile;\nint currentToken = 1;\n\nstruct XorShift {\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ULL) { x = seed; }\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int n) { return (int)(next() % n); }\n};\nXorShift rng;\n\nenum Mode { MIN_DEG = 0, MAX_DEG = 1, MAX_VALUE = 2 };\n\nstruct Param {\n    int avoidLevel; // -1 for no avoid, otherwise ignore deg<=avoidLevel if a higher deg exists\n    Mode mode;\n    int randProb; // 0..1023 chance to pick random move\n};\n\nstruct Path {\n    string moves;\n    int score;\n    int len;\n};\n\ninline int compute_deg(int idx) {\n    int tid = Tcell[idx];\n    int deg = 0;\n    for (int k = 0; k < nbCnt[idx]; k++) {\n        int nb = nbIdx[idx][k];\n        int nt = Tcell[nb];\n        if (nt == tid) continue;\n        if (visitedTile[nt] == currentToken) continue;\n        deg++;\n    }\n    return deg;\n}\n\nPath run_once(const Param &param) {\n    currentToken++;\n    if (currentToken == 0x3f3f3f3f) { // reset if overflowed\n        currentToken = 1;\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n    }\n    visitedTile[Tcell[startIdx]] = currentToken;\n    int cur = startIdx;\n    int score = Pcell[cur];\n    vector<char> mv;\n    mv.reserve(tileCount);\n    while (true) {\n        int candIdxArr[4];\n        char candDirArr[4];\n        int cnum = 0;\n        for (int k = 0; k < nbCnt[cur]; k++) {\n            int nb = nbIdx[cur][k];\n            if (visitedTile[Tcell[nb]] == currentToken) continue;\n            candIdxArr[cnum] = nb;\n            candDirArr[cnum] = nbDir[cur][k];\n            cnum++;\n        }\n        if (cnum == 0) break;\n\n        int chosen = -1;\n        if (param.randProb > 0 && ((rng.next() & 1023) < param.randProb)) {\n            chosen = rng.nextInt(cnum);\n        } else {\n            int degs[4];\n            int maxDeg = -1;\n            for (int i = 0; i < cnum; i++) {\n                degs[i] = compute_deg(candIdxArr[i]);\n                if (degs[i] > maxDeg) maxDeg = degs[i];\n            }\n            bool filtered = (param.avoidLevel >= 0 && maxDeg > param.avoidLevel);\n\n            if (param.mode == MIN_DEG) {\n                int bestDeg = 1e9, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    if (d < bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int v = Pcell[candIdxArr[i]];\n                        if (v > bestVal) {\n                            bestVal = v;\n                            chosen = i;\n                        } else if (v == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else if (param.mode == MAX_DEG) {\n                int bestDeg = -1, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    if (d > bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int v = Pcell[candIdxArr[i]];\n                        if (v > bestVal) {\n                            bestVal = v;\n                            chosen = i;\n                        } else if (v == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else { // MAX_VALUE\n                int bestVal = -1, bestDeg = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    int v = Pcell[candIdxArr[i]];\n                    if (v > bestVal) {\n                        bestVal = v;\n                        bestDeg = d;\n                        chosen = i;\n                    } else if (v == bestVal) {\n                        if (d > bestDeg) {\n                            bestDeg = d;\n                            chosen = i;\n                        } else if (d == bestDeg && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            }\n        }\n        if (chosen == -1) chosen = rng.nextInt(cnum);\n        int nxt = candIdxArr[chosen];\n        visitedTile[Tcell[nxt]] = currentToken;\n        score += Pcell[nxt];\n        mv.push_back(candDirArr[chosen]);\n        cur = nxt;\n    }\n    Path res;\n    res.score = score;\n    res.len = (int)mv.size() + 1;\n    res.moves.assign(mv.begin(), mv.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    int maxTid = -1;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Tcell[idx] = x;\n            if (x > maxTid) maxTid = x;\n        }\n    }\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Pcell[idx] = x;\n        }\n    }\n    tileCount = maxTid + 1;\n    visitedTile.assign(tileCount, 0);\n    startIdx = si * W + sj;\n\n    // Precompute neighbors\n    for (int r = 0; r < H; r++) {\n        for (int c = 0; c < W; c++) {\n            int idx = r * W + c;\n            int cnt = 0;\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 >= H || nc < 0 || nc >= W) continue;\n                nbIdx[idx][cnt] = nr * W + nc;\n                nbDir[idx][cnt] = dch[d];\n                cnt++;\n            }\n            nbCnt[idx] = cnt;\n        }\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    rng = XorShift(seed);\n\n    vector<Param> params = {\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 30},\n        {1, MIN_DEG, 0},\n        {1, MIN_DEG, 50},\n        {0, MAX_DEG, 0},\n        {0, MAX_DEG, 50},\n        {0, MAX_VALUE, 0},\n        {0, MAX_VALUE, 50},\n        {0, MIN_DEG, 200},\n        {2, MIN_DEG, 0},\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 0}\n    };\n\n    Path best;\n    best.score = -1;\n    best.len = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeLimit = startTime + chrono::milliseconds(1950);\n\n    size_t pidx = rng.nextInt((int)params.size());\n    while (chrono::steady_clock::now() < timeLimit) {\n        const Param &param = params[pidx];\n        pidx++;\n        if (pidx >= params.size()) pidx = 0;\n        Path curPath = run_once(param);\n        if (curPath.score > best.score || (curPath.score == best.score && curPath.len > best.len)) {\n            best = std::move(curPath);\n        }\n    }\n\n    cout << best.moves << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Neighbor {\n    int to;\n    int edge;\n    char dir;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int H = 30, W = 30;\n    const int N = H * W;\n    const int EH = H * (W - 1);\n    const int EV = (H - 1) * W;\n    const int E = EH + EV;\n\n    // index tables\n    int h_idx[H][W - 1];\n    int v_idx[H - 1][W];\n    int idx = 0;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            h_idx[i][j] = idx++;\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            v_idx[i][j] = idx++;\n        }\n    }\n\n    vector<vector<Neighbor>> adj(N);\n    // build graph\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            int e = h_idx[i][j];\n            int u = i * W + j;\n            int v = i * W + (j + 1);\n            adj[u].push_back({v, e, 'R'});\n            adj[v].push_back({u, e, 'L'});\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            int e = v_idx[i][j];\n            int u = i * W + j;\n            int v = (i + 1) * W + j;\n            adj[u].push_back({v, e, 'D'});\n            adj[v].push_back({u, e, 'U'});\n        }\n    }\n\n    vector<double> w(E, 5000.0);\n    vector<int> cnt(E, 0);\n\n    vector<int> rowSplit(H, -1), colSplit(W, -1);\n    vector<double> rowMeanAll(H, 5000.0), rowMeanL(H, 5000.0), rowMeanR(H, 5000.0);\n    vector<double> colMeanAll(W, 5000.0), colMeanT(W, 5000.0), colMeanB(W, 5000.0);\n\n    auto recompute_means_splits = [&](int qidx) {\n        double gSumH = 0.0, gSumV = 0.0;\n        int gCntH = 0, gCntV = 0;\n        for (int e = 0; e < EH; e++) if (cnt[e] > 0) { gSumH += w[e]; gCntH++; }\n        for (int e = EH; e < E; e++) if (cnt[e] > 0) { gSumV += w[e]; gCntV++; }\n        double gMeanH = gCntH ? gSumH / gCntH : 5000.0;\n        double gMeanV = gCntV ? gSumV / gCntV : 5000.0;\n\n        // rows\n        for (int i = 0; i < H; i++) {\n            vector<double> ps(W, 0.0);\n            vector<int> pc(W, 0);\n            for (int j = 0; j < W - 1; j++) {\n                ps[j + 1] = ps[j];\n                pc[j + 1] = pc[j];\n                int e = h_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[j + 1] += w[e];\n                    pc[j + 1] += 1;\n                }\n            }\n            double totalSum = ps[W - 1];\n            int totalCnt = pc[W - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanH;\n            rowMeanAll[i] = meanAll;\n            rowMeanL[i] = rowMeanR[i] = meanAll;\n            rowSplit[i] = -1;\n            if (totalCnt >= 4 && qidx >= 60) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int x = 1; x < W - 1; x++) {\n                    int lc = pc[x];\n                    int rc = totalCnt - lc;\n                    if (lc >= 2 && rc >= 2) {\n                        double ls = ps[x];\n                        double rs = totalSum - ls;\n                        double lm = ls / lc;\n                        double rm = rs / rc;\n                        double diff = fabs(lm - rm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = x;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 400.0) {\n                    rowSplit[i] = bestSplit;\n                    int lc = pc[bestSplit];\n                    int rc = totalCnt - lc;\n                    double ls = ps[bestSplit];\n                    double rs = totalSum - ls;\n                    rowMeanL[i] = lc ? ls / lc : meanAll;\n                    rowMeanR[i] = rc ? rs / rc : meanAll;\n                }\n            }\n        }\n\n        // columns\n        for (int j = 0; j < W; j++) {\n            vector<double> ps(H, 0.0);\n            vector<int> pc(H, 0);\n            for (int i = 0; i < H - 1; i++) {\n                ps[i + 1] = ps[i];\n                pc[i + 1] = pc[i];\n                int e = v_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[i + 1] += w[e];\n                    pc[i + 1] += 1;\n                }\n            }\n            double totalSum = ps[H - 1];\n            int totalCnt = pc[H - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanV;\n            colMeanAll[j] = meanAll;\n            colMeanT[j] = colMeanB[j] = meanAll;\n            colSplit[j] = -1;\n            if (totalCnt >= 4 && qidx >= 60) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int y = 1; y < H - 1; y++) {\n                    int tc = pc[y];\n                    int bc = totalCnt - tc;\n                    if (tc >= 2 && bc >= 2) {\n                        double ts = ps[y];\n                        double bs = totalSum - ts;\n                        double tm = ts / tc;\n                        double bm = bs / bc;\n                        double diff = fabs(tm - bm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = y;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 400.0) {\n                    colSplit[j] = bestSplit;\n                    int tc = pc[bestSplit];\n                    int bc = totalCnt - tc;\n                    double ts = ps[bestSplit];\n                    double bs = totalSum - ts;\n                    colMeanT[j] = tc ? ts / tc : meanAll;\n                    colMeanB[j] = bc ? bs / bc : meanAll;\n                }\n            }\n        }\n    };\n\n    auto smooth_edges = [&]() {\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W - 1; j++) {\n                int e = h_idx[i][j];\n                double pred = (rowSplit[i] == -1) ? rowMeanAll[i] : (j < rowSplit[i] ? rowMeanL[i] : rowMeanR[i]);\n                if (cnt[e] == 0) {\n                    w[e] = pred;\n                } else if (cnt[e] <= 2) {\n                    w[e] = 0.5 * w[e] + 0.5 * pred;\n                }\n            }\n        }\n        for (int j = 0; j < W; j++) {\n            for (int i = 0; i < H - 1; i++) {\n                int e = v_idx[i][j];\n                double pred = (colSplit[j] == -1) ? colMeanAll[j] : (i < colSplit[j] ? colMeanT[j] : colMeanB[j]);\n                if (cnt[e] == 0) {\n                    w[e] = pred;\n                } else if (cnt[e] <= 2) {\n                    w[e] = 0.5 * w[e] + 0.5 * pred;\n                }\n            }\n        }\n    };\n\n    const int EXP_END = 350;\n    const double EXP_BONUS = 3000.0;\n\n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        int s = si * W + sj;\n        int t = ti * W + tj;\n\n        if (q == 0 || q % 20 == 0) {\n            recompute_means_splits(q);\n            smooth_edges();\n        }\n\n        double explore_factor = (q < EXP_END) ? (double)(EXP_END - q) / EXP_END : 0.0;\n\n        // Dijkstra\n        const double INF = 1e100;\n        vector<double> dist(N, INF);\n        vector<int> prev(N, -1), prev_e(N, -1);\n        vector<char> prev_d(N, 0);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n        dist[s] = 0.0;\n        pq.push({0.0, s});\n        while (!pq.empty()) {\n            auto [d, v] = pq.top();\n            pq.pop();\n            if (d != dist[v]) continue;\n            if (v == t) break;\n            for (auto &nb : adj[v]) {\n                double cost = w[nb.edge];\n                if (cnt[nb.edge] == 0) {\n                    // if unknown, rely on predicted mean if available\n                    if (nb.edge < EH) {\n                        int ii = v / W;\n                        int jj = v % W;\n                        if (nb.dir == 'R') jj = jj;\n                        else if (nb.dir == 'L') jj = jj - 1;\n                        double pred = (rowSplit[ii] == -1) ? rowMeanAll[ii] : (jj < rowSplit[ii] ? rowMeanL[ii] : rowMeanR[ii]);\n                        cost = pred;\n                    } else {\n                        int ii = v / W;\n                        int jj = v % W;\n                        if (nb.dir == 'D') ii = ii;\n                        else if (nb.dir == 'U') ii = ii - 1;\n                        double pred = (colSplit[jj] == -1) ? colMeanAll[jj] : (ii < colSplit[jj] ? colMeanT[jj] : colMeanB[jj]);\n                        cost = pred;\n                    }\n                }\n                if (explore_factor > 0.0) {\n                    cost -= EXP_BONUS * explore_factor / sqrt((double)cnt[nb.edge] + 1.0);\n                }\n                if (cost < 1.0) cost = 1.0;\n                double nd = d + cost;\n                if (nd < dist[nb.to]) {\n                    dist[nb.to] = nd;\n                    prev[nb.to] = v;\n                    prev_e[nb.to] = nb.edge;\n                    prev_d[nb.to] = nb.dir;\n                    pq.push({nd, nb.to});\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        vector<int> edges_seq;\n        double pred_len = 0.0;\n        double pred_h = 0.0, pred_v = 0.0;\n        int v = t;\n        while (v != s && v != -1) {\n            int e = prev_e[v];\n            char dch = prev_d[v];\n            if (e < 0) break;\n            path.push_back(dch);\n            edges_seq.push_back(e);\n            pred_len += w[e];\n            if (e < EH) pred_h += w[e]; else pred_v += w[e];\n            v = prev[v];\n        }\n        reverse(path.begin(), path.end());\n        reverse(edges_seq.begin(), edges_seq.end());\n\n        cout << path << '\\n' << flush;\n\n        int obs_int;\n        if (!(cin >> obs_int)) break;\n        double obs_len = obs_int;\n        if (pred_len < 1e-6) pred_len = (double)edges_seq.size() * 5000.0;\n        double error = obs_len - pred_len;\n\n        double base_lr = (q < 200) ? 0.55 : (q < 600 ? 0.4 : 0.3);\n        double ph = pred_h, pv = pred_v;\n        double err_h = error, err_v = 0.0;\n        double total_pred = ph + pv;\n        if (total_pred > 1e-9) {\n            if (ph > 0 && pv > 0) {\n                err_h = error * (ph / total_pred);\n                err_v = error - err_h;\n            } else if (ph <= 0) {\n                err_h = 0.0;\n                err_v = error;\n            } else {\n                err_h = error;\n                err_v = 0.0;\n            }\n        }\n        double denom_h = max(ph, 1e-6);\n        double denom_v = max(pv, 1e-6);\n\n        for (int e : edges_seq) {\n            if (e < EH) {\n                double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n                double contrib = w[e] / denom_h;\n                w[e] += lr * err_h * contrib;\n            } else {\n                double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n                double contrib = w[e] / denom_v;\n                w[e] += lr * err_v * contrib;\n            }\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 9500.0) w[e] = 9500.0;\n            cnt[e]++;\n        }\n\n        if (q % 40 == 39) {\n            recompute_means_splits(q);\n            smooth_edges();\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// XorShift RNG\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    inline uint32_t next_u32() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return static_cast<uint32_t>(x);\n    }\n    inline int next_int(int n) { return static_cast<int>(next_u32() % n); }\n};\n\n// Constants\nconst int N = 20;\nconst int CELLS = N * N;   // 400\nconst int PL = 800;        // placements per string (400 horiz + 400 vert)\n\nint M;\nvector<string> s;\nvector<int> lens;\nvector<vector<uint8_t>> letters;          // s[i] as 0..7\nvector<vector<uint16_t>> cells;           // placements cells\nvector<uint16_t*> cellPtrs;\nvector<uint8_t*> letterPtrs;\n\n// counts for current placement assignment\nstatic int counts[CELLS][8];\nstatic int totalCnt[CELLS];\nvector<int> currPlacement;\n\n// add/remove placement to counts\ninline void addPlacement(int si, int pi) {\n    int len = lens[si];\n    const uint16_t* cp = cellPtrs[si] + pi * len;\n    const uint8_t* lp = letterPtrs[si];\n    for (int p = 0; p < len; ++p) {\n        int cell = cp[p];\n        int li = lp[p];\n        ++counts[cell][li];\n        ++totalCnt[cell];\n    }\n}\ninline void removePlacement(int si, int pi) {\n    int len = lens[si];\n    const uint16_t* cp = cellPtrs[si] + pi * len;\n    const uint8_t* lp = letterPtrs[si];\n    for (int p = 0; p < len; ++p) {\n        int cell = cp[p];\n        int li = lp[p];\n        --counts[cell][li];\n        --totalCnt[cell];\n    }\n}\n\n// conflict of string si with current counts\ninline int computeConf(int si) {\n    int len = lens[si];\n    const uint16_t* cp = cellPtrs[si] + currPlacement[si] * len;\n    const uint8_t* lp = letterPtrs[si];\n    int conf = 0;\n    for (int p = 0; p < len; ++p) {\n        int cell = cp[p];\n        int li = lp[p];\n        conf += totalCnt[cell] - counts[cell][li];\n    }\n    return conf;\n}\n\n// build majority matrix from counts\nvoid buildMatrix(vector<char>& mat, bool dotUnused) {\n    mat.resize(CELLS);\n    for (int cell = 0; cell < CELLS; ++cell) {\n        if (totalCnt[cell] == 0) {\n            mat[cell] = dotUnused ? '.' : 'A';\n        } else {\n            int bestL = 0;\n            int bestC = counts[cell][0];\n            for (int l = 1; l < 8; ++l) {\n                if (counts[cell][l] > bestC) {\n                    bestC = counts[cell][l];\n                    bestL = l;\n                }\n            }\n            mat[cell] = static_cast<char>('A' + bestL);\n        }\n    }\n}\n\n// evaluate how many strings are subsequences of matrix mat\nint evaluateMatrix(const vector<char>& mat) {\n    int satisfied = 0;\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cp = cellPtrs[i];\n        const char* sp = s[i].c_str();\n        bool ok = false;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            bool comp = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                if (mat[cell] != sp[p]) {\n                    comp = false;\n                    break;\n                }\n            }\n            if (comp) {\n                ok = true;\n                break;\n            }\n        }\n        if (ok) ++satisfied;\n    }\n    return satisfied;\n}\n\n// greedy construction trial with given order of string indices\nvoid greedyTrial(const vector<int>& order, XorShift64& rng, vector<char>& outMat, int& placedCount, int& coverage) {\n    vector<char> mat(CELLS, '.');\n    placedCount = 0;\n    for (int idx : order) {\n        int len = lens[idx];\n        const uint16_t* cp = cellPtrs[idx];\n        const char* sp = s[idx].c_str();\n        int bestMatch = -1;\n        int bestPi = -1;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            bool ok = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char mc = mat[cell];\n                char sc = sp[p];\n                if (mc == sc) {\n                    ++matches;\n                } else if (mc == '.') {\n                    // ok\n                } else {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        if (bestPi >= 0) {\n            ++placedCount;\n            int base = bestPi * len;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char sc = sp[p];\n                if (mat[cell] == '.') mat[cell] = sc;\n            }\n        }\n    }\n    coverage = evaluateMatrix(mat);\n    outMat.swap(mat);\n}\n\n// initialize placements from a given matrix by choosing placement with maximum matches\nvoid initPlacementsFromMatrix(const vector<char>& mat) {\n    memset(counts, 0, sizeof(counts));\n    memset(totalCnt, 0, sizeof(totalCnt));\n    currPlacement.resize(M);\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cp = cellPtrs[i];\n        const char* sp = s[i].c_str();\n        int bestMatch = -1;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                if (mat[cell] == sp[p]) ++matches;\n            }\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rand() % tie == 0) bestPi = pi;\n            }\n        }\n        currPlacement[i] = bestPi;\n        addPlacement(i, bestPi);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    s.resize(M);\n    lens.resize(M);\n    letters.resize(M);\n    cells.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        lens[i] = (int)s[i].size();\n        letters[i].resize(lens[i]);\n        for (int p = 0; p < lens[i]; ++p) letters[i][p] = (uint8_t)(s[i][p] - 'A');\n        cells[i].resize(PL * lens[i]);\n        int len = lens[i];\n        // horizontal placements 0..399\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int cc = (c + p) % N;\n                    cells[i][base + p] = (uint16_t)(r * N + cc);\n                }\n            }\n        }\n        // vertical placements 400..799\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = 400 + r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int rr = (r + p) % N;\n                    cells[i][base + p] = (uint16_t)(rr * N + c);\n                }\n            }\n        }\n    }\n    cellPtrs.resize(M);\n    letterPtrs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cellPtrs[i] = cells[i].data();\n        letterPtrs[i] = letters[i].data();\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    XorShift64 rng(seed);\n\n    auto timeStart = chrono::steady_clock::now();\n    auto elapsedSec = [&]() -> double {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - timeStart).count();\n    };\n    const double TIME_LIMIT = 2.9;\n    const double GREEDY_TIME = 1.2; // time budget for greedy trials\n\n    vector<char> bestMat(CELLS, 'A');\n    int bestSat = 0;\n\n    // Prepare length-descending order\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (lens[a] != lens[b]) return lens[a] > lens[b];\n        return a < b;\n    });\n\n    // Run one deterministic trial\n    vector<char> mat;\n    int placed = 0, cov = 0;\n    greedyTrial(order, rng, mat, placed, cov);\n    if (cov > bestSat) {\n        bestSat = cov;\n        bestMat = mat;\n    }\n\n    // Greedy trials with random orders until time budget\n    vector<int> randOrder(M);\n    iota(randOrder.begin(), randOrder.end(), 0);\n    while (elapsedSec() < GREEDY_TIME) {\n        // random shuffle\n        for (int i = M - 1; i > 0; --i) {\n            int j = rng.next_int(i + 1);\n            swap(randOrder[i], randOrder[j]);\n        }\n        greedyTrial(randOrder, rng, mat, placed, cov);\n        if (cov > bestSat) {\n            bestSat = cov;\n            bestMat = mat;\n        }\n    }\n\n    // Initialize placements from bestMat\n    initPlacementsFromMatrix(bestMat);\n\n    // Local search\n    int evalInterval = 500;\n    int iter = 0;\n    while (true) {\n        if (iter % evalInterval == 0) {\n            vector<char> curMat;\n            buildMatrix(curMat, false);\n            int c = evaluateMatrix(curMat);\n            if (c > bestSat) {\n                bestSat = c;\n                bestMat = curMat;\n            }\n            if (elapsedSec() > TIME_LIMIT) break;\n        }\n        if (elapsedSec() > TIME_LIMIT) break;\n\n        // compute conflicts\n        int maxConf = -1;\n        vector<int> conflictIdx;\n        conflictIdx.reserve(M);\n        for (int i = 0; i < M; ++i) {\n            int conf = computeConf(i);\n            if (conf > 0) conflictIdx.push_back(i);\n            if (conf > maxConf) maxConf = conf;\n        }\n        if (conflictIdx.empty()) {\n            // Consistent assignment\n            vector<char> curMat;\n            buildMatrix(curMat, true); // use dots for unused\n            int c = evaluateMatrix(curMat); // should be M\n            if (c > bestSat) {\n                bestSat = c;\n                bestMat = curMat;\n            }\n            break;\n        }\n\n        int si = conflictIdx[rng.next_int((int)conflictIdx.size())];\n\n        // adjust placement of si\n        removePlacement(si, currPlacement[si]);\n        int len = lens[si];\n        const uint8_t* lp = letterPtrs[si];\n        const uint16_t* cp = cellPtrs[si];\n        int minScore = INT_MAX;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int score = 0;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                int li = lp[p];\n                score += totalCnt[cell] - counts[cell][li];\n            }\n            if (score < minScore) {\n                minScore = score;\n                bestPi = pi;\n                tie = 1;\n            } else if (score == minScore) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        // occasional random move\n        if ((rng.next_u32() & 255) == 0) {\n            bestPi = rng.next_int(PL);\n        }\n        currPlacement[si] = bestPi;\n        addPlacement(si, bestPi);\n\n        ++iter;\n    }\n\n    // Final evaluation\n    vector<char> finalMat;\n    buildMatrix(finalMat, false);\n    int cfin = evaluateMatrix(finalMat);\n    if (cfin > bestSat) {\n        bestSat = cfin;\n        bestMat = finalMat;\n    }\n\n    // Output bestMat\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << bestMat[r * N + c];\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct CoverState {\n    int coveredCount;\n    vector<char> covered;\n    vector<char> rowCovered, colCovered;\n    vector<int> uncoveredRow, uncoveredCol;\n    CoverState(int R, int rsz, int csz, const vector<int> &rowSize, const vector<int> &colSize) {\n        coveredCount = 0;\n        covered.assign(R, 0);\n        rowCovered.assign(rsz, 0);\n        colCovered.assign(csz, 0);\n        uncoveredRow = rowSize;\n        uncoveredCol = colSize;\n    }\n};\n\nconst int INF = 1e9;\n\nvoid coverFrom(int u,\n               CoverState &st,\n               const vector<int> &row_id,\n               const vector<int> &col_id,\n               const vector<vector<int>> &row_nodes,\n               const vector<vector<int>> &col_nodes) {\n    int rid = row_id[u];\n    if (!st.rowCovered[rid]) {\n        st.rowCovered[rid] = 1;\n        for (int v : row_nodes[rid]) {\n            if (!st.covered[v]) {\n                st.covered[v] = 1;\n                st.coveredCount++;\n                st.uncoveredRow[row_id[v]]--;\n                st.uncoveredCol[col_id[v]]--;\n            }\n        }\n    }\n    int cid = col_id[u];\n    if (!st.colCovered[cid]) {\n        st.colCovered[cid] = 1;\n        for (int v : col_nodes[cid]) {\n            if (!st.covered[v]) {\n                st.covered[v] = 1;\n                st.coveredCount++;\n                st.uncoveredRow[row_id[v]]--;\n                st.uncoveredCol[col_id[v]]--;\n            }\n        }\n    }\n}\n\nvoid dijkstra(int src,\n              const vector<vector<pair<int, int>>> &adj,\n              vector<int> &dist,\n              vector<int> &prev) {\n    int n = adj.size();\n    dist.assign(n, INF);\n    prev.assign(n, -1);\n    dist[src] = 0;\n    using P = pair<int, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            int v = e.first, c = e.second;\n            int nd = d + c;\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pq.push({nd, v});\n            }\n        }\n    }\n}\n\nvector<int> reconstructPath(int src, int dst, const vector<int> &prev) {\n    vector<int> path;\n    int v = dst;\n    if (v != src && prev[v] == -1) return path;\n    while (true) {\n        path.push_back(v);\n        if (v == src) break;\n        v = prev[v];\n        if (v == -1) {\n            path.clear();\n            return path;\n        }\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nchar dirFromDiff(const pair<int, int> &a, const pair<int, int> &b) {\n    if (b.first == a.first - 1) return 'U';\n    if (b.first == a.first + 1) return 'D';\n    if (b.second == a.second - 1) return 'L';\n    return 'R';\n}\n\nstruct RouteResult {\n    string route;\n    long long cost;\n    bool full;\n};\n\nRouteResult buildRouteGreedy(int start,\n                             int R,\n                             const vector<int> &row_id,\n                             const vector<int> &col_id,\n                             const vector<vector<int>> &row_nodes,\n                             const vector<vector<int>> &col_nodes,\n                             const vector<vector<pair<int, int>>> &adj,\n                             const vector<pair<int, int>> &pos,\n                             const vector<int> &w) {\n    vector<int> rowSize(row_nodes.size()), colSize(col_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) rowSize[i] = (int)row_nodes[i].size();\n    for (size_t i = 0; i < col_nodes.size(); i++) colSize[i] = (int)col_nodes[i].size();\n    CoverState st(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, st, row_id, col_id, row_nodes, col_nodes);\n\n    string route;\n    long long cost = 0;\n    int current = start;\n    vector<int> dist, prev;\n    int iter_limit = 500;\n    int iter = 0;\n    while (st.coveredCount < R && iter < iter_limit) {\n        iter++;\n        dijkstra(current, adj, dist, prev);\n        int best = -1, bestGain = -1, bestDist = INF;\n        double bestScore = -1.0;\n        for (int u = 0; u < R; u++) {\n            int gain = st.uncoveredRow[row_id[u]] + st.uncoveredCol[col_id[u]] - (st.covered[u] ? 0 : 1);\n            if (gain <= 0) continue;\n            int d = dist[u];\n            if (d >= INF) continue;\n            double score = (double)gain / (double)(d + 1);\n            if (score > bestScore || (score == bestScore && (gain > bestGain || (gain == bestGain && d < bestDist)))) {\n                bestScore = score;\n                bestGain = gain;\n                bestDist = d;\n                best = u;\n            }\n        }\n        if (best == -1) break;\n        vector<int> path = reconstructPath(current, best, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n            current = v;\n            coverFrom(v, st, row_id, col_id, row_nodes, col_nodes);\n        }\n    }\n    // fallback nearest uncovered\n    while (st.coveredCount < R) {\n        dijkstra(current, adj, dist, prev);\n        int target = -1, bestD = INF;\n        for (int u = 0; u < R; u++) {\n            if (st.covered[u]) continue;\n            if (dist[u] < bestD) {\n                bestD = dist[u];\n                target = u;\n            }\n        }\n        if (target == -1 || bestD == INF) break;\n        vector<int> path = reconstructPath(current, target, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n            current = v;\n            coverFrom(v, st, row_id, col_id, row_nodes, col_nodes);\n        }\n    }\n    // return to start\n    if (current != start) {\n        dijkstra(current, adj, dist, prev);\n        vector<int> path = reconstructPath(current, start, prev);\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n        }\n    }\n    return {route, cost, st.coveredCount == R};\n}\n\nRouteResult buildRouteSetCoverTSP(int start,\n                                  int R,\n                                  const vector<int> &row_id,\n                                  const vector<int> &col_id,\n                                  const vector<vector<int>> &row_nodes,\n                                  const vector<vector<int>> &col_nodes,\n                                  const vector<vector<pair<int, int>>> &adj,\n                                  const vector<pair<int, int>> &pos,\n                                  const vector<int> &w) {\n    vector<int> rowSize(row_nodes.size()), colSize(col_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) rowSize[i] = (int)row_nodes[i].size();\n    for (size_t i = 0; i < col_nodes.size(); i++) colSize[i] = (int)col_nodes[i].size();\n    CoverState stSel(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, stSel, row_id, col_id, row_nodes, col_nodes);\n    vector<int> targets;\n    // greedy set cover\n    while (stSel.coveredCount < R) {\n        int best = -1;\n        int bestGain = -1;\n        for (int u = 0; u < R; u++) {\n            int gain = stSel.uncoveredRow[row_id[u]] + stSel.uncoveredCol[col_id[u]] - (stSel.covered[u] ? 0 : 1);\n            if (gain > bestGain) {\n                bestGain = gain;\n                best = u;\n            }\n        }\n        if (best == -1 || bestGain <= 0) break;\n        targets.push_back(best);\n        coverFrom(best, stSel, row_id, col_id, row_nodes, col_nodes);\n    }\n    // build nodes list\n    vector<char> used(R, 0);\n    vector<int> nodesList;\n    nodesList.push_back(start);\n    used[start] = 1;\n    for (int u : targets) {\n        if (!used[u]) {\n            used[u] = 1;\n            nodesList.push_back(u);\n        }\n    }\n    int M = nodesList.size();\n    if (M == 1) {\n        return {\"\", 0, stSel.coveredCount == R};\n    }\n\n    // distance matrix\n    vector<vector<int>> distMat(M, vector<int>(M, INF));\n    vector<int> dist, prev;\n    for (int i = 0; i < M; i++) {\n        dijkstra(nodesList[i], adj, dist, prev);\n        for (int j = 0; j < M; j++) {\n            distMat[i][j] = dist[nodesList[j]];\n        }\n    }\n\n    // initial tour: nearest neighbor\n    vector<int> tour;\n    tour.reserve(M + 1);\n    vector<char> vis(M, 0);\n    int curIdx = 0;\n    tour.push_back(curIdx);\n    vis[curIdx] = 1;\n    for (int cnt = 1; cnt < M; cnt++) {\n        int nxt = -1, bestD = INF;\n        for (int j = 0; j < M; j++) {\n            if (!vis[j] && distMat[curIdx][j] < bestD) {\n                bestD = distMat[curIdx][j];\n                nxt = j;\n            }\n        }\n        if (nxt == -1) {\n            for (int j = 0; j < M; j++) {\n                if (!vis[j]) {\n                    nxt = j;\n                    break;\n                }\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = 1;\n        curIdx = nxt;\n    }\n    tour.push_back(0);  // return to start\n\n    // 2-opt improvement\n    bool improved = true;\n    int len = tour.size();\n    while (improved) {\n        improved = false;\n        for (int i = 1; i < len - 2; i++) {\n            for (int j = i + 1; j < len - 1; j++) {\n                int a = tour[i - 1], b = tour[i], c = tour[j], d = tour[j + 1];\n                int curCost = distMat[a][b] + distMat[c][d];\n                int newCost = distMat[a][c] + distMat[b][d];\n                if (newCost < curCost) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // build route\n    CoverState stRoute(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, stRoute, row_id, col_id, row_nodes, col_nodes);\n    string routeStr;\n    long long costRoute = 0;\n    int currentNode = start;\n    for (size_t idx = 1; idx < tour.size(); idx++) {\n        int nextNode = nodesList[tour[idx]];\n        dijkstra(currentNode, adj, dist, prev);\n        vector<int> path = reconstructPath(currentNode, nextNode, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n            coverFrom(v, stRoute, row_id, col_id, row_nodes, col_nodes);\n        }\n        currentNode = nextNode;\n    }\n\n    // if not fully covered, fallback to greedy nearest uncovered\n    while (stRoute.coveredCount < R) {\n        dijkstra(currentNode, adj, dist, prev);\n        int target = -1, bestD = INF;\n        for (int u = 0; u < R; u++) {\n            if (stRoute.covered[u]) continue;\n            if (dist[u] < bestD) {\n                bestD = dist[u];\n                target = u;\n            }\n        }\n        if (target == -1 || bestD == INF) break;\n        vector<int> path = reconstructPath(currentNode, target, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n            coverFrom(v, stRoute, row_id, col_id, row_nodes, col_nodes);\n        }\n        currentNode = target;\n    }\n\n    // ensure return to start\n    if (currentNode != start) {\n        dijkstra(currentNode, adj, dist, prev);\n        vector<int> path = reconstructPath(currentNode, start, prev);\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n        }\n    }\n\n    return {routeStr, costRoute, stRoute.coveredCount == R};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int, int>> pos;\n    vector<int> w;\n    int R = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(grid[i][j] - '0');\n            }\n        }\n    }\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n\n    // adjacency\n    vector<vector<pair<int, int>>> adj(R);\n    int dx[4] = {-1, 1, 0, 0};\n    int dy[4] = {0, 0, -1, 1};\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = id[i][j];\n            if (u == -1) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (0 <= ni && ni < N && 0 <= nj && nj < N) {\n                    int v = id[ni][nj];\n                    if (v != -1) {\n                        adj[u].push_back({v, w[v]});\n                    }\n                }\n            }\n        }\n    }\n\n    // row segments\n    vector<int> row_id(R, -1);\n    vector<vector<int>> row_nodes;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (id[i][j] != -1) {\n                int segId = (int)row_nodes.size();\n                vector<int> seg;\n                while (j < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    row_id[u] = segId;\n                    seg.push_back(u);\n                    j++;\n                }\n                row_nodes.push_back(move(seg));\n            } else {\n                j++;\n            }\n        }\n    }\n    // column segments\n    vector<int> col_id(R, -1);\n    vector<vector<int>> col_nodes;\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (id[i][j] != -1) {\n                int segId = (int)col_nodes.size();\n                vector<int> seg;\n                while (i < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    col_id[u] = segId;\n                    seg.push_back(u);\n                    i++;\n                }\n                col_nodes.push_back(move(seg));\n            } else {\n                i++;\n            }\n        }\n    }\n\n    int start = id[si][sj];\n    RouteResult ra = buildRouteGreedy(start, R, row_id, col_id, row_nodes, col_nodes, adj, pos, w);\n    RouteResult rb = buildRouteSetCoverTSP(start, R, row_id, col_id, row_nodes, col_nodes, adj, pos, w);\n\n    string output;\n    if (ra.full && rb.full) {\n        if (rb.cost < ra.cost) output = rb.route;\n        else output = ra.route;\n    } else if (rb.full) {\n        output = rb.route;\n    } else {\n        output = ra.route;\n    }\n    cout << output << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> diff_sum(N, 0);\n    for (int i = 0; i < N; i++) {\n        int s = 0;\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n            s += d[i][k];\n        }\n        diff_sum[i] = s;\n    }\n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0), outdeg(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n        outdeg[u]++;\n    }\n    // compute height (longest distance to sink)\n    vector<int> height(N, 0);\n    for (int i = N - 1; i >= 0; i--) {\n        int h = 0;\n        for (int v : adj[i]) {\n            h = max(h, height[v] + 1);\n        }\n        height[i] = h;\n    }\n\n    vector<int> task_status(N, 0); // 0 ready/not started,1 working,2 done\n    vector<int> worker_status(M, -1);\n    vector<int> worker_start_day(M, -1);\n    vector<int> completed_count(M, 0);\n\n    // initial skill estimates\n    vector<double> mean_d(K, 0.0);\n    for (int k = 0; k < K; k++) {\n        long long s = 0;\n        for (int i = 0; i < N; i++) s += d[i][k];\n        mean_d[k] = (double)s / N;\n    }\n    std::mt19937 rng(1234567);\n    std::uniform_real_distribution<double> uni(1.3, 1.7);\n    vector<vector<double>> s_hat(M, vector<double>(K, 0.0));\n    for (int j = 0; j < M; j++) {\n        double f = uni(rng);\n        for (int k = 0; k < K; k++) {\n            s_hat[j][k] = mean_d[k] * f;\n        }\n    }\n\n    int day = 1;\n    const int MAX_CAND = 300;\n    const double SCORE_OUTWEIGHT = 0.3;\n    const double SCORE_DENOM_SHIFT = 0.5;\n    const double LR_BASE = 0.4;\n    const double LR_MIN = 0.05;\n    while (true) {\n        // gather ready tasks\n        vector<int> ready;\n        ready.reserve(N);\n        for (int i = 0; i < N; i++) {\n            if (task_status[i] == 0 && indeg[i] == 0) {\n                ready.push_back(i);\n            }\n        }\n        sort(ready.begin(), ready.end(), [&](int a, int b) {\n            if (height[a] != height[b]) return height[a] > height[b];\n            if (outdeg[a] != outdeg[b]) return outdeg[a] > outdeg[b];\n            if (diff_sum[a] != diff_sum[b]) return diff_sum[a] > diff_sum[b];\n            return a < b;\n        });\n        if ((int)ready.size() > MAX_CAND) ready.resize(MAX_CAND);\n\n        vector<int> idle_workers;\n        idle_workers.reserve(M);\n        for (int w = 0; w < M; w++) if (worker_status[w] == -1) idle_workers.push_back(w);\n\n        vector<pair<int,int>> assignments;\n\n        int W = (int)idle_workers.size();\n        int C = (int)ready.size();\n        if (W > 0 && C > 0) {\n            // precompute predicted times\n            vector<vector<double>> pred(W, vector<double>(C, 1.0));\n            for (int i = 0; i < W; i++) {\n                int w = idle_workers[i];\n                for (int j = 0; j < C; j++) {\n                    int t = ready[j];\n                    double p = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[t][k] - s_hat[w][k];\n                        if (diff > 0) p += diff;\n                    }\n                    if (p < 1.0) p = 1.0;\n                    pred[i][j] = p;\n                }\n            }\n            vector<char> task_used(C, 0);\n            while (!idle_workers.empty()) {\n                double bestScore = -1e18;\n                int bestWi = -1, bestTi = -1;\n                for (int i = 0; i < (int)idle_workers.size(); i++) {\n                    for (int j = 0; j < C; j++) {\n                        if (task_used[j]) continue;\n                        double p = pred[i][j];\n                        double score = (height[ready[j]] + SCORE_OUTWEIGHT * outdeg[ready[j]] + 1.0) / (p + SCORE_DENOM_SHIFT);\n                        if (score > bestScore) {\n                            bestScore = score;\n                            bestWi = i;\n                            bestTi = j;\n                        }\n                    }\n                }\n                if (bestWi == -1) break;\n                int w = idle_workers[bestWi];\n                int t = ready[bestTi];\n                assignments.push_back({w, t});\n                worker_status[w] = t;\n                worker_start_day[w] = day;\n                task_status[t] = 1;\n                task_used[bestTi] = 1;\n                idle_workers[bestWi] = idle_workers.back();\n                idle_workers.pop_back();\n            }\n        }\n\n        // output\n        cout << assignments.size();\n        for (auto &p : assignments) {\n            cout << \" \" << (p.first + 1) << \" \" << (p.second + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n\n        // input feedback\n        int nfin;\n        if (!(cin >> nfin)) break;\n        if (nfin == -1) {\n            break;\n        }\n        vector<int> fs(nfin);\n        for (int i = 0; i < nfin; i++) cin >> fs[i];\n        for (int idx = 0; idx < nfin; idx++) {\n            int w = fs[idx] - 1;\n            int tid = worker_status[w];\n            if (tid < 0) continue;\n            int duration = day - worker_start_day[w] + 1;\n            task_status[tid] = 2;\n            completed_count[w]++;\n            // update indegrees\n            for (int v : adj[tid]) {\n                indeg[v]--;\n            }\n            // skill update\n            double target = max(0.0, (double)duration - 1.0);\n            double pred_w = 0.0;\n            vector<int> active;\n            active.reserve(K);\n            for (int k = 0; k < K; k++) {\n                double diff = d[tid][k] - s_hat[w][k];\n                if (diff > 0) {\n                    pred_w += diff;\n                    active.push_back(k);\n                }\n            }\n            double lr = LR_BASE / sqrt((double)completed_count[w]);\n            if (lr < LR_MIN) lr = LR_MIN;\n            if (!active.empty()) {\n                double delta = lr * (pred_w - target) / active.size();\n                for (int k : active) {\n                    s_hat[w][k] += delta;\n                    if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                    if (s_hat[w][k] > 120) s_hat[w][k] = 120;\n                }\n            } else {\n                // no active dims, but took >1 day => overestimated skills\n                if (target > 0.0) {\n                    vector<int> idxs(K);\n                    iota(idxs.begin(), idxs.end(), 0);\n                    sort(idxs.begin(), idxs.end(), [&](int a, int b){ return d[tid][a] > d[tid][b]; });\n                    int use = min(3, K);\n                    double delta = lr * target / use;\n                    for (int i = 0; i < use; i++) {\n                        int k = idxs[i];\n                        s_hat[w][k] -= delta;\n                        if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                    }\n                } else {\n                    // took 1 day, maybe noise, do nothing\n                }\n            }\n            worker_status[w] = -1;\n        }\n        day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int NORD = 1000;\nconst int CHOOSE = 50;\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst double GLOBAL_TIME_LIMIT = 1.90; // seconds\n\nint ax[NORD], byy[NORD], cx[NORD], dy[NORD];\ndouble midx[NORD], midy[NORD];\n\ninline int mdist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Greedy nearest feasible neighbor route (used in search)\nlong long route_nearest(const int* subset, int k, vector<pair<int,int>>* path = nullptr) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < k; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int done = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (path) {\n        path->clear();\n        path->reserve(k * 2 + 2);\n        path->push_back({curx, cury});\n    }\n    while (done < k) {\n        int best = -1;\n        int bestd = INT_MAX;\n        int tx = 0, ty = 0;\n        for (int i = 0; i < k; i++) {\n            if (status[i] == 2) continue;\n            int x = (status[i] == 0 ? px[i] : qx[i]);\n            int y = (status[i] == 0 ? py[i] : qy[i]);\n            int d = abs(curx - x) + abs(cury - y);\n            if (d < bestd) {\n                bestd = d;\n                best = i;\n                tx = x;\n                ty = y;\n            }\n        }\n        total += bestd;\n        curx = tx; cury = ty;\n        if (path) path->push_back({curx, cury});\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; done++; }\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (path) path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\n// Pick nearest pickup, deliver immediately\nlong long route_immediate(const int* subset, int k, vector<pair<int,int>>* path = nullptr) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < k; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool rem[CHOOSE];\n    memset(rem, 1, sizeof(bool) * k);\n    int remaining = k;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (path) {\n        path->clear();\n        path->reserve(k * 2 + 2);\n        path->push_back({curx, cury});\n    }\n    while (remaining > 0) {\n        int best = -1;\n        int bestd = INT_MAX;\n        for (int i = 0; i < k; i++) {\n            if (!rem[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) {\n                bestd = d;\n                best = i;\n            }\n        }\n        total += bestd;\n        curx = px[best]; cury = py[best];\n        if (path) path->push_back({curx, cury});\n        int d2 = abs(curx - qx[best]) + abs(cury - qy[best]);\n        total += d2;\n        curx = qx[best]; cury = qy[best];\n        if (path) path->push_back({curx, cury});\n        rem[best] = false;\n        remaining--;\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (path) path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\n// Pick all by NN then deliver all by NN\nlong long route_pick_then_drop(const int* subset, int k, vector<pair<int,int>>* path = nullptr) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < k; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool picked[CHOOSE];\n    bool deliv[CHOOSE];\n    memset(picked, 0, sizeof(picked));\n    memset(deliv, 0, sizeof(deliv));\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    if (path) {\n        path->clear();\n        path->reserve(k * 2 + 2);\n        path->push_back({curx, cury});\n    }\n    int pcnt = 0, dcnt = 0;\n    while (pcnt < k) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < k; i++) {\n            if (picked[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) {\n                bestd = d; best = i;\n            }\n        }\n        total += bestd;\n        curx = px[best]; cury = py[best];\n        if (path) path->push_back({curx, cury});\n        picked[best] = true; pcnt++;\n    }\n    while (dcnt < k) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < k; i++) {\n            if (deliv[i]) continue;\n            int d = abs(curx - qx[i]) + abs(cury - qy[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        total += bestd;\n        curx = qx[best]; cury = qy[best];\n        if (path) path->push_back({curx, cury});\n        deliv[best] = true; dcnt++;\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    if (path) path->push_back({DEPOT_X, DEPOT_Y});\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < NORD; i++) {\n        if (!(cin >> ax[i] >> byy[i] >> cx[i] >> dy[i])) return 0;\n        midx[i] = 0.5 * (ax[i] + cx[i]);\n        midy[i] = 0.5 * (byy[i] + dy[i]);\n    }\n\n    auto start_all = chrono::steady_clock::now();\n\n    // baseline cost\n    vector<long long> cost(NORD);\n    for (int i = 0; i < NORD; i++) {\n        cost[i] = mdist(DEPOT_X, DEPOT_Y, ax[i], byy[i]) +\n                  mdist(ax[i], byy[i], cx[i], dy[i]) +\n                  mdist(cx[i], dy[i], DEPOT_X, DEPOT_Y);\n    }\n    vector<int> order_ids(NORD);\n    iota(order_ids.begin(), order_ids.end(), 0);\n    sort(order_ids.begin(), order_ids.end(), [&](int i, int j){ return cost[i] < cost[j]; });\n\n    array<int, CHOOSE> bestSubset;\n    for (int i = 0; i < CHOOSE; i++) bestSubset[i] = order_ids[i];\n    long long bestT = route_nearest(bestSubset.data(), CHOOSE);\n\n    // Cluster-based initial solutions\n    vector<pair<double,double>> seedPoints;\n    for (int gx = 0; gx <= 800; gx += 200) {\n        for (int gy = 0; gy <= 800; gy += 200) {\n            seedPoints.emplace_back(gx, gy);\n        }\n    }\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> distCoord(0, 800);\n    int randomSeeds = 40;\n    for (int i = 0; i < randomSeeds; i++) {\n        seedPoints.emplace_back(distCoord(rng), distCoord(rng));\n    }\n\n    vector<int> ids(NORD);\n    iota(ids.begin(), ids.end(), 0);\n\n    for (auto &sp : seedPoints) {\n        double sx = sp.first, sy = sp.second;\n        sort(ids.begin(), ids.end(), [&](int i, int j) {\n            double dx1 = midx[i] - sx, dy1 = midy[i] - sy;\n            double dx2 = midx[j] - sx, dy2 = midy[j] - sy;\n            return dx1*dx1 + dy1*dy1 < dx2*dx2 + dy2*dy2;\n        });\n        array<int, CHOOSE> cand;\n        for (int i = 0; i < CHOOSE; i++) cand[i] = ids[i];\n        long long t = route_nearest(cand.data(), CHOOSE);\n        if (t < bestT) {\n            bestT = t;\n            bestSubset = cand;\n        }\n    }\n\n    array<int, CHOOSE> curSubset = bestSubset;\n    long long curT = bestT;\n\n    // Build outList\n    vector<int> outList;\n    outList.reserve(NORD - CHOOSE);\n    vector<char> inSel(NORD, 0);\n    for (int i = 0; i < CHOOSE; i++) inSel[curSubset[i]] = 1;\n    for (int i = 0; i < NORD; i++) if (!inSel[i]) outList.push_back(i);\n\n    auto now = chrono::steady_clock::now();\n    double elapsed = chrono::duration<double>(now - start_all).count();\n    double time_left = GLOBAL_TIME_LIMIT - elapsed;\n    if (time_left > 0.05) {\n        auto end_time = now + chrono::duration<double>(time_left);\n        uniform_int_distribution<int> distIn(0, CHOOSE-1);\n        uniform_real_distribution<double> distReal(0.0, 1.0);\n        int outSize = NORD - CHOOSE;\n        uniform_int_distribution<int> distOut(0, outSize-1);\n        double startTemp = 3000.0, endTemp = 30.0;\n        double temp = startTemp;\n        long long iter = 0;\n        while (true) {\n            if ((iter & 0x3FF) == 0) {\n                now = chrono::steady_clock::now();\n                if (now >= end_time) break;\n                double progress = chrono::duration<double>(now - start_all).count() / GLOBAL_TIME_LIMIT;\n                if (progress > 1.0) progress = 1.0;\n                temp = startTemp * pow(endTemp / startTemp, progress);\n            }\n            iter++;\n            int idxIn = distIn(rng);\n            int idxOut = distOut(rng);\n            int oldIn = curSubset[idxIn];\n            int newIn = outList[idxOut];\n            curSubset[idxIn] = newIn;\n            long long newT = route_nearest(curSubset.data(), CHOOSE);\n            bool accept = false;\n            if (newT < curT) {\n                accept = true;\n            } else {\n                double diff = double(curT - newT);\n                double prob = exp(diff / temp);\n                if (distReal(rng) < prob) accept = true;\n            }\n            if (accept) {\n                curT = newT;\n                outList[idxOut] = oldIn;\n                if (newT < bestT) {\n                    bestT = newT;\n                    bestSubset = curSubset;\n                }\n            } else {\n                curSubset[idxIn] = oldIn; // revert\n            }\n        }\n    }\n\n    // Build final route using the best of several heuristics\n    vector<pair<int,int>> bestPath, tmpPath;\n    long long bestRouteCost = (1LL << 60);\n    long long t1 = route_nearest(bestSubset.data(), CHOOSE, &tmpPath);\n    if (t1 < bestRouteCost) {\n        bestRouteCost = t1;\n        bestPath = tmpPath;\n    }\n    long long t2 = route_immediate(bestSubset.data(), CHOOSE, &tmpPath);\n    if (t2 < bestRouteCost) {\n        bestRouteCost = t2;\n        bestPath = tmpPath;\n    }\n    long long t3 = route_pick_then_drop(bestSubset.data(), CHOOSE, &tmpPath);\n    if (t3 < bestRouteCost) {\n        bestRouteCost = t3;\n        bestPath = tmpPath;\n    }\n\n    // Output\n    cout << CHOOSE;\n    for (int i = 0; i < CHOOSE; i++) {\n        cout << ' ' << (bestSubset[i] + 1); // convert to 1-based\n    }\n    cout << '\\n';\n    cout << bestPath.size();\n    for (auto &p : bestPath) {\n        cout << ' ' << p.first << ' ' << p.second;\n    }\n    cout << '\\n';\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, sz;\n    DSU(int n_=0): n(n_), p(n_), sz(n_,1) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }\n    bool merge(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b];\n        return true;\n    }\n};\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u,v;\n    int d;\n    bool in_mst=false;\n};\n\nvector<Edge> edges(M);\nvector<int> xs(N), ys(N);\n\n// low-link globals\nvector<int> tin, low;\nvector<char> vis, is_bridge;\nvector<vector<pair<int,int>>> adj;\nint timer_dfs;\n\n// recompute bridges on graph of alive edges\nvoid compute_bridges(const vector<char>& alive){\n    for(int i=0;i<N;i++) adj[i].clear();\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        adj[u].push_back({v,id});\n        adj[v].push_back({u,id});\n    }\n    fill(vis.begin(), vis.end(), 0);\n    fill(is_bridge.begin(), is_bridge.end(), 0);\n    timer_dfs = 0;\n    function<void(int,int)> dfs = [&](int v,int pe){\n        vis[v]=1;\n        tin[v]=low[v]=++timer_dfs;\n        for(auto [to,eid]: adj[v]){\n            if(eid==pe) continue;\n            if(vis[to]){\n                low[v]=min(low[v], tin[to]);\n            }else{\n                dfs(to,eid);\n                low[v]=min(low[v], low[to]);\n                if(low[to] > tin[v]){\n                    is_bridge[eid]=1;\n                }\n            }\n        }\n    };\n    for(int i=0;i<N;i++){\n        if(!vis[i]) dfs(i,-1);\n    }\n}\n\n// compute out degree (alive edges to other comps) for each component\nvoid compute_out_count(const vector<char>& alive, DSU &dsu, vector<int>& out_cnt){\n    fill(out_cnt.begin(), out_cnt.end(), 0);\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        int ru=dsu.find(u), rv=dsu.find(v);\n        if(ru==rv) continue;\n        out_cnt[ru]++; out_cnt[rv]++;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<N;i++){\n        if(!(cin>>xs[i]>>ys[i])) return 0;\n    }\n    for(int i=0;i<M;i++){\n        int u,v;\n        cin>>u>>v;\n        edges[i].u=u;\n        edges[i].v=v;\n        long dx=xs[u]-xs[v];\n        long dy=ys[u]-ys[v];\n        edges[i].d = (int)llround(sqrt((double)(dx*dx + dy*dy)));\n    }\n\n    // compute MST on baseline distances d\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n        return a < b;\n    });\n    DSU dsu0(N);\n    int added=0;\n    for(int id: ord){\n        if(dsu0.merge(edges[id].u, edges[id].v)){\n            edges[id].in_mst = true;\n            if(++added == N-1) break;\n        }\n    }\n\n    vector<char> alive(M, 1);\n    DSU dsu_conn(N);\n    int comp_cnt = N;\n\n    tin.assign(N,0); low.assign(N,0); vis.assign(N,0);\n    is_bridge.assign(M,0);\n    adj.assign(N, {});\n    vector<int> out_cnt(N,0);\n\n    const double MST_START = 1.45;\n    const double MST_END   = 1.90;\n    const double OTH_START = 1.25;\n    const double OTH_END   = 1.60;\n    const double ALPHA     = 0.5;\n\n    for(int i=0;i<M;i++){\n        int l;\n        if(!(cin>>l)) break;\n        double r = (double)l / (double)edges[i].d;\n\n        compute_bridges(alive);\n        compute_out_count(alive, dsu_conn, out_cnt);\n\n        bool accept = false;\n        if(is_bridge[i]){\n            accept = true;\n        }else{\n            int ru = dsu_conn.find(edges[i].u);\n            int rv = dsu_conn.find(edges[i].v);\n            if(ru != rv){\n                double prog = (double)i / (double)(M-1);\n                double f = pow(prog, ALPHA);\n                double thr;\n                if(edges[i].in_mst){\n                    thr = MST_START + (MST_END - MST_START) * f;\n                }else{\n                    thr = OTH_START + (OTH_END - OTH_START) * f;\n                }\n                int k = min(out_cnt[ru], out_cnt[rv]);\n                if(k <= 2) thr += 0.30;\n                else if(k <= 4) thr += 0.15;\n                else if(k <= 6) thr += 0.07;\n\n                int rem = M - i - 1;\n                int need = comp_cnt - 1;\n                if(need > 0){\n                    if(rem <= need * 2) thr += 0.50;\n                    else if(rem <= need * 3) thr += 0.20;\n                }\n\n                if(thr > 2.8) thr = 2.8;\n                if(r <= thr) accept = true;\n            }else{\n                accept = false; // do not take cycle edges\n            }\n        }\n\n        if(accept){\n            if(dsu_conn.merge(edges[i].u, edges[i].v)) comp_cnt--;\n        }else{\n            alive[i]=0;\n        }\n\n        cout << (accept ? 1 : 0) << '\\n';\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet { int x,y,t; };\n\nint N,M;\nvector<Pet> pets;\nvector<int> hx, hy;\nvector<vector<bool>> wall(31, vector<bool>(31,false));\n\nint r1,r2,c1,c2;\nint colWallCol,rowWallRow;\nint builderCol,builderRow;\nchar colDir,rowDir;\nint entryWallX, entryWallY;\npair<int,int> entryDest;\nchar gapOrient; // 'R' for row wall gap, 'C' for col wall gap\nint T_close;\n\ninline int encode(int x,int y){ return x*64 + y; }\n\nint dist_point_to_rect(int px,int py,int r1,int r2,int c1,int c2){\n    int dx=0, dy=0;\n    if(px<r1) dx=r1-px;\n    else if(px>r2) dx=px-r2;\n    if(py<c1) dy=c1-py;\n    else if(py>c2) dy=py-c2;\n    return dx+dy;\n}\n\nbool can_build(int wx,int wy,const vector<Pet>& pets,const vector<int>& hx,const vector<int>& hy){\n    if(wx<1 || wx>30 || wy<1 || wy>30) return false;\n    for(auto &p: pets){\n        if(p.x==wx && p.y==wy) return false;\n        if(abs(p.x-wx)+abs(p.y-wy)<=1) return false;\n    }\n    for(size_t i=0;i<hx.size();i++){\n        if(hx[i]==wx && hy[i]==wy) return false;\n    }\n    return true;\n}\n\nchar bfs_move(int sx,int sy,int tx,int ty,bool regionOnly,const unordered_set<int>& buildTargets){\n    auto blocked=[&](int x,int y)->bool{\n        if(x<1||x>30||y<1||y>30) return true;\n        if(regionOnly && (x<r1 || x>r2 || y<c1 || y>c2)) return true;\n        if(wall[x][y]) return true;\n        if(buildTargets.find(encode(x,y))!=buildTargets.end()) return true;\n        return false;\n    };\n    if(blocked(tx,ty)) return '.';\n    static int dist[31][31];\n    for(int i=1;i<=30;i++) for(int j=1;j<=30;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[tx][ty]=0;\n    q.push({tx,ty});\n    int dxs[4]={-1,1,0,0};\n    int dys[4]={0,0,-1,1};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        int nd=dist[x][y]+1;\n        for(int d=0;d<4;d++){\n            int nx=x+dxs[d], ny=y+dys[d];\n            if(blocked(nx,ny)) continue;\n            if(dist[nx][ny]==-1){\n                dist[nx][ny]=nd;\n                q.push({nx,ny});\n            }\n        }\n    }\n    if(dist[sx][sy]<=0) return '.';\n    char dirc[4]={'U','D','L','R'};\n    for(int d=0;d<4;d++){\n        int nx=sx+dxs[d], ny=sy+dys[d];\n        if(nx<1||nx>30||ny<1||ny>30) continue;\n        if(regionOnly && (nx<r1||nx>r2||ny<c1||ny>c2)) continue;\n        if(blocked(nx,ny)) continue;\n        if(dist[nx][ny]==dist[sx][sy]-1) return dirc[d];\n    }\n    return '.';\n}\n\nvoid select_region(const vector<int>& initHx, const vector<int>& initHy){\n    double bestScore=-1e18;\n    int bestR1=1,bestR2=5,bestC1=1,bestC2=5;\n    bool foundZero=false;\n    for(int k=12;k>=5;k--){\n        for(int corner=0;corner<4;corner++){\n            int rr1,rr2,cc1,cc2;\n            switch(corner){\n                case 0: rr1=1; rr2=k; cc1=1; cc2=k; break;\n                case 1: rr1=1; rr2=k; cc1=30-k+1; cc2=30; break;\n                case 2: rr1=30-k+1; rr2=30; cc1=1; cc2=k; break;\n                default: rr1=30-k+1; rr2=30; cc1=30-k+1; cc2=30; break;\n            }\n            int inside=0;\n            int minDistPet=1000;\n            for(auto &p: pets){\n                if(rr1<=p.x && p.x<=rr2 && cc1<=p.y && p.y<=cc2) inside++;\n                int d=dist_point_to_rect(p.x,p.y,rr1,rr2,cc1,cc2);\n                minDistPet=min(minDistPet,d);\n            }\n            if(pets.empty()) minDistPet=100;\n            int maxHD=0;\n            int midc=(cc1+cc2)/2;\n            int midr=(rr1+rr2)/2;\n            for(size_t i=0;i<initHx.size();i++){\n                int d=abs(initHx[i]-midr)+abs(initHy[i]-midc);\n                maxHD=max(maxHD,d);\n            }\n            double area=k*k;\n            if(!foundZero && inside>0) continue;\n            if(inside==0) foundZero=true;\n            double score = area*1.5 + minDistPet*10.0 - maxHD*2.0 - inside*500.0;\n            if(score>bestScore){\n                bestScore=score;\n                bestR1=rr1; bestR2=rr2; bestC1=cc1; bestC2=cc2;\n            }\n        }\n        if(foundZero) break;\n    }\n    r1=bestR1; r2=bestR2; c1=bestC1; c2=bestC2;\n    if(c1==1){ colWallCol=c2+1; colDir='r'; builderCol=c2; }\n    else { colWallCol=c1-1; colDir='l'; builderCol=c1; }\n    if(r1==1){ rowWallRow=r2+1; rowDir='d'; builderRow=r2; }\n    else { rowWallRow=r1-1; rowDir='u'; builderRow=r1; }\n\n    // select opening (gap) position maximizing distance to nearest pet\n    int bestDist=-1;\n    gapOrient='R';\n    entryWallX=rowWallRow;\n    entryWallY=(c1+c2)/2;\n    entryDest={builderRow, entryWallY};\n    // row candidates\n    for(int y=c1; y<=c2; y++){\n        int gx=rowWallRow, gy=y;\n        int mind=1000;\n        for(auto &p: pets){\n            int d=abs(p.x-gx)+abs(p.y-gy);\n            mind=min(mind,d);\n        }\n        if(mind>bestDist){\n            bestDist=mind;\n            gapOrient='R';\n            entryWallX=gx; entryWallY=gy;\n            entryDest={builderRow, gy};\n        }\n    }\n    // col candidates\n    for(int x=r1; x<=r2; x++){\n        int gx=x, gy=colWallCol;\n        int mind=1000;\n        for(auto &p: pets){\n            int d=abs(p.x-gx)+abs(p.y-gy);\n            mind=min(mind,d);\n        }\n        if(mind>bestDist){\n            bestDist=mind;\n            gapOrient='C';\n            entryWallX=gx; entryWallY=gy;\n            entryDest={x, builderCol};\n        }\n    }\n    // T_close based on human distances\n    int maxD=0;\n    for(size_t i=0;i<initHx.size();i++){\n        int d=abs(initHx[i]-entryDest.first)+abs(initHy[i]-entryDest.second);\n        maxD=max(maxD,d);\n    }\n    int perimeter = (r2-r1+1)+(c2-c1+1);\n    T_close = min(80, max(30, maxD + perimeter/ (int)max(1,M) + 5));\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N;\n    pets.resize(N);\n    for(int i=0;i<N;i++) cin>>pets[i].x>>pets[i].y>>pets[i].t;\n    cin>>M;\n    hx.resize(M); hy.resize(M);\n    for(int i=0;i<M;i++) cin>>hx[i]>>hy[i];\n    vector<int> initHx=hx, initHy=hy;\n    select_region(initHx, initHy);\n\n    vector<pair<int,int>> colCells,rowCells;\n    for(int r=r1; r<=r2; r++) colCells.push_back({r,colWallCol});\n    for(int c=c1; c<=c2; c++) rowCells.push_back({rowWallRow,c});\n\n    for(int turn=0; turn<300; turn++){\n        bool all_inside=true;\n        int insideCnt=0;\n        for(int i=0;i<M;i++){\n            if(r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2) insideCnt++;\n            else all_inside=false;\n        }\n        bool petInside=false;\n        int petGapDist=1000;\n        for(auto &p: pets){\n            if(r1<=p.x && p.x<=r2 && c1<=p.y && p.y<=c2) petInside=true;\n            petGapDist=min(petGapDist, abs(p.x-entryWallX)+abs(p.y-entryWallY));\n        }\n        bool close_condition=false;\n        if(all_inside || turn>=T_close) close_condition=true;\n        if(insideCnt>= (M+1)/2 && petGapDist<=1) close_condition=true;\n\n        // compute missing walls\n        vector<int> colMissingRows;\n        for(auto &p: colCells){\n            if(gapOrient=='C' && p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) colMissingRows.push_back(p.first);\n        }\n        vector<int> rowMissingCols;\n        for(auto &p: rowCells){\n            if(gapOrient=='R' && p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) rowMissingCols.push_back(p.second);\n        }\n\n        unordered_set<int> buildTargets;\n        string actions(M,'.');\n\n        // attempt builds\n        for(int i=0;i<M;i++){\n            // col wall build\n            if(r1<=hx[i] && hx[i]<=r2 && hy[i]==builderCol){\n                if(!colMissingRows.empty()){\n                    if(!wall[hx[i]][colWallCol]){\n                        int wx=hx[i], wy=colWallCol;\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=colDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n            // row wall build\n            if(hx[i]==builderRow && hy[i]>=c1 && hy[i]<=c2){\n                if(!rowMissingCols.empty()){\n                    if(!wall[rowWallRow][hy[i]]){\n                        int wx=rowWallRow, wy=hy[i];\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=rowDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n        }\n\n        // movement\n        for(int i=0;i<M;i++){\n            if(actions[i]!='.') continue;\n            bool inside = (r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2);\n            if(!inside){\n                char mv=bfs_move(hx[i],hy[i],entryDest.first, entryDest.second, false, buildTargets);\n                actions[i]=mv;\n            }else{\n                if(!colMissingRows.empty()){\n                    int bestd=1e9, targRow=colMissingRows[0];\n                    for(int rr: colMissingRows){\n                        int d=abs(rr-hx[i])+abs(builderCol-hy[i]);\n                        if(d<bestd){bestd=d; targRow=rr;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],targRow,builderCol,true,buildTargets);\n                    actions[i]=mv;\n                }else if(!rowMissingCols.empty()){\n                    int bestd=1e9, targCol=rowMissingCols[0];\n                    for(int cc: rowMissingCols){\n                        int d=abs(builderRow-hx[i])+abs(cc-hy[i]);\n                        if(d<bestd){bestd=d; targCol=cc;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],builderRow,targCol,true,buildTargets);\n                    actions[i]=mv;\n                }else{\n                    actions[i]='.';\n                }\n            }\n        }\n\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // read pet moves\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            if(s==\".\") continue;\n            for(char ch: s){\n                if(ch=='U') pets[i].x--;\n                else if(ch=='D') pets[i].x++;\n                else if(ch=='L') pets[i].y--;\n                else if(ch=='R') pets[i].y++;\n            }\n        }\n        // apply builds\n        for(int key: buildTargets){\n            int wx=key/64, wy=key%64;\n            if(wx>=1 && wx<=30 && wy>=1 && wy<=30) wall[wx][wy]=true;\n        }\n        // move humans\n        for(int i=0;i<M;i++){\n            char ac=actions[i];\n            if(ac=='U') hx[i]--;\n            else if(ac=='D') hx[i]++;\n            else if(ac=='L') hy[i]--;\n            else if(ac=='R') hy[i]++;\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int DIRS = 4;\nconst int L = 200;\nconst double TIME_LIMIT = 1.95;\n\nint startId, targetId;\ndouble p_forget, q_exec;\n\nint moveTbl[N][DIRS];\ndouble weightArr[L];\ndouble weight_q[L];\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> uni01(0.0, 1.0);\n\ninline int idx(int i, int j) { return i * W + j; }\n\nvoid build_moves(const vector<string> &h, const vector<string> &v) {\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int id = idx(i, j);\n            // Up\n            if (i == 0 || v[i - 1][j] == '1')\n                moveTbl[id][0] = id;\n            else\n                moveTbl[id][0] = idx(i - 1, j);\n            // Down\n            if (i == H - 1 || v[i][j] == '1')\n                moveTbl[id][1] = id;\n            else\n                moveTbl[id][1] = idx(i + 1, j);\n            // Left\n            if (j == 0 || h[i][j - 1] == '1')\n                moveTbl[id][2] = id;\n            else\n                moveTbl[id][2] = idx(i, j - 1);\n            // Right\n            if (j == W - 1 || h[i][j] == '1')\n                moveTbl[id][3] = id;\n            else\n                moveTbl[id][3] = idx(i, j + 1);\n        }\n    }\n}\n\nvector<int> bfs_path(bool monotone_only) {\n    vector<int> prev(N, -1), prevDir(N, -1);\n    vector<char> vis(N, 0);\n    queue<int> q;\n    vis[startId] = 1;\n    q.push(startId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        if (u == targetId) break;\n        for (int dir = 0; dir < DIRS; dir++) {\n            if (monotone_only && !(dir == 1 || dir == 3)) continue; // only D or R\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (!vis[nb]) {\n                vis[nb] = 1;\n                prev[nb] = u;\n                prevDir[nb] = dir;\n                q.push(nb);\n            }\n        }\n    }\n    if (!vis[targetId]) return {};\n    vector<int> path;\n    int cur = targetId;\n    while (cur != startId) {\n        int d = prevDir[cur];\n        path.push_back(d);\n        cur = prev[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid compute_distances(vector<double> &dist1, vector<double> &dist2) {\n    dist1.assign(N, 1e9);\n    queue<int> q;\n    dist1[targetId] = 0;\n    q.push(targetId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        double du = dist1[u];\n        for (int dir = 0; dir < DIRS; dir++) {\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (dist1[nb] > du + 1) {\n                dist1[nb] = du + 1;\n                q.push(nb);\n            }\n        }\n    }\n    dist2.resize(N);\n    for (int i = 0; i < N; i++) dist2[i] = dist1[i] * dist1[i];\n}\n\nvector<int> greedy_seq(const vector<double> &dist, double eps) {\n    vector<double> cur(N, 0.0), nxt(N, 0.0);\n    cur[startId] = 1.0;\n    vector<int> seq(L);\n    static const int tieOrd[4] = {1, 3, 2, 0};\n    for (int t = 0; t < L; t++) {\n        double bestVal = 1e100;\n        int bestDir = 0;\n        double scores[4] = {0, 0, 0, 0};\n        for (int dir = 0; dir < DIRS; dir++) {\n            double s = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                s += pu * dist[nb];\n            }\n            scores[dir] = s;\n        }\n        bestDir = tieOrd[0];\n        bestVal = scores[bestDir];\n        for (int k = 1; k < 4; k++) {\n            int d = tieOrd[k];\n            double v = scores[d];\n            if (v < bestVal) {\n                bestVal = v;\n                bestDir = d;\n            }\n        }\n        if (eps > 0.0) {\n            double r = uni01(rng);\n            if (r < eps) {\n                bestDir = rng() & 3ULL;\n            }\n        }\n        seq[t] = bestDir;\n        fill(nxt.begin(), nxt.end(), 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb != targetId) nxt[nb] += mv;\n            nxt[u] += pu * p_forget;\n        }\n        cur.swap(nxt);\n    }\n    return seq;\n}\n\nvector<int> repeat_path_seed(const vector<int> &path, int r) {\n    vector<int> seq;\n    if (path.empty()) return seq;\n    seq.reserve(L);\n    for (int d : path) {\n        for (int k = 0; k < r && (int)seq.size() < L; k++) seq.push_back(d);\n        if ((int)seq.size() >= L) break;\n    }\n    while ((int)seq.size() < L) {\n        for (int d : path) {\n            if ((int)seq.size() >= L) break;\n            seq.push_back(d);\n        }\n    }\n    if ((int)seq.size() > L) seq.resize(L);\n    return seq;\n}\n\nvector<int> ratio_seed(int dv, int dh) {\n    vector<int> seq;\n    seq.reserve(L);\n    int total = max(1, dv + dh);\n    int nD = (int)round((double)L * dv / total);\n    nD = max(0, min(L, nD));\n    int nR = L - nD;\n    int cD = 0, cR = 0;\n    while ((int)seq.size() < L) {\n        double pd = (nD - cD);\n        double pr = (nR - cR);\n        if (pd <= 0) {\n            seq.push_back(3);\n            cR++;\n        } else if (pr <= 0) {\n            seq.push_back(1);\n            cD++;\n        } else {\n            double probD = pd / (pd + pr);\n            if (uni01(rng) < probD) {\n                seq.push_back(1);\n                cD++;\n            } else {\n                seq.push_back(3);\n                cR++;\n            }\n        }\n    }\n    return seq;\n}\n\ndouble eval_seq(const vector<int> &seq) {\n    static double cur[N], nxt[N];\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double score = 0.0;\n    for (int t = 0; t < L; t++) {\n        int dir = seq[t];\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][dir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\nstatic double backVal[L + 1][N];\n\nvoid compute_backward(const vector<int> &seq) {\n    for (int u = 0; u < N; u++) backVal[L][u] = 0.0;\n    for (int t = L - 1; t >= 0; t--) {\n        int dir = seq[t];\n        double wq = weight_q[t];\n        for (int u = 0; u < N; u++) {\n            int nb = moveTbl[u][dir];\n            double val = p_forget * backVal[t + 1][u];\n            if (nb == targetId) {\n                val += wq;\n            } else {\n                val += q_exec * backVal[t + 1][nb];\n            }\n            backVal[t][u] = val;\n        }\n    }\n}\n\ndouble build_new_seq(vector<int> &outSeq) {\n    static double curDist[N], nextDist[N];\n    fill(curDist, curDist + N, 0.0);\n    curDist[startId] = 1.0;\n    double score = 0.0;\n    static const int tieOrd[4] = {1, 3, 2, 0};\n    for (int t = 0; t < L; t++) {\n        double stay = 0.0;\n        for (int u = 0; u < N; u++) {\n            stay += curDist[u] * backVal[t + 1][u];\n        }\n        stay *= p_forget;\n        double bestVal = -1e100;\n        int bestDir = tieOrd[0];\n        for (int ki = 0; ki < 4; ki++) {\n            int dir = tieOrd[ki];\n            double sum = stay;\n            const double *backNext = backVal[t + 1];\n            for (int u = 0; u < N; u++) {\n                double pu = curDist[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                if (nb == targetId) sum += pu * weight_q[t];\n                else sum += pu * q_exec * backNext[nb];\n            }\n            if (sum > bestVal) {\n                bestVal = sum;\n                bestDir = dir;\n            }\n        }\n        outSeq[t] = bestDir;\n        fill(nextDist, nextDist + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = curDist[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nextDist[nb] += mv;\n            }\n            nextDist[u] += pu * p_forget;\n        }\n        swap(curDist, nextDist);\n    }\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj, ti, tj;\n    if (!(cin >> si >> sj >> ti >> tj >> p_forget)) return 0;\n    startId = idx(si, sj);\n    targetId = idx(ti, tj);\n    q_exec = 1.0 - p_forget;\n    vector<string> h(H), v(H - 1);\n    for (int i = 0; i < H; i++) cin >> h[i];\n    for (int i = 0; i < H - 1; i++) cin >> v[i];\n    for (int t = 0; t < L; t++) {\n        weightArr[t] = 400.0 - t;\n        weight_q[t] = weightArr[t] * q_exec;\n    }\n    auto time_start = chrono::steady_clock::now();\n    double time_limit = TIME_LIMIT;\n\n    build_moves(h, v);\n    vector<double> dist1, dist2;\n    compute_distances(dist1, dist2);\n    vector<int> shortest = bfs_path(false);\n    vector<int> monotone = bfs_path(true);\n\n    vector<vector<int>> seeds;\n    seeds.push_back(greedy_seq(dist1, 0.0));\n    seeds.push_back(greedy_seq(dist2, 0.0));\n    seeds.push_back(greedy_seq(dist1, 0.1));\n    seeds.push_back(greedy_seq(dist1, 0.3));\n    int rep_suggest = max(1, min(8, (int)ceil(log(0.1) / log(max(0.05, p_forget))))); // target ~90% success\n    if (!shortest.empty()) seeds.push_back(repeat_path_seed(shortest, rep_suggest));\n    if (!monotone.empty()) seeds.push_back(repeat_path_seed(monotone, rep_suggest));\n    seeds.push_back(ratio_seed(ti - si, tj - sj));\n\n    vector<pair<double, vector<int>>> seedScores;\n    seedScores.reserve(seeds.size());\n    for (auto &s : seeds) {\n        if ((int)s.size() != L) continue;\n        double sc = eval_seq(s);\n        seedScores.emplace_back(sc, s);\n    }\n    if (seedScores.empty()) return 0;\n    sort(seedScores.begin(), seedScores.end(),\n         [](const auto &a, const auto &b) { return a.first > b.first; });\n\n    double bestScore = -1.0;\n    vector<int> bestSeq;\n    int topK = min(4, (int)seedScores.size());\n    for (int i = 0; i < topK; i++) {\n        vector<int> seq = seedScores[i].second;\n        double curScore = seedScores[i].first;\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > time_limit) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 200) break;\n        }\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > time_limit) break;\n    }\n\n    // Random restarts if time remains\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > time_limit) break;\n        double eps = uni01(rng) * uni01(rng) * 0.5;\n        vector<int> seq = greedy_seq(dist1, eps);\n        double curScore = eval_seq(seq);\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > time_limit) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 50) break;\n        }\n    }\n\n    string out;\n    out.reserve(L);\n    for (int d : bestSeq) {\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        out.push_back(c);\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOT = N * N * 4;\nconst int di[4] = {0, -1, 0, 1};   // L,U,R,D\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Heuristic weights\nconst int MATCH_REWARD = 3;\nconst int MISMATCH_PENALTY = 2;\nconst int BOUNDARY_PENALTY = 3;\nconst int PAIR_MATCH_REWARD = 5;\nconst int PAIR_MISMATCH_PENALTY = 4;\n\nint toMap[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 usedMask[8];\nint rotMap[8][4];\nvector<array<int, 2>> pairsOfType[8];\n\ninline bool uses(int t, int dir) { return (usedMask[t] >> dir) & 1; }\ninline int apply_rot(int base, int r) { return rotMap[base][r]; }\ninline int idx_of(int i, int j, int d) { return ((i * N + j) << 2) | d; }\n\nint baseType[N][N];\nint rotCnt[N][N];\nint curType[N][N];\n\ninline int edge_contrib(int i, int j, int dir) {\n    int t = curType[i][j];\n    bool a = uses(t, dir);\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n        return a ? -BOUNDARY_PENALTY : 0;\n    }\n    bool b = uses(curType[ni][nj], dir ^ 2);\n    if (a && b) return MATCH_REWARD;\n    else if (a || b) return -MISMATCH_PENALTY;\n    else return 0;\n}\n\ninline int calc_edges_counted(int i, int j) {\n    int res = 0;\n    if (j < N - 1) res += edge_contrib(i, j, 2);\n    if (i < N - 1) res += edge_contrib(i, j, 3);\n    if (j == 0) res += edge_contrib(i, j, 0);\n    else res += edge_contrib(i, j - 1, 2);\n    if (i == 0) res += edge_contrib(i, j, 1);\n    else res += edge_contrib(i - 1, j, 3);\n    return res;\n}\n\ninline int compute_tile_pair(int i, int j) {\n    int t = curType[i][j];\n    int res = 0;\n    for (auto &pr : pairsOfType[t]) {\n        int a = pr[0], b = pr[1];\n        bool ma = false, mb = false;\n        int ni = i + di[a], nj = j + dj[a];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            ma = uses(curType[ni][nj], a ^ 2);\n        }\n        ni = i + di[b]; nj = j + dj[b];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            mb = uses(curType[ni][nj], b ^ 2);\n        }\n        if (ma && mb) res += PAIR_MATCH_REWARD;\n        else if (ma || mb) res -= PAIR_MISMATCH_PENALTY;\n    }\n    return res;\n}\n\n// Fast computation of real score (product of two largest cycles)\nint compute_real_score_fast() {\n    static int nextArr[TOT];\n    static unsigned char state[TOT];\n    static int depth[TOT];\n    int idx = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int t = curType[i][j];\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 == -1) {\n                nextArr[idx++] = -1;\n                continue;\n            }\n            int ni = i + di[d2], nj = j + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                nextArr[idx++] = -1;\n                continue;\n            }\n            int nd = (d2 + 2) & 3;\n            nextArr[idx++] = idx_of(ni, nj, nd);\n        }\n    }\n    memset(state, 0, TOT);\n    int best1 = 0, best2 = 0;\n    static int stack[TOT];\n    for (int v = 0; v < TOT; v++) {\n        if (state[v]) continue;\n        int top = 0;\n        int u = v;\n        while (u != -1 && state[u] == 0) {\n            state[u] = 1;\n            depth[u] = top;\n            stack[top++] = u;\n            u = nextArr[u];\n        }\n        if (u != -1 && state[u] == 1) {\n            int cycLen = top - depth[u];\n            if (cycLen > best1) {\n                best2 = best1;\n                best1 = cycLen;\n            } else if (cycLen > best2) {\n                best2 = cycLen;\n            }\n        }\n        for (int k = 0; k < top; k++) state[stack[k]] = 2;\n    }\n    if (best2 == 0) return 0;\n    return best1 * best2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Precompute masks and rotations and pairs\n    for (int t = 0; t < 8; t++) {\n        int m = 0;\n        for (int d = 0; d < 4; d++) if (toMap[t][d] != -1) m |= (1 << d);\n        usedMask[t] = m;\n    }\n    int nextType[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int b = 0; b < 8; b++) {\n        rotMap[b][0] = b;\n        for (int r = 1; r < 4; r++) rotMap[b][r] = nextType[rotMap[b][r - 1]];\n    }\n    for (int t = 0; t < 8; t++) {\n        pairsOfType[t].clear();\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 != -1 && d < d2) pairsOfType[t].push_back({d, d2});\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) baseType[i][j] = s[j] - '0';\n    }\n\n    // Initial rotation: minimize boundary usage\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int bestR = 0, bestPen = 100;\n        for (int r = 0; r < 4; r++) {\n            int t = apply_rot(baseType[i][j], r);\n            int pen = 0;\n            if (i == 0 && uses(t, 1)) pen++;\n            if (i == N - 1 && uses(t, 3)) pen++;\n            if (j == 0 && uses(t, 0)) pen++;\n            if (j == N - 1 && uses(t, 2)) pen++;\n            if (pen < bestPen) { bestPen = pen; bestR = r; }\n        }\n        rotCnt[i][j] = bestR;\n        curType[i][j] = apply_rot(baseType[i][j], bestR);\n    }\n\n    int edgeScore = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (j < N - 1) edgeScore += edge_contrib(i, j, 2);\n        if (i < N - 1) edgeScore += edge_contrib(i, j, 3);\n        if (j == 0) edgeScore += edge_contrib(i, j, 0);\n        if (i == 0) edgeScore += edge_contrib(i, j, 1);\n    }\n    int pairScore = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        pairScore += compute_tile_pair(i, j);\n    }\n    int heurScore = edgeScore + pairScore;\n    int bestHeur = heurScore;\n    int bestRotHeur[N][N];\n    int bestTypeHeur[N][N];\n    memcpy(bestRotHeur, rotCnt, sizeof(rotCnt));\n    memcpy(bestTypeHeur, curType, sizeof(curType));\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto timeStart = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9;\n    const double SA_DURATION = 1.2;\n    const double T0 = 5.0, T1 = 0.1;\n    double temp = T0;\n    int iter = 0;\n\n    while (true) {\n        iter++;\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - timeStart).count();\n            if (elapsed > SA_DURATION) break;\n            double progress = elapsed / SA_DURATION;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int newRot = rng() & 3;\n        if (newRot == rotCnt[i][j]) continue;\n        int oldType = curType[i][j];\n        int newType = apply_rot(baseType[i][j], newRot);\n\n        int oldEdges = calc_edges_counted(i, j);\n        int oldPairs = compute_tile_pair(i, j);\n        if (i > 0) oldPairs += compute_tile_pair(i - 1, j);\n        if (i + 1 < N) oldPairs += compute_tile_pair(i + 1, j);\n        if (j > 0) oldPairs += compute_tile_pair(i, j - 1);\n        if (j + 1 < N) oldPairs += compute_tile_pair(i, j + 1);\n\n        curType[i][j] = newType;\n\n        int newEdges = calc_edges_counted(i, j);\n        int newPairs = compute_tile_pair(i, j);\n        if (i > 0) newPairs += compute_tile_pair(i - 1, j);\n        if (i + 1 < N) newPairs += compute_tile_pair(i + 1, j);\n        if (j > 0) newPairs += compute_tile_pair(i, j - 1);\n        if (j + 1 < N) newPairs += compute_tile_pair(i, j + 1);\n\n        int delta = (newEdges - oldEdges) + (newPairs - oldPairs);\n        if (delta >= 0) {\n            edgeScore += (newEdges - oldEdges);\n            pairScore += (newPairs - oldPairs);\n            heurScore += delta;\n            rotCnt[i][j] = newRot;\n        } else {\n            double prob = exp(double(delta) / temp);\n            double rnd = (double)rng() / (double)rng.max();\n            if (rnd < prob) {\n                edgeScore += (newEdges - oldEdges);\n                pairScore += (newPairs - oldPairs);\n                heurScore += delta;\n                rotCnt[i][j] = newRot;\n            } else {\n                curType[i][j] = oldType; // revert\n            }\n        }\n        if (heurScore > bestHeur) {\n            bestHeur = heurScore;\n            memcpy(bestRotHeur, rotCnt, sizeof(rotCnt));\n            memcpy(bestTypeHeur, curType, sizeof(curType));\n        }\n    }\n\n    // Start from best heuristic state\n    memcpy(rotCnt, bestRotHeur, sizeof(rotCnt));\n    memcpy(curType, bestTypeHeur, sizeof(curType));\n\n    int curReal = compute_real_score_fast();\n    int bestReal = curReal;\n    int bestRot[N][N];\n    memcpy(bestRot, rotCnt, sizeof(rotCnt));\n    int bestType[N][N];\n    memcpy(bestType, curType, sizeof(curType));\n\n    // Greedy local search using real score\n    int greedyIter = 0;\n    while (true) {\n        greedyIter++;\n        if ((greedyIter & 31) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - timeStart).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int origRot = rotCnt[i][j];\n        int origType = curType[i][j];\n        int bestLocalRot = origRot;\n        int bestLocalScore = curReal;\n\n        for (int r = 0; r < 4; r++) {\n            if (r == origRot) continue;\n            curType[i][j] = apply_rot(baseType[i][j], r);\n            int sc = compute_real_score_fast();\n            if (sc > bestLocalScore) {\n                bestLocalScore = sc;\n                bestLocalRot = r;\n            }\n        }\n        curType[i][j] = origType; // revert\n        if (bestLocalRot != origRot) {\n            rotCnt[i][j] = bestLocalRot;\n            curType[i][j] = apply_rot(baseType[i][j], bestLocalRot);\n            curReal = bestLocalScore;\n            if (curReal > bestReal) {\n                bestReal = curReal;\n                memcpy(bestRot, rotCnt, sizeof(rotCnt));\n                memcpy(bestType, curType, sizeof(curType));\n            }\n        }\n    }\n\n    // Output best rotation counts\n    string out;\n    out.reserve(N * N);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        out.push_back(char('0' + (bestRot[i][j] & 3)));\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Metric {\n    int tree_size;\n    int comp_size;\n    int good_edges;\n};\n\nstruct Solver {\n    int N, Tlim, NN;\n    int full_size;\n    int init_zero;\n    vector<uint8_t> init_board;\n    vector<vector<pair<char,int>>> moves_from;\n    mt19937 rng;\n    chrono::steady_clock::time_point end_time;\n    double EPS = 0.15; // random move probability\n\n    Solver() {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    }\n\n    int hexval(char c){\n        if('0'<=c && c<='9') return c-'0';\n        return 10 + (c-'a');\n    }\n\n    Metric compute_metric(const vector<uint8_t>& b){\n        static uint8_t vis[100];\n        static uint8_t mark[100];\n        memset(vis, 0, NN);\n        memset(mark, 0, NN);\n        int good_edges = 0;\n        for(int r=0; r<N; r++){\n            int base = r*N;\n            for(int c=0; c<N; c++){\n                int idx = base + c;\n                int t = b[idx];\n                if(t==0) continue;\n                if(c+1 < N){\n                    int t2 = b[idx+1];\n                    if(t2!=0 && (t&4) && (t2&1)) good_edges++;\n                }\n                if(r+1 < N){\n                    int t2 = b[idx+N];\n                    if(t2!=0 && (t&8) && (t2&2)) good_edges++;\n                }\n            }\n        }\n        int best_tree = 0;\n        int best_comp = 0;\n        vector<int> q;\n        q.reserve(NN);\n        for(int idx=0; idx<NN; idx++){\n            if(b[idx]==0 || vis[idx]) continue;\n            q.clear();\n            vis[idx]=1;\n            q.push_back(idx);\n            for(int qi=0; qi<(int)q.size(); qi++){\n                int u = q[qi];\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(r>0){\n                    int v = u - N;\n                    if(!vis[v] && b[v]!=0 && (t&2) && (b[v]&8)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(!vis[v] && b[v]!=0 && (t&8) && (b[v]&2)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(c>0){\n                    int v = u - 1;\n                    if(!vis[v] && b[v]!=0 && (t&1) && (b[v]&4)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(c+1<N){\n                    int v = u + 1;\n                    if(!vis[v] && b[v]!=0 && (t&4) && (b[v]&1)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n            }\n            for(int u: q) mark[u]=1;\n            int edges = 0;\n            for(int u: q){\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(c+1<N){\n                    int v = u + 1;\n                    if(mark[v] && (t&4) && (b[v]&1)) edges++;\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(mark[v] && (t&8) && (b[v]&2)) edges++;\n                }\n            }\n            for(int u: q) mark[u]=0;\n            int sz = (int)q.size();\n            if(sz > best_comp) best_comp = sz;\n            if(edges == sz - 1){\n                if(sz > best_tree) best_tree = sz;\n            }\n        }\n        return {best_tree, best_comp, good_edges};\n    }\n\n    char inverse_move(char c){\n        if(c=='U') return 'D';\n        if(c=='D') return 'U';\n        if(c=='L') return 'R';\n        if(c=='R') return 'L';\n        return '?';\n    }\n\n    bool better_metric(const Metric& a, const Metric& b){\n        if(a.tree_size != b.tree_size) return a.tree_size > b.tree_size;\n        if(a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        return a.good_edges > b.good_edges;\n    }\n\n    pair<Metric,string> walk(){\n        vector<uint8_t> board = init_board;\n        int zero = init_zero;\n        string moves;\n        moves.reserve(Tlim);\n        Metric curr = compute_metric(board);\n        Metric best = curr;\n        string best_seq;\n        char prev_move = '?';\n        uniform_real_distribution<double> dist01(0.0,1.0);\n        for(int step=0; step<Tlim; step++){\n            if(chrono::steady_clock::now() > end_time) break;\n            const auto& opts_all = moves_from[zero];\n            vector<pair<char,int>> opts;\n            opts.reserve(4);\n            char inv = inverse_move(prev_move);\n            for(auto &p: opts_all){\n                if(inv==p.first && (int)opts_all.size()>1) continue;\n                opts.push_back(p);\n            }\n            if(opts.empty()){\n                opts = opts_all;\n            }\n            char chosen_move;\n            int chosen_delta;\n            Metric chosen_metric;\n            double rnd = dist01(rng);\n            if(rnd < EPS){\n                uniform_int_distribution<int> dist(0, (int)opts.size()-1);\n                int k = dist(rng);\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                chosen_metric = compute_metric(board);\n            }else{\n                Metric best_nei = {-1,-1,-1};\n                vector<int> best_idx;\n                best_idx.reserve(4);\n                vector<Metric> metrics(opts.size());\n                for(int i=0; i<(int)opts.size(); i++){\n                    int d = opts[i].second;\n                    swap(board[zero], board[zero+d]);\n                    Metric m = compute_metric(board);\n                    swap(board[zero], board[zero+d]);\n                    metrics[i]=m;\n                    if(better_metric(m, best_nei)){\n                        best_nei = m;\n                        best_idx.clear();\n                        best_idx.push_back(i);\n                    }else if(m.tree_size == best_nei.tree_size &&\n                             m.comp_size == best_nei.comp_size &&\n                             m.good_edges == best_nei.good_edges){\n                        best_idx.push_back(i);\n                    }\n                }\n                uniform_int_distribution<int> dist(0, (int)best_idx.size()-1);\n                int k = best_idx[dist(rng)];\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                chosen_metric = metrics[k];\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n            }\n            moves.push_back(chosen_move);\n            prev_move = chosen_move;\n            curr = chosen_metric;\n            if(better_metric(curr, best)){\n                best = curr;\n                best_seq = moves;\n                if(best.tree_size == full_size) break;\n            }\n        }\n        return {best, best_seq};\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin >> N >> Tlim;\n        NN = N*N;\n        full_size = NN - 1;\n        init_board.resize(NN);\n        for(int i=0;i<N;i++){\n            string s; cin >> s;\n            for(int j=0;j<N;j++){\n                int v = hexval(s[j]);\n                init_board[i*N + j] = (uint8_t)v;\n                if(v==0) init_zero = i*N + j;\n            }\n        }\n        // precompute moves\n        moves_from.resize(NN);\n        for(int pos=0; pos<NN; pos++){\n            int r = pos / N;\n            int c = pos - r*N;\n            if(r>0) moves_from[pos].push_back({'U', -N});\n            if(r+1<N) moves_from[pos].push_back({'D', N});\n            if(c>0) moves_from[pos].push_back({'L', -1});\n            if(c+1<N) moves_from[pos].push_back({'R', 1});\n        }\n        Metric init_metric = compute_metric(init_board);\n        Metric best_global = init_metric;\n        string best_seq;\n        end_time = chrono::steady_clock::now() + chrono::milliseconds(2800);\n        while(chrono::steady_clock::now() < end_time){\n            auto res = walk();\n            Metric m = res.first;\n            string seq = res.second;\n            if(better_metric(m, best_global)){\n                best_global = m;\n                best_seq = seq;\n                if(best_global.tree_size == full_size){\n                    // if we found perfect tree, try to minimize moves by continuing search if time left\n                    // else break\n                }\n            }else if(m.tree_size == best_global.tree_size && m.comp_size == best_global.comp_size &&\n                     m.good_edges == best_global.good_edges){\n                if(!seq.empty() && (best_seq.empty() || seq.size() < best_seq.size())){\n                    best_seq = seq;\n                }\n            }\n        }\n        cout << best_seq << \"\\n\";\n    }\n};\n\nint main(){\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    int obj = -1;\n    int V = 0, H = 0;\n    int stepX = 0, stepY = 0;\n    int offx = 0, offy = 0;\n    int mode = 0; // 0: axis (x,y), 1: diag (x+y, x-y)\n    vector<int> vx, vy; // line constants\n};\n\nconst int R = 10000;\nconst int BIG = 1000000000;\nconst double TIME_LIMIT = 2.9;\n\nint N, K;\nint a[11];\nvector<pair<int,int>> pts;\nvector<int> xs, ys, us, vs; // shifted coords for offset calc\n\nmt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nSolution best;\n\n// key for cache: (axis<<20) ^ step (step<=40000 so 16 bits ok)\nunordered_map<long long, vector<int>> offset_cache;\n\nvector<int> get_best_offsets(int step, int axis) {\n    if (step <= 0) return {0};\n    long long key = (static_cast<long long>(axis) << 20) ^ step;\n    auto it = offset_cache.find(key);\n    if (it != offset_cache.end()) return it->second;\n\n    vector<int> cnt(step, 0);\n    const vector<int> *arr;\n    if (axis == 0) arr = &xs;\n    else if (axis == 1) arr = &ys;\n    else if (axis == 2) arr = &us;\n    else arr = &vs;\n    for (int v : *arr) {\n        cnt[v % step]++;\n    }\n    int minc = *min_element(cnt.begin(), cnt.end());\n    vector<int> offs;\n    for (int i = 0; i < step && (int)offs.size() < 12; i++) {\n        if (cnt[i] == minc) offs.push_back(i);\n    }\n    if ((int)offs.size() < 8) {\n        int sec = INT_MAX;\n        for (int c : cnt) if (c > minc) sec = min(sec, c);\n        for (int i = 0; i < step && (int)offs.size() < 16; i++) {\n            if (cnt[i] == sec) offs.push_back(i);\n        }\n    }\n    for (int t = 0; t < 4 && (int)offs.size() < 20; t++) offs.push_back((int)(rng() % step));\n    sort(offs.begin(), offs.end());\n    offs.erase(unique(offs.begin(), offs.end()), offs.end());\n    offset_cache[key] = offs;\n    return offs;\n}\n\n// mode 0: axis grid, mode 1: diag grid (u=x+y,v=x-y)\nint evaluate_grid(int V, int H, int stepX, int offx, int stepY, int offy, int mode, bool update_best = true) {\n    int rows = V + 1;\n    int cols = H + 1;\n    int sz = rows * cols;\n    static vector<int> cnt;\n    cnt.assign(sz, 0);\n\n    if (mode == 0) {\n        int firstX = -R + offx + stepX;\n        int firstY = -R + offy + stepY;\n        for (auto &p : pts) {\n            int x = p.first, y = p.second;\n            int cidx = 0, ridx = 0;\n            if (V > 0) {\n                int diffx = x - firstX;\n                if (diffx >= 0) {\n                    int q = diffx / stepX;\n                    if (q < V && diffx % stepX == 0) continue; // on vertical line\n                    cidx = q + 1;\n                    if (cidx > V) cidx = V;\n                } else cidx = 0;\n            }\n            if (H > 0) {\n                int diffy = y - firstY;\n                if (diffy >= 0) {\n                    int qy = diffy / stepY;\n                    if (qy < H && diffy % stepY == 0) continue; // on horizontal line\n                    ridx = qy + 1;\n                    if (ridx > H) ridx = H;\n                } else ridx = 0;\n            }\n            cnt[cidx * cols + ridx]++;\n        }\n    } else { // diag\n        int firstU = -2 * R + offx + stepX; // u = x+y range [-20000,20000]\n        int firstV = -2 * R + offy + stepY; // v = x-y\n        for (auto &p : pts) {\n            int u = p.first + p.second;\n            int v = p.first - p.second;\n            int cidx = 0, ridx = 0;\n            if (V > 0) {\n                int diffu = u - firstU;\n                if (diffu >= 0) {\n                    int q = diffu / stepX;\n                    if (q < V && diffu % stepX == 0) continue; // on u-line\n                    cidx = q + 1;\n                    if (cidx > V) cidx = V;\n                } else cidx = 0;\n            }\n            if (H > 0) {\n                int diffv = v - firstV;\n                if (diffv >= 0) {\n                    int qv = diffv / stepY;\n                    if (qv < H && diffv % stepY == 0) continue; // on v-line\n                    ridx = qv + 1;\n                    if (ridx > H) ridx = H;\n                } else ridx = 0;\n            }\n            cnt[cidx * cols + ridx]++;\n        }\n    }\n    int b[11] = {0};\n    for (int v : cnt) {\n        if (v >= 1 && v <= 10) b[v]++;\n    }\n    int obj = 0;\n    for (int d = 1; d <= 10; d++) obj += min(a[d], b[d]);\n\n    if (update_best && obj > best.obj) {\n        best.obj = obj;\n        best.V = V; best.H = H;\n        best.stepX = stepX; best.stepY = stepY;\n        best.offx = offx; best.offy = offy;\n        best.mode = mode;\n        best.vx.resize(V);\n        best.vy.resize(H);\n        if (mode == 0) {\n            for (int i = 0; i < V; i++) best.vx[i] = -R + offx + stepX * (i + 1);\n            for (int j = 0; j < H; j++) best.vy[j] = -R + offy + stepY * (j + 1);\n        } else {\n            for (int i = 0; i < V; i++) best.vx[i] = -2 * R + offx + stepX * (i + 1); // u constants\n            for (int j = 0; j < H; j++) best.vy[j] = -2 * R + offy + stepY * (j + 1); // v constants\n        }\n    }\n    return obj;\n}\n\ndouble expected_obj_pair(int V, int H) {\n    int cells = (V + 1) * (H + 1);\n    double lambda = (double)N / cells;\n    double eexp = exp(-lambda);\n    double sum = 0.0;\n    double lp = 1.0;\n    for (int d = 1; d <= 10; d++) {\n        lp *= lambda;\n        double pd = lp * eexp / tgamma(d + 1);\n        double bd = cells * pd;\n        sum += min((double)a[d], bd);\n    }\n    return sum;\n}\n\nvoid optimize_pair(int V, int H, int mode) {\n    int range = (mode == 0) ? 20000 : 40000;\n    int stepX = max(1, range / (V + 1));\n    int stepY = max(1, range / (H + 1));\n    int axisX = (mode == 0) ? 0 : 2;\n    int axisY = (mode == 0) ? 1 : 3;\n    vector<int> offsX = get_best_offsets(stepX, axisX);\n    vector<int> offsY = get_best_offsets(stepY, axisY);\n    if (offsX.empty()) offsX.push_back(0);\n    if (offsY.empty()) offsY.push_back(0);\n    int offx = offsX[0], offy = offsY[0];\n    int cur = evaluate_grid(V, H, stepX, offx, stepY, offy, mode, true);\n    if (elapsed() > TIME_LIMIT) return;\n    const int MAX_SCAN = 1200;\n    bool improved = true;\n    while (improved && elapsed() < TIME_LIMIT) {\n        improved = false;\n        int best_offx = offx;\n        int best_val = cur;\n        if (stepX <= MAX_SCAN) {\n            for (int ox = 0; ox < stepX; ox++) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, ox, stepY, offy, mode, true);\n                if (val > best_val) { best_val = val; best_offx = ox; }\n            }\n        } else {\n            int stride = max(1, stepX / MAX_SCAN);\n            for (int ox = 0; ox < stepX; ox += stride) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, ox, stepY, offy, mode, true);\n                if (val > best_val) { best_val = val; best_offx = ox; }\n            }\n            for (int t = 0; t < 200 && elapsed() < TIME_LIMIT; t++) {\n                int ox = (int)(rng() % stepX);\n                int val = evaluate_grid(V, H, stepX, ox, stepY, offy, mode, true);\n                if (val > best_val) { best_val = val; best_offx = ox; }\n            }\n        }\n        if (best_offx != offx) { offx = best_offx; cur = best_val; improved = true; }\n        if (elapsed() > TIME_LIMIT) break;\n\n        int best_offy = offy;\n        best_val = cur;\n        if (stepY <= MAX_SCAN) {\n            for (int oy = 0; oy < stepY; oy++) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, offx, stepY, oy, mode, true);\n                if (val > best_val) { best_val = val; best_offy = oy; }\n            }\n        } else {\n            int stride = max(1, stepY / MAX_SCAN);\n            for (int oy = 0; oy < stepY; oy += stride) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, offx, stepY, oy, mode, true);\n                if (val > best_val) { best_val = val; best_offy = oy; }\n            }\n            for (int t = 0; t < 200 && elapsed() < TIME_LIMIT; t++) {\n                int oy = (int)(rng() % stepY);\n                int val = evaluate_grid(V, H, stepX, offx, stepY, oy, mode, true);\n                if (val > best_val) { best_val = val; best_offy = oy; }\n            }\n        }\n        if (best_offy != offy) { offy = best_offy; cur = best_val; improved = true; }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> K)) return 0;\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    pts.resize(N);\n    xs.resize(N);\n    ys.resize(N);\n    us.resize(N);\n    vs.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        pts[i] = {x, y};\n        xs[i] = x + R;\n        ys[i] = y + R;\n        us[i] = x + y + 2 * R;   // shift by 20000\n        vs[i] = x - y + 2 * R;   // shift by 20000\n    }\n\n    // generate candidate pairs\n    vector<pair<int,int>> pairs;\n    auto addPair = [&](int v, int h) {\n        if (v < 0 || h < 0) return;\n        if (v + h > K) return;\n        if (v > 100 || h > 100) return;\n        pairs.emplace_back(v, h);\n    };\n\n    // lambda-based candidates\n    vector<pair<double,double>> lambdaScore;\n    for (double lam = 0.8; lam <= 8.0; lam += 0.2) {\n        double cells = (double)N / lam;\n        double eexp = exp(-lam);\n        double sum = 0.0, lp = 1.0;\n        for (int d = 1; d <= 10; d++) {\n            lp *= lam;\n            double pd = lp * eexp / tgamma(d + 1);\n            double bd = cells * pd;\n            sum += min((double)a[d], bd);\n        }\n        lambdaScore.emplace_back(-sum, lam);\n    }\n    sort(lambdaScore.begin(), lambdaScore.end());\n    int topLam = 6;\n    for (int i = 0; i < (int)lambdaScore.size() && i < topLam; i++) {\n        double lam = lambdaScore[i].second;\n        double cells = (double)N / lam;\n        double base = sqrt(max(1.0, cells)) - 1.0;\n        int v0 = max(0, (int)(base + 0.5));\n        for (int dv = -2; dv <= 2; dv++) {\n            int v = v0 + dv;\n            if (v < 0) continue;\n            addPair(v, v);\n            addPair(v, v + 1);\n            addPair(v + 1, v);\n        }\n    }\n    vector<int> fixed = {8,12,16,20,24,28,32,36,40,44,48,52};\n    for (int v : fixed) if (2 * v <= K) addPair(v, v);\n\n    sort(pairs.begin(), pairs.end());\n    pairs.erase(unique(pairs.begin(), pairs.end()), pairs.end());\n\n    vector<pair<double, pair<int,int>>> order;\n    for (auto &pr : pairs) {\n        double eo = expected_obj_pair(pr.first, pr.second);\n        order.push_back({-eo, pr});\n    }\n    sort(order.begin(), order.end());\n\n    int maxAxis = 7, maxDiag = 5;\n    int axis_done = 0, diag_done = 0;\n    for (auto &ord : order) {\n        if (elapsed() > TIME_LIMIT) break;\n        int V = ord.second.first;\n        int H = ord.second.second;\n        if (axis_done < maxAxis) {\n            optimize_pair(V, H, 0);\n            axis_done++;\n        }\n        if (elapsed() > TIME_LIMIT) break;\n        if (diag_done < maxDiag) {\n            optimize_pair(V, H, 1);\n            diag_done++;\n        }\n        if (axis_done >= maxAxis && diag_done >= maxDiag) break;\n    }\n\n    // random search\n    while (elapsed() < TIME_LIMIT) {\n        int V = (int)(rng() % 51);\n        int H = (int)(rng() % 51);\n        if (V + H > K) continue;\n        int mode = (rng() & 1);\n        int range = (mode == 0) ? 20000 : 40000;\n        int stepX = max(1, range / (V + 1));\n        int stepY = max(1, range / (H + 1));\n        int offx = (int)(rng() % stepX);\n        int offy = (int)(rng() % stepY);\n        evaluate_grid(V, H, stepX, offx, stepY, offy, mode, true);\n    }\n\n    int k = (int)best.vx.size() + (int)best.vy.size();\n    cout << k << \"\\n\";\n    if (best.mode == 0) {\n        for (int x : best.vx) {\n            cout << x << \" \" << -BIG << \" \" << x << \" \" << BIG << \"\\n\";\n        }\n        for (int y : best.vy) {\n            cout << -BIG << \" \" << y << \" \" << BIG << \" \" << y << \"\\n\";\n        }\n    } else { // diag\n        for (int c : best.vx) { // u = x + y = c\n            // points (c,0) and (0,c)\n            cout << c << \" 0 0 \" << c << \"\\n\";\n        }\n        for (int d : best.vy) { // v = x - y = d\n            // points (d,0) and (0,-d)\n            cout << d << \" 0 0 \" << -d << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeIndex {\n    int N;\n    int H, V, D1, D2, E;\n    EdgeIndex(int N_) : N(N_) {\n        H = (N - 1) * N;\n        V = H;\n        D1 = (N - 1) * (N - 1);\n        D2 = D1;\n        E = H + V + D1 + D2;\n    }\n    inline int horizId(int x, int y) const { // (x,y)-(x+1,y)\n        return x + y * (N - 1);\n    }\n    inline int vertId(int x, int y) const { // (x,y)-(x,y+1)\n        return H + x * (N - 1) + y;\n    }\n    inline int diag1Id(int x, int y) const { // slope +1 (x,y)-(x+1,y+1)\n        return H + V + x * (N - 1) + y;\n    }\n    inline int diag2Id(int x, int y) const { // slope -1 (x,y)-(x+1,y-1) y>=1\n        return H + V + D1 + x * (N - 1) + (y - 1);\n    }\n    inline int id(int x1, int y1, int x2, int y2) const {\n        int dx = x2 - x1;\n        int dy = y2 - y1;\n        if (abs(dx) + abs(dy) == 1) { // axis neighbor\n            if (dy == 0) {\n                int x = min(x1, x2), y = y1;\n                return horizId(x, y);\n            } else {\n                int y = min(y1, y2), x = x1;\n                return vertId(x, y);\n            }\n        } else if (abs(dx) == 1 && abs(dy) == 1) { // diagonal neighbor\n            if (dx == dy) { // slope +1\n                int x = min(x1, x2), y = min(y1, y2);\n                return diag1Id(x, y);\n            } else { // slope -1\n                int x = min(x1, x2), y = max(y1, y2);\n                return diag2Id(x, y);\n            }\n        }\n        return -1;\n    }\n};\n\nstruct Cand {\n    uint8_t type; //0 rect,1 diamond\n    uint8_t miss;\n    uint8_t dx, dy; // rect: dx,dy ; diamond: dx=r\n    uint16_t x0, y0; // rect: bottom-left; diamond: center\n    int w;     // actual weight of missing dot\n    int score; // priority score\n};\n\nstruct CompScore {\n    bool operator()(const Cand &a, const Cand &b) const {\n        return a.score < b.score; // max-heap\n    }\n};\n\nclass Pool {\n    int mode; //0 score (weight),1 fifo,2 random\n    priority_queue<Cand, vector<Cand>, CompScore> pq;\n    deque<Cand> dq;\n    vector<Cand> vec;\n    mt19937 rng;\npublic:\n    Pool(int m, uint32_t seed) : mode(m), rng(seed) {}\n    void push(const Cand &c) {\n        if (mode == 0) pq.push(c);\n        else if (mode == 1) dq.push_back(c);\n        else vec.push_back(c);\n    }\n    bool empty() const {\n        if (mode == 0) return pq.empty();\n        if (mode == 1) return dq.empty();\n        return vec.empty();\n    }\n    Cand pop() {\n        if (mode == 0) { Cand c = pq.top(); pq.pop(); return c; }\n        if (mode == 1) { Cand c = dq.front(); dq.pop_front(); return c; }\n        int idx = (int)(rng() % vec.size());\n        Cand c = vec[idx];\n        vec[idx] = vec.back();\n        vec.pop_back();\n        return c;\n    }\n};\n\nstruct Stage {\n    int maxA;\n    int maxD;\n    int mode; // pool mode\n    int prio; //0 weight,1 ratio\n};\n\nstruct Result {\n    long long total;\n    vector<array<int,8>> ops;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> initialDots(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initialDots[i] = {x, y};\n    }\n    EdgeIndex EI(N);\n    int NN = N * N;\n    vector<int> weight(NN);\n    int c = (N - 1) / 2;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            int dx = x - c, dy = y - c;\n            weight[x * N + y] = dx * dx + dy * dy + 1;\n        }\n    }\n    vector<char> initialHasDot(NN, 0);\n    long long initSum = 0;\n    vector<pair<int,int>> initList;\n    initList.reserve(M + 10000);\n    for (auto &p : initialDots) {\n        int id = p.first * N + p.second;\n        if (!initialHasDot[id]) {\n            initialHasDot[id] = 1;\n            initSum += weight[id];\n            initList.push_back(p);\n        }\n    }\n\n    uint64_t seedBase = 1234567;\n    seedBase = seedBase * 1000003 + N;\n    seedBase = seedBase * 1000003 + M;\n    for (auto &p : initialDots) {\n        seedBase ^= (uint64_t)(p.first + 1) * 10007 + (uint64_t)(p.second + 1) * 1000003 + 12345;\n        seedBase = seedBase * 1000003 + 1;\n    }\n\n    vector<vector<Stage>> configList;\n    configList.push_back({{3,2,0,0},{5,3,0,0},{7,4,0,0}});\n    configList.push_back({{5,3,0,0},{7,4,0,0}});\n    configList.push_back({{7,4,0,1},{4,2,0,0}});\n    configList.push_back({{4,2,1,0},{6,3,0,0},{8,4,0,0}});\n    configList.push_back({{3,1,2,0},{5,2,2,0},{7,3,0,0}});\n    configList.push_back({{8,4,0,0},{5,3,0,0}});\n    configList.push_back({{6,3,0,1},{8,4,0,1}});\n\n    auto startTime = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8;\n\n    auto simulate = [&](const vector<Stage> &seq, uint32_t baseSeed)->Result {\n        vector<char> hasDot = initialHasDot;\n        vector<char> used(EI.E, 0);\n        vector<pair<int,int>> dotList = initList;\n        long long total = initSum;\n        vector<array<int,8>> ops;\n\n        for (int si = 0; si < (int)seq.size(); si++) {\n            const Stage &st = seq[si];\n            Pool pool(st.mode, baseSeed + si * 1000003u);\n\n            auto computeScoreRect = [&](int w, int dx, int dy) -> int {\n                if (st.prio == 0) return w;\n                int per = 2 * (dx + dy);\n                return (w * 256) / max(1, per);\n            };\n            auto computeScoreDiamond = [&](int w, int r) -> int {\n                if (st.prio == 0) return w;\n                int per = 4 * r;\n                return (w * 256) / max(1, per);\n            };\n\n            auto evalRect = [&](int x0, int y0, int dx, int dy) {\n                int x1 = x0 + dx;\n                int y1 = y0 + dy;\n                if (x0 < 0 || y0 < 0 || x1 >= N || y1 >= N) return;\n                int cid[4] = {\n                    x0 * N + y0,\n                    x1 * N + y0,\n                    x1 * N + y1,\n                    x0 * N + y1\n                };\n                int cnt = hasDot[cid[0]] + hasDot[cid[1]] + hasDot[cid[2]] + hasDot[cid[3]];\n                if (cnt != 3) return;\n                int miss;\n                if (!hasDot[cid[0]]) miss = 0;\n                else if (!hasDot[cid[1]]) miss = 1;\n                else if (!hasDot[cid[2]]) miss = 2;\n                else miss = 3;\n                for (int i = 0; i < dx; i++) {\n                    int e1 = EI.horizId(x0 + i, y0);\n                    int e2 = EI.horizId(x0 + i, y1);\n                    if (used[e1] || used[e2]) return;\n                }\n                for (int j = 0; j < dy; j++) {\n                    int e1 = EI.vertId(x0, y0 + j);\n                    int e2 = EI.vertId(x1, y0 + j);\n                    if (used[e1] || used[e2]) return;\n                }\n                if (dx > 1) {\n                    for (int i = 1; i < dx; i++) {\n                        if (hasDot[(x0 + i) * N + y0]) return;\n                        if (hasDot[(x0 + i) * N + y1]) return;\n                    }\n                }\n                if (dy > 1) {\n                    for (int j = 1; j < dy; j++) {\n                        if (hasDot[x0 * N + (y0 + j)]) return;\n                        if (hasDot[x1 * N + (y0 + j)]) return;\n                    }\n                }\n                int w = weight[cid[miss]];\n                Cand cnd;\n                cnd.type = 0;\n                cnd.miss = (uint8_t)miss;\n                cnd.dx = (uint8_t)dx;\n                cnd.dy = (uint8_t)dy;\n                cnd.x0 = (uint16_t)x0;\n                cnd.y0 = (uint16_t)y0;\n                cnd.w = w;\n                cnd.score = computeScoreRect(w, dx, dy);\n                pool.push(cnd);\n            };\n            auto evalDiamond = [&](int cx, int cy, int r) {\n                if (cx - r < 0 || cx + r >= N || cy - r < 0 || cy + r >= N) return;\n                int cid[4] = {\n                    (cx + r) * N + cy,\n                    cx * N + (cy + r),\n                    (cx - r) * N + cy,\n                    cx * N + (cy - r)\n                };\n                int cnt = hasDot[cid[0]] + hasDot[cid[1]] + hasDot[cid[2]] + hasDot[cid[3]];\n                if (cnt != 3) return;\n                int miss;\n                if (!hasDot[cid[0]]) miss = 0;\n                else if (!hasDot[cid[1]]) miss = 1;\n                else if (!hasDot[cid[2]]) miss = 2;\n                else miss = 3;\n                for (int t = 0; t < r; t++) {\n                    int x, y, e;\n                    x = cx + r - t; y = cy + t;\n                    e = EI.id(x, y, x - 1, y + 1);\n                    if (used[e]) return;\n                    x = cx - t; y = cy + r - t;\n                    e = EI.id(x, y, x - 1, y - 1);\n                    if (used[e]) return;\n                    x = cx - r + t; y = cy - t;\n                    e = EI.id(x, y, x + 1, y - 1);\n                    if (used[e]) return;\n                    x = cx + t; y = cy - r + t;\n                    e = EI.id(x, y, x + 1, y + 1);\n                    if (used[e]) return;\n                }\n                for (int t = 1; t < r; t++) {\n                    if (hasDot[(cx + r - t) * N + (cy + t)]) return;\n                    if (hasDot[(cx - t) * N + (cy + r - t)]) return;\n                    if (hasDot[(cx - r + t) * N + (cy - t)]) return;\n                    if (hasDot[(cx + t) * N + (cy - r + t)]) return;\n                }\n                int w = weight[cid[miss]];\n                Cand cnd;\n                cnd.type = 1;\n                cnd.miss = (uint8_t)miss;\n                cnd.dx = (uint8_t)r;\n                cnd.dy = 0;\n                cnd.x0 = (uint16_t)cx;\n                cnd.y0 = (uint16_t)cy;\n                cnd.w = w;\n                cnd.score = computeScoreDiamond(w, r);\n                pool.push(cnd);\n            };\n\n            auto addFromPoint = [&](int x, int y) {\n                for (int dx = 1; dx <= st.maxA; dx++) {\n                    for (int dy = 1; dy <= st.maxA; dy++) {\n                        evalRect(x, y, dx, dy);\n                        evalRect(x - dx, y, dx, dy);\n                        evalRect(x, y - dy, dx, dy);\n                        evalRect(x - dx, y - dy, dx, dy);\n                    }\n                }\n                for (int r = 1; r <= st.maxD; r++) {\n                    evalDiamond(x - r, y, r);\n                    evalDiamond(x, y - r, r);\n                    evalDiamond(x + r, y, r);\n                    evalDiamond(x, y + r, r);\n                }\n            };\n\n            for (auto &p : dotList) addFromPoint(p.first, p.second);\n\n            auto tryApplyRect = [&](const Cand &cnd, int &mx, int &my)->bool {\n                int x0 = cnd.x0, y0 = cnd.y0;\n                int dx = cnd.dx, dy = cnd.dy;\n                int x1 = x0 + dx, y1 = y0 + dy;\n                if (x0 < 0 || y0 < 0 || x1 >= N || y1 >= N) return false;\n                int cid[4] = {\n                    x0 * N + y0,\n                    x1 * N + y0,\n                    x1 * N + y1,\n                    x0 * N + y1\n                };\n                if (hasDot[cid[cnd.miss]]) return false;\n                for (int k = 0; k < 4; k++) {\n                    if (k == cnd.miss) continue;\n                    if (!hasDot[cid[k]]) return false;\n                }\n                for (int i = 0; i < dx; i++) {\n                    int e1 = EI.horizId(x0 + i, y0);\n                    int e2 = EI.horizId(x0 + i, y1);\n                    if (used[e1] || used[e2]) return false;\n                }\n                for (int j = 0; j < dy; j++) {\n                    int e1 = EI.vertId(x0, y0 + j);\n                    int e2 = EI.vertId(x1, y0 + j);\n                    if (used[e1] || used[e2]) return false;\n                }\n                if (dx > 1) {\n                    for (int i = 1; i < dx; i++) {\n                        if (hasDot[(x0 + i) * N + y0]) return false;\n                        if (hasDot[(x0 + i) * N + y1]) return false;\n                    }\n                }\n                if (dy > 1) {\n                    for (int j = 1; j < dy; j++) {\n                        if (hasDot[x0 * N + (y0 + j)]) return false;\n                        if (hasDot[x1 * N + (y0 + j)]) return false;\n                    }\n                }\n                hasDot[cid[cnd.miss]] = 1;\n                total += cnd.w;\n                for (int i = 0; i < dx; i++) {\n                    used[EI.horizId(x0 + i, y0)] = 1;\n                    used[EI.horizId(x0 + i, y1)] = 1;\n                }\n                for (int j = 0; j < dy; j++) {\n                    used[EI.vertId(x0, y0 + j)] = 1;\n                    used[EI.vertId(x1, y0 + j)] = 1;\n                }\n                mx = (cnd.miss == 0 || cnd.miss == 3) ? x0 : x1;\n                my = (cnd.miss == 0 || cnd.miss == 1) ? y0 : y1;\n                array<int,8> op;\n                for (int t = 0; t < 4; t++) {\n                    int idx = (cnd.miss + t) % 4;\n                    int ox, oy;\n                    if (idx == 0) { ox = x0; oy = y0; }\n                    else if (idx == 1) { ox = x1; oy = y0; }\n                    else if (idx == 2) { ox = x1; oy = y1; }\n                    else { ox = x0; oy = y1; }\n                    op[2 * t] = ox;\n                    op[2 * t + 1] = oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx, my);\n                return true;\n            };\n\n            auto tryApplyDiamond = [&](const Cand &cnd, int &mx, int &my)->bool {\n                int cx = cnd.x0, cy = cnd.y0, r = cnd.dx;\n                if (cx - r < 0 || cx + r >= N || cy - r < 0 || cy + r >= N) return false;\n                int cid[4] = {\n                    (cx + r) * N + cy,\n                    cx * N + (cy + r),\n                    (cx - r) * N + cy,\n                    cx * N + (cy - r)\n                };\n                if (hasDot[cid[cnd.miss]]) return false;\n                for (int k = 0; k < 4; k++) {\n                    if (k == cnd.miss) continue;\n                    if (!hasDot[cid[k]]) return false;\n                }\n                for (int t = 0; t < r; t++) {\n                    int x, y, e;\n                    x = cx + r - t; y = cy + t;\n                    e = EI.id(x, y, x - 1, y + 1);\n                    if (used[e]) return false;\n                    x = cx - t; y = cy + r - t;\n                    e = EI.id(x, y, x - 1, y - 1);\n                    if (used[e]) return false;\n                    x = cx - r + t; y = cy - t;\n                    e = EI.id(x, y, x + 1, y - 1);\n                    if (used[e]) return false;\n                    x = cx + t; y = cy - r + t;\n                    e = EI.id(x, y, x + 1, y + 1);\n                    if (used[e]) return false;\n                }\n                for (int t = 1; t < r; t++) {\n                    if (hasDot[(cx + r - t) * N + (cy + t)]) return false;\n                    if (hasDot[(cx - t) * N + (cy + r - t)]) return false;\n                    if (hasDot[(cx - r + t) * N + (cy - t)]) return false;\n                    if (hasDot[(cx + t) * N + (cy - r + t)]) return false;\n                }\n                hasDot[cid[cnd.miss]] = 1;\n                total += cnd.w;\n                for (int t = 0; t < r; t++) {\n                    int x, y;\n                    x = cx + r - t; y = cy + t;\n                    used[EI.id(x, y, x - 1, y + 1)] = 1;\n                    x = cx - t; y = cy + r - t;\n                    used[EI.id(x, y, x - 1, y - 1)] = 1;\n                    x = cx - r + t; y = cy - t;\n                    used[EI.id(x, y, x + 1, y - 1)] = 1;\n                    x = cx + t; y = cy - r + t;\n                    used[EI.id(x, y, x + 1, y + 1)] = 1;\n                }\n                if (cnd.miss == 0) { mx = cx + r; my = cy; }\n                else if (cnd.miss == 1) { mx = cx; my = cy + r; }\n                else if (cnd.miss == 2) { mx = cx - r; my = cy; }\n                else { mx = cx; my = cy - r; }\n                array<int,8> op;\n                for (int t = 0; t < 4; t++) {\n                    int idx = (cnd.miss + t) % 4;\n                    int ox, oy;\n                    if (idx == 0) { ox = cx + r; oy = cy; }\n                    else if (idx == 1) { ox = cx; oy = cy + r; }\n                    else if (idx == 2) { ox = cx - r; oy = cy; }\n                    else { ox = cx; oy = cy - r; }\n                    op[2 * t] = ox;\n                    op[2 * t + 1] = oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx, my);\n                return true;\n            };\n\n            while (!pool.empty()) {\n                Cand cand = pool.pop();\n                int mx = -1, my = -1;\n                bool ok = false;\n                if (cand.type == 0) ok = tryApplyRect(cand, mx, my);\n                else ok = tryApplyDiamond(cand, mx, my);\n                if (ok) dotList.emplace_back(mx, my);\n                // time guard\n                if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > TIME_LIMIT) break;\n            }\n            if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > TIME_LIMIT) break;\n        }\n        return {total, std::move(ops)};\n    };\n\n    Result best{initSum, {}};\n    for (int ci = 0; ci < (int)configList.size(); ci++) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > TIME_LIMIT) break;\n        uint32_t seed = (uint32_t)((seedBase + 1812433253ull * ci) & 0xffffffffu);\n        Result res = simulate(configList[ci], seed);\n        if (res.total > best.total) best = std::move(res);\n    }\n\n    cout << best.ops.size() << \"\\n\";\n    for (auto &op : best.ops) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0 = F(up), 1 = B(down), 2 = L(left), 3 = R(right)\nconst char DIR_CH[4] = {'F', 'B', 'L', 'R'};\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\n\nusing Board = array<array<int, 10>, 10>;\n\nBoard tilt(const Board &b, int dir) {\n    Board res;\n    for (auto &row : res) row.fill(0);\n    if (dir == 0) { // up\n        for (int c = 0; c < 10; c++) {\n            int pos = 0;\n            for (int r = 0; r < 10; r++) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 1) { // down\n        for (int c = 0; c < 10; c++) {\n            int pos = 9;\n            for (int r = 9; r >= 0; r--) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 2) { // left\n        for (int r = 0; r < 10; r++) {\n            int pos = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else { // right\n        for (int r = 0; r < 10; r++) {\n            int pos = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    }\n    return res;\n}\n\n// return {sum of squares, component count}\npair<int, int> scoreAndComp(const Board &b) {\n    bool vis[10][10] = {};\n    int totalScore = 0;\n    int comps = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            if (b[r][c] == 0 || vis[r][c]) continue;\n            comps++;\n            int col = b[r][c];\n            queue<pair<int, int>> q;\n            q.push({r, c});\n            vis[r][c] = true;\n            int sz = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front();\n                q.pop();\n                sz++;\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dr[k], ny = y + dc[k];\n                    if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;\n                    if (vis[nx][ny]) continue;\n                    if (b[nx][ny] != col) continue;\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n            totalScore += sz * sz;\n        }\n    }\n    return {totalScore, comps};\n}\n\nint distSum(const Board &b, const array<pair<int, int>, 4> &target) {\n    int s = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            int col = b[r][c];\n            if (col == 0) continue;\n            s += abs(r - target[col].first) + abs(c - target[col].second);\n        }\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavor(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavor[i])) return 0;\n    }\n\n    // count flavors\n    array<int, 4> cnt = {0, 0, 0, 0};\n    for (int f : flavor) cnt[f]++;\n\n    // corners\n    array<pair<int, int>, 4> corners = {make_pair(0, 0), make_pair(0, 9), make_pair(9, 0), make_pair(9, 9)};\n    // assign each flavor to a distinct corner maximizing weighted distance\n    array<pair<int, int>, 4> target;\n    target[0] = {0, 0};\n    long long bestMetric = -1;\n    array<int, 4> bestAssign = {0, 0, 0, 0};\n    for (int i = 0; i < 4; i++) {\n        for (int j = 0; j < 4; j++) if (j != i) {\n            for (int k = 0; k < 4; k++) if (k != i && k != j) {\n                long long metric = 0;\n                metric += 1LL * cnt[1] * cnt[2] * (abs(corners[i].first - corners[j].first) + abs(corners[i].second - corners[j].second));\n                metric += 1LL * cnt[1] * cnt[3] * (abs(corners[i].first - corners[k].first) + abs(corners[i].second - corners[k].second));\n                metric += 1LL * cnt[2] * cnt[3] * (abs(corners[j].first - corners[k].first) + abs(corners[j].second - corners[k].second));\n                if (metric > bestMetric) {\n                    bestMetric = metric;\n                    bestAssign[1] = i;\n                    bestAssign[2] = j;\n                    bestAssign[3] = k;\n                }\n            }\n        }\n    }\n    for (int f = 1; f <= 3; f++) {\n        target[f] = corners[bestAssign[f]];\n    }\n\n    Board cur;\n    for (auto &row : cur) row.fill(0);\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        if (!(cin >> p)) break;\n\n        // place new candy at p-th empty cell (row-major)\n        int cntEmpty = 0;\n        int pr = -1, pc = -1;\n        for (int r = 0; r < 10; r++) {\n            for (int c = 0; c < 10; c++) {\n                if (cur[r][c] == 0) {\n                    cntEmpty++;\n                    if (cntEmpty == p) {\n                        pr = r;\n                        pc = c;\n                        goto placed;\n                    }\n                }\n            }\n        }\n    placed:\n        if (pr == -1) { pr = 0; pc = 0; }\n        cur[pr][pc] = flavor[t];\n\n        int distCur = distSum(cur, target);\n\n        int bestDir = 0;\n        int bestScore = -1;\n        int bestDelta = -1e9;\n        int bestComp = 1e9;\n        int bestDist = 1e9;\n        Board bestBoard = cur;\n\n        for (int dir = 0; dir < 4; dir++) {\n            Board nb = tilt(cur, dir);\n            auto [sc, comp] = scoreAndComp(nb);\n            int d = distSum(nb, target);\n            int delta = distCur - d;\n            if (sc > bestScore ||\n                (sc == bestScore && delta > bestDelta) ||\n                (sc == bestScore && delta == bestDelta && comp < bestComp) ||\n                (sc == bestScore && delta == bestDelta && comp == bestComp && d < bestDist)) {\n                bestScore = sc;\n                bestDelta = delta;\n                bestComp = comp;\n                bestDist = d;\n                bestDir = dir;\n                bestBoard = nb;\n            }\n        }\n\n        cout << DIR_CH[bestDir] << '\\n' << flush;\n        cur = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GraphData {\n    int N;\n    vector<vector<uint8_t>> adj; // NxN\n    vector<int> deg, f1, f2, tri;\n    vector<int> sortedDeg;\n};\n\nvoid compute_features(GraphData &g){\n    int N = g.N;\n    g.deg.assign(N,0);\n    g.f1.assign(N,0);\n    g.f2.assign(N,0);\n    g.tri.assign(N,0);\n    // degree\n    for(int i=0;i<N;i++){\n        int d=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) d++;\n        g.deg[i]=d;\n    }\n    // f1\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.deg[j];\n        g.f1[i]=s;\n    }\n    // f2\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.f1[j];\n        g.f2[i]=s;\n    }\n    // triangles per vertex (naive)\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++) if(g.adj[i][j]){\n            for(int k=j+1;k<N;k++) if(g.adj[i][k] && g.adj[j][k]){\n                g.tri[i]++; g.tri[j]++; g.tri[k]++;\n            }\n        }\n    }\n    g.sortedDeg = g.deg;\n    sort(g.sortedDeg.begin(), g.sortedDeg.end());\n}\n\n// Hungarian algorithm for minimum cost assignment\nvector<int> hungarian(const vector<vector<double>> &a){\n    int n = (int)a.size();\n    int m = n;\n    const double INF = 1e18;\n    vector<double> u(n+1), v(m+1);\n    vector<int> p(m+1), way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;\n        int j0=0;\n        vector<double> minv(m+1, INF);\n        vector<char> used(m+1, false);\n        do{\n            used[j0]=true;\n            int i0 = p[j0];\n            double delta = INF;\n            int j1 = 0;\n            for(int j=1;j<=m;j++) if(!used[j]){\n                double cur = a[i0-1][j-1] - u[i0] - v[j];\n                if(cur < minv[j]){\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if(minv[j] < delta){\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for(int j=0;j<=m;j++){\n                if(used[j]){\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                }else{\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        }while(p[j0]!=0);\n        // augmenting\n        do{\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        }while(j0);\n    }\n    vector<int> assignment(n, -1); // row -> col\n    for(int j=1;j<=m;j++){\n        if(p[j]>0 && p[j]<=n) assignment[p[j]-1] = j-1;\n    }\n    return assignment;\n}\n\nint degree_distance(const vector<int>& a, const vector<int>& b){\n    int n=a.size();\n    int s=0;\n    for(int i=0;i<n;i++) s += abs(a[i]-b[i]);\n    return s;\n}\n\nint compute_mismatch(const vector<vector<uint8_t>>& H, const vector<vector<uint8_t>>& G, const vector<int>& assign, int bestLimit){\n    int n = assign.size();\n    int mism=0;\n    for(int i=0;i<n;i++){\n        int gi = assign[i];\n        for(int j=i+1;j<n;j++){\n            int gj = assign[j];\n            if(H[i][j] != G[gi][gj]) mism++;\n        }\n        if(mism >= bestLimit) return mism;\n    }\n    return mism;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n    // decide N\n    int N = 25 + int(60.0*eps + 0.5);\n    if(M > 80) N += 5;\n    else if(M > 50) N += 2;\n    if(M < 30) N -= 3;\n    if(eps > 0.30) N += 4;\n    N = max(4, min(100, N));\n    int Kcap = 30;\n    int K = min(M, max(5, min(Kcap, (int)(eps*75.0)+5)));\n    // generate graphs\n    mt19937 rng(1234567);\n    vector<GraphData> graphs(M);\n    for(int k=0;k<M;k++){\n        GraphData g;\n        g.N = N;\n        g.adj.assign(N, vector<uint8_t>(N,0));\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                bool e = (rng() & 1);\n                g.adj[i][j]=g.adj[j][i]= e;\n            }\n        }\n        compute_features(g);\n        graphs[k]=move(g);\n    }\n    // output graphs\n    cout<<N<<\"\\n\";\n    int E = N*(N-1)/2;\n    string line;\n    line.reserve(E);\n    for(int k=0;k<M;k++){\n        line.clear();\n        line.reserve(E);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                line.push_back(graphs[k].adj[i][j] ? '1' : '0');\n            }\n        }\n        cout<<line<<\"\\n\";\n    }\n    cout.flush();\n    // process queries\n    vector<vector<uint8_t>> HAdj(N, vector<uint8_t>(N,0));\n    GraphData HG;\n    HG.N = N;\n    for(int qi=0; qi<100; qi++){\n        string hstr;\n        if(!(cin>>hstr)) break;\n        // build adjacency\n        int idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                char c = hstr[idx++];\n                uint8_t v = (c=='1');\n                HAdj[i][j]=HAdj[j][i]=v;\n            }\n        }\n        HG.adj = HAdj;\n        compute_features(HG);\n        // distances for pruning\n        vector<pair<int,int>> distIdx;\n        distIdx.reserve(M);\n        for(int k=0;k<M;k++){\n            int d = degree_distance(HG.sortedDeg, graphs[k].sortedDeg);\n            distIdx.emplace_back(d, k);\n        }\n        nth_element(distIdx.begin(), distIdx.begin()+K, distIdx.end(),\n                    [](auto &a, auto &b){ return a.first < b.first; });\n        distIdx.resize(K);\n        sort(distIdx.begin(), distIdx.end()); // optional\n        int bestMismatch = N*N; // upper bound\n        int bestIdx = distIdx[0].second;\n        // precompute weight factors\n        double s = 1.0 - 2.0*eps;\n        if(s < 0.05) s = 0.05;\n        double w1 = s;\n        double w2 = s*s;\n        double w3 = s;\n        double invN = 1.0 / (double)N;\n        double invNN = 1.0 / ((double)N*(double)N);\n        // candidate evaluation\n        vector<vector<double>> cost(N, vector<double>(N));\n        for(auto &dk : distIdx){\n            int k = dk.second;\n            // build cost matrix\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    double c = abs(HG.deg[i] - graphs[k].deg[j]);\n                    c += w1 * (double)abs(HG.f1[i] - graphs[k].f1[j]) * invN;\n                    c += w2 * (double)abs(HG.f2[i] - graphs[k].f2[j]) * invNN;\n                    c += w3 * (double)abs(HG.tri[i] - graphs[k].tri[j]) * invN;\n                    cost[i][j]=c;\n                }\n            }\n            vector<int> assign = hungarian(cost); // H row -> G col\n            int mism = compute_mismatch(HAdj, graphs[k].adj, assign, bestMismatch);\n            if(mism < bestMismatch){\n                bestMismatch = mism;\n                bestIdx = k;\n            }\n        }\n        cout<<bestIdx<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\n// Dijkstra that skips one edge\nlong long dijkstra_skip(int s, int t, int skip_id,\n                        const vector<vector<Adj>> &adj,\n                        vector<long long> &dist) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        if (u == t) break;\n        for (auto &e : adj[u]) {\n            if (e.id == skip_id) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n    return dist[t];\n}\n\n// Dijkstra that records one parent edge (shortest path tree)\nvoid dijkstra_parent(int s, const vector<vector<Adj>> &adj,\n                     vector<long long> &dist, vector<int> &parent) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    fill(parent.begin(), parent.end(), -1);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                parent[e.to] = e.id;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u;\n        --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    // read coordinates (not used)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<long long> dist(N);\n    vector<long long> altDiff(M);\n    for (int i = 0; i < M; i++) {\n        auto &e = edges[i];\n        long long alt = dijkstra_skip(e.u, e.v, i, adj, dist);\n        if (alt >= (1LL << 59)) {\n            altDiff[i] = 0;  // fallback\n        } else {\n            altDiff[i] = alt - e.w;\n            if (altDiff[i] < 0) altDiff[i] = 0;\n        }\n    }\n\n    int S = min(N, 30);\n    vector<int> sources;\n    int step = max(1, N / S);\n    for (int i = 0; i < N && (int)sources.size() < S; i += step) {\n        sources.push_back(i);\n    }\n    while ((int)sources.size() < S) sources.push_back((int)sources.size());\n    vector<int> centrality(M, 0);\n    vector<int> parent(N);\n    for (int s : sources) {\n        dijkstra_parent(s, adj, dist, parent);\n        for (int v = 0; v < N; v++) {\n            if (v == s) continue;\n            int pe = parent[v];\n            if (pe >= 0) centrality[pe]++;\n        }\n    }\n\n    vector<long double> importance(M);\n    long double sumImp = 0;\n    for (int i = 0; i < M; i++) {\n        long double imp = (long double)altDiff[i] * ((long double)centrality[i] + 1.0L);\n        importance[i] = imp;\n        sumImp += imp;\n    }\n    long double avgImp = sumImp / (long double)max(1, M);\n    long double alpha = avgImp * 0.5L;\n    if (alpha < 1e-6) alpha = 1.0L;\n\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (importance[a] == importance[b]) return a < b;\n        return importance[a] > importance[b];\n    });\n\n    vector<int> answer(M, 0);\n    vector<long double> dayLoad(D, 0.0L);\n    vector<int> dayCount(D, 0);\n    vector<vector<uint16_t>> vtxCount(N, vector<uint16_t>(D, 0));\n\n    auto chooseDay = [&](int u, int v) -> int {\n        long double bestCost = 1e100;\n        int bestDay = -1;\n        for (int d = 0; d < D; d++) {\n            if (dayCount[d] >= K) continue;\n            int s1 = (int)vtxCount[u][d] + (int)vtxCount[v][d];\n            long double cost = dayLoad[d] + alpha * (long double)s1;\n            if (cost < bestCost - 1e-9L) {\n                bestCost = cost;\n                bestDay = d;\n            } else if (fabsl(cost - bestCost) <= 1e-9L) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay] ||\n                    (dayCount[d] == dayCount[bestDay] && d < bestDay)) {\n                    bestDay = d;\n                }\n            }\n        }\n        if (bestDay == -1) {\n            // should not happen, but fallback\n            for (int d = 0; d < D; d++) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay]) bestDay = d;\n            }\n        }\n        return bestDay;\n    };\n\n    // initial assignment\n    for (int eid : order) {\n        int u = edges[eid].u;\n        int v = edges[eid].v;\n        int d = chooseDay(u, v);\n        answer[eid] = d + 1;\n        dayLoad[d] += importance[eid];\n        dayCount[d]++;\n        vtxCount[u][d]++;\n        vtxCount[v][d]++;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int improvePasses = 1;\n    for (int pass = 0; pass < improvePasses; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.5) break;  // time guard\n        for (int eid : order) {\n            int curr = answer[eid] - 1;\n            int u = edges[eid].u;\n            int v = edges[eid].v;\n            long double imp = importance[eid];\n            // remove\n            dayLoad[curr] -= imp;\n            dayCount[curr]--;\n            vtxCount[u][curr]--;\n            vtxCount[v][curr]--;\n            // choose best day again\n            int nd = chooseDay(u, v);\n            answer[eid] = nd + 1;\n            dayLoad[nd] += imp;\n            dayCount[nd]++;\n            vtxCount[u][nd]++;\n            vtxCount[v][nd]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << answer[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct MatchingResult {\n    int domCount;\n    vector<pair<int,int>> doms;\n    vector<int> monos;\n    vector<char> occ;\n};\n\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> dist, matchL, matchR;\n    HopcroftKarp(int nL=0,int nR=0): nL(nL), nR(nR), adj(nL) {}\n    void addEdge(int u,int v){ adj[u].push_back(v); }\n    bool bfs(){\n        queue<int> q;\n        dist.assign(nL, -1);\n        for(int i=0;i<nL;i++){\n            if(matchL[i]==-1){\n                dist[i]=0;\n                q.push(i);\n            }\n        }\n        bool reachable=false;\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for(int v: adj[u]){\n                int mu = matchR[v];\n                if(mu>=0 && dist[mu]==-1){\n                    dist[mu]=dist[u]+1;\n                    q.push(mu);\n                }\n                if(mu==-1) reachable=true;\n            }\n        }\n        return reachable;\n    }\n    bool dfs(int u){\n        for(int v: adj[u]){\n            int mu=matchR[v];\n            if(mu==-1 || (dist[mu]==dist[u]+1 && dfs(mu))){\n                matchL[u]=v;\n                matchR[v]=u;\n                return true;\n            }\n        }\n        dist[u]=-1;\n        return false;\n    }\n    int maxMatching(){\n        matchL.assign(nL, -1);\n        matchR.assign(nR, -1);\n        int m=0;\n        while(bfs()){\n            for(int i=0;i<nL;i++){\n                if(matchL[i]==-1){\n                    if(dfs(i)) m++;\n                }\n            }\n        }\n        return m;\n    }\n};\n\nstruct Solver {\n    int D, V;\n    vector<string> f[2], r[2];\n    inline int idx(int x,int y,int z) const { return (x*D + y)*D + z; }\n    inline tuple<int,int,int> decode(int id) const {\n        int z = id % D;\n        int y = (id / D) % D;\n        int x = id / (D*D);\n        return {x,y,z};\n    }\n\n    vector<int> build_min_occ(const vector<string>& fmat, const vector<string>& rmat){\n        vector<int> occList;\n        vector<char> occ(V, 0);\n        for(int z=0; z<D; z++){\n            vector<int> xs, ys;\n            for(int x=0;x<D;x++) if(fmat[z][x]=='1') xs.push_back(x);\n            for(int y=0;y<D;y++) if(rmat[z][y]=='1') ys.push_back(y);\n            if(xs.empty() || ys.empty()) continue;\n            if(xs.size() >= ys.size()){\n                int y0 = ys[0];\n                for(int i=0;i<(int)xs.size();i++){\n                    int y = (i<(int)ys.size()) ? ys[i] : y0;\n                    int id = idx(xs[i], y, z);\n                    if(!occ[id]){\n                        occ[id]=1;\n                        occList.push_back(id);\n                    }\n                }\n            }else{\n                int x0 = xs[0];\n                for(int i=0;i<(int)ys.size();i++){\n                    int x = (i<(int)xs.size()) ? xs[i] : x0;\n                    int id = idx(x, ys[i], z);\n                    if(!occ[id]){\n                        occ[id]=1;\n                        occList.push_back(id);\n                    }\n                }\n            }\n        }\n        return occList;\n    }\n\n    MatchingResult max_match_on_occ(const vector<int>& occList){\n        vector<char> occ(V, 0);\n        for(int id: occList) occ[id]=1;\n        // map indices\n        vector<int> leftId(V, -1), rightId(V, -1);\n        vector<int> leftMap, rightMap;\n        int nL=0, nR=0;\n        for(int id: occList){\n            auto [x,y,z]=decode(id);\n            if( ( (x+y+z)&1)==0 ){\n                leftId[id]=nL++;\n                leftMap.push_back(id);\n            }else{\n                rightId[id]=nR++;\n                rightMap.push_back(id);\n            }\n        }\n        HopcroftKarp hk(nL, nR);\n        int dx[6]={1,-1,0,0,0,0};\n        int dy[6]={0,0,1,-1,0,0};\n        int dz[6]={0,0,0,0,1,-1};\n        for(int id: occList){\n            auto [x,y,z]=decode(id);\n            if( ((x+y+z)&1)!=0 ) continue;\n            int u=leftId[id];\n            for(int dir=0; dir<6; dir++){\n                int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                if(nx<0||ny<0||nz<0||nx>=D||ny>=D||nz>=D) continue;\n                int nid=idx(nx,ny,nz);\n                if(occ[nid] && rightId[nid]!=-1){\n                    hk.addEdge(u, rightId[nid]);\n                }\n            }\n        }\n        int msize = hk.maxMatching();\n        MatchingResult res;\n        res.domCount = msize;\n        res.doms.reserve(msize);\n        res.monos.clear();\n        res.occ = occ;\n        // build doms\n        for(int u=0; u<nL; u++){\n            int v = hk.matchL[u];\n            if(v!=-1){\n                int a = leftMap[u];\n                int b = rightMap[v];\n                res.doms.push_back({a,b});\n            }\n        }\n        // unmatched as monos\n        vector<char> matchedL(nL,0), matchedR(nR,0);\n        for(int u=0; u<nL; u++){\n            if(hk.matchL[u]!=-1) matchedL[u]=1;\n        }\n        for(int v=0; v<nR; v++){\n            if(hk.matchR[v]!=-1) matchedR[v]=1;\n        }\n        for(int u=0; u<nL; u++){\n            if(!matchedL[u]) res.monos.push_back(leftMap[u]);\n        }\n        for(int v=0; v<nR; v++){\n            if(!matchedR[v]) res.monos.push_back(rightMap[v]);\n        }\n        return res;\n    }\n\n    void augment(MatchingResult& res, int targetDom, int targetMono, const vector<char>& allowed){\n        int dx[3]={1,0,0};\n        int dy[3]={0,1,0};\n        int dz[3]={0,0,1};\n        // place dominos\n        while((int)res.doms.size() < targetDom){\n            bool placed=false;\n            for(int x=0; x<D && !placed; x++){\n                for(int y=0; y<D && !placed; y++){\n                    for(int z=0; z<D && !placed; z++){\n                        int id = idx(x,y,z);\n                        if(res.occ[id] || !allowed[id]) continue;\n                        for(int dir=0; dir<3 && !placed; dir++){\n                            int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                            if(nx>=D||ny>=D||nz>=D) continue;\n                            int id2=idx(nx,ny,nz);\n                            if(!res.occ[id2] && allowed[id2]){\n                                res.occ[id]=res.occ[id2]=1;\n                                res.doms.push_back({id,id2});\n                                placed=true;\n                            }\n                        }\n                    }\n                }\n            }\n            if(!placed) break;\n        }\n        // place monos\n        while((int)res.monos.size() < targetMono){\n            bool placed=false;\n            for(int x=0; x<D && !placed; x++){\n                for(int y=0; y<D && !placed; y++){\n                    for(int z=0; z<D && !placed; z++){\n                        int id = idx(x,y,z);\n                        if(!res.occ[id] && allowed[id]){\n                            res.occ[id]=1;\n                            res.monos.push_back(id);\n                            placed=true;\n                        }\n                    }\n                }\n            }\n            if(!placed) break;\n        }\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        if(!(cin>>D)) return;\n        V = D*D*D;\n        for(int s=0; s<2; s++){\n            f[s].resize(D);\n            for(int i=0;i<D;i++) cin>>f[s][i];\n            r[s].resize(D);\n            for(int i=0;i<D;i++) cin>>r[s][i];\n        }\n        vector<char> allowed[2];\n        for(int s=0; s<2; s++){\n            allowed[s].assign(V, 0);\n            for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n                if(f[s][z][x]=='1' && r[s][z][y]=='1'){\n                    allowed[s][idx(x,y,z)] = 1;\n                }\n            }\n        }\n        vector<int> occList[2];\n        MatchingResult res[2];\n        for(int s=0; s<2; s++){\n            occList[s] = build_min_occ(f[s], r[s]);\n            res[s] = max_match_on_occ(occList[s]);\n        }\n        int targetDom = max((int)res[0].doms.size(), (int)res[1].doms.size());\n        int targetMono = max((int)res[0].monos.size(), (int)res[1].monos.size());\n        augment(res[0], targetDom, targetMono, allowed[0]);\n        augment(res[1], targetDom, targetMono, allowed[1]);\n        int domMax = max((int)res[0].doms.size(), (int)res[1].doms.size());\n        int monoMax = max((int)res[0].monos.size(), (int)res[1].monos.size());\n        int n = domMax + monoMax;\n        vector<int> out0(V,0), out1(V,0);\n        for(int i=0;i<(int)res[0].doms.size();i++){\n            int id=i+1;\n            out0[res[0].doms[i].first]=id;\n            out0[res[0].doms[i].second]=id;\n        }\n        for(int i=0;i<(int)res[1].doms.size();i++){\n            int id=i+1;\n            out1[res[1].doms[i].first]=id;\n            out1[res[1].doms[i].second]=id;\n        }\n        for(int i=0;i<(int)res[0].monos.size();i++){\n            int id=domMax + i + 1;\n            out0[res[0].monos[i]] = id;\n        }\n        for(int i=0;i<(int)res[1].monos.size();i++){\n            int id=domMax + i + 1;\n            out1[res[1].monos[i]] = id;\n        }\n        cout<<n<<\"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout<<' ';\n            cout<<out0[i];\n        }\n        cout<<\"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout<<' ';\n            cout<<out1[i];\n        }\n        cout<<\"\\n\";\n    }\n};\n\nint main(){\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeAdj {\n    int to;\n    int id;\n    long long w;\n};\nstruct DSU {\n    vector<int> p;\n    DSU(int n) : p(n, -1) {}\n    int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (p[a] > p[b]) swap(a, b);\n        p[a] += p[b];\n        p[b] = a;\n        return true;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    long long cost;\n    int covered;\n};\n\nint ceil_sqrt_ll(long long x) {\n    if (x <= 0) return 0;\n    long long r = (long long)std::sqrt((long double)x);\n    while (r * r < x) ++r;\n    while ((r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<long long> W(M);\n    vector<vector<EdgeAdj>> g(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        U[j] = u; V[j] = v; W[j] = w;\n        g[u].push_back({v, j, w});\n        g[v].push_back({u, j, w});\n    }\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n\n    const int LIMIT = 5000;\n    const int LIMIT2 = LIMIT * LIMIT;\n    const long long INFLL = (1LL << 60);\n\n    // dist2 and within/sorted lists\n    vector<vector<int>> dist2(N, vector<int>(K));\n    vector<vector<int>> within(N);\n    vector<vector<pair<int, int>>> sortedList(N);\n    for (int i = 0; i < N; i++) {\n        within[i].reserve(K / 4);\n        sortedList[i].reserve(K / 4);\n        for (int k = 0; k < K; k++) {\n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            long long d2 = dx * dx + dy * dy;\n            dist2[i][k] = (int)d2;\n            if (d2 <= LIMIT2) {\n                within[i].push_back(k);\n                sortedList[i].push_back({(int)d2, k});\n            }\n        }\n        sort(sortedList[i].begin(), sortedList[i].end(),\n             [](const pair<int, int> &p1, const pair<int, int> &p2) {\n                 if (p1.first != p2.first) return p1.first < p2.first;\n                 return p1.second < p2.second;\n             });\n    }\n\n    // all-pairs shortest paths\n    vector<vector<long long>> distMat(N, vector<long long>(N, INFLL));\n    vector<vector<int>> parentEdge(N, vector<int>(N, -1));\n    using PLLI = pair<long long, int>;\n    for (int s = 0; s < N; s++) {\n        vector<long long> d(N, INFLL);\n        vector<int> p(N, -1);\n        d[s] = 0;\n        priority_queue<PLLI, vector<PLLI>, greater<PLLI>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cd, v] = pq.top(); pq.pop();\n            if (cd != d[v]) continue;\n            for (auto &e : g[v]) {\n                long long nd = cd + e.w;\n                if (nd < d[e.to]) {\n                    d[e.to] = nd;\n                    p[e.to] = e.id;\n                    pq.push({nd, e.to});\n                }\n            }\n        }\n        distMat[s] = move(d);\n        parentEdge[s] = move(p);\n    }\n    vector<long long> spCost(N);\n    for (int i = 0; i < N; i++) spCost[i] = distMat[0][i];\n\n    // full MST edges\n    struct EItem { long long w; int id; };\n    vector<EItem> eList;\n    eList.reserve(M);\n    for (int i = 0; i < M; i++) eList.push_back({W[i], i});\n    sort(eList.begin(), eList.end(), [](const EItem &a, const EItem &b){ return a.w < b.w; });\n    DSU dsuFull(N);\n    vector<int> mstFullEdges;\n    mstFullEdges.reserve(N - 1);\n    for (auto &ei : eList) {\n        int id = ei.id;\n        if (dsuFull.unite(U[id], V[id])) {\n            mstFullEdges.push_back(id);\n            if ((int)mstFullEdges.size() == N - 1) break;\n        }\n    }\n\n    auto prune_edges = [&](const vector<int> &Pvec, vector<int> &Bvec) {\n        vector<int> deg(N, 0);\n        vector<vector<int>> inc(N);\n        inc.assign(N, {});\n        for (int e = 0; e < M; e++) if (Bvec[e]) {\n            int a = U[e], b = V[e];\n            deg[a]++; deg[b]++;\n            inc[a].push_back(e);\n            inc[b].push_back(e);\n        }\n        auto isTerminal = [&](int v)->bool {\n            return Pvec[v] > 0 || v == 0;\n        };\n        queue<int> q;\n        vector<char> inq(N, false);\n        for (int i = 0; i < N; i++) {\n            if (!isTerminal(i) && deg[i] == 1) { q.push(i); inq[i] = true; }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (isTerminal(v) || deg[v] != 1) continue;\n            int eAct = -1;\n            for (int eid : inc[v]) if (Bvec[eid]) { eAct = eid; break; }\n            if (eAct == -1) continue;\n            Bvec[eAct] = 0;\n            int nei = (U[eAct] == v ? V[eAct] : U[eAct]);\n            deg[v]--; deg[nei]--;\n            if (!isTerminal(nei) && deg[nei] == 1 && !inq[nei]) { q.push(nei); inq[nei] = true; }\n        }\n    };\n\n    auto improve_P = [&](vector<int> P) {\n        // compute coverage counts\n        vector<int> cnt(K, 0);\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                cnt[pr.second]++;\n            }\n        }\n        for (int iter = 0; iter < 2; iter++) {\n            bool changed = false;\n            for (int i = 0; i < N; i++) {\n                if (P[i] == 0) continue;\n                long long curR2 = 1LL * P[i] * P[i];\n                long long needR2 = -1;\n                for (auto &pr : sortedList[i]) {\n                    if (pr.first > curR2) break;\n                    int k = pr.second;\n                    if (cnt[k] == 1 && pr.first > needR2) needR2 = pr.first;\n                }\n                long long newR2 = (needR2 == -1 ? 0 : needR2);\n                if (newR2 < curR2) {\n                    bool ok = true;\n                    for (auto &pr : sortedList[i]) {\n                        if (pr.first > curR2) break;\n                        if (pr.first > newR2) {\n                            int k = pr.second;\n                            if (cnt[k] <= 1) { ok = false; break; }\n                        }\n                    }\n                    if (ok) {\n                        for (auto &pr : sortedList[i]) {\n                            if (pr.first > curR2) break;\n                            if (pr.first > newR2) {\n                                int k = pr.second;\n                                cnt[k]--;\n                            }\n                        }\n                        int newR = (newR2 == 0 ? 0 : ceil_sqrt_ll(newR2));\n                        P[i] = newR;\n                        changed = true;\n                    }\n                }\n            }\n            if (!changed) break;\n        }\n        return P;\n    };\n\n    auto eval_with_P = [&](vector<int> P)->Solution {\n        P = improve_P(P);\n        // coverage\n        vector<char> covered(K, false);\n        int covcnt = 0;\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                int k = pr.second;\n                if (!covered[k]) { covered[k] = true; covcnt++; }\n            }\n        }\n        long long costP = 0;\n        for (int i = 0; i < N; i++) costP += 1LL * P[i] * P[i];\n\n        vector<int> terminals;\n        terminals.push_back(0);\n        for (int i = 1; i < N; i++) if (P[i] > 0) terminals.push_back(i);\n        int T = terminals.size();\n\n        // Option 1: metric MST\n        vector<int> B1(M, 0);\n        if (T > 1) {\n            vector<tuple<long long, int, int>> es;\n            es.reserve(T * (T - 1) / 2);\n            for (int i = 0; i < T; i++) {\n                int u = terminals[i];\n                for (int j = i + 1; j < T; j++) {\n                    int v = terminals[j];\n                    es.emplace_back(distMat[u][v], u, v);\n                }\n            }\n            sort(es.begin(), es.end(),\n                 [](const auto &a, const auto &b){ return get<0>(a) < get<0>(b); });\n            DSU dsu(N);\n            int added = 0;\n            for (auto &ed : es) {\n                long long w; int u, v;\n                tie(w, u, v) = ed;\n                if (dsu.unite(u, v)) {\n                    int cur = v;\n                    while (cur != u) {\n                        int e = parentEdge[u][cur];\n                        if (e == -1) break;\n                        B1[e] = 1;\n                        cur = (U[e] == cur ? V[e] : U[e]);\n                    }\n                    if (++added == T - 1) break;\n                }\n            }\n        }\n        prune_edges(P, B1);\n        long long costE1 = 0;\n        for (int e = 0; e < M; e++) if (B1[e]) costE1 += W[e];\n\n        // Option 2: full MST pruned\n        vector<int> B2(M, 0);\n        for (int eid : mstFullEdges) B2[eid] = 1;\n        prune_edges(P, B2);\n        long long costE2 = 0;\n        for (int e = 0; e < M; e++) if (B2[e]) costE2 += W[e];\n\n        // Option 3: shortest path tree from root\n        vector<int> B3(M, 0);\n        for (int v : terminals) {\n            if (v == 0) continue;\n            int cur = v;\n            while (cur != 0) {\n                int e = parentEdge[0][cur];\n                if (e == -1) break;\n                B3[e] = 1;\n                cur = (U[e] == cur ? V[e] : U[e]);\n            }\n        }\n        prune_edges(P, B3);\n        long long costE3 = 0;\n        for (int e = 0; e < M; e++) if (B3[e]) costE3 += W[e];\n\n        long long tot1 = costP + costE1;\n        long long tot2 = costP + costE2;\n        long long tot3 = costP + costE3;\n        if (tot1 <= tot2 && tot1 <= tot3) {\n            return Solution{P, B1, tot1, covcnt};\n        } else if (tot2 <= tot1 && tot2 <= tot3) {\n            return Solution{P, B2, tot2, covcnt};\n        } else {\n            return Solution{P, B3, tot3, covcnt};\n        }\n    };\n\n    auto ensure_coverage = [&](vector<int> allowed) {\n        vector<char> inAllowed(N, false);\n        for (int v : allowed) inAllowed[v] = true;\n        vector<char> cov(K, false);\n        int uncovered = K;\n        for (int v : allowed) {\n            for (int k : within[v]) {\n                if (!cov[k]) { cov[k] = true; uncovered--; }\n            }\n        }\n        while (uncovered > 0) {\n            int target = -1;\n            for (int k = 0; k < K; k++) if (!cov[k]) { target = k; break; }\n            if (target == -1) break;\n            int bestv = -1; int bestd = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                int d = dist2[i][target];\n                if (d <= LIMIT2 && d < bestd) { bestd = d; bestv = i; }\n            }\n            if (bestv == -1) break;\n            if (!inAllowed[bestv]) {\n                inAllowed[bestv] = true;\n                allowed.push_back(bestv);\n                for (int k : within[bestv]) if (!cov[k]) { cov[k] = true; uncovered--; }\n            } else {\n                break;\n            }\n        }\n        return allowed;\n    };\n\n    auto buildP_nearest = [&](const vector<int> &allowed) {\n        vector<int> maxd2(N, -1);\n        for (int k = 0; k < K; k++) {\n            int best = -1;\n            int bestd = INT_MAX;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < bestd) { bestd = d; best = v; }\n            }\n            if (best == -1) continue;\n            if (bestd > maxd2[best]) maxd2[best] = bestd;\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (maxd2[i] >= 0) {\n                int r = ceil_sqrt_ll(maxd2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto buildP_incAssign = [&](const vector<int> &allowed) {\n        vector<long long> cur_r2(N, 0);\n        vector<int> minDist2(K, INT_MAX);\n        for (int k = 0; k < K; k++) {\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < minDist2[k]) minDist2[k] = d;\n            }\n        }\n        vector<int> order(K);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j){ return minDist2[i] > minDist2[j]; });\n        double gamma = 0.1;\n        for (int idx = 0; idx < K; idx++) {\n            int k = order[idx];\n            int best = -1;\n            double bestInc = 1e100;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d > LIMIT2) continue;\n                long long inc = max(cur_r2[v], (long long)d) - cur_r2[v];\n                double incAdj = (double)inc + (cur_r2[v] == 0 ? gamma * spCost[v] : 0.0);\n                if (incAdj < bestInc) {\n                    bestInc = incAdj;\n                    best = v;\n                }\n            }\n            if (best == -1) continue;\n            long long nd = dist2[best][k];\n            if (nd > cur_r2[best]) cur_r2[best] = nd;\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (cur_r2[i] > 0) {\n                int r = ceil_sqrt_ll(cur_r2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto expansion_greedy = [&](double beta) {\n        vector<long long> cur_r2(N, 0);\n        vector<char> covered(K, false);\n        int uncovered = K;\n        while (uncovered > 0) {\n            int bestStation = -1;\n            double bestRatio = 1e100;\n            long long bestR2 = 0;\n            for (int i = 0; i < N; i++) {\n                long long rcur = cur_r2[i];\n                int cnt = 0;\n                long long lastd = -1;\n                double bestLocalRatio = 1e100;\n                long long bestLocalR2 = -1;\n                for (auto &pr : sortedList[i]) {\n                    int d2 = pr.first;\n                    if (d2 <= rcur) continue;\n                    int res = pr.second;\n                    if (!covered[res]) cnt++;\n                    if (d2 != lastd) {\n                        if (cnt > 0) {\n                            double incCost = (double)(d2 - rcur);\n                            if (rcur == 0) incCost += beta * (double)spCost[i];\n                            double ratio = incCost / cnt;\n                            if (ratio < bestLocalRatio) {\n                                bestLocalRatio = ratio;\n                                bestLocalR2 = d2;\n                            }\n                        }\n                        lastd = d2;\n                    }\n                }\n                if (bestLocalR2 != -1 && bestLocalRatio < bestRatio) {\n                    bestRatio = bestLocalRatio;\n                    bestStation = i;\n                    bestR2 = bestLocalR2;\n                }\n            }\n            if (bestStation == -1) break;\n            cur_r2[bestStation] = bestR2;\n            for (auto &pr : sortedList[bestStation]) {\n                if (pr.first > bestR2) break;\n                int res = pr.second;\n                if (!covered[res]) {\n                    covered[res] = true;\n                    uncovered--;\n                }\n            }\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (cur_r2[i] > 0) {\n                int r = ceil_sqrt_ll(cur_r2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    // allowed sets\n    auto greedy_cover_allowed = [&]() {\n        vector<char> covered(K, false);\n        int uncovered = K;\n        vector<char> sel(N, false);\n        sel[0] = true;\n        while (uncovered > 0) {\n            int best = -1;\n            int bestCnt = 0;\n            for (int i = 0; i < N; i++) {\n                if (sel[i]) continue;\n                int cnt = 0;\n                for (int k : within[i]) if (!covered[k]) cnt++;\n                if (cnt > bestCnt) { bestCnt = cnt; best = i; }\n            }\n            if (best == -1 || bestCnt == 0) break;\n            sel[best] = true;\n            for (int k : within[best]) if (!covered[k]) { covered[k] = true; uncovered--; }\n        }\n        vector<int> res;\n        for (int i = 0; i < N; i++) if (sel[i]) res.push_back(i);\n        return res;\n    };\n    vector<int> allowedSel = greedy_cover_allowed();\n    vector<int> allowedAug;\n    {\n        int TH = 3500, TH2 = TH * TH;\n        vector<char> flag(N, false);\n        for (int v : allowedSel) flag[v] = true;\n        for (int k = 0; k < K; k++) {\n            int bestd = INT_MAX;\n            for (int v : allowedSel) {\n                int d = dist2[v][k];\n                if (d < bestd) bestd = d;\n            }\n            if (bestd > TH2) {\n                int bestv = -1; int bestdv = INT_MAX;\n                for (int i = 0; i < N; i++) {\n                    int d = dist2[i][k];\n                    if (d < bestdv) { bestdv = d; bestv = i; }\n                }\n                if (bestv != -1) flag[bestv] = true;\n            }\n        }\n        for (int i = 0; i < N; i++) if (flag[i]) allowedAug.push_back(i);\n    }\n    vector<int> allSet(N);\n    iota(allSet.begin(), allSet.end(), 0);\n\n    vector<Solution> candidates;\n    vector<int> allowed1 = ensure_coverage(allowedSel);\n    candidates.push_back(eval_with_P(buildP_nearest(allowed1)));\n    vector<int> allowed2 = ensure_coverage(allowedAug);\n    candidates.push_back(eval_with_P(buildP_nearest(allowed2)));\n    candidates.push_back(eval_with_P(buildP_nearest(allSet)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allSet)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowed1)));\n    vector<double> betas = {0.0, 0.3, 1.0};\n    for (double beta : betas) {\n        candidates.push_back(eval_with_P(expansion_greedy(beta)));\n    }\n    long long maxd2root = 0;\n    for (int k = 0; k < K; k++) {\n        if (dist2[0][k] > maxd2root) maxd2root = dist2[0][k];\n    }\n    if (maxd2root <= LIMIT2) {\n        int r = ceil_sqrt_ll(maxd2root);\n        vector<int> P(N, 0);\n        P[0] = r;\n        candidates.push_back(eval_with_P(P));\n    }\n\n    Solution best;\n    best.cost = (long long)4e18;\n    best.covered = 0;\n    for (auto &sol : candidates) {\n        if (sol.covered == K) {\n            if (sol.cost < best.cost) best = sol;\n        } else if (best.covered < K) {\n            if (sol.covered > best.covered || (sol.covered == best.covered && sol.cost < best.cost)) {\n                best = sol;\n            }\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best.P[i] << (i + 1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (best.B[j] ? 1 : 0) << (j + 1 == M ? '\\n' : ' ');\n    }\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int TOT = N * (N + 1) / 2; // 465\n    vector<int> val(TOT);\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int v;\n            if (!(cin >> v)) return 0;\n            int id = x * (x + 1) / 2 + y;\n            val[id] = v;\n        }\n    }\n    // coordinate lookup\n    vector<int> xs(TOT), ys(TOT);\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int id = x * (x + 1) / 2 + y;\n            xs[id] = x;\n            ys[id] = y;\n        }\n    }\n    // children arrays (-1 if leaf)\n    vector<int> ch1(TOT, -1), ch2(TOT, -1);\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            int id = x * (x + 1) / 2 + y;\n            int c = (x + 1) * (x + 2) / 2 + y;\n            ch1[id] = c;\n            ch2[id] = c + 1;\n        }\n    }\n\n    const int LIMIT = 10000;\n    vector<array<int, 4>> moves;\n    moves.reserve(5000);\n\n    // bottom-up heapify (Floyd) on this binary tree\n    int last_internal = TOT - N - 1; // index of last internal node\n    for (int i = last_internal; i >= 0; i--) {\n        int cur = i;\n        while (ch1[cur] != -1) {\n            int c = ch1[cur];\n            if (val[ch2[cur]] < val[c]) c = ch2[cur];\n            if (val[cur] <= val[c]) break;\n            swap(val[cur], val[c]);\n            moves.push_back({xs[cur], ys[cur], xs[c], ys[c]});\n            cur = c;\n            if ((int)moves.size() >= LIMIT) break;\n        }\n        if ((int)moves.size() >= LIMIT) break;\n    }\n\n    // output\n    cout << moves.size() << \"\\n\";\n    for (auto &op : moves) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int label;\n    int idx;\n    int r, c;\n};\nstruct Comp {\n    bool operator()(const Node &a, const Node &b) const {\n        if (a.label != b.label) return a.label > b.label;\n        return a.idx > b.idx;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    const int er = 0, ec = (D - 1) / 2;\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; k++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    const int dr[4] = {1, -1, 0, 0};\n    const int dc[4] = {0, 0, 1, -1};\n\n    /* distance from entrance */\n    vector<vector<int>> dist0(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist0[er][ec] = 0;\n    q.push({er, ec});\n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (dist0[nr][nc] != -1) continue;\n            dist0[nr][nc] = dist0[r][c] + 1;\n            q.push({nr, nc});\n        }\n    }\n\n    /* list of usable cells sorted by distance */\n    vector<pair<int, int>> cells;\n    cells.reserve(D * D);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (obstacle[i][j]) continue;\n            if (i == er && j == ec) continue;\n            cells.push_back({i, j});\n        }\n    }\n    sort(cells.begin(), cells.end(), [&](auto a, auto b) {\n        int da = dist0[a.first][a.second];\n        int db = dist0[b.first][b.second];\n        if (da != db) return da < db;\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    int K = (int)cells.size();\n    vector<int> idx_of(D * D, -1);\n    for (int idx = 0; idx < K; idx++) {\n        idx_of[cells[idx].first * D + cells[idx].second] = idx;\n    }\n\n    vector<vector<bool>> filled(D, vector<bool>(D, false));\n    vector<vector<int>> label_grid(D, vector<int>(D, -1));\n    int empties_count = K;\n\n    auto is_safe = [&](int r, int c) -> bool {\n        filled[r][c] = true;\n        bool vis[9][9] = {};\n        queue<pair<int, int>> qq;\n        qq.push({er, ec});\n        vis[er][ec] = true;\n        int cnt = 0;\n        while (!qq.empty()) {\n            auto [cr, cc] = qq.front();\n            qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int nr = cr + dr[k], nc = cc + dc[k];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (filled[nr][nc]) continue;\n                if (vis[nr][nc]) continue;\n                vis[nr][nc] = true;\n                cnt++;\n                qq.push({nr, nc});\n            }\n        }\n        filled[r][c] = false;\n        return cnt == empties_count - 1;\n    };\n\n    /* placement phase */\n    for (int step = 0; step < K; step++) {\n        int t;\n        cin >> t;\n        int chosen = -1;\n\n        /* prefer smallest available safe idx >= t */\n        for (int idx = t; idx < K; idx++) {\n            auto [r, c] = cells[idx];\n            if (filled[r][c]) continue;\n            if (is_safe(r, c)) {\n                chosen = idx;\n                break;\n            }\n        }\n        if (chosen == -1) {\n            /* fallback: largest available safe idx < t */\n            for (int idx = t - 1; idx >= 0; idx--) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    chosen = idx;\n                    break;\n                }\n            }\n        }\n        if (chosen == -1) {\n            /* final fallback */\n            for (int idx = 0; idx < K; idx++) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    chosen = idx;\n                    break;\n                }\n            }\n        }\n        auto [pr, pc] = cells[chosen];\n        filled[pr][pc] = true;\n        label_grid[pr][pc] = t;\n        empties_count--;\n        cout << pr << \" \" << pc << '\\n';\n        cout.flush();\n    }\n\n    /* retrieval phase */\n    vector<vector<bool>> present(D, vector<bool>(D, false));\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (label_grid[i][j] != -1) present[i][j] = true;\n    }\n\n    priority_queue<Node, vector<Node>, Comp> pq;\n    auto push_if_present = [&](int r, int c) {\n        if (r < 0 || r >= D || c < 0 || c >= D) return;\n        if (obstacle[r][c]) return;\n        if (present[r][c]) {\n            int idx = idx_of[r * D + c];\n            pq.push({label_grid[r][c], idx, r, c});\n        }\n    };\n    push_if_present(er + 1, ec);\n    push_if_present(er - 1, ec);\n    push_if_present(er, ec + 1);\n    push_if_present(er, ec - 1);\n\n    int removed = 0;\n    while (removed < K) {\n        if (pq.empty()) {\n            bool done = false;\n            for (int i = 0; i < D && !done; i++) {\n                for (int j = 0; j < D && !done; j++) {\n                    if (!present[i][j]) continue;\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dr[k], nj = j + dc[k];\n                        if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                        if (obstacle[ni][nj]) continue;\n                        if (!present[ni][nj] || (ni == er && nj == ec)) {\n                            int idx = idx_of[i * D + j];\n                            pq.push({label_grid[i][j], idx, i, j});\n                            done = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        auto cur = pq.top();\n        pq.pop();\n        int r = cur.r, c = cur.c;\n        if (!present[r][c]) continue;\n        present[r][c] = false;\n        removed++;\n        cout << r << \" \" << c << '\\n';\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            push_if_present(nr, nc);\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int n, m, C;\n    vector<int> orig;              // flattened grid\n    vector<int> initSz;\n    vector<vector<int>> initAdjCnt;\n    vector<vector<char>> adjOrig;\n    vector<char> boundary;\n    const int dr[4] = {1, -1, 0, 0};\n    const int dc[4] = {0, 0, 1, -1};\n\n    Solver(int n_, int m_, const vector<int> &g) : n(n_), m(m_), orig(g) {\n        C = m + 1;\n        initSz.assign(C, 0);\n        for (int v : orig) initSz[v]++;\n        computeAdj();\n    }\n\n    void computeAdj() {\n        initAdjCnt.assign(C, vector<int>(C, 0));\n        auto addEdge = [&](int a, int b) {\n            if (a == b) return;\n            initAdjCnt[a][b]++;\n            initAdjCnt[b][a]++;\n        };\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                int a = orig[i * n + j];\n                if (i + 1 < n) addEdge(a, orig[(i + 1) * n + j]);\n                if (j + 1 < n) addEdge(a, orig[i * n + j + 1]);\n                if (i == 0) addEdge(0, a);\n                if (i == n - 1) addEdge(0, a);\n                if (j == 0) addEdge(0, a);\n                if (j == n - 1) addEdge(0, a);\n            }\n        }\n        adjOrig.assign(C, vector<char>(C, 0));\n        for (int i = 0; i < C; i++) for (int j = 0; j < C; j++) if (initAdjCnt[i][j] > 0) adjOrig[i][j] = 1;\n        boundary.assign(C, 0);\n        boundary[0] = 1;\n        for (int c = 1; c <= m; c++) if (adjOrig[0][c]) boundary[c] = 1;\n    }\n\n    // Check connectivity of color col after removing cell idx\n    bool connectedAfterRemoval(int idx, int col, const vector<int> &g, const vector<int> &sz, vector<int> &vis, int &curMark) {\n        if (sz[col] <= 1) return false;\n        int r0 = idx / n, c0 = idx % n;\n        int start = -1;\n        for (int k = 0; k < 4; k++) {\n            int nr = r0 + dr[k], nc = c0 + dc[k];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            int nb = nr * n + nc;\n            if (g[nb] == col) { start = nb; break; }\n        }\n        if (start == -1) {\n            for (int i = 0; i < n * n; i++) {\n                if (i == idx) continue;\n                if (g[i] == col) { start = i; break; }\n            }\n        }\n        if (start == -1) return false;\n        curMark++;\n        queue<int> q;\n        q.push(start);\n        vis[start] = curMark;\n        int cnt = 1;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int r = v / n, c = v % n;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n                int nb = nr * n + nc;\n                if (nb == idx) continue;\n                if (g[nb] != col) continue;\n                if (vis[nb] == curMark) continue;\n                vis[nb] = curMark;\n                q.push(nb);\n                cnt++;\n            }\n        }\n        return cnt == sz[col] - 1;\n    }\n\n    pair<int, vector<int>> runWithOrder(const vector<int> &order) {\n        vector<int> g = orig;\n        vector<int> sz = initSz;\n        vector<vector<int>> adjCnt = initAdjCnt;\n        vector<int> vis(n * n, 0);\n        int curMark = 0;\n        vector<int> remEdges(C, 0);\n\n        auto isAdjZero = [&](int idx, const vector<int> &grid) -> bool {\n            int r = idx / n, c = idx % n;\n            if (r == 0 || r == n - 1 || c == 0 || c == n - 1) return true;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                int nb = nr * n + nc;\n                if (grid[nb] == 0) return true;\n            }\n            return false;\n        };\n\n        while (true) {\n            bool removed = false;\n            for (int idx : order) {\n                int col = g[idx];\n                if (col == 0) continue;\n                if (!boundary[col]) continue;\n                if (sz[col] <= 1) continue;\n                if (!isAdjZero(idx, g)) continue;\n                int r = idx / n, c = idx % n;\n                int num0 = 0, numSame = 0;\n                vector<int> touched;\n                bool bad = false;\n                for (int k = 0; k < 4; k++) {\n                    int nr = r + dr[k], nc = c + dc[k];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) {\n                        num0++;\n                        continue;\n                    }\n                    int d = g[nr * n + nc];\n                    if (d == 0) num0++;\n                    else if (d == col) numSame++;\n                    else {\n                        if (remEdges[d] == 0) touched.push_back(d);\n                        remEdges[d]++;\n                        if (!boundary[d]) { bad = true; break; }\n                    }\n                }\n                if (bad) {\n                    for (int d : touched) remEdges[d] = 0;\n                    continue;\n                }\n                bool ok = true;\n                for (int d : touched) {\n                    if (adjOrig[col][d]) {\n                        if (adjCnt[col][d] - remEdges[d] <= 0) { ok = false; break; }\n                    }\n                }\n                if (ok) {\n                    int predicted0c = adjCnt[0][col] - num0 + numSame;\n                    if (predicted0c <= 0) ok = false;\n                }\n                if (ok) {\n                    if (numSame >= 2) {\n                        if (!connectedAfterRemoval(idx, col, g, sz, vis, curMark)) ok = false;\n                    }\n                }\n                for (int d : touched) remEdges[d] = 0;\n                if (!ok) continue;\n                // perform removal\n                for (int k = 0; k < 4; k++) {\n                    int nr = r + dr[k], nc = c + dc[k];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) {\n                        adjCnt[0][col]--; adjCnt[col][0]--;\n                    } else {\n                        int d = g[nr * n + nc];\n                        if (d == col) {\n                            adjCnt[0][col]++; adjCnt[col][0]++;\n                        } else if (d == 0) {\n                            adjCnt[0][col]--; adjCnt[col][0]--;\n                        } else {\n                            adjCnt[col][d]--; adjCnt[d][col]--;\n                            adjCnt[0][d]++; adjCnt[d][0]++;\n                        }\n                    }\n                }\n                g[idx] = 0;\n                sz[col]--;\n                removed = true;\n                break;\n            }\n            if (!removed) break;\n        }\n        int zeros = 0;\n        for (int v : g) if (v == 0) zeros++;\n        return {zeros, move(g)};\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<int> g(n * n);\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c; cin >> c;\n            g[i * n + j] = c;\n        }\n    }\n    Solver solver(n, m, g);\n\n    vector<int> base(n * n);\n    iota(base.begin(), base.end(), 0);\n    vector<vector<int>> initialOrders;\n    vector<int> ord0 = base;\n    initialOrders.push_back(ord0);\n    vector<int> ord1 = base;\n    reverse(ord1.begin(), ord1.end());\n    initialOrders.push_back(ord1);\n    vector<int> ord2 = base;\n    sort(ord2.begin(), ord2.end(), [&](int a, int b) {\n        int ra = a / n, ca = a % n;\n        int rb = b / n, cb = b % n;\n        int da = min({ra, n - 1 - ra, ca, n - 1 - ca});\n        int db = min({rb, n - 1 - rb, cb, n - 1 - cb});\n        if (da != db) return da < db;\n        return a < b;\n    });\n    initialOrders.push_back(ord2);\n    vector<int> ord3 = base;\n    sort(ord3.begin(), ord3.end(), [&](int a, int b) {\n        int ra = a / n, ca = a % n;\n        int rb = b / n, cb = b % n;\n        int da = max({ra, n - 1 - ra, ca, n - 1 - ca});\n        int db = max({rb, n - 1 - rb, cb, n - 1 - cb});\n        if (da != db) return da < db;\n        return a < b;\n    });\n    initialOrders.push_back(ord3);\n\n    int bestZeros = -1;\n    vector<int> bestGrid;\n\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9; // seconds\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n    // Evaluate initial orders\n    for (auto &ord : initialOrders) {\n        auto res = solver.runWithOrder(ord);\n        if (res.first > bestZeros) {\n            bestZeros = res.first;\n            bestGrid = move(res.second);\n        }\n    }\n\n    vector<int> order = base;\n    int iter = 0;\n    while (true) {\n        iter++;\n        shuffle(order.begin(), order.end(), rng);\n        auto res = solver.runWithOrder(order);\n        if (res.first > bestZeros) {\n            bestZeros = res.first;\n            bestGrid = move(res.second);\n        }\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TIME_LIMIT) break;\n    }\n\n    // Output best grid\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j) cout << ' ';\n            cout << bestGrid[i * n + j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if(!(cin >> N >> D >> Q)) return 0;\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<double> score(N, 0.0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n\n    int used = 0;\n    string res;\n\n    // Swiss-like tournament\n    while(used < Q){\n        shuffle(order.begin(), order.end(), rng);\n        stable_sort(order.begin(), order.end(), [&](int a, int b){\n            if (score[a] != score[b]) return score[a] > score[b];\n            return a < b;\n        });\n        for(int idx = 0; idx + 1 < N && used < Q; idx += 2){\n            int a = order[idx], b = order[idx+1];\n            cout << 1 << \" \" << 1 << \" \" << a << \" \" << b << \"\\n\";\n            cout.flush();\n            if(!(cin >> res)) return 0;\n            char c = res[0];\n            if(c == '>') score[a] += 1.0;\n            else if(c == '<') score[b] += 1.0;\n            else { score[a] += 0.5; score[b] += 0.5; }\n            used++;\n        }\n    }\n\n    // Final ranking by score\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    shuffle(idx.begin(), idx.end(), rng); // random tie-break\n    stable_sort(idx.begin(), idx.end(), [&](int a, int b){\n        if (score[a] != score[b]) return score[a] > score[b];\n        return a < b;\n    });\n    vector<int> rank(N);\n    for(int pos = 0; pos < N; pos++) rank[idx[pos]] = pos;\n\n    double lambda = 1e-5;\n    double M = 100000.0 * N / D;\n    double ex = exp(-lambda * M);\n\n    vector<double> west(N);\n    for(int i = 0; i < N; i++){\n        double p = (N - rank[i] - 0.5) / N; // quantile estimate\n        if(p <= 1e-9) p = 1e-9;\n        if(p >= 1 - 1e-9) p = 1 - 1e-9;\n        double w = -log(1.0 - p * (1.0 - ex)) / lambda;\n        if(w > M) w = M;\n        west[i] = w;\n    }\n\n    // Initial greedy assignment\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b){\n        return west[a] > west[b];\n    });\n    vector<double> sum(D, 0.0);\n    vector<int> assign(N, 0);\n    for(int id : ord){\n        int best = 0;\n        double bestsum = sum[0];\n        for(int d = 1; d < D; d++){\n            if(sum[d] < bestsum){\n                bestsum = sum[d];\n                best = d;\n            }\n        }\n        assign[id] = best;\n        sum[best] += west[id];\n    }\n\n    double total = 0.0;\n    for(double w: west) total += w;\n    double mean = total / D;\n    double curVar = 0.0;\n    for(int d = 0; d < D; d++){\n        double diff = sum[d] - mean;\n        curVar += diff * diff;\n    }\n\n    // Local search (move and swap) to minimize variance\n    int ITER = 200000;\n    for(int it = 0; it < ITER; it++){\n        if((rng() & 1) == 0){\n            // move\n            int i = rng() % N;\n            int gi = assign[i];\n            int gj = rng() % D;\n            if(gi == gj) continue;\n            double w = west[i];\n            double si = sum[gi], sj = sum[gj];\n            double nsi = si - w, nsj = sj + w;\n            double newVar = curVar\n                - (si - mean) * (si - mean) - (sj - mean) * (sj - mean)\n                + (nsi - mean) * (nsi - mean) + (nsj - mean) * (nsj - mean);\n            if(newVar < curVar){\n                curVar = newVar;\n                assign[i] = gj;\n                sum[gi] = nsi;\n                sum[gj] = nsj;\n            }\n        }else{\n            // swap\n            int i = rng() % N;\n            int j = rng() % N;\n            if(assign[i] == assign[j]) continue;\n            int gi = assign[i], gj = assign[j];\n            double wi = west[i], wj = west[j];\n            double si = sum[gi], sj = sum[gj];\n            double nsi = si - wi + wj;\n            double nsj = sj - wj + wi;\n            double newVar = curVar\n                - (si - mean) * (si - mean) - (sj - mean) * (sj - mean)\n                + (nsi - mean) * (nsi - mean) + (nsj - mean) * (nsj - mean);\n            if(newVar < curVar){\n                curVar = newVar;\n                swap(assign[i], assign[j]);\n                sum[gi] = nsi;\n                sum[gj] = nsj;\n            }\n        }\n    }\n\n    for(int i = 0; i < N; i++){\n        if(i) cout << ' ';\n        cout << assign[i];\n    }\n    cout << \"\\n\";\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF_INT = 1e9;\nconst int N_CONST = 200;\nconst int M_CONST = 10;\nconst int BUCKET_SIZE = 20; // n/m fixed\n\nstruct Param {\n    int block_threshold; // if number of boxes above >= threshold -> move as a block\n    int indiv_mode;      // 0: patience(top>=x), 1: bucket, 2: largestTop, 3: minHeight\n    int block_mode;      // 0: minHeight, 1: largestTop, 2: bucket\n    bool random_tie;\n};\n\nstruct Result {\n    int cost;\n    int op_count;\n    vector<pair<int,int>> ops;\n    bool success;\n};\n\ndouble TIME_LIMIT = 1.9; // seconds\nchrono::steady_clock::time_point g_start;\n\ndouble elapsed_sec() {\n    return chrono::duration<double>(chrono::steady_clock::now() - g_start).count();\n}\n\n// select destination stack for individual move of box x from src\nint select_dest_individual(int x, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.indiv_mode == 2) { // largestTop\n        int best = -1;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.indiv_mode == 1) { // bucket preference\n        int target = (x - 1) / BUCKET_SIZE;\n        if (target != src) {\n            if (st[target].empty() || st[target].back() >= x) {\n                return target;\n            }\n        }\n    }\n    if (p.indiv_mode == 3) { // minHeight\n        int best = -1;\n        int bestSz = INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int sz = (int)st[i].size();\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n                bestSz = sz; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // patience mode\n    int bestTop = INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top >= x) {\n            if (top < bestTop) {\n                bestTop = top;\n                cand.clear();\n                cand.push_back(i);\n            } else if (top == bestTop) {\n                cand.push_back(i);\n            }\n        }\n    }\n    if (!cand.empty()) {\n        if (p.random_tie && cand.size() > 1) {\n            uniform_int_distribution<int> dist(0, (int)cand.size()-1);\n            return cand[dist(rng)];\n        } else {\n            int best = cand[0];\n            int bestSz = (int)st[best].size();\n            for (int idx = 1; idx < (int)cand.size(); idx++) {\n                int i = cand[idx];\n                int sz = (int)st[i].size();\n                if (sz < bestSz) { bestSz = sz; best = i; }\n            }\n            return best;\n        }\n    }\n    // no top>=x, choose largest top\n    bestTop = -INF_INT;\n    cand.clear();\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) {\n            bestTop = top;\n            cand.clear();\n            cand.push_back(i);\n        } else if (top == bestTop) cand.push_back(i);\n    }\n    if (p.random_tie && cand.size() > 1) {\n        uniform_int_distribution<int> dist(0, (int)cand.size()-1);\n        return cand[dist(rng)];\n    } else {\n        int best = cand[0];\n        int bestSz = (int)st[best].size();\n        for (int idx = 1; idx < (int)cand.size(); idx++) {\n            int i = cand[idx];\n            int sz = (int)st[i].size();\n            if (sz < bestSz) { bestSz = sz; best = i; }\n        }\n        return best;\n    }\n}\n\n// select destination stack for block move (representative value rep, from src)\nint select_dest_block(int rep, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.block_mode == 2) { // bucket\n        int t = (rep - 1) / BUCKET_SIZE;\n        if (t != src) return t;\n        // else fall through to minHeight\n    }\n    if (p.block_mode == 1) { // largestTop\n        int best = -1;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // minHeight\n    int best = -1;\n    int bestSz = INF_INT;\n    int bestTop = -INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int sz = (int)st[i].size();\n        if (sz < bestSz) {\n            bestSz = sz;\n            cand.clear();\n            cand.push_back(i);\n        } else if (sz == bestSz) cand.push_back(i);\n    }\n    if (cand.size() == 1) return cand[0];\n    // tie-breaker: larger top\n    bestTop = -INF_INT;\n    best = cand[0];\n    for (int idx = 0; idx < (int)cand.size(); idx++) {\n        int i = cand[idx];\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) { bestTop = top; best = i; }\n    }\n    return best;\n}\n\nResult simulate(const vector<vector<int>>& init, const Param& p, uint64_t seed, bool record_ops, int best_cost_so_far) {\n    mt19937 rng(seed);\n    vector<vector<int>> st = init;\n    vector<int> pos(N_CONST + 1, -1);\n    int m = (int)st.size();\n    for (int i = 0; i < m; i++) {\n        for (int v : st[i]) pos[v] = i;\n    }\n    int energy = 0;\n    int op_cnt = 0;\n    vector<pair<int,int>> ops;\n    ops.reserve(3000);\n    for (int cur = 1; cur <= N_CONST; cur++) {\n        while (true) {\n            int s = pos[cur];\n            if (s < 0) return {INF_INT, op_cnt, ops, false}; // shouldn't happen\n            if (!st[s].empty() && st[s].back() == cur) {\n                st[s].pop_back();\n                pos[cur] = -1;\n                op_cnt++;\n                if (record_ops) ops.emplace_back(cur, 0);\n                break;\n            } else {\n                // compute boxes above cur\n                int d = 0;\n                for (int idx = (int)st[s].size() - 1; idx >= 0; idx--) {\n                    if (st[s][idx] == cur) break;\n                    d++;\n                }\n                bool did_block = false;\n                if (d > 0 && d >= p.block_threshold) {\n                    did_block = true;\n                    int k = d;\n                    int v = st[s][(int)st[s].size() - k]; // bottom of block (just above cur)\n                    int dest = select_dest_block(v, s, st, p, rng);\n                    // move block\n                    int start_idx = (int)st[s].size() - k;\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        int val = st[s][idx];\n                        st[dest].push_back(val);\n                        pos[val] = dest;\n                    }\n                    st[s].resize(start_idx);\n                    energy += k + 1;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(v, dest + 1);\n                }\n                if (!did_block) {\n                    int x = st[s].back();\n                    int dest = select_dest_individual(x, s, st, p, rng);\n                    st[s].pop_back();\n                    st[dest].push_back(x);\n                    pos[x] = dest;\n                    energy += 2;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(x, dest + 1);\n                }\n                if (op_cnt > 5000) return {INF_INT, op_cnt, ops, false};\n                if (!record_ops && energy >= best_cost_so_far) {\n                    return {INF_INT, op_cnt, ops, false};\n                }\n            }\n        }\n    }\n    return {energy, op_cnt, ops, true};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> init(m);\n    for (int i = 0; i < m; i++) {\n        init[i].reserve(n / m);\n        for (int j = 0; j < n / m; j++) {\n            int v; cin >> v;\n            init[i].push_back(v);\n        }\n    }\n\n    g_start = chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Param> base_params;\n    // block_threshold, indiv_mode, block_mode\n    base_params.push_back({1000, 0, 0, false}); // patience\n    base_params.push_back({1000, 1, 0, false}); // bucket\n    base_params.push_back({1000, 2, 0, false}); // largestTop\n    base_params.push_back({1000, 3, 0, false}); // minHeight\n    base_params.push_back({6, 0, 0, false});\n    base_params.push_back({4, 0, 0, false});\n    base_params.push_back({4, 1, 0, false});\n    base_params.push_back({4, 3, 0, false});\n    base_params.push_back({3, 0, 0, false});\n    base_params.push_back({2, 0, 0, false});\n    base_params.push_back({2, 1, 0, false});\n    base_params.push_back({2, 3, 0, false});\n    base_params.push_back({1, 0, 0, false});\n    base_params.push_back({1, 0, 1, false});\n    base_params.push_back({3, 0, 1, false});\n\n    int best_cost = INF_INT;\n    vector<pair<int,int>> best_ops;\n\n    for (const auto& p : base_params) {\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n        if (elapsed_sec() > TIME_LIMIT) break;\n    }\n\n    // random exploration with random tie-breaking\n    while (elapsed_sec() < TIME_LIMIT) {\n        Param p = base_params[rng() % base_params.size()];\n        p.random_tie = true;\n        // slight random tweak of threshold\n        int delta = (int)(rng() % 3) - 1; // -1,0,1\n        int th = max(1, p.block_threshold + delta);\n        if (p.block_threshold >= 1000) th = 1000;\n        p.block_threshold = th;\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    if (best_ops.empty()) {\n        // fallback trivial plan\n        Param p{1000, 3, 0, false}; // individual minHeight\n        Result r = simulate(init, p, 123456789, true, INF_INT);\n        best_ops.swap(r.ops);\n    }\n\n    for (auto &op : best_ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hwall, vwall;\nvector<int> dflat;\nint V;\nvector<vector<int>> adj;\nvector<short> distMat;\nvector<int> parMat;\n\ninline int id(int i, int j) { return i * N + j; }\n\nchar dirChar(int a, int b) {\n    int ai = a / N, aj = a % N;\n    int bi = b / N, bj = b % N;\n    if (bi == ai + 1) return 'D';\n    if (bi == ai - 1) return 'U';\n    if (bj == aj + 1) return 'R';\n    if (bj == aj - 1) return 'L';\n    return '?';\n}\n\n// BFS from source s to fill distMat and parMat rows\nvoid bfs_all_pairs() {\n    distMat.assign(V * V, 0);\n    parMat.assign(V * V, -1);\n    vector<int> dist(V);\n    queue<int> q;\n    for (int s = 0; s < V; s++) {\n        fill(dist.begin(), dist.end(), -1);\n        dist[s] = 0;\n        parMat[s * V + s] = -1;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int nb : adj[v]) {\n                if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    parMat[s * V + nb] = v;\n                    q.push(nb);\n                }\n            }\n        }\n        short *row = &distMat[s * V];\n        for (int i = 0; i < V; i++) row[i] = (short)dist[i];\n    }\n}\n\nlong long tour_length(const vector<int> &ord) {\n    long long len = 0;\n    for (int i = 0; i < V; i++) {\n        int a = ord[i];\n        int b = ord[(i + 1) % V];\n        len += (int)distMat[a * V + b];\n    }\n    return len;\n}\n\nvoid rotate_to_start(vector<int> &ord, int start = 0) {\n    int pos = -1;\n    for (int i = 0; i < V; i++) {\n        if (ord[i] == start) { pos = i; break; }\n    }\n    if (pos > 0) {\n        rotate(ord.begin(), ord.begin() + pos, ord.end());\n    }\n}\n\nvoid two_opt(vector<int> &ord, long long &curLen, double timeLimit, chrono::steady_clock::time_point startTime) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < V; i++) {\n            int a = ord[i];\n            int b = ord[(i + 1) % V];\n            for (int j = i + 2; j < V; j++) {\n                if (j == i) continue;\n                if (i == 0 && j == V - 1) continue; // adjacent edges\n                int c = ord[j];\n                int d = ord[(j + 1) % V];\n                int delta = (int)distMat[a * V + c] + (int)distMat[b * V + d] - (int)distMat[a * V + b] - (int)distMat[c * V + d];\n                if (delta < 0) {\n                    if (i + 1 <= j) {\n                        reverse(ord.begin() + i + 1, ord.begin() + j + 1);\n                    } else {\n                        // should not happen with indices chosen\n                    }\n                    curLen += delta;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n            if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > timeLimit) {\n                return;\n            }\n        }\n    }\n}\n\nvector<int> build_nn(bool randomized = false, int K = 10, mt19937 *rng = nullptr) {\n    vector<int> ord(V);\n    vector<char> used(V, 0);\n    ord[0] = 0;\n    used[0] = 1;\n    for (int idx = 1; idx < V; idx++) {\n        int cur = ord[idx - 1];\n        int best = -1;\n        int bestd = INT_MAX;\n        if (randomized && rng) {\n            // collect K nearest unused\n            vector<pair<int,int>> cand;\n            cand.reserve(K+1);\n            const short *row = &distMat[cur * V];\n            for (int v = 0; v < V; v++) if (!used[v]) {\n                int d = row[v];\n                if ((int)cand.size() < K) {\n                    cand.emplace_back(d, v);\n                    push_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                } else if (d < cand.front().first) {\n                    pop_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                    cand.back() = {d, v};\n                    push_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                }\n            }\n            if (cand.empty()) break;\n            uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n            int choice = dist(*rng);\n            best = cand[choice].second;\n        } else {\n            const short *row = &distMat[cur * V];\n            for (int v = 0; v < V; v++) if (!used[v]) {\n                int d = row[v];\n                if (d < bestd) {\n                    bestd = d;\n                    best = v;\n                }\n            }\n        }\n        if (best == -1) break;\n        ord[idx] = best;\n        used[best] = 1;\n    }\n    return ord;\n}\n\nvector<int> build_cheapest_insertion() {\n    vector<int> cycle;\n    cycle.reserve(V);\n    vector<char> used(V, 0);\n    cycle.push_back(0);\n    used[0] = 1;\n    // add nearest to 0\n    int nearest = -1;\n    int bestd = INT_MAX;\n    const short *row0 = &distMat[0];\n    for (int v = 1; v < V; v++) {\n        int d = row0[v];\n        if (d < bestd) {\n            bestd = d;\n            nearest = v;\n        }\n    }\n    if (nearest == -1) nearest = 0;\n    cycle.push_back(nearest);\n    used[nearest] = 1;\n    while ((int)cycle.size() < V) {\n        int bestNode = -1;\n        int bestPos = -1;\n        int bestInc = INT_MAX;\n        for (int v = 0; v < V; v++) if (!used[v]) {\n            int m = (int)cycle.size();\n            for (int i = 0; i < m; i++) {\n                int a = cycle[i];\n                int b = cycle[(i + 1) % m];\n                int inc = (int)distMat[a * V + v] + (int)distMat[v * V + b] - (int)distMat[a * V + b];\n                if (inc < bestInc) {\n                    bestInc = inc;\n                    bestNode = v;\n                    bestPos = i;\n                }\n            }\n        }\n        if (bestNode == -1) break;\n        cycle.insert(cycle.begin() + bestPos + 1, bestNode);\n        used[bestNode] = 1;\n    }\n    return cycle;\n}\n\nvector<int> build_mst_preorder() {\n    vector<int> parent(V, -1);\n    vector<int> key(V, INT_MAX);\n    vector<char> inMST(V, 0);\n    key[0] = 0;\n    for (int cnt = 0; cnt < V; cnt++) {\n        int u = -1;\n        int minKey = INT_MAX;\n        for (int v = 0; v < V; v++) if (!inMST[v] && key[v] < minKey) {\n            minKey = key[v];\n            u = v;\n        }\n        if (u == -1) break;\n        inMST[u] = 1;\n        const short *row = &distMat[u * V];\n        for (int v = 0; v < V; v++) if (!inMST[v]) {\n            int w = row[v];\n            if (w < key[v]) {\n                key[v] = w;\n                parent[v] = u;\n            }\n        }\n    }\n    vector<vector<int>> tree(V);\n    for (int v = 1; v < V; v++) {\n        int p = parent[v];\n        if (p >= 0) {\n            tree[p].push_back(v);\n        }\n    }\n    vector<int> order;\n    order.reserve(V);\n    function<void(int)> dfs = [&](int u) {\n        order.push_back(u);\n        for (int v : tree[u]) dfs(v);\n    };\n    dfs(0);\n    return order;\n}\n\nstring build_route(const vector<int> &ord) {\n    string moves;\n    moves.reserve(tour_length(ord));\n    for (int i = 0; i < V; i++) {\n        int s = ord[i];\n        int t = ord[(i + 1) % V];\n        if (s == t) continue;\n        vector<int> path;\n        int cur = t;\n        path.push_back(cur);\n        while (cur != s) {\n            int p = parMat[s * V + cur];\n            if (p == -1) { path.clear(); break; }\n            cur = p;\n            path.push_back(cur);\n        }\n        if (path.empty()) return \"\";\n        reverse(path.begin(), path.end());\n        for (int k = 1; k < (int)path.size(); k++) {\n            moves.push_back(dirChar(path[k - 1], path[k]));\n        }\n    }\n    return moves;\n}\n\nstring build_dfs_route() {\n    string res;\n    vector<vector<char>> vis(N, vector<char>(N, 0));\n    int di[4] = {0, 1, 0, -1};\n    int dj[4] = {1, 0, -1, 0};\n    char dc[4] = {'R', 'D', 'L', 'U'};\n    function<void(int, int)> dfs = [&](int i, int j) {\n        vis[i][j] = 1;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) wall = (vwall[i][j] == '1');\n            else if (dir == 2) wall = (vwall[i][j - 1] == '1');\n            else if (dir == 1) wall = (hwall[i][j] == '1');\n            else wall = (hwall[i - 1][j] == '1');\n            if (wall) continue;\n            if (!vis[ni][nj]) {\n                res.push_back(dc[dir]);\n                dfs(ni, nj);\n                res.push_back(dc[(dir + 2) % 4]);\n            }\n        }\n    };\n    dfs(0, 0);\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N)) return 0;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; i++) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; i++) cin >> vwall[i];\n    dflat.resize(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int x; cin >> x;\n            dflat[id(i, j)] = x;\n        }\n    }\n    V = N * N;\n    adj.assign(V, {});\n    auto add_edge = [&](int i1, int j1, int i2, int j2) {\n        int a = id(i1, j1), b = id(i2, j2);\n        adj[a].push_back(b);\n        adj[b].push_back(a);\n    };\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i + 1 < N && hwall[i][j] == '0') add_edge(i, j, i + 1, j);\n            if (j + 1 < N && vwall[i][j] == '0') add_edge(i, j, i, j + 1);\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    bfs_all_pairs();\n\n    vector<vector<int>> candidates;\n    mt19937 rng(1234567);\n\n    candidates.push_back(build_nn(false));\n    candidates.push_back(build_nn(true, 10, &rng));\n    candidates.push_back(build_cheapest_insertion());\n    candidates.push_back(build_mst_preorder());\n\n    long long bestLen = (1LL << 60);\n    vector<int> bestOrder;\n    double timeLimit = 1.8;\n\n    for (auto &ord0 : candidates) {\n        rotate_to_start(ord0, 0);\n        long long len = tour_length(ord0);\n        two_opt(ord0, len, timeLimit, startTime);\n        rotate_to_start(ord0, 0);\n        len = tour_length(ord0);\n        if (len < bestLen) {\n            bestLen = len;\n            bestOrder = ord0;\n        }\n        if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > timeLimit) break;\n    }\n\n    string route;\n    if (!bestOrder.empty()) route = build_route(bestOrder);\n    if (route.empty() || route.size() > 100000) {\n        route = build_dfs_route();\n        if (route.size() > 100000) {\n            route = route.substr(0, 100000);\n        }\n    }\n    cout << route << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n\n    // Greedy shortest common superstring\n    auto overlap = [](const string &a, const string &b) {\n        int maxk = min(a.size(), b.size());\n        for (int k = maxk; k >= 1; k--) {\n            bool ok = true;\n            for (int t = 0; t < k; t++) {\n                if (a[a.size() - k + t] != b[t]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return k;\n        }\n        return 0;\n    };\n\n    vector<string> v = words;\n    while (v.size() > 1) {\n        int n = (int)v.size();\n        int best_i = 0, best_j = 1, best_o = -1;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) if (i != j) {\n                int o = overlap(v[i], v[j]);\n                if (o > best_o) {\n                    best_o = o;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        string merged = v[best_i] + v[best_j].substr(best_o);\n        vector<string> nv;\n        nv.reserve(n - 1);\n        for (int idx = 0; idx < n; idx++) {\n            if (idx == best_i || idx == best_j) continue;\n            nv.push_back(std::move(v[idx]));\n        }\n        nv.push_back(std::move(merged));\n        v.swap(nv);\n    }\n    string S = v[0];\n    int L = (int)S.size();\n\n    // Positions of each letter\n    vector<pair<int,int>> posList[26];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            posList[grid[i][j]-'A'].push_back({i,j});\n        }\n    }\n\n    const int INF = 1e9;\n    vector<vector<int>> dp(L);\n    vector<vector<int>> pre(L);\n\n    for (int k = 0; k < L; k++) {\n        int c = S[k]-'A';\n        int m = posList[c].size();\n        dp[k].assign(m, INF);\n        pre[k].assign(m, -1);\n        if (k == 0) {\n            for (int idx = 0; idx < m; idx++) {\n                auto [i,j] = posList[c][idx];\n                dp[k][idx] = abs(i - si) + abs(j - sj) + 1;\n            }\n        } else {\n            int pc = S[k-1]-'A';\n            int pm = posList[pc].size();\n            for (int idx = 0; idx < m; idx++) {\n                auto [ci,cj] = posList[c][idx];\n                int bestCost = INF;\n                int bestPrev = -1;\n                for (int pid = 0; pid < pm; pid++) {\n                    auto [pi,pj] = posList[pc][pid];\n                    int cand = dp[k-1][pid] + abs(pi - ci) + abs(pj - cj) + 1;\n                    if (cand < bestCost) {\n                        bestCost = cand;\n                        bestPrev = pid;\n                    }\n                }\n                dp[k][idx] = bestCost;\n                pre[k][idx] = bestPrev;\n            }\n        }\n    }\n\n    int endIdx = 0;\n    int best = INF;\n    for (int idx = 0; idx < (int)dp[L-1].size(); idx++) {\n        if (dp[L-1][idx] < best) {\n            best = dp[L-1][idx];\n            endIdx = idx;\n        }\n    }\n\n    vector<pair<int,int>> path(L);\n    int idx = endIdx;\n    for (int k = L-1; k >= 0; k--) {\n        int c = S[k]-'A';\n        path[k] = posList[c][idx];\n        idx = pre[k][idx];\n    }\n\n    for (auto &p : path) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    vector<int> cells; // flattened cell ids\n};\n\nclass Solver {\npublic:\n    int N, M;\n    double eps;\n    vector<vector<pair<int,int>>> shapes;\n\n    vector<vector<Placement>> placements;              // [field] placements\n    vector<vector<vector<int>>> cellToPlacements;      // [field][cell] -> list of placement indices\n    vector<vector<char>> alive;                        // [field][placement] alive\n    vector<int> domainSize;                            // [field] number of alive placements\n    vector<vector<int>> cellCoverCount;                // [field][cell] number of alive placements covering cell\n    vector<int> totalCoverage;                         // [cell] total alive placements covering cell\n    vector<int> fieldCoverage;                         // [cell] number of fields that can cover cell (alive placements >0)\n\n    vector<int> obs;                                   // observed value per cell (-1 unknown)\n    vector<int> drilledIds, drilledVals;\n\n    chrono::steady_clock::time_point startTime;\n\n    Solver(int N_, int M_, double eps_) : N(N_), M(M_), eps(eps_) {}\n\n    int cellId(int i,int j) const { return i*N + j; }\n    pair<int,int> cellCoord(int id) const { return {id / N, id % N}; }\n\n    void readInput() {\n        shapes.resize(M);\n        for (int k=0;k<M;k++) {\n            int d; cin>>d;\n            shapes[k].resize(d);\n            for (int t=0;t<d;t++) {\n                int i,j; cin>>i>>j;\n                shapes[k][t] = {i,j};\n            }\n        }\n    }\n\n    void buildPlacements() {\n        placements.resize(M);\n        cellToPlacements.resize(M, vector<vector<int>>(N*N));\n        alive.resize(M);\n        domainSize.resize(M);\n        cellCoverCount.assign(M, vector<int>(N*N, 0));\n        totalCoverage.assign(N*N, 0);\n        fieldCoverage.assign(N*N, 0);\n\n        for (int f=0; f<M; f++) {\n            int maxI=0, maxJ=0;\n            for (auto &p: shapes[f]) { maxI = max(maxI, p.first); maxJ = max(maxJ, p.second); }\n            int h = maxI+1;\n            int w = maxJ+1;\n            for (int di=0; di<=N-h; di++) {\n                for (int dj=0; dj<=N-w; dj++) {\n                    Placement pl;\n                    pl.cells.reserve(shapes[f].size());\n                    for (auto &p: shapes[f]) {\n                        int ni = p.first + di;\n                        int nj = p.second + dj;\n                        pl.cells.push_back(cellId(ni,nj));\n                    }\n                    int idx = placements[f].size();\n                    placements[f].push_back(std::move(pl));\n                    for (int c: placements[f].back().cells) {\n                        cellToPlacements[f][c].push_back(idx);\n                    }\n                }\n            }\n            int sz = placements[f].size();\n            alive[f].assign(sz, 1);\n            domainSize[f] = sz;\n            for (int idx=0; idx<sz; idx++) {\n                for (int c: placements[f][idx].cells) {\n                    totalCoverage[c]++;\n                    cellCoverCount[f][c]++;\n                }\n            }\n        }\n        for (int c=0; c<N*N; c++) {\n            int cnt=0;\n            for (int f=0; f<M; f++) if (cellCoverCount[f][c]>0) cnt++;\n            fieldCoverage[c] = cnt;\n        }\n    }\n\n    bool removePlacement(int f,int p) {\n        if (!alive[f][p]) return false;\n        alive[f][p]=0;\n        domainSize[f]--;\n        for (int c: placements[f][p].cells) {\n            totalCoverage[c]--;\n            cellCoverCount[f][c]--;\n            if (cellCoverCount[f][c]==0) {\n                fieldCoverage[c]--;\n            }\n        }\n        return true;\n    }\n\n    bool placementCoversCell(int f,int p,int cell) {\n        for (int c: placements[f][p].cells) if (c==cell) return true;\n        return false;\n    }\n\n    bool removePlacementsCovering(int f,int cell) {\n        bool changed=false;\n        for (int p: cellToPlacements[f][cell]) {\n            if (alive[f][p]) {\n                removePlacement(f,p);\n                changed=true;\n            }\n        }\n        return changed;\n    }\n\n    bool removePlacementsNotCovering(int f,int cell) {\n        bool changed=false;\n        int sz = placements[f].size();\n        for (int p=0; p<sz; p++) if (alive[f][p]) {\n            if (!placementCoversCell(f,p,cell)) {\n                removePlacement(f,p);\n                changed=true;\n            }\n        }\n        return changed;\n    }\n\n    void propagateConstraints() {\n        bool changed;\n        do {\n            changed=false;\n            for (size_t idx=0; idx<drilledIds.size(); idx++) {\n                int cell = drilledIds[idx];\n                int val = drilledVals[idx];\n                if (val<0) continue;\n                int maxCov=0, minCov=0;\n                for (int f=0; f<M; f++) {\n                    if (domainSize[f]==0) continue;\n                    int cnt = cellCoverCount[f][cell];\n                    if (cnt>0) maxCov++;\n                    if (cnt==domainSize[f] && cnt>0) minCov++;\n                }\n                if (val==0) {\n                    for (int f=0; f<M; f++) {\n                        if (cellCoverCount[f][cell]>0) {\n                            if (removePlacementsCovering(f,cell)) changed=true;\n                        }\n                    }\n                    continue;\n                }\n                if (val==maxCov && maxCov>0) {\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0) {\n                            if (cellCoverCount[f][cell] < domainSize[f]) {\n                                if (removePlacementsNotCovering(f,cell)) changed=true;\n                            }\n                        }\n                    }\n                } else if (val==minCov) {\n                    // optional fields must not cover\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0 && cellCoverCount[f][cell]<domainSize[f]) {\n                            if (removePlacementsCovering(f,cell)) changed=true;\n                        }\n                    }\n                }\n            }\n        } while (changed);\n    }\n\n    int drillCell(int cell) {\n        auto [i,j] = cellCoord(cell);\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int resp;\n        if (!(cin >> resp)) exit(0);\n        obs[cell]=resp;\n        drilledIds.push_back(cell);\n        drilledVals.push_back(resp);\n        if (resp==0) {\n            for (int f=0; f<M; f++) {\n                if (cellCoverCount[f][cell]>0) {\n                    removePlacementsCovering(f,cell);\n                }\n            }\n        }\n        return resp;\n    }\n\n    bool allDomainsSingleton() const {\n        for (int f=0; f<M; f++) if (domainSize[f]!=1) return false;\n        return true;\n    }\n\n    vector<int> computeUnionFromDomains() const {\n        vector<char> oil(N*N,0);\n        for (int f=0; f<M; f++) {\n            int pidx=-1;\n            for (int p=0; p<(int)placements[f].size(); p++) if (alive[f][p]) { pidx=p; break; }\n            if (pidx==-1) continue;\n            for (int c: placements[f][pidx].cells) oil[c]=1;\n        }\n        vector<int> res;\n        for (int c=0; c<N*N; c++) if (oil[c]) res.push_back(c);\n        return res;\n    }\n\n    struct DFSState {\n        const vector<vector<int>> *domains;\n        const vector<vector<vector<int>>> *placementDrilled;\n        const vector<vector<char>> *fieldCanCover;\n        const vector<int> *obsVals;\n        vector<int> order;\n        vector<int> curCov;\n        vector<int> remCan;\n        vector<int> assignment;\n        int solutions=0;\n        vector<int> solAssign;\n        chrono::steady_clock::time_point deadline;\n        bool timedOut=false;\n\n        void dfs(int idx) {\n            if (timedOut) return;\n            if (chrono::steady_clock::now() > deadline) { timedOut=true; return; }\n            if (solutions>=2) return;\n            int D = obsVals->size();\n            if (idx==(int)order.size()) {\n                // all fields assigned\n                for (int d=0; d<D; d++) {\n                    if (curCov[d]!=(*obsVals)[d]) return;\n                }\n                solutions++;\n                solAssign = assignment;\n                return;\n            }\n            int f = order[idx];\n            // update remCan removing this field\n            for (int d=0; d<D; d++) {\n                if ((*fieldCanCover)[f][d]) remCan[d]--;\n            }\n            const auto &dom = (*domains)[f];\n            for (int pi=0; pi<(int)dom.size(); pi++) {\n                int pidx = dom[pi];\n                bool ok=true;\n                for (int d: (*placementDrilled)[f][pi]) {\n                    curCov[d]++;\n                    if (curCov[d] > (*obsVals)[d]) { ok=false; }\n                }\n                if (ok) {\n                    for (int d=0; d<D; d++) {\n                        if (curCov[d] + remCan[d] < (*obsVals)[d]) { ok=false; break; }\n                    }\n                }\n                if (ok) {\n                    assignment[f]=pidx;\n                    dfs(idx+1);\n                }\n                for (int d: (*placementDrilled)[f][pi]) curCov[d]--;\n                if (solutions>=2 || timedOut) break;\n            }\n            for (int d=0; d<D; d++) {\n                if ((*fieldCanCover)[f][d]) remCan[d]++;\n            }\n        }\n    };\n\n    int solveUnique(vector<int> &solution, int timeLimitMs) {\n        int D = drilledIds.size();\n        if (D==0) return 2;\n        vector<int> cellToD(N*N, -1);\n        for (int d=0; d<D; d++) cellToD[drilledIds[d]] = d;\n\n        vector<vector<int>> domains(M);\n        for (int f=0; f<M; f++) {\n            domains[f].reserve(domainSize[f]);\n            for (int p=0; p<(int)placements[f].size(); p++) if (alive[f][p]) domains[f].push_back(p);\n            if (domains[f].empty()) return 0;\n        }\n        double logProd=0;\n        for (int f=0; f<M; f++) logProd += log((double)domains[f].size());\n        if (logProd > log(1e8)) return 2; // too large\n\n        vector<vector<vector<int>>> placementDrilled(M);\n        vector<vector<char>> fieldCanCover(M, vector<char>(D, 0));\n        for (int f=0; f<M; f++) {\n            int ds = domains[f].size();\n            placementDrilled[f].resize(ds);\n            for (int idx=0; idx<ds; idx++) {\n                int pidx = domains[f][idx];\n                for (int c: placements[f][pidx].cells) {\n                    int di = cellToD[c];\n                    if (di>=0) {\n                        placementDrilled[f][idx].push_back(di);\n                        fieldCanCover[f][di]=1;\n                    }\n                }\n            }\n        }\n\n        DFSState st;\n        st.domains = &domains;\n        st.placementDrilled = &placementDrilled;\n        st.fieldCanCover = &fieldCanCover;\n        st.obsVals = &drilledVals;\n        st.order.resize(M);\n        iota(st.order.begin(), st.order.end(), 0);\n        sort(st.order.begin(), st.order.end(), [&](int a,int b){\n            return domains[a].size() < domains[b].size();\n        });\n        st.curCov.assign(D, 0);\n        st.remCan.assign(D, 0);\n        st.assignment.assign(M, -1);\n        for (int d=0; d<D; d++) {\n            int cnt=0;\n            for (int f=0; f<M; f++) if (fieldCanCover[f][d]) cnt++;\n            st.remCan[d]=cnt;\n        }\n        st.deadline = chrono::steady_clock::now() + chrono::milliseconds(timeLimitMs);\n        st.dfs(0);\n        if (st.timedOut) return 2;\n        if (st.solutions==1) {\n            solution = st.solAssign;\n            return 1;\n        }\n        if (st.solutions==0) return 0;\n        return 2;\n    }\n\n    void outputAnswer(const vector<int> &cells) {\n        cout << \"a \" << cells.size();\n        for (int id: cells) {\n            auto [i,j] = cellCoord(id);\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << \"\\n\" << flush;\n        int res;\n        if (!(cin >> res)) exit(0);\n        // Assume res == 1\n    }\n\n    void solve() {\n        startTime = chrono::steady_clock::now();\n        obs.assign(N*N, -1);\n        propagateConstraints();\n        int steps=0;\n        while (true) {\n            if (allDomainsSingleton()) {\n                vector<int> ans = computeUnionFromDomains();\n                outputAnswer(ans);\n                return;\n            }\n            // choose best cell to drill\n            int best=-1;\n            int bestOpt=-1;\n            int bestCov=-1;\n            for (int c=0; c<N*N; c++) if (obs[c]==-1) {\n                int opt=0;\n                for (int f=0; f<M; f++) {\n                    int cc = cellCoverCount[f][c];\n                    if (cc>0 && cc<domainSize[f]) opt++;\n                }\n                if (opt==0) continue;\n                int cov = totalCoverage[c];\n                if (opt>bestOpt || (opt==bestOpt && cov>bestCov)) {\n                    best=c; bestOpt=opt; bestCov=cov;\n                }\n            }\n            if (best==-1) break; // no informative cell\n            drillCell(best);\n            steps++;\n            propagateConstraints();\n            // limit total drills to 2*N*N just in case\n            if (steps >= 2*N*N) break;\n            auto elapsed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n            if (elapsed > 2500) break;\n        }\n        // Attempt unique solve with search\n        vector<int> solAssign;\n        int remainMs = 2500 - (int)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n        if (remainMs > 50) {\n            int status = solveUnique(solAssign, min(200, remainMs-20));\n            if (status==1) {\n                vector<char> oil(N*N,0);\n                for (int f=0; f<M; f++) {\n                    int pidx = solAssign[f];\n                    for (int c: placements[f][pidx].cells) oil[c]=1;\n                }\n                vector<int> ans;\n                for (int c=0; c<N*N; c++) if (oil[c]) ans.push_back(c);\n                outputAnswer(ans);\n                return;\n            }\n        }\n        // fallback: drill remaining cells\n        for (int c=0; c<N*N; c++) if (obs[c]==-1) {\n            drillCell(c);\n        }\n        vector<int> ans;\n        for (int c=0; c<N*N; c++) if (obs[c]>0) ans.push_back(c);\n        outputAnswer(ans);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M;\n    double eps;\n    if (!(cin>>N>>M>>eps)) return 0;\n    Solver solver(N,M,eps);\n    solver.readInput();\n    solver.buildPlacements();\n    solver.solve();\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct PQItem {\n    int ben;\n    int idx;\n    bool operator<(const PQItem &o) const {\n        if (ben != o.ben) return ben < o.ben; // max-heap\n        return idx > o.idx;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0; // W is always 1000\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++) cin >> a[d][k];\n    }\n\n    vector<int> prev_p; // previous boundary positions (size N-1)\n\n    for (int d = 0; d < D; d++) {\n        // sort requests descending with original indices\n        vector<pair<int, int>> reqs;\n        reqs.reserve(N);\n        for (int k = 0; k < N; k++) reqs.emplace_back(a[d][k], k);\n        sort(reqs.begin(), reqs.end(), [&](const auto &p1, const auto &p2) {\n            if (p1.first != p2.first) return p1.first > p2.first;\n            return p1.second < p2.second;\n        });\n\n        vector<int> r(N);\n        for (int i = 0; i < N; i++) r[i] = reqs[i].first;\n\n        vector<int> heights(N, 0);\n        if (N == 1) {\n            heights[0] = W;\n        } else {\n            vector<int> hmin(N);\n            int sum_min = 0;\n            for (int i = 0; i < N; i++) {\n                hmin[i] = (r[i] + W - 1) / W;\n                sum_min += hmin[i];\n            }\n\n            if (sum_min <= W) {\n                int slack = W - sum_min;\n                int m = N - 1;\n                vector<int> low(m);\n                int pref = 0;\n                for (int j = 0; j < m; j++) {\n                    pref += hmin[j];\n                    low[j] = pref; // minimal position of boundary j\n                }\n\n                vector<int> target(m, -1);\n                if (d == 0) {\n                    for (int j = 0; j < m; j++) {\n                        target[j] = (long long)(slack) * (j + 1) / N;\n                    }\n                } else {\n                    for (int j = 0; j < m; j++) {\n                        int t = prev_p[j] - low[j];\n                        if (0 <= t && t <= slack) target[j] = t;\n                        else target[j] = -1;\n                    }\n                }\n\n                // DP to find nondecreasing sequence x_j in [0, slack] maximizing matches to target\n                vector<vector<int>> dp(m, vector<int>(slack + 1, -1e9));\n                vector<vector<int>> pre(m, vector<int>(slack + 1, -1));\n                for (int v = 0; v <= slack; v++) {\n                    dp[0][v] = (target[0] != -1 && v == target[0]) ? 1 : 0;\n                }\n                for (int j = 1; j < m; j++) {\n                    int best = -1e9;\n                    int bestv = 0;\n                    for (int v = 0; v <= slack; v++) {\n                        if (dp[j - 1][v] > best) {\n                            best = dp[j - 1][v];\n                            bestv = v;\n                        }\n                        int add = (target[j] != -1 && v == target[j]) ? 1 : 0;\n                        dp[j][v] = best + add;\n                        pre[j][v] = bestv;\n                    }\n                }\n                int best = -1e9, bestv = 0;\n                for (int v = 0; v <= slack; v++) {\n                    if (dp[m - 1][v] > best) {\n                        best = dp[m - 1][v];\n                        bestv = v;\n                    }\n                }\n                vector<int> x(m);\n                int curv = bestv;\n                for (int j = m - 1; j >= 0; j--) {\n                    x[j] = curv;\n                    curv = pre[j][curv];\n                    if (curv < 0) curv = 0;\n                }\n\n                vector<int> delta(N, 0);\n                delta[0] = x[0];\n                for (int i = 1; i < m; i++) {\n                    delta[i] = x[i] - x[i - 1];\n                }\n                delta[N - 1] = slack - x[m - 1];\n                for (int i = 0; i < N; i++) {\n                    heights[i] = hmin[i] + delta[i];\n                }\n            } else {\n                // fallback: greedy allocation of extra rows to minimize deficiency for this day\n                heights.assign(N, 1);\n                vector<int> caps(N, W); // current capacity per stripe\n                int rem = W - N;\n                priority_queue<PQItem> pq;\n                for (int i = 0; i < N; i++) {\n                    int deficiency = max(0, r[i] - caps[i]);\n                    int ben = min(W, deficiency);\n                    pq.push({ben, i});\n                }\n                while (rem > 0) {\n                    auto it = pq.top();\n                    pq.pop();\n                    int i = it.idx;\n                    heights[i] += 1;\n                    caps[i] += W;\n                    rem--;\n                    int deficiency = max(0, r[i] - caps[i]);\n                    int ben = min(W, deficiency);\n                    pq.push({ben, i});\n                }\n                // ensure sum == W\n                int s = 0;\n                for (int h : heights) s += h;\n                if (s != W) heights[N - 1] += (W - s);\n            }\n        }\n\n        // build stripes coordinates and boundaries\n        vector<array<int, 4>> stripes(N);\n        vector<int> cur_p;\n        cur_p.reserve(max(0, N - 1));\n        int y = 0;\n        for (int i = 0; i < N; i++) {\n            int h = heights[i];\n            stripes[i] = {y, 0, y + h, W};\n            y += h;\n            if (i < N - 1) cur_p.push_back(y);\n        }\n        // adjust last stripe if rounding error\n        if (y != W && N > 0) {\n            stripes[N - 1][2] += (W - y);\n            if (!cur_p.empty()) cur_p.back() = W;\n        }\n\n        // map to original indices\n        vector<array<int, 4>> out(N);\n        for (int i = 0; i < N; i++) {\n            int idx = reqs[i].second;\n            out[idx] = stripes[i];\n        }\n\n        for (int k = 0; k < N; k++) {\n            auto &rct = out[k];\n            cout << rct[0] << \" \" << rct[1] << \" \" << rct[2] << \" \" << rct[3] << \"\\n\";\n        }\n\n        prev_p = cur_p; // update boundaries for next day\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353LL;\n\nstruct OpInfo {\n    int m, p, q;\n    int idx[9];\n    int inc[9];\n};\n\nuint64_t rng_state;\ninline uint64_t rng64() {\n    rng_state ^= rng_state << 7;\n    rng_state ^= rng_state >> 9;\n    return rng_state;\n}\ninline int rand_int(int n) { return int(rng64() % n); }\ninline double rand_double() {\n    return (rng64() >> 11) * (1.0 / 9007199254740992.0);\n}\n\n// Greedy addition of up to maxAdd positive operations\nvoid greedy_fill(const vector<OpInfo>& opsInfo, int totalOps, int K,\n                 vector<ll>& modv, ll& score, vector<int>& opsVec, int maxAdd) {\n    int canAdd = K - (int)opsVec.size();\n    if (maxAdd > canAdd) maxAdd = canAdd;\n    for (int step = 0; step < maxAdd; step++) {\n        ll best_delta = 0;\n        int best_id = -1;\n        for (int opId = 0; opId < totalOps; opId++) {\n            const auto& op = opsInfo[opId];\n            ll delta = 0;\n            ll nv;\n            nv = modv[op.idx[0]] + op.inc[0]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[0]];\n            nv = modv[op.idx[1]] + op.inc[1]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[1]];\n            nv = modv[op.idx[2]] + op.inc[2]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[2]];\n            nv = modv[op.idx[3]] + op.inc[3]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[3]];\n            nv = modv[op.idx[4]] + op.inc[4]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[4]];\n            nv = modv[op.idx[5]] + op.inc[5]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[5]];\n            nv = modv[op.idx[6]] + op.inc[6]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[6]];\n            nv = modv[op.idx[7]] + op.inc[7]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[7]];\n            nv = modv[op.idx[8]] + op.inc[8]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[8]];\n            if (delta > best_delta) {\n                best_delta = delta;\n                best_id = opId;\n            }\n        }\n        if (best_delta > 0 && best_id != -1) {\n            const auto& op = opsInfo[best_id];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] + op.inc[t];\n                if (nv >= MOD) nv -= MOD;\n                score += nv - modv[pos];\n                modv[pos] = nv;\n            }\n            opsVec.push_back(best_id);\n        } else {\n            break;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    rng_state = chrono::high_resolution_clock::now().time_since_epoch().count();\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<ll> base(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            ll v; cin >> v;\n            base[i * N + j] = v;\n        }\n    }\n    vector<vector<vector<int>>> s(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int v; cin >> v;\n                s[m][i][j] = v;\n            }\n        }\n    }\n\n    // Precompute all operations\n    vector<OpInfo> opsInfo;\n    opsInfo.reserve(M * (N - 2) * (N - 2));\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                OpInfo op;\n                op.m = m; op.p = p; op.q = q;\n                int t = 0;\n                for (int di = 0; di < 3; di++) {\n                    for (int dj = 0; dj < 3; dj++) {\n                        op.idx[t] = (p + di) * N + (q + dj);\n                        op.inc[t] = s[m][di][dj];\n                        t++;\n                    }\n                }\n                opsInfo.push_back(op);\n            }\n        }\n    }\n    int totalOps = (int)opsInfo.size(); // 980\n\n    vector<ll> modv(N * N);\n    ll score = 0;\n    for (int i = 0; i < N * N; i++) {\n        modv[i] = base[i] % MOD;\n        score += modv[i];\n    }\n\n    vector<int> curOps;\n    curOps.reserve(K);\n\n    // Initial greedy solution\n    greedy_fill(opsInfo, totalOps, K, modv, score, curOps, K);\n\n    vector<int> bestOps = curOps;\n    ll bestScore = score;\n\n    // Simulated Annealing\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.95;\n    const double SA_LIMIT = 1.6;\n    const double T0 = 1e8;\n    const double T1 = 1e5;\n    double temp = T0;\n    int iter = 0;\n    const int CHECK_INTERVAL = 1024;\n\n    while (true) {\n        if ((iter & (CHECK_INTERVAL - 1)) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n            if (elapsed > SA_LIMIT) break;\n            double progress = elapsed / SA_LIMIT;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        iter++;\n        int L = (int)curOps.size();\n        int moveType;\n        uint64_t rstate = rng64();\n        if (L == 0) {\n            moveType = 1; // insert\n        } else if (L == K) {\n            moveType = (rstate & 15) ? 0 : 2; // mostly replace\n        } else {\n            int v = (int)(rstate % 100);\n            if (v < 70) moveType = 0;      // replace\n            else if (v < 85) moveType = 1; // insert\n            else moveType = 2;             // delete\n        }\n\n        if (moveType == 0) {\n            // replace\n            if (L == 0) continue;\n            int idx = (int)(rstate % L);\n            int oldOpId = curOps[idx];\n            int newOpId = rand_int(totalOps);\n            if (newOpId == oldOpId) continue;\n            const auto& oldOp = opsInfo[oldOpId];\n            const auto& newOp = opsInfo[newOpId];\n            int idxs[18];\n            ll deltaAdd[18];\n            int cnt = 0;\n            auto add_d = [&](int pos, ll d) {\n                for (int t = 0; t < cnt; t++) {\n                    if (idxs[t] == pos) {\n                        deltaAdd[t] += d;\n                        return;\n                    }\n                }\n                idxs[cnt] = pos;\n                deltaAdd[cnt] = d;\n                cnt++;\n            };\n            for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n            for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n            ll deltaScore = 0;\n            ll newMods[18];\n            for (int t = 0; t < cnt; t++) {\n                int pos = idxs[t];\n                ll nm = modv[pos] + deltaAdd[t];\n                if (nm >= MOD) nm -= MOD;\n                else if (nm < 0) nm += MOD;\n                deltaScore += nm - modv[pos];\n                newMods[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < cnt; t++) modv[idxs[t]] = newMods[t];\n                curOps[idx] = newOpId;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else if (moveType == 1) {\n            // insert\n            if (L >= K) continue;\n            int newOpId = (int)(rstate % totalOps);\n            const auto& op = opsInfo[newOpId];\n            ll deltaScore = 0;\n            ll newMods[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nm = modv[pos] + op.inc[t];\n                if (nm >= MOD) nm -= MOD;\n                deltaScore += nm - modv[pos];\n                newMods[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newMods[t];\n                curOps.push_back(newOpId);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else {\n            // delete\n            if (L == 0) continue;\n            int idx = (int)(rstate % L);\n            int oldOpId = curOps[idx];\n            const auto& op = opsInfo[oldOpId];\n            ll deltaScore = 0;\n            ll newMods[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nm = modv[pos] - op.inc[t];\n                if (nm < 0) nm += MOD;\n                deltaScore += nm - modv[pos];\n                newMods[t] = nm;\n            }\n            bool accept = false;\n            if (deltaScore >= 0) accept = true;\n            else {\n                double prob = exp((double)deltaScore / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += deltaScore;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newMods[t];\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        }\n    }\n\n    // Reconstruct best solution and apply greedy fill\n    vector<ll> modv_best(N * N);\n    ll score_best = 0;\n    for (int i = 0; i < N * N; i++) {\n        modv_best[i] = base[i] % MOD;\n        score_best += modv_best[i];\n    }\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        for (int t = 0; t < 9; t++) {\n            int pos = op.idx[t];\n            ll nv = modv_best[pos] + op.inc[t];\n            if (nv >= MOD) nv -= MOD;\n            score_best += nv - modv_best[pos];\n            modv_best[pos] = nv;\n        }\n    }\n    greedy_fill(opsInfo, totalOps, K, modv_best, score_best, bestOps, K - (int)bestOps.size());\n\n    // Hill climbing replacements\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > TIME_LIMIT) break;\n        ll bestDelta = 0;\n        int bestIdx = -1;\n        int bestNewOp = -1;\n        int bestCnt = 0;\n        int bestPos[18];\n        ll bestAdd[18];\n        int L = (int)bestOps.size();\n        for (int idx = 0; idx < L; idx++) {\n            int oldOpId = bestOps[idx];\n            const auto& oldOp = opsInfo[oldOpId];\n            for (int newOpId = 0; newOpId < totalOps; newOpId++) {\n                if (newOpId == oldOpId) continue;\n                const auto& newOp = opsInfo[newOpId];\n                int idxs[18];\n                ll deltaAdd[18];\n                int cnt = 0;\n                auto add_d = [&](int pos, ll d) {\n                    for (int t = 0; t < cnt; t++) {\n                        if (idxs[t] == pos) {\n                            deltaAdd[t] += d;\n                            return;\n                        }\n                    }\n                    idxs[cnt] = pos;\n                    deltaAdd[cnt] = d;\n                    cnt++;\n                };\n                for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n                for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n                ll deltaScore = 0;\n                for (int t = 0; t < cnt; t++) {\n                    int pos = idxs[t];\n                    ll nm = modv_best[pos] + deltaAdd[t];\n                    if (nm >= MOD) nm -= MOD;\n                    else if (nm < 0) nm += MOD;\n                    deltaScore += nm - modv_best[pos];\n                }\n                if (deltaScore > bestDelta) {\n                    bestDelta = deltaScore;\n                    bestIdx = idx;\n                    bestNewOp = newOpId;\n                    bestCnt = cnt;\n                    for (int t = 0; t < cnt; t++) {\n                        bestPos[t] = idxs[t];\n                        bestAdd[t] = deltaAdd[t];\n                    }\n                }\n            }\n        }\n        if (bestDelta > 0 && bestIdx != -1) {\n            score_best += bestDelta;\n            for (int t = 0; t < bestCnt; t++) {\n                int pos = bestPos[t];\n                ll nm = modv_best[pos] + bestAdd[t];\n                if (nm >= MOD) nm -= MOD;\n                else if (nm < 0) nm += MOD;\n                modv_best[pos] = nm;\n            }\n            bestOps[bestIdx] = bestNewOp;\n            // if size < K, try fill new positives\n            if ((int)bestOps.size() < K) {\n                greedy_fill(opsInfo, totalOps, K, modv_best, score_best, bestOps, K - (int)bestOps.size());\n            }\n        } else {\n            break;\n        }\n    }\n\n    // Output\n    cout << bestOps.size() << \"\\n\";\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;\n    int hold;   // -1 if not holding\n    bool alive;\n};\n\nstruct Task { int src, cid; };\n\nstruct Candidate {\n    vector<string> ops;\n    long long M0, M1, M2, M3;\n    long long score() const {\n        return M0 + 100LL * M1 + 10000LL * M2 + 1000000LL * M3;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n\n    const int base = N + 1; // 6\n    const int POS = N + 1;  // 6\n    int totalStates = 1;\n    for (int i = 0; i < N; i++) totalStates *= base; // 7776\n\n    // powers for incrementing pointers\n    vector<int> powBase(N);\n    powBase[N - 1] = 1;\n    for (int k = N - 2; k >= 0; k--) powBase[k] = powBase[k + 1] * base;\n\n    // decode all states and group by sum\n    vector<array<int,5>> pvec(totalStates);\n    vector<int> sumPtr(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        int tmp = code;\n        int sum = 0;\n        array<int,5> p{};\n        for (int i = N - 1; i >= 0; i--) {\n            p[i] = tmp % base;\n            tmp /= base;\n            sum += p[i];\n        }\n        pvec[code] = p;\n        sumPtr[code] = sum;\n    }\n    vector<vector<int>> codesBySum(N * N + 1);\n    for (int code = 0; code < totalStates; code++) {\n        codesBySum[sumPtr[code]].push_back(code);\n    }\n\n    // dest rows precompute and invAdd table\n    vector<vector<int>> destRow(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) destRow[i][j] = A[i][j] / N;\n\n    vector<array<int,5>> invAddTable(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        const auto &p = pvec[code];\n        for (int s = 0; s < N; s++) {\n            if (p[s] >= N) {\n                invAddTable[code][s] = 0;\n                continue;\n            }\n            int cid = A[s][p[s]];\n            int dr = cid / N;\n            int cnt = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < p[i]; j++) {\n                    int cid2 = A[i][j];\n                    if (cid2 / N == dr && cid2 > cid) cnt++;\n                }\n            }\n            invAddTable[code][s] = cnt;\n        }\n    }\n\n    auto plan_dp = [&](int weight) -> Candidate {\n        const long long INF = (1LL << 60);\n        int stateSize = totalStates * POS;\n        vector<long long> dp(stateSize, INF);\n        vector<int> parent(stateSize, -1);\n        vector<int> parentSrc(stateSize, -1);\n\n        int startIdx = 0 * POS + (POS - 1); // code=0, pos=start\n        dp[startIdx] = 0;\n\n        for (int total = 0; total <= N * N; total++) {\n            for (int code : codesBySum[total]) {\n                const auto &p = pvec[code];\n                for (int pos = 0; pos < POS; pos++) {\n                    int idx = code * POS + pos;\n                    long long curCost = dp[idx];\n                    if (curCost == INF) continue;\n                    for (int s = 0; s < N; s++) {\n                        if (p[s] >= N) continue;\n                        int dr = destRow[s][p[s]];\n                        int dist1 = (pos == POS - 1) ? abs(0 - s) : 4 + abs(pos - s);\n                        int dist2 = 4 + abs(s - dr);\n                        int moveCost = dist1 + dist2 + 2; // pick+drop\n                        int invAdd = invAddTable[code][s];\n                        long long newCost = curCost + moveCost + 1LL * weight * invAdd;\n                        int nextCode = code + powBase[s];\n                        int nextPos = dr;\n                        int nextIdx = nextCode * POS + nextPos;\n                        if (newCost < dp[nextIdx]) {\n                            dp[nextIdx] = newCost;\n                            parent[nextIdx] = idx;\n                            parentSrc[nextIdx] = s;\n                        }\n                    }\n                }\n            }\n        }\n\n        int fullCode = 0;\n        for (int i = 0; i < N; i++) fullCode = fullCode * base + N;\n        int bestIdx = fullCode * POS;\n        long long bestCost = dp[bestIdx];\n        for (int pos = 1; pos < POS; pos++) {\n            int idx = fullCode * POS + pos;\n            if (dp[idx] < bestCost) {\n                bestCost = dp[idx];\n                bestIdx = idx;\n            }\n        }\n\n        vector<int> seqSources;\n        int curIdx = bestIdx;\n        while (curIdx != startIdx) {\n            int s = parentSrc[curIdx];\n            seqSources.push_back(s);\n            curIdx = parent[curIdx];\n        }\n        reverse(seqSources.begin(), seqSources.end());\n\n        vector<int> ptr(N, 0);\n        vector<Task> tasks;\n        tasks.reserve(N * N);\n        for (int s : seqSources) {\n            tasks.push_back({s, A[s][ptr[s]]});\n            ptr[s]++;\n        }\n\n        // simulation\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        int dispatched = 0;\n        int task_idx = 0;\n        int turn = 0;\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        const int TURN_LIMIT = 10000;\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn step\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) {\n                        blocked = true;\n                        break;\n                    }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            // large crane action\n            Crane &lc = cranes[0];\n            char a0 = '.';\n            if (lc.hold == -1) {\n                if (task_idx < (int)tasks.size()) {\n                    int sr = tasks[task_idx].src;\n                    if (lc.r < sr) a0 = 'D';\n                    else if (lc.r > sr) a0 = 'U';\n                    else if (lc.c > 0) a0 = 'L';\n                    else {\n                        if (grid[lc.r][lc.c] != -1) a0 = 'P';\n                        else a0 = '.';\n                    }\n                } else {\n                    a0 = '.';\n                }\n            } else {\n                int destR = lc.hold / N;\n                if (lc.c < N - 1) a0 = 'R';\n                else if (lc.r < destR) a0 = 'D';\n                else if (lc.r > destR) a0 = 'U';\n                else {\n                    if (grid[lc.r][lc.c] == -1) a0 = 'Q';\n                    else a0 = '.';\n                }\n            }\n            act[0] = a0;\n\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            // new positions for moves\n            vector<pair<int,int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            // execute\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') {\n                    cranes[i].alive = false;\n                    continue;\n                }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) {\n                        cranes[i].hold = grid[r][c];\n                        grid[r][c] = -1;\n                    }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                        if (i == 0) task_idx++;\n                    }\n                }\n            }\n\n            // dispatch\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn;\n        long long M1 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                for (int k = j + 1; k < len; k++) {\n                    if (seq[j] > seq[k]) M1++;\n                }\n            }\n        }\n        long long M3 = N * N - dispatched;\n        long long M2 = 0;\n        // count wrong gates (should be none)\n        for (int i = 0; i < N; i++) {\n            for (int id : dispatchedList[i]) {\n                int dr = id / N;\n                if (dr != i) M2++;\n            }\n        }\n        return Candidate{ops, M0, M1, M2, M3};\n    };\n\n    auto plan_buffer = [&]() -> Candidate {\n        // mapping id -> source row, index\n        vector<int> id2row(N * N), id2idx(N * N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int id = A[i][j];\n                id2row[id] = i;\n                id2idx[id] = j;\n            }\n        }\n\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        vector<bool> dispatchedId(N * N, false);\n        vector<int> nextNeeded(N);\n        for (int i = 0; i < N; i++) nextNeeded[i] = i * N;\n\n        int dispatched = 0;\n        int turn = 0;\n        const int TURN_LIMIT = 10000;\n\n        auto bufferCell = [&](const vector<vector<int>> &grid, const vector<int> &idxSpawn, const Crane &lc) -> pair<int,int> {\n            for (int r = 0; r < N; r++) {\n                for (int c = 1; c <= 3; c++) {\n                    if (grid[r][c] == -1 || (r == lc.r && c == lc.c && grid[r][c] == -1)) {\n                        return {r, c};\n                    }\n                }\n            }\n            for (int r = 0; r < N; r++) {\n                if (idxSpawn[r] == N && grid[r][0] == -1 && !(lc.r == r && lc.c == 0))\n                    return {r, 0};\n            }\n            return {-1, -1};\n        };\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn step\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) {\n                        blocked = true;\n                        break;\n                    }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            // decide action for large crane\n            Crane &lc = cranes[0];\n\n            auto manhattan = [&](int r1, int c1, int r2, int c2) {\n                return abs(r1 - r2) + abs(c1 - c2);\n            };\n\n            // find ready containers\n            vector<pair<int,int>> readyPos;\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int id = grid[r][c];\n                    if (id == -1) continue;\n                    int dr = id / N;\n                    if (nextNeeded[dr] < (dr + 1) * N && id == nextNeeded[dr]) {\n                        readyPos.emplace_back(r, c);\n                    }\n                }\n            }\n\n            char a0 = '.';\n            if (lc.hold != -1) {\n                int cid = lc.hold;\n                int dr = cid / N;\n                bool ready = (nextNeeded[dr] < (dr + 1) * N && cid == nextNeeded[dr]);\n                if (ready) {\n                    int tr = dr, tc = N - 1;\n                    if (lc.r == tr && lc.c == tc) {\n                        if (grid[tr][tc] == -1) a0 = 'Q';\n                        else a0 = '.';\n                    } else {\n                        if (lc.r < tr) a0 = 'D';\n                        else if (lc.r > tr) a0 = 'U';\n                        else if (lc.c < tc) a0 = 'R';\n                        else if (lc.c > tc) a0 = 'L';\n                    }\n                } else {\n                    auto buf = bufferCell(grid, idxSpawn, lc);\n                    if (buf.first == -1) {\n                        // no buffer, fallback dispatch\n                        int tr = dr, tc = N - 1;\n                        if (lc.r == tr && lc.c == tc) {\n                            if (grid[tr][tc] == -1) a0 = 'Q';\n                            else a0 = '.';\n                        } else {\n                            if (lc.r < tr) a0 = 'D';\n                            else if (lc.r > tr) a0 = 'U';\n                            else if (lc.c < tc) a0 = 'R';\n                            else if (lc.c > tc) a0 = 'L';\n                        }\n                    } else {\n                        int tr = buf.first, tc = buf.second;\n                        if (lc.r == tr && lc.c == tc) {\n                            if (grid[tr][tc] == -1) a0 = 'Q';\n                            else a0 = '.';\n                        } else {\n                            if (lc.r < tr) a0 = 'D';\n                            else if (lc.r > tr) a0 = 'U';\n                            else if (lc.c < tc) a0 = 'R';\n                            else if (lc.c > tc) a0 = 'L';\n                        }\n                    }\n                }\n            } else {\n                if (!readyPos.empty()) {\n                    // pick nearest ready\n                    int bestd = 1e9, br = -1, bc = -1;\n                    for (auto [r, c] : readyPos) {\n                        int d = manhattan(lc.r, lc.c, r, c);\n                        if (d < bestd) {\n                            bestd = d;\n                            br = r;\n                            bc = c;\n                        }\n                    }\n                    if (lc.r == br && lc.c == bc) {\n                        a0 = 'P';\n                    } else {\n                        if (lc.r < br) a0 = 'D';\n                        else if (lc.r > br) a0 = 'U';\n                        else if (lc.c < bc) a0 = 'R';\n                        else if (lc.c > bc) a0 = 'L';\n                    }\n                } else {\n                    // choose smallest nextNeeded id remaining\n                    int targetId = 1e9, targetRow = -1;\n                    for (int dr = 0; dr < N; dr++) {\n                        if (nextNeeded[dr] < (dr + 1) * N) {\n                            if (nextNeeded[dr] < targetId) {\n                                targetId = nextNeeded[dr];\n                                targetRow = dr;\n                            }\n                        }\n                    }\n                    if (targetRow == -1) {\n                        a0 = '.';\n                    } else {\n                        int srcRow = id2row[targetId];\n                        if (lc.r != srcRow || lc.c != 0) {\n                            int tr = srcRow, tc = 0;\n                            if (lc.r < tr) a0 = 'D';\n                            else if (lc.r > tr) a0 = 'U';\n                            else if (lc.c < tc) a0 = 'R';\n                            else if (lc.c > tc) a0 = 'L';\n                        } else {\n                            if (grid[srcRow][0] == -1) {\n                                a0 = '.';\n                            } else {\n                                a0 = 'P';\n                            }\n                        }\n                    }\n                }\n            }\n\n            act[0] = a0;\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            // compute new positions for moves\n            vector<pair<int,int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            // execute actions\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') {\n                    cranes[i].alive = false;\n                    continue;\n                }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) {\n                        cranes[i].hold = grid[r][c];\n                        grid[r][c] = -1;\n                    }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                    }\n                }\n            }\n\n            // dispatch step\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedId[id] = true;\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                    // update nextNeeded for this row\n                    while (nextNeeded[i] < (i + 1) * N && dispatchedId[nextNeeded[i]]) {\n                        nextNeeded[i]++;\n                    }\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn;\n        long long M3 = N * N - dispatched;\n        long long M2 = 0;\n        long long M1 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            // wrong gate\n            for (int id : seq) {\n                int dr = id / N;\n                if (dr != i) M2++;\n            }\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                for (int k = j + 1; k < len; k++) {\n                    if (seq[j] > seq[k]) M1++;\n                }\n            }\n        }\n        return Candidate{ops, M0, M1, M2, M3};\n    };\n\n    // run multiple candidates\n    vector<int> weights = {50, 80, 110, 150, 200};\n    Candidate best;\n    best.M0 = best.M1 = best.M2 = best.M3 = (1LL << 60);\n    bool bestInit = false;\n    for (int w : weights) {\n        Candidate cand = plan_dp(w);\n        if (!bestInit || cand.score() < best.score()) {\n            best = cand;\n            bestInit = true;\n        }\n    }\n    Candidate candBuf = plan_buffer();\n    if (!bestInit || candBuf.score() < best.score()) {\n        best = candBuf;\n        bestInit = true;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best.ops[i] << \"\\n\";\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing pii = pair<int,int>;\n\nstruct Plan {\n    vector<string> ops;\n    ll cost;\n    bool valid;\n};\n\n// ----- Path generators -----\nvector<pii> build_path_down_serp_rows(int N){\n    vector<pii> p;\n    for(int r=1;r<N;r++) p.push_back({r,0});\n    for(int r=N-1;r>=0;r--){\n        if(r%2==1){\n            for(int c=1;c<N;c++) p.push_back({r,c});\n        }else{\n            for(int c=N-1;c>=1;c--) p.push_back({r,c});\n        }\n    }\n    return p;\n}\n\nvector<pii> build_path_right_serp_cols(int N){\n    vector<pii> p;\n    for(int c=1;c<N;c++) p.push_back({0,c});\n    for(int c=N-1;c>=0;c--){\n        int parity = (N-1 - c);\n        if(parity%2==0){\n            for(int r=1;r<N;r++) p.push_back({r,c});\n        }else{\n            for(int r=N-1;r>=1;r--) p.push_back({r,c});\n        }\n    }\n    return p;\n}\n\nvector<pii> build_row_snake(int N){\n    vector<pii> p;\n    for(int r=0;r<N;r++){\n        if(r%2==0){\n            for(int c=0;c<N;c++){\n                if(r==0 && c==0) continue;\n                p.push_back({r,c});\n            }\n        }else{\n            for(int c=N-1;c>=0;c--){\n                p.push_back({r,c});\n            }\n        }\n    }\n    return p;\n}\n\nvector<pii> build_col_snake(int N){\n    vector<pii> p;\n    for(int c=0;c<N;c++){\n        if(c%2==0){\n            for(int r=0;r<N;r++){\n                if(r==0 && c==0) continue;\n                p.push_back({r,c});\n            }\n        }else{\n            for(int r=N-1;r>=0;r--){\n                p.push_back({r,c});\n            }\n        }\n    }\n    return p;\n}\n\nvector<pii> build_spiral(int N){\n    vector<pii> order;\n    int top=0,bottom=N-1,left=0,right=N-1;\n    while(top<=bottom && left<=right){\n        for(int c=left;c<=right;c++) order.push_back({top,c});\n        top++;\n        for(int r=top;r<=bottom;r++) order.push_back({r,right});\n        right--;\n        if(top<=bottom){\n            for(int c=right;c>=left;c--) order.push_back({bottom,c});\n            bottom--;\n        }\n        if(left<=right){\n            for(int r=bottom;r>=top;r--) order.push_back({r,left});\n            left++;\n        }\n    }\n    vector<pii> p;\n    p.reserve(order.size()-1);\n    for(auto &co: order){\n        if(co.first==0 && co.second==0) continue;\n        p.push_back(co);\n    }\n    return p;\n}\n\nvector<pii> reverse_if_adjacent(const vector<pii>& path){\n    vector<pii> rev;\n    if(path.empty()) return rev;\n    auto last = path.back();\n    if(abs(last.first) + abs(last.second) != 1) return rev;\n    rev.reserve(path.size());\n    for(int i=(int)path.size()-1;i>=0;i--){\n        rev.push_back(path[i]);\n    }\n    return rev;\n}\n\n// Simulate cost for path (excluding start)\nll simulate_cost(const vector<pii>& path, const vector<vector<int>>& h, ll& outBorrow){\n    ll pref=0, minPref=0;\n    for(auto [r,c]: path){\n        pref += h[r][c];\n        if(pref < minPref) minPref = pref;\n    }\n    ll borrow = -minPref;\n    outBorrow = borrow;\n    ll cost=0;\n    ll load = borrow;\n    if(borrow>0) cost += borrow;\n    int cr=0, cc=0;\n    for(auto [r,c]: path){\n        int dist = abs(r-cr) + abs(c-cc);\n        cost += (100 + load) * 1LL * dist;\n        int val = h[r][c];\n        cost += llabs((ll)val);\n        load += val;\n        cr = r; cc = c;\n    }\n    int distback = abs(cr) + abs(cc);\n    cost += (100 + load) * 1LL * distback;\n    cost += llabs(load); // final adjust at start\n    return cost;\n}\n\n// Build plan for a given path\nPlan build_path_plan(const vector<pii>& path, const vector<vector<int>>& h){\n    Plan res;\n    res.cost = 0;\n    res.valid = true;\n    vector<vector<int>> g = h;\n    ll pref=0, minPref=0;\n    for(auto [r,c]: path){\n        pref += h[r][c];\n        minPref = min(minPref, pref);\n    }\n    ll borrow = -minPref;\n    ll load = 0;\n    vector<string> ops;\n    if(borrow > 0){\n        ops.push_back(\"+\" + to_string(borrow));\n        res.cost += borrow;\n        load += borrow;\n        g[0][0] -= (int)borrow;\n    }\n\n    int cr=0, cc=0;\n    for(auto [r,c]: path){\n        int dr = r - cr;\n        int dc = c - cc;\n        while(dr > 0){ ops.push_back(\"D\"); res.cost += 100 + load; cr++; dr--; }\n        while(dr < 0){ ops.push_back(\"U\"); res.cost += 100 + load; cr--; dr++; }\n        while(dc > 0){ ops.push_back(\"R\"); res.cost += 100 + load; cc++; dc--; }\n        while(dc < 0){ ops.push_back(\"L\"); res.cost += 100 + load; cc--; dc++; }\n        int val = g[cr][cc];\n        if(val > 0){\n            ops.push_back(\"+\" + to_string(val));\n            res.cost += val;\n            load += val;\n            g[cr][cc] = 0;\n        }else if(val < 0){\n            int d = -val;\n            ops.push_back(\"-\" + to_string(d));\n            res.cost += d;\n            load -= d;\n            g[cr][cc] = 0;\n        }\n    }\n\n    // Return to origin\n    while(cr > 0){ ops.push_back(\"U\"); res.cost += 100 + load; cr--; }\n    while(cc > 0){ ops.push_back(\"L\"); res.cost += 100 + load; cc--; }\n\n    // Final adjust start\n    int sval = g[0][0];\n    if(sval > 0){\n        ops.push_back(\"+\" + to_string(sval));\n        res.cost += sval;\n        load += sval;\n        g[0][0] = 0;\n    }else if(sval < 0){\n        int d = -sval;\n        ops.push_back(\"-\" + to_string(d));\n        res.cost += d;\n        load -= d;\n        g[0][0] = 0;\n    }\n\n    if((int)ops.size() > 100000) res.valid = false;\n    res.ops.swap(ops);\n    return res;\n}\n\n// Greedy transport plan\nPlan build_greedy_plan(const vector<vector<int>>& h){\n    int N = h.size();\n    vector<vector<int>> a = h;\n    ll total_nonzero = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) total_nonzero += llabs((ll)a[i][j]);\n\n    Plan res;\n    res.cost = 0;\n    res.valid = true;\n    vector<string> ops;\n    ll load = 0;\n    int r=0, c=0;\n\n    auto move_steps = [&](int nr, int nc){\n        int dr = nr - r;\n        int dc = nc - c;\n        while(dr > 0){ ops.push_back(\"D\"); res.cost += 100 + load; r++; dr--; }\n        while(dr < 0){ ops.push_back(\"U\"); res.cost += 100 + load; r--; dr++; }\n        while(dc > 0){ ops.push_back(\"R\"); res.cost += 100 + load; c++; dc--; }\n        while(dc < 0){ ops.push_back(\"L\"); res.cost += 100 + load; c--; dc++; }\n    };\n\n    int iter=0;\n    while(total_nonzero > 0 && (int)ops.size() < 100000){\n        iter++;\n        if(load == 0){\n            int bestR=-1,bestC=-1,bestD=1e9, bestVal=0;\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    int val = a[i][j];\n                    if(val > 0){\n                        int d = abs(i-r) + abs(j-c);\n                        if(d < bestD || (d == bestD && val > bestVal)){\n                            bestD = d; bestR = i; bestC = j; bestVal = val;\n                        }\n                    }\n                }\n            }\n            if(bestR==-1){\n                // no positive, should not happen\n                res.valid = false;\n                break;\n            }\n            move_steps(bestR, bestC);\n            int val = a[r][c];\n            ops.push_back(\"+\" + to_string(val));\n            res.cost += val;\n            load += val;\n            total_nonzero -= val;\n            a[r][c] = 0;\n        }else{\n            int bestR=-1,bestC=-1,bestD=1e9, bestNeed=0;\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    int val = a[i][j];\n                    if(val < 0){\n                        int d = abs(i-r) + abs(j-c);\n                        int need = -val;\n                        if(d < bestD || (d == bestD && need > bestNeed)){\n                            bestD = d; bestR = i; bestC = j; bestNeed = need;\n                        }\n                    }\n                }\n            }\n            if(bestR==-1){\n                // no negative, should not happen if load>0\n                res.valid = false;\n                break;\n            }\n            move_steps(bestR, bestC);\n            int need = -a[r][c];\n            int t = (int)min<ll>(load, need);\n            ops.push_back(\"-\" + to_string(t));\n            res.cost += t;\n            load -= t;\n            a[r][c] += t;\n            total_nonzero -= t;\n        }\n    }\n\n    if(total_nonzero != 0 || (int)ops.size()>100000) res.valid = false;\n    res.ops.swap(ops);\n    return res;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cin>>h[i][j];\n        }\n    }\n\n    vector<vector<pii>> candidates;\n    auto pA = build_path_down_serp_rows(N);\n    auto pB = build_path_right_serp_cols(N);\n    auto pRow = build_row_snake(N);\n    auto pCol = build_col_snake(N);\n    auto pSp = build_spiral(N);\n    candidates.push_back(pA);\n    candidates.push_back(pB);\n    candidates.push_back(pRow);\n    candidates.push_back(pCol);\n    candidates.push_back(pSp);\n    auto revA = reverse_if_adjacent(pA);\n    if(!revA.empty()) candidates.push_back(revA);\n    auto revB = reverse_if_adjacent(pB);\n    if(!revB.empty()) candidates.push_back(revB);\n    auto revSp = reverse_if_adjacent(pSp);\n    if(!revSp.empty()) candidates.push_back(revSp);\n\n    ll bestSimCost = (1LL<<60);\n    vector<pii> bestPath = candidates[0];\n    for(auto &p: candidates){\n        if((int)p.size() != N*N-1) continue;\n        ll bor;\n        ll cst = simulate_cost(p, h, bor);\n        if(cst < bestSimCost){\n            bestSimCost = cst;\n            bestPath = p;\n        }\n    }\n\n    Plan scanPlan = build_path_plan(bestPath, h);\n    Plan greedyPlan = build_greedy_plan(h);\n\n    Plan *bestPlan = nullptr;\n    if(greedyPlan.valid && (!scanPlan.valid || greedyPlan.cost < scanPlan.cost)){\n        bestPlan = &greedyPlan;\n    }else{\n        bestPlan = &scanPlan;\n    }\n\n    for(auto &s: bestPlan->ops){\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int SEED_COUNT = 2 * N * (N - 1); // 60 for N=6\n    vector<array<int, 15>> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; i++) {\n        for (int j = 0; j < M; j++) cin >> seeds[i][j];\n    }\n\n    int SZ = N * N;\n    // neighbor positions and edges (for possible future use)\n    vector<vector<int>> neighPos(SZ);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int p = i * N + j;\n            if (i > 0) neighPos[p].push_back((i - 1) * N + j);\n            if (i + 1 < N) neighPos[p].push_back((i + 1) * N + j);\n            if (j > 0) neighPos[p].push_back(i * N + (j - 1));\n            if (j + 1 < N) neighPos[p].push_back(i * N + (j + 1));\n        }\n    }\n\n    int center_i = N / 2 - 1, center_j = N / 2 - 1;\n    int centerPos = center_i * N + center_j;\n    double cx = (N - 1) / 2.0, cy = (N - 1) / 2.0;\n    vector<double> posDist(SZ);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int p = i * N + j;\n        posDist[p] = fabs(i - cx) + fabs(j - cy);\n    }\n\n    // global max per attribute from initial seeds (won't increase)\n    array<int, 15> globalMax{};\n    for (int l = 0; l < M; l++) {\n        int mx = 0;\n        for (int k = 0; k < SEED_COUNT; k++) mx = max(mx, seeds[k][l]);\n        globalMax[l] = mx;\n    }\n\n    std::mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    vector<vector<int>> synergy(SEED_COUNT, vector<int>(SEED_COUNT, 0));\n\n    for (int turn = 0; turn < T; turn++) {\n        // compute value and cntMax\n        vector<int> val(SEED_COUNT, 0), cntMax(SEED_COUNT, 0);\n        for (int k = 0; k < SEED_COUNT; k++) {\n            int s = 0, c = 0;\n            for (int l = 0; l < M; l++) {\n                s += seeds[k][l];\n                if (seeds[k][l] == globalMax[l]) c++;\n            }\n            val[k] = s;\n            cntMax[k] = c;\n        }\n        // best seed\n        int best_id = 0;\n        for (int i = 1; i < SEED_COUNT; i++) if (val[i] > val[best_id]) best_id = i;\n\n        // champions per attribute\n        vector<int> championList;\n        vector<int> champId(M);\n        vector<char> seenChamp(SEED_COUNT, 0);\n        for (int l = 0; l < M; l++) {\n            int cid = 0;\n            for (int k = 1; k < SEED_COUNT; k++) {\n                if (seeds[k][l] > seeds[cid][l] ||\n                    (seeds[k][l] == seeds[cid][l] && val[k] > val[cid])) {\n                    cid = k;\n                }\n            }\n            champId[l] = cid;\n            if (!seenChamp[cid]) {\n                seenChamp[cid] = 1;\n                championList.push_back(cid);\n            }\n        }\n\n        // improvers relative to best\n        struct Item { int score, val, id; };\n        vector<Item> improvers;\n        improvers.reserve(SEED_COUNT);\n        for (int k = 0; k < SEED_COUNT; k++) if (k != best_id) {\n            int imp = 0;\n            for (int l = 0; l < M; l++) imp += max(seeds[best_id][l], seeds[k][l]) - seeds[best_id][l];\n            improvers.push_back({imp, val[k], k});\n        }\n        sort(improvers.begin(), improvers.end(), [&](const Item &a, const Item &b) {\n            if (a.score != b.score) return a.score > b.score;\n            return a.val > b.val;\n        });\n\n        // selection\n        vector<char> used(SEED_COUNT, 0);\n        vector<int> selected;\n        auto add_sel = [&](int id) {\n            if (!used[id]) {\n                used[id] = 1;\n                selected.push_back(id);\n            }\n        };\n        add_sel(best_id);\n        for (int cid : championList) add_sel(cid);\n        int IMP_LIMIT = 10;\n        int impAdded = 0;\n        for (auto &it : improvers) {\n            if (impAdded >= IMP_LIMIT) break;\n            if (!used[it.id]) {\n                add_sel(it.id);\n                impAdded++;\n            }\n        }\n        // fill remaining\n        vector<int> fillOrder(SEED_COUNT);\n        iota(fillOrder.begin(), fillOrder.end(), 0);\n        sort(fillOrder.begin(), fillOrder.end(), [&](int a, int b) {\n            if (cntMax[a] != cntMax[b]) return cntMax[a] > cntMax[b];\n            return val[a] > val[b];\n        });\n        for (int id : fillOrder) {\n            if ((int)selected.size() >= SZ) break;\n            add_sel(id);\n        }\n\n        // neighbor seeds list\n        vector<int> neighborSeeds;\n        for (auto &it : improvers) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            int id = it.id;\n            if (!used[id] || id == best_id) continue;\n            neighborSeeds.push_back(id);\n        }\n        for (int id : fillOrder) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            if (used[id] && id != best_id &&\n                find(neighborSeeds.begin(), neighborSeeds.end(), id) == neighborSeeds.end()) {\n                neighborSeeds.push_back(id);\n            }\n        }\n\n        // essential flags\n        vector<char> essential(SEED_COUNT, 0);\n        essential[best_id] = 1;\n        for (int cid : championList) essential[cid] = 1;\n        for (int id : neighborSeeds) essential[id] = 1;\n\n        // trim if oversized\n        while ((int)selected.size() > SZ) {\n            int remIdx = -1;\n            int worstCnt = INT_MAX, worstVal = INT_MAX;\n            for (int idx = 0; idx < (int)selected.size(); idx++) {\n                int id = selected[idx];\n                if (essential[id]) continue;\n                if (cntMax[id] < worstCnt || (cntMax[id] == worstCnt && val[id] < worstVal)) {\n                    worstCnt = cntMax[id];\n                    worstVal = val[id];\n                    remIdx = idx;\n                }\n            }\n            if (remIdx == -1) break;\n            used[selected[remIdx]] = 0;\n            selected.erase(selected.begin() + remIdx);\n        }\n\n        // recompute neighbor seeds from selected\n        neighborSeeds.clear();\n        for (auto &it : improvers) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            int id = it.id;\n            if (used[id] && id != best_id) neighborSeeds.push_back(id);\n        }\n\n        // compute synergy matrix\n        for (int a = 0; a < SEED_COUNT; a++) {\n            for (int b = 0; b < SEED_COUNT; b++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(seeds[a][l], seeds[b][l]);\n                synergy[a][b] = s;\n            }\n        }\n\n        vector<int> assign(SZ, -1);\n        vector<char> pinned(SZ, 0);\n        assign[centerPos] = best_id;\n        pinned[centerPos] = 1;\n\n        vector<int> centerNbrs;\n        int ci = center_i, cj = center_j;\n        if (cj - 1 >= 0) centerNbrs.push_back(ci * N + (cj - 1));\n        if (cj + 1 < N) centerNbrs.push_back(ci * N + (cj + 1));\n        if (ci - 1 >= 0) centerNbrs.push_back((ci - 1) * N + cj);\n        if (ci + 1 < N) centerNbrs.push_back((ci + 1) * N + cj);\n\n        for (size_t idx = 0; idx < centerNbrs.size() && idx < neighborSeeds.size(); idx++) {\n            int pos = centerNbrs[idx];\n            assign[pos] = neighborSeeds[idx];\n            pinned[pos] = 1;\n        }\n\n        // seeds left to place\n        vector<int> seedsLeft;\n        for (int id : selected) {\n            bool isPinnedSeed = (id == best_id);\n            for (int ns : neighborSeeds) if (id == ns) isPinnedSeed = true;\n            if (!isPinnedSeed) seedsLeft.push_back(id);\n        }\n        // positions left to fill\n        struct PosInfo {\n            int pos;\n            int deg;\n            double dist;\n        };\n        vector<PosInfo> posLeft;\n        for (int p = 0; p < SZ; p++) {\n            if (pinned[p]) continue;\n            posLeft.push_back({p, (int)neighPos[p].size(), posDist[p]});\n        }\n        sort(posLeft.begin(), posLeft.end(), [&](const PosInfo &a, const PosInfo &b) {\n            if (a.deg != b.deg) return a.deg > b.deg;\n            return a.dist < b.dist;\n        });\n        sort(seedsLeft.begin(), seedsLeft.end(), [&](int a, int b) {\n            if (cntMax[a] != cntMax[b]) return cntMax[a] > cntMax[b];\n            return val[a] > val[b];\n        });\n\n        for (size_t i = 0; i < posLeft.size() && i < seedsLeft.size(); i++) {\n            assign[posLeft[i].pos] = seedsLeft[i];\n        }\n\n        // hillclimb swap among non-pinned positions\n        vector<int> varPosList;\n        for (int p = 0; p < SZ; p++) if (!pinned[p]) varPosList.push_back(p);\n\n        auto computeDelta = [&](int p, int q) -> int {\n            int sp = assign[p], sq = assign[q];\n            int delta = 0;\n            for (int n : neighPos[p]) {\n                if (n == q) continue;\n                int sn = assign[n];\n                delta -= synergy[sp][sn];\n                delta += synergy[sq][sn];\n            }\n            for (int n : neighPos[q]) {\n                if (n == p) continue;\n                int sn = assign[n];\n                delta -= synergy[sq][sn];\n                delta += synergy[sp][sn];\n            }\n            return delta;\n        };\n\n        const int MAX_ITERS = 20000;\n        int vps = varPosList.size();\n        if (vps >= 2) {\n            for (int it = 0; it < MAX_ITERS; it++) {\n                int idx1 = rng() % vps;\n                int idx2 = rng() % vps;\n                if (idx1 == idx2) continue;\n                int p = varPosList[idx1], q = varPosList[idx2];\n                int delta = computeDelta(p, q);\n                if (delta > 0) {\n                    swap(assign[p], assign[q]);\n                }\n            }\n        }\n\n        // output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j) cout << ' ';\n                cout << assign[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // read next generation seeds\n        if (turn != T - 1) {\n            for (int i = 0; i < SEED_COUNT; i++) {\n                for (int j = 0; j < M; j++) {\n                    cin >> seeds[i][j];\n                }\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\ninline int manh(const Pos &a, const Pos &b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Hungarian algorithm for square cost matrix (n x n)\nvector<int> hungarian(const vector<vector<int>> &a) {\n    int n = (int)a.size();\n    const int INF = 1e9;\n    vector<int> u(n + 1), v(n + 1), p(n + 1), way(n + 1);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(n + 1, INF);\n        vector<char> used(n + 1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= n; j++) if (!used[j]) {\n                int cur = a[i0 - 1][j - 1] - u[i0] - v[j];\n                if (cur < minv[j]) {\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if (minv[j] < delta) {\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for (int j = 0; j <= n; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    vector<int> matchL(n, -1);\n    for (int j = 1; j <= n; j++) {\n        if (p[j] != 0) matchL[p[j] - 1] = j - 1;\n    }\n    return matchL;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    vector<Pos> sources, targets;\n    sources.reserve(M);\n    targets.reserve(M);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1' && t[i][j] == '0') sources.push_back({i, j});\n            else if (s[i][j] == '0' && t[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n    int n = (int)sources.size();\n    cout << 1 << \"\\n\";\n    if (n == 0) {\n        cout << 0 << \" \" << 0 << \"\\n\";\n        return 0;\n    }\n\n    auto startAll = chrono::steady_clock::now();\n    const double TIME_LIMIT = 2.8;\n\n    // assignment\n    vector<vector<int>> costAssign(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            costAssign[i][j] = manh(sources[i], targets[j]);\n    vector<int> matchS = hungarian(costAssign); // target index for each source\n\n    vector<Pos> taskTarget(n);\n    for (int i = 0; i < n; i++) taskTarget[i] = targets[matchS[i]];\n\n    // edgeCost: target of i to source of j\n    vector<vector<int>> edgeCost(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            edgeCost[i][j] = manh(taskTarget[i], sources[j]);\n        }\n    }\n\n    mt19937 rng((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto elapsed = [&]() -> double {\n        chrono::duration<double> diff = chrono::steady_clock::now() - startAll;\n        return diff.count();\n    };\n\n    // initial sequences\n    vector<int> bestSeq;\n    long long bestTrans = (1LL << 60);\n    int numStarts = min(n, 12);\n    vector<int> startCandidates;\n    startCandidates.reserve(numStarts);\n    Pos center{N / 2, N / 2};\n    int bestCenterIdx = 0;\n    int bestCenterDist = 1e9;\n    for (int i = 0; i < n; i++) {\n        int d = manh(sources[i], center);\n        if (d < bestCenterDist) {\n            bestCenterDist = d;\n            bestCenterIdx = i;\n        }\n    }\n    startCandidates.push_back(bestCenterIdx);\n    uniform_int_distribution<int> uid(0, n - 1);\n    while ((int)startCandidates.size() < numStarts) {\n        int v = uid(rng);\n        bool dup = false;\n        for (int x : startCandidates) if (x == v) { dup = true; break; }\n        if (!dup) startCandidates.push_back(v);\n    }\n\n    for (int st : startCandidates) {\n        vector<char> used(n, false);\n        vector<int> seq;\n        seq.reserve(n);\n        int cur = st;\n        used[cur] = true;\n        seq.push_back(cur);\n        for (int k = 1; k < n; k++) {\n            int best = -1, bestd = 1e9;\n            for (int j = 0; j < n; j++) if (!used[j]) {\n                int d = edgeCost[cur][j];\n                if (d < bestd) {\n                    bestd = d;\n                    best = j;\n                }\n            }\n            used[best] = true;\n            seq.push_back(best);\n            cur = best;\n        }\n        long long trans = 0;\n        for (int i = 0; i + 1 < n; i++) trans += edgeCost[seq[i]][seq[i + 1]];\n        if (trans < bestTrans) {\n            bestTrans = trans;\n            bestSeq = seq;\n        }\n    }\n\n    vector<int> seq = bestSeq;\n    long long curCost = bestTrans;\n    long long bestCostAll = curCost;\n    vector<int> bestSeqAll = seq;\n\n    auto swapDelta = [&](int i, int j) -> int {\n        if (i == j) return 0;\n        if (i > j) swap(i, j);\n        int nseq = (int)seq.size();\n        int a = (i > 0) ? seq[i - 1] : -1;\n        int b = seq[i];\n        int c = (i + 1 < nseq) ? seq[i + 1] : -1;\n        int d = (j > 0) ? seq[j - 1] : -1;\n        int e = seq[j];\n        int f = (j + 1 < nseq) ? seq[j + 1] : -1;\n        if (i + 1 == j) {\n            long long oldc = 0, newc = 0;\n            if (a != -1) { oldc += edgeCost[a][b]; newc += edgeCost[a][e]; }\n            oldc += edgeCost[b][e];\n            newc += edgeCost[e][b];\n            if (f != -1) { oldc += edgeCost[e][f]; newc += edgeCost[b][f]; }\n            return (int)(newc - oldc);\n        } else {\n            long long oldc = 0, newc = 0;\n            if (a != -1) { oldc += edgeCost[a][b]; newc += edgeCost[a][e]; }\n            oldc += edgeCost[b][c];\n            newc += edgeCost[e][c];\n            oldc += edgeCost[d][e];\n            newc += edgeCost[d][b];\n            if (f != -1) { oldc += edgeCost[e][f]; newc += edgeCost[b][f]; }\n            return (int)(newc - oldc);\n        }\n    };\n\n    auto relocateDelta = [&](int i, int j) -> int {\n        int nseq = (int)seq.size();\n        if (i == j || i + 1 == j) return 0;\n        int b = seq[i];\n        int prev = (i > 0) ? seq[i - 1] : -1;\n        int nxt = (i + 1 < nseq) ? seq[i + 1] : -1;\n        long long delta = 0;\n        if (prev != -1) delta -= edgeCost[prev][b];\n        if (nxt != -1) delta -= edgeCost[b][nxt];\n        if (prev != -1 && nxt != -1) delta += edgeCost[prev][nxt];\n        int pos = j;\n        if (j > i) pos--;\n        auto getElem = [&](int idx) -> int {\n            if (idx < i) return seq[idx];\n            else return seq[idx + 1];\n        };\n        int prevIns = (pos > 0) ? getElem(pos - 1) : -1;\n        int nextIns = (pos < nseq - 1) ? getElem(pos) : -1;\n        if (prevIns != -1) delta += edgeCost[prevIns][b];\n        if (nextIns != -1) delta += edgeCost[b][nextIns];\n        if (prevIns != -1 && nextIns != -1) delta -= edgeCost[prevIns][nextIns];\n        return (int)delta;\n    };\n\n    // Simulated annealing\n    double T0 = 30.0, T1 = 1e-3;\n    int nseq = n;\n    while (true) {\n        double t = elapsed();\n        if (t > TIME_LIMIT) break;\n        double progress = t / TIME_LIMIT;\n        double Temp = exp(log(T0) * (1.0 - progress) + log(T1) * progress);\n        int moveType = uniform_int_distribution<int>(0, 1)(rng);\n        if (moveType == 0) {\n            int i = uniform_int_distribution<int>(0, nseq - 1)(rng);\n            int j = uniform_int_distribution<int>(0, nseq - 1)(rng);\n            if (i == j) continue;\n            int d = swapDelta(i, j);\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                swap(seq[i], seq[j]);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        } else {\n            int i = uniform_int_distribution<int>(0, nseq - 1)(rng);\n            int j = uniform_int_distribution<int>(0, nseq)(rng);\n            if (i == j || i + 1 == j) continue;\n            int d = relocateDelta(i, j);\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                int node = seq[i];\n                seq.erase(seq.begin() + i);\n                if (j > i) j--;\n                seq.insert(seq.begin() + j, node);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        }\n    }\n\n    seq = bestSeqAll;\n    curCost = bestCostAll;\n\n    // Hill climbing small-range swaps/relocates\n    int range = min(30, nseq - 1);\n    int iterCheck = 0;\n    while (elapsed() < TIME_LIMIT) {\n        iterCheck++;\n        int i = uniform_int_distribution<int>(0, nseq - 1)(rng);\n        int jOff = uniform_int_distribution<int>(-range, range)(rng);\n        int j = i + jOff;\n        if (j < 0) j = 0;\n        if (j >= nseq) j = nseq - 1;\n        if (i != j) {\n            int d = swapDelta(i, j);\n            if (d < 0) {\n                swap(seq[i], seq[j]);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        } else continue;\n\n        if ((iterCheck & 1023) == 0 && elapsed() > TIME_LIMIT) break;\n    }\n    seq = bestSeqAll;\n\n    // initial root position at first source\n    Pos root = sources[seq[0]];\n    cout << root.x << \" \" << root.y << \"\\n\";\n\n    vector<string> cmds;\n    cmds.reserve((size_t)(bestCostAll + n * 2 + 10));\n\n    Pos cur = root;\n    auto moveTo = [&](const Pos &dest, bool doP) {\n        int dx = dest.x - cur.x;\n        int dy = dest.y - cur.y;\n        if (dx != 0) {\n            char mv = (dx > 0) ? 'D' : 'U';\n            int steps = abs(dx);\n            for (int k = 1; k <= steps; k++) {\n                bool last = (k == steps) && (dy == 0) && doP;\n                string s;\n                s.push_back(mv);\n                s.push_back(last ? 'P' : '.');\n                cmds.push_back(std::move(s));\n            }\n        }\n        if (dy != 0) {\n            char mv = (dy > 0) ? 'R' : 'L';\n            int steps = abs(dy);\n            for (int k = 1; k <= steps; k++) {\n                bool last = (k == steps) && doP;\n                string s;\n                s.push_back(mv);\n                s.push_back(last ? 'P' : '.');\n                cmds.push_back(std::move(s));\n            }\n        }\n        if (dx == 0 && dy == 0) {\n            string s;\n            s.push_back('.');\n            s.push_back(doP ? 'P' : '.');\n            cmds.push_back(std::move(s));\n        }\n        cur = dest;\n    };\n\n    // Execute tasks\n    moveTo(sources[seq[0]], true);\n    moveTo(taskTarget[seq[0]], true);\n    for (int idx = 1; idx < n; idx++) {\n        int task = seq[idx];\n        moveTo(sources[task], true);\n        moveTo(taskTarget[task], true);\n    }\n\n    for (auto &c : cmds) cout << c << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x1, x2, y1, y2;\n};\n\nconst int LIM = 100000;\n\ninline Rect normalize(Rect r) {\n    if (r.x1 > r.x2) swap(r.x1, r.x2);\n    if (r.y1 > r.y2) swap(r.y1, r.y2);\n    r.x1 = max(0, min(LIM, r.x1));\n    r.x2 = max(0, min(LIM, r.x2));\n    r.y1 = max(0, min(LIM, r.y1));\n    r.y2 = max(0, min(LIM, r.y2));\n    if (r.x1 == r.x2) {\n        if (r.x2 < LIM) r.x2++;\n        else if (r.x1 > 0) r.x1--;\n        else r.x2 = r.x1 + 1;\n    }\n    if (r.y1 == r.y2) {\n        if (r.y2 < LIM) r.y2++;\n        else if (r.y1 > 0) r.y1--;\n        else r.y2 = r.y1 + 1;\n    }\n    return r;\n}\n\nstruct Evaluator {\n    int tot;\n    const vector<int> &xs, &ys, &ws;\n    Evaluator(const vector<int>& _xs, const vector<int>& _ys, const vector<int>& _ws)\n        : tot((int)_xs.size()), xs(_xs), ys(_ys), ws(_ws) {}\n    inline int evalRect(const Rect& r) const {\n        int s = 0;\n        int x1 = r.x1, x2 = r.x2, y1 = r.y1, y2 = r.y2;\n        for (int i = 0; i < tot; i++) {\n            int x = xs[i];\n            if (x < x1 || x > x2) continue;\n            int y = ys[i];\n            if (y < y1 || y > y2) continue;\n            s += ws[i];\n        }\n        return s;\n    }\n};\n\nRect bestGridRect(int G, const vector<int>& xs, const vector<int>& ys, const vector<int>& ws) {\n    int cell = (LIM + G - 1) / G;\n    vector<vector<int>> diff(G, vector<int>(G, 0));\n    int tot = (int)xs.size();\n    for (int i = 0; i < tot; i++) {\n        int cx = xs[i] / cell; if (cx >= G) cx = G - 1;\n        int cy = ys[i] / cell; if (cy >= G) cy = G - 1;\n        diff[cy][cx] += ws[i];\n    }\n    int best = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n    vector<int> col(G);\n    for (int top = 0; top < G; top++) {\n        fill(col.begin(), col.end(), 0);\n        for (int bottom = top; bottom < G; bottom++) {\n            for (int x = 0; x < G; x++) col[x] += diff[bottom][x];\n            int cur = 0, start = 0;\n            int bestSum = -1e9, bestL = 0, bestR = 0;\n            for (int x = 0; x < G; x++) {\n                if (cur <= 0) {\n                    cur = col[x];\n                    start = x;\n                } else {\n                    cur += col[x];\n                }\n                if (cur > bestSum) {\n                    bestSum = cur;\n                    bestL = start;\n                    bestR = x;\n                }\n            }\n            if (bestSum > best) {\n                best = bestSum;\n                int x1 = bestL * cell;\n                int x2 = min(LIM, (bestR + 1) * cell);\n                int y1 = top * cell;\n                int y2 = min(LIM, (bottom + 1) * cell);\n                bestRect = normalize({x1, x2, y1, y2});\n            }\n        }\n    }\n    return bestRect;\n}\n\nstruct Candidate {\n    int score;\n    Rect rect;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    int TOT = 2 * N;\n    vector<int> xs(TOT), ys(TOT), ws(TOT);\n    for (int i = 0; i < TOT; i++) {\n        int x, y;\n        cin >> x >> y;\n        xs[i] = x;\n        ys[i] = y;\n        ws[i] = (i < N) ? 1 : -1;\n    }\n    Evaluator eval(xs, ys, ws);\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    auto startTime = chrono::steady_clock::now();\n\n    int bestScore = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n\n    vector<Candidate> candList;\n    auto addCandidate = [&](int sc, const Rect& r) {\n        // check duplicates\n        for (auto &c : candList) {\n            if (c.rect.x1 == r.x1 && c.rect.x2 == r.x2 && c.rect.y1 == r.y1 && c.rect.y2 == r.y2) {\n                if (sc > c.score) c.score = sc;\n                return;\n            }\n        }\n        candList.push_back({sc, r});\n        sort(candList.begin(), candList.end(), [](const Candidate& a, const Candidate& b) {\n            return a.score > b.score;\n        });\n        if ((int)candList.size() > 40) candList.resize(40);\n    };\n\n    auto consider = [&](const Rect& r) {\n        Rect nr = normalize(r);\n        int sc = eval.evalRect(nr);\n        addCandidate(sc, nr);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRect = nr;\n        }\n    };\n\n    // bounding box of mackerels\n    int minMx = LIM, maxMx = 0, minMy = LIM, maxMy = 0;\n    for (int i = 0; i < N; i++) {\n        minMx = min(minMx, xs[i]);\n        maxMx = max(maxMx, xs[i]);\n        minMy = min(minMy, ys[i]);\n        maxMy = max(maxMy, ys[i]);\n    }\n    consider({minMx, maxMx, minMy, maxMy});\n\n    // grid search\n    vector<int> Gs = {8, 12, 16, 20, 25, 30, 40, 50};\n    for (int g : Gs) {\n        Rect r = bestGridRect(g, xs, ys, ws);\n        consider(r);\n    }\n\n    // random search\n    vector<int> sizes = {200, 300, 500, 800, 1000, 1200, 1500, 2000, 2500, 3000, 4000, 5000, 6000, 8000, 10000, 12000, 15000, 20000, 25000};\n    const double RAND_TIME = 1.1; // seconds\n    int iter = 0;\n    while (true) {\n        iter++;\n        int t = rng() % 4;\n        if (t == 0) {\n            int idx = rng() % N;\n            int w = sizes[rng() % sizes.size()];\n            int h = sizes[rng() % sizes.size()];\n            Rect r{xs[idx] - w, xs[idx] + w, ys[idx] - h, ys[idx] + h};\n            consider(r);\n        } else if (t == 1) {\n            int i = rng() % TOT;\n            int j = rng() % TOT;\n            int x1 = min(xs[i], xs[j]);\n            int x2 = max(xs[i], xs[j]);\n            int y1 = min(ys[i], ys[j]);\n            int y2 = max(ys[i], ys[j]);\n            int marg = sizes[rng() % sizes.size()] / 2;\n            Rect r{x1 - marg, x2 + marg, y1 - marg, y2 + marg};\n            consider(r);\n        } else if (t == 2) {\n            Rect r = bestRect;\n            int delta = sizes[rng() % sizes.size()] / 2 + 1;\n            int dx1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dx2 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy2 = (int)(rng() % (2 * delta + 1)) - delta;\n            r.x1 += dx1; r.x2 += dx2; r.y1 += dy1; r.y2 += dy2;\n            consider(r);\n        } else {\n            // random thin rectangle\n            int idx = rng() % TOT;\n            int w = sizes[rng() % sizes.size()] / 4 + 1;\n            Rect r{xs[idx] - w, xs[idx] + w, 0, LIM};\n            consider(r);\n            r = {0, LIM, ys[idx] - w, ys[idx] + w};\n            consider(r);\n        }\n        if ((iter & 31) == 0) {\n            double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - startTime).count();\n            if (elapsed > RAND_TIME) break;\n        }\n    }\n\n    // hill climbing around bestRect\n    vector<int> steps = {20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50};\n    Rect cur = bestRect;\n    for (int step : steps) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int edge = 0; edge < 4; edge++) {\n                for (int dir = -1; dir <= 1; dir += 2) {\n                    Rect r = cur;\n                    if (edge == 0) r.x1 += dir * step;\n                    else if (edge == 1) r.x2 += dir * step;\n                    else if (edge == 2) r.y1 += dir * step;\n                    else r.y2 += dir * step;\n                    r = normalize(r);\n                    int sc = eval.evalRect(r);\n                    addCandidate(sc, r);\n                    if (sc > bestScore) {\n                        bestScore = sc;\n                        bestRect = cur = r;\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // evaluate pair connections\n    int bestPairScore = bestScore;\n    Rect bestA = bestRect, bestB = bestRect;\n    bool usePair = false;\n    bool horiz = true;\n    int corridorC = 0;\n    // only top K candidates\n    int K = min<int>(candList.size(), 25);\n    for (int i = 0; i < K; i++) for (int j = i + 1; j < K; j++) {\n        Rect A = candList[i].rect;\n        Rect B = candList[j].rect;\n        // horizontal connection: disjoint in x with y-overlap length>=1\n        if (A.x2 < B.x1 || B.x2 < A.x1) {\n            Rect L = A, R = B;\n            if (B.x2 < A.x1) { L = B; R = A; }\n            int ovL = max(L.y1, R.y1);\n            int ovH = min(L.y2, R.y2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int y1 = c, y2 = c + 1;\n                    int x1 = L.x2, x2 = R.x1;\n                    if (x1 > x2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= L.x1 && x <= L.x2 && y >= L.y1 && y <= L.y2) inside = true;\n                        else if (x >= R.x1 && x <= R.x2 && y >= R.y1 && y <= R.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = L;\n                        bestB = R;\n                        horiz = true;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n        // vertical connection: disjoint in y with x-overlap length>=1\n        if (A.y2 < B.y1 || B.y2 < A.y1) {\n            Rect Lw = A, Up = B;\n            if (B.y2 < A.y1) { Lw = B; Up = A; }\n            int ovL = max(Lw.x1, Up.x1);\n            int ovH = min(Lw.x2, Up.x2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int x1 = c, x2 = c + 1;\n                    int y1 = Lw.y2, y2 = Up.y1;\n                    if (y1 > y2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= Lw.x1 && x <= Lw.x2 && y >= Lw.y1 && y <= Lw.y2) inside = true;\n                        else if (x >= Up.x1 && x <= Up.x2 && y >= Up.y1 && y <= Up.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = Lw;\n                        bestB = Up;\n                        horiz = false;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int,int>> poly;\n    if (usePair) {\n        if (horiz) {\n            Rect L = bestA, R = bestB;\n            int c = corridorC;\n            int ch = 1;\n            vector<pair<int,int>> tmp = {\n                {L.x1, L.y1},\n                {L.x2, L.y1},\n                {L.x2, c},\n                {R.x1, c},\n                {R.x1, R.y1},\n                {R.x2, R.y1},\n                {R.x2, R.y2},\n                {R.x1, R.y2},\n                {R.x1, c + ch},\n                {L.x2, c + ch},\n                {L.x2, L.y2},\n                {L.x1, L.y2}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        } else {\n            Rect Lw = bestA, Up = bestB;\n            int c = corridorC;\n            int cw = 1;\n            vector<pair<int,int>> tmp = {\n                {Lw.x1, Lw.y1},\n                {Lw.x1, Lw.y2},\n                {c, Lw.y2},\n                {c, Up.y1},\n                {Up.x1, Up.y1},\n                {Up.x1, Up.y2},\n                {Up.x2, Up.y2},\n                {Up.x2, Up.y1},\n                {c + cw, Up.y1},\n                {c + cw, Lw.y2},\n                {Lw.x2, Lw.y2},\n                {Lw.x2, Lw.y1}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        }\n    } else {\n        poly = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n    }\n    // compress consecutive duplicates\n    vector<pair<int,int>> comp;\n    comp.reserve(poly.size());\n    for (auto &p : poly) {\n        if (comp.empty() || comp.back() != p) comp.push_back(p);\n    }\n    if (comp.size() >= 2 && comp.front() == comp.back()) comp.pop_back();\n    // check distinct\n    bool okDistinct = true;\n    {\n        unordered_set<long long> st;\n        st.reserve(comp.size() * 2);\n        for (auto &p : comp) {\n            long long key = ((long long)p.first << 32) ^ (unsigned)p.second;\n            if (st.find(key) != st.end()) {\n                okDistinct = false;\n                break;\n            }\n            st.insert(key);\n        }\n    }\n    long long perim = 0;\n    int m = (int)comp.size();\n    for (int i = 0; i < m; i++) {\n        auto [x1, y1] = comp[i];\n        auto [x2, y2] = comp[(i + 1) % m];\n        perim += llabs(x1 - x2) + llabs(y1 - y2);\n    }\n    if (!okDistinct || perim > 400000 || m < 4) {\n        comp = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n        m = 4;\n    }\n    cout << comp.size() << \"\\n\";\n    for (auto &p : comp) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Command {\n    int p;\n    int r;\n    char d;\n    int b;\n};\n\nstruct Candidate {\n    vector<Command> cmds;\n    long long estScore;\n};\n\n// simulate placement given commands and estimated widths/heights\npair<long long, long long> simulate(const vector<Command>& cmds,\n                                    const vector<long long>& w_est,\n                                    const vector<long long>& h_est) {\n    int N = (int)w_est.size();\n    vector<long long> x(N, 0), y(N, 0), ww(N, 0), hh(N, 0);\n    vector<char> placed(N, 0);\n    long long W = 0, H = 0;\n    for (const auto& cmd : cmds) {\n        int i = cmd.p;\n        long long w = (cmd.r == 0 ? w_est[i] : h_est[i]);\n        long long h = (cmd.r == 0 ? h_est[i] : w_est[i]);\n        long long xi, yi;\n        if (cmd.d == 'U') {\n            xi = (cmd.b == -1) ? 0LL : x[cmd.b] + ww[cmd.b];\n            yi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long l1 = xi, r1 = xi + w;\n                long long l2 = x[j], r2 = x[j] + ww[j];\n                if (max(l1, l2) < min(r1, r2)) {\n                    yi = max(yi, y[j] + hh[j]);\n                }\n            }\n        } else { // 'L'\n            yi = (cmd.b == -1) ? 0LL : y[cmd.b] + hh[cmd.b];\n            xi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long t1 = yi, b1 = yi + h;\n                long long t2 = y[j], b2 = y[j] + hh[j];\n                if (max(t1, t2) < min(b1, b2)) {\n                    xi = max(xi, x[j] + ww[j]);\n                }\n            }\n        }\n        x[i] = xi; y[i] = yi; ww[i] = w; hh[i] = h; placed[i] = 1;\n        W = max(W, xi + w);\n        H = max(H, yi + h);\n    }\n    return {W, H};\n}\n\nvector<int> dp_partition(const vector<long long>& w, const vector<long long>& h_eff, long long Wlim) {\n    int N = (int)w.size();\n    const long long INF = (1LL << 60);\n    vector<long long> dp(N + 1, INF);\n    vector<int> prv(N + 1, -1);\n    dp[0] = 0;\n    for (int i = 0; i < N; i++) {\n        long long width = 0;\n        long long height = 0;\n        for (int j = i; j >= 0; j--) {\n            width += w[j];\n            if (width > Wlim) break;\n            height = max(height, h_eff[j]);\n            if (dp[j] + height < dp[i + 1]) {\n                dp[i + 1] = dp[j] + height;\n                prv[i + 1] = j;\n            }\n        }\n    }\n    if (dp[N] >= INF / 2) prv.clear();\n    return prv;\n}\n\nvector<pair<int,int>> reconstruct_rows(const vector<int>& prv) {\n    vector<pair<int,int>> rows;\n    if (prv.empty()) return rows;\n    int idx = (int)prv.size() - 1;\n    while (idx > 0) {\n        int j = prv[idx];\n        if (j < 0) { rows.clear(); return rows; }\n        rows.push_back({j, idx});\n        idx = j;\n    }\n    reverse(rows.begin(), rows.end());\n    return rows;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_obs[i] >> h_obs[i];\n    }\n\n    // build orientation patterns\n    vector<vector<int>> orientations;\n    auto add_ori = [&](const vector<int>& o) {\n        for (auto &v : orientations) {\n            if (v == o) return;\n        }\n        orientations.push_back(o);\n    };\n    vector<int> ori_none(N, 0);\n    add_ori(ori_none);\n    vector<int> ori_minH(N), ori_minW(N);\n    for (int i = 0; i < N; i++) {\n        ori_minH[i] = (w_obs[i] < h_obs[i]) ? 1 : 0;\n        ori_minW[i] = (w_obs[i] > h_obs[i]) ? 1 : 0;\n    }\n    add_ori(ori_minH);\n    add_ori(ori_minW);\n    // lambda thresholds\n    vector<double> lambdas = {0.8, 1.0, 1.2};\n    for (double lam : lambdas) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            o[i] = ((double)w_obs[i] > lam * (double)h_obs[i]) ? 1 : 0;\n        }\n        add_ori(o);\n    }\n    // orientations adapted to some width limits\n    auto build_width_candidates_base = [&](const vector<long long>& w, const vector<long long>& h) {\n        long long sumW = 0, maxW = 0;\n        long double area = 0;\n        for (int i = 0; i < N; i++) {\n            sumW += w[i];\n            maxW = max(maxW, w[i]);\n            area += (long double)w[i] * (long double)h[i];\n        }\n        long long sqrtA = (long long)(sqrt(area) + 0.5);\n        set<long long> s;\n        s.insert(maxW);\n        s.insert(sumW);\n        s.insert(sqrtA);\n        int Kpart = min(8, N);\n        for (int k = 2; k <= Kpart; k++) {\n            s.insert((sumW + k - 1) / k);\n        }\n        int Kgeo = 8;\n        if (maxW > 0) {\n            long double ratio = (long double)sumW / (long double)maxW;\n            for (int k = 0; k < Kgeo; k++) {\n                long double val = (long double)maxW * pow(ratio, (long double)k / (long double)(Kgeo - 1));\n                long long W = (long long)(val + 0.5);\n                W = max(W, maxW);\n                W = min(W, sumW);\n                s.insert(W);\n            }\n        }\n        vector<long long> res(s.begin(), s.end());\n        return res;\n    };\n    vector<long long> base_w = w_obs, base_h = h_obs;\n    vector<long long> w_candidates_base = build_width_candidates_base(base_w, base_h);\n    for (long long Wlim : w_candidates_base) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            bool fit0 = w_obs[i] <= Wlim;\n            bool fitR = h_obs[i] <= Wlim;\n            if (fit0 && fitR) {\n                o[i] = (h_obs[i] > w_obs[i]) ? 1 : 0;\n            } else if (fit0) {\n                o[i] = 0;\n            } else if (fitR) {\n                o[i] = 1;\n            } else {\n                o[i] = 0;\n            }\n        }\n        add_ori(o);\n    }\n\n    vector<Candidate> candidates;\n    vector<long long> margins = {0}; // could add small margin if desired\n\n    auto build_candidates_for_orientation = [&](const vector<int>& r_choice) {\n        vector<long long> w_rot(N), h_rot(N);\n        long long sumW = 0, maxW = 0;\n        long long sumH = 0, maxH = 0;\n        long double area = 0;\n        for (int i = 0; i < N; i++) {\n            long long w = (r_choice[i] == 0 ? w_obs[i] : h_obs[i]);\n            long long h = (r_choice[i] == 0 ? h_obs[i] : w_obs[i]);\n            w_rot[i] = w; h_rot[i] = h;\n            sumW += w; sumH += h;\n            maxW = max(maxW, w);\n            maxH = max(maxH, h);\n            area += (long double)w * (long double)h;\n        }\n        long long sqrtA = (long long)(sqrt(area) + 0.5);\n\n        auto build_limits = [&](long long sumV, long long maxV, long long sqrtA) {\n            set<long long> s;\n            s.insert(maxV);\n            s.insert(sumV);\n            s.insert(sqrtA);\n            int Kpart = min(10, N);\n            for (int k = 2; k <= Kpart; k++) {\n                s.insert((sumV + k - 1) / k);\n            }\n            int Kgeo = 10;\n            if (maxV > 0) {\n                long double ratio = (long double)sumV / (long double)maxV;\n                for (int k = 0; k < Kgeo; k++) {\n                    long double val = (long double)maxV * pow(ratio, (long double)k / (long double)(Kgeo - 1));\n                    long long V = (long long)(val + 0.5);\n                    V = max(V, maxV);\n                    V = min(V, sumV);\n                    s.insert(V);\n                }\n            }\n            vector<long long> res(s.begin(), s.end());\n            return res;\n        };\n\n        vector<long long> Wlims = build_limits(sumW, maxW, sqrtA);\n        vector<long long> Hlims = build_limits(sumH, maxH, sqrtA);\n\n        // row packings\n        for (long long margin : margins) {\n            vector<long long> h_eff(N);\n            for (int i = 0; i < N; i++) h_eff[i] = h_rot[i] + margin;\n            for (long long Wlim : Wlims) {\n                if (Wlim < maxW) continue;\n                vector<int> prv = dp_partition(w_rot, h_eff, Wlim);\n                if (prv.empty()) continue;\n                vector<pair<int,int>> rows = reconstruct_rows(prv);\n                if (rows.empty()) continue;\n                vector<int> ref_idx(rows.size());\n                for (size_t ri = 0; ri < rows.size(); ri++) {\n                    int l = rows[ri].first;\n                    int r = rows[ri].second;\n                    long long besth = -1;\n                    int idx = l;\n                    for (int i = l; i < r; i++) {\n                        if (h_eff[i] > besth || (h_eff[i] == besth && i > idx)) {\n                            besth = h_eff[i];\n                            idx = i;\n                        }\n                    }\n                    ref_idx[ri] = idx;\n                }\n                vector<Command> cmds;\n                cmds.reserve(N);\n                for (size_t ri = 0; ri < rows.size(); ri++) {\n                    int b = (ri == 0) ? -1 : ref_idx[ri - 1];\n                    int l = rows[ri].first;\n                    int r = rows[ri].second;\n                    for (int i = l; i < r; i++) {\n                        cmds.push_back({i, r_choice[i], 'L', b});\n                    }\n                }\n                auto est = simulate(cmds, w_obs, h_obs);\n                Candidate cand{cmds, est.first + est.second};\n                candidates.push_back(move(cand));\n            }\n        }\n\n        // column packings\n        for (long long margin : margins) {\n            vector<long long> h_eff_col(N);\n            for (int i = 0; i < N; i++) h_eff_col[i] = w_rot[i] + margin; // heights become widths\n            for (long long Hlim : Hlims) {\n                if (Hlim < maxH) continue;\n                vector<int> prv = dp_partition(h_rot, h_eff_col, Hlim); // widths -> h_rot, heights -> w_rot\n                if (prv.empty()) continue;\n                vector<pair<int,int>> cols = reconstruct_rows(prv);\n                if (cols.empty()) continue;\n                vector<int> ref_idx(cols.size());\n                for (size_t ci = 0; ci < cols.size(); ci++) {\n                    int l = cols[ci].first;\n                    int r = cols[ci].second;\n                    long long bestw = -1;\n                    int idx = l;\n                    for (int i = l; i < r; i++) {\n                        if (w_rot[i] > bestw || (w_rot[i] == bestw && i > idx)) {\n                            bestw = w_rot[i];\n                            idx = i;\n                        }\n                    }\n                    ref_idx[ci] = idx;\n                }\n                vector<Command> cmds;\n                cmds.reserve(N);\n                for (size_t ci = 0; ci < cols.size(); ci++) {\n                    int b = (ci == 0) ? -1 : ref_idx[ci - 1];\n                    int l = cols[ci].first;\n                    int r = cols[ci].second;\n                    for (int i = l; i < r; i++) {\n                        cmds.push_back({i, r_choice[i], 'U', b});\n                    }\n                }\n                auto est = simulate(cmds, w_obs, h_obs);\n                Candidate cand{cmds, est.first + est.second};\n                candidates.push_back(move(cand));\n            }\n        }\n    };\n\n    for (auto &ori : orientations) {\n        build_candidates_for_orientation(ori);\n    }\n\n    // fallback simple packings\n    {\n        vector<Command> cmds;\n        cmds.reserve(N);\n        for (int i = 0; i < N; i++) cmds.push_back({i, ori_minH[i], 'L', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n    {\n        vector<Command> cmds;\n        cmds.reserve(N);\n        for (int i = 0; i < N; i++) cmds.push_back({i, ori_minW[i], 'U', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    if (candidates.empty()) {\n        vector<Command> cmds;\n        for (int i = 0; i < N; i++) cmds.push_back({i, 0, 'L', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n        return a.estScore < b.estScore;\n    });\n\n    vector<vector<Command>> outputs;\n    int useCnt = min((int)candidates.size(), T);\n    for (int i = 0; i < useCnt; i++) outputs.push_back(candidates[i].cmds);\n    while ((int)outputs.size() < T) outputs.push_back(outputs[0]);\n\n    for (int t = 0; t < T; t++) {\n        const auto& cmds = outputs[t];\n        cout << cmds.size() << \"\\n\";\n        for (auto &cmd : cmds) {\n            cout << cmd.p << \" \" << cmd.r << \" \" << cmd.d << \" \" << cmd.b << \"\\n\";\n        }\n        cout.flush();\n        long long Wm, Hm;\n        if (!(cin >> Wm >> Hm)) break;\n        // ignore measurements in this heuristic\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    vector<int> parent;\n    long long score;\n};\n\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    // Precompute all-pairs shortest distances\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    queue<int> q;\n    for (int s = 0; s < N; s++) {\n        auto &drow = dist[s];\n        drow[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            int nd = drow[u] + 1;\n            for (int v : adj[u]) {\n                if (drow[v] == INF) {\n                    drow[v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Eccentricity\n    vector<int> ecc(N, 0);\n    for (int i = 0; i < N; i++) {\n        int mx = 0;\n        for (int j = 0; j < N; j++) {\n            if (dist[i][j] > mx) mx = dist[i][j];\n        }\n        ecc[i] = mx;\n    }\n\n    // Neighbor ordering\n    vector<vector<int>> adj_desc(N), adj_rand(N);\n    for (int u = 0; u < N; u++) {\n        adj_desc[u] = adj[u];\n        sort(adj_desc[u].begin(), adj_desc[u].end(), [&](int a, int b) {\n            if (A[a] != A[b]) return A[a] > A[b];\n            return a < b;\n        });\n        adj_rand[u] = adj[u];\n        shuffle(adj_rand[u].begin(), adj_rand[u].end(), rng);\n    }\n\n    // Seeds\n    vector<int> seeds;\n    vector<char> seen_seed(N, 0);\n    auto add_seed = [&](int v) {\n        if (!seen_seed[v]) {\n            seen_seed[v] = 1;\n            seeds.push_back(v);\n        }\n    };\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (A[i] != A[j]) return A[i] < A[j];\n        return i < j;\n    });\n    int kLow = min(30, N);\n    for (int i = 0; i < kLow; i++) add_seed(idx[i]);\n\n    int cen = 0;\n    for (int i = 1; i < N; i++) {\n        if (ecc[i] < ecc[cen] || (ecc[i] == ecc[cen] && A[i] < A[cen]))\n            cen = i;\n    }\n    add_seed(cen);\n\n    long long bestd = (long long)(x[0] - 500) * (x[0] - 500) +\n                      (long long)(y[0] - 500) * (y[0] - 500);\n    int centerCoord = 0;\n    for (int i = 1; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d < bestd) {\n            bestd = d;\n            centerCoord = i;\n        }\n    }\n    add_seed(centerCoord);\n\n    long long maxd = bestd;\n    int farCoord = centerCoord;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d > maxd) {\n            maxd = d;\n            farCoord = i;\n        }\n    }\n    add_seed(farCoord);\n\n    uniform_int_distribution<int> uid(0, N - 1);\n    for (int i = 0; i < 50; i++) add_seed(uid(rng));\n\n    auto prune_roots = [&](vector<int> &roots) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int idx_r = 0; idx_r < (int)roots.size(); idx_r++) {\n                vector<int> tmp(N, INF);\n                for (int j = 0; j < (int)roots.size(); j++) {\n                    if (j == idx_r) continue;\n                    int r = roots[j];\n                    for (int i = 0; i < N; i++) {\n                        int d = dist[r][i];\n                        if (d < tmp[i]) tmp[i] = d;\n                    }\n                }\n                int mx = *max_element(tmp.begin(), tmp.end());\n                if (mx <= H) {\n                    roots.erase(roots.begin() + idx_r);\n                    changed = true;\n                    break;\n                }\n            }\n        }\n    };\n\n    auto select_roots_farthest = [&](int seed) {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> minDist = dist[seed];\n        while (true) {\n            int farNode = -1, farDist = -1, farA = 1e9;\n            for (int i = 0; i < N; i++) {\n                if (minDist[i] > farDist ||\n                    (minDist[i] == farDist && A[i] < farA)) {\n                    farDist = minDist[i];\n                    farNode = i;\n                    farA = A[i];\n                }\n            }\n            if (farDist <= H) break;\n            roots.push_back(farNode);\n            for (int i = 0; i < N; i++) {\n                int d = dist[farNode][i];\n                if (d < minDist[i]) minDist[i] = d;\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_cover_greedy = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        while (remaining > 0) {\n            int best = -1, bestCnt = -1, bestA = 1e9;\n            for (int c = 0; c < N; c++) {\n                int cnt = 0;\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[c][i] <= H) cnt++;\n                }\n                if (cnt > bestCnt || (cnt == bestCnt && A[c] < bestA)) {\n                    bestCnt = cnt;\n                    best = c;\n                    bestA = A[c];\n                }\n            }\n            if (best == -1) break;\n            roots.push_back(best);\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[best][i] <= H) {\n                    covered[i] = 1;\n                    remaining--;\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto finalize_and_score = [&](vector<int> parent) -> Solution {\n        vector<vector<int>> children(N);\n        vector<int> depth(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        // Clamp invalid\n        for (int v = 0; v < N; v++) {\n            if (depth[v] == -1 || depth[v] > H) {\n                parent[v] = -1;\n            }\n        }\n        // recompute depths after fixing\n        children.assign(N, {});\n        depth.assign(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0) d = 0;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    auto leaf_reparent = [&](vector<int> &parent, vector<int> &depth) {\n        vector<int> childCnt(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) childCnt[parent[v]]++;\n        }\n        bool changed = true;\n        int iter = 0;\n        while (changed && iter < H * 2 + 5) {\n            changed = false;\n            iter++;\n            for (int v = 0; v < N; v++) {\n                if (childCnt[v] == 0) {\n                    int bestDepth = depth[v];\n                    int bestPar = -1;\n                    for (int u : adj[v]) {\n                        int nd = depth[u] + 1;\n                        if (nd <= H && nd > bestDepth) {\n                            bestDepth = nd;\n                            bestPar = u;\n                        }\n                    }\n                    if (bestPar != -1 && parent[v] != bestPar) {\n                        int oldp = parent[v];\n                        if (oldp != -1) childCnt[oldp]--;\n                        parent[v] = bestPar;\n                        childCnt[bestPar]++;\n                        depth[v] = bestDepth;\n                        changed = true;\n                    }\n                }\n            }\n        }\n    };\n\n    auto build_solution = [&](const vector<int> &roots, int orderMode,\n                              int neighborMode) -> Solution {\n        const vector<vector<int>> *adj_used;\n        if (neighborMode == 0)\n            adj_used = &adj_desc;\n        else\n            adj_used = &adj_rand;\n        vector<int> parent(N, -2), depth(N, INF);\n        vector<char> visited(N, 0);\n        vector<int> root_order = roots;\n        if (orderMode == 0) {\n            sort(root_order.begin(), root_order.end(),\n                 [&](int a, int b) { return A[a] < A[b]; });\n        } else {\n            shuffle(root_order.begin(), root_order.end(), rng);\n        }\n        for (int r : root_order) {\n            if (visited[r]) continue;\n            parent[r] = -1;\n            depth[r] = 0;\n            visited[r] = 1;\n            vector<pair<int, int>> st;\n            st.reserve(N);\n            st.push_back({r, 0});\n            while (!st.empty()) {\n                int u = st.back().first;\n                int &idxn = st.back().second;\n                if (depth[u] == H) {\n                    st.pop_back();\n                    continue;\n                }\n                if (idxn >= (int)(*adj_used)[u].size()) {\n                    st.pop_back();\n                    continue;\n                }\n                int v = (*adj_used)[u][idxn++];\n                if (visited[v]) continue;\n                parent[v] = u;\n                depth[v] = depth[u] + 1;\n                visited[v] = 1;\n                st.push_back({v, 0});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            if (!visited[i]) {\n                parent[i] = -1;\n                depth[i] = 0;\n                visited[i] = 1;\n                vector<pair<int, int>> st;\n                st.reserve(N);\n                st.push_back({i, 0});\n                while (!st.empty()) {\n                    int u = st.back().first;\n                    int &idxn = st.back().second;\n                    if (depth[u] == H) {\n                        st.pop_back();\n                        continue;\n                    }\n                    if (idxn >= (int)(*adj_used)[u].size()) {\n                        st.pop_back();\n                        continue;\n                    }\n                    int v = (*adj_used)[u][idxn++];\n                    if (visited[v]) continue;\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    visited[v] = 1;\n                    st.push_back({v, 0});\n                }\n            }\n        }\n        leaf_reparent(parent, depth);\n        return finalize_and_score(parent);\n    };\n\n    auto build_growth = [&](int seedCount) -> Solution {\n        vector<int> parent(N, -1), depth(N, -1);\n        vector<char> done(N, 0);\n        int processed = 0;\n        for (int i = 0; i < seedCount && i < N; i++) {\n            int v = idx[i];\n            if (!done[v]) {\n                done[v] = 1;\n                parent[v] = -1;\n                depth[v] = 0;\n                processed++;\n            }\n        }\n        while (processed < N) {\n            bool progress = false;\n            for (int v = 0; v < N; v++) {\n                if (done[v]) continue;\n                int bestPar = -1, bestDepth = -1, bestA = 1e9;\n                for (int u : adj_desc[v]) {\n                    if (!done[u]) continue;\n                    int nd = depth[u] + 1;\n                    if (nd > H) continue;\n                    if (nd > bestDepth || (nd == bestDepth && A[u] < bestA)) {\n                        bestDepth = nd;\n                        bestPar = u;\n                        bestA = A[u];\n                    }\n                }\n                if (bestPar != -1) {\n                    parent[v] = bestPar;\n                    depth[v] = bestDepth;\n                    done[v] = 1;\n                    processed++;\n                    progress = true;\n                }\n            }\n            if (!progress) {\n                int nr = -1, minA = 1e9;\n                for (int v = 0; v < N; v++) {\n                    if (!done[v] && A[v] < minA) {\n                        minA = A[v];\n                        nr = v;\n                    }\n                }\n                if (nr == -1) break;\n                done[nr] = 1;\n                parent[nr] = -1;\n                depth[nr] = 0;\n                processed++;\n            }\n        }\n        leaf_reparent(parent, depth);\n        return finalize_and_score(parent);\n    };\n\n    auto hill_climb = [&](Solution sol) -> Solution {\n        vector<int> &parent = sol.parent;\n        vector<int> depth(N, -1);\n        while (true) {\n            // build children and depth\n            vector<vector<int>> children(N);\n            for (int v = 0; v < N; v++) {\n                int p = parent[v];\n                if (p >= 0) children[p].push_back(v);\n            }\n            fill(depth.begin(), depth.end(), -1);\n            queue<int> qq;\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) {\n                    depth[v] = 0;\n                    qq.push(v);\n                }\n            }\n            while (!qq.empty()) {\n                int u = qq.front();\n                qq.pop();\n                for (int c : children[u]) {\n                    depth[c] = depth[u] + 1;\n                    qq.push(c);\n                }\n            }\n            // tin/tout\n            vector<int> tin(N, 0), tout(N, 0);\n            int timer = 0;\n            function<void(int)> dfs = [&](int u) {\n                tin[u] = timer++;\n                for (int c : children[u]) dfs(c);\n                tout[u] = timer;\n            };\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) dfs(v);\n            }\n            // order for postorder\n            vector<int> order;\n            order.reserve(N);\n            function<void(int)> dfs2 = [&](int u) {\n                order.push_back(u);\n                for (int c : children[u]) dfs2(c);\n            };\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) dfs2(v);\n            }\n            vector<long long> subSumA(N, 0);\n            vector<int> subMaxDepth(N, 0);\n            for (int i = (int)order.size() - 1; i >= 0; i--) {\n                int v = order[i];\n                long long sum = A[v];\n                int mx = depth[v];\n                for (int c : children[v]) {\n                    sum += subSumA[c];\n                    if (subMaxDepth[c] > mx) mx = subMaxDepth[c];\n                }\n                subSumA[v] = sum;\n                subMaxDepth[v] = mx;\n            }\n\n            long long bestGain = 0;\n            int bestV = -1, bestU = -1, bestDelta = 0;\n            for (int v = 0; v < N; v++) {\n                for (int u : adj[v]) {\n                    if (tin[v] <= tin[u] && tout[u] <= tout[v]) continue; // u in subtree\n                    int delta = depth[u] + 1 - depth[v];\n                    if (delta <= 0) continue;\n                    if (subMaxDepth[v] + delta > H) continue;\n                    long long gain = 1LL * delta * subSumA[v];\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestV = v;\n                        bestU = u;\n                        bestDelta = delta;\n                    }\n                }\n            }\n            if (bestGain <= 0) break;\n            int v = bestV, u = bestU, delta = bestDelta;\n            // update parent\n            parent[v] = u;\n            // update depths of subtree v\n            vector<int> st;\n            st.push_back(v);\n            while (!st.empty()) {\n                int w = st.back();\n                st.pop_back();\n                depth[w] += delta;\n                for (int c : children[w]) st.push_back(c);\n            }\n        }\n        // compute final score\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        fill(depth.begin(), depth.end(), -1);\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0 || d > H) d = 0;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    vector<vector<int>> rootSets;\n    for (int sd : seeds) {\n        rootSets.push_back(select_roots_farthest(sd));\n    }\n    rootSets.push_back(select_roots_cover_greedy());\n\n    vector<Solution> candidates;\n    candidates.reserve(rootSets.size() * 4 + 5);\n    for (const auto &roots : rootSets) {\n        candidates.push_back(build_solution(roots, 0, 0));\n        candidates.push_back(build_solution(roots, 0, 1));\n        candidates.push_back(build_solution(roots, 2, 0));\n        candidates.push_back(build_solution(roots, 2, 1));\n    }\n    // growth-based\n    candidates.push_back(build_growth(5));\n    candidates.push_back(build_growth(10));\n    candidates.push_back(build_growth(20));\n\n    sort(candidates.begin(), candidates.end(),\n         [](const Solution &a, const Solution &b) {\n             return a.score > b.score;\n         });\n    int topK = min<int>(8, candidates.size());\n    long long bestScore = -1;\n    vector<int> bestParent(N, -1);\n    for (int i = 0; i < topK; i++) {\n        Solution imp = hill_climb(candidates[i]);\n        if (imp.score > bestScore) {\n            bestScore = imp.score;\n            bestParent = imp.parent;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option {\n    int line; // 0..4N-1\n    int len;  // 1..N\n};\n\nstruct Solver {\n    static const int N = 20;\n    vector<string> board;\n    vector<int> upLim, downLim, leftLim, rightLim;\n    vector<pair<int,int>> oni;               // positions of oni\n    vector<vector<Option>> opts;             // options for each oni\n    int M;                                   // #oni\n\n    // state\n    vector<array<int, N+1>> cnt; // cnt[line][len]\n    vector<int> maxLen;          // max len per line\n    vector<int> assign;          // chosen option index per oni\n    long cost;                   // 2 * sum(maxLen)\n\n    mt19937 rng;\n\n    Solver(const vector<string>& g): board(g) {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n        compute_limits();\n        collect_oni();\n        build_options();\n    }\n\n    void compute_limits() {\n        upLim.assign(N, N);\n        downLim.assign(N, N);\n        leftLim.assign(N, N);\n        rightLim.assign(N, N);\n        // columns\n        for (int j = 0; j < N; j++) {\n            for (int i = 0; i < N; i++) {\n                if (board[i][j] == 'o') { upLim[j] = i; break; }\n            }\n            for (int i = N-1; i >= 0; i--) {\n                if (board[i][j] == 'o') { downLim[j] = N-1 - i; break; }\n            }\n        }\n        // rows\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'o') { leftLim[i] = j; break; }\n            }\n            for (int j = N-1; j >= 0; j--) {\n                if (board[i][j] == 'o') { rightLim[i] = N-1 - j; break; }\n            }\n        }\n    }\n\n    void collect_oni() {\n        oni.clear();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') oni.emplace_back(i,j);\n            }\n        }\n        M = (int)oni.size();\n    }\n\n    void build_options() {\n        opts.assign(M, {});\n        for (int idx = 0; idx < M; idx++) {\n            auto [r,c] = oni[idx];\n            // Up\n            if (r+1 <= upLim[c]) {\n                opts[idx].push_back({c, r+1});\n            }\n            // Down\n            if (N - r <= downLim[c]) {\n                opts[idx].push_back({N + c, N - r});\n            }\n            // Left\n            if (c+1 <= leftLim[r]) {\n                opts[idx].push_back({2*N + r, c+1});\n            }\n            // Right\n            if (N - c <= rightLim[r]) {\n                opts[idx].push_back({3*N + r, N - c});\n            }\n            if (opts[idx].empty()) {\n                // Should not happen\n                opts[idx].push_back({c, r+1}); // dummy\n            }\n        }\n    }\n\n    void rebuild_from_assign() {\n        cnt.assign(4*N, {});\n        maxLen.assign(4*N, 0);\n        cost = 0;\n        for (int i = 0; i < M; i++) {\n            int optIdx = assign[i];\n            const Option &op = opts[i][optIdx];\n            cnt[op.line][op.len] ++;\n            if (op.len > maxLen[op.line]) maxLen[op.line] = op.len;\n        }\n        for (int l = 0; l < 4*N; l++) {\n            cost += 2LL * maxLen[l];\n        }\n    }\n\n    // helpers for delta computation\n    int newMaxAfterRemoval(int line, int len) const {\n        int oldMax = maxLen[line];\n        if (len < oldMax) return oldMax;\n        if (cnt[line][len] >= 2) return oldMax;\n        // len == oldMax and will be removed\n        for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) return l;\n        return 0;\n    }\n\n    int computeDelta(int i, int newOpt) const {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return 0;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        if (cur.line == nxt.line) {\n            int line = cur.line;\n            int oldMax = maxLen[line];\n            int newMax = oldMax;\n            if (cur.len == oldMax && cnt[line][cur.len] == 1) {\n                newMax = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[line][l] > 0) {newMax=l; break;}\n            }\n            if (nxt.len > newMax) newMax = nxt.len;\n            return 2 * (newMax - oldMax);\n        } else {\n            int oldMaxA = maxLen[cur.line];\n            int oldMaxB = maxLen[nxt.line];\n            int newMaxA = oldMaxA;\n            if (cur.len == oldMaxA && cnt[cur.line][cur.len] == 1) {\n                newMaxA = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[cur.line][l] > 0) {newMaxA=l; break;}\n            }\n            int newMaxB = (nxt.len > oldMaxB) ? nxt.len : oldMaxB;\n            return 2 * ((newMaxA - oldMaxA) + (newMaxB - oldMaxB));\n        }\n    }\n\n    void remove_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]--;\n        if (len == oldMax && cnt[line][len] == 0) {\n            int m = 0;\n            for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) {m = l; break;}\n            maxLen[line] = m;\n        }\n        cost += 2LL * maxLen[line];\n    }\n\n    void add_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]++;\n        if (len > oldMax) maxLen[line] = len;\n        cost += 2LL * maxLen[line];\n    }\n\n    void applyMove(int i, int newOpt) {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        remove_assignment(cur.line, cur.len);\n        add_assignment(nxt.line, nxt.len);\n        assign[i] = newOpt;\n    }\n\n    void hillClimb() {\n        while (true) {\n            int bestDelta = 0;\n            int bestI = -1;\n            int bestOpt = -1;\n            for (int i = 0; i < M; i++) {\n                int curOpt = assign[i];\n                for (int k = 0; k < (int)opts[i].size(); k++) {\n                    if (k == curOpt) continue;\n                    int delta = computeDelta(i, k);\n                    if (delta < bestDelta) {\n                        bestDelta = delta;\n                        bestI = i;\n                        bestOpt = k;\n                    }\n                }\n            }\n            if (bestDelta < 0) {\n                applyMove(bestI, bestOpt);\n            } else break;\n        }\n    }\n\n    void simulatedAnnealing(int ITER, double T0, double T1) {\n        vector<int> bestAssignLocal = assign;\n        long bestCostLocal = cost;\n        uniform_real_distribution<double> dist01(0.0, 1.0);\n        for (int it = 0; it < ITER; it++) {\n            double T = T0 + (T1 - T0) * (double)it / (double)ITER;\n            int i = rng() % M;\n            if (opts[i].size() <= 1) continue;\n            int newOpt = rng() % opts[i].size();\n            if (newOpt == assign[i]) continue;\n            int delta = computeDelta(i, newOpt);\n            if (delta <= 0 || exp(-delta / T) > dist01(rng)) {\n                applyMove(i, newOpt);\n                if (cost < bestCostLocal) {\n                    bestCostLocal = cost;\n                    bestAssignLocal = assign;\n                }\n            }\n        }\n        assign = bestAssignLocal;\n        rebuild_from_assign();\n    }\n\n    // Large neighborhood search: reassign a subset exhaustively\n    bool lns_once(int k) {\n        if (M == 0) return false;\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        // sort by current required length descending\n        sort(idx.begin(), idx.end(), [&](int a, int b){\n            int lena = opts[a][assign[a]].len;\n            int lenb = opts[b][assign[b]].len;\n            return lena > lenb;\n        });\n        int candSize = min(M, 10);\n        if (candSize < k) k = candSize;\n        if (k == 0) return false;\n        // choose first candSize then shuffle\n        vector<int> cands(idx.begin(), idx.begin() + candSize);\n        shuffle(cands.begin(), cands.end(), rng);\n        vector<int> subset(cands.begin(), cands.begin() + k);\n\n        vector<int> backupAssign = assign;\n        long originalCost = cost;\n\n        // remove subset assignments\n        for (int id : subset) {\n            const Option &op = opts[id][assign[id]];\n            remove_assignment(op.line, op.len);\n            assign[id] = -1;\n        }\n        long baseCost = cost;\n\n        vector<int> bestChoices(k, 0);\n        long bestCost = (1LL<<60);\n\n        function<void(int)> dfs = [&](int depth){\n            if (depth == k) {\n                if (cost < bestCost) {\n                    bestCost = cost;\n                    for (int t = 0; t < k; t++) {\n                        bestChoices[t] = assign[subset[t]];\n                    }\n                }\n                return;\n            }\n            int oniId = subset[depth];\n            for (int optIdx = 0; optIdx < (int)opts[oniId].size(); optIdx++) {\n                const Option &op = opts[oniId][optIdx];\n                add_assignment(op.line, op.len);\n                assign[oniId] = optIdx;\n                dfs(depth+1);\n                remove_assignment(op.line, op.len);\n                assign[oniId] = -1;\n            }\n        };\n        dfs(0);\n\n        // restore assignment based on result\n        if (bestCost < originalCost) {\n            assign = backupAssign;\n            for (int t = 0; t < k; t++) {\n                assign[subset[t]] = bestChoices[t];\n            }\n            rebuild_from_assign();\n            return true;\n        } else {\n            assign = backupAssign;\n            rebuild_from_assign();\n            return false;\n        }\n    }\n\n    void solve() {\n        int NUM_SEEDS = 8;\n        int SA_ITER = 40000;\n        double T0 = 5.0, T1 = 0.1;\n        int LNS_TRIES = 60;\n        int LNS_K = 5;\n\n        long globalBestCost = (1LL<<60);\n        vector<int> globalBestAssign;\n        vector<int> globalBestMaxLen;\n\n        uniform_int_distribution<int> seedDist(0, 1e9);\n\n        for (int seed = 0; seed < NUM_SEEDS; seed++) {\n            // initial assignment\n            assign.assign(M, 0);\n            for (int i = 0; i < M; i++) {\n                if (seed == 0) {\n                    // choose minimal len (tie random)\n                    int bestLen = 1e9;\n                    vector<int> cand;\n                    for (int k = 0; k < (int)opts[i].size(); k++) {\n                        int len = opts[i][k].len;\n                        if (len < bestLen) {\n                            bestLen = len;\n                            cand.clear();\n                            cand.push_back(k);\n                        } else if (len == bestLen) {\n                            cand.push_back(k);\n                        }\n                    }\n                    assign[i] = cand[rng() % cand.size()];\n                } else {\n                    assign[i] = rng() % opts[i].size();\n                }\n            }\n            rebuild_from_assign();\n            hillClimb();\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n\n            simulatedAnnealing(SA_ITER, T0, T1);\n            hillClimb();\n\n            bool improved = true;\n            int tries = 0;\n            while (improved && tries < LNS_TRIES) {\n                improved = lns_once(LNS_K);\n                tries++;\n            }\n\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n        }\n\n        // use global best\n        assign = globalBestAssign;\n        maxLen = globalBestMaxLen;\n        // output operations\n        vector<pair<char,int>> ops;\n        auto add_ops = [&](char dir, int idx, int len){\n            for (int k = 0; k < len; k++) ops.emplace_back(dir, idx);\n        };\n        // Up then Down for up lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[j];\n            if (len > 0) {\n                add_ops('U', j, len);\n                add_ops('D', j, len);\n            }\n        }\n        // Down then Up for down lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[N + j];\n            if (len > 0) {\n                add_ops('D', j, len);\n                add_ops('U', j, len);\n            }\n        }\n        // Left then Right\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[2*N + i];\n            if (len > 0) {\n                add_ops('L', i, len);\n                add_ops('R', i, len);\n            }\n        }\n        // Right then Left\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[3*N + i];\n            if (len > 0) {\n                add_ops('R', i, len);\n                add_ops('L', i, len);\n            }\n        }\n\n        for (auto &op : ops) {\n            cout << op.first << \" \" << op.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n;\n    if (!(cin >> n)) return 0;\n    vector<string> g(n);\n    for (int i = 0; i < n; i++) cin >> g[i];\n    Solver solver(g);\n    solver.solve();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift {\n    using result_type = uint64_t;\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return UINT64_MAX; }\n    result_type operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint64_t next() { return (*this)(); }\n    int next_int(int l, int r) { return l + (int)(next() % (uint64_t)(r - l + 1)); }\n};\n\nint N, Ltot;\nvector<int> T;\nvector<double> pi;\nvector<long long> prefixT;\nXorShift rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n// weighted random by target distribution\nint rand_by_target() {\n    uint64_t r = rng.next() % (uint64_t)Ltot;\n    int idx = int(lower_bound(prefixT.begin(), prefixT.end(), (long long)r + 1) - prefixT.begin());\n    if (idx >= N) idx = N - 1;\n    return idx;\n}\n\n// approximate error using power iteration\ndouble approx_error(const vector<int>& a, const vector<int>& b, vector<double>* outCounts = nullptr) {\n    static double d0[105], d1[105];\n    double inv = 1.0 / N;\n    for (int i = 0; i < N; i++) d0[i] = inv;\n    double* cur = d0;\n    double* nxt = d1;\n    const int ITER = 45;\n    for (int it = 0; it < ITER; it++) {\n        for (int j = 0; j < N; j++) nxt[j] = 0.0;\n        for (int i = 0; i < N; i++) {\n            double v = cur[i];\n            int ai = a[i], bi = b[i];\n            if (ai == bi) {\n                nxt[ai] += v;\n            } else {\n                double h = 0.5 * v;\n                nxt[ai] += h;\n                nxt[bi] += h;\n            }\n        }\n        swap(cur, nxt);\n    }\n    double err = 0.0;\n    if (outCounts) outCounts->assign(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        double c = cur[i] * Ltot;\n        if (outCounts) (*outCounts)[i] = c;\n        err += fabs(c - (double)T[i]);\n    }\n    return err;\n}\n\n// simulate exact process\nlong long simulate(const vector<int>& a, const vector<int>& b, vector<int>* outCnt = nullptr) {\n    static int cnt[105];\n    for (int i = 0; i < N; i++) cnt[i] = 0;\n    int cur = 0;\n    for (int step = 0; step < Ltot; step++) {\n        int c = ++cnt[cur];\n        cur = (c & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)cnt[i] - (long long)T[i];\n        err += d >= 0 ? d : -d;\n    }\n    if (outCnt) outCnt->assign(cnt, cnt + N);\n    return err;\n}\n\n// ensure nodes with T>0 have indegree>0\nvoid enforce_indegree(vector<int>& a, vector<int>& b) {\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < N; i++) {\n        indeg[a[i]]++;\n        indeg[b[i]]++;\n    }\n    for (int j = 0; j < N; j++) {\n        if (T[j] > 0 && indeg[j] == 0) {\n            int s = rng.next_int(0, N - 1);\n            if (rng.next_int(0, 1) == 0) {\n                indeg[a[s]]--;\n                a[s] = j;\n            } else {\n                indeg[b[s]]--;\n                b[s] = j;\n            }\n            indeg[j]++;\n        }\n    }\n}\n\n// compute indegree distribution summing to 2N\nvoid compute_degrees(int minMode, const vector<double>& desired, vector<int>& deg) {\n    int edges = 2 * N;\n    deg.assign(N, 0);\n    int minSum = 0;\n    for (int i = 0; i < N; i++) {\n        int mv = 0;\n        if (minMode == 1) {\n            if (T[i] > 0) mv = 1;\n        } else if (minMode == 2) {\n            mv = 1;\n        }\n        deg[i] = mv;\n        minSum += mv;\n    }\n    int R = edges - minSum;\n    static double quota[105];\n    double qsum = 0.0;\n    for (int i = 0; i < N; i++) {\n        double q = desired[i] - deg[i];\n        if (q < 0) q = 0;\n        quota[i] = q;\n        qsum += q;\n    }\n    static pair<double, int> fr[105];\n    int sumDeg = minSum;\n    if (qsum > 1e-9) {\n        double scale = (double)R / qsum;\n        for (int i = 0; i < N; i++) {\n            double v = quota[i] * scale;\n            int add = (int)v;\n            deg[i] += add;\n            sumDeg += add;\n            fr[i] = make_pair(v - add, i);\n        }\n    } else {\n        for (int i = 0; i < N; i++) fr[i] = make_pair(0.0, i);\n    }\n    int leftover = edges - sumDeg;\n    for (int i = N - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(fr[i], fr[j]);\n    }\n    sort(fr, fr + N, [](const pair<double, int>& a, const pair<double, int>& b) {\n        return a.first > b.first;\n    });\n    for (int k = 0; k < leftover; k++) deg[fr[k].second]++;\n}\n\n// build candidate using apportionment\nvoid build_apportion(int minMode, const vector<double>& desired, vector<int>& a, vector<int>& b) {\n    vector<int> deg;\n    compute_degrees(minMode, desired, deg);\n    vector<int> slots;\n    slots.reserve(2 * N);\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n    }\n    while ((int)slots.size() < 2 * N) slots.push_back(rand_by_target());\n    while ((int)slots.size() > 2 * N) slots.pop_back();\n    for (int i = (int)slots.size() - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(slots[i], slots[j]);\n    }\n    a.resize(N);\n    b.resize(N);\n    for (int i = 0; i < N; i++) {\n        a[i] = slots[2 * i];\n        b[i] = slots[2 * i + 1];\n    }\n    enforce_indegree(a, b);\n}\n\n// greedy assignment variants\nvoid build_greedy(int variant, vector<int>& a, vector<int>& b) {\n    a.assign(N, -1);\n    b.assign(N, -1);\n    vector<double> r(N);\n    for (int j = 0; j < N; j++) r[j] = 2.0 * pi[j];\n    vector<int> order(2 * N);\n    for (int i = 0; i < N; i++) {\n        order[2 * i] = i;\n        order[2 * i + 1] = i;\n    }\n    if (variant == 0) {\n        sort(order.begin(), order.end(), [&](int i, int j) { return pi[i] > pi[j]; });\n    } else if (variant == 1) {\n        sort(order.begin(), order.end(), [&](int i, int j) { return pi[i] < pi[j]; });\n    } else {\n        for (int i = (int)order.size() - 1; i > 0; --i) {\n            int j = rng.next() % (uint64_t)(i + 1);\n            swap(order[i], order[j]);\n        }\n    }\n    for (int idx = 0; idx < (int)order.size(); idx++) {\n        int s = order[idx];\n        double w = pi[s];\n        int bestJ = 0;\n        if (variant == 2) { // fit residual\n            double bestVal = 1e18;\n            for (int j = 0; j < N; j++) {\n                double v = fabs(r[j] - w);\n                if (v < bestVal) {\n                    bestVal = v;\n                    bestJ = j;\n                }\n            }\n        } else {\n            double bestVal = -1e18;\n            for (int j = 0; j < N; j++) {\n                if (r[j] > bestVal) {\n                    bestVal = r[j];\n                    bestJ = j;\n                }\n            }\n        }\n        r[bestJ] -= w;\n        if (a[s] == -1)\n            a[s] = bestJ;\n        else\n            b[s] = bestJ;\n    }\n    for (int i = 0; i < N; i++) if (b[i] == -1) b[i] = a[i];\n    enforce_indegree(a, b);\n}\n\nstruct Candidate {\n    double approxErr;\n    vector<int> a, b;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> Ltot)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    pi.resize(N);\n    for (int i = 0; i < N; i++) pi[i] = (double)T[i] / (double)Ltot;\n    prefixT.resize(N);\n    long long acc = 0;\n    for (int i = 0; i < N; i++) {\n        acc += T[i];\n        prefixT[i] = acc;\n    }\n    vector<double> desiredEdges(N);\n    for (int i = 0; i < N; i++) desiredEdges[i] = pi[i] * 2.0 * N;\n\n    // top nodes\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return T[i] > T[j]; });\n    int top1 = idx[0], top2 = idx[1];\n\n    vector<int> bestA(N), bestB(N);\n    double bestApproxErr = 1e100;\n    vector<double> bestApproxCounts;\n\n    vector<Candidate> topList;\n    const int TOPK = 20;\n    auto updateTop = [&](const vector<int>& a, const vector<int>& b, double err) {\n        topList.push_back({err, a, b});\n        nth_element(topList.begin(), topList.begin() + min(TOPK, (int)topList.size()) - 1, topList.end(),\n                    [](const Candidate& x, const Candidate& y) { return x.approxErr < y.approxErr; });\n        if ((int)topList.size() > TOPK) topList.resize(TOPK);\n    };\n\n    vector<int> candA, candB;\n\n    // initial candidates: greedy variants\n    for (int v = 0; v < 3; v++) {\n        build_greedy(v, candA, candB);\n        double err = approx_error(candA, candB);\n        updateTop(candA, candB, err);\n        if (err < bestApproxErr) {\n            bestApproxErr = err;\n            bestA = candA;\n            bestB = candB;\n            approx_error(bestA, bestB, &bestApproxCounts);\n        }\n    }\n    // apportionment initial\n    build_apportion(1, desiredEdges, candA, candB);\n    double errAp = approx_error(candA, candB);\n    updateTop(candA, candB, errAp);\n    if (errAp < bestApproxErr) {\n        bestApproxErr = errAp;\n        bestA = candA;\n        bestB = candB;\n        approx_error(bestA, bestB, &bestApproxCounts);\n    }\n\n    auto start = chrono::steady_clock::now();\n    const double TOTAL_LIMIT = 1.85;\n    double genLimit = 0.9;\n\n    // generation loop\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > genLimit) break;\n        int mode = rng.next_int(0, 7);\n        switch (mode) {\n            case 0: { // random by target\n                candA.resize(N);\n                candB.resize(N);\n                for (int i = 0; i < N; i++) {\n                    candA[i] = rand_by_target();\n                    candB[i] = rand_by_target();\n                }\n                enforce_indegree(candA, candB);\n                break;\n            }\n            case 1: { // both edges same by target\n                candA.resize(N);\n                candB.resize(N);\n                for (int i = 0; i < N; i++) {\n                    int v = rand_by_target();\n                    candA[i] = v;\n                    candB[i] = v;\n                }\n                enforce_indegree(candA, candB);\n                break;\n            }\n            case 2: { // apportionment min0\n                build_apportion(0, desiredEdges, candA, candB);\n                break;\n            }\n            case 3: { // apportionment min2\n                build_apportion(2, desiredEdges, candA, candB);\n                break;\n            }\n            case 4: { // greedy random\n                build_greedy(2, candA, candB);\n                break;\n            }\n            case 5: { // cycle + target\n                candA.resize(N);\n                candB.resize(N);\n                for (int i = 0; i < N; i++) {\n                    candA[i] = (i + 1) % N;\n                    candB[i] = rand_by_target();\n                }\n                enforce_indegree(candA, candB);\n                break;\n            }\n            case 6: { // top nodes\n                candA.resize(N);\n                candB.resize(N);\n                for (int i = 0; i < N; i++) {\n                    candA[i] = top1;\n                    candB[i] = top2;\n                }\n                break;\n            }\n            case 7: { // uniform random\n                candA.resize(N);\n                candB.resize(N);\n                for (int i = 0; i < N; i++) {\n                    candA[i] = rng.next_int(0, N - 1);\n                    candB[i] = rng.next_int(0, N - 1);\n                }\n                enforce_indegree(candA, candB);\n                break;\n            }\n        }\n        double err = approx_error(candA, candB);\n        updateTop(candA, candB, err);\n        if (err < bestApproxErr) {\n            bestApproxErr = err;\n            bestA = candA;\n            bestB = candB;\n            approx_error(bestA, bestB, &bestApproxCounts);\n        }\n    }\n\n    // small local search on best approximate\n    vector<int> curA = bestA, curB = bestB;\n    vector<double> curCounts = bestApproxCounts, tmpCounts;\n    double curErr = bestApproxErr;\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > TOTAL_LIMIT - 0.25) break;\n        // compute diff\n        double totalPos = 0, totalNeg = 0;\n        static double diff[105];\n        for (int i = 0; i < N; i++) {\n            diff[i] = curCounts[i] - (double)T[i];\n            if (diff[i] > 0) totalPos += diff[i];\n            else totalNeg += -diff[i];\n        }\n        if (totalPos < 1e-9 || totalNeg < 1e-9) break;\n        int s = rng.next_int(0, N - 1);\n        // pick target underfilled\n        double rtar = (double)(rng.next()) / (double)UINT64_MAX * totalNeg;\n        double accn = 0;\n        int under = 0;\n        for (; under < N; under++) {\n            if (diff[under] < 0) {\n                accn += -diff[under];\n                if (accn >= rtar) break;\n            }\n        }\n        if (under >= N) under = rng.next_int(0, N - 1);\n        int edgeIdx = rng.next_int(0, 1);\n        vector<int> tempA = curA, tempB = curB;\n        if (edgeIdx == 0) tempA[s] = under;\n        else tempB[s] = under;\n        double err = approx_error(tempA, tempB, &tmpCounts);\n        if (err + 1e-6 < curErr) {\n            curErr = err;\n            curA.swap(tempA);\n            curB.swap(tempB);\n            curCounts.swap(tmpCounts);\n            updateTop(curA, curB, curErr);\n            if (err < bestApproxErr) {\n                bestApproxErr = err;\n                bestA = curA;\n                bestB = curB;\n                bestApproxCounts = curCounts;\n            }\n        }\n    }\n\n    // evaluate actual errors for top candidates\n    long long bestActualErr = (1LL << 60);\n    vector<int> bestActualA = bestA, bestActualB = bestB;\n    vector<int> bestActualCnt;\n    for (auto& c : topList) {\n        vector<int> cnt;\n        long long e = simulate(c.a, c.b, &cnt);\n        if (e < bestActualErr) {\n            bestActualErr = e;\n            bestActualA = c.a;\n            bestActualB = c.b;\n            bestActualCnt = cnt;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << bestActualA[i] << ' ' << bestActualB[i] << '\\n';\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// XorShift random\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    inline uint64_t rng() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int randint(int l, int r) { // [l, r)\n        return (int)(rng() % (uint64_t)(r - l)) + l;\n    }\n    inline double rand01() {\n        return (double)(rng() & 0xFFFFFFFFULL) / 4294967296.0;\n    }\n} rnd;\n\n// DSU\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\n// Hilbert order\nuint64_t hilbertOrder(int x, int y, int order_bits, int max_coord) {\n    uint64_t d = 0;\n    for (int s = order_bits - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        d <<= 2;\n        d |= (uint64_t)((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) {\n                x = max_coord - x;\n                y = max_coord - y;\n            }\n            int t = x; x = y; y = t;\n        }\n    }\n    return d;\n}\n\n// Prim cost using precomputed dist matrix\ndouble primCost(const vector<int>& nodes, const vector<float>& distMat, int N) {\n    int n = (int)nodes.size();\n    if (n <= 1) return 0.0;\n    vector<float> minD(n, 1e30f);\n    vector<char> used(n, 0);\n    minD[0] = 0.0f;\n    double cost = 0.0;\n    for (int it = 0; it < n; ++it) {\n        int v = -1;\n        float best = 1e30f;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        cost += minD[v];\n        int idv = nodes[v];\n        int base = idv * N;\n        for (int i = 0; i < n; ++i) if (!used[i]) {\n            int idu = nodes[i];\n            float d = distMat[base + idu];\n            if (d < minD[i]) minD[i] = d;\n        }\n    }\n    return cost;\n}\n\n// Prim edges using dist matrix\nvector<pair<int,int>> primEdges(const vector<int>& nodes, const vector<float>& distMat, int N) {\n    int n = (int)nodes.size();\n    if (n <= 1) return {};\n    vector<float> minD(n, 1e30f);\n    vector<int> parent(n, -1);\n    vector<char> used(n, 0);\n    minD[0] = 0.0f;\n    for (int it = 0; it < n; ++it) {\n        int v = -1;\n        float best = 1e30f;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        int idv = nodes[v];\n        int base = idv * N;\n        for (int i = 0; i < n; ++i) if (!used[i]) {\n            int idu = nodes[i];\n            float d = distMat[base + idu];\n            if (d < minD[i]) {\n                minD[i] = d;\n                parent[i] = v;\n            }\n        }\n    }\n    vector<pair<int,int>> edges;\n    edges.reserve(n-1);\n    for (int i = 1; i < n; ++i) edges.emplace_back(nodes[i], nodes[parent[i]]);\n    return edges;\n}\n\n// nearest neighbor order\nvector<int> nearestNeighborOrder(int N, const vector<float>& distMat) {\n    vector<int> order;\n    order.reserve(N);\n    vector<char> used(N, 0);\n    int cur = 0;\n    used[cur] = 1;\n    order.push_back(cur);\n    for (int step = 1; step < N; ++step) {\n        int best = -1;\n        float bestd = 1e30f;\n        int base = cur * N;\n        for (int i = 0; i < N; ++i) {\n            if (used[i]) continue;\n            float d = distMat[base + i];\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        cur = best;\n        used[cur] = 1;\n        order.push_back(cur);\n    }\n    return order;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    vector<double> px(N), py(N);\n    for (int i = 0; i < N; ++i) {\n        px[i] = (lx[i] + rx[i]) * 0.5;\n        py[i] = (ly[i] + ry[i]) * 0.5;\n    }\n\n    // distance matrix\n    vector<float> distMat(N * N);\n    for (int i = 0; i < N; ++i) {\n        distMat[i * N + i] = 0.0f;\n        for (int j = i + 1; j < N; ++j) {\n            double dx = px[i] - px[j];\n            double dy = py[i] - py[j];\n            float d = (float)std::sqrt(dx * dx + dy * dy);\n            distMat[i * N + j] = d;\n            distMat[j * N + i] = d;\n        }\n    }\n\n    const int order_bits = 15;\n    const int max_coord = (1 << order_bits) - 1;\n\n    vector<vector<int>> candidates;\n\n    // Hilbert variants\n    for (int variant = 0; variant < 5; ++variant) {\n        vector<pair<uint64_t,int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            int x = (int)px[i];\n            int y = (int)py[i];\n            switch (variant) {\n                case 0: break;\n                case 1: x = max_coord - x; break;\n                case 2: y = max_coord - y; break;\n                case 3: x = max_coord - x; y = max_coord - y; break;\n                case 4: { int t=x; x=y; y=t; } break;\n            }\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b){ return a.first < b.first; });\n        vector<int> ord;\n        ord.reserve(N);\n        for (auto& p : keys) ord.push_back(p.second);\n        candidates.push_back(move(ord));\n    }\n    // random jitter hilbert\n    for (int rep = 0; rep < 3; ++rep) {\n        vector<pair<uint64_t,int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            double nx = px[i] + (rnd.rand01() - 0.5) * W * 0.3;\n            double ny = py[i] + (rnd.rand01() - 0.5) * W * 0.3;\n            int x = max(0, min(max_coord, (int)nx));\n            int y = max(0, min(max_coord, (int)ny));\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b){ return a.first < b.first; });\n        vector<int> ord;\n        ord.reserve(N);\n        for (auto& p : keys) ord.push_back(p.second);\n        candidates.push_back(move(ord));\n    }\n    // simple sorts\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b){\n            if (px[a]==px[b]) return py[a]<py[b];\n            return px[a]<px[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b){\n            if (py[a]==py[b]) return px[a]<px[b];\n            return py[a]<py[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b){\n            double va=px[a]+py[a], vb=px[b]+py[b];\n            if (va==vb) {\n                if (px[a]==px[b]) return py[a]<py[b];\n                return px[a]<px[b];\n            }\n            return va<vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b){\n            double va=px[a]-py[a], vb=px[b]-py[b];\n            if (va==vb) {\n                if (px[a]==px[b]) return py[a]<py[b];\n                return px[a]<px[b];\n            }\n            return va<vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    candidates.push_back(nearestNeighborOrder(N, distMat));\n\n    auto evalCost = [&](const vector<int>& order)->double{\n        double total=0.0;\n        int pos=0;\n        for (int k=0;k<M;++k){\n            int g=G[k];\n            vector<int> grp;\n            grp.reserve(g);\n            for (int t=0;t<g;++t) grp.push_back(order[pos+t]);\n            pos+=g;\n            total += primCost(grp, distMat, N);\n        }\n        return total;\n    };\n\n    double bestInit = 1e100;\n    int bestIdx = 0;\n    for (int i = 0; i < (int)candidates.size(); ++i) {\n        double c = evalCost(candidates[i]);\n        if (c < bestInit) {\n            bestInit = c;\n            bestIdx = i;\n        }\n    }\n    const vector<int>& initOrder = candidates[bestIdx];\n\n    // initial groups\n    vector<vector<int>> groups(M);\n    int pos=0;\n    for (int k=0;k<M;++k){\n        int g=G[k];\n        groups[k].reserve(g);\n        for (int t=0;t<g;++t) groups[k].push_back(initOrder[pos+t]);\n        pos+=g;\n    }\n\n    // neighbor list for SA\n    const int KNEI = 30;\n    vector<vector<int>> neigh(N);\n    vector<int> tmp(N);\n    for (int i = 0; i < N; ++i) {\n        for (int j=0;j<N;++j) tmp[j]=j;\n        sort(tmp.begin(), tmp.end(), [&](int a,int b){\n            return distMat[i*N+a] < distMat[i*N+b];\n        });\n        neigh[i].reserve(KNEI);\n        for (int t=1;t<=KNEI;++t) neigh[i].push_back(tmp[t]); // skip itself\n    }\n\n    vector<double> groupCost(M,0.0);\n    double totalCost=0.0;\n    for (int k=0;k<M;++k){\n        double c=primCost(groups[k], distMat, N);\n        groupCost[k]=c;\n        totalCost+=c;\n    }\n    vector<vector<int>> bestGroups=groups;\n    double bestCost=totalCost;\n\n    auto startAll = chrono::steady_clock::now();\n    double timeLimit = 0.9; // seconds\n    const double T0=30.0, Tend=1e-3;\n    while (true) {\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-startAll).count();\n        if (elapsed > timeLimit) break;\n        double t=elapsed/timeLimit;\n        double T=exp(log(T0)*(1.0-t)+log(Tend)*t);\n\n        int va;\n        int vb;\n        if (rnd.rand01() < 0.7) {\n            va = rnd.randint(0, N);\n            int nb = rnd.randint(0, KNEI);\n            vb = neigh[va][nb];\n        } else {\n            int ga = rnd.randint(0, M);\n            if (groups[ga].empty()) continue;\n            int gb = rnd.randint(0, M);\n            if (groups[gb].empty()) continue;\n            va = groups[ga][rnd.randint(0, (int)groups[ga].size())];\n            vb = groups[gb][rnd.randint(0, (int)groups[gb].size())];\n        }\n        // find groups\n        int ga = -1, gb = -1;\n        for (int k=0;k<M;++k){\n            // small linear search not good; build map? we can build belong array\n        }\n        // build belong array once\n        break;\n    }\n    // Build belong array for faster lookup\n    vector<int> belong(N,-1);\n    for (int k=0;k<M;++k){\n        for (int v:groups[k]) belong[v]=k;\n    }\n    // re-run SA with belong\n    startAll = chrono::steady_clock::now();\n    while (true) {\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-startAll).count();\n        if (elapsed > timeLimit) break;\n        double t=elapsed/timeLimit;\n        double T=exp(log(T0)*(1.0-t)+log(Tend)*t);\n\n        int va, vb;\n        int ga, gb;\n        if (rnd.rand01() < 0.7) {\n            va = rnd.randint(0, N);\n            int nb = rnd.randint(0, KNEI);\n            vb = neigh[va][nb];\n            ga = belong[va];\n            gb = belong[vb];\n            if (ga == gb) continue;\n        } else {\n            ga = rnd.randint(0, M);\n            gb = rnd.randint(0, M);\n            if (ga == gb || groups[ga].empty() || groups[gb].empty()) continue;\n            va = groups[ga][rnd.randint(0, (int)groups[ga].size())];\n            vb = groups[gb][rnd.randint(0, (int)groups[gb].size())];\n        }\n        // perform swap\n        auto &A = groups[ga];\n        auto &B = groups[gb];\n        int ia = -1, ib = -1;\n        for (int i=0;i<(int)A.size();++i) if (A[i]==va){ ia=i; break;}\n        for (int i=0;i<(int)B.size();++i) if (B[i]==vb){ ib=i; break;}\n        if (ia<0 || ib<0) continue;\n        A[ia]=vb;\n        B[ib]=va;\n\n        double oldSum = groupCost[ga]+groupCost[gb];\n        double newA = primCost(A, distMat, N);\n        double newB = primCost(B, distMat, N);\n        double newSum = newA+newB;\n        double delta = newSum - oldSum;\n        bool accept = false;\n        if (delta < 0) accept = true;\n        else {\n            double prob = exp(-delta / T);\n            if (rnd.rand01() < prob) accept = true;\n        }\n        if (accept) {\n            groupCost[ga]=newA;\n            groupCost[gb]=newB;\n            totalCost += delta;\n            belong[va]=gb;\n            belong[vb]=ga;\n            if (totalCost < bestCost) {\n                bestCost = totalCost;\n                bestGroups = groups;\n            }\n        } else {\n            // revert\n            A[ia]=va;\n            B[ib]=vb;\n        }\n    }\n\n    groups.swap(bestGroups);\n\n    // sort each group by hilbert for queries/MST\n    vector<vector<int>> sortedGroups(M);\n    for (int k=0;k<M;++k){\n        auto &g=groups[k];\n        vector<pair<uint64_t,int>> keys;\n        keys.reserve(g.size());\n        for (int v: g) {\n            int x=(int)px[v], y=(int)py[v];\n            uint64_t h=hilbertOrder(x,y,order_bits,max_coord);\n            keys.emplace_back(h,v);\n        }\n        sort(keys.begin(), keys.end(), [](auto&a,auto&b){return a.first<b.first;});\n        for (auto&p:keys) sortedGroups[k].push_back(p.second);\n    }\n    groups.swap(sortedGroups);\n\n    // plan queries\n    vector<vector<pair<int,int>>> queryEdges(M);\n    int queries_used=0;\n\n    vector<int> groupOrder(M);\n    iota(groupOrder.begin(), groupOrder.end(), 0);\n    // prioritize small groups first\n    for (int pass=0; pass<2; ++pass) {\n        for (int k : groupOrder) {\n            int sz = (int)groups[k].size();\n            if (sz <= 1) continue;\n            if (pass==0 && sz> L) continue; // first pass small only\n            if (pass==1 && sz<=L) continue;\n            int need;\n            if (sz <= L) need = 1;\n            else need = (sz - 2) / (L - 1) + 1; // ceil((sz-1)/(L-1))\n            int remain = Q - queries_used;\n            if (remain <= 0) break;\n            int use = min(need, remain);\n            if (use <= 0) continue;\n\n            vector<int> &nodes = groups[k];\n            int gsz = nodes.size();\n            vector<vector<int>> windows;\n            if (use == 1) {\n                if (gsz <= L) {\n                    windows.push_back(nodes);\n                } else {\n                    vector<int> win;\n                    for (int i=0;i<L;++i) win.push_back(nodes[i]);\n                    windows.push_back(move(win));\n                }\n            } else {\n                double stepd = (double)(gsz - L) / (use - 1);\n                for (int i=0;i<use;++i) {\n                    int start = (int)round(i * stepd);\n                    if (start > gsz - L) start = gsz - L;\n                    if (start < 0) start = 0;\n                    int len = min(L, gsz - start);\n                    if (len < 2) continue;\n                    vector<int> win;\n                    win.reserve(len);\n                    for (int j=0;j<len;++j) win.push_back(nodes[start+j]);\n                    windows.push_back(move(win));\n                }\n            }\n            for (auto &win : windows) {\n                if (queries_used >= Q) break;\n                int l = win.size();\n                if (l < 2) continue;\n                cout << \"? \" << l;\n                for (int v: win) cout << ' ' << v;\n                cout << endl;\n                queries_used++;\n                for (int i=0;i<l-1;++i){\n                    int a,b;\n                    if (!(cin >> a >> b)) return 0;\n                    queryEdges[k].emplace_back(a,b);\n                }\n            }\n        }\n    }\n\n    // build final edges\n    vector<vector<pair<int,int>>> finalEdges(M);\n    vector<int> idxMap(N, -1);\n    for (int k=0;k<M;++k){\n        auto &nodes = groups[k];\n        int gsz = nodes.size();\n        if (gsz <= 1) continue;\n        for (int i=0;i<gsz;++i) idxMap[nodes[i]]=i;\n        DSU uf(gsz);\n        vector<pair<int,int>> chosen;\n        chosen.reserve(gsz-1);\n        // add query edges first\n        for (auto &e : queryEdges[k]) {\n            int a=e.first, b=e.second;\n            int ia=idxMap[a], ib=idxMap[b];\n            if (ia<0 || ib<0) continue;\n            if (uf.unite(ia,ib)) chosen.push_back(e);\n        }\n        // add predicted MST edges\n        auto preds = primEdges(nodes, distMat, N);\n        for (auto &e : preds) {\n            if ((int)chosen.size() >= gsz-1) break;\n            int ia=idxMap[e.first], ib=idxMap[e.second];\n            if (uf.unite(ia,ib)) chosen.push_back(e);\n        }\n        finalEdges[k]=move(chosen);\n        for (int v: nodes) idxMap[v]=-1;\n    }\n\n    // output\n    cout << \"!\\n\";\n    for (int k=0;k<M;++k){\n        auto &nodes = groups[k];\n        for (int i=0;i<(int)nodes.size();++i){\n            if (i) cout << ' ';\n            cout << nodes[i];\n        }\n        cout << '\\n';\n        for (auto &e: finalEdges[k]){\n            cout << e.first << ' ' << e.second << '\\n';\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1e9;\nint N, M;\nvector<int> idxs;\nvector<pair<int, int>> pos;\nvector<int> dr = {-1, 1, 0, 0};\nvector<int> dc = {0, 0, -1, 1};\nvector<char> dirChar = {'U', 'D', 'L', 'R'};\nvector<char> isTarget;  // size N*N\n\ninline int slide_stop(int r, int c, int dir, const vector<char> &blocked) {\n    int nr = r, nc = c;\n    while (true) {\n        int tr = nr + dr[dir], tc = nc + dc[dir];\n        if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n        if (blocked[tr * N + tc]) break;\n        nr = tr;\n        nc = tc;\n    }\n    return nr * N + nc;\n}\n\nint dist_between(int s, int g, const vector<char> &blocked) {\n    if (blocked[s] || blocked[g]) return INF;\n    static vector<int> dist;\n    static queue<int> q;\n    if ((int)dist.size() != N * N) dist.resize(N * N);\n    fill(dist.begin(), dist.end(), -1);\n    while (!q.empty()) q.pop();\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front();\n        q.pop();\n        int d = dist[v];\n        if (v == g) return d;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = d + 1;\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = d + 1;\n                q.push(sid);\n            }\n        }\n    }\n    return INF;\n}\n\nvector<pair<char, char>> path_between(int s, int g, const vector<char> &blocked) {\n    vector<int> dist(N * N, -1), prev(N * N, -1);\n    vector<char> prevAct(N * N), prevDir(N * N);\n    queue<int> q;\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front();\n        q.pop();\n        if (v == g) break;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'M';\n                    prevDir[ni] = dirChar[dir];\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = dist[v] + 1;\n                prev[sid] = v;\n                prevAct[sid] = 'S';\n                prevDir[sid] = dirChar[dir];\n                q.push(sid);\n            }\n        }\n    }\n    vector<pair<char, char>> actions;\n    if (dist[g] == -1) return actions;  // unreachable\n    int cur = g;\n    while (cur != s) {\n        actions.push_back({prevAct[cur], prevDir[cur]});\n        cur = prev[cur];\n    }\n    reverse(actions.begin(), actions.end());\n    return actions;\n}\n\n// Adjacent candidate cells per target index\nvector<vector<int>> adjCells;\n\n// evaluate cost of a plan (boolean array size N*N)\nint evaluate_plan(const vector<char> &plan) {\n    vector<char> blocked(N * N, false);\n    int cost = 0;\n    for (int t = 0; t < M - 1; t++) {\n        // place planned blocks adjacent to current target\n        for (int idx : adjCells[t]) {\n            if (plan[idx] && !blocked[idx]) {\n                blocked[idx] = true;\n                cost += 1;  // alter action\n            }\n        }\n        int d = dist_between(idxs[t], idxs[t + 1], blocked);\n        if (d >= INF / 2) return INF;\n        cost += d;\n    }\n    return cost;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> M)) return 0;\n    pos.resize(M);\n    idxs.resize(M);\n    isTarget.assign(N * N, false);\n    for (int k = 0; k < M; k++) {\n        int r, c;\n        cin >> r >> c;\n        pos[k] = {r, c};\n        idxs[k] = r * N + c;\n        isTarget[idxs[k]] = true;\n    }\n\n    adjCells.assign(M, {});\n    vector<char> isCandidate(N * N, false);\n    for (int t = 0; t < M - 1; t++) {  // last target has no outgoing edge\n        int r = pos[t].first, c = pos[t].second;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int idx = nr * N + nc;\n                if (isTarget[idx]) continue;\n                adjCells[t].push_back(idx);\n                isCandidate[idx] = true;\n            }\n        }\n    }\n\n    vector<int> candidates;\n    for (int i = 0; i < N * N; i++) {\n        if (isCandidate[i] && !isTarget[i]) candidates.push_back(i);\n    }\n\n    vector<char> plan(N * N, false);\n    int bestCost = evaluate_plan(plan);\n    vector<char> bestPlan = plan;\n    int curCost = bestCost;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> urd(0.0, 1.0);\n\n    auto start = chrono::steady_clock::now();\n    const double timeLimit = 1.2;  // seconds for optimization\n    int iter = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > timeLimit) break;\n        iter++;\n        int ci = candidates[rng() % candidates.size()];\n        plan[ci] = !plan[ci];\n        int newCost = evaluate_plan(plan);\n        int diff = newCost - curCost;\n        double temp = 1.0 - elapsed / timeLimit;\n        temp = max(temp, 0.01);\n        if (diff <= 0 || exp(-diff / temp) > urd(rng)) {\n            curCost = newCost;\n            if (newCost < bestCost) {\n                bestCost = newCost;\n                bestPlan = plan;\n            }\n        } else {\n            plan[ci] = !plan[ci];\n        }\n    }\n\n    // Use bestPlan\n    plan = bestPlan;\n    if (bestCost >= INF / 2) {\n        fill(plan.begin(), plan.end(), false);\n    }\n\n    vector<char> blocked(N * N, false);\n    vector<pair<char, char>> actions;\n\n    for (int t = 0; t < M - 1; t++) {\n        int r = pos[t].first, c = pos[t].second;\n        // place planned blocks adjacent to current target\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int idx = nr * N + nc;\n                if (plan[idx] && !blocked[idx]) {\n                    actions.push_back({'A', dirChar[dir]});\n                    blocked[idx] = true;\n                }\n            }\n        }\n        int cur = idxs[t];\n        int nxt = idxs[t + 1];\n        int curDist = dist_between(cur, nxt, blocked);\n        // local greedy toggle for immediate next move (skip planned cells and targets)\n        while (true) {\n            int bestGain = 0;\n            int bestDir = -1;\n            bool bestPlace = true;\n            int bestNewDist = curDist;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r + dr[dir], nc = c + dc[dir];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                int idx = nr * N + nc;\n                if (isTarget[idx]) continue;\n                if (plan[idx]) continue;  // don't toggle planned cells\n                if (!blocked[idx]) {\n                    blocked[idx] = true;\n                    int nd = dist_between(cur, nxt, blocked);\n                    blocked[idx] = false;\n                    if (nd < INF / 2) {\n                        int gain = curDist - (1 + nd);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = true;\n                            bestNewDist = nd;\n                        }\n                    }\n                } else {  // remove\n                    blocked[idx] = false;\n                    int nd = dist_between(cur, nxt, blocked);\n                    blocked[idx] = true;\n                    if (nd < INF / 2) {\n                        int gain = curDist - (1 + nd);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = false;\n                            bestNewDist = nd;\n                        }\n                    }\n                }\n            }\n            if (bestGain > 0 && bestDir != -1) {\n                actions.push_back({'A', dirChar[bestDir]});\n                int idx = (r + dr[bestDir]) * N + (c + dc[bestDir]);\n                blocked[idx] = bestPlace;\n                curDist = bestNewDist;\n            } else {\n                break;\n            }\n        }\n        // move to next target\n        auto path = path_between(cur, nxt, blocked);\n        actions.insert(actions.end(), path.begin(), path.end());\n    }\n\n    for (auto &p : actions) {\n        cout << p.first << ' ' << p.second << '\\n';\n    }\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nstruct Move {\n    double diff;\n    int dir;\n    int len;\n    Move(double _d = 0.0, int _dir = -1, int _len = 0) : diff(_d), dir(_dir), len(_len) {}\n};\n\nint n;\nvector<int> x_coord, y_coord;\nvector<long long> r_target;\nvector<Rect> rects;\n\ninline long long area(const Rect &rc) {\n    return 1LL * (rc.c - rc.a) * (rc.d - rc.b);\n}\n\ninline double compute_p_val(long long ri, long long s) {\n    double mn = (double)min(ri, s);\n    double mx = (double)max(ri, s);\n    double diff = 1.0 - mn / mx;\n    return 1.0 - diff * diff;\n}\n\n// compute maximum expandable length in 4 directions without overlap\nvoid compute_max_expands(int idx, int &left, int &right, int &up, int &down) {\n    const Rect &ri = rects[idx];\n    left = ri.a;\n    right = 10000 - ri.c;\n    up = ri.b;\n    down = 10000 - ri.d;\n    for (int j = 0; j < n; j++) if (j != idx) {\n        const Rect &rj = rects[j];\n        // vertical overlap\n        if (rj.b < ri.d && rj.d > ri.b) {\n            if (rj.c <= ri.a) {\n                int cand = ri.a - rj.c;\n                if (cand < left) left = cand;\n            }\n            if (rj.a >= ri.c) {\n                int cand = rj.a - ri.c;\n                if (cand < right) right = cand;\n            }\n        }\n        // horizontal overlap\n        if (rj.a < ri.c && rj.c > ri.a) {\n            if (rj.d <= ri.b) {\n                int cand = ri.b - rj.d;\n                if (cand < up) up = cand;\n            }\n            if (rj.b >= ri.d) {\n                int cand = rj.b - ri.d;\n                if (cand < down) down = cand;\n            }\n        }\n    }\n}\n\nMove find_best_expand(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s >= rt) return best;\n\n    int left, right, up, down;\n    compute_max_expands(idx, left, right, up, down);\n    int maxLens[4] = {left, right, up, down};\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(rt - s) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\nMove find_best_contract(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s <= rt) return best;\n\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int maxLens[4] = {\n        min(x_coord[idx] - rc.a, w - 1),                // shrink left\n        min(rc.c - (x_coord[idx] + 1), w - 1),          // shrink right\n        min(y_coord[idx] - rc.b, h - 1),                // shrink up\n        min(rc.d - (y_coord[idx] + 1), h - 1)           // shrink down\n    };\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n    int deltas[4] = {h, h, w, w};\n\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(s - rt) / (double)delta;\n        int cand[5];\n        int cc = 0;\n        auto add = [&](int l) {\n            if (l > 0 && l <= maxLen) cand[cc++] = l;\n        };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf);\n        add(lc);\n        add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff;\n                best.dir = dir;\n                best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\ninline void apply_move(int idx, const Move &mv, bool expand) {\n    if (mv.dir < 0 || mv.len <= 0) return;\n    Rect &rc = rects[idx];\n    int l = mv.len;\n    if (expand) {\n        if (mv.dir == 0) rc.a -= l;\n        else if (mv.dir == 1) rc.c += l;\n        else if (mv.dir == 2) rc.b -= l;\n        else rc.d += l;\n    } else {\n        if (mv.dir == 0) rc.a += l;\n        else if (mv.dir == 1) rc.c -= l;\n        else if (mv.dir == 2) rc.b += l;\n        else rc.d -= l;\n    }\n}\n\n// Adjust shared vertical edge between two rectangles with same height, rect L on left of R\nbool adjust_vertical_edge(int L, int R) {\n    Rect &A = rects[L];\n    Rect &B = rects[R];\n    int H = A.d - A.b;\n    if (H <= 0) return false;\n    long long sA0 = 1LL * (A.c - A.a) * H;\n    long long sB0 = 1LL * (B.c - B.a) * H;\n    int x0 = A.c; // shared edge\n    int low = max(A.a + 1, x_coord[L] + 1);\n    int high = min(B.c - 1, x_coord[R]);\n    if (low > high) return false;\n\n    auto eval = [&](int xx) -> double {\n        if (xx < low || xx > high) return -1e30;\n        long long sA = sA0 + 1LL * (xx - x0) * H;\n        long long sB = sB0 - 1LL * (xx - x0) * H;\n        double pA = compute_p_val(r_target[L], sA);\n        double pB = compute_p_val(r_target[R], sB);\n        return pA + pB;\n    };\n\n    double cur = eval(x0);\n    double bestVal = cur;\n    int bestX = x0;\n    vector<int> cand;\n    cand.reserve(8);\n    cand.push_back(low);\n    cand.push_back(high);\n    double tA = x0 + (double)(r_target[L] - sA0) / (double)H;\n    double tB = x0 - (double)(r_target[R] - sB0) / (double)H;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA);  if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB);  if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int xx : cand) {\n        double val = eval(xx);\n        if (val > bestVal + EPS) {\n            bestVal = val;\n            bestX = xx;\n        }\n    }\n    if (bestX != x0) {\n        int dx = bestX - x0;\n        A.c += dx;\n        B.a += dx;\n        return true;\n    }\n    return false;\n}\n\n// Adjust shared horizontal edge between two rectangles with same width, rect U below D\nbool adjust_horizontal_edge(int U, int D) {\n    Rect &A = rects[U]; // lower\n    Rect &B = rects[D]; // upper\n    int W = A.c - A.a;\n    if (W <= 0) return false;\n    long long sA0 = 1LL * (A.d - A.b) * W;\n    long long sB0 = 1LL * (B.d - B.b) * W;\n    int y0 = A.d; // shared edge\n    int low = max(A.b + 1, y_coord[U] + 1);\n    int high = min(B.d - 1, y_coord[D]);\n    if (low > high) return false;\n\n    auto eval = [&](int yy) -> double {\n        if (yy < low || yy > high) return -1e30;\n        long long sA = sA0 + 1LL * (yy - y0) * W;\n        long long sB = sB0 - 1LL * (yy - y0) * W;\n        double pA = compute_p_val(r_target[U], sA);\n        double pB = compute_p_val(r_target[D], sB);\n        return pA + pB;\n    };\n\n    double cur = eval(y0);\n    double bestVal = cur;\n    int bestY = y0;\n    vector<int> cand;\n    cand.reserve(8);\n    cand.push_back(low);\n    cand.push_back(high);\n    double tA = y0 + (double)(r_target[U] - sA0) / (double)W;\n    double tB = y0 - (double)(r_target[D] - sB0) / (double)W;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA);  if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB);  if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int yy : cand) {\n        double val = eval(yy);\n        if (val > bestVal + EPS) {\n            bestVal = val;\n            bestY = yy;\n        }\n    }\n    if (bestY != y0) {\n        int dy = bestY - y0;\n        A.d += dy;\n        B.b += dy;\n        return true;\n    }\n    return false;\n}\n\ndouble compute_total_score() {\n    double tot = 0.0;\n    for (int i = 0; i < n; i++) {\n        tot += compute_p_val(r_target[i], area(rects[i]));\n    }\n    return tot;\n}\n\nvoid greedy_expand(const vector<int>& order) {\n    const double EPS = 1e-12;\n    for (int idx : order) {\n        for (int iter = 0; iter < 1000; iter++) {\n            Move mv = find_best_expand(idx);\n            if (mv.diff > EPS) {\n                apply_move(idx, mv, true);\n            } else break;\n        }\n    }\n}\n\nvoid improve_solution_loop(int max_outer, chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    const double EPS = 1e-12;\n    vector<int> idxs(n);\n    for (int outer = 0; outer < max_outer; outer++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        iota(idxs.begin(), idxs.end(), 0);\n        shuffle(idxs.begin(), idxs.end(), rng);\n        for (int id : idxs) {\n            double bestDiff = 0.0;\n            bool doExpand = false;\n            Move mvE = find_best_expand(id);\n            if (mvE.diff > bestDiff) {\n                bestDiff = mvE.diff;\n                doExpand = true;\n            }\n            Move mvC = find_best_contract(id);\n            if (mvC.diff > bestDiff) {\n                bestDiff = mvC.diff;\n                doExpand = false;\n            }\n            if (bestDiff > EPS) {\n                if (doExpand) apply_move(id, mvE, true);\n                else apply_move(id, mvC, false);\n                improved = true;\n            }\n        }\n        elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool pair_improved = false;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (rects[i].b == rects[j].b && rects[i].d == rects[j].d) {\n                    if (rects[i].c == rects[j].a) {\n                        if (adjust_vertical_edge(i, j)) pair_improved = true;\n                    } else if (rects[j].c == rects[i].a) {\n                        if (adjust_vertical_edge(j, i)) pair_improved = true;\n                    }\n                }\n                if (rects[i].a == rects[j].a && rects[i].c == rects[j].c) {\n                    if (rects[i].d == rects[j].b) {\n                        if (adjust_horizontal_edge(i, j)) pair_improved = true;\n                    } else if (rects[j].d == rects[i].b) {\n                        if (adjust_horizontal_edge(j, i)) pair_improved = true;\n                    }\n                }\n            }\n            elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        if (pair_improved) improved = true;\n        if (!improved) break;\n    }\n}\n\nvoid compute_max_contracts(int idx, int maxLens[4]) {\n    Rect &rc = rects[idx];\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    maxLens[0] = min(x_coord[idx] - rc.a, w - 1);\n    maxLens[1] = min(rc.c - (x_coord[idx] + 1), w - 1);\n    maxLens[2] = min(y_coord[idx] - rc.b, h - 1);\n    maxLens[3] = min(rc.d - (y_coord[idx] + 1), h - 1);\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n}\n\nvoid simulated_annealing(chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    double duration = TIME_LIMIT - elapsed - 0.08;\n    if (duration <= 0) return;\n    double sa_start = elapsed;\n    double sa_end = sa_start + duration;\n\n    double cur_score = compute_total_score();\n    double best_score = cur_score;\n    vector<Rect> best_rects = rects;\n\n    const double T0 = 0.6, T1 = 0.03;\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    uniform_int_distribution<int> dist_rect(0, n - 1);\n\n    int iter = 0;\n    while (true) {\n        iter++;\n        if ((iter & 0x3FF) == 0) {\n            double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (now > sa_end) break;\n        }\n        double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double t = (now - sa_start) / duration;\n        if (t < 0) t = 0; if (t > 1) t = 1;\n        double temp = T0 + (T1 - T0) * t;\n\n        int i = dist_rect(rng);\n        Rect &rc = rects[i];\n        long long s = area(rc);\n        long long rt = r_target[i];\n        double p_cur = compute_p_val(rt, s);\n\n        bool choose_expand;\n        if (s < rt) {\n            choose_expand = (urd(rng) < 0.75);\n        } else if (s > rt) {\n            choose_expand = (urd(rng) < 0.25);\n        } else {\n            choose_expand = (urd(rng) < 0.5);\n        }\n\n        if (choose_expand) {\n            int left, right, up, down;\n            compute_max_expands(i, left, right, up, down);\n            int maxLens[4] = {left, right, up, down};\n            int w = rc.c - rc.a;\n            int h = rc.d - rc.b;\n            int deltas[4] = {h, h, w, w};\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) if (maxLens[d] > 0) dirs.push_back(d);\n            if (dirs.empty()) continue;\n            int dir = dirs[rng() % dirs.size()];\n            int maxLen = maxLens[dir];\n            int delta = deltas[dir];\n            if (delta <= 0) continue;\n            double len_target = (rt > s) ? (double)(rt - s) / (double)delta : 1.0;\n            int l = (int)round(len_target);\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            int tweak = (int)(urd(rng) * 5.0) - 2; // -2..2\n            l += tweak;\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            bool accept = diff >= 0 || urd(rng) < exp(diff / temp);\n            if (accept) {\n                if (dir == 0) rc.a -= l;\n                else if (dir == 1) rc.c += l;\n                else if (dir == 2) rc.b -= l;\n                else rc.d += l;\n                cur_score += diff;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_rects = rects;\n                }\n            }\n        } else {\n            int w = rc.c - rc.a;\n            int h = rc.d - rc.b;\n            if (w <= 1 && h <= 1) continue;\n            int maxLens[4];\n            compute_max_contracts(i, maxLens);\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) if (maxLens[d] > 0) dirs.push_back(d);\n            if (dirs.empty()) continue;\n            int dir = dirs[rng() % dirs.size()];\n            int maxLen = maxLens[dir];\n            int delta = (dir < 2) ? h : w;\n            if (delta <= 0) continue;\n            double len_target = (s > rt) ? (double)(s - rt) / (double)delta : 1.0;\n            int l = (int)round(len_target);\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            int tweak = (int)(urd(rng) * 5.0) - 2;\n            l += tweak;\n            if (l < 1) l = 1;\n            if (l > maxLen) l = maxLen;\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            bool accept = diff >= 0 || urd(rng) < exp(diff / temp);\n            if (accept) {\n                if (dir == 0) rc.a += l;\n                else if (dir == 1) rc.c -= l;\n                else if (dir == 2) rc.b += l;\n                else rc.d -= l;\n                cur_score += diff;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    best_rects = rects;\n                }\n            }\n        }\n    }\n    rects = best_rects;\n}\n\n// compute limits along anchor row/column ignoring rectangle i\nvoid compute_anchor_limits(int idx, int &left_lim, int &right_lim, int &up_lim, int &down_lim) {\n    int xi = x_coord[idx];\n    int yi = y_coord[idx];\n    left_lim = xi;\n    right_lim = 10000 - (xi + 1);\n    up_lim = yi;\n    down_lim = 10000 - (yi + 1);\n    for (int j = 0; j < n; j++) if (j != idx) {\n        const Rect &rj = rects[j];\n        if (rj.b < yi + 1 && rj.d > yi) { // overlaps anchor row\n            if (rj.c <= xi) {\n                int d = xi - rj.c;\n                if (d < left_lim) left_lim = d;\n            }\n            if (rj.a >= xi + 1) {\n                int d = rj.a - (xi + 1);\n                if (d < right_lim) right_lim = d;\n            }\n        }\n        if (rj.a < xi + 1 && rj.c > xi) { // overlaps anchor column\n            if (rj.d <= yi) {\n                int d = yi - rj.d;\n                if (d < up_lim) up_lim = d;\n            }\n            if (rj.b >= yi + 1) {\n                int d = rj.b - (yi + 1);\n                if (d < down_lim) down_lim = d;\n            }\n        }\n    }\n}\n\nbool overlap_with_others(const Rect &cand, int skip) {\n    for (int j = 0; j < n; j++) if (j != skip) {\n        const Rect &rj = rects[j];\n        if (cand.a < rj.c && cand.c > rj.a && cand.b < rj.d && cand.d > rj.b) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Randomly reassign worst rectangles to escape local minima\nvoid random_reassign_worst(chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    double remaining = TIME_LIMIT - chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    if (remaining < 0.1) return;\n    vector<pair<double,int>> vals;\n    vals.reserve(n);\n    for (int i = 0; i < n; i++) {\n        double p = compute_p_val(r_target[i], area(rects[i]));\n        vals.emplace_back(p, i);\n    }\n    sort(vals.begin(), vals.end()); // ascending by p\n    int k = min(30, n);\n    uniform_real_distribution<double> urd(0.5, 1.5);\n    for (int idx = 0; idx < k; idx++) {\n        double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (now > TIME_LIMIT - 0.05) break;\n        int i = vals[idx].second;\n        double pcur = vals[idx].first;\n        int left_lim, right_lim, up_lim, down_lim;\n        compute_anchor_limits(i, left_lim, right_lim, up_lim, down_lim);\n        int maxW = left_lim + right_lim + 1;\n        int maxH = up_lim + down_lim + 1;\n        if (maxW <= 0 || maxH <= 0) continue;\n        int samples = 80;\n        for (int s = 0; s < samples; s++) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT - 0.05) break;\n            double fac = urd(rng);\n            int w = (int)llround(sqrt((double)r_target[i]) * fac);\n            if (w < 1) w = 1;\n            if (w > maxW) w = maxW;\n            int h = (int)((double)r_target[i] / w);\n            if (h < 1) h = 1;\n            if (h > maxH) h = maxH;\n            int L_min = max(0, w - 1 - right_lim);\n            int L_max = min(left_lim, w - 1);\n            if (L_min > L_max) continue;\n            int L = L_min + rng() % (L_max - L_min + 1);\n            int R = w - 1 - L;\n            int U_min = max(0, h - 1 - down_lim);\n            int U_max = min(up_lim, h - 1);\n            if (U_min > U_max) continue;\n            int U = U_min + rng() % (U_max - U_min + 1);\n            int D = h - 1 - U;\n            Rect cand{x_coord[i] - L, y_coord[i] - U, x_coord[i] - L + w, y_coord[i] - U + h};\n            if (cand.a < 0 || cand.b < 0 || cand.c > 10000 || cand.d > 10000) continue;\n            if (overlap_with_others(cand, i)) continue;\n            double p_new = compute_p_val(r_target[i], 1LL * w * h);\n            if (p_new > pcur + 1e-12) {\n                rects[i] = cand;\n                pcur = p_new;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> n)) return 0;\n    x_coord.resize(n);\n    y_coord.resize(n);\n    r_target.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        int xi, yi;\n        long long ri;\n        cin >> xi >> yi >> ri;\n        x_coord[i] = xi;\n        y_coord[i] = yi;\n        r_target[i] = ri;\n    }\n\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.9;\n    mt19937 rng(1234567);\n\n    vector<vector<int>> base_orders;\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return r_target[a] > r_target[b]; });\n    base_orders.push_back(order); // descending\n    sort(order.begin(), order.end(), [&](int a, int b) { return r_target[a] < r_target[b]; });\n    base_orders.push_back(order); // ascending\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (x_coord[a] != x_coord[b]) return x_coord[a] < x_coord[b];\n        return y_coord[a] < y_coord[b];\n    });\n    base_orders.push_back(order); // by x\n\n    double best_score = -1.0;\n    vector<Rect> best_rects;\n\n    auto elapsed = [&]() -> double {\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n\n    auto run_candidate = [&](const vector<int> &ord, int outer_limit, double time_cut)->void{\n        for (int i = 0; i < n; i++) {\n            rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n        }\n        greedy_expand(ord);\n        improve_solution_loop(outer_limit, start_time, time_cut, rng);\n        double sc = compute_total_score();\n        if (sc > best_score) {\n            best_score = sc;\n            best_rects = rects;\n        }\n    };\n\n    // Try base orders\n    for (auto &ord : base_orders) {\n        if (elapsed() > TIME_LIMIT * 0.35) break;\n        run_candidate(ord, 8, TIME_LIMIT * 0.5);\n    }\n\n    // Random restarts\n    while (elapsed() < TIME_LIMIT * 0.4) {\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        run_candidate(order, 6, TIME_LIMIT * 0.5);\n    }\n\n    if (!best_rects.empty()) rects = best_rects;\n    else {\n        for (int i = 0; i < n; i++) rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n    }\n\n    // Deep improvement\n    improve_solution_loop(20, start_time, TIME_LIMIT * 0.75, rng);\n    // Another greedy fill with descending order\n    sort(order.begin(), order.end(), [&](int a, int b){ return r_target[a] > r_target[b]; });\n    greedy_expand(order);\n    improve_solution_loop(10, start_time, TIME_LIMIT * 0.82, rng);\n\n    // Simulated annealing with remaining time\n    simulated_annealing(start_time, TIME_LIMIT * 0.95, rng);\n\n    // Random reassign worst rectangles if time remains\n    random_reassign_worst(start_time, TIME_LIMIT * 0.98, rng);\n\n    // Final polish\n    improve_solution_loop(5, start_time, TIME_LIMIT, rng);\n\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << ' ' << rects[i].b << ' ' << rects[i].c << ' ' << rects[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 50;\nconst int W = 50;\nconst int N = H * W;\n\nint Tcell[N];\nint Pcell[N];\n\nint nbCnt[N];\nint nbIdx[N][4];\nchar nbDir[N][4];\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nint startIdx;\nint tileCount;\n\nvector<int> visitedTile;\nint currentToken = 1;\n\nstruct XorShift {\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ULL) { x = seed; }\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int n) { return (int)(next() % n); }\n};\nXorShift rng;\n\nenum Mode { MIN_DEG = 0, MAX_DEG = 1, MAX_VALUE = 2 };\n\nstruct Param {\n    int avoidLevel; // -1 for no avoid, otherwise ignore deg<=avoidLevel if a higher deg exists\n    Mode mode;\n    int randProb; // 0..1023 chance to pick random move\n};\n\nstruct Path {\n    string moves;\n    int score;\n    int len;\n};\n\ninline int compute_deg(int idx) {\n    int tid = Tcell[idx];\n    int deg = 0;\n    for (int k = 0; k < nbCnt[idx]; k++) {\n        int nb = nbIdx[idx][k];\n        int nt = Tcell[nb];\n        if (nt == tid) continue;\n        if (visitedTile[nt] == currentToken) continue;\n        deg++;\n    }\n    return deg;\n}\n\nPath run_once(const Param &param) {\n    currentToken++;\n    if (currentToken == 0x3f3f3f3f) { // reset if overflowed\n        currentToken = 1;\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n    }\n    visitedTile[Tcell[startIdx]] = currentToken;\n    int cur = startIdx;\n    int score = Pcell[cur];\n    vector<char> mv;\n    mv.reserve(tileCount);\n    while (true) {\n        int candIdxArr[4];\n        char candDirArr[4];\n        int cnum = 0;\n        for (int k = 0; k < nbCnt[cur]; k++) {\n            int nb = nbIdx[cur][k];\n            if (visitedTile[Tcell[nb]] == currentToken) continue;\n            candIdxArr[cnum] = nb;\n            candDirArr[cnum] = nbDir[cur][k];\n            cnum++;\n        }\n        if (cnum == 0) break;\n\n        int chosen = -1;\n        if (param.randProb > 0 && ((rng.next() & 1023) < param.randProb)) {\n            chosen = rng.nextInt(cnum);\n        } else {\n            int degs[4];\n            int maxDeg = -1;\n            for (int i = 0; i < cnum; i++) {\n                degs[i] = compute_deg(candIdxArr[i]);\n                if (degs[i] > maxDeg) maxDeg = degs[i];\n            }\n            bool filtered = (param.avoidLevel >= 0 && maxDeg > param.avoidLevel);\n\n            if (param.mode == MIN_DEG) {\n                int bestDeg = 1e9, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    if (d < bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int v = Pcell[candIdxArr[i]];\n                        if (v > bestVal) {\n                            bestVal = v;\n                            chosen = i;\n                        } else if (v == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else if (param.mode == MAX_DEG) {\n                int bestDeg = -1, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    if (d > bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int v = Pcell[candIdxArr[i]];\n                        if (v > bestVal) {\n                            bestVal = v;\n                            chosen = i;\n                        } else if (v == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else { // MAX_VALUE\n                int bestVal = -1, bestDeg = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    int v = Pcell[candIdxArr[i]];\n                    if (v > bestVal) {\n                        bestVal = v;\n                        bestDeg = d;\n                        chosen = i;\n                    } else if (v == bestVal) {\n                        if (d > bestDeg) {\n                            bestDeg = d;\n                            chosen = i;\n                        } else if (d == bestDeg && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            }\n        }\n        if (chosen == -1) chosen = rng.nextInt(cnum);\n        int nxt = candIdxArr[chosen];\n        visitedTile[Tcell[nxt]] = currentToken;\n        score += Pcell[nxt];\n        mv.push_back(candDirArr[chosen]);\n        cur = nxt;\n    }\n    Path res;\n    res.score = score;\n    res.len = (int)mv.size() + 1;\n    res.moves.assign(mv.begin(), mv.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    int maxTid = -1;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Tcell[idx] = x;\n            if (x > maxTid) maxTid = x;\n        }\n    }\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Pcell[idx] = x;\n        }\n    }\n    tileCount = maxTid + 1;\n    visitedTile.assign(tileCount, 0);\n    startIdx = si * W + sj;\n\n    // Precompute neighbors\n    for (int r = 0; r < H; r++) {\n        for (int c = 0; c < W; c++) {\n            int idx = r * W + c;\n            int cnt = 0;\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 >= H || nc < 0 || nc >= W) continue;\n                nbIdx[idx][cnt] = nr * W + nc;\n                nbDir[idx][cnt] = dch[d];\n                cnt++;\n            }\n            nbCnt[idx] = cnt;\n        }\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    rng = XorShift(seed);\n\n    vector<Param> params = {\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 30},\n        {1, MIN_DEG, 0},\n        {1, MIN_DEG, 50},\n        {0, MAX_DEG, 0},\n        {0, MAX_DEG, 50},\n        {0, MAX_VALUE, 0},\n        {0, MAX_VALUE, 50},\n        {0, MIN_DEG, 200},\n        {2, MIN_DEG, 0},\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 0}\n    };\n\n    Path best;\n    best.score = -1;\n    best.len = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeLimit = startTime + chrono::milliseconds(1950);\n\n    size_t pidx = rng.nextInt((int)params.size());\n    while (chrono::steady_clock::now() < timeLimit) {\n        const Param &param = params[pidx];\n        pidx++;\n        if (pidx >= params.size()) pidx = 0;\n        Path curPath = run_once(param);\n        if (curPath.score > best.score || (curPath.score == best.score && curPath.len > best.len)) {\n            best = std::move(curPath);\n        }\n    }\n\n    cout << best.moves << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Neighbor {\n    int to;\n    int edge;\n    char dir;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int H = 30, W = 30;\n    const int N = H * W;\n    const int EH = H * (W - 1);\n    const int EV = (H - 1) * W;\n    const int E = EH + EV;\n\n    // index tables\n    int h_idx[H][W - 1];\n    int v_idx[H - 1][W];\n    int idx = 0;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            h_idx[i][j] = idx++;\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            v_idx[i][j] = idx++;\n        }\n    }\n\n    vector<vector<Neighbor>> adj(N);\n    // build graph\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            int e = h_idx[i][j];\n            int u = i * W + j;\n            int v = i * W + (j + 1);\n            adj[u].push_back({v, e, 'R'});\n            adj[v].push_back({u, e, 'L'});\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            int e = v_idx[i][j];\n            int u = i * W + j;\n            int v = (i + 1) * W + j;\n            adj[u].push_back({v, e, 'D'});\n            adj[v].push_back({u, e, 'U'});\n        }\n    }\n\n    vector<double> w(E, 5000.0);\n    vector<int> cnt(E, 0);\n\n    vector<int> rowSplit(H, -1), colSplit(W, -1);\n    vector<double> rowMeanAll(H, 5000.0), rowMeanL(H, 5000.0), rowMeanR(H, 5000.0);\n    vector<double> colMeanAll(W, 5000.0), colMeanT(W, 5000.0), colMeanB(W, 5000.0);\n\n    auto recompute_means_splits = [&](int qidx) {\n        double gSumH = 0.0, gSumV = 0.0;\n        int gCntH = 0, gCntV = 0;\n        for (int e = 0; e < EH; e++) if (cnt[e] > 0) { gSumH += w[e]; gCntH++; }\n        for (int e = EH; e < E; e++) if (cnt[e] > 0) { gSumV += w[e]; gCntV++; }\n        double gMeanH = gCntH ? gSumH / gCntH : 5000.0;\n        double gMeanV = gCntV ? gSumV / gCntV : 5000.0;\n\n        // rows\n        for (int i = 0; i < H; i++) {\n            vector<double> ps(W, 0.0);\n            vector<int> pc(W, 0);\n            for (int j = 0; j < W - 1; j++) {\n                ps[j + 1] = ps[j];\n                pc[j + 1] = pc[j];\n                int e = h_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[j + 1] += w[e];\n                    pc[j + 1] += 1;\n                }\n            }\n            double totalSum = ps[W - 1];\n            int totalCnt = pc[W - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanH;\n            rowMeanAll[i] = meanAll;\n            rowMeanL[i] = rowMeanR[i] = meanAll;\n            rowSplit[i] = -1;\n            if (totalCnt >= 4 && qidx >= 60) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int x = 1; x < W - 1; x++) {\n                    int lc = pc[x];\n                    int rc = totalCnt - lc;\n                    if (lc >= 2 && rc >= 2) {\n                        double ls = ps[x];\n                        double rs = totalSum - ls;\n                        double lm = ls / lc;\n                        double rm = rs / rc;\n                        double diff = fabs(lm - rm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = x;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 400.0) {\n                    rowSplit[i] = bestSplit;\n                    int lc = pc[bestSplit];\n                    int rc = totalCnt - lc;\n                    double ls = ps[bestSplit];\n                    double rs = totalSum - ls;\n                    rowMeanL[i] = lc ? ls / lc : meanAll;\n                    rowMeanR[i] = rc ? rs / rc : meanAll;\n                }\n            }\n        }\n\n        // columns\n        for (int j = 0; j < W; j++) {\n            vector<double> ps(H, 0.0);\n            vector<int> pc(H, 0);\n            for (int i = 0; i < H - 1; i++) {\n                ps[i + 1] = ps[i];\n                pc[i + 1] = pc[i];\n                int e = v_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[i + 1] += w[e];\n                    pc[i + 1] += 1;\n                }\n            }\n            double totalSum = ps[H - 1];\n            int totalCnt = pc[H - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanV;\n            colMeanAll[j] = meanAll;\n            colMeanT[j] = colMeanB[j] = meanAll;\n            colSplit[j] = -1;\n            if (totalCnt >= 4 && qidx >= 60) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int y = 1; y < H - 1; y++) {\n                    int tc = pc[y];\n                    int bc = totalCnt - tc;\n                    if (tc >= 2 && bc >= 2) {\n                        double ts = ps[y];\n                        double bs = totalSum - ts;\n                        double tm = ts / tc;\n                        double bm = bs / bc;\n                        double diff = fabs(tm - bm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = y;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 400.0) {\n                    colSplit[j] = bestSplit;\n                    int tc = pc[bestSplit];\n                    int bc = totalCnt - tc;\n                    double ts = ps[bestSplit];\n                    double bs = totalSum - ts;\n                    colMeanT[j] = tc ? ts / tc : meanAll;\n                    colMeanB[j] = bc ? bs / bc : meanAll;\n                }\n            }\n        }\n    };\n\n    auto smooth_edges = [&]() {\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W - 1; j++) {\n                int e = h_idx[i][j];\n                double pred = (rowSplit[i] == -1) ? rowMeanAll[i] : (j < rowSplit[i] ? rowMeanL[i] : rowMeanR[i]);\n                if (cnt[e] == 0) {\n                    w[e] = pred;\n                } else if (cnt[e] <= 2) {\n                    w[e] = 0.5 * w[e] + 0.5 * pred;\n                }\n            }\n        }\n        for (int j = 0; j < W; j++) {\n            for (int i = 0; i < H - 1; i++) {\n                int e = v_idx[i][j];\n                double pred = (colSplit[j] == -1) ? colMeanAll[j] : (i < colSplit[j] ? colMeanT[j] : colMeanB[j]);\n                if (cnt[e] == 0) {\n                    w[e] = pred;\n                } else if (cnt[e] <= 2) {\n                    w[e] = 0.5 * w[e] + 0.5 * pred;\n                }\n            }\n        }\n    };\n\n    const int EXP_END = 350;\n    const double EXP_BONUS = 3000.0;\n\n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        int s = si * W + sj;\n        int t = ti * W + tj;\n\n        if (q == 0 || q % 20 == 0) {\n            recompute_means_splits(q);\n            smooth_edges();\n        }\n\n        double explore_factor = (q < EXP_END) ? (double)(EXP_END - q) / EXP_END : 0.0;\n\n        // Dijkstra\n        const double INF = 1e100;\n        vector<double> dist(N, INF);\n        vector<int> prev(N, -1), prev_e(N, -1);\n        vector<char> prev_d(N, 0);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n        dist[s] = 0.0;\n        pq.push({0.0, s});\n        while (!pq.empty()) {\n            auto [d, v] = pq.top();\n            pq.pop();\n            if (d != dist[v]) continue;\n            if (v == t) break;\n            for (auto &nb : adj[v]) {\n                double cost = w[nb.edge];\n                if (cnt[nb.edge] == 0) {\n                    // if unknown, rely on predicted mean if available\n                    if (nb.edge < EH) {\n                        int ii = v / W;\n                        int jj = v % W;\n                        if (nb.dir == 'R') jj = jj;\n                        else if (nb.dir == 'L') jj = jj - 1;\n                        double pred = (rowSplit[ii] == -1) ? rowMeanAll[ii] : (jj < rowSplit[ii] ? rowMeanL[ii] : rowMeanR[ii]);\n                        cost = pred;\n                    } else {\n                        int ii = v / W;\n                        int jj = v % W;\n                        if (nb.dir == 'D') ii = ii;\n                        else if (nb.dir == 'U') ii = ii - 1;\n                        double pred = (colSplit[jj] == -1) ? colMeanAll[jj] : (ii < colSplit[jj] ? colMeanT[jj] : colMeanB[jj]);\n                        cost = pred;\n                    }\n                }\n                if (explore_factor > 0.0) {\n                    cost -= EXP_BONUS * explore_factor / sqrt((double)cnt[nb.edge] + 1.0);\n                }\n                if (cost < 1.0) cost = 1.0;\n                double nd = d + cost;\n                if (nd < dist[nb.to]) {\n                    dist[nb.to] = nd;\n                    prev[nb.to] = v;\n                    prev_e[nb.to] = nb.edge;\n                    prev_d[nb.to] = nb.dir;\n                    pq.push({nd, nb.to});\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        vector<int> edges_seq;\n        double pred_len = 0.0;\n        double pred_h = 0.0, pred_v = 0.0;\n        int v = t;\n        while (v != s && v != -1) {\n            int e = prev_e[v];\n            char dch = prev_d[v];\n            if (e < 0) break;\n            path.push_back(dch);\n            edges_seq.push_back(e);\n            pred_len += w[e];\n            if (e < EH) pred_h += w[e]; else pred_v += w[e];\n            v = prev[v];\n        }\n        reverse(path.begin(), path.end());\n        reverse(edges_seq.begin(), edges_seq.end());\n\n        cout << path << '\\n' << flush;\n\n        int obs_int;\n        if (!(cin >> obs_int)) break;\n        double obs_len = obs_int;\n        if (pred_len < 1e-6) pred_len = (double)edges_seq.size() * 5000.0;\n        double error = obs_len - pred_len;\n\n        double base_lr = (q < 200) ? 0.55 : (q < 600 ? 0.4 : 0.3);\n        double ph = pred_h, pv = pred_v;\n        double err_h = error, err_v = 0.0;\n        double total_pred = ph + pv;\n        if (total_pred > 1e-9) {\n            if (ph > 0 && pv > 0) {\n                err_h = error * (ph / total_pred);\n                err_v = error - err_h;\n            } else if (ph <= 0) {\n                err_h = 0.0;\n                err_v = error;\n            } else {\n                err_h = error;\n                err_v = 0.0;\n            }\n        }\n        double denom_h = max(ph, 1e-6);\n        double denom_v = max(pv, 1e-6);\n\n        for (int e : edges_seq) {\n            if (e < EH) {\n                double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n                double contrib = w[e] / denom_h;\n                w[e] += lr * err_h * contrib;\n            } else {\n                double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n                double contrib = w[e] / denom_v;\n                w[e] += lr * err_v * contrib;\n            }\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 9500.0) w[e] = 9500.0;\n            cnt[e]++;\n        }\n\n        if (q % 40 == 39) {\n            recompute_means_splits(q);\n            smooth_edges();\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// RNG\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    inline uint32_t next_u32() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return static_cast<uint32_t>(x);\n    }\n    inline int next_int(int n) { return static_cast<int>(next_u32() % n); }\n};\n\nconst int N = 20;\nconst int CELLS = N * N;   // 400\nconst int PL = 800;        // placements per string (400 horiz + 400 vert)\n\nint M;\nvector<string> s;\nvector<int> lens;\nvector<vector<uint8_t>> letters;   // letter indices 0..7\nvector<vector<uint16_t>> cells;    // placement cells\nvector<uint16_t*> cellPtrs;\nvector<uint8_t*> letterPtrs;\n\n// global counts for current assignment\nstatic int counts[CELLS][8];\nstatic int totalCnt[CELLS];\n\n// assign placements maximizing matches to matVal; rebuild counts; return satisfied count\nint assignAll(const vector<uint8_t>& matVal, XorShift64& rng) {\n    memset(counts, 0, sizeof(counts));\n    memset(totalCnt, 0, sizeof(totalCnt));\n    int satisfied = 0;\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cp = cellPtrs[i];\n        const uint8_t* lp = letterPtrs[i];\n        int bestMatch = -1;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            for (int p = 0; p < len; ++p) {\n                if (matVal[cp[base + p]] == lp[p]) ++matches;\n            }\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        if (bestMatch == len) ++satisfied;\n        int base = bestPi * len;\n        for (int p = 0; p < len; ++p) {\n            int cell = cp[base + p];\n            int li = lp[p];\n            ++counts[cell][li];\n            ++totalCnt[cell];\n        }\n    }\n    return satisfied;\n}\n\n// build majority matrix (numeric) from counts with random tie-break\nvoid buildMajority(vector<uint8_t>& matVal, XorShift64& rng) {\n    matVal.resize(CELLS);\n    for (int cell = 0; cell < CELLS; ++cell) {\n        if (totalCnt[cell] == 0) {\n            matVal[cell] = (uint8_t)rng.next_int(8);\n        } else {\n            int bestC = counts[cell][0];\n            int bestL = 0;\n            int tie = 1;\n            for (int l = 1; l < 8; ++l) {\n                if (counts[cell][l] > bestC) {\n                    bestC = counts[cell][l];\n                    bestL = l;\n                    tie = 1;\n                } else if (counts[cell][l] == bestC) {\n                    ++tie;\n                    if (rng.next_u32() % tie == 0) bestL = l;\n                }\n            }\n            matVal[cell] = (uint8_t)bestL;\n        }\n    }\n}\n\n// greedy placement with '.' wildcard\nvoid greedyTrial(const vector<int>& order, XorShift64& rng, vector<char>& outMat) {\n    vector<char> mat(CELLS, '.');\n    for (int idx : order) {\n        int len = lens[idx];\n        const uint16_t* cp = cellPtrs[idx];\n        const char* sp = s[idx].c_str();\n        int bestMatch = -1;\n        int bestPi = -1;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            bool ok = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char mc = mat[cell];\n                char sc = sp[p];\n                if (mc == sc) {\n                    ++matches;\n                } else if (mc == '.') {\n                    // ok\n                } else {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        if (bestPi >= 0) {\n            int base = bestPi * len;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char sc = sp[p];\n                if (mat[cell] == '.') mat[cell] = sc;\n            }\n        }\n    }\n    outMat.swap(mat);\n}\n\n// fill '.' with random letters according to freq; produce numeric matrix\nvoid fillDotsToNumeric(vector<char>& mat, const vector<int>& freq, XorShift64& rng, vector<uint8_t>& matVal) {\n    int freqSum = 0;\n    for (int f : freq) freqSum += f;\n    matVal.resize(CELLS);\n    for (int i = 0; i < CELLS; ++i) {\n        char c = mat[i];\n        if (c == '.') {\n            int r = rng.next_int(freqSum);\n            int acc = 0;\n            int l = 0;\n            for (; l < 8; ++l) {\n                acc += freq[l];\n                if (r < acc) break;\n            }\n            if (l >= 8) l = rng.next_int(8);\n            mat[i] = char('A' + l);\n            matVal[i] = (uint8_t)l;\n        } else {\n            matVal[i] = (uint8_t)(c - 'A');\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    s.resize(M);\n    lens.resize(M);\n    letters.resize(M);\n    cells.resize(M);\n    vector<int> freq(8, 0);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        lens[i] = (int)s[i].size();\n        letters[i].resize(lens[i]);\n        for (int p = 0; p < lens[i]; ++p) {\n            letters[i][p] = (uint8_t)(s[i][p] - 'A');\n            ++freq[letters[i][p]];\n        }\n        cells[i].resize(PL * lens[i]);\n        int len = lens[i];\n        // horizontal placements 0..399\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int cc = (c + p) % N;\n                    cells[i][base + p] = (uint16_t)(r * N + cc);\n                }\n            }\n        }\n        // vertical placements 400..799\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = 400 + r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int rr = (r + p) % N;\n                    cells[i][base + p] = (uint16_t)(rr * N + c);\n                }\n            }\n        }\n    }\n    cellPtrs.resize(M);\n    letterPtrs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cellPtrs[i] = cells[i].data();\n        letterPtrs[i] = letters[i].data();\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    XorShift64 rng(seed);\n\n    auto timeStart = chrono::steady_clock::now();\n    auto elapsedSec = [&]() -> double {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - timeStart).count();\n    };\n    const double TIME_LIMIT = 2.9;\n    const double GREEDY_TIME = 0.9;\n\n    vector<uint8_t> bestMatVal(CELLS);\n    int bestSat = -1;\n\n    // Prepare initial order (length descending)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (lens[a] != lens[b]) return lens[a] > lens[b];\n        return a < b;\n    });\n\n    vector<char> matC;\n    vector<uint8_t> matVal;\n    // First greedy trial with sorted order\n    greedyTrial(order, rng, matC);\n    fillDotsToNumeric(matC, freq, rng, matVal);\n    int sat = assignAll(matVal, rng);\n    if (sat > bestSat) {\n        bestSat = sat;\n        bestMatVal = matVal;\n    }\n\n    // Random greedy trials within time budget\n    vector<int> randOrder(M);\n    iota(randOrder.begin(), randOrder.end(), 0);\n    while (elapsedSec() < GREEDY_TIME) {\n        for (int i = M - 1; i > 0; --i) {\n            int j = rng.next_int(i + 1);\n            swap(randOrder[i], randOrder[j]);\n        }\n        greedyTrial(randOrder, rng, matC);\n        fillDotsToNumeric(matC, freq, rng, matVal);\n        sat = assignAll(matVal, rng);\n        if (sat > bestSat) {\n            bestSat = sat;\n            bestMatVal = matVal;\n        }\n    }\n\n    // EM-like iterations starting from bestMatVal\n    matVal = bestMatVal;\n    sat = assignAll(matVal, rng);\n    if (sat > bestSat) {\n        bestSat = sat;\n        bestMatVal = matVal;\n    }\n    int noImp = 0;\n    while (elapsedSec() < TIME_LIMIT) {\n        vector<uint8_t> newMatVal;\n        buildMajority(newMatVal, rng);\n        if (noImp >= 6) {\n            // random perturbation of few cells\n            int changes = 6;\n            for (int k = 0; k < changes; ++k) {\n                int cell = rng.next_int(CELLS);\n                newMatVal[cell] = (uint8_t)rng.next_int(8);\n            }\n            noImp = 0;\n        }\n        matVal.swap(newMatVal);\n        sat = assignAll(matVal, rng);\n        if (sat > bestSat) {\n            bestSat = sat;\n            bestMatVal = matVal;\n            noImp = 0;\n            if (bestSat == M) break;\n        } else {\n            ++noImp;\n        }\n    }\n\n    // Output bestMatVal as characters\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << char('A' + bestMatVal[r * N + c]);\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct CoverState {\n    int coveredCount;\n    vector<char> covered;\n    vector<char> rowCovered, colCovered;\n    vector<int> uncoveredRow, uncoveredCol;\n    CoverState(int R, int rsz, int csz, const vector<int> &rowSize, const vector<int> &colSize) {\n        coveredCount = 0;\n        covered.assign(R, 0);\n        rowCovered.assign(rsz, 0);\n        colCovered.assign(csz, 0);\n        uncoveredRow = rowSize;\n        uncoveredCol = colSize;\n    }\n};\n\nconst int INF = 1e9;\n\nvoid coverFrom(int u,\n               CoverState &st,\n               const vector<int> &row_id,\n               const vector<int> &col_id,\n               const vector<vector<int>> &row_nodes,\n               const vector<vector<int>> &col_nodes) {\n    int rid = row_id[u];\n    if (!st.rowCovered[rid]) {\n        st.rowCovered[rid] = 1;\n        for (int v : row_nodes[rid]) {\n            if (!st.covered[v]) {\n                st.covered[v] = 1;\n                st.coveredCount++;\n                st.uncoveredRow[row_id[v]]--;\n                st.uncoveredCol[col_id[v]]--;\n            }\n        }\n    }\n    int cid = col_id[u];\n    if (!st.colCovered[cid]) {\n        st.colCovered[cid] = 1;\n        for (int v : col_nodes[cid]) {\n            if (!st.covered[v]) {\n                st.covered[v] = 1;\n                st.coveredCount++;\n                st.uncoveredRow[row_id[v]]--;\n                st.uncoveredCol[col_id[v]]--;\n            }\n        }\n    }\n}\n\nvoid dijkstra(int src,\n              const vector<vector<pair<int, int>>> &adj,\n              vector<int> &dist,\n              vector<int> &prev) {\n    int n = adj.size();\n    dist.assign(n, INF);\n    prev.assign(n, -1);\n    dist[src] = 0;\n    using P = pair<int, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            int v = e.first, c = e.second;\n            int nd = d + c;\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pq.push({nd, v});\n            }\n        }\n    }\n}\n\nvector<int> reconstructPath(int src, int dst, const vector<int> &prev) {\n    vector<int> path;\n    int v = dst;\n    if (v != src && prev[v] == -1) return path;\n    while (true) {\n        path.push_back(v);\n        if (v == src) break;\n        v = prev[v];\n        if (v == -1) {\n            path.clear();\n            return path;\n        }\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nchar dirFromDiff(const pair<int, int> &a, const pair<int, int> &b) {\n    if (b.first == a.first - 1) return 'U';\n    if (b.first == a.first + 1) return 'D';\n    if (b.second == a.second - 1) return 'L';\n    return 'R';\n}\n\nstruct RouteResult {\n    string route;\n    long long cost;\n    bool full;\n};\n\nRouteResult buildRouteGreedy(int start,\n                             int R,\n                             const vector<int> &row_id,\n                             const vector<int> &col_id,\n                             const vector<vector<int>> &row_nodes,\n                             const vector<vector<int>> &col_nodes,\n                             const vector<vector<pair<int, int>>> &adj,\n                             const vector<pair<int, int>> &pos,\n                             const vector<int> &w) {\n    vector<int> rowSize(row_nodes.size()), colSize(col_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) rowSize[i] = (int)row_nodes[i].size();\n    for (size_t i = 0; i < col_nodes.size(); i++) colSize[i] = (int)col_nodes[i].size();\n    CoverState st(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, st, row_id, col_id, row_nodes, col_nodes);\n\n    string route;\n    long long cost = 0;\n    int current = start;\n    vector<int> dist, prev;\n    int iter_limit = 500;\n    int iter = 0;\n    while (st.coveredCount < R && iter < iter_limit) {\n        iter++;\n        dijkstra(current, adj, dist, prev);\n        int best = -1, bestGain = -1, bestDist = INF;\n        double bestScore = -1.0;\n        for (int u = 0; u < R; u++) {\n            int gain = st.uncoveredRow[row_id[u]] + st.uncoveredCol[col_id[u]] - (st.covered[u] ? 0 : 1);\n            if (gain <= 0) continue;\n            int d = dist[u];\n            if (d >= INF) continue;\n            double score = (double)gain / (double)(d + 1);\n            if (score > bestScore || (score == bestScore && (gain > bestGain || (gain == bestGain && d < bestDist)))) {\n                bestScore = score;\n                bestGain = gain;\n                bestDist = d;\n                best = u;\n            }\n        }\n        if (best == -1) break;\n        vector<int> path = reconstructPath(current, best, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n            current = v;\n            coverFrom(v, st, row_id, col_id, row_nodes, col_nodes);\n        }\n    }\n    // fallback nearest uncovered\n    while (st.coveredCount < R) {\n        dijkstra(current, adj, dist, prev);\n        int target = -1, bestD = INF;\n        for (int u = 0; u < R; u++) {\n            if (st.covered[u]) continue;\n            if (dist[u] < bestD) {\n                bestD = dist[u];\n                target = u;\n            }\n        }\n        if (target == -1 || bestD == INF) break;\n        vector<int> path = reconstructPath(current, target, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n            current = v;\n            coverFrom(v, st, row_id, col_id, row_nodes, col_nodes);\n        }\n    }\n    // return to start\n    if (current != start) {\n        dijkstra(current, adj, dist, prev);\n        vector<int> path = reconstructPath(current, start, prev);\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n        }\n    }\n    return {route, cost, st.coveredCount == R};\n}\n\nRouteResult buildRouteSetCoverTSP(int start,\n                                  int R,\n                                  const vector<int> &row_id,\n                                  const vector<int> &col_id,\n                                  const vector<vector<int>> &row_nodes,\n                                  const vector<vector<int>> &col_nodes,\n                                  const vector<vector<pair<int, int>>> &adj,\n                                  const vector<pair<int, int>> &pos,\n                                  const vector<int> &w) {\n    vector<int> rowSize(row_nodes.size()), colSize(col_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) rowSize[i] = (int)row_nodes[i].size();\n    for (size_t i = 0; i < col_nodes.size(); i++) colSize[i] = (int)col_nodes[i].size();\n    CoverState stSel(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, stSel, row_id, col_id, row_nodes, col_nodes);\n    vector<int> targets;\n    // greedy set cover\n    while (stSel.coveredCount < R) {\n        int best = -1;\n        int bestGain = -1;\n        for (int u = 0; u < R; u++) {\n            int gain = stSel.uncoveredRow[row_id[u]] + stSel.uncoveredCol[col_id[u]] - (stSel.covered[u] ? 0 : 1);\n            if (gain > bestGain) {\n                bestGain = gain;\n                best = u;\n            }\n        }\n        if (best == -1 || bestGain <= 0) break;\n        targets.push_back(best);\n        coverFrom(best, stSel, row_id, col_id, row_nodes, col_nodes);\n    }\n    // build nodes list\n    vector<char> used(R, 0);\n    vector<int> nodesList;\n    nodesList.push_back(start);\n    used[start] = 1;\n    for (int u : targets) {\n        if (!used[u]) {\n            used[u] = 1;\n            nodesList.push_back(u);\n        }\n    }\n    int M = nodesList.size();\n    if (M == 1) {\n        return {\"\", 0, stSel.coveredCount == R};\n    }\n\n    // distance matrix\n    vector<vector<int>> distMat(M, vector<int>(M, INF));\n    vector<int> dist, prev;\n    for (int i = 0; i < M; i++) {\n        dijkstra(nodesList[i], adj, dist, prev);\n        for (int j = 0; j < M; j++) {\n            distMat[i][j] = dist[nodesList[j]];\n        }\n    }\n\n    // initial tour: nearest neighbor\n    vector<int> tour;\n    tour.reserve(M + 1);\n    vector<char> vis(M, 0);\n    int curIdx = 0;\n    tour.push_back(curIdx);\n    vis[curIdx] = 1;\n    for (int cnt = 1; cnt < M; cnt++) {\n        int nxt = -1, bestD = INF;\n        for (int j = 0; j < M; j++) {\n            if (!vis[j] && distMat[curIdx][j] < bestD) {\n                bestD = distMat[curIdx][j];\n                nxt = j;\n            }\n        }\n        if (nxt == -1) {\n            for (int j = 0; j < M; j++) {\n                if (!vis[j]) {\n                    nxt = j;\n                    break;\n                }\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = 1;\n        curIdx = nxt;\n    }\n    tour.push_back(0);  // return to start\n\n    // 2-opt improvement\n    bool improved = true;\n    int len = tour.size();\n    while (improved) {\n        improved = false;\n        for (int i = 1; i < len - 2; i++) {\n            for (int j = i + 1; j < len - 1; j++) {\n                int a = tour[i - 1], b = tour[i], c = tour[j], d = tour[j + 1];\n                int curCost = distMat[a][b] + distMat[c][d];\n                int newCost = distMat[a][c] + distMat[b][d];\n                if (newCost < curCost) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // build route\n    CoverState stRoute(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, stRoute, row_id, col_id, row_nodes, col_nodes);\n    string routeStr;\n    long long costRoute = 0;\n    int currentNode = start;\n    for (size_t idx = 1; idx < tour.size(); idx++) {\n        int nextNode = nodesList[tour[idx]];\n        dijkstra(currentNode, adj, dist, prev);\n        vector<int> path = reconstructPath(currentNode, nextNode, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n            coverFrom(v, stRoute, row_id, col_id, row_nodes, col_nodes);\n        }\n        currentNode = nextNode;\n    }\n\n    // if not fully covered, fallback to greedy nearest uncovered\n    while (stRoute.coveredCount < R) {\n        dijkstra(currentNode, adj, dist, prev);\n        int target = -1, bestD = INF;\n        for (int u = 0; u < R; u++) {\n            if (stRoute.covered[u]) continue;\n            if (dist[u] < bestD) {\n                bestD = dist[u];\n                target = u;\n            }\n        }\n        if (target == -1 || bestD == INF) break;\n        vector<int> path = reconstructPath(currentNode, target, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n            coverFrom(v, stRoute, row_id, col_id, row_nodes, col_nodes);\n        }\n        currentNode = target;\n    }\n\n    // ensure return to start\n    if (currentNode != start) {\n        dijkstra(currentNode, adj, dist, prev);\n        vector<int> path = reconstructPath(currentNode, start, prev);\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n        }\n    }\n\n    return {routeStr, costRoute, stRoute.coveredCount == R};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int, int>> pos;\n    vector<int> w;\n    int R = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(grid[i][j] - '0');\n            }\n        }\n    }\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n\n    // adjacency\n    vector<vector<pair<int, int>>> adj(R);\n    int dx[4] = {-1, 1, 0, 0};\n    int dy[4] = {0, 0, -1, 1};\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = id[i][j];\n            if (u == -1) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (0 <= ni && ni < N && 0 <= nj && nj < N) {\n                    int v = id[ni][nj];\n                    if (v != -1) {\n                        adj[u].push_back({v, w[v]});\n                    }\n                }\n            }\n        }\n    }\n\n    // row segments\n    vector<int> row_id(R, -1);\n    vector<vector<int>> row_nodes;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (id[i][j] != -1) {\n                int segId = (int)row_nodes.size();\n                vector<int> seg;\n                while (j < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    row_id[u] = segId;\n                    seg.push_back(u);\n                    j++;\n                }\n                row_nodes.push_back(move(seg));\n            } else {\n                j++;\n            }\n        }\n    }\n    // column segments\n    vector<int> col_id(R, -1);\n    vector<vector<int>> col_nodes;\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (id[i][j] != -1) {\n                int segId = (int)col_nodes.size();\n                vector<int> seg;\n                while (i < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    col_id[u] = segId;\n                    seg.push_back(u);\n                    i++;\n                }\n                col_nodes.push_back(move(seg));\n            } else {\n                i++;\n            }\n        }\n    }\n\n    int start = id[si][sj];\n    RouteResult ra = buildRouteGreedy(start, R, row_id, col_id, row_nodes, col_nodes, adj, pos, w);\n    RouteResult rb = buildRouteSetCoverTSP(start, R, row_id, col_id, row_nodes, col_nodes, adj, pos, w);\n\n    string output;\n    if (ra.full && rb.full) {\n        if (rb.cost < ra.cost) output = rb.route;\n        else output = ra.route;\n    } else if (rb.full) {\n        output = rb.route;\n    } else {\n        output = ra.route;\n    }\n    cout << output << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Hungarian algorithm for min-cost assignment (rows <= cols)\nvector<int> hungarian(const vector<vector<double>>& a) {\n    int n = (int)a.size();\n    int m = (int)a[0].size();\n    vector<double> u(n + 1, 0), v(m + 1, 0);\n    vector<int> p(m + 1, 0), way(m + 1, 0);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<double> minv(m + 1, 1e18);\n        vector<char> used(m + 1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0];\n            double delta = 1e18;\n            int j1 = 0;\n            for (int j = 1; j <= m; j++) if (!used[j]) {\n                double cur = a[i0 - 1][j - 1] - u[i0] - v[j];\n                if (cur < minv[j]) {\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if (minv[j] < delta) {\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for (int j = 0; j <= m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    vector<int> assign(n, -1);\n    for (int j = 1; j <= m; j++) {\n        if (p[j] != 0) assign[p[j] - 1] = j - 1;\n    }\n    return assign;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> diff_sum(N, 0);\n    for (int i = 0; i < N; i++) {\n        int s = 0;\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n            s += d[i][k];\n        }\n        diff_sum[i] = s;\n    }\n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0), outdeg(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n        outdeg[u]++;\n    }\n    // compute height (longest path length) and weighted height by diff_sum\n    vector<int> height(N, 0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return a > b; }); // descending id ~ topological due to u<v\n    for (int idx = 0; idx < N; idx++) {\n        int i = order[idx];\n        int h = 0;\n        for (int v : adj[i]) h = max(h, height[v] + 1);\n        height[i] = h;\n    }\n    vector<int> wheight(N, 0);\n    for (int idx = 0; idx < N; idx++) {\n        int i = order[idx];\n        int w = diff_sum[i];\n        for (int v : adj[i]) w = max(w, diff_sum[i] + wheight[v]);\n        wheight[i] = w;\n    }\n\n    vector<int> task_status(N, 0); // 0 not started,1 working,2 done\n    vector<int> worker_status(M, -1);\n    vector<int> worker_start_day(M, -1);\n    vector<int> completed_count(M, 0);\n\n    // initial skill estimates\n    vector<double> mean_d(K, 0.0);\n    for (int k = 0; k < K; k++) {\n        long long s = 0;\n        for (int i = 0; i < N; i++) s += d[i][k];\n        mean_d[k] = (double)s / N;\n    }\n    std::mt19937 rng(123456789);\n    std::uniform_real_distribution<double> uni_factor(1.2, 1.8);\n    vector<vector<double>> s_hat(M, vector<double>(K, 0.0));\n    for (int j = 0; j < M; j++) {\n        double f = uni_factor(rng);\n        for (int k = 0; k < K; k++) s_hat[j][k] = mean_d[k] * f;\n    }\n    vector<double> bias_mul(M, 1.0);\n\n    int day = 1;\n    const int MAX_CAND = 300;\n    const int EXP_LIMIT = 2;\n    const double OUT_W = 0.45;\n    const double DIFF_W = 0.01;\n    const double WHEIGHT_W = 0.02;\n    const double DENOM_SHIFT = 0.7;\n    const double LR_BASE = 0.45;\n    const double LR_MIN = 0.03;\n    const double BIAS_ALPHA = 0.15;\n\n    while (true) {\n        // gather ready tasks\n        vector<int> ready;\n        ready.reserve(N);\n        for (int i = 0; i < N; i++) {\n            if (task_status[i] == 0 && indeg[i] == 0) {\n                ready.push_back(i);\n            }\n        }\n        sort(ready.begin(), ready.end(), [&](int a, int b) {\n            if (height[a] != height[b]) return height[a] > height[b];\n            if (outdeg[a] != outdeg[b]) return outdeg[a] > outdeg[b];\n            if (diff_sum[a] != diff_sum[b]) return diff_sum[a] > diff_sum[b];\n            return a < b;\n        });\n        if ((int)ready.size() > MAX_CAND) ready.resize(MAX_CAND);\n\n        vector<int> idle_workers;\n        idle_workers.reserve(M);\n        for (int w = 0; w < M; w++) if (worker_status[w] == -1) idle_workers.push_back(w);\n\n        vector<pair<int,int>> assignments;\n        vector<char> used_task(N, 0);\n\n        // exploration for inexperienced workers\n        if (!idle_workers.empty() && !ready.empty()) {\n            vector<int> new_idle;\n            for (int w : idle_workers) {\n                if (completed_count[w] < EXP_LIMIT) {\n                    int best_t = -1;\n                    double best_pred = 1e18;\n                    for (int t : ready) {\n                        if (used_task[t]) continue;\n                        if (task_status[t] != 0) continue;\n                        double pred = 0.0;\n                        for (int k = 0; k < K; k++) {\n                            double diff = d[t][k] - s_hat[w][k];\n                            if (diff > 0) pred += diff;\n                        }\n                        pred *= bias_mul[w];\n                        if (pred < 1.0) pred = 1.0;\n                        if (pred < best_pred) {\n                            best_pred = pred;\n                            best_t = t;\n                        }\n                    }\n                    if (best_t != -1) {\n                        assignments.push_back({w, best_t});\n                        worker_status[w] = best_t;\n                        worker_start_day[w] = day;\n                        task_status[best_t] = 1;\n                        used_task[best_t] = 1;\n                    } else new_idle.push_back(w);\n                } else new_idle.push_back(w);\n            }\n            idle_workers.swap(new_idle);\n        }\n\n        // remaining ready tasks\n        vector<int> ready_remain;\n        ready_remain.reserve(ready.size());\n        for (int t : ready) if (!used_task[t]) ready_remain.push_back(t);\n\n        int W = (int)idle_workers.size();\n        int C = (int)ready_remain.size();\n        if (W > 0 && C > 0) {\n            int cols = max(C, W);\n            vector<vector<double>> cost(W, vector<double>(cols, 0.0));\n            for (int i = 0; i < W; i++) {\n                int w = idle_workers[i];\n                for (int j = 0; j < C; j++) {\n                    int t = ready_remain[j];\n                    double pred = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[t][k] - s_hat[w][k];\n                        if (diff > 0) pred += diff;\n                    }\n                    double t_pred = pred * bias_mul[w];\n                    if (t_pred < 1.0) t_pred = 1.0;\n                    double hterm = height[t] + OUT_W * outdeg[t] + DIFF_W * diff_sum[t] + WHEIGHT_W * wheight[t];\n                    double score = hterm / (t_pred + DENOM_SHIFT);\n                    cost[i][j] = -score;\n                }\n                for (int j = C; j < cols; j++) cost[i][j] = 0.0; // dummy\n            }\n            vector<int> assign_idx = hungarian(cost);\n            for (int i = 0; i < W; i++) {\n                int j = assign_idx[i];\n                if (j >= 0 && j < C) {\n                    int w = idle_workers[i];\n                    int t = ready_remain[j];\n                    if (task_status[t] == 0) {\n                        assignments.push_back({w, t});\n                        worker_status[w] = t;\n                        worker_start_day[w] = day;\n                        task_status[t] = 1;\n                    }\n                }\n            }\n        }\n\n        // output\n        cout << assignments.size();\n        for (auto &p : assignments) {\n            cout << \" \" << (p.first + 1) << \" \" << (p.second + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n\n        // feedback\n        int nfin;\n        if (!(cin >> nfin)) break;\n        if (nfin == -1) break;\n        vector<int> fs(nfin);\n        for (int i = 0; i < nfin; i++) cin >> fs[i];\n        for (int idx = 0; idx < nfin; idx++) {\n            int w = fs[idx] - 1;\n            int tid = worker_status[w];\n            if (tid < 0) continue;\n            int duration = day - worker_start_day[w] + 1;\n            task_status[tid] = 2;\n            completed_count[w]++;\n\n            // update indegrees\n            for (int v : adj[tid]) indeg[v]--;\n\n            double actual_w = max(0.0, (double)duration - 1.0);\n            double w_pred = 0.0;\n            vector<int> active;\n            active.reserve(K);\n            for (int k = 0; k < K; k++) {\n                double diff = d[tid][k] - s_hat[w][k];\n                if (diff > 0) {\n                    w_pred += diff;\n                    active.push_back(k);\n                }\n            }\n            // update bias\n            double ratio = (actual_w + 1.0) / (w_pred + 1.0);\n            if (ratio < 0.5) ratio = 0.5;\n            if (ratio > 2.0) ratio = 2.0;\n            bias_mul[w] = (1.0 - BIAS_ALPHA) * bias_mul[w] + BIAS_ALPHA * ratio;\n\n            double lr = LR_BASE / sqrt((double)completed_count[w]);\n            if (lr < LR_MIN) lr = LR_MIN;\n            if (!active.empty()) {\n                if (w_pred < 1e-9) w_pred = 1e-9;\n                double factor = lr * (w_pred - actual_w);\n                for (int k : active) {\n                    double weight = (d[tid][k] - s_hat[w][k]) / w_pred;\n                    if (weight < 0) weight = 0;\n                    s_hat[w][k] += factor * weight;\n                    if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                    if (s_hat[w][k] > 200) s_hat[w][k] = 200;\n                }\n            } else {\n                if (actual_w > 0.0) {\n                    vector<int> idxs(K);\n                    iota(idxs.begin(), idxs.end(), 0);\n                    sort(idxs.begin(), idxs.end(), [&](int a, int b){ return d[tid][a] > d[tid][b]; });\n                    int use = min(3, K);\n                    double delta = lr * actual_w / use;\n                    for (int i = 0; i < use; i++) {\n                        int k = idxs[i];\n                        s_hat[w][k] -= delta;\n                        if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                    }\n                }\n            }\n            worker_status[w] = -1;\n        }\n        day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int NORD = 1000;\nconst int CHOOSE = 50;\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\n\nconst double TOTAL_LIMIT = 1.90;\nconst double RESERVE_TIME = 0.20;\nconst int GRID_STEP = 100;\nconst int RANDOM_SEEDS = 150;\nconst int POOL_SIZE = 300;\n\nint ax[NORD], byy[NORD], cx[NORD], dy[NORD];\ndouble midx[NORD], midy[NORD];\n\ninline int mdist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Greedy nearest feasible route cost for a subset (0-based indices)\nlong long nearest_cost(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int done = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    while (done < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        int tx = 0, ty = 0;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (status[i] == 2) continue;\n            int x = (status[i] == 0 ? px[i] : qx[i]);\n            int y = (status[i] == 0 ? py[i] : qy[i]);\n            int d = abs(curx - x) + abs(cury - y);\n            if (d < bestd) { bestd = d; best = i; tx = x; ty = y; }\n        }\n        total += bestd;\n        curx = tx; cury = ty;\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; done++; }\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    return total;\n}\n\n// Build sequences of node indices (0..99) for various heuristics\nvector<int> route_nearest_seq(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int done = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    vector<int> seq;\n    seq.reserve(CHOOSE * 2);\n    while (done < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        int tx = 0, ty = 0;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (status[i] == 2) continue;\n            int x = (status[i] == 0 ? px[i] : qx[i]);\n            int y = (status[i] == 0 ? py[i] : qy[i]);\n            int d = abs(curx - x) + abs(cury - y);\n            if (d < bestd) { bestd = d; best = i; tx = x; ty = y; }\n        }\n        curx = tx; cury = ty;\n        if (status[best] == 0) seq.push_back(best);\n        else seq.push_back(best + CHOOSE);\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; done++; }\n    }\n    return seq;\n}\n\n// Pickup then immediate delivery\nvector<int> route_immediate_seq(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool rem[CHOOSE];\n    memset(rem, 1, sizeof(bool) * CHOOSE);\n    int remaining = CHOOSE;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    vector<int> seq;\n    seq.reserve(CHOOSE * 2);\n    while (remaining > 0) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (!rem[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        seq.push_back(best);\n        seq.push_back(best + CHOOSE);\n        curx = qx[best]; cury = qy[best];\n        rem[best] = false;\n        remaining--;\n    }\n    return seq;\n}\n\n// Pick all, then deliver all\nvector<int> route_pickdrop_seq(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool picked[CHOOSE], deliv[CHOOSE];\n    memset(picked, 0, sizeof(picked));\n    memset(deliv, 0, sizeof(deliv));\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    vector<int> seq;\n    seq.reserve(CHOOSE * 2);\n    int pcnt = 0, dcnt = 0;\n    while (pcnt < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (picked[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        seq.push_back(best);\n        curx = px[best]; cury = py[best];\n        picked[best] = true; pcnt++;\n    }\n    while (dcnt < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (deliv[i]) continue;\n            int d = abs(curx - qx[i]) + abs(cury - qy[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        seq.push_back(best + CHOOSE);\n        curx = qx[best]; cury = qy[best];\n        deliv[best] = true; dcnt++;\n    }\n    return seq;\n}\n\n// Cost of a sequence using precomputed matrices\nlong long seq_cost(const vector<int>& seq, const vector<vector<int>>& distMat, const vector<int>& distDepot) {\n    long long cost = 0;\n    int n = (int)seq.size();\n    cost += distDepot[seq[0]];\n    for (int i = 0; i < n - 1; i++) {\n        cost += distMat[seq[i]][seq[i + 1]];\n    }\n    cost += distDepot[seq.back()];\n    return cost;\n}\n\n// Local improvement: relocate pickup-delivery pair\nvoid local_optimize(vector<int>& seq, const vector<vector<int>>& distMat, const vector<int>& distDepot, mt19937& rng, chrono::steady_clock::time_point end_time) {\n    int n = (int)seq.size();\n    vector<int> posPick(CHOOSE), posDrop(CHOOSE);\n    auto recompute = [&]() {\n        for (int i = 0; i < n; i++) {\n            int node = seq[i];\n            if (node < CHOOSE) posPick[node] = i;\n            else posDrop[node - CHOOSE] = i;\n        }\n    };\n    recompute();\n    long long curCost = seq_cost(seq, distMat, distDepot);\n    const int MAX_IT = 7000;\n    for (int it = 0; it < MAX_IT; it++) {\n        if ((it & 0x1FF) == 0) {\n            if (chrono::steady_clock::now() >= end_time) break;\n        }\n        int ord = rng() % CHOOSE;\n        int ppos_old = posPick[ord];\n        int dpos_old = posDrop[ord];\n        if (ppos_old > dpos_old) continue;\n        vector<int> rem;\n        rem.reserve(n - 2);\n        for (int i = 0; i < n; i++) {\n            if (i == ppos_old || i == dpos_old) continue;\n            rem.push_back(seq[i]);\n        }\n        int lenRem = n - 2;\n        int ppos_new = rng() % (lenRem + 1);\n        int dpos_new = rng() % (lenRem + 2);\n        if (dpos_new < ppos_new) dpos_new = ppos_new;\n        vector<int> newSeq;\n        newSeq.reserve(n);\n        bool insP = false, insD = false;\n        for (int i = 0; i <= lenRem; i++) {\n            if (!insP && (int)newSeq.size() == ppos_new) {\n                newSeq.push_back(ord);\n                insP = true;\n            }\n            if (!insD && (int)newSeq.size() == dpos_new) {\n                newSeq.push_back(ord + CHOOSE);\n                insD = true;\n            }\n            if (i == lenRem) break;\n            newSeq.push_back(rem[i]);\n        }\n        if (!insP) newSeq.push_back(ord);\n        if (!insD) newSeq.push_back(ord + CHOOSE);\n        long long newCost = seq_cost(newSeq, distMat, distDepot);\n        if (newCost < curCost) {\n            seq.swap(newSeq);\n            curCost = newCost;\n            recompute();\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < NORD; i++) {\n        if (!(cin >> ax[i] >> byy[i] >> cx[i] >> dy[i])) return 0;\n        midx[i] = 0.5 * (ax[i] + cx[i]);\n        midy[i] = 0.5 * (byy[i] + dy[i]);\n    }\n\n    auto time_start = chrono::steady_clock::now();\n    auto total_end = time_start + chrono::duration_cast<chrono::steady_clock::duration>(chrono::duration<double>(TOTAL_LIMIT));\n    auto sa_end = time_start + chrono::duration_cast<chrono::steady_clock::duration>(chrono::duration<double>(TOTAL_LIMIT - RESERVE_TIME));\n\n    // Base costs\n    vector<long long> baseCost(NORD);\n    for (int i = 0; i < NORD; i++) {\n        baseCost[i] = mdist(DEPOT_X, DEPOT_Y, ax[i], byy[i]) +\n                      mdist(ax[i], byy[i], cx[i], dy[i]) +\n                      mdist(cx[i], dy[i], DEPOT_X, DEPOT_Y);\n    }\n    vector<int> sorted_ids(NORD);\n    iota(sorted_ids.begin(), sorted_ids.end(), 0);\n    sort(sorted_ids.begin(), sorted_ids.end(), [&](int i, int j) { return baseCost[i] < baseCost[j]; });\n\n    int poolN = min(POOL_SIZE, NORD);\n    vector<int> pool(sorted_ids.begin(), sorted_ids.begin() + poolN);\n\n    array<int, CHOOSE> bestSubset;\n    for (int i = 0; i < CHOOSE; i++) bestSubset[i] = pool[i];\n    long long bestEval = nearest_cost(bestSubset);\n\n    // Seeds\n    vector<pair<double, double>> seeds;\n    for (int x = 0; x <= 800; x += GRID_STEP) {\n        for (int y = 0; y <= 800; y += GRID_STEP) {\n            seeds.emplace_back(x, y);\n        }\n    }\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> coordDist(0, 800);\n    for (int i = 0; i < RANDOM_SEEDS; i++) {\n        seeds.emplace_back(coordDist(rng), coordDist(rng));\n    }\n\n    vector<int> tmpIds(poolN);\n    iota(tmpIds.begin(), tmpIds.end(), 0);\n    array<int, CHOOSE> tmpSubset;\n    for (auto &s : seeds) {\n        double sx = s.first, sy = s.second;\n        sort(tmpIds.begin(), tmpIds.end(), [&](int i, int j) {\n            double dx1 = midx[pool[i]] - sx, dy1 = midy[pool[i]] - sy;\n            double dx2 = midx[pool[j]] - sx, dy2 = midy[pool[j]] - sy;\n            return dx1 * dx1 + dy1 * dy1 < dx2 * dx2 + dy2 * dy2;\n        });\n        for (int i = 0; i < CHOOSE; i++) tmpSubset[i] = pool[tmpIds[i]];\n        long long t = nearest_cost(tmpSubset);\n        if (t < bestEval) {\n            bestEval = t;\n            bestSubset = tmpSubset;\n        }\n    }\n\n    // Random sampling\n    array<int, CHOOSE> randomSubset;\n    int random_trials = 200;\n    for (int t = 0; t < random_trials; t++) {\n        shuffle(pool.begin(), pool.end(), rng);\n        for (int i = 0; i < CHOOSE; i++) randomSubset[i] = pool[i];\n        long long val = nearest_cost(randomSubset);\n        if (val < bestEval) {\n            bestEval = val;\n            bestSubset = randomSubset;\n        }\n    }\n\n    // SA over subset (swap selected vs non-selected)\n    array<int, CHOOSE> curSubset = bestSubset;\n    long long curEval = bestEval;\n\n    vector<int> outList;\n    outList.reserve(poolN - CHOOSE);\n    vector<char> inSel(NORD, 0);\n    for (int i = 0; i < CHOOSE; i++) inSel[curSubset[i]] = 1;\n    for (int v : pool) if (!inSel[v]) outList.push_back(v);\n\n    uniform_int_distribution<int> distIn(0, CHOOSE - 1);\n    uniform_real_distribution<double> distReal(0.0, 1.0);\n    if (!outList.empty()) {\n        uniform_int_distribution<int> distOut(0, (int)outList.size() - 1);\n        double startTemp = 3000.0, endTemp = 30.0;\n        while (chrono::steady_clock::now() < sa_end) {\n            int idxIn = distIn(rng);\n            int idxOut = distOut(rng);\n            int oldIn = curSubset[idxIn];\n            int newIn = outList[idxOut];\n            curSubset[idxIn] = newIn;\n            long long newEval = nearest_cost(curSubset);\n            double progress = chrono::duration<double>(chrono::steady_clock::now() - time_start).count() / (TOTAL_LIMIT - RESERVE_TIME);\n            if (progress > 1.0) progress = 1.0;\n            double temp = startTemp * pow(endTemp / startTemp, progress);\n            bool accept = false;\n            if (newEval < curEval) accept = true;\n            else {\n                double diff = double(curEval - newEval);\n                double prob = exp(diff / temp);\n                if (distReal(rng) < prob) accept = true;\n            }\n            if (accept) {\n                curEval = newEval;\n                outList[idxOut] = oldIn;\n                if (newEval < bestEval) {\n                    bestEval = newEval;\n                    bestSubset = curSubset;\n                }\n            } else {\n                curSubset[idxIn] = oldIn;\n            }\n        }\n    }\n\n    // Build coordinates for best subset (nodes 0..99)\n    vector<pair<int, int>> coords;\n    coords.reserve(CHOOSE * 2);\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = bestSubset[i];\n        coords.emplace_back(ax[id], byy[id]);\n    }\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = bestSubset[i];\n        coords.emplace_back(cx[id], dy[id]);\n    }\n    int nodeCount = CHOOSE * 2;\n    vector<vector<int>> distMat(nodeCount, vector<int>(nodeCount));\n    vector<int> distDepot(nodeCount);\n    for (int i = 0; i < nodeCount; i++) {\n        distDepot[i] = mdist(DEPOT_X, DEPOT_Y, coords[i].first, coords[i].second);\n        for (int j = 0; j < nodeCount; j++) {\n            distMat[i][j] = mdist(coords[i].first, coords[i].second, coords[j].first, coords[j].second);\n        }\n    }\n\n    // Build candidate sequences\n    vector<int> seq1 = route_nearest_seq(bestSubset);\n    vector<int> seq2 = route_immediate_seq(bestSubset);\n    vector<int> seq3 = route_pickdrop_seq(bestSubset);\n\n    long long c1 = seq_cost(seq1, distMat, distDepot);\n    long long c2 = seq_cost(seq2, distMat, distDepot);\n    long long c3 = seq_cost(seq3, distMat, distDepot);\n\n    vector<int> bestSeq = seq1;\n    long long bestCost = c1;\n    if (c2 < bestCost) { bestCost = c2; bestSeq = seq2; }\n    if (c3 < bestCost) { bestCost = c3; bestSeq = seq3; }\n\n    // Local optimization with remaining time\n    local_optimize(bestSeq, distMat, distDepot, rng, total_end);\n\n    // Build path for output\n    vector<pair<int, int>> path;\n    path.reserve(nodeCount + 2);\n    path.emplace_back(DEPOT_X, DEPOT_Y);\n    for (int idx : bestSeq) {\n        path.push_back(coords[idx]);\n    }\n    path.emplace_back(DEPOT_X, DEPOT_Y);\n\n    // Output\n    cout << CHOOSE;\n    for (int i = 0; i < CHOOSE; i++) cout << ' ' << (bestSubset[i] + 1); // 1-based\n    cout << '\\n';\n    cout << path.size();\n    for (auto &p : path) cout << ' ' << p.first << ' ' << p.second;\n    cout << '\\n';\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, sz;\n    DSU(int n_=0): n(n_), p(n_), sz(n_,1) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }\n    bool merge(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b];\n        return true;\n    }\n};\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u,v;\n    int d;\n    int tid;       // tree id 0..4\n    bool in_mst;   // in first tree\n};\n\nvector<Edge> edges(M);\nvector<int> xs(N), ys(N);\n\n// low-link globals\nvector<int> tin, low;\nvector<char> vis, is_bridge;\nvector<vector<pair<int,int>>> adj;\nint timer_dfs;\n\nvoid compute_bridges(const vector<char>& alive){\n    for(int i=0;i<N;i++) adj[i].clear();\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        adj[u].push_back({v,id});\n        adj[v].push_back({u,id});\n    }\n    fill(vis.begin(), vis.end(), 0);\n    fill(is_bridge.begin(), is_bridge.end(), 0);\n    timer_dfs = 0;\n    function<void(int,int)> dfs = [&](int v,int pe){\n        vis[v]=1;\n        tin[v]=low[v]=++timer_dfs;\n        for(auto [to,eid]: adj[v]){\n            if(eid==pe) continue;\n            if(vis[to]){\n                low[v]=min(low[v], tin[to]);\n            }else{\n                dfs(to,eid);\n                low[v]=min(low[v], low[to]);\n                if(low[to] > tin[v]){\n                    is_bridge[eid]=1;\n                }\n            }\n        }\n    };\n    for(int i=0;i<N;i++){\n        if(!vis[i]) dfs(i,-1);\n    }\n}\n\nvoid compute_out_count(const vector<char>& alive, DSU &dsu, vector<int>& out_cnt){\n    fill(out_cnt.begin(), out_cnt.end(), 0);\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        int ru=dsu.find(u), rv=dsu.find(v);\n        if(ru==rv) continue;\n        out_cnt[ru]++; out_cnt[rv]++;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<N;i++){\n        if(!(cin>>xs[i]>>ys[i])) return 0;\n    }\n    for(int i=0;i<M;i++){\n        int u,v;\n        cin>>u>>v;\n        edges[i].u=u;\n        edges[i].v=v;\n        long dx=xs[u]-xs[v];\n        long dy=ys[u]-ys[v];\n        edges[i].d = (int)llround(sqrt((double)(dx*dx + dy*dy)));\n        edges[i].tid = 4;\n        edges[i].in_mst = false;\n    }\n\n    // sort edges by d for decomposition\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n        return a < b;\n    });\n\n    // decompose into 5 spanning trees\n    vector<char> used(M, 0);\n    for(int t=0; t<5; t++){\n        DSU dsu(N);\n        int cnt=0;\n        for(int id: ord){\n            if(used[id]) continue;\n            if(dsu.merge(edges[id].u, edges[id].v)){\n                edges[id].tid = t;\n                used[id]=1;\n                cnt++;\n                if(cnt == N-1) break;\n            }\n        }\n    }\n    // mark first tree edges as in_mst\n    for(int i=0;i<M;i++){\n        if(edges[i].tid==0) edges[i].in_mst = true;\n    }\n\n    // quantiles of d\n    vector<int> ds;\n    ds.reserve(M);\n    for(auto &e: edges) ds.push_back(e.d);\n    sort(ds.begin(), ds.end());\n    int q1 = ds[M/4];\n    int q3 = ds[(3*M)/4];\n\n    vector<char> alive(M, 1);\n    DSU dsu_conn(N);\n    int comp_cnt = N;\n\n    tin.assign(N,0); low.assign(N,0); vis.assign(N,0);\n    is_bridge.assign(M,0);\n    adj.assign(N, {});\n    vector<int> out_cnt(N,0);\n\n    array<double,5> start = {1.45, 1.38, 1.30, 1.20, 1.10};\n    array<double,5> finish= {1.90, 1.80, 1.70, 1.55, 1.40};\n    const double ALPHA = 0.50;\n\n    for(int iedge=0; iedge<M; iedge++){\n        int l;\n        if(!(cin>>l)) break;\n        double r = (double)l / (double)edges[iedge].d;\n\n        compute_bridges(alive);\n        compute_out_count(alive, dsu_conn, out_cnt);\n\n        bool accept=false;\n        if(is_bridge[iedge]){\n            accept=true;\n        }else{\n            int ru = dsu_conn.find(edges[iedge].u);\n            int rv = dsu_conn.find(edges[iedge].v);\n            if(ru != rv){\n                double prog = (double)iedge / (double)(M-1);\n                double f = pow(prog, ALPHA);\n                int t = edges[iedge].tid;\n                double thr = start[t] + (finish[t] - start[t]) * f;\n\n                int outm = min(out_cnt[ru], out_cnt[rv]);\n                if(outm <= 2) thr += 0.30;\n                else if(outm <= 4) thr += 0.15;\n                else if(outm <= 6) thr += 0.07;\n\n                int rem = M - iedge - 1;\n                int need = comp_cnt - 1;\n                if(need > 0){\n                    if(rem <= need * 2) thr += 0.50;\n                    else if(rem <= need * 3) thr += 0.20;\n                }\n\n                if(edges[iedge].d <= q1) thr += 0.05;\n                else if(edges[iedge].d >= q3) thr -= 0.05;\n\n                if(thr > 2.7) thr = 2.7;\n                if(r <= thr) accept = true;\n            }else{\n                accept = false; // never take cycle edges\n            }\n        }\n\n        if(accept){\n            if(dsu_conn.merge(edges[iedge].u, edges[iedge].v)){\n                comp_cnt--;\n            }\n        }else{\n            alive[iedge]=0;\n        }\n\n        cout << (accept ? 1 : 0) << '\\n';\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet { int x,y,t; };\n\nint N,M;\nvector<Pet> pets;\nvector<int> hx, hy;\nvector<vector<bool>> wall(31, vector<bool>(31,false));\n\nint r1,r2,c1,c2;\nint colWallCol,rowWallRow;\nint builderCol,builderRow;\nchar colDir,rowDir;\nint entryWallX, entryWallY;\npair<int,int> entryDest;\nchar gapOrient; // 'R' for row wall gap, 'C' for col wall gap\nint T_close;\n\ninline int encode(int x,int y){ return x*64 + y; }\n\nint dist_point_to_rect(int px,int py,int r1,int r2,int c1,int c2){\n    int dx=0, dy=0;\n    if(px<r1) dx=r1-px;\n    else if(px>r2) dx=px-r2;\n    if(py<c1) dy=c1-py;\n    else if(py>c2) dy=py-c2;\n    return dx+dy;\n}\n\nbool can_build(int wx,int wy,const vector<Pet>& pets,const vector<int>& hx,const vector<int>& hy){\n    if(wx<1 || wx>30 || wy<1 || wy>30) return false;\n    for(auto &p: pets){\n        if(p.x==wx && p.y==wy) return false;\n        if(abs(p.x-wx)+abs(p.y-wy)<=1) return false;\n    }\n    for(size_t i=0;i<hx.size();i++){\n        if(hx[i]==wx && hy[i]==wy) return false;\n    }\n    return true;\n}\n\nchar bfs_move(int sx,int sy,int tx,int ty,bool regionOnly,const unordered_set<int>& buildTargets){\n    auto blocked=[&](int x,int y)->bool{\n        if(x<1||x>30||y<1||y>30) return true;\n        if(regionOnly && (x<r1 || x>r2 || y<c1 || y>c2)) return true;\n        if(wall[x][y]) return true;\n        if(buildTargets.find(encode(x,y))!=buildTargets.end()) return true;\n        return false;\n    };\n    if(blocked(tx,ty)) return '.';\n    static int dist[31][31];\n    for(int i=1;i<=30;i++) for(int j=1;j<=30;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[tx][ty]=0;\n    q.push({tx,ty});\n    int dxs[4]={-1,1,0,0};\n    int dys[4]={0,0,-1,1};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        int nd=dist[x][y]+1;\n        for(int d=0;d<4;d++){\n            int nx=x+dxs[d], ny=y+dys[d];\n            if(blocked(nx,ny)) continue;\n            if(dist[nx][ny]==-1){\n                dist[nx][ny]=nd;\n                q.push({nx,ny});\n            }\n        }\n    }\n    if(dist[sx][sy]<=0) return '.';\n    char dirc[4]={'U','D','L','R'};\n    for(int d=0;d<4;d++){\n        int nx=sx+dxs[d], ny=sy+dys[d];\n        if(nx<1||nx>30||ny<1||ny>30) continue;\n        if(regionOnly && (nx<r1||nx>r2||ny<c1||ny>c2)) continue;\n        if(blocked(nx,ny)) continue;\n        if(dist[nx][ny]==dist[sx][sy]-1) return dirc[d];\n    }\n    return '.';\n}\n\nvoid select_region(const vector<int>& initHx, const vector<int>& initHy){\n    double bestScore=-1e18;\n    int bestR1=1,bestR2=5,bestC1=1,bestC2=5;\n    bool foundZero=false;\n    for(int k=12;k>=5;k--){\n        for(int corner=0;corner<4;corner++){\n            int rr1,rr2,cc1,cc2;\n            switch(corner){\n                case 0: rr1=1; rr2=k; cc1=1; cc2=k; break;\n                case 1: rr1=1; rr2=k; cc1=30-k+1; cc2=30; break;\n                case 2: rr1=30-k+1; rr2=30; cc1=1; cc2=k; break;\n                default: rr1=30-k+1; rr2=30; cc1=30-k+1; cc2=30; break;\n            }\n            int inside=0;\n            int minDistPet=1000;\n            for(auto &p: pets){\n                if(rr1<=p.x && p.x<=rr2 && cc1<=p.y && p.y<=cc2) inside++;\n                int d=dist_point_to_rect(p.x,p.y,rr1,rr2,cc1,cc2);\n                minDistPet=min(minDistPet,d);\n            }\n            if(pets.empty()) minDistPet=100;\n            int maxHD=0;\n            int midc=(cc1+cc2)/2;\n            int midr=(rr1+rr2)/2;\n            for(size_t i=0;i<initHx.size();i++){\n                int d=abs(initHx[i]-midr)+abs(initHy[i]-midc);\n                maxHD=max(maxHD,d);\n            }\n            double area=k*k;\n            if(!foundZero && inside>0) continue;\n            if(inside==0) foundZero=true;\n            double score = area*1.5 + minDistPet*10.0 - maxHD*2.0 - inside*500.0;\n            if(score>bestScore){\n                bestScore=score;\n                bestR1=rr1; bestR2=rr2; bestC1=cc1; bestC2=cc2;\n            }\n        }\n        if(foundZero) break;\n    }\n    r1=bestR1; r2=bestR2; c1=bestC1; c2=bestC2;\n    if(c1==1){ colWallCol=c2+1; colDir='r'; builderCol=c2; }\n    else { colWallCol=c1-1; colDir='l'; builderCol=c1; }\n    if(r1==1){ rowWallRow=r2+1; rowDir='d'; builderRow=r2; }\n    else { rowWallRow=r1-1; rowDir='u'; builderRow=r1; }\n\n    // select opening (gap) position maximizing distance to nearest pet\n    int bestDist=-1;\n    gapOrient='R';\n    entryWallX=rowWallRow;\n    entryWallY=(c1+c2)/2;\n    entryDest={builderRow, entryWallY};\n    // row candidates\n    for(int y=c1; y<=c2; y++){\n        int gx=rowWallRow, gy=y;\n        int mind=1000;\n        for(auto &p: pets){\n            int d=abs(p.x-gx)+abs(p.y-gy);\n            mind=min(mind,d);\n        }\n        if(mind>bestDist){\n            bestDist=mind;\n            gapOrient='R';\n            entryWallX=gx; entryWallY=gy;\n            entryDest={builderRow, gy};\n        }\n    }\n    // col candidates\n    for(int x=r1; x<=r2; x++){\n        int gx=x, gy=colWallCol;\n        int mind=1000;\n        for(auto &p: pets){\n            int d=abs(p.x-gx)+abs(p.y-gy);\n            mind=min(mind,d);\n        }\n        if(mind>bestDist){\n            bestDist=mind;\n            gapOrient='C';\n            entryWallX=gx; entryWallY=gy;\n            entryDest={x, builderCol};\n        }\n    }\n    // T_close based on human distances\n    int maxD=0;\n    for(size_t i=0;i<initHx.size();i++){\n        int d=abs(initHx[i]-entryDest.first)+abs(initHy[i]-entryDest.second);\n        maxD=max(maxD,d);\n    }\n    int perimeter = (r2-r1+1)+(c2-c1+1);\n    T_close = min(80, max(30, maxD + perimeter/ (int)max(1,M) + 5));\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N;\n    pets.resize(N);\n    for(int i=0;i<N;i++) cin>>pets[i].x>>pets[i].y>>pets[i].t;\n    cin>>M;\n    hx.resize(M); hy.resize(M);\n    for(int i=0;i<M;i++) cin>>hx[i]>>hy[i];\n    vector<int> initHx=hx, initHy=hy;\n    select_region(initHx, initHy);\n\n    vector<pair<int,int>> colCells,rowCells;\n    for(int r=r1; r<=r2; r++) colCells.push_back({r,colWallCol});\n    for(int c=c1; c<=c2; c++) rowCells.push_back({rowWallRow,c});\n\n    for(int turn=0; turn<300; turn++){\n        bool all_inside=true;\n        int insideCnt=0;\n        for(int i=0;i<M;i++){\n            if(r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2) insideCnt++;\n            else all_inside=false;\n        }\n        bool petInside=false;\n        int petGapDist=1000;\n        for(auto &p: pets){\n            if(r1<=p.x && p.x<=r2 && c1<=p.y && p.y<=c2) petInside=true;\n            petGapDist=min(petGapDist, abs(p.x-entryWallX)+abs(p.y-entryWallY));\n        }\n        bool close_condition=false;\n        if(all_inside || turn>=T_close) close_condition=true;\n        if(insideCnt>= (M+1)/2 && petGapDist<=1) close_condition=true;\n\n        // compute missing walls\n        vector<int> colMissingRows;\n        for(auto &p: colCells){\n            if(gapOrient=='C' && p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) colMissingRows.push_back(p.first);\n        }\n        vector<int> rowMissingCols;\n        for(auto &p: rowCells){\n            if(gapOrient=='R' && p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) rowMissingCols.push_back(p.second);\n        }\n\n        unordered_set<int> buildTargets;\n        string actions(M,'.');\n\n        // attempt builds\n        for(int i=0;i<M;i++){\n            // col wall build\n            if(r1<=hx[i] && hx[i]<=r2 && hy[i]==builderCol){\n                if(!colMissingRows.empty()){\n                    if(!wall[hx[i]][colWallCol]){\n                        int wx=hx[i], wy=colWallCol;\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=colDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n            // row wall build\n            if(hx[i]==builderRow && hy[i]>=c1 && hy[i]<=c2){\n                if(!rowMissingCols.empty()){\n                    if(!wall[rowWallRow][hy[i]]){\n                        int wx=rowWallRow, wy=hy[i];\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=rowDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n        }\n\n        // movement\n        for(int i=0;i<M;i++){\n            if(actions[i]!='.') continue;\n            bool inside = (r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2);\n            if(!inside){\n                char mv=bfs_move(hx[i],hy[i],entryDest.first, entryDest.second, false, buildTargets);\n                actions[i]=mv;\n            }else{\n                if(!colMissingRows.empty()){\n                    int bestd=1e9, targRow=colMissingRows[0];\n                    for(int rr: colMissingRows){\n                        int d=abs(rr-hx[i])+abs(builderCol-hy[i]);\n                        if(d<bestd){bestd=d; targRow=rr;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],targRow,builderCol,true,buildTargets);\n                    actions[i]=mv;\n                }else if(!rowMissingCols.empty()){\n                    int bestd=1e9, targCol=rowMissingCols[0];\n                    for(int cc: rowMissingCols){\n                        int d=abs(builderRow-hx[i])+abs(cc-hy[i]);\n                        if(d<bestd){bestd=d; targCol=cc;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],builderRow,targCol,true,buildTargets);\n                    actions[i]=mv;\n                }else{\n                    actions[i]='.';\n                }\n            }\n        }\n\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // read pet moves\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            if(s==\".\") continue;\n            for(char ch: s){\n                if(ch=='U') pets[i].x--;\n                else if(ch=='D') pets[i].x++;\n                else if(ch=='L') pets[i].y--;\n                else if(ch=='R') pets[i].y++;\n            }\n        }\n        // apply builds\n        for(int key: buildTargets){\n            int wx=key/64, wy=key%64;\n            if(wx>=1 && wx<=30 && wy>=1 && wy<=30) wall[wx][wy]=true;\n        }\n        // move humans\n        for(int i=0;i<M;i++){\n            char ac=actions[i];\n            if(ac=='U') hx[i]--;\n            else if(ac=='D') hx[i]++;\n            else if(ac=='L') hy[i]--;\n            else if(ac=='R') hy[i]++;\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int DIRS = 4;\nconst int L = 200;\nconst double TIME_LIMIT_TOTAL = 1.95;\nconst double TIME_LIMIT_MAIN = 1.85;\n\nint startId, targetId;\ndouble p_forget, q_exec;\n\nint moveTbl[N][DIRS];\ndouble weightArr[L];\ndouble weight_q[L];\nint tieOrd[4];\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> uni01(0.0, 1.0);\n\ninline int idx(int i, int j) { return i * W + j; }\n\nvoid build_moves(const vector<string> &h, const vector<string> &v) {\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int id = idx(i, j);\n            // Up\n            if (i == 0 || v[i - 1][j] == '1')\n                moveTbl[id][0] = id;\n            else\n                moveTbl[id][0] = idx(i - 1, j);\n            // Down\n            if (i == H - 1 || v[i][j] == '1')\n                moveTbl[id][1] = id;\n            else\n                moveTbl[id][1] = idx(i + 1, j);\n            // Left\n            if (j == 0 || h[i][j - 1] == '1')\n                moveTbl[id][2] = id;\n            else\n                moveTbl[id][2] = idx(i, j - 1);\n            // Right\n            if (j == W - 1 || h[i][j] == '1')\n                moveTbl[id][3] = id;\n            else\n                moveTbl[id][3] = idx(i, j + 1);\n        }\n    }\n}\n\nvoid set_tie_order(int dv, int dh) {\n    // Prefer directions towards target; fallback order D,R,L,U\n    vector<pair<int,int>> dirs;\n    // pair of priority (smaller better), dir\n    dirs.push_back({-dv, 1}); // Down\n    dirs.push_back({-dh, 3}); // Right\n    dirs.push_back({dh, 2});  // Left\n    dirs.push_back({dv, 0});  // Up\n    sort(dirs.begin(), dirs.end(), [](auto &a, auto &b){\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    for (int k = 0; k < 4; k++) tieOrd[k] = dirs[k].second;\n}\n\nvector<int> bfs_path(bool monotone_only) {\n    vector<int> prev(N, -1), prevDir(N, -1);\n    vector<char> vis(N, 0);\n    queue<int> q;\n    vis[startId] = 1;\n    q.push(startId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        if (u == targetId) break;\n        for (int dir = 0; dir < DIRS; dir++) {\n            if (monotone_only && !(dir == 1 || dir == 3)) continue; // only D or R\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (!vis[nb]) {\n                vis[nb] = 1;\n                prev[nb] = u;\n                prevDir[nb] = dir;\n                q.push(nb);\n            }\n        }\n    }\n    if (!vis[targetId]) return {};\n    vector<int> path;\n    int cur = targetId;\n    while (cur != startId) {\n        int d = prevDir[cur];\n        path.push_back(d);\n        cur = prev[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid compute_distances(vector<double> &dist1, vector<double> &dist2) {\n    dist1.assign(N, 1e9);\n    queue<int> q;\n    dist1[targetId] = 0;\n    q.push(targetId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        double du = dist1[u];\n        for (int dir = 0; dir < DIRS; dir++) {\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (dist1[nb] > du + 1) {\n                dist1[nb] = du + 1;\n                q.push(nb);\n            }\n        }\n    }\n    dist2.resize(N);\n    for (int i = 0; i < N; i++) dist2[i] = dist1[i] * dist1[i];\n}\n\nvector<int> greedy_seq(const vector<double> &dist, double eps) {\n    vector<double> cur(N, 0.0), nxt(N, 0.0);\n    cur[startId] = 1.0;\n    vector<int> seq(L);\n    for (int t = 0; t < L; t++) {\n        double bestVal = 1e100;\n        int bestDir = tieOrd[0];\n        for (int k = 0; k < 4; k++) {\n            int dir = tieOrd[k];\n            double s = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                s += pu * dist[nb];\n            }\n            if (s < bestVal) {\n                bestVal = s;\n                bestDir = dir;\n            }\n        }\n        if (eps > 0.0 && uni01(rng) < eps) {\n            bestDir = rng() & 3ULL;\n        }\n        seq[t] = bestDir;\n        fill(nxt.begin(), nxt.end(), 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb != targetId) nxt[nb] += mv;\n            nxt[u] += pu * p_forget;\n        }\n        cur.swap(nxt);\n    }\n    return seq;\n}\n\nvector<int> greedy_suffix(const double *dist0, int len, const vector<double> &heuristic) {\n    vector<double> cur(dist0, dist0 + N);\n    vector<double> nxt(N, 0.0);\n    vector<int> seq(len);\n    for (int t = 0; t < len; t++) {\n        double bestVal = 1e100;\n        int bestDir = tieOrd[0];\n        for (int k = 0; k < 4; k++) {\n            int dir = tieOrd[k];\n            double s = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                s += pu * heuristic[nb];\n            }\n            if (s < bestVal) {\n                bestVal = s;\n                bestDir = dir;\n            }\n        }\n        seq[t] = bestDir;\n        fill(nxt.begin(), nxt.end(), 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb != targetId) nxt[nb] += mv;\n            nxt[u] += pu * p_forget;\n        }\n        cur.swap(nxt);\n    }\n    return seq;\n}\n\nvector<int> greedy_from(const vector<double> &dist, int tStart, const vector<double> &heuristic) {\n    int len = L - tStart;\n    return greedy_suffix(dist.data(), len, heuristic);\n}\n\nvector<int> repeat_path_seed(const vector<int> &path, int r) {\n    vector<int> seq;\n    if (path.empty()) return seq;\n    seq.reserve(L);\n    for (int d : path) {\n        for (int k = 0; k < r && (int)seq.size() < L; k++) seq.push_back(d);\n        if ((int)seq.size() >= L) break;\n    }\n    while ((int)seq.size() < L) {\n        for (int d : path) {\n            if ((int)seq.size() >= L) break;\n            seq.push_back(d);\n        }\n    }\n    if ((int)seq.size() > L) seq.resize(L);\n    return seq;\n}\n\nvector<vector<int>> repeat_variants(const vector<int> &path) {\n    vector<vector<int>> res;\n    int len = (int)path.size();\n    if (len == 0) return res;\n    int maxR = max(1, min(15, L / len));\n    for (int r = 1; r <= maxR; r++) {\n        res.push_back(repeat_path_seed(path, r));\n    }\n    return res;\n}\n\nvector<int> ratio_seed(int dv, int dh) {\n    vector<int> seq;\n    seq.reserve(L);\n    int total = max(1, dv + dh);\n    int nD = (int)round((double)L * dv / total);\n    nD = max(0, min(L, nD));\n    int nR = L - nD;\n    int cD = 0, cR = 0;\n    while ((int)seq.size() < L) {\n        double pd = (nD - cD);\n        double pr = (nR - cR);\n        if (pd <= 0) {\n            seq.push_back(3);\n            cR++;\n        } else if (pr <= 0) {\n            seq.push_back(1);\n            cD++;\n        } else {\n            double probD = pd / (pd + pr);\n            if (uni01(rng) < probD) {\n                seq.push_back(1);\n                cD++;\n            } else {\n                seq.push_back(3);\n                cR++;\n            }\n        }\n    }\n    return seq;\n}\n\ndouble eval_seq(const vector<int> &seq) {\n    static double cur[N], nxt[N];\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double score = 0.0;\n    for (int t = 0; t < L; t++) {\n        int dir = seq[t];\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][dir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\nstatic double backVal[L + 1][N];\nstatic double fwdProb[L + 1][N];\n\nvoid compute_backward(const vector<int> &seq) {\n    for (int u = 0; u < N; u++) backVal[L][u] = 0.0;\n    for (int t = L - 1; t >= 0; t--) {\n        int dir = seq[t];\n        double wq = weight_q[t];\n        const double *next = backVal[t + 1];\n        double *cur = backVal[t];\n        for (int u = 0; u < N; u++) {\n            int nb = moveTbl[u][dir];\n            double val = p_forget * next[u];\n            if (nb == targetId) {\n                val += wq;\n            } else {\n                val += q_exec * next[nb];\n            }\n            cur[u] = val;\n        }\n    }\n}\n\nvoid compute_forward(const vector<int> &seq) {\n    for (int u = 0; u < N; u++) fwdProb[0][u] = 0.0;\n    fwdProb[0][startId] = 1.0;\n    for (int t = 0; t < L; t++) {\n        int dir = seq[t];\n        double *cur = fwdProb[t];\n        double *nxt = fwdProb[t + 1];\n        for (int u = 0; u < N; u++) nxt[u] = 0.0;\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            nxt[u] += pu * p_forget;\n            int nb = moveTbl[u][dir];\n            if (nb != targetId) nxt[nb] += pu * q_exec;\n        }\n    }\n}\n\n// Coordinate ascent by single-position mutation using forward/backward\nvoid local_improve(vector<int> &seq, double &bestScore,\n                   const chrono::steady_clock::time_point &time_start) {\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > TIME_LIMIT_TOTAL) break;\n        compute_forward(seq);\n        compute_backward(seq);\n        double baseScore = backVal[0][startId];\n        double bestDelta = 1e-9;\n        int bestT = -1, bestDir = -1;\n        for (int t = 0; t < L; t++) {\n            if ((t & 31) == 0) {\n                elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > TIME_LIMIT_TOTAL) break;\n            }\n            double baseline_chunk = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = fwdProb[t][u];\n                if (pu == 0.0) continue;\n                baseline_chunk += pu * backVal[t][u];\n            }\n            for (int dir = 0; dir < 4; dir++) {\n                if (dir == seq[t]) continue;\n                double newChunk = 0.0;\n                for (int u = 0; u < N; u++) {\n                    double pu = fwdProb[t][u];\n                    if (pu == 0.0) continue;\n                    int nb = moveTbl[u][dir];\n                    double v = p_forget * backVal[t + 1][u];\n                    if (nb == targetId) v += weight_q[t];\n                    else v += q_exec * backVal[t + 1][nb];\n                    newChunk += pu * v;\n                }\n                double delta = newChunk - baseline_chunk;\n                if (delta > bestDelta) {\n                    bestDelta = delta;\n                    bestT = t;\n                    bestDir = dir;\n                }\n            }\n        }\n        if (bestT == -1) break;\n        seq[bestT] = bestDir;\n        baseScore += bestDelta;\n        if (baseScore > bestScore) {\n            bestScore = baseScore;\n        }\n    }\n}\n\ndouble build_new_seq([[maybe_unused]] const vector<int> &oldSeq, vector<int> &outSeq) {\n    static double cur[N], nxt[N];\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double score = 0.0;\n    for (int t = 0; t < L; t++) {\n        double stay = 0.0;\n        double *nextBack = backVal[t + 1];\n        for (int u = 0; u < N; u++) {\n            stay += cur[u] * nextBack[u];\n        }\n        stay *= p_forget;\n        double bestVal = -1e100;\n        int bestDir = tieOrd[0];\n        for (int ki = 0; ki < 4; ki++) {\n            int dir = tieOrd[ki];\n            double sum = stay;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                if (nb == targetId) sum += pu * weight_q[t];\n                else sum += pu * q_exec * nextBack[nb];\n            }\n            if (sum > bestVal) {\n                bestVal = sum;\n                bestDir = dir;\n            }\n        }\n        outSeq[t] = bestDir;\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\nstruct BeamState {\n    vector<double> dist;\n    double score;\n    vector<int> seq;\n};\n\nvector<int> beam_seed(int depth, int width, const vector<double> &heuristic) {\n    BeamState init;\n    init.dist.assign(N, 0.0);\n    init.dist[startId] = 1.0;\n    init.score = 0.0;\n    init.seq.clear();\n    vector<BeamState> cur;\n    cur.reserve(width * 4);\n    cur.push_back(move(init));\n    for (int t = 0; t < depth; t++) {\n        vector<BeamState> nxtStates;\n        nxtStates.reserve(width * 4);\n        for (const auto &st : cur) {\n            for (int dir = 0; dir < 4; dir++) {\n                BeamState ns;\n                ns.dist.assign(N, 0.0);\n                ns.seq = st.seq;\n                ns.seq.push_back(dir);\n                double add = 0.0;\n                for (int u = 0; u < N; u++) {\n                    double pu = st.dist[u];\n                    if (pu == 0.0) continue;\n                    int nb = moveTbl[u][dir];\n                    double mv = pu * q_exec;\n                    if (nb == targetId) {\n                        add += mv * weightArr[t];\n                    } else {\n                        ns.dist[nb] += mv;\n                    }\n                    ns.dist[u] += pu * p_forget;\n                }\n                ns.score = st.score + add;\n                nxtStates.push_back(move(ns));\n            }\n        }\n        if ((int)nxtStates.size() > width) {\n            nth_element(nxtStates.begin(), nxtStates.begin() + width, nxtStates.end(),\n                        [](const BeamState &a, const BeamState &b) { return a.score > b.score; });\n            nxtStates.resize(width);\n        }\n        cur.swap(nxtStates);\n    }\n    const BeamState *best = &cur[0];\n    for (const auto &st : cur) {\n        if (st.score > best->score) best = &st;\n    }\n    vector<int> suffix = greedy_from(best->dist, depth, heuristic);\n    vector<int> seq = best->seq;\n    seq.insert(seq.end(), suffix.begin(), suffix.end());\n    if ((int)seq.size() > L) seq.resize(L);\n    return seq;\n}\n\n// Precompute all sequences of length up to 6\nvector<vector<int>> preSeq[7];\nvoid init_preSeq() {\n    for (int len = 1; len <= 6; len++) {\n        int total = 1 << (2 * len);\n        preSeq[len].resize(total, vector<int>(len));\n        for (int code = 0; code < total; code++) {\n            int tmp = code;\n            for (int i = 0; i < len; i++) {\n                preSeq[len][code][i] = tmp & 3;\n                tmp >>= 2;\n            }\n        }\n    }\n}\n\n// Block optimization for small window lengths 6,5,4\nvoid block_optimize(vector<int> &seq, double &bestScore,\n                    const chrono::steady_clock::time_point &time_start) {\n    static double curSim[N], nxtSim[N];\n    auto simulate = [&](const vector<int> &dirs, int pos, const double *dist0, const double *backEnd) {\n        int len = dirs.size();\n        memcpy(curSim, dist0, sizeof(double) * N);\n        double reward = 0.0;\n        for (int s = 0; s < len; s++) {\n            int dir = dirs[s];\n            int tIdx = pos + s;\n            fill(nxtSim, nxtSim + N, 0.0);\n            for (int u = 0; u < N; u++) {\n                double pu = curSim[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                double mv = pu * q_exec;\n                if (nb == targetId) {\n                    reward += mv * weightArr[tIdx];\n                } else {\n                    nxtSim[nb] += mv;\n                }\n                nxtSim[u] += pu * p_forget;\n            }\n            swap(curSim, nxtSim);\n        }\n        double tail = 0.0;\n        for (int u = 0; u < N; u++) tail += curSim[u] * backEnd[u];\n        return reward + tail;\n    };\n    compute_forward(seq);\n    compute_backward(seq);\n    double totalScore = backVal[0][startId];\n    struct LenTry { int len; int tries; };\n    vector<LenTry> lts = { {6,6}, {5,8}, {4,8} };\n    for (auto lt : lts) {\n        int len = lt.len;\n        int tries = lt.tries;\n        int maxPos = L - len;\n        if (maxPos < 0) continue;\n        for (int it = 0; it < tries; it++) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n            if (elapsed > TIME_LIMIT_TOTAL * 0.97) return;\n            int pos = rng() % (maxPos + 1);\n            const double *dist0 = fwdProb[pos];\n            const double *backEnd = backVal[pos + len];\n            double baseline_chunk = 0.0;\n            for (int u = 0; u < N; u++) baseline_chunk += dist0[u] * backVal[pos][u];\n            double bestChunk = baseline_chunk;\n            int bestIdx = -1;\n            int totalCodes = preSeq[len].size();\n            for (int code = 0; code < totalCodes; code++) {\n                double val = simulate(preSeq[len][code], pos, dist0, backEnd);\n                if (val > bestChunk) {\n                    bestChunk = val;\n                    bestIdx = code;\n                }\n            }\n            if (bestIdx != -1) {\n                for (int s = 0; s < len; s++) {\n                    seq[pos + s] = preSeq[len][bestIdx][s];\n                }\n                compute_forward(seq);\n                compute_backward(seq);\n                totalScore = backVal[0][startId];\n                if (totalScore > bestScore) bestScore = totalScore;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj, ti, tj;\n    if (!(cin >> si >> sj >> ti >> tj >> p_forget)) return 0;\n    startId = idx(si, sj);\n    targetId = idx(ti, tj);\n    q_exec = 1.0 - p_forget;\n    vector<string> h(H), v(H - 1);\n    for (int i = 0; i < H; i++) cin >> h[i];\n    for (int i = 0; i < H - 1; i++) cin >> v[i];\n    for (int t = 0; t < L; t++) {\n        weightArr[t] = 400.0 - t;\n        weight_q[t] = weightArr[t] * q_exec;\n    }\n    auto time_start = chrono::steady_clock::now();\n    init_preSeq();\n\n    build_moves(h, v);\n    set_tie_order(ti - si, tj - sj);\n    vector<double> dist1, dist2;\n    compute_distances(dist1, dist2);\n    vector<int> shortest = bfs_path(false);\n    vector<int> monotone = bfs_path(true);\n\n    vector<vector<int>> seeds;\n    seeds.push_back(greedy_seq(dist1, 0.0));\n    seeds.push_back(greedy_seq(dist2, 0.0));\n    seeds.push_back(greedy_seq(dist1, 0.1));\n    seeds.push_back(greedy_seq(dist1, 0.3));\n    int rep_suggest = max(1, min(10, (int)ceil(log(0.1) / log(max(0.05, p_forget)))));\n    if (!shortest.empty()) seeds.push_back(repeat_path_seed(shortest, rep_suggest));\n    if (!monotone.empty()) seeds.push_back(repeat_path_seed(monotone, rep_suggest));\n    auto rv1 = repeat_variants(shortest);\n    auto rv2 = repeat_variants(monotone);\n    seeds.insert(seeds.end(), rv1.begin(), rv1.end());\n    seeds.insert(seeds.end(), rv2.begin(), rv2.end());\n    seeds.push_back(ratio_seed(ti - si, tj - sj));\n    int beamDepth = 22;\n    int beamWidth = 32;\n    seeds.push_back(beam_seed(beamDepth, beamWidth, dist1));\n    seeds.push_back(beam_seed(beamDepth, beamWidth, dist2));\n\n    vector<pair<double, vector<int>>> seedScores;\n    seedScores.reserve(seeds.size());\n    for (auto &s : seeds) {\n        if ((int)s.size() != L) continue;\n        double sc = eval_seq(s);\n        seedScores.emplace_back(sc, s);\n    }\n    if (seedScores.empty()) return 0;\n    sort(seedScores.begin(), seedScores.end(),\n         [](const auto &a, const auto &b) { return a.first > b.first; });\n\n    double bestScore = -1.0;\n    vector<int> bestSeq;\n\n    int topK = min(5, (int)seedScores.size());\n    for (int i = 0; i < topK; i++) {\n        vector<int> seq = seedScores[i].second;\n        double curScore = seedScores[i].first;\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > TIME_LIMIT_MAIN) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(seq, newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 200) break;\n        }\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > TIME_LIMIT_MAIN) break;\n    }\n\n    // Random restarts with greedy noise\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > TIME_LIMIT_MAIN) break;\n        double eps = uni01(rng) * uni01(rng) * 0.5;\n        const vector<double> &heur = (rng() & 1) ? dist1 : dist2;\n        vector<int> seq = greedy_seq(heur, eps);\n        double curScore = eval_seq(seq);\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > TIME_LIMIT_MAIN) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(seq, newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 50) break;\n        }\n    }\n\n    // Tail regeneration using greedy suffix\n    double regen_limit = TIME_LIMIT_TOTAL - 0.08;\n    if (regen_limit < TIME_LIMIT_MAIN) regen_limit = TIME_LIMIT_MAIN;\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > regen_limit) break;\n        compute_forward(bestSeq);\n        int k = rng() % L;\n        const vector<double> *heur = (rng() & 1) ? &dist1 : &dist2;\n        int len = L - k;\n        if (len <= 0) break;\n        vector<int> suffix = greedy_suffix(fwdProb[k], len, *heur);\n        vector<int> newSeq;\n        newSeq.reserve(L);\n        newSeq.insert(newSeq.end(), bestSeq.begin(), bestSeq.begin() + k);\n        newSeq.insert(newSeq.end(), suffix.begin(), suffix.end());\n        double newScore = eval_seq(newSeq);\n        if (newScore > bestScore) {\n            bestScore = newScore;\n            bestSeq = move(newSeq);\n        }\n    }\n\n    // Block optimization\n    block_optimize(bestSeq, bestScore, time_start);\n\n    // Final coordinate ascent improvement on the best sequence\n    local_improve(bestSeq, bestScore, time_start);\n\n    string out;\n    out.reserve(L);\n    for (int d : bestSeq) {\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        out.push_back(c);\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOT = N * N * 4;\nconst int di[4] = {0, -1, 0, 1};   // L,U,R,D\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Heuristic weights\nconst int MATCH_REWARD = 3;\nconst int MISMATCH_PENALTY = 2;\nconst int BOUNDARY_PENALTY = 3;\nconst int PAIR_MATCH_REWARD = 5;\nconst int PAIR_MISMATCH_PENALTY = 4;\n\nint toMap[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 usedMask[8];\nint rotMap[8][4];\nvector<array<int, 2>> pairsOfType[8];\n\ninline bool uses(int t, int dir) { return (usedMask[t] >> dir) & 1; }\ninline int apply_rot(int base, int r) { return rotMap[base][r]; }\ninline int idx_of(int i, int j, int d) { return ((i * N + j) << 2) | d; }\n\nint baseType[N][N];\nint rotCnt[N][N];\nint curType[N][N];\n\ninline int edge_contrib(int i, int j, int dir) {\n    int t = curType[i][j];\n    bool a = uses(t, dir);\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n        return a ? -BOUNDARY_PENALTY : 0;\n    }\n    bool b = uses(curType[ni][nj], dir ^ 2);\n    if (a && b) return MATCH_REWARD;\n    else if (a || b) return -MISMATCH_PENALTY;\n    else return 0;\n}\n\ninline int calc_edges_counted(int i, int j) {\n    int res = 0;\n    if (j < N - 1) res += edge_contrib(i, j, 2);\n    if (i < N - 1) res += edge_contrib(i, j, 3);\n    if (j == 0) res += edge_contrib(i, j, 0);\n    else res += edge_contrib(i, j - 1, 2);\n    if (i == 0) res += edge_contrib(i, j, 1);\n    else res += edge_contrib(i - 1, j, 3);\n    return res;\n}\n\ninline int compute_tile_pair(int i, int j) {\n    int t = curType[i][j];\n    int res = 0;\n    for (auto &pr : pairsOfType[t]) {\n        int a = pr[0], b = pr[1];\n        bool ma = false, mb = false;\n        int ni = i + di[a], nj = j + dj[a];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            ma = uses(curType[ni][nj], a ^ 2);\n        }\n        ni = i + di[b]; nj = j + dj[b];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            mb = uses(curType[ni][nj], b ^ 2);\n        }\n        if (ma && mb) res += PAIR_MATCH_REWARD;\n        else if (ma || mb) res -= PAIR_MISMATCH_PENALTY;\n    }\n    return res;\n}\n\n// Fast computation of real score (product of two largest cycles)\nint compute_real_score_fast() {\n    static int nextArr[TOT];\n    static unsigned char state[TOT];\n    static int depth[TOT];\n    int idx = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int t = curType[i][j];\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 == -1) {\n                nextArr[idx++] = -1;\n                continue;\n            }\n            int ni = i + di[d2], nj = j + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                nextArr[idx++] = -1;\n                continue;\n            }\n            int nd = (d2 + 2) & 3;\n            nextArr[idx++] = idx_of(ni, nj, nd);\n        }\n    }\n    memset(state, 0, TOT);\n    int best1 = 0, best2 = 0;\n    static int stack[TOT];\n    for (int v = 0; v < TOT; v++) {\n        if (state[v]) continue;\n        int top = 0;\n        int u = v;\n        while (u != -1 && state[u] == 0) {\n            state[u] = 1;\n            depth[u] = top;\n            stack[top++] = u;\n            u = nextArr[u];\n        }\n        if (u != -1 && state[u] == 1) {\n            int cycLen = top - depth[u];\n            if (cycLen > best1) {\n                best2 = best1;\n                best1 = cycLen;\n            } else if (cycLen > best2) {\n                best2 = cycLen;\n            }\n        }\n        for (int k = 0; k < top; k++) state[stack[k]] = 2;\n    }\n    if (best2 == 0) return 0;\n    return best1 * best2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Precompute masks and rotations and pairs\n    for (int t = 0; t < 8; t++) {\n        int m = 0;\n        for (int d = 0; d < 4; d++) if (toMap[t][d] != -1) m |= (1 << d);\n        usedMask[t] = m;\n    }\n    int nextType[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int b = 0; b < 8; b++) {\n        rotMap[b][0] = b;\n        for (int r = 1; r < 4; r++) rotMap[b][r] = nextType[rotMap[b][r - 1]];\n    }\n    for (int t = 0; t < 8; t++) {\n        pairsOfType[t].clear();\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 != -1 && d < d2) pairsOfType[t].push_back({d, d2});\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) baseType[i][j] = s[j] - '0';\n    }\n\n    // Initial rotation: minimize boundary usage\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int bestR = 0, bestPen = 100;\n        for (int r = 0; r < 4; r++) {\n            int t = apply_rot(baseType[i][j], r);\n            int pen = 0;\n            if (i == 0 && uses(t, 1)) pen++;\n            if (i == N - 1 && uses(t, 3)) pen++;\n            if (j == 0 && uses(t, 0)) pen++;\n            if (j == N - 1 && uses(t, 2)) pen++;\n            if (pen < bestPen) { bestPen = pen; bestR = r; }\n        }\n        rotCnt[i][j] = bestR;\n        curType[i][j] = apply_rot(baseType[i][j], bestR);\n    }\n\n    int edgeScore = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (j < N - 1) edgeScore += edge_contrib(i, j, 2);\n        if (i < N - 1) edgeScore += edge_contrib(i, j, 3);\n        if (j == 0) edgeScore += edge_contrib(i, j, 0);\n        if (i == 0) edgeScore += edge_contrib(i, j, 1);\n    }\n    int pairScore = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        pairScore += compute_tile_pair(i, j);\n    }\n    int heurScore = edgeScore + pairScore;\n    int bestHeur = heurScore;\n    int bestRotHeur[N][N];\n    int bestTypeHeur[N][N];\n    memcpy(bestRotHeur, rotCnt, sizeof(rotCnt));\n    memcpy(bestTypeHeur, curType, sizeof(curType));\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto timeStart = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9;\n    const double SA_DURATION = 1.2;\n    const double T0 = 5.0, T1 = 0.1;\n    double temp = T0;\n    int iter = 0;\n\n    while (true) {\n        iter++;\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - timeStart).count();\n            if (elapsed > SA_DURATION) break;\n            double progress = elapsed / SA_DURATION;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int newRot = rng() & 3;\n        if (newRot == rotCnt[i][j]) continue;\n        int oldType = curType[i][j];\n        int newType = apply_rot(baseType[i][j], newRot);\n\n        int oldEdges = calc_edges_counted(i, j);\n        int oldPairs = compute_tile_pair(i, j);\n        if (i > 0) oldPairs += compute_tile_pair(i - 1, j);\n        if (i + 1 < N) oldPairs += compute_tile_pair(i + 1, j);\n        if (j > 0) oldPairs += compute_tile_pair(i, j - 1);\n        if (j + 1 < N) oldPairs += compute_tile_pair(i, j + 1);\n\n        curType[i][j] = newType;\n\n        int newEdges = calc_edges_counted(i, j);\n        int newPairs = compute_tile_pair(i, j);\n        if (i > 0) newPairs += compute_tile_pair(i - 1, j);\n        if (i + 1 < N) newPairs += compute_tile_pair(i + 1, j);\n        if (j > 0) newPairs += compute_tile_pair(i, j - 1);\n        if (j + 1 < N) newPairs += compute_tile_pair(i, j + 1);\n\n        int delta = (newEdges - oldEdges) + (newPairs - oldPairs);\n        if (delta >= 0) {\n            edgeScore += (newEdges - oldEdges);\n            pairScore += (newPairs - oldPairs);\n            heurScore += delta;\n            rotCnt[i][j] = newRot;\n        } else {\n            double prob = exp(double(delta) / temp);\n            double rnd = (double)rng() / (double)rng.max();\n            if (rnd < prob) {\n                edgeScore += (newEdges - oldEdges);\n                pairScore += (newPairs - oldPairs);\n                heurScore += delta;\n                rotCnt[i][j] = newRot;\n            } else {\n                curType[i][j] = oldType; // revert\n            }\n        }\n        if (heurScore > bestHeur) {\n            bestHeur = heurScore;\n            memcpy(bestRotHeur, rotCnt, sizeof(rotCnt));\n            memcpy(bestTypeHeur, curType, sizeof(curType));\n        }\n    }\n\n    // Start from best heuristic state\n    memcpy(rotCnt, bestRotHeur, sizeof(rotCnt));\n    memcpy(curType, bestTypeHeur, sizeof(curType));\n\n    int curReal = compute_real_score_fast();\n    int bestReal = curReal;\n    int bestRot[N][N];\n    memcpy(bestRot, rotCnt, sizeof(rotCnt));\n    int bestType[N][N];\n    memcpy(bestType, curType, sizeof(curType));\n\n    // Greedy local search using real score\n    int greedyIter = 0;\n    while (true) {\n        greedyIter++;\n        if ((greedyIter & 31) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - timeStart).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int origRot = rotCnt[i][j];\n        int origType = curType[i][j];\n        int bestLocalRot = origRot;\n        int bestLocalScore = curReal;\n\n        for (int r = 0; r < 4; r++) {\n            if (r == origRot) continue;\n            curType[i][j] = apply_rot(baseType[i][j], r);\n            int sc = compute_real_score_fast();\n            if (sc > bestLocalScore) {\n                bestLocalScore = sc;\n                bestLocalRot = r;\n            }\n        }\n        curType[i][j] = origType; // revert\n        if (bestLocalRot != origRot) {\n            rotCnt[i][j] = bestLocalRot;\n            curType[i][j] = apply_rot(baseType[i][j], bestLocalRot);\n            curReal = bestLocalScore;\n            if (curReal > bestReal) {\n                bestReal = curReal;\n                memcpy(bestRot, rotCnt, sizeof(rotCnt));\n                memcpy(bestType, curType, sizeof(curType));\n            }\n        }\n    }\n\n    // Output best rotation counts\n    string out;\n    out.reserve(N * N);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        out.push_back(char('0' + (bestRot[i][j] & 3)));\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Metric {\n    int tree_size;   // size of largest acyclic component\n    int comp_size;   // size of largest connected component\n    int good_edges;  // total matched edges\n};\n\nstruct Solver {\n    int N, Tlim, NN;\n    int full_size;\n    int init_zero;\n    vector<uint8_t> init_board;\n    vector<vector<pair<char,int>>> moves_from;\n    mt19937 rng;\n    chrono::steady_clock::time_point end_time;\n    double EPS = 0.15; // random move probability\n\n    Solver() {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    }\n\n    int hexval(char c){\n        if('0'<=c && c<='9') return c-'0';\n        return 10 + (c-'a');\n    }\n\n    Metric compute_metric(const vector<uint8_t>& b){\n        static uint8_t vis[100];\n        static uint8_t mark[100];\n        memset(vis, 0, NN);\n        memset(mark, 0, NN);\n        int good_edges = 0;\n        for(int r=0; r<N; r++){\n            int base = r*N;\n            for(int c=0; c<N; c++){\n                int idx = base + c;\n                int t = b[idx];\n                if(t==0) continue;\n                if(c+1 < N){\n                    int t2 = b[idx+1];\n                    if(t2!=0 && (t&4) && (t2&1)) good_edges++;\n                }\n                if(r+1 < N){\n                    int t2 = b[idx+N];\n                    if(t2!=0 && (t&8) && (t2&2)) good_edges++;\n                }\n            }\n        }\n        int best_tree = 0;\n        int best_comp = 0;\n        vector<int> q;\n        q.reserve(NN);\n        for(int idx=0; idx<NN; idx++){\n            if(b[idx]==0 || vis[idx]) continue;\n            q.clear();\n            vis[idx]=1;\n            q.push_back(idx);\n            for(int qi=0; qi<(int)q.size(); qi++){\n                int u = q[qi];\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(r>0){\n                    int v = u - N;\n                    if(!vis[v] && b[v]!=0 && (t&2) && (b[v]&8)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(!vis[v] && b[v]!=0 && (t&8) && (b[v]&2)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(c>0){\n                    int v = u - 1;\n                    if(!vis[v] && b[v]!=0 && (t&1) && (b[v]&4)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(c+1<N){\n                    int v = u + 1;\n                    if(!vis[v] && b[v]!=0 && (t&4) && (b[v]&1)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n            }\n            for(int u: q) mark[u]=1;\n            int edges = 0;\n            for(int u: q){\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(c+1<N){\n                    int v = u + 1;\n                    if(mark[v] && (t&4) && (b[v]&1)) edges++;\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(mark[v] && (t&8) && (b[v]&2)) edges++;\n                }\n            }\n            for(int u: q) mark[u]=0;\n            int sz = (int)q.size();\n            if(sz > best_comp) best_comp = sz;\n            if(edges == sz - 1){\n                if(sz > best_tree) best_tree = sz;\n            }\n        }\n        return {best_tree, best_comp, good_edges};\n    }\n\n    char inverse_move(char c){\n        if(c=='U') return 'D';\n        if(c=='D') return 'U';\n        if(c=='L') return 'R';\n        if(c=='R') return 'L';\n        return '?';\n    }\n\n    bool better_metric(const Metric& a, const Metric& b){\n        if(a.tree_size != b.tree_size) return a.tree_size > b.tree_size;\n        if(a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        return a.good_edges > b.good_edges;\n    }\n\n    pair<Metric,string> walk(){\n        vector<uint8_t> board = init_board;\n        int zero = init_zero;\n        string moves;\n        moves.reserve(Tlim);\n        Metric curr = compute_metric(board);\n        Metric best = curr;\n        string best_seq;\n        char prev_move = '?';\n        uniform_real_distribution<double> dist01(0.0,1.0);\n        for(int step=0; step<Tlim; step++){\n            if(chrono::steady_clock::now() > end_time) break;\n            const auto& opts_all = moves_from[zero];\n            vector<pair<char,int>> opts;\n            opts.reserve(4);\n            char inv = inverse_move(prev_move);\n            for(auto &p: opts_all){\n                if(inv==p.first && (int)opts_all.size()>1) continue;\n                opts.push_back(p);\n            }\n            if(opts.empty()){\n                opts = opts_all;\n            }\n            char chosen_move;\n            int chosen_delta;\n            Metric chosen_metric;\n            double rnd = dist01(rng);\n            if(rnd < EPS){\n                uniform_int_distribution<int> dist(0, (int)opts.size()-1);\n                int k = dist(rng);\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                chosen_metric = compute_metric(board);\n            }else{\n                Metric best_nei = {-1,-1,-1};\n                vector<int> best_idx;\n                best_idx.reserve(4);\n                vector<Metric> metrics(opts.size());\n                for(int i=0; i<(int)opts.size(); i++){\n                    int d = opts[i].second;\n                    swap(board[zero], board[zero+d]);\n                    Metric m = compute_metric(board);\n                    swap(board[zero], board[zero+d]);\n                    metrics[i]=m;\n                    if(better_metric(m, best_nei)){\n                        best_nei = m;\n                        best_idx.clear();\n                        best_idx.push_back(i);\n                    }else if(m.tree_size == best_nei.tree_size &&\n                             m.comp_size == best_nei.comp_size &&\n                             m.good_edges == best_nei.good_edges){\n                        best_idx.push_back(i);\n                    }\n                }\n                uniform_int_distribution<int> dist(0, (int)best_idx.size()-1);\n                int k = best_idx[dist(rng)];\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                chosen_metric = metrics[k];\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n            }\n            moves.push_back(chosen_move);\n            prev_move = chosen_move;\n            curr = chosen_metric;\n            if(better_metric(curr, best)){\n                best = curr;\n                best_seq = moves;\n                if(best.tree_size == full_size) break;\n            }\n        }\n        return {best, best_seq};\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin >> N >> Tlim;\n        NN = N*N;\n        full_size = NN - 1;\n        init_board.resize(NN);\n        for(int i=0;i<N;i++){\n            string s; cin >> s;\n            for(int j=0;j<N;j++){\n                int v = hexval(s[j]);\n                init_board[i*N + j] = (uint8_t)v;\n                if(v==0) init_zero = i*N + j;\n            }\n        }\n        // precompute moves\n        moves_from.resize(NN);\n        for(int pos=0; pos<NN; pos++){\n            int r = pos / N;\n            int c = pos - r*N;\n            if(r>0) moves_from[pos].push_back({'U', -N});\n            if(r+1<N) moves_from[pos].push_back({'D', N});\n            if(c>0) moves_from[pos].push_back({'L', -1});\n            if(c+1<N) moves_from[pos].push_back({'R', 1});\n        }\n        Metric init_metric = compute_metric(init_board);\n        Metric best_global = init_metric;\n        string best_seq;\n        end_time = chrono::steady_clock::now() + chrono::milliseconds(2800);\n        while(chrono::steady_clock::now() < end_time){\n            auto res = walk();\n            Metric m = res.first;\n            string seq = res.second;\n            if(better_metric(m, best_global)){\n                best_global = m;\n                best_seq = seq;\n            }else if(m.tree_size == best_global.tree_size &&\n                     m.comp_size == best_global.comp_size &&\n                     m.good_edges == best_global.good_edges){\n                if(!seq.empty() && (best_seq.empty() || seq.size() < best_seq.size())){\n                    best_seq = seq;\n                }\n            }\n        }\n        cout << best_seq << \"\\n\";\n    }\n};\n\nint main(){\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    int obj = -1;\n    int V = 0, H = 0;\n    int stepX = 0, stepY = 0;\n    int offx = 0, offy = 0;\n    int mode = 0; // 0: axis (x,y), 1: diag (x+y, x-y)\n    vector<int> vx, vy; // line constants\n};\n\nconst int R = 10000;\nconst int BIG = 1000000000;\nconst double TIME_LIMIT = 2.9;\n\nint N, K;\nint a[11];\nvector<pair<int,int>> pts;\nvector<int> xs, ys, us, vs; // shifted coords for offset calc\n\nmt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nSolution best;\n\n// key for cache: (axis<<20) ^ step (step<=40000 so 16 bits ok)\nunordered_map<long long, vector<int>> offset_cache;\n\nvector<int> get_best_offsets(int step, int axis) {\n    if (step <= 0) return {0};\n    long long key = (static_cast<long long>(axis) << 20) ^ step;\n    auto it = offset_cache.find(key);\n    if (it != offset_cache.end()) return it->second;\n\n    vector<int> cnt(step, 0);\n    const vector<int> *arr;\n    if (axis == 0) arr = &xs;\n    else if (axis == 1) arr = &ys;\n    else if (axis == 2) arr = &us;\n    else arr = &vs;\n    for (int v : *arr) {\n        cnt[v % step]++;\n    }\n    int minc = *min_element(cnt.begin(), cnt.end());\n    vector<int> offs;\n    for (int i = 0; i < step && (int)offs.size() < 12; i++) {\n        if (cnt[i] == minc) offs.push_back(i);\n    }\n    if ((int)offs.size() < 8) {\n        int sec = INT_MAX;\n        for (int c : cnt) if (c > minc) sec = min(sec, c);\n        for (int i = 0; i < step && (int)offs.size() < 16; i++) {\n            if (cnt[i] == sec) offs.push_back(i);\n        }\n    }\n    for (int t = 0; t < 4 && (int)offs.size() < 20; t++) offs.push_back((int)(rng() % step));\n    sort(offs.begin(), offs.end());\n    offs.erase(unique(offs.begin(), offs.end()), offs.end());\n    offset_cache[key] = offs;\n    return offs;\n}\n\n// mode 0: axis grid, mode 1: diag grid (u=x+y,v=x-y)\nint evaluate_grid(int V, int H, int stepX, int offx, int stepY, int offy, int mode, bool update_best = true) {\n    int rows = V + 1;\n    int cols = H + 1;\n    int sz = rows * cols;\n    static vector<int> cnt;\n    cnt.assign(sz, 0);\n\n    if (mode == 0) {\n        int firstX = -R + offx + stepX;\n        int firstY = -R + offy + stepY;\n        for (auto &p : pts) {\n            int x = p.first, y = p.second;\n            int cidx = 0, ridx = 0;\n            if (V > 0) {\n                int diffx = x - firstX;\n                if (diffx >= 0) {\n                    int q = diffx / stepX;\n                    if (q < V && diffx % stepX == 0) continue; // on vertical line\n                    cidx = q + 1;\n                    if (cidx > V) cidx = V;\n                } else cidx = 0;\n            }\n            if (H > 0) {\n                int diffy = y - firstY;\n                if (diffy >= 0) {\n                    int qy = diffy / stepY;\n                    if (qy < H && diffy % stepY == 0) continue; // on horizontal line\n                    ridx = qy + 1;\n                    if (ridx > H) ridx = H;\n                } else ridx = 0;\n            }\n            cnt[cidx * cols + ridx]++;\n        }\n    } else { // diag\n        int firstU = -2 * R + offx + stepX; // u = x+y range [-20000,20000]\n        int firstV = -2 * R + offy + stepY; // v = x-y\n        for (auto &p : pts) {\n            int u = p.first + p.second;\n            int v = p.first - p.second;\n            int cidx = 0, ridx = 0;\n            if (V > 0) {\n                int diffu = u - firstU;\n                if (diffu >= 0) {\n                    int q = diffu / stepX;\n                    if (q < V && diffu % stepX == 0) continue; // on u-line\n                    cidx = q + 1;\n                    if (cidx > V) cidx = V;\n                } else cidx = 0;\n            }\n            if (H > 0) {\n                int diffv = v - firstV;\n                if (diffv >= 0) {\n                    int qv = diffv / stepY;\n                    if (qv < H && diffv % stepY == 0) continue; // on v-line\n                    ridx = qv + 1;\n                    if (ridx > H) ridx = H;\n                } else ridx = 0;\n            }\n            cnt[cidx * cols + ridx]++;\n        }\n    }\n    int b[11] = {0};\n    for (int v : cnt) {\n        if (v >= 1 && v <= 10) b[v]++;\n    }\n    int obj = 0;\n    for (int d = 1; d <= 10; d++) obj += min(a[d], b[d]);\n\n    if (update_best && obj > best.obj) {\n        best.obj = obj;\n        best.V = V; best.H = H;\n        best.stepX = stepX; best.stepY = stepY;\n        best.offx = offx; best.offy = offy;\n        best.mode = mode;\n        best.vx.resize(V);\n        best.vy.resize(H);\n        if (mode == 0) {\n            for (int i = 0; i < V; i++) best.vx[i] = -R + offx + stepX * (i + 1);\n            for (int j = 0; j < H; j++) best.vy[j] = -R + offy + stepY * (j + 1);\n        } else {\n            for (int i = 0; i < V; i++) best.vx[i] = -2 * R + offx + stepX * (i + 1); // u constants\n            for (int j = 0; j < H; j++) best.vy[j] = -2 * R + offy + stepY * (j + 1); // v constants\n        }\n    }\n    return obj;\n}\n\ndouble expected_obj_pair(int V, int H) {\n    int cells = (V + 1) * (H + 1);\n    double lambda = (double)N / cells;\n    double eexp = exp(-lambda);\n    double sum = 0.0;\n    double lp = 1.0;\n    for (int d = 1; d <= 10; d++) {\n        lp *= lambda;\n        double pd = lp * eexp / tgamma(d + 1);\n        double bd = cells * pd;\n        sum += min((double)a[d], bd);\n    }\n    return sum;\n}\n\nvoid optimize_pair(int V, int H, int mode) {\n    int range = (mode == 0) ? 20000 : 40000;\n    int stepX = max(1, range / (V + 1));\n    int stepY = max(1, range / (H + 1));\n    int axisX = (mode == 0) ? 0 : 2;\n    int axisY = (mode == 0) ? 1 : 3;\n    vector<int> offsX = get_best_offsets(stepX, axisX);\n    vector<int> offsY = get_best_offsets(stepY, axisY);\n    if (offsX.empty()) offsX.push_back(0);\n    if (offsY.empty()) offsY.push_back(0);\n    int offx = offsX[0], offy = offsY[0];\n    int cur = evaluate_grid(V, H, stepX, offx, stepY, offy, mode, true);\n    if (elapsed() > TIME_LIMIT) return;\n    const int MAX_SCAN = 1200;\n    bool improved = true;\n    while (improved && elapsed() < TIME_LIMIT) {\n        improved = false;\n        int best_offx = offx;\n        int best_val = cur;\n        if (stepX <= MAX_SCAN) {\n            for (int ox = 0; ox < stepX; ox++) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, ox, stepY, offy, mode, true);\n                if (val > best_val) { best_val = val; best_offx = ox; }\n            }\n        } else {\n            int stride = max(1, stepX / MAX_SCAN);\n            for (int ox = 0; ox < stepX; ox += stride) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, ox, stepY, offy, mode, true);\n                if (val > best_val) { best_val = val; best_offx = ox; }\n            }\n            for (int t = 0; t < 200 && elapsed() < TIME_LIMIT; t++) {\n                int ox = (int)(rng() % stepX);\n                int val = evaluate_grid(V, H, stepX, ox, stepY, offy, mode, true);\n                if (val > best_val) { best_val = val; best_offx = ox; }\n            }\n        }\n        if (best_offx != offx) { offx = best_offx; cur = best_val; improved = true; }\n        if (elapsed() > TIME_LIMIT) break;\n\n        int best_offy = offy;\n        best_val = cur;\n        if (stepY <= MAX_SCAN) {\n            for (int oy = 0; oy < stepY; oy++) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, offx, stepY, oy, mode, true);\n                if (val > best_val) { best_val = val; best_offy = oy; }\n            }\n        } else {\n            int stride = max(1, stepY / MAX_SCAN);\n            for (int oy = 0; oy < stepY; oy += stride) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, stepX, offx, stepY, oy, mode, true);\n                if (val > best_val) { best_val = val; best_offy = oy; }\n            }\n            for (int t = 0; t < 200 && elapsed() < TIME_LIMIT; t++) {\n                int oy = (int)(rng() % stepY);\n                int val = evaluate_grid(V, H, stepX, offx, stepY, oy, mode, true);\n                if (val > best_val) { best_val = val; best_offy = oy; }\n            }\n        }\n        if (best_offy != offy) { offy = best_offy; cur = best_val; improved = true; }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> K)) return 0;\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    pts.resize(N);\n    xs.resize(N);\n    ys.resize(N);\n    us.resize(N);\n    vs.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        pts[i] = {x, y};\n        xs[i] = x + R;\n        ys[i] = y + R;\n        us[i] = x + y + 2 * R;   // shift by 20000\n        vs[i] = x - y + 2 * R;   // shift by 20000\n    }\n\n    // generate candidate pairs\n    vector<pair<int,int>> pairs;\n    auto addPair = [&](int v, int h) {\n        if (v < 0 || h < 0) return;\n        if (v + h > K) return;\n        if (v > 100 || h > 100) return;\n        pairs.emplace_back(v, h);\n    };\n\n    // lambda-based candidates\n    vector<pair<double,double>> lambdaScore;\n    for (double lam = 0.8; lam <= 8.0; lam += 0.2) {\n        double cells = (double)N / lam;\n        double eexp = exp(-lam);\n        double sum = 0.0, lp = 1.0;\n        for (int d = 1; d <= 10; d++) {\n            lp *= lam;\n            double pd = lp * eexp / tgamma(d + 1);\n            double bd = cells * pd;\n            sum += min((double)a[d], bd);\n        }\n        lambdaScore.emplace_back(-sum, lam);\n    }\n    sort(lambdaScore.begin(), lambdaScore.end());\n    int topLam = 6;\n    for (int i = 0; i < (int)lambdaScore.size() && i < topLam; i++) {\n        double lam = lambdaScore[i].second;\n        double cells = (double)N / lam;\n        double base = sqrt(max(1.0, cells)) - 1.0;\n        int v0 = max(0, (int)(base + 0.5));\n        for (int dv = -2; dv <= 2; dv++) {\n            int v = v0 + dv;\n            if (v < 0) continue;\n            addPair(v, v);\n            addPair(v, v + 1);\n            addPair(v + 1, v);\n        }\n    }\n    vector<int> fixed = {8,12,16,20,24,28,32,36,40,44,48,52};\n    for (int v : fixed) if (2 * v <= K) addPair(v, v);\n\n    sort(pairs.begin(), pairs.end());\n    pairs.erase(unique(pairs.begin(), pairs.end()), pairs.end());\n\n    vector<pair<double, pair<int,int>>> order;\n    for (auto &pr : pairs) {\n        double eo = expected_obj_pair(pr.first, pr.second);\n        order.push_back({-eo, pr});\n    }\n    sort(order.begin(), order.end());\n\n    int maxAxis = 7, maxDiag = 5;\n    int axis_done = 0, diag_done = 0;\n    for (auto &ord : order) {\n        if (elapsed() > TIME_LIMIT) break;\n        int V = ord.second.first;\n        int H = ord.second.second;\n        if (axis_done < maxAxis) {\n            optimize_pair(V, H, 0);\n            axis_done++;\n        }\n        if (elapsed() > TIME_LIMIT) break;\n        if (diag_done < maxDiag) {\n            optimize_pair(V, H, 1);\n            diag_done++;\n        }\n        if (axis_done >= maxAxis && diag_done >= maxDiag) break;\n    }\n\n    // random search\n    while (elapsed() < TIME_LIMIT) {\n        int V = (int)(rng() % 51);\n        int H = (int)(rng() % 51);\n        if (V + H > K) continue;\n        int mode = (rng() & 1);\n        int range = (mode == 0) ? 20000 : 40000;\n        int stepX = max(1, range / (V + 1));\n        int stepY = max(1, range / (H + 1));\n        int offx = (int)(rng() % stepX);\n        int offy = (int)(rng() % stepY);\n        evaluate_grid(V, H, stepX, offx, stepY, offy, mode, true);\n    }\n\n    int k = (int)best.vx.size() + (int)best.vy.size();\n    cout << k << \"\\n\";\n    if (best.mode == 0) {\n        for (int x : best.vx) {\n            cout << x << \" \" << -BIG << \" \" << x << \" \" << BIG << \"\\n\";\n        }\n        for (int y : best.vy) {\n            cout << -BIG << \" \" << y << \" \" << BIG << \" \" << y << \"\\n\";\n        }\n    } else { // diag\n        for (int c : best.vx) { // u = x + y = c\n            // points (c,0) and (0,c)\n            cout << c << \" 0 0 \" << c << \"\\n\";\n        }\n        for (int d : best.vy) { // v = x - y = d\n            // points (d,0) and (0,-d)\n            cout << d << \" 0 0 \" << -d << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeIndex {\n    int N;\n    int H, V, D1, D2, E;\n    EdgeIndex(int N_) : N(N_) {\n        H = (N - 1) * N;\n        V = H;\n        D1 = (N - 1) * (N - 1);\n        D2 = D1;\n        E = H + V + D1 + D2;\n    }\n    inline int horizId(int x, int y) const { return x + y * (N - 1); }\n    inline int vertId(int x, int y) const { return H + x * (N - 1) + y; }\n    inline int diag1Id(int x, int y) const { return H + V + x * (N - 1) + y; }       // (x,y)-(x+1,y+1)\n    inline int diag2Id(int x, int y) const { return H + V + D1 + x * (N - 1) + (y - 1); } // (x,y)-(x+1,y-1)\n    inline int id(int x1, int y1, int x2, int y2) const {\n        int dx = x2 - x1, dy = y2 - y1;\n        if (abs(dx) + abs(dy) == 1) {\n            if (dy == 0) return horizId(min(x1, x2), y1);\n            else return vertId(x1, min(y1, y2));\n        } else if (abs(dx) == 1 && abs(dy) == 1) {\n            if (dx == dy) return diag1Id(min(x1, x2), min(y1, y2));\n            else return diag2Id(min(x1, x2), max(y1, y2));\n        }\n        return -1;\n    }\n};\n\nstruct Cand {\n    uint8_t type; //0 rect axis,1 diamond,2 diag-rect\n    uint8_t miss;\n    uint8_t dx, dy; // rect: dx,dy; diamond: dx=r; diag-rect: dx=a, dy=b\n    uint16_t x0, y0; // rect: bottom-left; diamond: center; diag: p0\n    int w;\n    int score;\n};\n\nstruct CompScore {\n    bool operator()(const Cand &a, const Cand &b) const { return a.score < b.score; }\n};\n\nclass Pool {\n    int mode; //0 score,1 fifo,2 random\n    priority_queue<Cand, vector<Cand>, CompScore> pq;\n    deque<Cand> dq;\n    vector<Cand> vec;\n    mt19937 rng;\npublic:\n    Pool(int m, uint32_t seed) : mode(m), rng(seed) {}\n    void push(const Cand &c) {\n        if (mode == 0) pq.push(c);\n        else if (mode == 1) dq.push_back(c);\n        else vec.push_back(c);\n    }\n    bool empty() const {\n        if (mode == 0) return pq.empty();\n        if (mode == 1) return dq.empty();\n        return vec.empty();\n    }\n    Cand pop() {\n        if (mode == 0) { Cand c=pq.top(); pq.pop(); return c; }\n        if (mode == 1) { Cand c=dq.front(); dq.pop_front(); return c; }\n        int idx = (int)(rng()%vec.size());\n        Cand c = vec[idx];\n        vec[idx]=vec.back();\n        vec.pop_back();\n        return c;\n    }\n};\n\nstruct Stage {\n    int maxA; // axis rectangle size\n    int maxD; // diamond radius\n    int maxR; // diag-rect lengths\n    int mode; // pool mode\n    int prio; //0 weight,1 ratio\n};\n\nstruct Result {\n    long long total;\n    vector<array<int,8>> ops;\n};\n\ninline int jitterVal(int x0,int y0,int dx,int dy,uint32_t seed){\n    uint32_t h = seed;\n    h ^= (uint32_t)(x0 * 73856093);\n    h ^= (uint32_t)(y0 * 19349663);\n    h ^= (uint32_t)(dx * 83492791);\n    h ^= (uint32_t)(dy * 1234567);\n    h ^= (h >> 16);\n    return (int)(h & 7);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> initialDots(M);\n    for (int i=0;i<M;i++){\n        int x,y;cin>>x>>y;\n        initialDots[i]={x,y};\n    }\n    EdgeIndex EI(N);\n    int NN = N*N;\n    vector<int> weight(NN);\n    int c = (N-1)/2;\n    for (int x=0;x<N;x++) for (int y=0;y<N;y++){\n        int dx=x-c, dy=y-c;\n        weight[x*N+y]=dx*dx+dy*dy+1;\n    }\n    vector<char> initialHas(NN,0);\n    long long initSum=0;\n    vector<pair<int,int>> initList;\n    initList.reserve(M+8000);\n    for (auto &p: initialDots){\n        int id=p.first*N+p.second;\n        if (!initialHas[id]){\n            initialHas[id]=1;\n            initSum += weight[id];\n            initList.push_back(p);\n        }\n    }\n    uint64_t seedBase=1234567;\n    seedBase = seedBase*1000003 + N;\n    seedBase = seedBase*1000003 + M;\n    for (auto &p: initialDots){\n        seedBase ^= (uint64_t)(p.first+1)*10007 + (uint64_t)(p.second+1)*1000003 + 12345;\n        seedBase = seedBase*1000003 + 1;\n    }\n\n    vector<vector<Stage>> configList;\n    configList.push_back({{8,4,2,0,0},{6,3,2,0,1}});\n    configList.push_back({{6,3,2,0,1},{10,5,2,0,0}});\n    configList.push_back({{4,2,3,1,1},{7,3,3,0,0},{10,4,2,0,0}});\n    configList.push_back({{5,2,2,2,1},{8,3,2,0,0},{11,5,2,0,0}});\n    configList.push_back({{12,6,1,0,0}});\n    configList.push_back({{7,4,3,2,1},{9,5,2,2,0}});\n    configList.push_back({{9,4,2,0,0},{6,3,2,1,1}});\n\n    const double TIME_LIMIT = 4.95;\n    auto startTime = chrono::steady_clock::now();\n\n    auto simulate = [&](const vector<Stage> &seq, uint32_t baseSeed)->Result{\n        vector<char> has=initialHas;\n        vector<char> used(EI.E,0);\n        vector<pair<int,int>> dotList=initList;\n        long long total=initSum;\n        vector<array<int,8>> ops;\n\n        for (int si=0; si<(int)seq.size(); si++){\n            if (chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>TIME_LIMIT) break;\n            const Stage &st=seq[si];\n            Pool pool(st.mode, baseSeed + si*1000003u);\n\n            auto scoreRect=[&](int w,int per){ if (st.prio==0) return w; return (w*1024)/max(1,per); };\n\n            auto evalRectAxis = [&](int x0,int y0,int dx,int dy){\n                int x1=x0+dx, y1=y0+dy;\n                if (x0<0||y0<0||x1>=N||y1>=N) return;\n                int cid[4]={x0*N+y0, x1*N+y0, x1*N+y1, x0*N+y1};\n                int cnt=has[cid[0]]+has[cid[1]]+has[cid[2]]+has[cid[3]];\n                if (cnt!=3) return;\n                int miss;\n                if (!has[cid[0]]) miss=0;\n                else if (!has[cid[1]]) miss=1;\n                else if (!has[cid[2]]) miss=2;\n                else miss=3;\n                for (int i=0;i<dx;i++){\n                    int e1=EI.horizId(x0+i,y0), e2=EI.horizId(x0+i,y1);\n                    if (used[e1]||used[e2]) return;\n                }\n                for (int j=0;j<dy;j++){\n                    int e1=EI.vertId(x0,y0+j), e2=EI.vertId(x1,y0+j);\n                    if (used[e1]||used[e2]) return;\n                }\n                if (dx>1){\n                    for (int i=1;i<dx;i++){\n                        if (has[(x0+i)*N+y0]) return;\n                        if (has[(x0+i)*N+y1]) return;\n                    }\n                }\n                if (dy>1){\n                    for (int j=1;j<dy;j++){\n                        if (has[x0*N+(y0+j)]) return;\n                        if (has[x1*N+(y0+j)]) return;\n                    }\n                }\n                int w=weight[cid[miss]];\n                Cand cnd; cnd.type=0; cnd.miss=miss; cnd.dx=dx; cnd.dy=dy; cnd.x0=x0; cnd.y0=y0; cnd.w=w;\n                cnd.score=scoreRect(w, 2*(dx+dy)) + jitterVal(x0,y0,dx,dy,baseSeed);\n                pool.push(cnd);\n            };\n\n            auto evalDiamond = [&](int cx,int cy,int r){\n                if (cx-r<0||cx+r>=N||cy-r<0||cy+r>=N) return;\n                int cid[4]={ (cx+r)*N+cy, cx*N+(cy+r), (cx-r)*N+cy, cx*N+(cy-r) };\n                int cnt=has[cid[0]]+has[cid[1]]+has[cid[2]]+has[cid[3]];\n                if (cnt!=3) return;\n                int miss;\n                if (!has[cid[0]]) miss=0;\n                else if (!has[cid[1]]) miss=1;\n                else if (!has[cid[2]]) miss=2;\n                else miss=3;\n                for (int t=0;t<r;t++){\n                    int x,y,e;\n                    x=cx+r-t; y=cy+t; e=EI.id(x,y,x-1,y+1); if (used[e]) return;\n                    x=cx-t; y=cy+r-t; e=EI.id(x,y,x-1,y-1); if (used[e]) return;\n                    x=cx-r+t; y=cy-t; e=EI.id(x,y,x+1,y-1); if (used[e]) return;\n                    x=cx+t; y=cy-r+t; e=EI.id(x,y,x+1,y+1); if (used[e]) return;\n                }\n                for (int t=1;t<r;t++){\n                    if (has[(cx+r-t)*N+(cy+t)]) return;\n                    if (has[(cx-t)*N+(cy+r-t)]) return;\n                    if (has[(cx-r+t)*N+(cy-t)]) return;\n                    if (has[(cx+t)*N+(cy-r+t)]) return;\n                }\n                int w=weight[cid[miss]];\n                Cand cnd; cnd.type=1; cnd.miss=miss; cnd.dx=r; cnd.dy=0; cnd.x0=cx; cnd.y0=cy; cnd.w=w;\n                cnd.score=scoreRect(w, 4*r) + jitterVal(cx,cy,r,0,baseSeed+31);\n                pool.push(cnd);\n            };\n\n            auto evalDiagRect = [&](int x0,int y0,int a,int b){\n                int x1=x0+a, y1=y0+a;\n                int x2=x0+a+b, y2=y0+a-b;\n                int x3=x0+b, y3=y0-b;\n                if (x0<0||y0<0||x2>=N||y1>=N||y3<0) return;\n                int cid[4]={x0*N+y0, x1*N+y1, x2*N+y2, x3*N+y3};\n                int cnt=has[cid[0]]+has[cid[1]]+has[cid[2]]+has[cid[3]];\n                if (cnt!=3) return;\n                int miss;\n                if (!has[cid[0]]) miss=0;\n                else if (!has[cid[1]]) miss=1;\n                else if (!has[cid[2]]) miss=2;\n                else miss=3;\n                for (int i=0;i<a;i++){\n                    int e=EI.diag1Id(x0+i, y0+i);\n                    int e2=EI.diag1Id(x3+i, y3+i);\n                    if (used[e]||used[e2]) return;\n                }\n                for (int i=0;i<b;i++){\n                    int e=EI.diag2Id(x1+i, y1-i);\n                    int e2=EI.diag2Id(x0+i, y0-i);\n                    if (used[e]||used[e2]) return;\n                }\n                if (a>1){\n                    for (int i=1;i<a;i++){\n                        if (has[(x0+i)*N+(y0+i)]) return;\n                        if (has[(x3+i)*N+(y3+i)]) return;\n                    }\n                }\n                if (b>1){\n                    for (int i=1;i<b;i++){\n                        if (has[(x1+i)*N+(y1-i)]) return;\n                        if (has[(x0+i)*N+(y0-i)]) return;\n                    }\n                }\n                int w=weight[cid[miss]];\n                Cand cnd; cnd.type=2; cnd.miss=miss; cnd.dx=a; cnd.dy=b; cnd.x0=x0; cnd.y0=y0; cnd.w=w;\n                cnd.score=scoreRect(w, 2*(a+b)) + jitterVal(x0,y0,a,b,baseSeed+97);\n                pool.push(cnd);\n            };\n\n            auto addFromPoint = [&](int x,int y){\n                for (int dx=1; dx<=st.maxA; dx++){\n                    for (int dy=1; dy<=st.maxA; dy++){\n                        evalRectAxis(x,y,dx,dy);\n                        evalRectAxis(x-dx,y,dx,dy);\n                        evalRectAxis(x,y-dy,dx,dy);\n                        evalRectAxis(x-dx,y-dy,dx,dy);\n                    }\n                }\n                for (int r=1; r<=st.maxD; r++){\n                    evalDiamond(x-r,y,r);\n                    evalDiamond(x,y-r,r);\n                    evalDiamond(x+r,y,r);\n                    evalDiamond(x,y+r,r);\n                }\n                if (st.maxR>0){\n                    for (int a=1; a<=st.maxR; a++){\n                        for (int b=1; b<=st.maxR; b++){\n                            evalDiagRect(x, y, a, b);\n                            evalDiagRect(x-a, y-a, a, b);\n                            evalDiagRect(x-a-b, y-(a-b), a, b);\n                            evalDiagRect(x-b, y+b, a, b);\n                        }\n                    }\n                }\n            };\n\n            for (auto &p: dotList){\n                addFromPoint(p.first,p.second);\n                if (chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>TIME_LIMIT) break;\n            }\n\n            auto tryApplyRectAxis = [&](const Cand &cnd,int &mx,int &my)->bool{\n                int x0=cnd.x0,y0=cnd.y0,dx=cnd.dx,dy=cnd.dy;\n                int x1=x0+dx, y1=y0+dy;\n                if (x0<0||y0<0||x1>=N||y1>=N) return false;\n                int cid[4]={x0*N+y0,x1*N+y0,x1*N+y1,x0*N+y1};\n                if (has[cid[cnd.miss]]) return false;\n                for (int k=0;k<4;k++) if (k!=cnd.miss && !has[cid[k]]) return false;\n                for (int i=0;i<dx;i++){\n                    int e1=EI.horizId(x0+i,y0), e2=EI.horizId(x0+i,y1);\n                    if (used[e1]||used[e2]) return false;\n                }\n                for (int j=0;j<dy;j++){\n                    int e1=EI.vertId(x0,y0+j), e2=EI.vertId(x1,y0+j);\n                    if (used[e1]||used[e2]) return false;\n                }\n                if (dx>1){\n                    for (int i=1;i<dx;i++){\n                        if (has[(x0+i)*N+y0]) return false;\n                        if (has[(x0+i)*N+y1]) return false;\n                    }\n                }\n                if (dy>1){\n                    for (int j=1;j<dy;j++){\n                        if (has[x0*N+(y0+j)]) return false;\n                        if (has[x1*N+(y0+j)]) return false;\n                    }\n                }\n                has[cid[cnd.miss]]=1;\n                total += cnd.w;\n                for (int i=0;i<dx;i++){\n                    used[EI.horizId(x0+i,y0)]=1;\n                    used[EI.horizId(x0+i,y1)]=1;\n                }\n                for (int j=0;j<dy;j++){\n                    used[EI.vertId(x0,y0+j)]=1;\n                    used[EI.vertId(x1,y0+j)]=1;\n                }\n                mx = (cnd.miss==0||cnd.miss==3)?x0:x1;\n                my = (cnd.miss==0||cnd.miss==1)?y0:y1;\n                array<int,8> op;\n                for (int t=0;t<4;t++){\n                    int idx=(cnd.miss+t)%4;\n                    int ox,oy;\n                    if (idx==0){ox=x0;oy=y0;}\n                    else if (idx==1){ox=x1;oy=y0;}\n                    else if (idx==2){ox=x1;oy=y1;}\n                    else {ox=x0;oy=y1;}\n                    op[2*t]=ox; op[2*t+1]=oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx,my);\n                return true;\n            };\n\n            auto tryApplyDiamond = [&](const Cand &cnd,int &mx,int &my)->bool{\n                int cx=cnd.x0, cy=cnd.y0, r=cnd.dx;\n                if (cx-r<0||cx+r>=N||cy-r<0||cy+r>=N) return false;\n                int cid[4]={ (cx+r)*N+cy, cx*N+(cy+r), (cx-r)*N+cy, cx*N+(cy-r) };\n                if (has[cid[cnd.miss]]) return false;\n                for (int k=0;k<4;k++) if (k!=cnd.miss && !has[cid[k]]) return false;\n                for (int t=0;t<r;t++){\n                    int x,y,e;\n                    x=cx+r-t; y=cy+t; e=EI.id(x,y,x-1,y+1); if (used[e]) return false;\n                    x=cx-t; y=cy+r-t; e=EI.id(x,y,x-1,y-1); if (used[e]) return false;\n                    x=cx-r+t; y=cy-t; e=EI.id(x,y,x+1,y-1); if (used[e]) return false;\n                    x=cx+t; y=cy-r+t; e=EI.id(x,y,x+1,y+1); if (used[e]) return false;\n                }\n                for (int t=1;t<r;t++){\n                    if (has[(cx+r-t)*N+(cy+t)]) return false;\n                    if (has[(cx-t)*N+(cy+r-t)]) return false;\n                    if (has[(cx-r+t)*N+(cy-t)]) return false;\n                    if (has[(cx+t)*N+(cy-r+t)]) return false;\n                }\n                has[cid[cnd.miss]]=1;\n                total += cnd.w;\n                for (int t=0;t<r;t++){\n                    int x,y;\n                    x=cx+r-t; y=cy+t; used[EI.id(x,y,x-1,y+1)]=1;\n                    x=cx-t; y=cy+r-t; used[EI.id(x,y,x-1,y-1)]=1;\n                    x=cx-r+t; y=cy-t; used[EI.id(x,y,x+1,y-1)]=1;\n                    x=cx+t; y=cy-r+t; used[EI.id(x,y,x+1,y+1)]=1;\n                }\n                if (cnd.miss==0){mx=cx+r; my=cy;}\n                else if (cnd.miss==1){mx=cx; my=cy+r;}\n                else if (cnd.miss==2){mx=cx-r; my=cy;}\n                else {mx=cx; my=cy-r;}\n                array<int,8> op;\n                for (int t=0;t<4;t++){\n                    int idx=(cnd.miss+t)%4;\n                    int ox,oy;\n                    if (idx==0){ox=cx+r; oy=cy;}\n                    else if (idx==1){ox=cx; oy=cy+r;}\n                    else if (idx==2){ox=cx-r; oy=cy;}\n                    else {ox=cx; oy=cy-r;}\n                    op[2*t]=ox; op[2*t+1]=oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx,my);\n                return true;\n            };\n\n            auto tryApplyDiag = [&](const Cand &cnd,int &mx,int &my)->bool{\n                int x0=cnd.x0, y0=cnd.y0, a=cnd.dx, b=cnd.dy;\n                int x1=x0+a, y1=y0+a;\n                int x2=x0+a+b, y2=y0+a-b;\n                int x3=x0+b, y3=y0-b;\n                if (x0<0||y0<0||x2>=N||y1>=N||y3<0) return false;\n                int cid[4]={x0*N+y0, x1*N+y1, x2*N+y2, x3*N+y3};\n                if (has[cid[cnd.miss]]) return false;\n                for (int k=0;k<4;k++) if (k!=cnd.miss && !has[cid[k]]) return false;\n                for (int i=0;i<a;i++){\n                    int e=EI.diag1Id(x0+i,y0+i);\n                    int e2=EI.diag1Id(x3+i,y3+i);\n                    if (used[e]||used[e2]) return false;\n                }\n                for (int i=0;i<b;i++){\n                    int e=EI.diag2Id(x1+i, y1-i);\n                    int e2=EI.diag2Id(x0+i, y0-i);\n                    if (used[e]||used[e2]) return false;\n                }\n                if (a>1){\n                    for (int i=1;i<a;i++){\n                        if (has[(x0+i)*N+(y0+i)]) return false;\n                        if (has[(x3+i)*N+(y3+i)]) return false;\n                    }\n                }\n                if (b>1){\n                    for (int i=1;i<b;i++){\n                        if (has[(x1+i)*N+(y1-i)]) return false;\n                        if (has[(x0+i)*N+(y0-i)]) return false;\n                    }\n                }\n                has[cid[cnd.miss]]=1;\n                total += cnd.w;\n                for (int i=0;i<a;i++){\n                    used[EI.diag1Id(x0+i,y0+i)]=1;\n                    used[EI.diag1Id(x3+i,y3+i)]=1;\n                }\n                for (int i=0;i<b;i++){\n                    used[EI.diag2Id(x1+i,y1-i)]=1;\n                    used[EI.diag2Id(x0+i,y0-i)]=1;\n                }\n                if (cnd.miss==0){mx=x0; my=y0;}\n                else if (cnd.miss==1){mx=x1; my=y1;}\n                else if (cnd.miss==2){mx=x2; my=y2;}\n                else {mx=x3; my=y3;}\n                array<int,8> op;\n                for (int t=0;t<4;t++){\n                    int idx=(cnd.miss+t)%4;\n                    int ox,oy;\n                    if (idx==0){ox=x0; oy=y0;}\n                    else if (idx==1){ox=x1; oy=y1;}\n                    else if (idx==2){ox=x2; oy=y2;}\n                    else {ox=x3; oy=y3;}\n                    op[2*t]=ox; op[2*t+1]=oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx,my);\n                return true;\n            };\n\n            while (!pool.empty()){\n                if (chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>TIME_LIMIT) break;\n                Cand cand=pool.pop();\n                int mx=-1,my=-1;\n                bool ok=false;\n                if (cand.type==0) ok=tryApplyRectAxis(cand,mx,my);\n                else if (cand.type==1) ok=tryApplyDiamond(cand,mx,my);\n                else ok=tryApplyDiag(cand,mx,my);\n                if (ok) dotList.emplace_back(mx,my);\n            }\n        }\n        return {total, std::move(ops)};\n    };\n\n    Result best{initSum, {}};\n    int runId=0;\n    while (true){\n        double t = chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n        if (t > TIME_LIMIT) break;\n        int ci = runId % (int)configList.size();\n        uint32_t seed = (uint32_t)((seedBase + 1812433253ull * runId) & 0xffffffffu);\n        Result res = simulate(configList[ci], seed);\n        if (res.total > best.total) best = std::move(res);\n        runId++;\n    }\n\n    cout << best.ops.size() << \"\\n\";\n    for (auto &op: best.ops){\n        for (int i=0;i<8;i++){\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0 = F(up), 1 = B(down), 2 = L(left), 3 = R(right)\nconst char DIR_CH[4] = {'F', 'B', 'L', 'R'};\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\n\nusing Board = array<array<int, 10>, 10>;\n\nBoard tilt(const Board &b, int dir) {\n    Board res;\n    for (auto &row : res) row.fill(0);\n    if (dir == 0) { // up\n        for (int c = 0; c < 10; c++) {\n            int pos = 0;\n            for (int r = 0; r < 10; r++) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 1) { // down\n        for (int c = 0; c < 10; c++) {\n            int pos = 9;\n            for (int r = 9; r >= 0; r--) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 2) { // left\n        for (int r = 0; r < 10; r++) {\n            int pos = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else { // right\n        for (int r = 0; r < 10; r++) {\n            int pos = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    }\n    return res;\n}\n\n// return {sum of squares, component count}\npair<int, int> scoreAndComp(const Board &b) {\n    bool vis[10][10] = {};\n    int totalScore = 0;\n    int comps = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            if (b[r][c] == 0 || vis[r][c]) continue;\n            comps++;\n            int col = b[r][c];\n            queue<pair<int, int>> q;\n            q.push({r, c});\n            vis[r][c] = true;\n            int sz = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front();\n                q.pop();\n                sz++;\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dr[k], ny = y + dc[k];\n                    if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;\n                    if (vis[nx][ny]) continue;\n                    if (b[nx][ny] != col) continue;\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n            totalScore += sz * sz;\n        }\n    }\n    return {totalScore, comps};\n}\n\nint distSum(const Board &b, const array<pair<int, int>, 4> &target) {\n    int s = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            int col = b[r][c];\n            if (col == 0) continue;\n            s += abs(r - target[col].first) + abs(c - target[col].second);\n        }\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavor(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavor[i])) return 0;\n    }\n\n    // count flavors\n    array<int, 4> cnt = {0, 0, 0, 0};\n    for (int f : flavor) cnt[f]++;\n\n    // corners\n    array<pair<int, int>, 4> corners = {make_pair(0, 0), make_pair(0, 9), make_pair(9, 0), make_pair(9, 9)};\n    // assign each flavor to a distinct corner maximizing weighted distance\n    array<pair<int, int>, 4> target;\n    target[0] = {0, 0};\n    long long bestMetric = -1;\n    array<int, 4> bestAssign = {0, 0, 0, 0};\n    for (int i = 0; i < 4; i++) {\n        for (int j = 0; j < 4; j++) if (j != i) {\n            for (int k = 0; k < 4; k++) if (k != i && k != j) {\n                long long metric = 0;\n                metric += 1LL * cnt[1] * cnt[2] * (abs(corners[i].first - corners[j].first) + abs(corners[i].second - corners[j].second));\n                metric += 1LL * cnt[1] * cnt[3] * (abs(corners[i].first - corners[k].first) + abs(corners[i].second - corners[k].second));\n                metric += 1LL * cnt[2] * cnt[3] * (abs(corners[j].first - corners[k].first) + abs(corners[j].second - corners[k].second));\n                if (metric > bestMetric) {\n                    bestMetric = metric;\n                    bestAssign[1] = i;\n                    bestAssign[2] = j;\n                    bestAssign[3] = k;\n                }\n            }\n        }\n    }\n    for (int f = 1; f <= 3; f++) {\n        target[f] = corners[bestAssign[f]];\n    }\n\n    Board cur;\n    for (auto &row : cur) row.fill(0);\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        if (!(cin >> p)) break;\n\n        // place new candy at p-th empty cell (row-major)\n        int cntEmpty = 0;\n        int pr = -1, pc = -1;\n        for (int r = 0; r < 10; r++) {\n            for (int c = 0; c < 10; c++) {\n                if (cur[r][c] == 0) {\n                    cntEmpty++;\n                    if (cntEmpty == p) {\n                        pr = r;\n                        pc = c;\n                        goto placed;\n                    }\n                }\n            }\n        }\n    placed:\n        if (pr == -1) { pr = 0; pc = 0; }\n        cur[pr][pc] = flavor[t];\n\n        int distCur = distSum(cur, target);\n\n        int bestDir = 0;\n        int bestScore = -1;\n        int bestDelta = -1e9;\n        int bestComp = 1e9;\n        int bestDist = 1e9;\n        Board bestBoard = cur;\n\n        for (int dir = 0; dir < 4; dir++) {\n            Board nb = tilt(cur, dir);\n            auto [sc, comp] = scoreAndComp(nb);\n            int d = distSum(nb, target);\n            int delta = distCur - d;\n            if (sc > bestScore ||\n                (sc == bestScore && delta > bestDelta) ||\n                (sc == bestScore && delta == bestDelta && comp < bestComp) ||\n                (sc == bestScore && delta == bestDelta && comp == bestComp && d < bestDist)) {\n                bestScore = sc;\n                bestDelta = delta;\n                bestComp = comp;\n                bestDist = d;\n                bestDir = dir;\n                bestBoard = nb;\n            }\n        }\n\n        cout << DIR_CH[bestDir] << '\\n' << flush;\n        cur = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GraphData {\n    int N;\n    vector<vector<uint8_t>> adj; // NxN\n    vector<int> deg, f1, f2, tri;\n    vector<int> sortedDeg;\n};\n\nvoid compute_features(GraphData &g){\n    int N = g.N;\n    g.deg.assign(N,0);\n    g.f1.assign(N,0);\n    g.f2.assign(N,0);\n    g.tri.assign(N,0);\n    // degree\n    for(int i=0;i<N;i++){\n        int d=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) d++;\n        g.deg[i]=d;\n    }\n    // f1\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.deg[j];\n        g.f1[i]=s;\n    }\n    // f2\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.f1[j];\n        g.f2[i]=s;\n    }\n    // triangles per vertex (naive)\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++) if(g.adj[i][j]){\n            for(int k=j+1;k<N;k++) if(g.adj[i][k] && g.adj[j][k]){\n                g.tri[i]++; g.tri[j]++; g.tri[k]++;\n            }\n        }\n    }\n    g.sortedDeg = g.deg;\n    sort(g.sortedDeg.begin(), g.sortedDeg.end());\n}\n\n// Hungarian algorithm for minimum cost assignment\nvector<int> hungarian(const vector<vector<double>> &a){\n    int n = (int)a.size();\n    int m = n;\n    const double INF = 1e18;\n    vector<double> u(n+1), v(m+1);\n    vector<int> p(m+1), way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;\n        int j0=0;\n        vector<double> minv(m+1, INF);\n        vector<char> used(m+1, false);\n        do{\n            used[j0]=true;\n            int i0 = p[j0];\n            double delta = INF;\n            int j1 = 0;\n            for(int j=1;j<=m;j++) if(!used[j]){\n                double cur = a[i0-1][j-1] - u[i0] - v[j];\n                if(cur < minv[j]){\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if(minv[j] < delta){\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for(int j=0;j<=m;j++){\n                if(used[j]){\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                }else{\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        }while(p[j0]!=0);\n        // augmenting\n        do{\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        }while(j0);\n    }\n    vector<int> assignment(n, -1); // row -> col\n    for(int j=1;j<=m;j++){\n        if(p[j]>0 && p[j]<=n) assignment[p[j]-1] = j-1;\n    }\n    return assignment;\n}\n\nint degree_distance(const vector<int>& a, const vector<int>& b){\n    int n=a.size();\n    int s=0;\n    for(int i=0;i<n;i++) s += abs(a[i]-b[i]);\n    return s;\n}\n\nint compute_mismatch(const vector<vector<uint8_t>>& H, const vector<vector<uint8_t>>& G, const vector<int>& assign, int bestLimit){\n    int n = assign.size();\n    int mism=0;\n    for(int i=0;i<n;i++){\n        int gi = assign[i];\n        for(int j=i+1;j<n;j++){\n            int gj = assign[j];\n            if(H[i][j] != G[gi][gj]) mism++;\n        }\n        if(mism >= bestLimit) return mism;\n    }\n    return mism;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n    // decide N\n    int N = 25 + int(60.0*eps + 0.5);\n    if(M > 80) N += 5;\n    else if(M > 50) N += 2;\n    if(M < 30) N -= 3;\n    if(eps > 0.30) N += 4;\n    N = max(4, min(100, N));\n    int Kcap = 30;\n    int K = min(M, max(5, min(Kcap, (int)(eps*75.0)+5)));\n    // generate graphs\n    mt19937 rng(1234567);\n    vector<GraphData> graphs(M);\n    for(int k=0;k<M;k++){\n        GraphData g;\n        g.N = N;\n        g.adj.assign(N, vector<uint8_t>(N,0));\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                bool e = (rng() & 1);\n                g.adj[i][j]=g.adj[j][i]= e;\n            }\n        }\n        compute_features(g);\n        graphs[k]=move(g);\n    }\n    // output graphs\n    cout<<N<<\"\\n\";\n    int E = N*(N-1)/2;\n    string line;\n    line.reserve(E);\n    for(int k=0;k<M;k++){\n        line.clear();\n        line.reserve(E);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                line.push_back(graphs[k].adj[i][j] ? '1' : '0');\n            }\n        }\n        cout<<line<<\"\\n\";\n    }\n    cout.flush();\n    // process queries\n    vector<vector<uint8_t>> HAdj(N, vector<uint8_t>(N,0));\n    GraphData HG;\n    HG.N = N;\n    for(int qi=0; qi<100; qi++){\n        string hstr;\n        if(!(cin>>hstr)) break;\n        // build adjacency\n        int idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                char c = hstr[idx++];\n                uint8_t v = (c=='1');\n                HAdj[i][j]=HAdj[j][i]=v;\n            }\n        }\n        HG.adj = HAdj;\n        compute_features(HG);\n        // distances for pruning\n        vector<pair<int,int>> distIdx;\n        distIdx.reserve(M);\n        for(int k=0;k<M;k++){\n            int d = degree_distance(HG.sortedDeg, graphs[k].sortedDeg);\n            distIdx.emplace_back(d, k);\n        }\n        nth_element(distIdx.begin(), distIdx.begin()+K, distIdx.end(),\n                    [](auto &a, auto &b){ return a.first < b.first; });\n        distIdx.resize(K);\n        sort(distIdx.begin(), distIdx.end()); // optional\n        int bestMismatch = N*N; // upper bound\n        int bestIdx = distIdx[0].second;\n        // precompute weight factors\n        double s = 1.0 - 2.0*eps;\n        if(s < 0.05) s = 0.05;\n        double w1 = s;\n        double w2 = s*s;\n        double w3 = s;\n        double invN = 1.0 / (double)N;\n        double invNN = 1.0 / ((double)N*(double)N);\n        // candidate evaluation\n        vector<vector<double>> cost(N, vector<double>(N));\n        for(auto &dk : distIdx){\n            int k = dk.second;\n            // build cost matrix\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    double c = abs(HG.deg[i] - graphs[k].deg[j]);\n                    c += w1 * (double)abs(HG.f1[i] - graphs[k].f1[j]) * invN;\n                    c += w2 * (double)abs(HG.f2[i] - graphs[k].f2[j]) * invNN;\n                    c += w3 * (double)abs(HG.tri[i] - graphs[k].tri[j]) * invN;\n                    cost[i][j]=c;\n                }\n            }\n            vector<int> assign = hungarian(cost); // H row -> G col\n            int mism = compute_mismatch(HAdj, graphs[k].adj, assign, bestMismatch);\n            if(mism < bestMismatch){\n                bestMismatch = mism;\n                bestIdx = k;\n            }\n        }\n        cout<<bestIdx<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\n// Dijkstra that skips one edge\nlong long dijkstra_skip(int s, int t, int skip_id,\n                        const vector<vector<Adj>> &adj,\n                        vector<long long> &dist) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        if (u == t) break;\n        for (auto &e : adj[u]) {\n            if (e.id == skip_id) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n    return dist[t];\n}\n\n// Dijkstra that records one parent edge (shortest path tree)\nvoid dijkstra_parent(int s, const vector<vector<Adj>> &adj,\n                     vector<long long> &dist, vector<int> &parent) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    fill(parent.begin(), parent.end(), -1);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                parent[e.to] = e.id;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u;\n        --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    // read coordinates (not used)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<long long> dist(N);\n    vector<long long> altDiff(M);\n    for (int i = 0; i < M; i++) {\n        auto &e = edges[i];\n        long long alt = dijkstra_skip(e.u, e.v, i, adj, dist);\n        if (alt >= (1LL << 59)) {\n            altDiff[i] = 0;  // fallback\n        } else {\n            altDiff[i] = alt - e.w;\n            if (altDiff[i] < 0) altDiff[i] = 0;\n        }\n    }\n\n    int S = min(N, 30);\n    vector<int> sources;\n    int step = max(1, N / S);\n    for (int i = 0; i < N && (int)sources.size() < S; i += step) {\n        sources.push_back(i);\n    }\n    while ((int)sources.size() < S) sources.push_back((int)sources.size());\n    vector<int> centrality(M, 0);\n    vector<int> parent(N);\n    for (int s : sources) {\n        dijkstra_parent(s, adj, dist, parent);\n        for (int v = 0; v < N; v++) {\n            if (v == s) continue;\n            int pe = parent[v];\n            if (pe >= 0) centrality[pe]++;\n        }\n    }\n\n    vector<long double> importance(M);\n    long double sumImp = 0;\n    for (int i = 0; i < M; i++) {\n        long double imp = (long double)altDiff[i] * ((long double)centrality[i] + 1.0L);\n        importance[i] = imp;\n        sumImp += imp;\n    }\n    long double avgImp = sumImp / (long double)max(1, M);\n    long double alpha = avgImp * 0.5L;\n    if (alpha < 1e-6) alpha = 1.0L;\n\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (importance[a] == importance[b]) return a < b;\n        return importance[a] > importance[b];\n    });\n\n    vector<int> answer(M, 0);\n    vector<long double> dayLoad(D, 0.0L);\n    vector<int> dayCount(D, 0);\n    vector<vector<uint16_t>> vtxCount(N, vector<uint16_t>(D, 0));\n\n    auto chooseDay = [&](int u, int v) -> int {\n        long double bestCost = 1e100;\n        int bestDay = -1;\n        for (int d = 0; d < D; d++) {\n            if (dayCount[d] >= K) continue;\n            int s1 = (int)vtxCount[u][d] + (int)vtxCount[v][d];\n            long double cost = dayLoad[d] + alpha * (long double)s1;\n            if (cost < bestCost - 1e-9L) {\n                bestCost = cost;\n                bestDay = d;\n            } else if (fabsl(cost - bestCost) <= 1e-9L) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay] ||\n                    (dayCount[d] == dayCount[bestDay] && d < bestDay)) {\n                    bestDay = d;\n                }\n            }\n        }\n        if (bestDay == -1) {\n            // should not happen, but fallback\n            for (int d = 0; d < D; d++) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay]) bestDay = d;\n            }\n        }\n        return bestDay;\n    };\n\n    // initial assignment\n    for (int eid : order) {\n        int u = edges[eid].u;\n        int v = edges[eid].v;\n        int d = chooseDay(u, v);\n        answer[eid] = d + 1;\n        dayLoad[d] += importance[eid];\n        dayCount[d]++;\n        vtxCount[u][d]++;\n        vtxCount[v][d]++;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int improvePasses = 1;\n    for (int pass = 0; pass < improvePasses; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.5) break;  // time guard\n        for (int eid : order) {\n            int curr = answer[eid] - 1;\n            int u = edges[eid].u;\n            int v = edges[eid].v;\n            long double imp = importance[eid];\n            // remove\n            dayLoad[curr] -= imp;\n            dayCount[curr]--;\n            vtxCount[u][curr]--;\n            vtxCount[v][curr]--;\n            // choose best day again\n            int nd = chooseDay(u, v);\n            answer[eid] = nd + 1;\n            dayLoad[nd] += imp;\n            dayCount[nd]++;\n            vtxCount[u][nd]++;\n            vtxCount[v][nd]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << answer[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> dist, matchL, matchR;\n    HopcroftKarp(int nL=0,int nR=0): nL(nL), nR(nR), adj(nL) {}\n    void addEdge(int u,int v){ adj[u].push_back(v); }\n    bool bfs(){\n        queue<int> q;\n        dist.assign(nL, -1);\n        for(int i=0;i<nL;i++){\n            if(matchL[i]==-1){\n                dist[i]=0;\n                q.push(i);\n            }\n        }\n        bool reachable=false;\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for(int v: adj[u]){\n                int mu=matchR[v];\n                if(mu>=0 && dist[mu]==-1){\n                    dist[mu]=dist[u]+1;\n                    q.push(mu);\n                }\n                if(mu==-1) reachable=true;\n            }\n        }\n        return reachable;\n    }\n    bool dfs(int u){\n        for(int v: adj[u]){\n            int mu=matchR[v];\n            if(mu==-1 || (dist[mu]==dist[u]+1 && dfs(mu))){\n                matchL[u]=v;\n                matchR[v]=u;\n                return true;\n            }\n        }\n        dist[u]=-1;\n        return false;\n    }\n    int maxMatching(){\n        matchL.assign(nL, -1);\n        matchR.assign(nR, -1);\n        int m=0;\n        while(bfs()){\n            for(int i=0;i<nL;i++){\n                if(matchL[i]==-1){\n                    if(dfs(i)) m++;\n                }\n            }\n        }\n        return m;\n    }\n};\n\nstruct SilPack {\n    vector<array<int,8>> bars8;\n    vector<array<int,4>> bars4;\n    vector<pair<int,int>> doms;\n};\n\nstruct Placement {\n    vector<array<int,8>> bars8;\n    vector<array<int,4>> bars4;\n    vector<pair<int,int>> doms;\n    vector<int> monos;\n};\n\nstruct Solver {\n    int D, V;\n    vector<string> f[2], r[2];\n    inline int idx(int x,int y,int z) const { return (x*D + y)*D + z; }\n    inline tuple<int,int,int> decode(int id) const {\n        int z = id % D;\n        int y = (id / D) % D;\n        int x = id / (D*D);\n        return {x,y,z};\n    }\n\n    int bar_score8(const array<int,8>& ids){\n        vector<pair<int,int>> fx, ry;\n        fx.reserve(8); ry.reserve(8);\n        for(int id: ids){\n            auto [x,y,z]=decode(id);\n            fx.push_back({z,x});\n            ry.push_back({z,y});\n        }\n        sort(fx.begin(), fx.end());\n        fx.erase(unique(fx.begin(), fx.end()), fx.end());\n        sort(ry.begin(), ry.end());\n        ry.erase(unique(ry.begin(), ry.end()), ry.end());\n        return (int)fx.size() + (int)ry.size();\n    }\n    int bar_score4(const array<int,4>& ids){\n        vector<pair<int,int>> fx, ry;\n        fx.reserve(4); ry.reserve(4);\n        for(int id: ids){\n            auto [x,y,z]=decode(id);\n            fx.push_back({z,x});\n            ry.push_back({z,y});\n        }\n        sort(fx.begin(), fx.end());\n        fx.erase(unique(fx.begin(), fx.end()), fx.end());\n        sort(ry.begin(), ry.end());\n        ry.erase(unique(ry.begin(), ry.end()), ry.end());\n        return (int)fx.size() + (int)ry.size();\n    }\n    int dom_score(const pair<int,int>& p){\n        auto [x1,y1,z1]=decode(p.first);\n        auto [x2,y2,z2]=decode(p.second);\n        vector<pair<int,int>> fx={{z1,x1},{z2,x2}};\n        vector<pair<int,int>> ry={{z1,y1},{z2,y2}};\n        sort(fx.begin(), fx.end());\n        fx.erase(unique(fx.begin(), fx.end()), fx.end());\n        sort(ry.begin(), ry.end());\n        ry.erase(unique(ry.begin(), ry.end()), ry.end());\n        return (int)fx.size() + (int)ry.size();\n    }\n\n    SilPack pack_sil(const vector<char>& allowed){\n        vector<char> used(V,0);\n        SilPack sp;\n        // bars length 8 along axes\n        // x-axis\n        for(int x=0; x<=D-8; x++){\n            for(int y=0; y<D; y++){\n                for(int z=0; z<D; z++){\n                    array<int,8> ids;\n                    bool ok=true;\n                    for(int k=0;k<8;k++){\n                        ids[k]=idx(x+k,y,z);\n                        if(used[ids[k]] || !allowed[ids[k]]){ ok=false; break; }\n                    }\n                    if(ok){\n                        for(int k=0;k<8;k++) used[ids[k]]=1;\n                        sp.bars8.push_back(ids);\n                    }\n                }\n            }\n        }\n        // y-axis\n        for(int x=0; x<D; x++){\n            for(int y=0; y<=D-8; y++){\n                for(int z=0; z<D; z++){\n                    array<int,8> ids;\n                    bool ok=true;\n                    for(int k=0;k<8;k++){\n                        ids[k]=idx(x,y+k,z);\n                        if(used[ids[k]] || !allowed[ids[k]]){ ok=false; break; }\n                    }\n                    if(ok){\n                        for(int k=0;k<8;k++) used[ids[k]]=1;\n                        sp.bars8.push_back(ids);\n                    }\n                }\n            }\n        }\n        // z-axis\n        for(int x=0; x<D; x++){\n            for(int y=0; y<D; y++){\n                for(int z=0; z<=D-8; z++){\n                    array<int,8> ids;\n                    bool ok=true;\n                    for(int k=0;k<8;k++){\n                        ids[k]=idx(x,y,z+k);\n                        if(used[ids[k]] || !allowed[ids[k]]){ ok=false; break; }\n                    }\n                    if(ok){\n                        for(int k=0;k<8;k++) used[ids[k]]=1;\n                        sp.bars8.push_back(ids);\n                    }\n                }\n            }\n        }\n        // bars length 4\n        // x-axis\n        for(int x=0; x<=D-4; x++){\n            for(int y=0; y<D; y++){\n                for(int z=0; z<D; z++){\n                    array<int,4> ids;\n                    bool ok=true;\n                    for(int k=0;k<4;k++){\n                        ids[k]=idx(x+k,y,z);\n                        if(used[ids[k]] || !allowed[ids[k]]){ ok=false; break; }\n                    }\n                    if(ok){\n                        for(int k=0;k<4;k++) used[ids[k]]=1;\n                        sp.bars4.push_back(ids);\n                    }\n                }\n            }\n        }\n        // y-axis\n        for(int x=0; x<D; x++){\n            for(int y=0; y<=D-4; y++){\n                for(int z=0; z<D; z++){\n                    array<int,4> ids;\n                    bool ok=true;\n                    for(int k=0;k<4;k++){\n                        ids[k]=idx(x,y+k,z);\n                        if(used[ids[k]] || !allowed[ids[k]]){ ok=false; break; }\n                    }\n                    if(ok){\n                        for(int k=0;k<4;k++) used[ids[k]]=1;\n                        sp.bars4.push_back(ids);\n                    }\n                }\n            }\n        }\n        // z-axis\n        for(int x=0; x<D; x++){\n            for(int y=0; y<D; y++){\n                for(int z=0; z<=D-4; z++){\n                    array<int,4> ids;\n                    bool ok=true;\n                    for(int k=0;k<4;k++){\n                        ids[k]=idx(x,y,z+k);\n                        if(used[ids[k]] || !allowed[ids[k]]){ ok=false; break; }\n                    }\n                    if(ok){\n                        for(int k=0;k<4;k++) used[ids[k]]=1;\n                        sp.bars4.push_back(ids);\n                    }\n                }\n            }\n        }\n        // remaining free allowed for dom matching\n        vector<int> freeIds;\n        freeIds.reserve(V);\n        for(int id=0; id<V; id++){\n            if(!used[id] && allowed[id]) freeIds.push_back(id);\n        }\n        vector<int> leftId(V, -1), rightId(V, -1);\n        vector<int> leftMap, rightMap;\n        int nL=0, nR=0;\n        for(int id: freeIds){\n            auto [x,y,z]=decode(id);\n            if(((x+y+z)&1)==0){\n                leftId[id]=nL++;\n                leftMap.push_back(id);\n            }else{\n                rightId[id]=nR++;\n                rightMap.push_back(id);\n            }\n        }\n        HopcroftKarp hk(nL, nR);\n        int dx[6]={1,-1,0,0,0,0};\n        int dy[6]={0,0,1,-1,0,0};\n        int dz[6]={0,0,0,0,1,-1};\n        for(int id: freeIds){\n            auto [x,y,z]=decode(id);\n            if(((x+y+z)&1)!=0) continue;\n            int u=leftId[id];\n            for(int dir=0; dir<6; dir++){\n                int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                if(nx<0||ny<0||nz<0||nx>=D||ny>=D||nz>=D) continue;\n                int nid=idx(nx,ny,nz);\n                if(!used[nid] && allowed[nid] && rightId[nid]!=-1){\n                    hk.addEdge(u, rightId[nid]);\n                }\n            }\n        }\n        hk.maxMatching();\n        for(int u=0; u<nL; u++){\n            int v=hk.matchL[u];\n            if(v!=-1){\n                sp.doms.push_back({leftMap[u], rightMap[v]});\n            }\n        }\n        return sp;\n    }\n\n    Placement build_place(const SilPack& base, int c8, int c4, int c2,\n                          const vector<char>& allowed,\n                          const vector<string>& fmat, const vector<string>& rmat,\n                          int targetMono){\n        Placement pl;\n        vector<char> used(V,0);\n        // select bars by score\n        vector<pair<int,int>> ord8;\n        for(int i=0;i<(int)base.bars8.size();i++){\n            ord8.push_back({-bar_score8(base.bars8[i]), i});\n        }\n        sort(ord8.begin(), ord8.end());\n        for(int k=0;k<c8 && k<(int)ord8.size();k++){\n            auto arr = base.bars8[ord8[k].second];\n            pl.bars8.push_back(arr);\n            for(int id: arr) used[id]=1;\n        }\n        vector<pair<int,int>> ord4;\n        for(int i=0;i<(int)base.bars4.size();i++){\n            ord4.push_back({-bar_score4(base.bars4[i]), i});\n        }\n        sort(ord4.begin(), ord4.end());\n        for(int k=0;k<c4 && k<(int)ord4.size();k++){\n            auto arr = base.bars4[ord4[k].second];\n            pl.bars4.push_back(arr);\n            for(int id: arr) used[id]=1;\n        }\n        vector<pair<int,int>> ord2;\n        for(int i=0;i<(int)base.doms.size();i++){\n            ord2.push_back({-dom_score(base.doms[i]), i});\n        }\n        sort(ord2.begin(), ord2.end());\n        for(int k=0;k<c2 && k<(int)ord2.size();k++){\n            auto p = base.doms[ord2[k].second];\n            pl.doms.push_back(p);\n            used[p.first]=used[p.second]=1;\n        }\n        vector<char> coveredF(D*D,0), coveredR(D*D,0);\n        for(int id=0; id<V; id++){\n            if(used[id]){\n                auto [x,y,z]=decode(id);\n                coveredF[z*D + x]=1;\n                coveredR[z*D + y]=1;\n            }\n        }\n        // cover front\n        for(int z=0; z<D; z++){\n            for(int x=0; x<D; x++){\n                if(fmat[z][x]=='1' && !coveredF[z*D + x]){\n                    for(int y=0; y<D; y++){\n                        int id=idx(x,y,z);\n                        if(allowed[id] && !used[id]){\n                            used[id]=1;\n                            pl.monos.push_back(id);\n                            coveredF[z*D + x]=1;\n                            coveredR[z*D + y]=1;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        // cover right\n        for(int z=0; z<D; z++){\n            for(int y=0; y<D; y++){\n                if(rmat[z][y]=='1' && !coveredR[z*D + y]){\n                    for(int x=0; x<D; x++){\n                        int id=idx(x,y,z);\n                        if(allowed[id] && !used[id]){\n                            used[id]=1;\n                            pl.monos.push_back(id);\n                            coveredR[z*D + y]=1;\n                            coveredF[z*D + x]=1;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        // extra monos\n        for(int id=0; id<V && (int)pl.monos.size()<targetMono; id++){\n            if(!used[id] && allowed[id]){\n                used[id]=1;\n                pl.monos.push_back(id);\n            }\n        }\n        return pl;\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        if(!(cin>>D)) return;\n        V = D*D*D;\n        for(int s=0; s<2; s++){\n            f[s].resize(D);\n            for(int i=0;i<D;i++) cin>>f[s][i];\n            r[s].resize(D);\n            for(int i=0;i<D;i++) cin>>r[s][i];\n        }\n        vector<char> allowed[2];\n        for(int s=0; s<2; s++){\n            allowed[s].assign(V,0);\n            for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0; z<D; z++){\n                if(f[s][z][x]=='1' && r[s][z][y]=='1'){\n                    allowed[s][idx(x,y,z)] = 1;\n                }\n            }\n        }\n        SilPack base[2];\n        for(int s=0; s<2; s++){\n            base[s] = pack_sil(allowed[s]);\n        }\n        int max8 = min((int)base[0].bars8.size(), (int)base[1].bars8.size());\n        int max4 = min((int)base[0].bars4.size(), (int)base[1].bars4.size());\n        int max2 = min((int)base[0].doms.size(), (int)base[1].doms.size());\n        vector<int> opts8 = {0, max8/2, max8};\n        vector<int> opts4 = {0, max4/2, max4};\n        vector<int> opts2 = {0, max2/2, max2};\n        auto uniq = [](vector<int>& v){\n            sort(v.begin(), v.end());\n            v.erase(unique(v.begin(), v.end()), v.end());\n        };\n        uniq(opts8); uniq(opts4); uniq(opts2);\n        double bestEval=1e18;\n        int best8=0,best4=0,best2=0, bestMono=0;\n        Placement bestPl0, bestPl1;\n        for(int c8: opts8){\n            for(int c4: opts4){\n                for(int c2: opts2){\n                    Placement p0 = build_place(base[0], c8, c4, c2, allowed[0], f[0], r[0], 0);\n                    Placement p1 = build_place(base[1], c8, c4, c2, allowed[1], f[1], r[1], 0);\n                    int monoT = max((int)p0.monos.size(), (int)p1.monos.size());\n                    double eval = monoT + c2*0.5 + c4*0.25 + c8*0.125;\n                    if(eval < bestEval){\n                        bestEval = eval;\n                        best8=c8; best4=c4; best2=c2; bestMono=monoT;\n                        bestPl0 = build_place(base[0], c8, c4, c2, allowed[0], f[0], r[0], bestMono);\n                        bestPl1 = build_place(base[1], c8, c4, c2, allowed[1], f[1], r[1], bestMono);\n                    }\n                }\n            }\n        }\n        int n = best8 + best4 + best2 + bestMono;\n        vector<int> out0(V,0), out1(V,0);\n        int id=1;\n        for(int i=0;i<best8;i++,id++){\n            for(int k=0;k<8;k++){\n                out0[bestPl0.bars8[i][k]] = id;\n                out1[bestPl1.bars8[i][k]] = id;\n            }\n        }\n        for(int i=0;i<best4;i++,id++){\n            for(int k=0;k<4;k++){\n                out0[bestPl0.bars4[i][k]] = id;\n                out1[bestPl1.bars4[i][k]] = id;\n            }\n        }\n        for(int i=0;i<best2;i++,id++){\n            out0[bestPl0.doms[i].first]=id;\n            out0[bestPl0.doms[i].second]=id;\n            out1[bestPl1.doms[i].first]=id;\n            out1[bestPl1.doms[i].second]=id;\n        }\n        for(int i=0;i<bestMono;i++,id++){\n            if(i<(int)bestPl0.monos.size()) out0[bestPl0.monos[i]] = id;\n            if(i<(int)bestPl1.monos.size()) out1[bestPl1.monos[i]] = id;\n        }\n        cout<<n<<\"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout<<' ';\n            cout<<out0[i];\n        }\n        cout<<\"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout<<' ';\n            cout<<out1[i];\n        }\n        cout<<\"\\n\";\n    }\n};\n\nint main(){\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeAdj {\n    int to;\n    int id;\n    long long w;\n};\nstruct DSU {\n    vector<int> p;\n    DSU(int n) : p(n, -1) {}\n    int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (p[a] > p[b]) swap(a, b);\n        p[a] += p[b];\n        p[b] = a;\n        return true;\n    }\n};\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    long long cost;\n    int covered;\n};\nint ceil_sqrt_ll(long long x) {\n    if (x <= 0) return 0;\n    long long r = (long long)std::sqrt((long double)x);\n    while (r * r < x) ++r;\n    while ((r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<long long> W(M);\n    vector<vector<EdgeAdj>> g(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        U[j] = u; V[j] = v; W[j] = w;\n        g[u].push_back({v, j, w});\n        g[v].push_back({u, j, w});\n    }\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n\n    const int LIMIT = 5000;\n    const int LIMIT2 = LIMIT * LIMIT;\n    const long long INFLL = (1LL << 60);\n\n    vector<vector<int>> dist2(N, vector<int>(K));\n    vector<vector<int>> within(N);\n    vector<vector<pair<int, int>>> sortedList(N);\n    for (int i = 0; i < N; i++) {\n        within[i].reserve(K / 4);\n        sortedList[i].reserve(K / 4);\n        for (int k = 0; k < K; k++) {\n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            long long d2 = dx * dx + dy * dy;\n            dist2[i][k] = (int)d2;\n            if (d2 <= LIMIT2) {\n                within[i].push_back(k);\n                sortedList[i].push_back({(int)d2, k});\n            }\n        }\n        sort(sortedList[i].begin(), sortedList[i].end(),\n             [](const pair<int, int> &p1, const pair<int, int> &p2) {\n                 if (p1.first != p2.first) return p1.first < p2.first;\n                 return p1.second < p2.second;\n             });\n    }\n\n    vector<vector<long long>> distMat(N, vector<long long>(N, INFLL));\n    vector<vector<int>> parentEdge(N, vector<int>(N, -1));\n    using PLLI = pair<long long, int>;\n    for (int s = 0; s < N; s++) {\n        vector<long long> d(N, INFLL);\n        vector<int> p(N, -1);\n        d[s] = 0;\n        priority_queue<PLLI, vector<PLLI>, greater<PLLI>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cd, v] = pq.top(); pq.pop();\n            if (cd != d[v]) continue;\n            for (auto &e : g[v]) {\n                long long nd = cd + e.w;\n                if (nd < d[e.to]) {\n                    d[e.to] = nd;\n                    p[e.to] = e.id;\n                    pq.push({nd, e.to});\n                }\n            }\n        }\n        distMat[s] = move(d);\n        parentEdge[s] = move(p);\n    }\n    vector<long long> spCost(N);\n    for (int i = 0; i < N; i++) spCost[i] = distMat[0][i];\n\n    struct EItem { long long w; int id; };\n    vector<EItem> eList;\n    eList.reserve(M);\n    for (int i = 0; i < M; i++) eList.push_back({W[i], i});\n    sort(eList.begin(), eList.end(), [](const EItem &a, const EItem &b){ return a.w < b.w; });\n    DSU dsuFull(N);\n    vector<int> mstFullEdges;\n    mstFullEdges.reserve(N - 1);\n    for (auto &ei : eList) {\n        int id = ei.id;\n        if (dsuFull.unite(U[id], V[id])) {\n            mstFullEdges.push_back(id);\n            if ((int)mstFullEdges.size() == N - 1) break;\n        }\n    }\n\n    auto prune_edges = [&](const vector<int> &Pvec, vector<int> &Bvec) {\n        vector<int> deg(N, 0);\n        vector<vector<int>> inc(N);\n        inc.assign(N, {});\n        for (int e = 0; e < M; e++) if (Bvec[e]) {\n            int a = U[e], b = V[e];\n            deg[a]++; deg[b]++;\n            inc[a].push_back(e);\n            inc[b].push_back(e);\n        }\n        auto isTerminal = [&](int v)->bool {\n            return Pvec[v] > 0 || v == 0;\n        };\n        queue<int> q;\n        vector<char> inq(N, false);\n        for (int i = 0; i < N; i++) {\n            if (!isTerminal(i) && deg[i] == 1) { q.push(i); inq[i] = true; }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (isTerminal(v) || deg[v] != 1) continue;\n            int eAct = -1;\n            for (int eid : inc[v]) if (Bvec[eid]) { eAct = eid; break; }\n            if (eAct == -1) continue;\n            Bvec[eAct] = 0;\n            int nei = (U[eAct] == v ? V[eAct] : U[eAct]);\n            deg[v]--; deg[nei]--;\n            if (!isTerminal(nei) && deg[nei] == 1 && !inq[nei]) { q.push(nei); inq[nei] = true; }\n        }\n    };\n\n    auto improve_P = [&](vector<int> P) {\n        vector<int> cnt(K, 0);\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                cnt[pr.second]++;\n            }\n        }\n        for (int iter = 0; iter < 2; iter++) {\n            bool changed = false;\n            for (int i = 0; i < N; i++) {\n                if (P[i] == 0) continue;\n                long long curR2 = 1LL * P[i] * P[i];\n                long long needR2 = -1;\n                for (auto &pr : sortedList[i]) {\n                    if (pr.first > curR2) break;\n                    int k = pr.second;\n                    if (cnt[k] == 1 && pr.first > needR2) needR2 = pr.first;\n                }\n                long long newR2 = (needR2 == -1 ? 0 : needR2);\n                if (newR2 < curR2) {\n                    bool ok = true;\n                    for (auto &pr : sortedList[i]) {\n                        if (pr.first > curR2) break;\n                        if (pr.first > newR2) {\n                            int k = pr.second;\n                            if (cnt[k] <= 1) { ok = false; break; }\n                        }\n                    }\n                    if (ok) {\n                        for (auto &pr : sortedList[i]) {\n                            if (pr.first > curR2) break;\n                            if (pr.first > newR2) {\n                                int k = pr.second;\n                                cnt[k]--;\n                            }\n                        }\n                        int newR = (newR2 == 0 ? 0 : ceil_sqrt_ll(newR2));\n                        P[i] = newR;\n                        changed = true;\n                    }\n                }\n            }\n            if (!changed) break;\n        }\n        for (int pass = 0; pass < 2; pass++) {\n            for (int i = 1; i < N; i++) {\n                if (P[i] == 0) continue;\n                int r2 = P[i] * P[i];\n                bool removable = true;\n                for (auto &pr : sortedList[i]) {\n                    if (pr.first > r2) break;\n                    int k = pr.second;\n                    if (cnt[k] <= 1) { removable = false; break; }\n                }\n                if (removable) {\n                    for (auto &pr : sortedList[i]) {\n                        if (pr.first > r2) break;\n                        int k = pr.second;\n                        cnt[k]--;\n                    }\n                    P[i] = 0;\n                }\n            }\n        }\n        return P;\n    };\n\n    auto eval_with_P = [&](vector<int> P)->Solution {\n        P = improve_P(P);\n        vector<char> covered(K, false);\n        int covcnt = 0;\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                int k = pr.second;\n                if (!covered[k]) { covered[k] = true; covcnt++; }\n            }\n        }\n        long long costP = 0;\n        for (int i = 0; i < N; i++) costP += 1LL * P[i] * P[i];\n\n        vector<int> terminals;\n        terminals.push_back(0);\n        for (int i = 1; i < N; i++) if (P[i] > 0) terminals.push_back(i);\n        int T = terminals.size();\n\n        vector<int> B1(M, 0), B2(M, 0), B3(M, 0);\n        long long costE1 = 0, costE2 = 0, costE3 = 0;\n\n        if (T > 1) {\n            vector<tuple<long long, int, int>> es;\n            es.reserve(T * (T - 1) / 2);\n            for (int i = 0; i < T; i++) {\n                int u = terminals[i];\n                for (int j = i + 1; j < T; j++) {\n                    int v = terminals[j];\n                    es.emplace_back(distMat[u][v], u, v);\n                }\n            }\n            sort(es.begin(), es.end(),\n                 [](const auto &a, const auto &b){ return get<0>(a) < get<0>(b); });\n            DSU dsu(N);\n            int added = 0;\n            for (auto &ed : es) {\n                long long w; int u, v;\n                tie(w, u, v) = ed;\n                if (dsu.unite(u, v)) {\n                    int cur = v;\n                    while (cur != u) {\n                        int e = parentEdge[u][cur];\n                        if (e == -1) break;\n                        B1[e] = 1;\n                        cur = (U[e] == cur ? V[e] : U[e]);\n                    }\n                    if (++added == T - 1) break;\n                }\n            }\n        }\n        prune_edges(P, B1);\n        for (int e = 0; e < M; e++) if (B1[e]) costE1 += W[e];\n\n        for (int eid : mstFullEdges) B2[eid] = 1;\n        prune_edges(P, B2);\n        for (int e = 0; e < M; e++) if (B2[e]) costE2 += W[e];\n\n        for (int v : terminals) {\n            if (v == 0) continue;\n            int cur = v;\n            while (cur != 0) {\n                int e = parentEdge[0][cur];\n                if (e == -1) break;\n                B3[e] = 1;\n                cur = (U[e] == cur ? V[e] : U[e]);\n            }\n        }\n        prune_edges(P, B3);\n        for (int e = 0; e < M; e++) if (B3[e]) costE3 += W[e];\n\n        long long tot1 = costP + costE1;\n        long long tot2 = costP + costE2;\n        long long tot3 = costP + costE3;\n        if (tot1 <= tot2 && tot1 <= tot3) {\n            return Solution{P, B1, tot1, covcnt};\n        } else if (tot2 <= tot1 && tot2 <= tot3) {\n            return Solution{P, B2, tot2, covcnt};\n        } else {\n            return Solution{P, B3, tot3, covcnt};\n        }\n    };\n\n    auto ensure_coverage = [&](vector<int> allowed, const vector<char> *banned = nullptr) {\n        vector<char> inAllowed(N, false);\n        for (int v : allowed) inAllowed[v] = true;\n        vector<char> cov(K, false);\n        int uncovered = K;\n        for (int v : allowed) {\n            for (int k : within[v]) {\n                if (!cov[k]) { cov[k] = true; uncovered--; }\n            }\n        }\n        while (uncovered > 0) {\n            int target = -1;\n            for (int k = 0; k < K; k++) if (!cov[k]) { target = k; break; }\n            if (target == -1) break;\n            int bestv = -1; int bestd = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                if (banned && (*banned)[i]) continue;\n                int d = dist2[i][target];\n                if (d <= LIMIT2 && d < bestd) { bestd = d; bestv = i; }\n            }\n            if (bestv == -1) break;\n            if (!inAllowed[bestv]) {\n                inAllowed[bestv] = true;\n                allowed.push_back(bestv);\n                for (int k : within[bestv]) if (!cov[k]) { cov[k] = true; uncovered--; }\n            } else {\n                break;\n            }\n        }\n        return allowed;\n    };\n\n    auto buildP_nearest = [&](const vector<int> &allowed) {\n        vector<int> maxd2(N, -1);\n        for (int k = 0; k < K; k++) {\n            int best = -1;\n            int bestd = INT_MAX;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < bestd) { bestd = d; best = v; }\n            }\n            if (best == -1) continue;\n            if (bestd > maxd2[best]) maxd2[best] = bestd;\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (maxd2[i] >= 0) {\n                int r = ceil_sqrt_ll(maxd2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto buildP_incAssign = [&](const vector<int> &allowed, double gamma) {\n        vector<long long> cur_r2(N, 0);\n        vector<int> minDist2(K, INT_MAX);\n        for (int k = 0; k < K; k++) {\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < minDist2[k]) minDist2[k] = d;\n            }\n        }\n        vector<int> order(K);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j){ return minDist2[i] > minDist2[j]; });\n        for (int idx = 0; idx < K; idx++) {\n            int k = order[idx];\n            int best = -1;\n            double bestInc = 1e100;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d > LIMIT2) continue;\n                long long inc = max(cur_r2[v], (long long)d) - cur_r2[v];\n                double incAdj = (double)inc + (cur_r2[v] == 0 ? gamma * spCost[v] : 0.0);\n                if (incAdj < bestInc) {\n                    bestInc = incAdj;\n                    best = v;\n                }\n            }\n            if (best == -1) continue;\n            long long nd = dist2[best][k];\n            if (nd > cur_r2[best]) cur_r2[best] = nd;\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (cur_r2[i] > 0) {\n                int r = ceil_sqrt_ll(cur_r2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto expansion_greedy = [&](double beta) {\n        vector<long long> cur_r2(N, 0);\n        vector<char> covered(K, false);\n        int uncovered = K;\n        while (uncovered > 0) {\n            int bestStation = -1;\n            double bestRatio = 1e100;\n            long long bestR2 = 0;\n            for (int i = 0; i < N; i++) {\n                long long rcur = cur_r2[i];\n                int cnt = 0;\n                long long lastd = -1;\n                double bestLocalRatio = 1e100;\n                long long bestLocalR2 = -1;\n                for (auto &pr : sortedList[i]) {\n                    int d2 = pr.first;\n                    if (d2 <= rcur) continue;\n                    int res = pr.second;\n                    if (!covered[res]) cnt++;\n                    if (d2 != lastd) {\n                        if (cnt > 0) {\n                            double incCost = (double)(d2 - rcur);\n                            if (rcur == 0) incCost += beta * (double)spCost[i];\n                            double ratio = incCost / cnt;\n                            if (ratio < bestLocalRatio) {\n                                bestLocalRatio = ratio;\n                                bestLocalR2 = d2;\n                            }\n                        }\n                        lastd = d2;\n                    }\n                }\n                if (bestLocalR2 != -1 && bestLocalRatio < bestRatio) {\n                    bestRatio = bestLocalRatio;\n                    bestStation = i;\n                    bestR2 = bestLocalR2;\n                }\n            }\n            if (bestStation == -1) break;\n            cur_r2[bestStation] = bestR2;\n            for (auto &pr : sortedList[bestStation]) {\n                if (pr.first > bestR2) break;\n                int res = pr.second;\n                if (!covered[res]) {\n                    covered[res] = true;\n                    uncovered--;\n                }\n            }\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (cur_r2[i] > 0) {\n                int r = ceil_sqrt_ll(cur_r2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto greedy_cover_allowed = [&]() {\n        vector<char> covered(K, false);\n        int uncovered = K;\n        vector<char> sel(N, false);\n        sel[0] = true;\n        while (uncovered > 0) {\n            int best = -1;\n            int bestCnt = 0;\n            for (int i = 0; i < N; i++) {\n                if (sel[i]) continue;\n                int cnt = 0;\n                for (int k : within[i]) if (!covered[k]) cnt++;\n                if (cnt > bestCnt) { bestCnt = cnt; best = i; }\n            }\n            if (best == -1 || bestCnt == 0) break;\n            sel[best] = true;\n            for (int k : within[best]) if (!covered[k]) { covered[k] = true; uncovered--; }\n        }\n        vector<int> res;\n        for (int i = 0; i < N; i++) if (sel[i]) res.push_back(i);\n        return res;\n    };\n\n    vector<int> allowedSel = greedy_cover_allowed();\n    vector<int> allowedAug;\n    {\n        int TH = 3500, TH2 = TH * TH;\n        vector<char> flag(N, false);\n        for (int v : allowedSel) flag[v] = true;\n        for (int k = 0; k < K; k++) {\n            int bestd = INT_MAX;\n            for (int v : allowedSel) {\n                int d = dist2[v][k];\n                if (d < bestd) bestd = d;\n            }\n            if (bestd > TH2) {\n                int bestv = -1; int bestdv = INT_MAX;\n                for (int i = 0; i < N; i++) {\n                    int d = dist2[i][k];\n                    if (d < bestdv) { bestdv = d; bestv = i; }\n                }\n                if (bestv != -1) flag[bestv] = true;\n            }\n        }\n        for (int i = 0; i < N; i++) if (flag[i]) allowedAug.push_back(i);\n    }\n    vector<int> allSet(N);\n    iota(allSet.begin(), allSet.end(), 0);\n\n    vector<int> allowedCheap;\n    {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j){ return spCost[i] < spCost[j]; });\n        vector<char> cov(K, false);\n        int uncovered = K;\n        allowedCheap.push_back(0);\n        for (int v : order) {\n            if (v == 0) continue;\n            int cnt = 0;\n            for (int k : within[v]) if (!cov[k]) cnt++;\n            if (cnt == 0) continue;\n            allowedCheap.push_back(v);\n            for (int k : within[v]) if (!cov[k]) { cov[k] = true; uncovered--; }\n            if (uncovered == 0) break;\n        }\n        if (uncovered > 0) {\n            for (int i = 0; i < N; i++) if (find(allowedCheap.begin(), allowedCheap.end(), i) == allowedCheap.end()) allowedCheap.push_back(i);\n        }\n    }\n\n    vector<Solution> candidates;\n    vector<int> allowed1 = ensure_coverage(allowedSel);\n    vector<int> allowed2 = ensure_coverage(allowedAug);\n    vector<int> allowedAll = ensure_coverage(allSet);\n    vector<int> allowedC = ensure_coverage(allowedCheap);\n\n    candidates.push_back(eval_with_P(buildP_nearest(allowed1)));\n    candidates.push_back(eval_with_P(buildP_nearest(allowed2)));\n    candidates.push_back(eval_with_P(buildP_nearest(allowedAll)));\n    candidates.push_back(eval_with_P(buildP_nearest(allowedC)));\n\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedAll, 0.1)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedAll, 0.5)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedAll, 0.05)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowed1, 0.1)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedC, 0.1)));\n\n    vector<double> betas = {0.0, 0.2, 0.6, 1.5};\n    for (double beta : betas) {\n        candidates.push_back(eval_with_P(expansion_greedy(beta)));\n    }\n\n    long long maxd2root = 0;\n    for (int k = 0; k < K; k++) if (dist2[0][k] > maxd2root) maxd2root = dist2[0][k];\n    if (maxd2root <= LIMIT2) {\n        int r = ceil_sqrt_ll(maxd2root);\n        vector<int> P(N, 0);\n        P[0] = r;\n        candidates.push_back(eval_with_P(P));\n    }\n\n    Solution best;\n    best.cost = (long long)4e18;\n    best.covered = 0;\n    for (auto &sol : candidates) {\n        if (sol.covered == K) {\n            if (sol.cost < best.cost) best = sol;\n        } else if (best.covered < K) {\n            if (sol.covered > best.covered || (sol.covered == best.covered && sol.cost < best.cost)) {\n                best = sol;\n            }\n        }\n    }\n\n    auto refine_solution = [&](Solution sol) {\n        if (sol.covered < K) return sol;\n        int it = 0;\n        while (it < 2) {\n            it++;\n            vector<int> allowed;\n            allowed.push_back(0);\n            for (int i = 1; i < N; i++) if (sol.P[i] > 0) allowed.push_back(i);\n            bool improved = false;\n            for (int idx = 1; idx < (int)allowed.size(); idx++) {\n                int v = allowed[idx];\n                vector<char> banned(N, false);\n                banned[v] = true;\n                vector<int> newAllowed = allowed;\n                newAllowed.erase(newAllowed.begin() + idx);\n                newAllowed = ensure_coverage(newAllowed, &banned);\n                Solution cand = eval_with_P(buildP_incAssign(newAllowed, 0.1));\n                if (cand.covered == K && cand.cost < sol.cost - 1000) {\n                    sol = cand;\n                    improved = true;\n                    break;\n                }\n            }\n            if (!improved) break;\n        }\n        return sol;\n    };\n\n    best = refine_solution(best);\n\n    for (int i = 0; i < N; i++) {\n        cout << best.P[i] << (i + 1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (best.B[j] ? 1 : 0) << (j + 1 == M ? '\\n' : ' ');\n    }\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    static constexpr int N = 30;\n    static constexpr int TOT = N * (N + 1) / 2; // 465\n\n    vector<int> xs, ys;\n    vector<array<int, 2>> children; // -1 if none\n    vector<array<int, 2>> parents;  // -1 if none\n    vector<pair<int, int>> adj_edges; // undirected adjacency edges\n\n    Solver() {\n        xs.resize(TOT);\n        ys.resize(TOT);\n        children.assign(TOT, array<int, 2>{-1, -1});\n        parents.assign(TOT, array<int, 2>{-1, -1});\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                int id = x * (x + 1) / 2 + y;\n                xs[id] = x;\n                ys[id] = y;\n                if (x + 1 < N) {\n                    int c1 = (x + 1) * (x + 2) / 2 + y;\n                    int c2 = c1 + 1;\n                    children[id][0] = c1;\n                    children[id][1] = c2;\n                }\n                if (x > 0) {\n                    int p0 = (x - 1) * x / 2 + (y - 1); // upper-left\n                    int p1 = (x - 1) * x / 2 + y;       // upper-right\n                    parents[id][0] = (y > 0 ? p0 : -1);\n                    parents[id][1] = (y < x ? p1 : -1);\n                }\n            }\n        }\n        // build adjacency edges (undirected) without duplicates\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                int id = x * (x + 1) / 2 + y;\n                if (y + 1 <= x) {\n                    int nid = id + 1;\n                    adj_edges.emplace_back(id, nid);\n                }\n                if (x + 1 < N) {\n                    int dl = (x + 1) * (x + 2) / 2 + y;\n                    int dr = dl + 1;\n                    adj_edges.emplace_back(id, dl);\n                    adj_edges.emplace_back(id, dr);\n                }\n            }\n        }\n    }\n\n    int computeE(const vector<int> &val) const {\n        int e = 0;\n        for (int i = 0; i < TOT; i++) {\n            int c1 = children[i][0], c2 = children[i][1];\n            if (c1 != -1 && val[i] > val[c1]) e++;\n            if (c2 != -1 && val[i] > val[c2]) e++;\n        }\n        return e;\n    }\n\n    int computeDelta(const vector<int> &val, int u, int v) const {\n        int ep[10], ec[10];\n        int cnt = 0;\n        auto addEdge = [&](int p, int c) {\n            if (p == -1 || c == -1) return;\n            for (int i = 0; i < cnt; i++) {\n                if (ep[i] == p && ec[i] == c) return;\n            }\n            ep[cnt] = p;\n            ec[cnt] = c;\n            cnt++;\n        };\n        addEdge(u, children[u][0]);\n        addEdge(u, children[u][1]);\n        addEdge(v, children[v][0]);\n        addEdge(v, children[v][1]);\n        addEdge(parents[u][0], u);\n        addEdge(parents[u][1], u);\n        addEdge(parents[v][0], v);\n        addEdge(parents[v][1], v);\n\n        int oldE = 0, newE = 0;\n        for (int i = 0; i < cnt; i++) {\n            int p = ep[i], c = ec[i];\n            int vp_old = val[p], vc_old = val[c];\n            int vp_new = vp_old, vc_new = vc_old;\n            if (p == u) vp_new = val[v];\n            else if (p == v) vp_new = val[u];\n            if (c == u) vc_new = val[v];\n            else if (c == v) vc_new = val[u];\n            oldE += (vp_old > vc_old);\n            newE += (vp_new > vc_new);\n        }\n        return newE - oldE;\n    }\n\n    void heapify(vector<int> &val, vector<array<int, 4>> &moves, int moveLimit = 10000) const {\n        int last_internal = TOT - N - 1; // last node with children\n        for (int i = last_internal; i >= 0; i--) {\n            int cur = i;\n            while (children[cur][0] != -1) {\n                int c1 = children[cur][0];\n                int c2 = children[cur][1];\n                int c = (val[c2] < val[c1] ? c2 : c1);\n                if (val[cur] <= val[c]) break;\n                swap(val[cur], val[c]);\n                moves.push_back({xs[cur], ys[cur], xs[c], ys[c]});\n                cur = c;\n                if ((int)moves.size() >= moveLimit) return;\n            }\n        }\n    }\n\n    void prepass(vector<int> &val, vector<array<int, 4>> &moves, int maxSteps, int moveLimit, int minDeltaThreshold) const {\n        for (int step = 0; step < maxSteps; step++) {\n            int bestDelta = 0;\n            int bestA = -1, bestB = -1;\n            for (auto &e : adj_edges) {\n                int a = e.first, b = e.second;\n                int delta = computeDelta(val, a, b);\n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestA = a;\n                    bestB = b;\n                }\n            }\n            if (bestDelta >= minDeltaThreshold) break; // no sufficiently good move\n            swap(val[bestA], val[bestB]);\n            moves.push_back({xs[bestA], ys[bestA], xs[bestB], ys[bestB]});\n            if ((int)moves.size() >= moveLimit) break;\n        }\n    }\n\n    vector<array<int, 4>> produceCandidate(const vector<int> &initVal, bool mirrored, int preType, int moveLimit = 10000) const {\n        vector<int> val(TOT);\n        auto mirrorCoord = [&](int id) {\n            int x = xs[id], y = ys[id];\n            int my = x - y;\n            return x * (x + 1) / 2 + my;\n        };\n        if (!mirrored) {\n            val = initVal;\n        } else {\n            for (int id = 0; id < TOT; id++) {\n                int mid = mirrorCoord(id);\n                val[mid] = initVal[id];\n            }\n        }\n        vector<array<int, 4>> moves;\n        moves.reserve(4000);\n        if (preType > 0) {\n            int maxSteps = 0;\n            int threshold = -1;\n            if (preType == 1) { // strict\n                maxSteps = 400;\n                threshold = -2;\n            } else if (preType == 2) { // relaxed\n                maxSteps = 800;\n                threshold = -1;\n            } else { // full hillclimb\n                maxSteps = 1200;\n                threshold = 0;\n            }\n            prepass(val, moves, maxSteps, moveLimit, threshold);\n            if ((int)moves.size() >= moveLimit) {\n                if (mirrored) {\n                    for (auto &op : moves) {\n                        op[1] = op[0] - op[1];\n                        op[3] = op[2] - op[3];\n                    }\n                }\n                return moves;\n            }\n        }\n        heapify(val, moves, moveLimit);\n        if (mirrored) {\n            for (auto &op : moves) {\n                op[1] = op[0] - op[1];\n                op[3] = op[2] - op[3];\n            }\n        }\n        return moves;\n    }\n\n    int simulateE(const vector<int> &initVal, const vector<array<int, 4>> &moves) const {\n        vector<int> val = initVal;\n        for (auto &op : moves) {\n            int id1 = op[0] * (op[0] + 1) / 2 + op[1];\n            int id2 = op[2] * (op[2] + 1) / 2 + op[3];\n            swap(val[id1], val[id2]);\n        }\n        return computeE(val);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    vector<int> initVal(Solver::TOT);\n    for (int x = 0; x < Solver::N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int v;\n            if (!(cin >> v)) return 0;\n            int id = x * (x + 1) / 2 + y;\n            initVal[id] = v;\n        }\n    }\n    const int MOVE_LIMIT = 10000;\n    vector<vector<array<int, 4>>> candidates;\n    candidates.reserve(8);\n    for (bool mirrored : {false, true}) {\n        for (int preType = 0; preType <= 3; preType++) {\n            candidates.push_back(solver.produceCandidate(initVal, mirrored, preType, MOVE_LIMIT));\n        }\n    }\n    int bestIdx = -1;\n    int bestLen = INT_MAX;\n    for (int i = 0; i < (int)candidates.size(); i++) {\n        auto &mv = candidates[i];\n        if ((int)mv.size() > MOVE_LIMIT) continue;\n        int E = solver.simulateE(initVal, mv);\n        if (E != 0) continue;\n        if ((int)mv.size() < bestLen) {\n            bestLen = (int)mv.size();\n            bestIdx = i;\n        }\n    }\n    if (bestIdx == -1) {\n        bestIdx = 0; // fallback\n    }\n    auto &bestMoves = candidates[bestIdx];\n    cout << bestMoves.size() << \"\\n\";\n    for (auto &op : bestMoves) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int label;\n    int idx;\n    int r, c;\n};\nstruct Comp {\n    bool operator()(const Node &a, const Node &b) const {\n        if (a.label != b.label) return a.label > b.label;\n        return a.idx > b.idx;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    const int er = 0, ec = (D - 1) / 2;\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; k++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    const int dr[4] = {1, -1, 0, 0};\n    const int dc[4] = {0, 0, 1, -1};\n\n    /* distance from entrance */\n    vector<vector<int>> dist0(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist0[er][ec] = 0;\n    q.push({er, ec});\n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (dist0[nr][nc] != -1) continue;\n            dist0[nr][nc] = dist0[r][c] + 1;\n            q.push({nr, nc});\n        }\n    }\n\n    /* list of usable cells sorted by distance */\n    vector<pair<int, int>> cells;\n    cells.reserve(D * D);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (obstacle[i][j]) continue;\n            if (i == er && j == ec) continue;\n            cells.push_back({i, j});\n        }\n    }\n    sort(cells.begin(), cells.end(), [&](auto a, auto b) {\n        int da = dist0[a.first][a.second];\n        int db = dist0[b.first][b.second];\n        if (da != db) return da < db;\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    int K = (int)cells.size();\n    vector<int> idx_of(D * D, -1);\n    for (int idx = 0; idx < K; idx++) {\n        idx_of[cells[idx].first * D + cells[idx].second] = idx;\n    }\n\n    vector<vector<bool>> filled(D, vector<bool>(D, false));\n    vector<vector<int>> label_grid(D, vector<int>(D, -1));\n    int empties_count = K;\n\n    auto is_safe = [&](int r, int c) -> bool {\n        filled[r][c] = true;\n        bool vis[9][9] = {};\n        queue<pair<int, int>> qq;\n        qq.push({er, ec});\n        vis[er][ec] = true;\n        int cnt = 0;\n        while (!qq.empty()) {\n            auto [cr, cc] = qq.front();\n            qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int nr = cr + dr[k], nc = cc + dc[k];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (filled[nr][nc]) continue;\n                if (vis[nr][nc]) continue;\n                vis[nr][nc] = true;\n                cnt++;\n                qq.push({nr, nc});\n            }\n        }\n        filled[r][c] = false;\n        return cnt == empties_count - 1;\n    };\n\n    /* placement phase */\n    for (int step = 0; step < K; step++) {\n        int t;\n        cin >> t;\n        int chosen = -1;\n\n        /* prefer smallest available safe idx >= t */\n        for (int idx = t; idx < K; idx++) {\n            auto [r, c] = cells[idx];\n            if (filled[r][c]) continue;\n            if (is_safe(r, c)) {\n                chosen = idx;\n                break;\n            }\n        }\n        if (chosen == -1) {\n            /* fallback: largest available safe idx < t */\n            for (int idx = t - 1; idx >= 0; idx--) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    chosen = idx;\n                    break;\n                }\n            }\n        }\n        if (chosen == -1) {\n            /* final fallback */\n            for (int idx = 0; idx < K; idx++) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    chosen = idx;\n                    break;\n                }\n            }\n        }\n        auto [pr, pc] = cells[chosen];\n        filled[pr][pc] = true;\n        label_grid[pr][pc] = t;\n        empties_count--;\n        cout << pr << \" \" << pc << '\\n';\n        cout.flush();\n    }\n\n    /* retrieval phase */\n    vector<vector<bool>> present(D, vector<bool>(D, false));\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (label_grid[i][j] != -1) present[i][j] = true;\n    }\n\n    priority_queue<Node, vector<Node>, Comp> pq;\n    auto push_if_present = [&](int r, int c) {\n        if (r < 0 || r >= D || c < 0 || c >= D) return;\n        if (obstacle[r][c]) return;\n        if (present[r][c]) {\n            int idx = idx_of[r * D + c];\n            pq.push({label_grid[r][c], idx, r, c});\n        }\n    };\n    push_if_present(er + 1, ec);\n    push_if_present(er - 1, ec);\n    push_if_present(er, ec + 1);\n    push_if_present(er, ec - 1);\n\n    int removed = 0;\n    while (removed < K) {\n        if (pq.empty()) {\n            bool done = false;\n            for (int i = 0; i < D && !done; i++) {\n                for (int j = 0; j < D && !done; j++) {\n                    if (!present[i][j]) continue;\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dr[k], nj = j + dc[k];\n                        if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                        if (obstacle[ni][nj]) continue;\n                        if (!present[ni][nj] || (ni == er && nj == ec)) {\n                            int idx = idx_of[i * D + j];\n                            pq.push({label_grid[i][j], idx, i, j});\n                            done = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        auto cur = pq.top();\n        pq.pop();\n        int r = cur.r, c = cur.c;\n        if (!present[r][c]) continue;\n        present[r][c] = false;\n        removed++;\n        cout << r << \" \" << c << '\\n';\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            push_if_present(nr, nc);\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t x = 88172645463325252ull;\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int mod) {\n        return int(next() % mod);\n    }\n};\n\nstruct Solver {\n    int n, m, C;\n    vector<int> orig;              // flattened grid\n    vector<vector<char>> adjOrig;\n    vector<char> boundary;\n    const int dr[4] = {1, -1, 0, 0};\n    const int dc[4] = {0, 0, 1, -1};\n\n    Solver(int n_, int m_, const vector<int> &g) : n(n_), m(m_), orig(g) {\n        C = m + 1;\n        computeAdjOrig();\n    }\n\n    void computeAdjOrig() {\n        adjOrig.assign(C, vector<char>(C, 0));\n        auto addEdge = [&](int a, int b) {\n            if (a == b) return;\n            adjOrig[a][b] = adjOrig[b][a] = 1;\n        };\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                int a = orig[i * n + j];\n                if (i + 1 < n) addEdge(a, orig[(i + 1) * n + j]);\n                if (j + 1 < n) addEdge(a, orig[i * n + j + 1]);\n                if (i == 0) addEdge(0, a);\n                if (i == n - 1) addEdge(0, a);\n                if (j == 0) addEdge(0, a);\n                if (j == n - 1) addEdge(0, a);\n            }\n        }\n        boundary.assign(C, 0);\n        boundary[0] = 1;\n        for (int c = 1; c <= m; c++) if (adjOrig[0][c]) boundary[c] = 1;\n    }\n\n    // Check connectivity of color col after removing cell idx\n    bool connectedAfterRemoval(int idx, int col, const vector<int> &g, const vector<int> &sz, vector<int> &vis, int &curMark) {\n        if (sz[col] <= 1) return false;\n        int r0 = idx / n, c0 = idx % n;\n        int start = -1;\n        for (int k = 0; k < 4; k++) {\n            int nr = r0 + dr[k], nc = c0 + dc[k];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            int nb = nr * n + nc;\n            if (g[nb] == col) { start = nb; break; }\n        }\n        if (start == -1) {\n            for (int i = 0; i < n * n; i++) {\n                if (i == idx) continue;\n                if (g[i] == col) { start = i; break; }\n            }\n        }\n        if (start == -1) return false;\n        curMark++;\n        queue<int> q;\n        q.push(start);\n        vis[start] = curMark;\n        int cnt = 1;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int r = v / n, c = v % n;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n                int nb = nr * n + nc;\n                if (nb == idx) continue;\n                if (g[nb] != col) continue;\n                if (vis[nb] == curMark) continue;\n                vis[nb] = curMark;\n                q.push(nb);\n                cnt++;\n            }\n        }\n        return cnt == sz[col] - 1;\n    }\n\n    pair<int, vector<int>> runWithOrder(const vector<int> &startGrid, const vector<int> &order) {\n        vector<int> g = startGrid;\n        vector<int> sz(C, 0);\n        for (int v : g) sz[v]++;\n\n        // adjacency counts flat\n        vector<int> adjCnt(C * C, 0);\n        auto addEdge = [&](int a, int b) {\n            if (a == b) return;\n            adjCnt[a * C + b]++;\n            adjCnt[b * C + a]++;\n        };\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                int a = g[i * n + j];\n                if (i + 1 < n) addEdge(a, g[(i + 1) * n + j]);\n                if (j + 1 < n) addEdge(a, g[i * n + j + 1]);\n                if (i == 0) addEdge(0, a);\n                if (i == n - 1) addEdge(0, a);\n                if (j == 0) addEdge(0, a);\n                if (j == n - 1) addEdge(0, a);\n            }\n        }\n\n        vector<int> vis(n * n, 0);\n        int curMark = 0;\n        vector<int> remEdges(C, 0);\n\n        auto isAdjZero = [&](int idx, const vector<int> &grid) -> bool {\n            int r = idx / n, c = idx % n;\n            if (r == 0 || r == n - 1 || c == 0 || c == n - 1) return true;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                int nb = nr * n + nc;\n                if (grid[nb] == 0) return true;\n            }\n            return false;\n        };\n\n        while (true) {\n            bool removed = false;\n            for (int idx : order) {\n                int col = g[idx];\n                if (col == 0) continue;\n                if (!boundary[col]) continue; // internal colors untouched\n                if (sz[col] <= 1) continue;\n                if (!isAdjZero(idx, g)) continue; // ensure 0 connectivity\n                int r = idx / n, c = idx % n;\n                int num0 = 0, numSame = 0;\n                vector<int> touched;\n                bool bad = false;\n                for (int k = 0; k < 4; k++) {\n                    int nr = r + dr[k], nc = c + dc[k];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) {\n                        num0++;\n                        continue;\n                    }\n                    int d = g[nr * n + nc];\n                    if (d == 0) num0++;\n                    else if (d == col) numSame++;\n                    else {\n                        if (remEdges[d] == 0) touched.push_back(d);\n                        remEdges[d]++;\n                        if (!boundary[d]) { bad = true; break; } // would create 0-adj for internal\n                    }\n                }\n                if (bad) {\n                    for (int d : touched) remEdges[d] = 0;\n                    continue;\n                }\n                bool ok = true;\n                for (int d : touched) {\n                    if (adjOrig[col][d]) {\n                        if (adjCnt[col * C + d] - remEdges[d] <= 0) { ok = false; break; }\n                    }\n                }\n                if (ok) {\n                    int predicted0c = adjCnt[0 * C + col] - num0 + numSame;\n                    if (predicted0c <= 0) ok = false;\n                }\n                if (ok && numSame >= 2) {\n                    if (!connectedAfterRemoval(idx, col, g, sz, vis, curMark)) ok = false;\n                }\n                for (int d : touched) remEdges[d] = 0;\n                if (!ok) continue;\n                // perform removal\n                for (int k = 0; k < 4; k++) {\n                    int nr = r + dr[k], nc = c + dc[k];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) {\n                        adjCnt[0 * C + col]--; adjCnt[col * C + 0]--;\n                    } else {\n                        int d = g[nr * n + nc];\n                        if (d == col) {\n                            adjCnt[0 * C + col]++; adjCnt[col * C + 0]++;\n                        } else if (d == 0) {\n                            adjCnt[0 * C + col]--; adjCnt[col * C + 0]--;\n                        } else {\n                            adjCnt[col * C + d]--; adjCnt[d * C + col]--;\n                            adjCnt[0 * C + d]++; adjCnt[d * C + 0]++;\n                        }\n                    }\n                }\n                g[idx] = 0;\n                sz[col]--;\n                removed = true;\n                break;\n            }\n            if (!removed) break;\n        }\n        int zeros = 0;\n        for (int v : g) if (v == 0) zeros++;\n        return {zeros, move(g)};\n    }\n};\n\nvoid fastShuffle(vector<int> &v, FastRNG &rng) {\n    for (int i = (int)v.size() - 1; i > 0; --i) {\n        int j = rng.nextInt(i + 1);\n        swap(v[i], v[j]);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<int> g(n * n);\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { int c; cin >> c; g[i * n + j] = c; }\n\n    Solver solver(n, m, g);\n\n    vector<int> base(n * n);\n    iota(base.begin(), base.end(), 0);\n\n    vector<vector<int>> initialOrders;\n    vector<int> ord0 = base;\n    initialOrders.push_back(ord0);\n    vector<int> ord1 = base;\n    reverse(ord1.begin(), ord1.end());\n    initialOrders.push_back(ord1);\n    vector<int> ord2 = base;\n    sort(ord2.begin(), ord2.end(), [&](int a, int b) {\n        int ra = a / n, ca = a % n;\n        int rb = b / n, cb = b % n;\n        int da = min({ra, n - 1 - ra, ca, n - 1 - ca});\n        int db = min({rb, n - 1 - rb, cb, n - 1 - cb});\n        if (da != db) return da < db;\n        return a < b;\n    });\n    initialOrders.push_back(ord2);\n    vector<int> ord3 = base;\n    sort(ord3.begin(), ord3.end(), [&](int a, int b) {\n        int ra = a / n, ca = a % n;\n        int rb = b / n, cb = b % n;\n        int da = max({ra, n - 1 - ra, ca, n - 1 - ca});\n        int db = max({rb, n - 1 - rb, cb, n - 1 - cb});\n        if (da != db) return da < db;\n        return a < b;\n    });\n    initialOrders.push_back(ord3);\n\n    int bestZeros = -1;\n    vector<int> bestGrid = g;\n\n    for (auto &ord : initialOrders) {\n        auto res = solver.runWithOrder(g, ord);\n        if (res.first > bestZeros) {\n            bestZeros = res.first;\n            bestGrid = move(res.second);\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.6; // seconds per test\n    FastRNG rng;\n    vector<int> order = base;\n\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        fastShuffle(order, rng);\n        const vector<int> &startGrid = (rng.next() & 1) ? g : bestGrid;\n        auto res = solver.runWithOrder(startGrid, order);\n        if (res.first > bestZeros) {\n            bestZeros = res.first;\n            bestGrid = move(res.second);\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j) cout << ' ';\n            cout << bestGrid[i * n + j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, D, Q;\n    mt19937 rng;\n    int used;\n    vector<vector<char>> cmp; // 0 unknown, 1 i>j, 2 equal, 3 i<j\n    vector<double> wins;\n    vector<int> comps;\n    string resp;\n\n    Solver(int n,int d,int q):N(n),D(d),Q(q),rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count()){\n        used = 0;\n        cmp.assign(N, vector<char>(N, 0));\n        wins.assign(N, 0.0);\n        comps.assign(N, 0);\n    }\n\n    // interactive compare i vs j, return true if i heavier than j\n    bool compare(int i, int j) {\n        if (cmp[i][j]) {\n            return cmp[i][j] == 1;\n        }\n        cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << \"\\n\";\n        cout.flush();\n        if (!(cin >> resp)) exit(0);\n        char c = resp[0];\n        used++;\n        if (c == '>') {\n            cmp[i][j] = 1; cmp[j][i] = 3;\n            comps[i]++; comps[j]++; wins[i] += 1.0;\n            return true;\n        } else if (c == '<') {\n            cmp[i][j] = 3; cmp[j][i] = 1;\n            comps[i]++; comps[j]++; wins[j] += 1.0;\n            return false;\n        } else {\n            cmp[i][j] = cmp[j][i] = 2;\n            comps[i]++; comps[j]++; wins[i] += 0.5; wins[j] += 0.5;\n            return false; // equal, treat as not greater\n        }\n    }\n\n    vector<int> merge_sort(const vector<int>& arr) {\n        int n = arr.size();\n        if (n <= 1) return arr;\n        int mid = n / 2;\n        vector<int> left(arr.begin(), arr.begin() + mid);\n        vector<int> right(arr.begin() + mid, arr.end());\n        left = merge_sort(left);\n        right = merge_sort(right);\n        vector<int> res;\n        res.reserve(n);\n        int i = 0, j = 0;\n        while (i < (int)left.size() && j < (int)right.size()) {\n            int a = left[i], b = right[j];\n            if (compare(a, b)) {\n                res.push_back(a);\n                i++;\n            } else {\n                res.push_back(b);\n                j++;\n            }\n        }\n        while (i < (int)left.size()) res.push_back(left[i++]);\n        while (j < (int)right.size()) res.push_back(right[j++]);\n        return res;\n    }\n\n    void filler_queries() {\n        while (used < Q) {\n            int a = 0, b = 1;\n            cout << 1 << \" \" << 1 << \" \" << a << \" \" << b << \"\\n\";\n            cout.flush();\n            if (!(cin >> resp)) exit(0);\n            used++;\n        }\n    }\n\n    void solve() {\n        // threshold for full sort\n        int lg = 0;\n        while ((1 << lg) < N) lg++;\n        int needComp = N * lg - (1 << lg) + 1; // mergesort worst-case comparisons\n        vector<double> west(N, 0.0);\n        vector<int> rank(N, 0);\n        bool sorted = false;\n\n        if (Q >= needComp + 1) {\n            // Perform full mergesort\n            vector<int> arr(N);\n            iota(arr.begin(), arr.end(), 0);\n            vector<int> ord = merge_sort(arr);\n            // ord is sorted from heavy to light\n            for (int pos = 0; pos < N; pos++) {\n                rank[ord[pos]] = pos;\n            }\n            sorted = true;\n        } else {\n            // Fallback: random pair comparisons\n            vector<pair<int,int>> pairs;\n            pairs.reserve(N*(N-1)/2);\n            for (int i = 0; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    pairs.emplace_back(i, j);\n                }\n            }\n            shuffle(pairs.begin(), pairs.end(), rng);\n            int pidx = 0;\n            while (used < Q) {\n                if (pidx >= (int)pairs.size()) {\n                    shuffle(pairs.begin(), pairs.end(), rng);\n                    pidx = 0;\n                }\n                auto pr = pairs[pidx++];\n                int a = pr.first, b = pr.second;\n                cout << 1 << \" \" << 1 << \" \" << a << \" \" << b << \"\\n\";\n                cout.flush();\n                if (!(cin >> resp)) exit(0);\n                used++;\n                char c = resp[0];\n                comps[a]++; comps[b]++;\n                if (c == '>') wins[a] += 1.0;\n                else if (c == '<') wins[b] += 1.0;\n                else { wins[a] += 0.5; wins[b] += 0.5; }\n            }\n            for (int i = 0; i < N; i++) {\n                double p;\n                if (comps[i] == 0) p = 0.5;\n                else p = (wins[i] + 1.0) / (comps[i] + 2.0);\n                rank[i] = (int)((1.0 - p) * N); // rough\n            }\n        }\n\n        // consume remaining queries if sorted used fewer than Q\n        if (sorted && used < Q) {\n            filler_queries();\n        }\n\n        double lambda = 1e-5;\n        double M = 100000.0 * N / D;\n        double ex = exp(-lambda * M);\n\n        // weight estimation from rank\n        for (int i = 0; i < N; i++) {\n            double p = (N - rank[i] - 0.5) / N;\n            if (p <= 1e-9) p = 1e-9;\n            if (p >= 1 - 1e-9) p = 1 - 1e-9;\n            double w;\n            if (ex < 1e-9) w = -log(1.0 - p) / lambda;\n            else w = -log(1.0 - p * (1.0 - ex)) / lambda;\n            if (w > M) w = M;\n            west[i] = w;\n        }\n\n        // initial greedy assignment\n        vector<int> ord(N);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) {\n            if (west[a] == west[b]) return a < b;\n            return west[a] > west[b];\n        });\n        vector<double> sum(D, 0.0);\n        vector<int> assign(N, 0);\n        for (int id : ord) {\n            int best = 0;\n            double bestsum = sum[0];\n            for (int d = 1; d < D; d++) {\n                if (sum[d] < bestsum) {\n                    bestsum = sum[d];\n                    best = d;\n                }\n            }\n            assign[id] = best;\n            sum[best] += west[id];\n        }\n\n        double total = accumulate(west.begin(), west.end(), 0.0);\n        double mean = total / D;\n        double curVar = 0.0;\n        for (int d = 0; d < D; d++) {\n            double diff = sum[d] - mean;\n            curVar += diff * diff;\n        }\n\n        // Simulated annealing\n        int ITER = 400000;\n        double T0 = sqrt(curVar);\n        if (T0 < 1e-3) T0 = 1.0;\n        double Tend = 1e-4;\n        uniform_real_distribution<double> ur(0.0, 1.0);\n\n        for (int it = 0; it < ITER; it++) {\n            double tfrac = (double)it / ITER;\n            double T = T0 * pow(Tend / T0, tfrac);\n            if ((rng() & 1) == 0) {\n                int i = rng() % N;\n                int gi = assign[i];\n                int gj = rng() % D;\n                if (gi == gj) continue;\n                double w = west[i];\n                double si = sum[gi], sj = sum[gj];\n                double nsi = si - w, nsj = sj + w;\n                double newVar = curVar\n                    - (si - mean)*(si - mean) - (sj - mean)*(sj - mean)\n                    + (nsi - mean)*(nsi - mean) + (nsj - mean)*(nsj - mean);\n                double delta = newVar - curVar;\n                if (delta < 0 || exp(-delta / T) > ur(rng)) {\n                    curVar = newVar;\n                    assign[i] = gj;\n                    sum[gi] = nsi;\n                    sum[gj] = nsj;\n                }\n            } else {\n                int i = rng() % N;\n                int j = rng() % N;\n                if (assign[i] == assign[j]) continue;\n                int gi = assign[i], gj = assign[j];\n                double wi = west[i], wj = west[j];\n                double si = sum[gi], sj = sum[gj];\n                double nsi = si - wi + wj;\n                double nsj = sj - wj + wi;\n                double newVar = curVar\n                    - (si - mean)*(si - mean) - (sj - mean)*(sj - mean)\n                    + (nsi - mean)*(nsi - mean) + (nsj - mean)*(nsj - mean);\n                double delta = newVar - curVar;\n                if (delta < 0 || exp(-delta / T) > ur(rng)) {\n                    curVar = newVar;\n                    swap(assign[i], assign[j]);\n                    sum[gi] = nsi;\n                    sum[gj] = nsj;\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (i) cout << ' ';\n            cout << assign[i];\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    Solver solver(N, D, Q);\n    solver.solve();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N_CONST = 200;\nconst int M_CONST = 10;\nconst int BUCKET_SIZE = 20;\nconst int INF_INT = 1e9;\n\nstruct Param {\n    int block_threshold; // if boxes above >= threshold, consider chunk/block move\n    int indiv_mode;      // 0: patience(top>=x), 1: bucket, 2: largestTop, 3: minHeight\n    int block_mode;      // 0: minHeight, 1: largestTop, 2: bucket, 3: patience(minVal), 4: maxMinStack, 5: safeMinStack>cur\n    int limit_block;     // 0 => move all above (until cur), else max chunk size to move\n    int safe_margin;     // if min(chunk) < cur + safe_margin, restrict chunk size\n    bool random_tie;     // random tie-breaking\n};\n\nstruct Result {\n    int cost;\n    int op_count;\n    vector<pair<int,int>> ops;\n    bool success;\n};\n\nchrono::steady_clock::time_point g_start;\ndouble TIME_LIMIT = 1.95;\n\ndouble elapsed_sec() {\n    return chrono::duration<double>(chrono::steady_clock::now() - g_start).count();\n}\n\n// destination for individual move of box x from src\nint select_dest_individual(int x, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.indiv_mode == 2) { // largestTop\n        int best = -1, bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.indiv_mode == 1) { // bucket preference\n        int target = (x - 1) / BUCKET_SIZE;\n        if (target != src) {\n            if (st[target].empty() || st[target].back() >= x) return target;\n        }\n    }\n    if (p.indiv_mode == 3) { // minHeight\n        int best = -1, bestSz = INF_INT, bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int sz = (int)st[i].size();\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n                bestSz = sz; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // patience\n    int bestTop = INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top >= x) {\n            if (top < bestTop) {\n                bestTop = top; cand.clear(); cand.push_back(i);\n            } else if (top == bestTop) cand.push_back(i);\n        }\n    }\n    if (!cand.empty()) {\n        if (p.random_tie && cand.size() > 1) {\n            uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n            return cand[dist(rng)];\n        } else {\n            int best = cand[0], bestSz = (int)st[best].size();\n            for (int id = 1; id < (int)cand.size(); id++) {\n                int i = cand[id];\n                int sz = (int)st[i].size();\n                if (sz < bestSz) { bestSz = sz; best = i; }\n            }\n            return best;\n        }\n    }\n    // fallback largest top\n    bestTop = -INF_INT; cand.clear();\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) {\n            bestTop = top; cand.clear(); cand.push_back(i);\n        } else if (top == bestTop) cand.push_back(i);\n    }\n    if (p.random_tie && cand.size() > 1) {\n        uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n        return cand[dist(rng)];\n    } else {\n        int best = cand[0], bestSz = (int)st[best].size();\n        for (int id = 1; id < (int)cand.size(); id++) {\n            int i = cand[id];\n            int sz = (int)st[i].size();\n            if (sz < bestSz) { bestSz = sz; best = i; }\n        }\n        return best;\n    }\n}\n\n// destination for block/chunk move given minVal in chunk, current target cur, from src\nint select_dest_block(int minVal, int cur, int src, const vector<vector<int>>& st,\n                      const vector<int>& minStack, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.block_mode == 1) { // largestTop\n        int best = -1, bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.block_mode == 2) { // bucket on minVal\n        int target = (minVal - 1) / BUCKET_SIZE;\n        if (target != src) return target;\n        // fallback to minHeight\n    }\n    if (p.block_mode == 3) { // patience on minVal\n        int bestTop = INF_INT;\n        vector<int> cand;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top >= minVal) {\n                if (top < bestTop) {\n                    bestTop = top; cand.clear(); cand.push_back(i);\n                } else if (top == bestTop) cand.push_back(i);\n            }\n        }\n        if (!cand.empty()) {\n            if (p.random_tie && cand.size() > 1) {\n                uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n                return cand[dist(rng)];\n            } else {\n                int best = cand[0], bestSz = (int)st[best].size();\n                for (int id = 1; id < (int)cand.size(); id++) {\n                    int i = cand[id];\n                    int sz = (int)st[i].size();\n                    if (sz < bestSz) { bestSz = sz; best = i; }\n                }\n                return best;\n            }\n        }\n        // fallback largestTop\n        int best = -1, bestT = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestT || (top == bestT && st[i].size() < st[best].size())) {\n                bestT = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.block_mode == 4) { // choose stack with maximum current minimum element\n        int best = -1;\n        int bestMin = -INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int mn = minStack[i];\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (mn > bestMin || (mn == bestMin && top > bestTop)) {\n                bestMin = mn; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.block_mode == 5) { // prefer stacks with minStack > cur\n        int best = -1;\n        int bestMin = -INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int mn = minStack[i];\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (mn > cur) {\n                if (mn > bestMin || (mn == bestMin && top > bestTop)) {\n                    bestMin = mn; bestTop = top; best = i;\n                }\n            }\n        }\n        if (best != -1) return best;\n        // fallback to block_mode 4\n        int b2 = -1; bestMin = -INF_INT; bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int mn = minStack[i];\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (mn > bestMin || (mn == bestMin && top > bestTop)) {\n                bestMin = mn; bestTop = top; b2 = i;\n            }\n        }\n        return b2;\n    }\n    // minHeight\n    int best = -1, bestSz = INF_INT, bestTop = -INF_INT;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int sz = (int)st[i].size();\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n            bestSz = sz; bestTop = top; best = i;\n        }\n    }\n    return best;\n}\n\nResult simulate(const vector<vector<int>>& init, const Param& p, uint64_t seed, bool record_ops, int best_cost_so_far) {\n    mt19937 rng(seed);\n    vector<vector<int>> st = init;\n    vector<int> pos(N_CONST + 1, -1);\n    int m = (int)st.size();\n    vector<int> minStack(m, INF_INT);\n    for (int i = 0; i < m; i++) {\n        int mn = INF_INT;\n        for (int v : st[i]) { pos[v] = i; mn = min(mn, v); }\n        minStack[i] = mn;\n    }\n    int energy = 0, op_cnt = 0;\n    vector<pair<int,int>> ops;\n    if (record_ops) ops.reserve(3000);\n\n    for (int cur = 1; cur <= N_CONST; cur++) {\n        while (true) {\n            int s = pos[cur];\n            if (s < 0) return {INF_INT, op_cnt, ops, false};\n            if (!st[s].empty() && st[s].back() == cur) {\n                st[s].pop_back();\n                pos[cur] = -1;\n                op_cnt++;\n                if (record_ops) ops.emplace_back(cur, 0);\n                if (st[s].empty()) minStack[s] = INF_INT;\n                else if (cur == minStack[s]) {\n                    int mn = INF_INT;\n                    for (int v : st[s]) mn = min(mn, v);\n                    minStack[s] = mn;\n                }\n                break;\n            } else {\n                int d = 0;\n                for (int idx = (int)st[s].size() - 1; idx >= 0; idx--) {\n                    if (st[s][idx] == cur) break;\n                    d++;\n                }\n                bool did_block = false;\n                if (d > 0 && d >= p.block_threshold) {\n                    // compute min of all above\n                    int minAbove = INF_INT;\n                    for (int idx = (int)st[s].size() - d; idx < (int)st[s].size(); idx++) {\n                        minAbove = min(minAbove, st[s][idx]);\n                    }\n                    int move_k;\n                    if (p.safe_margin > 0 && minAbove < cur + p.safe_margin) {\n                        // risky, move only a small chunk\n                        if (p.limit_block > 0) move_k = min(d, p.limit_block);\n                        else move_k = p.block_threshold; // small chunk\n                    } else {\n                        move_k = d;\n                        if (p.limit_block > 0) move_k = min(move_k, p.limit_block);\n                    }\n                    // compute minVal of chunk to move (top move_k)\n                    int start_idx = (int)st[s].size() - move_k;\n                    int rep = st[s][start_idx];\n                    int minVal = INF_INT;\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        minVal = min(minVal, st[s][idx]);\n                    }\n                    int dest = select_dest_block(minVal, cur, s, st, minStack, p, rng);\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        int val = st[s][idx];\n                        st[dest].push_back(val);\n                        pos[val] = dest;\n                        minStack[dest] = min(minStack[dest], val);\n                    }\n                    st[s].resize(start_idx);\n                    if (st[s].empty()) minStack[s] = INF_INT;\n                    else {\n                        int mn = INF_INT;\n                        for (int v : st[s]) mn = min(mn, v);\n                        minStack[s] = mn;\n                    }\n                    energy += move_k + 1;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(rep, dest + 1);\n                    did_block = true;\n                }\n                if (!did_block) {\n                    int x = st[s].back();\n                    int dest = select_dest_individual(x, s, st, p, rng);\n                    st[s].pop_back();\n                    st[dest].push_back(x);\n                    pos[x] = dest;\n                    if (x == minStack[s]) {\n                        if (st[s].empty()) minStack[s] = INF_INT;\n                        else {\n                            int mn = INF_INT;\n                            for (int v : st[s]) mn = min(mn, v);\n                            minStack[s] = mn;\n                        }\n                    }\n                    minStack[dest] = min(minStack[dest], x);\n                    energy += 2;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(x, dest + 1);\n                }\n                if (op_cnt > 5000) return {INF_INT, op_cnt, ops, false};\n                if (!record_ops && energy >= best_cost_so_far) {\n                    return {INF_INT, op_cnt, ops, false};\n                }\n            }\n        }\n    }\n    return {energy, op_cnt, ops, true};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> init(m);\n    for (int i = 0; i < m; i++) {\n        init[i].reserve(n / m);\n        for (int j = 0; j < n / m; j++) {\n            int v; cin >> v;\n            init[i].push_back(v);\n        }\n    }\n\n    g_start = chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Param> base;\n    // diverse parameter candidates including safe_margin and block_mode=5\n    base.push_back({2, 0, 5, 0, 5, true});\n    base.push_back({3, 0, 5, 0, 5, true});\n    base.push_back({2, 1, 5, 0, 5, true});\n    base.push_back({2, 3, 5, 0, 5, true});\n    base.push_back({2, 0, 4, 0, 0, false});\n    base.push_back({3, 0, 4, 0, 0, false});\n    base.push_back({2, 0, 4, 5, 3, true});\n    base.push_back({3, 0, 4, 5, 3, true});\n    base.push_back({2, 0, 3, 0, 3, true});\n    base.push_back({2, 0, 2, 0, 0, false});\n    base.push_back({2, 0, 1, 0, 0, false});\n    base.push_back({1, 0, 5, 0, 5, true});\n    base.push_back({1, 0, 4, 0, 3, true});\n    base.push_back({2, 2, 5, 0, 5, true});\n    base.push_back({2, 0, 5, 5, 5, true});\n    base.push_back({2, 0, 5, 8, 5, true});\n    base.push_back({2, 0, 4, 8, 3, true});\n    base.push_back({3, 0, 4, 8, 3, true});\n    base.push_back({2, 0, 0, 0, 0, false}); // patience classic\n    base.push_back({3, 0, 0, 0, 0, false});\n    base.push_back({2, 1, 0, 0, 0, false});\n    base.push_back({2, 3, 0, 0, 0, false});\n\n    int best_cost = INF_INT;\n    vector<pair<int,int>> best_ops;\n\n    // evaluate base params quickly\n    for (const auto &p : base) {\n        if (elapsed_sec() > TIME_LIMIT) break;\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    // random exploration within time limit\n    vector<int> limits = {0, 5, 8, 10};\n    while (elapsed_sec() < TIME_LIMIT) {\n        Param p = base[rng() % base.size()];\n        p.random_tie = true;\n        int delta = (int)(rng() % 3) - 1; // -1,0,1\n        p.block_threshold = max(1, p.block_threshold + delta);\n        p.limit_block = limits[rng() % limits.size()];\n        // vary safe_margin slightly\n        int smd = (int)(rng() % 3) - 1;\n        p.safe_margin = max(0, p.safe_margin + smd);\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    if (best_ops.empty()) {\n        // fallback simple strategy\n        Param p{2, 0, 4, 0, 3, true};\n        Result r = simulate(init, p, 1234567, true, INF_INT);\n        best_ops.swap(r.ops);\n    }\n\n    for (auto &op : best_ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, V;\nvector<string> hwall, vwall;\nvector<int> dflat;\nvector<vector<int>> adj;\nvector<short> distMat;\nvector<int> parMat;\n\ninline int id(int i, int j) { return i * N + j; }\n\nchar dirChar(int a, int b) {\n    int ai = a / N, aj = a % N;\n    int bi = b / N, bj = b % N;\n    if (bi == ai + 1) return 'D';\n    if (bi == ai - 1) return 'U';\n    if (bj == aj + 1) return 'R';\n    if (bj == aj - 1) return 'L';\n    return '?';\n}\n\nvoid bfs_all_pairs() {\n    distMat.assign(V * V, 0);\n    parMat.assign(V * V, -1);\n    vector<int> dist(V);\n    queue<int> q;\n    for (int s = 0; s < V; s++) {\n        fill(dist.begin(), dist.end(), -1);\n        dist[s] = 0;\n        parMat[s * V + s] = -1;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int nb : adj[v]) {\n                if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    parMat[s * V + nb] = v;\n                    q.push(nb);\n                }\n            }\n        }\n        short *row = &distMat[s * V];\n        for (int i = 0; i < V; i++) row[i] = (short)dist[i];\n    }\n}\n\nvector<int> build_nn(bool randomized, mt19937 &rng) {\n    vector<int> ord(V);\n    vector<char> used(V, 0);\n    ord[0] = 0;\n    used[0] = 1;\n    for (int idx = 1; idx < V; idx++) {\n        int cur = ord[idx - 1];\n        int best = -1;\n        int bestd = INT_MAX;\n        const short *row = &distMat[cur * V];\n        if (randomized) {\n            vector<pair<int,int>> cand;\n            cand.reserve(10);\n            for (int v = 0; v < V; v++) if (!used[v]) {\n                int d = row[v];\n                if ((int)cand.size() < 10) {\n                    cand.emplace_back(d, v);\n                    push_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                } else if (d < cand.front().first) {\n                    pop_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                    cand.back() = {d, v};\n                    push_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                }\n            }\n            if (cand.empty()) break;\n            uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n            best = cand[dist(rng)].second;\n        } else {\n            for (int v = 0; v < V; v++) if (!used[v]) {\n                int d = row[v];\n                if (d < bestd) { bestd = d; best = v; }\n            }\n        }\n        if (best == -1) break;\n        ord[idx] = best;\n        used[best] = 1;\n    }\n    return ord;\n}\n\nvector<int> build_cheapest_insertion() {\n    vector<int> cycle;\n    vector<char> used(V, 0);\n    cycle.push_back(0);\n    used[0] = 1;\n    int nearest = -1, bestd = INT_MAX;\n    const short *row0 = &distMat[0];\n    for (int v = 1; v < V; v++) {\n        int d = row0[v];\n        if (d < bestd) { bestd = d; nearest = v; }\n    }\n    if (nearest == -1) nearest = 0;\n    cycle.push_back(nearest);\n    used[nearest] = 1;\n    while ((int)cycle.size() < V) {\n        int bestNode = -1, bestPos = -1, bestInc = INT_MAX;\n        int m = (int)cycle.size();\n        for (int v = 0; v < V; v++) if (!used[v]) {\n            for (int i = 0; i < m; i++) {\n                int a = cycle[i];\n                int b = cycle[(i + 1) % m];\n                int inc = (int)distMat[a * V + v] + (int)distMat[v * V + b] - (int)distMat[a * V + b];\n                if (inc < bestInc) {\n                    bestInc = inc;\n                    bestNode = v;\n                    bestPos = i;\n                }\n            }\n        }\n        if (bestNode == -1) break;\n        cycle.insert(cycle.begin() + bestPos + 1, bestNode);\n        used[bestNode] = 1;\n    }\n    return cycle;\n}\n\nvector<int> build_mst_preorder() {\n    vector<int> parent(V, -1);\n    vector<int> key(V, INT_MAX);\n    vector<char> inMST(V, 0);\n    key[0] = 0;\n    for (int cnt = 0; cnt < V; cnt++) {\n        int u = -1, minKey = INT_MAX;\n        for (int v = 0; v < V; v++) if (!inMST[v] && key[v] < minKey) {\n            minKey = key[v]; u = v;\n        }\n        if (u == -1) break;\n        inMST[u] = 1;\n        const short *row = &distMat[u * V];\n        for (int v = 0; v < V; v++) if (!inMST[v]) {\n            int w = row[v];\n            if (w < key[v]) {\n                key[v] = w;\n                parent[v] = u;\n            }\n        }\n    }\n    vector<vector<int>> tree(V);\n    for (int v = 1; v < V; v++) if (parent[v] >= 0) tree[parent[v]].push_back(v);\n    vector<int> order;\n    order.reserve(V);\n    function<void(int)> dfs = [&](int u) {\n        order.push_back(u);\n        for (int v : tree[u]) dfs(v);\n    };\n    dfs(0);\n    return order;\n}\n\nlong long tour_length(const vector<int> &ord) {\n    long long len = 0;\n    for (int i = 0; i < V; i++) {\n        int a = ord[i];\n        int b = ord[(i + 1) % V];\n        len += (int)distMat[a * V + b];\n    }\n    return len;\n}\n\nvoid rotate_to_start(vector<int> &ord, int start = 0) {\n    int pos = -1;\n    for (int i = 0; i < V; i++) if (ord[i] == start) { pos = i; break; }\n    if (pos > 0) rotate(ord.begin(), ord.begin() + pos, ord.end());\n}\n\nvoid two_opt(vector<int> &ord, long long &curLen, double timeLimit, chrono::steady_clock::time_point startTime) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < V; i++) {\n            int a = ord[i];\n            int b = ord[(i + 1) % V];\n            for (int j = i + 2; j < V; j++) {\n                if (i == 0 && j == V - 1) continue;\n                int c = ord[j];\n                int d = ord[(j + 1) % V];\n                int delta = (int)distMat[a * V + c] + (int)distMat[b * V + d] - (int)distMat[a * V + b] - (int)distMat[c * V + d];\n                if (delta < 0) {\n                    reverse(ord.begin() + i + 1, ord.begin() + j + 1);\n                    curLen += delta;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n            if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > timeLimit) return;\n        }\n    }\n}\n\nvector<int> path_nodes(int s, int t) {\n    vector<int> path;\n    int cur = t;\n    while (cur != s) {\n        path.push_back(cur);\n        cur = parMat[s * V + cur];\n        if (cur == -1) { path.clear(); return path; }\n    }\n    path.push_back(s);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring moves_from_path(const vector<int> &path) {\n    string res;\n    for (int i = 1; i < (int)path.size(); i++) {\n        res.push_back(dirChar(path[i - 1], path[i]));\n    }\n    return res;\n}\n\nstring build_route_from_order(const vector<int> &ord) {\n    string moves;\n    moves.reserve((size_t)tour_length(ord) + 5);\n    for (int i = 0; i < V; i++) {\n        int s = ord[i];\n        int t = ord[(i + 1) % V];\n        if (s == t) continue;\n        vector<int> path = path_nodes(s, t);\n        if (path.empty()) return \"\";\n        for (int k = 1; k < (int)path.size(); k++) {\n            moves.push_back(dirChar(path[k - 1], path[k]));\n        }\n    }\n    return moves;\n}\n\nstring build_dfs_route() {\n    string res;\n    vector<vector<char>> vis(N, vector<char>(N, 0));\n    int di[4] = {0, 1, 0, -1};\n    int dj[4] = {1, 0, -1, 0};\n    char dc[4] = {'R', 'D', 'L', 'U'};\n    function<void(int, int)> dfs = [&](int i, int j) {\n        vis[i][j] = 1;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) wall = (vwall[i][j] == '1');\n            else if (dir == 2) wall = (vwall[i][j - 1] == '1');\n            else if (dir == 1) wall = (hwall[i][j] == '1');\n            else wall = (hwall[i - 1][j] == '1');\n            if (wall) continue;\n            if (!vis[ni][nj]) {\n                res.push_back(dc[dir]);\n                dfs(ni, nj);\n                res.push_back(dc[(dir + 2) % 4]);\n            }\n        }\n    };\n    dfs(0, 0);\n    return res;\n}\n\ndouble compute_average(const string &route) {\n    int L = (int)route.size();\n    int i = 0, j = 0;\n    vector<vector<int>> times(V);\n    times.reserve(V);\n    for (int t = 0; t < L; t++) {\n        char c = route[t];\n        int ni = i, nj = j;\n        if (c == 'U') {\n            ni--;\n            if (ni < 0 || hwall[ni][nj] == '1') return 1e100;\n        } else if (c == 'D') {\n            if (i >= N - 1 || hwall[i][j] == '1') return 1e100;\n            ni++;\n        } else if (c == 'L') {\n            if (j <= 0 || vwall[i][j - 1] == '1') return 1e100;\n            nj--;\n        } else if (c == 'R') {\n            if (j >= N - 1 || vwall[i][j] == '1') return 1e100;\n            nj++;\n        } else {\n            return 1e100;\n        }\n        i = ni; j = nj;\n        times[i * N + j].push_back(t);\n    }\n    if (i != 0 || j != 0) return 1e100;\n    double total = 0.0;\n    for (int v = 0; v < V; v++) {\n        if (times[v].empty()) return 1e100;\n        const auto &vec = times[v];\n        int k = (int)vec.size();\n        for (int idx = 0; idx < k; idx++) {\n            int t1 = vec[idx];\n            int t2 = (idx + 1 < k) ? vec[idx + 1] : vec[0] + L;\n            long long len = (long long)t2 - t1;\n            total += (double)dflat[v] * (double)(len * (len - 1) / 2.0);\n        }\n    }\n    return total / (double)L;\n}\n\nchar invertDir(char c) {\n    if (c == 'U') return 'D';\n    if (c == 'D') return 'U';\n    if (c == 'L') return 'R';\n    if (c == 'R') return 'L';\n    return c;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; i++) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; i++) cin >> vwall[i];\n    dflat.resize(N * N);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int x; cin >> x;\n        dflat[id(i, j)] = x;\n    }\n    V = N * N;\n    adj.assign(V, {});\n    auto add_edge = [&](int i1, int j1, int i2, int j2) {\n        int a = id(i1, j1), b = id(i2, j2);\n        adj[a].push_back(b);\n        adj[b].push_back(a);\n    };\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i + 1 < N && hwall[i][j] == '0') add_edge(i, j, i + 1, j);\n            if (j + 1 < N && vwall[i][j] == '0') add_edge(i, j, i, j + 1);\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    bfs_all_pairs();\n    mt19937 rng(1234567);\n\n    vector<vector<int>> candOrders;\n    candOrders.push_back(build_nn(false, rng));\n    candOrders.push_back(build_nn(true, rng));\n    candOrders.push_back(build_cheapest_insertion());\n    candOrders.push_back(build_mst_preorder());\n\n    long long bestLen = (1LL << 60);\n    vector<int> bestOrder;\n    double timeLimit = 1.0; // seconds for optimization\n    for (auto &ord : candOrders) {\n        rotate_to_start(ord, 0);\n        long long len = tour_length(ord);\n        two_opt(ord, len, timeLimit, startTime);\n        rotate_to_start(ord, 0);\n        len = tour_length(ord);\n        if (len < bestLen) {\n            bestLen = len;\n            bestOrder = ord;\n        }\n        if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > 1.0) break;\n    }\n\n    string baseRoute;\n    if (!bestOrder.empty()) baseRoute = build_route_from_order(bestOrder);\n    if (baseRoute.empty() || baseRoute.size() > 100000) {\n        baseRoute = build_dfs_route();\n        if (baseRoute.size() > 100000) {\n            baseRoute = baseRoute.substr(0, 100000);\n        }\n        cout << baseRoute << \"\\n\";\n        return 0;\n    }\n\n    double bestAvg = compute_average(baseRoute);\n    string bestRoute = baseRoute;\n\n    // Build loop candidates\n    vector<int> idx(V);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int a, int b){ return dflat[a] > dflat[b]; });\n    int K = min(8, V - 1);\n    vector<int> top;\n    for (int i = 0; i < K; i++) top.push_back(idx[i]);\n    vector<string> loopCandidates;\n\n    for (int v : top) {\n        vector<int> path = path_nodes(0, v);\n        if (path.empty()) continue;\n        string moves = moves_from_path(path);\n        string loop = moves;\n        for (int i = (int)moves.size() - 1; i >= 0; i--) loop.push_back(invertDir(moves[i]));\n        if (!loop.empty()) loopCandidates.push_back(loop);\n    }\n    auto build_cluster_loop = [&](int cnt) {\n        cnt = min(cnt, (int)top.size());\n        if (cnt == 0) return;\n        vector<int> sel(top.begin(), top.begin() + cnt);\n        vector<char> used(V, 0);\n        int cur = 0;\n        vector<int> orderNodes;\n        orderNodes.push_back(0);\n        while (!sel.empty()) {\n            int best = -1, bestd = INT_MAX, bestIdx = -1;\n            for (int i = 0; i < (int)sel.size(); i++) {\n                int v = sel[i];\n                int d = distMat[cur * V + v];\n                if (d < bestd) { bestd = d; best = v; bestIdx = i; }\n            }\n            if (best == -1) break;\n            orderNodes.push_back(best);\n            cur = best;\n            sel.erase(sel.begin() + bestIdx);\n        }\n        orderNodes.push_back(0);\n        string moves;\n        bool fail = false;\n        for (int i = 1; i < (int)orderNodes.size(); i++) {\n            vector<int> path = path_nodes(orderNodes[i - 1], orderNodes[i]);\n            if (path.empty()) { fail = true; break; }\n            moves += moves_from_path(path);\n        }\n        if (!fail && !moves.empty()) loopCandidates.push_back(moves);\n    };\n    build_cluster_loop(3);\n    build_cluster_loop(5);\n\n    int baseLen = (int)baseRoute.size();\n    for (const string &loop : loopCandidates) {\n        int lLen = (int)loop.size();\n        if (lLen == 0) continue;\n        int maxReps = (100000 - baseLen) / lLen;\n        if (maxReps <= 0) continue;\n        int repsToTest = min(maxReps, 12);\n        string temp = baseRoute;\n        for (int r = 1; r <= repsToTest; r++) {\n            temp += loop;\n            double avg = compute_average(temp);\n            if (avg < bestAvg) {\n                bestAvg = avg;\n                bestRoute = temp;\n            }\n            if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > 1.8) break;\n        }\n        if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > 1.8) break;\n    }\n\n    cout << bestRoute << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift {\n    uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t operator()() {\n        uint32_t t = x ^ (x << 11);\n        x = y; y = z; z = w;\n        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n        return w;\n    }\n    int nextInt(int n) { return (*this)() % n; }\n    double nextDouble() { return (*this)() * (1.0 / 4294967296.0); }\n} rng;\n\ninline int computeOverlap(const string &a, const string &b) {\n    int maxk = min((int)a.size(), (int)b.size());\n    for (int k = maxk; k >= 1; k--) {\n        bool ok = true;\n        const char *pa = a.data() + a.size() - k;\n        const char *pb = b.data();\n        for (int t = 0; t < k; t++) {\n            if (pa[t] != pb[t]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// Greedy pairwise merge, ties random if randomize=true\nstring greedyMerge(vector<string> v, bool randomize) {\n    while (v.size() > 1) {\n        int n = (int)v.size();\n        int best_o = -1;\n        vector<pair<int,int>> cand;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) if (i != j) {\n                int o = computeOverlap(v[i], v[j]);\n                if (o > best_o) {\n                    best_o = o;\n                    cand.clear();\n                    cand.emplace_back(i, j);\n                } else if (o == best_o) {\n                    cand.emplace_back(i, j);\n                }\n            }\n        }\n        pair<int,int> chosen = cand[randomize ? rng.nextInt((int)cand.size()) : 0];\n        int i = chosen.first, j = chosen.second;\n        string merged = v[i] + v[j].substr(best_o);\n        vector<string> nv;\n        nv.reserve(n - 1);\n        for (int k = 0; k < n; k++) {\n            if (k == i || k == j) continue;\n            nv.push_back(std::move(v[k]));\n        }\n        nv.push_back(std::move(merged));\n        v.swap(nv);\n    }\n    return v[0];\n}\n\n// Compute minimal typing cost for string S (DP)\nint computeCost(const string &S, const array<vector<pair<int,int>>,26> &posList, int si, int sj) {\n    const int INF = 1e9;\n    int L = (int)S.size();\n    vector<int> prevCost, currCost;\n    int c0 = S[0]-'A';\n    const auto &v0 = posList[c0];\n    prevCost.resize(v0.size());\n    for (size_t i = 0; i < v0.size(); i++) {\n        prevCost[i] = abs(v0[i].first - si) + abs(v0[i].second - sj) + 1;\n    }\n    for (int k = 1; k < L; k++) {\n        int c = S[k]-'A';\n        const auto &cv = posList[c];\n        currCost.assign(cv.size(), INF);\n        int pc = S[k-1]-'A';\n        const auto &pv = posList[pc];\n        for (size_t ci = 0; ci < cv.size(); ci++) {\n            int best = INF;\n            int x2 = cv[ci].first, y2 = cv[ci].second;\n            for (size_t pi = 0; pi < pv.size(); pi++) {\n                int cand = prevCost[pi] + abs(pv[pi].first - x2) + abs(pv[pi].second - y2) + 1;\n                if (cand < best) best = cand;\n            }\n            currCost[ci] = best;\n        }\n        prevCost.swap(currCost);\n    }\n    int res = *min_element(prevCost.begin(), prevCost.end());\n    return res;\n}\n\n// Compute optimal path (positions) for string S\nvector<pair<int,int>> computePath(const string &S, const array<vector<pair<int,int>>,26> &posList, int si, int sj) {\n    const int INF = 1e9;\n    int L = (int)S.size();\n    vector<vector<int>> dp(L);\n    vector<vector<int>> parent(L);\n    int c0 = S[0]-'A';\n    const auto &v0 = posList[c0];\n    dp[0].assign(v0.size(), INF);\n    parent[0].assign(v0.size(), -1);\n    for (size_t i = 0; i < v0.size(); i++) {\n        dp[0][i] = abs(v0[i].first - si) + abs(v0[i].second - sj) + 1;\n    }\n    for (int k = 1; k < L; k++) {\n        int c = S[k]-'A';\n        int pc = S[k-1]-'A';\n        const auto &cv = posList[c];\n        const auto &pv = posList[pc];\n        dp[k].assign(cv.size(), INF);\n        parent[k].assign(cv.size(), -1);\n        for (size_t ci = 0; ci < cv.size(); ci++) {\n            int best = INF;\n            int bestIdx = -1;\n            int x2 = cv[ci].first, y2 = cv[ci].second;\n            for (size_t pi = 0; pi < pv.size(); pi++) {\n                int cand = dp[k-1][pi] + abs(pv[pi].first - x2) + abs(pv[pi].second - y2) + 1;\n                if (cand < best) {\n                    best = cand;\n                    bestIdx = (int)pi;\n                }\n            }\n            dp[k][ci] = best;\n            parent[k][ci] = bestIdx;\n        }\n    }\n    int endIdx = (int)(min_element(dp[L-1].begin(), dp[L-1].end()) - dp[L-1].begin());\n    vector<pair<int,int>> path(L);\n    int idx = endIdx;\n    for (int k = L-1; k >= 0; k--) {\n        int c = S[k]-'A';\n        path[k] = posList[c][idx];\n        idx = parent[k][idx];\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n\n    // positions for each letter\n    array<vector<pair<int,int>>,26> posList;\n    for (int c = 0; c < 26; c++) posList[c].clear();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int c = grid[i][j]-'A';\n            posList[c].push_back({i,j});\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    double totalLimit = 1.9; // seconds\n\n    // Precompute overlaps between original words (length 5)\n    vector<vector<int>> ov(M, vector<int>(M, 0));\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < M; j++) if (i != j) {\n            ov[i][j] = computeOverlap(words[i], words[j]); // <=5\n        }\n    }\n\n    // Candidate best string and cost\n    string bestString = greedyMerge(words, false);\n    int bestCost = computeCost(bestString, posList, si, sj);\n\n    // Randomized greedy merges for some time\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > totalLimit * 0.5) break;\n        string cand = greedyMerge(words, true);\n        int cost = computeCost(cand, posList, si, sj);\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestString = std::move(cand);\n        }\n    }\n\n    // Build initial order: start with word whose first letter closest to start\n    int bestStart = 0;\n    int minStartDist = INT_MAX;\n    for (int i = 0; i < M; i++) {\n        int c = words[i][0]-'A';\n        int md = INT_MAX;\n        for (auto &p : posList[c]) {\n            int d = abs(p.first - si) + abs(p.second - sj);\n            if (d < md) md = d;\n        }\n        if (md < minStartDist) {\n            minStartDist = md;\n            bestStart = i;\n        }\n    }\n    vector<int> order;\n    order.reserve(M);\n    vector<char> used(M, 0);\n    order.push_back(bestStart);\n    used[bestStart] = 1;\n    for (int step = 1; step < M; step++) {\n        int cur = order.back();\n        int best = -1, bestO = -1;\n        for (int j = 0; j < M; j++) if (!used[j]) {\n            int o = ov[cur][j];\n            if (o > bestO) {\n                bestO = o;\n                best = j;\n            }\n        }\n        if (best == -1) {\n            for (int j = 0; j < M; j++) if (!used[j]) { best = j; break; }\n        }\n        used[best] = 1;\n        order.push_back(best);\n    }\n\n    auto buildStringFromOrder = [&](const vector<int> &ord) {\n        string s = words[ord[0]];\n        for (int i = 1; i < (int)ord.size(); i++) {\n            int o = ov[ord[i-1]][ord[i]];\n            s += words[ord[i]].substr(o);\n        }\n        return s;\n    };\n\n    // SA to maximize total overlap sum (fixed first)\n    auto calcScore = [&](const vector<int> &ord) {\n        int sum = 0;\n        for (int i = 0; i + 1 < (int)ord.size(); i++) sum += ov[ord[i]][ord[i+1]];\n        return sum;\n    };\n    int curScore = calcScore(order);\n    int bestScore = curScore;\n    vector<int> bestOrder = order;\n\n    auto edgeVal = [&](const vector<int> &ord, int idx) -> int {\n        if (idx < 0 || idx + 1 >= (int)ord.size()) return 0;\n        return ov[ord[idx]][ord[idx+1]];\n    };\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > totalLimit) break;\n        int a = 1 + rng.nextInt(M-1);\n        int b = 1 + rng.nextInt(M-1);\n        if (a == b) continue;\n        if (a > b) swap(a,b);\n        int oldSum = edgeVal(order, a-1) + edgeVal(order, a) + edgeVal(order, b-1) + edgeVal(order, b);\n        swap(order[a], order[b]);\n        int newSum = edgeVal(order, a-1) + edgeVal(order, a) + edgeVal(order, b-1) + edgeVal(order, b);\n        int delta = newSum - oldSum;\n        if (delta >= 0 || rng.nextDouble() < 0.001) { // simple acceptance\n            curScore += delta;\n            if (curScore > bestScore) {\n                bestScore = curScore;\n                bestOrder = order;\n            }\n        } else {\n            swap(order[a], order[b]); // revert\n        }\n    }\n\n    string saString = buildStringFromOrder(bestOrder);\n    int saCost = computeCost(saString, posList, si, sj);\n    if (saCost < bestCost) {\n        bestCost = saCost;\n        bestString = std::move(saString);\n    }\n\n    // compute path for bestString and output\n    auto path = computePath(bestString, posList, si, sj);\n    for (auto &p : path) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    vector<int> cells; // flattened cell ids\n};\n\nclass Solver {\npublic:\n    int N, M;\n    double eps;\n    vector<vector<pair<int,int>>> shapes;\n\n    vector<vector<Placement>> placements;\n    vector<vector<vector<int>>> cellToPlacements;\n    vector<vector<char>> alive;\n    vector<int> domainSize;\n    vector<vector<int>> cellCoverCount;\n    vector<int> totalCoverage;\n    vector<int> fieldCoverage;\n\n    vector<int> obs;\n    vector<int> drilledIds, drilledVals;\n\n    chrono::steady_clock::time_point startTime;\n    int searchTimeUsed = 0;\n\n    Solver(int N_, int M_, double eps_) : N(N_), M(M_), eps(eps_) {}\n\n    int cellId(int i,int j) const { return i*N + j; }\n    pair<int,int> cellCoord(int id) const { return {id / N, id % N}; }\n\n    void readInput() {\n        shapes.resize(M);\n        for (int k=0;k<M;k++) {\n            int d; cin>>d;\n            shapes[k].resize(d);\n            for (int t=0;t<d;t++) {\n                int i,j; cin>>i>>j;\n                shapes[k][t] = {i,j};\n            }\n        }\n    }\n\n    void buildPlacements() {\n        placements.resize(M);\n        cellToPlacements.resize(M, vector<vector<int>>(N*N));\n        alive.resize(M);\n        domainSize.resize(M);\n        cellCoverCount.assign(M, vector<int>(N*N, 0));\n        totalCoverage.assign(N*N, 0);\n        fieldCoverage.assign(N*N, 0);\n\n        for (int f=0; f<M; f++) {\n            int maxI=0, maxJ=0;\n            for (auto &p: shapes[f]) { maxI = max(maxI, p.first); maxJ = max(maxJ, p.second); }\n            int h = maxI+1;\n            int w = maxJ+1;\n            for (int di=0; di<=N-h; di++) {\n                for (int dj=0; dj<=N-w; dj++) {\n                    Placement pl;\n                    pl.cells.reserve(shapes[f].size());\n                    for (auto &p: shapes[f]) {\n                        int ni = p.first + di;\n                        int nj = p.second + dj;\n                        pl.cells.push_back(cellId(ni,nj));\n                    }\n                    int idx = placements[f].size();\n                    placements[f].push_back(std::move(pl));\n                    for (int c: placements[f].back().cells) {\n                        cellToPlacements[f][c].push_back(idx);\n                    }\n                }\n            }\n            int sz = placements[f].size();\n            alive[f].assign(sz, 1);\n            domainSize[f] = sz;\n            for (int idx=0; idx<sz; idx++) {\n                for (int c: placements[f][idx].cells) {\n                    totalCoverage[c]++;\n                    cellCoverCount[f][c]++;\n                }\n            }\n        }\n        for (int c=0; c<N*N; c++) {\n            int cnt=0;\n            for (int f=0; f<M; f++) if (cellCoverCount[f][c]>0) cnt++;\n            fieldCoverage[c] = cnt;\n        }\n    }\n\n    bool removePlacement(int f,int p) {\n        if (!alive[f][p]) return false;\n        alive[f][p]=0;\n        domainSize[f]--;\n        for (int c: placements[f][p].cells) {\n            totalCoverage[c]--;\n            cellCoverCount[f][c]--;\n            if (cellCoverCount[f][c]==0) {\n                fieldCoverage[c]--;\n            }\n        }\n        return true;\n    }\n\n    bool placementCoversCell(int f,int p,int cell) {\n        for (int c: placements[f][p].cells) if (c==cell) return true;\n        return false;\n    }\n\n    bool removePlacementsCovering(int f,int cell) {\n        bool changed=false;\n        for (int p: cellToPlacements[f][cell]) {\n            if (alive[f][p]) {\n                removePlacement(f,p);\n                changed=true;\n            }\n        }\n        return changed;\n    }\n\n    bool removePlacementsNotCovering(int f,int cell) {\n        bool changed=false;\n        int sz = placements[f].size();\n        for (int p=0; p<sz; p++) if (alive[f][p]) {\n            if (!placementCoversCell(f,p,cell)) {\n                removePlacement(f,p);\n                changed=true;\n            }\n        }\n        return changed;\n    }\n\n    void propagateConstraints() {\n        bool changed;\n        do {\n            changed=false;\n            for (size_t idx=0; idx<drilledIds.size(); idx++) {\n                int cell = drilledIds[idx];\n                int val = drilledVals[idx];\n                if (val<0) continue;\n                int maxCov=0, minCov=0;\n                for (int f=0; f<M; f++) {\n                    if (domainSize[f]==0) continue;\n                    int cnt = cellCoverCount[f][cell];\n                    if (cnt>0) maxCov++;\n                    if (cnt==domainSize[f] && cnt>0) minCov++;\n                }\n                if (val==0) {\n                    for (int f=0; f<M; f++) {\n                        if (cellCoverCount[f][cell]>0) {\n                            if (removePlacementsCovering(f,cell)) changed=true;\n                        }\n                    }\n                    continue;\n                }\n                if (val==maxCov && maxCov>0) {\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0) {\n                            if (cellCoverCount[f][cell] < domainSize[f]) {\n                                if (removePlacementsNotCovering(f,cell)) changed=true;\n                            }\n                        }\n                    }\n                } else if (val==minCov) {\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0 && cellCoverCount[f][cell]<domainSize[f]) {\n                            if (removePlacementsCovering(f,cell)) changed=true;\n                        }\n                    }\n                }\n            }\n        } while (changed);\n    }\n\n    int drillCell(int cell) {\n        auto [i,j] = cellCoord(cell);\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int resp;\n        if (!(cin >> resp)) exit(0);\n        obs[cell]=resp;\n        drilledIds.push_back(cell);\n        drilledVals.push_back(resp);\n        if (resp==0) {\n            for (int f=0; f<M; f++) {\n                if (cellCoverCount[f][cell]>0) {\n                    removePlacementsCovering(f,cell);\n                }\n            }\n        }\n        return resp;\n    }\n\n    bool allDomainsSingleton() const {\n        for (int f=0; f<M; f++) if (domainSize[f]!=1) return false;\n        return true;\n    }\n\n    vector<int> computeUnionFromDomains() const {\n        vector<char> oil(N*N,0);\n        for (int f=0; f<M; f++) {\n            int pidx=-1;\n            for (int p=0; p<(int)placements[f].size(); p++) if (alive[f][p]) { pidx=p; break; }\n            if (pidx==-1) continue;\n            for (int c: placements[f][pidx].cells) oil[c]=1;\n        }\n        vector<int> res;\n        for (int c=0; c<N*N; c++) if (oil[c]) res.push_back(c);\n        return res;\n    }\n\n    struct DFSState {\n        const vector<vector<int>> *domains;\n        const vector<vector<vector<int>>> *placementDrilled;\n        const vector<vector<char>> *fieldCanCover;\n        const vector<int> *obsVals;\n        vector<int> order;\n        vector<int> curCov;\n        vector<int> remCan;\n        vector<int> assignment;\n        int solutions=0;\n        vector<int> solAssign;\n        chrono::steady_clock::time_point deadline;\n        bool timedOut=false;\n\n        void dfs(int idx) {\n            if (timedOut) return;\n            if (chrono::steady_clock::now() > deadline) { timedOut=true; return; }\n            if (solutions>=2) return;\n            int D = obsVals->size();\n            if (idx==(int)order.size()) {\n                for (int d=0; d<D; d++) {\n                    if (curCov[d]!=(*obsVals)[d]) return;\n                }\n                solutions++;\n                solAssign = assignment;\n                return;\n            }\n            int f = order[idx];\n            for (int d=0; d<D; d++) {\n                if ((*fieldCanCover)[f][d]) remCan[d]--;\n            }\n            const auto &dom = (*domains)[f];\n            for (int pi=0; pi<(int)dom.size(); pi++) {\n                int pidx = dom[pi];\n                bool ok=true;\n                for (int d: (*placementDrilled)[f][pi]) {\n                    curCov[d]++;\n                    if (curCov[d] > (*obsVals)[d]) { ok=false; }\n                }\n                if (ok) {\n                    for (int d=0; d<D; d++) {\n                        if (curCov[d] + remCan[d] < (*obsVals)[d]) { ok=false; break; }\n                    }\n                }\n                if (ok) {\n                    assignment[f]=pidx;\n                    dfs(idx+1);\n                }\n                for (int d: (*placementDrilled)[f][pi]) curCov[d]--;\n                if (solutions>=2 || timedOut) break;\n            }\n            for (int d=0; d<D; d++) {\n                if ((*fieldCanCover)[f][d]) remCan[d]++;\n            }\n        }\n    };\n\n    int solveComponent(const vector<int> &fields, const vector<int> &dIdxs,\n                      vector<int> &assignOut, int timeLimitMs) {\n        int F = fields.size();\n        int D = dIdxs.size();\n\n        vector<vector<int>> domains(F);\n        for (int i=0;i<F;i++) {\n            int f = fields[i];\n            for (int p=0;p<(int)placements[f].size();p++) if (alive[f][p]) domains[i].push_back(p);\n            if (domains[i].empty()) return 0;\n        }\n\n        if (D==0) {\n            // Only solvable if all domains are singleton\n            for (int i=0;i<F;i++) {\n                if ((int)domains[i].size() != 1) return 2;\n            }\n            assignOut.resize(F);\n            for (int i=0;i<F;i++) assignOut[i] = domains[i][0];\n            return 1;\n        }\n\n        vector<int> drilledIndexByCell(N*N, -1);\n        for (int idx=0; idx<(int)drilledIds.size(); idx++) {\n            drilledIndexByCell[drilledIds[idx]] = idx;\n        }\n        vector<int> cellToLocal(drilledIds.size(), -1);\n        for (int i=0;i<D;i++) cellToLocal[dIdxs[i]] = i;\n\n        vector<vector<vector<int>>> placementDrilled(F);\n        vector<vector<char>> fieldCanCover(F, vector<char>(D, 0));\n        for (int i=0;i<F;i++) {\n            int f = fields[i];\n            int ds = domains[i].size();\n            placementDrilled[i].resize(ds);\n            for (int idx=0; idx<ds; idx++) {\n                int pidx = domains[i][idx];\n                for (int c: placements[f][pidx].cells) {\n                    int dg = drilledIndexByCell[c];\n                    if (dg<0) continue;\n                    int dl = cellToLocal[dg];\n                    if (dl>=0) {\n                        placementDrilled[i][idx].push_back(dl);\n                        fieldCanCover[i][dl]=1;\n                    }\n                }\n            }\n        }\n\n        vector<int> obsComp(D);\n        for (int i=0;i<D;i++) obsComp[i] = drilledVals[dIdxs[i]];\n\n        DFSState st;\n        st.domains = &domains;\n        st.placementDrilled = &placementDrilled;\n        st.fieldCanCover = &fieldCanCover;\n        st.obsVals = &obsComp;\n        st.order.resize(F);\n        iota(st.order.begin(), st.order.end(), 0);\n        sort(st.order.begin(), st.order.end(), [&](int a,int b){\n            return domains[a].size() < domains[b].size();\n        });\n        st.curCov.assign(D, 0);\n        st.remCan.assign(D, 0);\n        st.assignment.assign(F, -1);\n        for (int d=0; d<D; d++) {\n            int cnt=0;\n            for (int i=0;i<F;i++) if (fieldCanCover[i][d]) cnt++;\n            st.remCan[d]=cnt;\n        }\n        st.deadline = chrono::steady_clock::now() + chrono::milliseconds(timeLimitMs);\n        st.dfs(0);\n        if (st.timedOut) return 2;\n        if (st.solutions==1) {\n            assignOut.resize(F);\n            for (int i=0;i<F;i++) assignOut[i]=st.solAssign[i];\n            return 1;\n        }\n        if (st.solutions==0) return 0;\n        return 2;\n    }\n\n    int solveUnique(vector<int> &solution, int timeLimitMs) {\n        int D = drilledIds.size();\n        if (D==0) return 2;\n        // build bipartite connectivity\n        int V = M + D;\n        vector<vector<int>> adj(V);\n        for (int f=0; f<M; f++) {\n            for (int di=0; di<D; di++) {\n                int cell = drilledIds[di];\n                if (cellCoverCount[f][cell] > 0) {\n                    adj[f].push_back(M+di);\n                    adj[M+di].push_back(f);\n                }\n            }\n        }\n        vector<char> vis(V,0);\n        vector<vector<int>> compsF, compsD;\n        for (int v=0; v<V; v++) if (!vis[v]) {\n            queue<int> q;\n            q.push(v); vis[v]=1;\n            vector<int> cf, cd;\n            while(!q.empty()) {\n                int u=q.front(); q.pop();\n                if (u < M) cf.push_back(u);\n                else cd.push_back(u-M);\n                for (int to: adj[u]) if (!vis[to]) {\n                    vis[to]=1; q.push(to);\n                }\n            }\n            compsF.push_back(cf);\n            compsD.push_back(cd);\n        }\n        solution.assign(M, -1);\n        int comps = compsF.size();\n        int timeLeft = timeLimitMs;\n        for (int idx=0; idx<comps; idx++) {\n            auto tstart = chrono::steady_clock::now();\n            int alloc = max(5, timeLeft / (comps - idx));\n            vector<int> assignComp;\n            int status = solveComponent(compsF[idx], compsD[idx], assignComp, alloc);\n            auto tused = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-tstart).count();\n            timeLeft -= min(timeLeft, (int)tused);\n            if (status==0) return 0;\n            if (status==2) return 2;\n            for (int i=0;i<(int)compsF[idx].size();i++) {\n                solution[compsF[idx][i]] = assignComp[i];\n            }\n        }\n        return 1;\n    }\n\n    void outputAnswer(const vector<int> &cells) {\n        cout << \"a \" << cells.size();\n        for (int id: cells) {\n            auto [i,j] = cellCoord(id);\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << \"\\n\" << flush;\n        int res;\n        if (!(cin >> res)) exit(0);\n    }\n\n    double currentLogProd() const {\n        double lp=0;\n        for (int f=0; f<M; f++) {\n            if (domainSize[f]>0)\n                lp += log((double)domainSize[f]);\n            else\n                lp += log(1e9);\n        }\n        return lp;\n    }\n\n    void trySearchAndAnswer(int extraTimeBudgetMs=0) {\n        int elapsed = (int)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n        int remain = 2900 - elapsed;\n        remain = max(remain, 0);\n        int budget = min(remain, 200 + extraTimeBudgetMs);\n        budget = max(20, budget);\n        if (searchTimeUsed + budget > 1600) {\n            budget = max(10, 1600 - searchTimeUsed);\n        }\n        if (budget <= 0) return;\n        vector<int> solAssign;\n        int status = solveUnique(solAssign, budget);\n        searchTimeUsed += budget;\n        if (status==1) {\n            vector<char> oil(N*N,0);\n            for (int f=0; f<M; f++) {\n                int pidx = solAssign[f];\n                for (int c: placements[f][pidx].cells) oil[c]=1;\n            }\n            vector<int> ans;\n            for (int c=0; c<N*N; c++) if (oil[c]) ans.push_back(c);\n            outputAnswer(ans);\n            exit(0);\n        }\n    }\n\n    void solve() {\n        startTime = chrono::steady_clock::now();\n        obs.assign(N*N, -1);\n        propagateConstraints();\n        int steps=0;\n        while (true) {\n            if (allDomainsSingleton()) {\n                vector<int> ans = computeUnionFromDomains();\n                outputAnswer(ans);\n                return;\n            }\n            int elapsed = (int)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n            if (elapsed > 2700) break;\n            if (steps>=3 && steps%3==0) {\n                trySearchAndAnswer();\n            }\n            int best=-1;\n            long long bestElim=-1;\n            int bestOpt=-1;\n            int bestCov=-1;\n            for (int c=0; c<N*N; c++) if (obs[c]==-1) {\n                int opt=0;\n                long long elim=0;\n                int cov=0;\n                for (int f=0; f<M; f++) {\n                    int A = cellCoverCount[f][c];\n                    if (A==0) continue;\n                    int B = domainSize[f]-A;\n                    cov++;\n                    if (A>0 && B>0) opt++;\n                    elim += min(A,B);\n                }\n                if (opt==0 && elim==0) continue;\n                if (elim>bestElim || (elim==bestElim && (opt>bestOpt || (opt==bestOpt && cov>bestCov)))) {\n                    best=c; bestElim=elim; bestOpt=opt; bestCov=cov;\n                }\n            }\n            if (best==-1) break;\n            drillCell(best);\n            steps++;\n            propagateConstraints();\n            if (steps >= 2*N*N) break;\n        }\n        trySearchAndAnswer(200);\n        for (int c=0; c<N*N; c++) if (obs[c]==-1) {\n            drillCell(c);\n        }\n        vector<int> ans;\n        for (int c=0; c<N*N; c++) if (obs[c]>0) ans.push_back(c);\n        outputAnswer(ans);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M; double eps;\n    if (!(cin>>N>>M>>eps)) return 0;\n    Solver solver(N,M,eps);\n    solver.readInput();\n    solver.buildPlacements();\n    solver.solve();\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct PQItem {\n    int ben;\n    int idx;\n    bool operator<(const PQItem &o) const {\n        if (ben != o.ben) return ben < o.ben; // max-heap\n        return idx > o.idx;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0; // W is always 1000\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++) cin >> a[d][k];\n    }\n\n    vector<int> prev_p; // previous boundary positions (size N-1)\n\n    for (int d = 0; d < D; d++) {\n        // sort requests descending with original indices\n        vector<pair<int, int>> reqs;\n        reqs.reserve(N);\n        for (int k = 0; k < N; k++) reqs.emplace_back(a[d][k], k);\n        sort(reqs.begin(), reqs.end(), [&](const auto &p1, const auto &p2) {\n            if (p1.first != p2.first) return p1.first > p2.first;\n            return p1.second < p2.second;\n        });\n\n        vector<int> r(N);\n        for (int i = 0; i < N; i++) r[i] = reqs[i].first;\n\n        vector<int> heights(N, 0);\n        if (N == 1) {\n            heights[0] = W;\n        } else {\n            vector<int> hmin(N);\n            int sum_min = 0;\n            for (int i = 0; i < N; i++) {\n                hmin[i] = (r[i] + W - 1) / W;\n                sum_min += hmin[i];\n            }\n\n            if (sum_min <= W) {\n                int slack = W - sum_min;\n                int m = N - 1;\n                vector<int> low(m);\n                int pref = 0;\n                for (int j = 0; j < m; j++) {\n                    pref += hmin[j];\n                    low[j] = pref; // minimal position of boundary j\n                }\n\n                vector<int> target(m, -1);\n                if (d == 0) {\n                    for (int j = 0; j < m; j++) {\n                        target[j] = (long long)(slack) * (j + 1) / N;\n                    }\n                } else {\n                    for (int j = 0; j < m; j++) {\n                        int t = prev_p[j] - low[j];\n                        if (0 <= t && t <= slack) target[j] = t;\n                        else target[j] = -1;\n                    }\n                }\n\n                // DP to find nondecreasing sequence x_j in [0, slack] maximizing matches to target\n                vector<vector<int>> dp(m, vector<int>(slack + 1, -1e9));\n                vector<vector<int>> pre(m, vector<int>(slack + 1, -1));\n                for (int v = 0; v <= slack; v++) {\n                    dp[0][v] = (target[0] != -1 && v == target[0]) ? 1 : 0;\n                }\n                for (int j = 1; j < m; j++) {\n                    int best = -1e9;\n                    int bestv = 0;\n                    for (int v = 0; v <= slack; v++) {\n                        if (dp[j - 1][v] > best) {\n                            best = dp[j - 1][v];\n                            bestv = v;\n                        }\n                        int add = (target[j] != -1 && v == target[j]) ? 1 : 0;\n                        dp[j][v] = best + add;\n                        pre[j][v] = bestv;\n                    }\n                }\n                int best = -1e9, bestv = 0;\n                for (int v = 0; v <= slack; v++) {\n                    if (dp[m - 1][v] > best) {\n                        best = dp[m - 1][v];\n                        bestv = v;\n                    }\n                }\n                vector<int> x(m);\n                int curv = bestv;\n                for (int j = m - 1; j >= 0; j--) {\n                    x[j] = curv;\n                    curv = pre[j][curv];\n                    if (curv < 0) curv = 0;\n                }\n\n                vector<int> delta(N, 0);\n                delta[0] = x[0];\n                for (int i = 1; i < m; i++) {\n                    delta[i] = x[i] - x[i - 1];\n                }\n                delta[N - 1] = slack - x[m - 1];\n                for (int i = 0; i < N; i++) {\n                    heights[i] = hmin[i] + delta[i];\n                }\n            } else {\n                // fallback: greedy allocation of extra rows to minimize deficiency for this day\n                heights.assign(N, 1);\n                vector<int> caps(N, W); // current capacity per stripe\n                int rem = W - N;\n                priority_queue<PQItem> pq;\n                for (int i = 0; i < N; i++) {\n                    int deficiency = max(0, r[i] - caps[i]);\n                    int ben = min(W, deficiency);\n                    pq.push({ben, i});\n                }\n                while (rem > 0) {\n                    auto it = pq.top();\n                    pq.pop();\n                    int i = it.idx;\n                    heights[i] += 1;\n                    caps[i] += W;\n                    rem--;\n                    int deficiency = max(0, r[i] - caps[i]);\n                    int ben = min(W, deficiency);\n                    pq.push({ben, i});\n                }\n                // ensure sum == W\n                int s = 0;\n                for (int h : heights) s += h;\n                if (s != W) heights[N - 1] += (W - s);\n            }\n        }\n\n        // build stripes coordinates and boundaries\n        vector<array<int, 4>> stripes(N);\n        vector<int> cur_p;\n        cur_p.reserve(max(0, N - 1));\n        int y = 0;\n        for (int i = 0; i < N; i++) {\n            int h = heights[i];\n            stripes[i] = {y, 0, y + h, W};\n            y += h;\n            if (i < N - 1) cur_p.push_back(y);\n        }\n        // adjust last stripe if rounding error\n        if (y != W && N > 0) {\n            stripes[N - 1][2] += (W - y);\n            if (!cur_p.empty()) cur_p.back() = W;\n        }\n\n        // map to original indices\n        vector<array<int, 4>> out(N);\n        for (int i = 0; i < N; i++) {\n            int idx = reqs[i].second;\n            out[idx] = stripes[i];\n        }\n\n        for (int k = 0; k < N; k++) {\n            auto &rct = out[k];\n            cout << rct[0] << \" \" << rct[1] << \" \" << rct[2] << \" \" << rct[3] << \"\\n\";\n        }\n\n        prev_p = cur_p; // update boundaries for next day\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353LL;\nconst double TIME_LIMIT = 1.95;\n\nstruct OpInfo {\n    int m, p, q;\n    int idx[9];\n    int inc[9];\n};\n\nuint64_t rng_state;\ninline uint64_t rng64() {\n    rng_state ^= rng_state << 7;\n    rng_state ^= rng_state >> 9;\n    return rng_state;\n}\ninline int rand_int(int n) { return int(rng64() % n); }\ninline double rand_double() { return (rng64() >> 11) * (1.0 / 9007199254740992.0); }\n\n// delta if we add op\ninline ll delta_add(const OpInfo& op, const vector<ll>& modv) {\n    ll delta = 0;\n    ll nv;\n    nv = modv[op.idx[0]] + op.inc[0]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[0]];\n    nv = modv[op.idx[1]] + op.inc[1]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[1]];\n    nv = modv[op.idx[2]] + op.inc[2]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[2]];\n    nv = modv[op.idx[3]] + op.inc[3]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[3]];\n    nv = modv[op.idx[4]] + op.inc[4]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[4]];\n    nv = modv[op.idx[5]] + op.inc[5]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[5]];\n    nv = modv[op.idx[6]] + op.inc[6]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[6]];\n    nv = modv[op.idx[7]] + op.inc[7]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[7]];\n    nv = modv[op.idx[8]] + op.inc[8]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[8]];\n    return delta;\n}\n// delta if we remove op\ninline ll delta_remove(const OpInfo& op, const vector<ll>& modv) {\n    ll delta = 0;\n    ll nv;\n    nv = modv[op.idx[0]] - op.inc[0]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[0]];\n    nv = modv[op.idx[1]] - op.inc[1]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[1]];\n    nv = modv[op.idx[2]] - op.inc[2]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[2]];\n    nv = modv[op.idx[3]] - op.inc[3]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[3]];\n    nv = modv[op.idx[4]] - op.inc[4]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[4]];\n    nv = modv[op.idx[5]] - op.inc[5]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[5]];\n    nv = modv[op.idx[6]] - op.inc[6]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[6]];\n    nv = modv[op.idx[7]] - op.inc[7]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[7]];\n    nv = modv[op.idx[8]] - op.inc[8]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[8]];\n    return delta;\n}\n\n// greedy addition of positive delta ops\nvoid greedy_fill(const vector<OpInfo>& opsInfo, int totalOps, int K,\n                 vector<ll>& modv, ll& score, vector<int>& opsVec, int maxAdd) {\n    int canAdd = K - (int)opsVec.size();\n    if (maxAdd > canAdd) maxAdd = canAdd;\n    for (int step = 0; step < maxAdd; step++) {\n        ll bestDelta = 0;\n        int bestId = -1;\n        for (int opId = 0; opId < totalOps; opId++) {\n            ll delta = delta_add(opsInfo[opId], modv);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestId = opId;\n            }\n        }\n        if (bestDelta > 0 && bestId != -1) {\n            const auto& op = opsInfo[bestId];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] + op.inc[t];\n                if (nv >= MOD) nv -= MOD;\n                score += nv - modv[pos];\n                modv[pos] = nv;\n            }\n            opsVec.push_back(bestId);\n        } else break;\n    }\n}\n\n// hill climb with addition/removal/replacement until no improvement or time limit reached\nvoid hill_climb_full(const vector<OpInfo>& opsInfo, int totalOps, int K,\n                     vector<ll>& modv, ll& score, vector<int>& opsVec,\n                     chrono::steady_clock::time_point start_time) {\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        int L = (int)opsVec.size();\n\n        // Addition if possible\n        if (L < K) {\n            ll bestDeltaAdd = 0;\n            int bestIdAdd = -1;\n            for (int opId = 0; opId < totalOps; opId++) {\n                ll delta = delta_add(opsInfo[opId], modv);\n                if (delta > bestDeltaAdd) {\n                    bestDeltaAdd = delta;\n                    bestIdAdd = opId;\n                }\n            }\n            if (bestDeltaAdd > 0 && bestIdAdd != -1) {\n                const auto& op = opsInfo[bestIdAdd];\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modv[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    score += nv - modv[pos];\n                    modv[pos] = nv;\n                }\n                opsVec.push_back(bestIdAdd);\n                improved = true;\n                continue;\n            }\n        }\n\n        ll bestDelta = 0;\n        int bestIdx = -1;\n        int bestNewOp = -2; // -1 removal, >=0 replacement\n\n        // Removal\n        for (int idx = 0; idx < L; idx++) {\n            ll delta = delta_remove(opsInfo[opsVec[idx]], modv);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestIdx = idx;\n                bestNewOp = -1;\n            }\n        }\n\n        // Replacement\n        for (int idx = 0; idx < L; idx++) {\n            int oldId = opsVec[idx];\n            const auto& oldOp = opsInfo[oldId];\n            for (int newId = 0; newId < totalOps; newId++) {\n                if (newId == oldId) continue;\n                const auto& newOp = opsInfo[newId];\n                int idxs[18];\n                ll dadd[18];\n                int cnt = 0;\n                auto add_d = [&](int pos, ll d) {\n                    for (int t = 0; t < cnt; t++) {\n                        if (idxs[t] == pos) { dadd[t] += d; return; }\n                    }\n                    idxs[cnt] = pos;\n                    dadd[cnt] = d;\n                    cnt++;\n                };\n                for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n                for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n                ll delta = 0;\n                for (int t = 0; t < cnt; t++) {\n                    int pos = idxs[t];\n                    ll nv = modv[pos] + dadd[t];\n                    if (nv >= MOD) nv -= MOD;\n                    else if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                }\n                if (delta > bestDelta) {\n                    bestDelta = delta;\n                    bestIdx = idx;\n                    bestNewOp = newId;\n                }\n            }\n        }\n\n        if (bestDelta > 0 && bestIdx != -1) {\n            if (bestNewOp == -1) {\n                // removal\n                const auto& op = opsInfo[opsVec[bestIdx]];\n                ll delta = 0;\n                ll newVals[9];\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modv[pos] - op.inc[t];\n                    if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                    newVals[t] = nv;\n                }\n                score += delta;\n                for (int t = 0; t < 9; t++) {\n                    modv[op.idx[t]] = newVals[t];\n                }\n                opsVec[bestIdx] = opsVec.back();\n                opsVec.pop_back();\n                improved = true;\n            } else {\n                // replacement\n                const auto& oldOp = opsInfo[opsVec[bestIdx]];\n                const auto& newOp = opsInfo[bestNewOp];\n                int idxs[18];\n                ll dadd[18];\n                int cnt = 0;\n                auto add_d = [&](int pos, ll d) {\n                    for (int t = 0; t < cnt; t++) {\n                        if (idxs[t] == pos) { dadd[t] += d; return; }\n                    }\n                    idxs[cnt] = pos;\n                    dadd[cnt] = d;\n                    cnt++;\n                };\n                for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n                for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n                ll delta = 0;\n                ll newVals[18];\n                for (int t = 0; t < cnt; t++) {\n                    int pos = idxs[t];\n                    ll nv = modv[pos] + dadd[t];\n                    if (nv >= MOD) nv -= MOD;\n                    else if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                    newVals[t] = nv;\n                }\n                score += delta;\n                for (int t = 0; t < cnt; t++) modv[idxs[t]] = newVals[t];\n                opsVec[bestIdx] = bestNewOp;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    rng_state = chrono::high_resolution_clock::now().time_since_epoch().count();\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<ll> base(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            ll v; cin >> v;\n            base[i * N + j] = v;\n        }\n    }\n    vector<vector<vector<int>>> s(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int v; cin >> v;\n                s[m][i][j] = v;\n            }\n        }\n    }\n\n    // precompute operations\n    vector<OpInfo> opsInfo;\n    opsInfo.reserve(M * (N - 2) * (N - 2));\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                OpInfo op;\n                op.m = m; op.p = p; op.q = q;\n                int t = 0;\n                for (int di = 0; di < 3; di++) {\n                    for (int dj = 0; dj < 3; dj++) {\n                        op.idx[t] = (p + di) * N + (q + dj);\n                        op.inc[t] = s[m][di][dj];\n                        t++;\n                    }\n                }\n                opsInfo.push_back(op);\n            }\n        }\n    }\n    int totalOps = (int)opsInfo.size(); // 980\n\n    auto start_time = chrono::steady_clock::now();\n\n    // initial board mod values\n    vector<ll> modv(N * N);\n    ll score = 0;\n    for (int i = 0; i < N * N; i++) {\n        modv[i] = base[i] % MOD;\n        score += modv[i];\n    }\n\n    vector<int> curOps;\n    curOps.reserve(K);\n\n    // initial greedy\n    greedy_fill(opsInfo, totalOps, K, modv, score, curOps, K);\n\n    vector<int> bestOps = curOps;\n    ll bestScore = score;\n\n    // simulated annealing (short)\n    const double SA_LIMIT = 0.6;\n    const double T0 = 1e8;\n    const double T1 = 1e5;\n    double temp = T0;\n    int iter = 0;\n    const int CHECK_MASK = 1023;\n\n    while (true) {\n        if ((iter & CHECK_MASK) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > SA_LIMIT) break;\n            double progress = elapsed / SA_LIMIT;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        iter++;\n        int L = (int)curOps.size();\n        int moveType;\n        uint64_t rstate = rng64();\n        if (L == 0) moveType = 1;\n        else if (L == K) moveType = (rstate & 7) ? 0 : 2;\n        else {\n            int v = (int)(rstate % 100);\n            if (v < 65) moveType = 0;\n            else if (v < 85) moveType = 1;\n            else moveType = 2;\n        }\n\n        if (moveType == 0) {\n            // replace\n            int idx = (int)(rstate % L);\n            int oldId = curOps[idx];\n            int newId = rand_int(totalOps);\n            if (newId == oldId) continue;\n            const auto& oldOp = opsInfo[oldId];\n            const auto& newOp = opsInfo[newId];\n            int idxs[18];\n            ll dadd[18];\n            int cnt = 0;\n            auto add_d = [&](int pos, ll d) {\n                for (int t = 0; t < cnt; t++) {\n                    if (idxs[t] == pos) { dadd[t] += d; return; }\n                }\n                idxs[cnt] = pos;\n                dadd[cnt] = d;\n                cnt++;\n            };\n            for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n            for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n            ll delta = 0;\n            ll newVals[18];\n            for (int t = 0; t < cnt; t++) {\n                int pos = idxs[t];\n                ll nv = modv[pos] + dadd[t];\n                if (nv >= MOD) nv -= MOD;\n                else if (nv < 0) nv += MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp((double)delta / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += delta;\n                for (int t = 0; t < cnt; t++) modv[idxs[t]] = newVals[t];\n                curOps[idx] = newId;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else if (moveType == 1) {\n            // insert\n            if (L >= K) continue;\n            int newId = (int)(rstate % totalOps);\n            const auto& op = opsInfo[newId];\n            ll delta = 0;\n            ll newVals[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] + op.inc[t];\n                if (nv >= MOD) nv -= MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp((double)delta / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += delta;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newVals[t];\n                curOps.push_back(newId);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        } else {\n            // delete\n            int idx = (int)(rstate % L);\n            int oldId = curOps[idx];\n            const auto& op = opsInfo[oldId];\n            ll delta = 0;\n            ll newVals[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] - op.inc[t];\n                if (nv < 0) nv += MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp((double)delta / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += delta;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newVals[t];\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                }\n            }\n        }\n    }\n\n    // reconstruct best state\n    vector<ll> bestModv(N * N);\n    ll recomputed = 0;\n    for (int i = 0; i < N * N; i++) {\n        bestModv[i] = base[i] % MOD;\n        recomputed += bestModv[i];\n    }\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        for (int t = 0; t < 9; t++) {\n            int pos = op.idx[t];\n            ll nv = bestModv[pos] + op.inc[t];\n            if (nv >= MOD) nv -= MOD;\n            recomputed += nv - bestModv[pos];\n            bestModv[pos] = nv;\n        }\n    }\n    bestScore = recomputed;\n    // fill remaining slots greedily\n    greedy_fill(opsInfo, totalOps, K, bestModv, bestScore, bestOps, K - (int)bestOps.size());\n\n    // hill climb to local optimum\n    hill_climb_full(opsInfo, totalOps, K, bestModv, bestScore, bestOps, start_time);\n\n    // ruin & recreate loop\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        vector<ll> curModv = bestModv;\n        ll curScore = bestScore;\n        vector<int> curOps = bestOps;\n\n        int removeCnt = 2 + rand_int(7); // 2..8 removals\n        for (int t = 0; t < removeCnt && !curOps.empty(); t++) {\n            int idx = rand_int((int)curOps.size());\n            const auto& op = opsInfo[curOps[idx]];\n            for (int k = 0; k < 9; k++) {\n                int pos = op.idx[k];\n                ll nv = curModv[pos] - op.inc[k];\n                if (nv < 0) nv += MOD;\n                curScore += nv - curModv[pos];\n                curModv[pos] = nv;\n            }\n            curOps[idx] = curOps.back();\n            curOps.pop_back();\n        }\n\n        greedy_fill(opsInfo, totalOps, K, curModv, curScore, curOps, K - (int)curOps.size());\n\n        hill_climb_full(opsInfo, totalOps, K, curModv, curScore, curOps, start_time);\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n            bestModv = curModv;\n        }\n    }\n\n    cout << bestOps.size() << \"\\n\";\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;\n    int hold;   // -1 if empty\n    bool alive;\n};\n\nstruct Candidate {\n    vector<string> ops;\n    long long M0, M1, M2, M3;\n    long long score() const {\n        return M0 + 100LL * M1 + 10000LL * M2 + 1000000LL * M3;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n\n    const int base = N + 1; // 6\n    const int POS = N + 1;  // 6 (0..4 rows, 5 = undefined/start)\n    int totalStates = 1;\n    for (int i = 0; i < N; i++) totalStates *= base; // 6^5 = 7776\n\n    vector<int> powBase(N);\n    powBase[N - 1] = 1;\n    for (int k = N - 2; k >= 0; k--) powBase[k] = powBase[k + 1] * base;\n\n    // decode all states and group by sum\n    vector<array<int,5>> pvec(totalStates);\n    vector<int> sumPtr(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        int tmp = code, sum = 0;\n        array<int,5> p{};\n        for (int i = N - 1; i >= 0; i--) {\n            p[i] = tmp % base;\n            tmp /= base;\n            sum += p[i];\n        }\n        pvec[code] = p;\n        sumPtr[code] = sum;\n    }\n    vector<vector<int>> codesBySum(N * N + 1);\n    for (int code = 0; code < totalStates; code++) {\n        codesBySum[sumPtr[code]].push_back(code);\n    }\n\n    vector<vector<int>> destRow(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) destRow[i][j] = A[i][j] / N;\n\n    vector<array<int,5>> invAddTable(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        const auto &p = pvec[code];\n        for (int s = 0; s < N; s++) {\n            if (p[s] >= N) { invAddTable[code][s] = 0; continue; }\n            int cid = A[s][p[s]];\n            int dr = cid / N;\n            int cnt = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < p[i]; j++) {\n                    int cid2 = A[i][j];\n                    if (cid2 / N == dr && cid2 > cid) cnt++;\n                }\n            }\n            invAddTable[code][s] = cnt;\n        }\n    }\n\n    auto plan_dp = [&](int weight) -> Candidate {\n        const long long INF = (1LL << 60);\n        int stateSize = totalStates * POS;\n        vector<long long> dp(stateSize, INF);\n        vector<int> parent(stateSize, -1);\n        vector<int> parentSrc(stateSize, -1);\n\n        int startIdx = 0 * POS + (POS - 1); // code=0, pos=start\n        dp[startIdx] = 0;\n\n        for (int total = 0; total <= N * N; total++) {\n            for (int code : codesBySum[total]) {\n                const auto &p = pvec[code];\n                for (int pos = 0; pos < POS; pos++) {\n                    int idx = code * POS + pos;\n                    long long curCost = dp[idx];\n                    if (curCost == INF) continue;\n                    for (int s = 0; s < N; s++) {\n                        if (p[s] >= N) continue;\n                        int dr = destRow[s][p[s]];\n                        int dist1 = (pos == POS - 1) ? abs(0 - s) : 4 + abs(pos - s);\n                        int dist2 = 4 + abs(s - dr);\n                        int moveCost = dist1 + dist2 + 2; // pick+drop\n                        int invAdd = invAddTable[code][s];\n                        long long newCost = curCost + moveCost + 1LL * weight * invAdd;\n                        int nextCode = code + powBase[s];\n                        int nextPos = dr;\n                        int nextIdx = nextCode * POS + nextPos;\n                        if (newCost < dp[nextIdx]) {\n                            dp[nextIdx] = newCost;\n                            parent[nextIdx] = idx;\n                            parentSrc[nextIdx] = s;\n                        }\n                    }\n                }\n            }\n        }\n\n        int fullCode = 0;\n        for (int i = 0; i < N; i++) fullCode = fullCode * base + N;\n        int bestIdx = fullCode * POS;\n        long long bestCost = dp[bestIdx];\n        for (int pos = 1; pos < POS; pos++) {\n            int idx = fullCode * POS + pos;\n            if (dp[idx] < bestCost) { bestCost = dp[idx]; bestIdx = idx; }\n        }\n\n        // reconstruct sequence of sources\n        vector<int> seqSources;\n        int curIdx = bestIdx;\n        while (curIdx != startIdx) {\n            int s = parentSrc[curIdx];\n            seqSources.push_back(s);\n            curIdx = parent[curIdx];\n        }\n        reverse(seqSources.begin(), seqSources.end());\n\n        vector<int> ptr(N, 0);\n        vector<pair<int,int>> tasks;\n        tasks.reserve(N * N);\n        for (int s : seqSources) {\n            tasks.emplace_back(s, A[s][ptr[s]]);\n            ptr[s]++;\n        }\n\n        // simulation\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        int dispatched = 0, task_idx = 0, turn = 0;\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        const int TURN_LIMIT = 10000;\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) { blocked = true; break; }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            Crane &lc = cranes[0];\n            char a0 = '.';\n            if (lc.hold == -1) {\n                if (task_idx < (int)tasks.size()) {\n                    int sr = tasks[task_idx].first;\n                    if (lc.r < sr) a0 = 'D';\n                    else if (lc.r > sr) a0 = 'U';\n                    else if (lc.c > 0) a0 = 'L';\n                    else {\n                        if (grid[lc.r][lc.c] != -1) a0 = 'P';\n                        else a0 = '.';\n                    }\n                } else a0 = '.';\n            } else {\n                int destR = lc.hold / N;\n                if (lc.c < N - 1) a0 = 'R';\n                else if (lc.r < destR) a0 = 'D';\n                else if (lc.r > destR) a0 = 'U';\n                else {\n                    if (grid[lc.r][lc.c] == -1) a0 = 'Q';\n                    else a0 = '.';\n                }\n            }\n            act[0] = a0;\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            vector<pair<int,int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') { cranes[i].alive = false; continue; }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) { cranes[i].hold = grid[r][c]; grid[r][c] = -1; }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                        if (i == 0) task_idx++;\n                    }\n                }\n            }\n\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn, M1 = 0, M2 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                if (seq[j] / N != i) M2++;\n                for (int k = j + 1; k < len; k++) if (seq[j] > seq[k]) M1++;\n            }\n        }\n        long long M3 = N * N - dispatched;\n        return Candidate{ops, M0, M1, M2, M3};\n    };\n\n    auto plan_buffer = [&]() -> Candidate {\n        vector<int> id2row(N * N);\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) id2row[A[i][j]] = i;\n\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        vector<bool> dispatchedId(N * N, false);\n        vector<int> nextNeeded(N);\n        for (int i = 0; i < N; i++) nextNeeded[i] = i * N;\n\n        int dispatched = 0, turn = 0;\n        const int TURN_LIMIT = 10000;\n\n        auto chooseBuffer = [&](const Crane &lc, int cid) -> pair<int,int> {\n            int dr = cid / N;\n            vector<int> cols = {3, 2, 1};\n            for (int c : cols) if (grid[dr][c] == -1) return {dr, c};\n            for (int c : cols) for (int r = 0; r < N; r++) if (grid[r][c] == -1) return {r, c};\n            for (int r = 0; r < N; r++) for (int c = 0; c < N - 1; c++) if (grid[r][c] == -1) return {r, c};\n            return {lc.r, lc.c};\n        };\n\n        auto manhattan = [&](int r1, int c1, int r2, int c2) {\n            return abs(r1 - r2) + abs(c1 - c2);\n        };\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) { blocked = true; break; }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            Crane &lc = cranes[0];\n            // find ready containers\n            vector<pair<int,int>> readyPos;\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int id = grid[r][c];\n                    if (id == -1) continue;\n                    int dr = id / N;\n                    if (nextNeeded[dr] < (dr + 1) * N && id == nextNeeded[dr]) {\n                        readyPos.emplace_back(r, c);\n                    }\n                }\n            }\n\n            char a0 = '.';\n            if (lc.hold != -1) {\n                int cid = lc.hold;\n                int dr = cid / N;\n                bool ready = (nextNeeded[dr] < (dr + 1) * N && cid == nextNeeded[dr]);\n                if (ready) {\n                    int tr = dr, tc = N - 1;\n                    if (lc.r == tr && lc.c == tc) {\n                        if (grid[tr][tc] == -1) a0 = 'Q';\n                        else a0 = '.';\n                    } else {\n                        if (lc.r < tr) a0 = 'D';\n                        else if (lc.r > tr) a0 = 'U';\n                        else if (lc.c < tc) a0 = 'R';\n                        else if (lc.c > tc) a0 = 'L';\n                    }\n                } else {\n                    auto buf = chooseBuffer(lc, cid);\n                    int tr = buf.first, tc = buf.second;\n                    if (lc.r == tr && lc.c == tc) {\n                        if (grid[tr][tc] == -1) a0 = 'Q';\n                        else a0 = '.';\n                    } else {\n                        if (lc.r < tr) a0 = 'D';\n                        else if (lc.r > tr) a0 = 'U';\n                        else if (lc.c < tc) a0 = 'R';\n                        else if (lc.c > tc) a0 = 'L';\n                    }\n                }\n            } else {\n                if (!readyPos.empty()) {\n                    int bestd = 1e9, br = -1, bc = -1;\n                    for (auto [r, c] : readyPos) {\n                        int d = manhattan(lc.r, lc.c, r, c);\n                        if (d < bestd) { bestd = d; br = r; bc = c; }\n                    }\n                    if (lc.r == br && lc.c == bc) a0 = 'P';\n                    else {\n                        if (lc.r < br) a0 = 'D';\n                        else if (lc.r > br) a0 = 'U';\n                        else if (lc.c < bc) a0 = 'R';\n                        else if (lc.c > bc) a0 = 'L';\n                    }\n                } else {\n                    // approach nearest receiving gate with container\n                    int bestd = 1e9, br = -1;\n                    for (int r = 0; r < N; r++) {\n                        if (grid[r][0] != -1) {\n                            int d = manhattan(lc.r, lc.c, r, 0);\n                            if (d < bestd) { bestd = d; br = r; }\n                        }\n                    }\n                    if (br == -1) a0 = '.';\n                    else {\n                        int tr = br, tc = 0;\n                        if (lc.r == tr && lc.c == tc) a0 = 'P';\n                        else {\n                            if (lc.r < tr) a0 = 'D';\n                            else if (lc.r > tr) a0 = 'U';\n                            else if (lc.c < tc) a0 = 'R';\n                            else if (lc.c > tc) a0 = 'L';\n                        }\n                    }\n                }\n            }\n\n            act[0] = a0;\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            vector<pair<int,int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') { cranes[i].alive = false; continue; }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) { cranes[i].hold = grid[r][c]; grid[r][c] = -1; }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                    }\n                }\n            }\n\n            // dispatch\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedId[id] = true;\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                    while (nextNeeded[i] < (i + 1) * N && dispatchedId[nextNeeded[i]]) nextNeeded[i]++;\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn;\n        long long M1 = 0, M2 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                if (seq[j] / N != i) M2++;\n                for (int k = j + 1; k < len; k++) if (seq[j] > seq[k]) M1++;\n            }\n        }\n        long long M3 = N * N - dispatched;\n        return Candidate{ops, M0, M1, M2, M3};\n    };\n\n    vector<int> weights = {80, 120, 160, 200};\n    Candidate best;\n    best.M0 = best.M1 = best.M2 = best.M3 = (1LL << 60);\n    bool init = false;\n    for (int w : weights) {\n        Candidate cand = plan_dp(w);\n        if (!init || cand.score() < best.score()) { best = cand; init = true; }\n    }\n    Candidate candBuf = plan_buffer();\n    if (!init || candBuf.score() < best.score()) { best = candBuf; init = true; }\n\n    for (int i = 0; i < N; i++) cout << best.ops[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing pii = pair<int,int>;\n\nstruct Plan {\n    vector<string> ops;\n    ll cost;\n    bool valid;\n};\n\n// ----- Path generators -----\nvector<pii> build_path_down_serp_rows(int N){\n    vector<pii> p;\n    for(int r=1;r<N;r++) p.push_back({r,0});\n    for(int r=N-1;r>=0;r--){\n        if(r%2==1){\n            for(int c=1;c<N;c++) p.push_back({r,c});\n        }else{\n            for(int c=N-1;c>=1;c--) p.push_back({r,c});\n        }\n    }\n    return p;\n}\n\nvector<pii> build_path_right_serp_cols(int N){\n    vector<pii> p;\n    for(int c=1;c<N;c++) p.push_back({0,c});\n    for(int c=N-1;c>=0;c--){\n        int parity = (N-1 - c);\n        if(parity%2==0){\n            for(int r=1;r<N;r++) p.push_back({r,c});\n        }else{\n            for(int r=N-1;r>=1;r--) p.push_back({r,c});\n        }\n    }\n    return p;\n}\n\nvector<pii> build_row_snake(int N){\n    vector<pii> p;\n    for(int r=0;r<N;r++){\n        if(r%2==0){\n            for(int c=0;c<N;c++){\n                if(r==0 && c==0) continue;\n                p.push_back({r,c});\n            }\n        }else{\n            for(int c=N-1;c>=0;c--){\n                p.push_back({r,c});\n            }\n        }\n    }\n    return p;\n}\n\nvector<pii> build_col_snake(int N){\n    vector<pii> p;\n    for(int c=0;c<N;c++){\n        if(c%2==0){\n            for(int r=0;r<N;r++){\n                if(r==0 && c==0) continue;\n                p.push_back({r,c});\n            }\n        }else{\n            for(int r=N-1;r>=0;r--){\n                p.push_back({r,c});\n            }\n        }\n    }\n    return p;\n}\n\nvector<pii> build_spiral(int N){\n    vector<pii> order;\n    int top=0,bottom=N-1,left=0,right=N-1;\n    while(top<=bottom && left<=right){\n        for(int c=left;c<=right;c++) order.push_back({top,c});\n        top++;\n        for(int r=top;r<=bottom;r++) order.push_back({r,right});\n        right--;\n        if(top<=bottom){\n            for(int c=right;c>=left;c--) order.push_back({bottom,c});\n            bottom--;\n        }\n        if(left<=right){\n            for(int r=bottom;r>=top;r--) order.push_back({r,left});\n            left++;\n        }\n    }\n    vector<pii> p;\n    p.reserve(order.size()-1);\n    for(auto &co: order){\n        if(co.first==0 && co.second==0) continue;\n        p.push_back(co);\n    }\n    return p;\n}\n\nvector<pii> reverse_if_adjacent(const vector<pii>& path){\n    vector<pii> rev;\n    if(path.empty()) return rev;\n    auto last = path.back();\n    if(abs(last.first) + abs(last.second) != 1) return rev;\n    rev.reserve(path.size());\n    for(int i=(int)path.size()-1;i>=0;i--){\n        rev.push_back(path[i]);\n    }\n    return rev;\n}\n\n// Simulate cost for path (excluding start)\nll simulate_cost(const vector<pii>& path, const vector<vector<int>>& h, ll& outBorrow){\n    ll pref=0, minPref=0;\n    for(auto [r,c]: path){\n        pref += h[r][c];\n        if(pref < minPref) minPref = pref;\n    }\n    ll borrow = -minPref;\n    outBorrow = borrow;\n    ll cost=0;\n    ll load = borrow;\n    if(borrow>0) cost += borrow;\n    int cr=0, cc=0;\n    for(auto [r,c]: path){\n        int dist = abs(r-cr) + abs(c-cc);\n        cost += (100 + load) * 1LL * dist;\n        int val = h[r][c];\n        cost += llabs((ll)val);\n        load += val;\n        cr = r; cc = c;\n    }\n    int distback = abs(cr) + abs(cc);\n    cost += (100 + load) * 1LL * distback;\n    cost += llabs(load); // final adjust at start\n    return cost;\n}\n\n// Build plan for a given path\nPlan build_path_plan(const vector<pii>& path, const vector<vector<int>>& h){\n    Plan res;\n    res.cost = 0;\n    res.valid = true;\n    vector<vector<int>> g = h;\n    ll pref=0, minPref=0;\n    for(auto [r,c]: path){\n        pref += h[r][c];\n        minPref = min(minPref, pref);\n    }\n    ll borrow = -minPref;\n    ll load = 0;\n    vector<string> ops;\n    if(borrow > 0){\n        ops.push_back(\"+\" + to_string(borrow));\n        res.cost += borrow;\n        load += borrow;\n        g[0][0] -= (int)borrow;\n    }\n\n    int cr=0, cc=0;\n    for(auto [r,c]: path){\n        int dr = r - cr;\n        int dc = c - cc;\n        while(dr > 0){ ops.push_back(\"D\"); res.cost += 100 + load; cr++; dr--; }\n        while(dr < 0){ ops.push_back(\"U\"); res.cost += 100 + load; cr--; dr++; }\n        while(dc > 0){ ops.push_back(\"R\"); res.cost += 100 + load; cc++; dc--; }\n        while(dc < 0){ ops.push_back(\"L\"); res.cost += 100 + load; cc--; dc++; }\n        int val = g[cr][cc];\n        if(val > 0){\n            ops.push_back(\"+\" + to_string(val));\n            res.cost += val;\n            load += val;\n            g[cr][cc] = 0;\n        }else if(val < 0){\n            int d = -val;\n            ops.push_back(\"-\" + to_string(d));\n            res.cost += d;\n            load -= d;\n            g[cr][cc] = 0;\n        }\n    }\n\n    // Return to origin\n    while(cr > 0){ ops.push_back(\"U\"); res.cost += 100 + load; cr--; }\n    while(cc > 0){ ops.push_back(\"L\"); res.cost += 100 + load; cc--; }\n\n    // Final adjust start\n    int sval = g[0][0];\n    if(sval > 0){\n        ops.push_back(\"+\" + to_string(sval));\n        res.cost += sval;\n        load += sval;\n        g[0][0] = 0;\n    }else if(sval < 0){\n        int d = -sval;\n        ops.push_back(\"-\" + to_string(d));\n        res.cost += d;\n        load -= d;\n        g[0][0] = 0;\n    }\n\n    if((int)ops.size() > 100000) res.valid = false;\n    res.ops.swap(ops);\n    return res;\n}\n\n// Greedy transport plan\nPlan build_greedy_plan(const vector<vector<int>>& h){\n    int N = h.size();\n    vector<vector<int>> a = h;\n    ll total_nonzero = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) total_nonzero += llabs((ll)a[i][j]);\n\n    Plan res;\n    res.cost = 0;\n    res.valid = true;\n    vector<string> ops;\n    ll load = 0;\n    int r=0, c=0;\n\n    auto move_steps = [&](int nr, int nc){\n        int dr = nr - r;\n        int dc = nc - c;\n        while(dr > 0){ ops.push_back(\"D\"); res.cost += 100 + load; r++; dr--; }\n        while(dr < 0){ ops.push_back(\"U\"); res.cost += 100 + load; r--; dr++; }\n        while(dc > 0){ ops.push_back(\"R\"); res.cost += 100 + load; c++; dc--; }\n        while(dc < 0){ ops.push_back(\"L\"); res.cost += 100 + load; c--; dc++; }\n    };\n\n    int iter=0;\n    while(total_nonzero > 0 && (int)ops.size() < 100000){\n        iter++;\n        if(load == 0){\n            int bestR=-1,bestC=-1,bestD=1e9, bestVal=0;\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    int val = a[i][j];\n                    if(val > 0){\n                        int d = abs(i-r) + abs(j-c);\n                        if(d < bestD || (d == bestD && val > bestVal)){\n                            bestD = d; bestR = i; bestC = j; bestVal = val;\n                        }\n                    }\n                }\n            }\n            if(bestR==-1){\n                // no positive, should not happen\n                res.valid = false;\n                break;\n            }\n            move_steps(bestR, bestC);\n            int val = a[r][c];\n            ops.push_back(\"+\" + to_string(val));\n            res.cost += val;\n            load += val;\n            total_nonzero -= val;\n            a[r][c] = 0;\n        }else{\n            int bestR=-1,bestC=-1,bestD=1e9, bestNeed=0;\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    int val = a[i][j];\n                    if(val < 0){\n                        int d = abs(i-r) + abs(j-c);\n                        int need = -val;\n                        if(d < bestD || (d == bestD && need > bestNeed)){\n                            bestD = d; bestR = i; bestC = j; bestNeed = need;\n                        }\n                    }\n                }\n            }\n            if(bestR==-1){\n                // no negative, should not happen if load>0\n                res.valid = false;\n                break;\n            }\n            move_steps(bestR, bestC);\n            int need = -a[r][c];\n            int t = (int)min<ll>(load, need);\n            ops.push_back(\"-\" + to_string(t));\n            res.cost += t;\n            load -= t;\n            a[r][c] += t;\n            total_nonzero -= t;\n        }\n    }\n\n    if(total_nonzero != 0 || (int)ops.size()>100000) res.valid = false;\n    res.ops.swap(ops);\n    return res;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cin>>h[i][j];\n        }\n    }\n\n    vector<vector<pii>> candidates;\n    auto pA = build_path_down_serp_rows(N);\n    auto pB = build_path_right_serp_cols(N);\n    auto pRow = build_row_snake(N);\n    auto pCol = build_col_snake(N);\n    auto pSp = build_spiral(N);\n    candidates.push_back(pA);\n    candidates.push_back(pB);\n    candidates.push_back(pRow);\n    candidates.push_back(pCol);\n    candidates.push_back(pSp);\n    auto revA = reverse_if_adjacent(pA);\n    if(!revA.empty()) candidates.push_back(revA);\n    auto revB = reverse_if_adjacent(pB);\n    if(!revB.empty()) candidates.push_back(revB);\n    auto revSp = reverse_if_adjacent(pSp);\n    if(!revSp.empty()) candidates.push_back(revSp);\n\n    ll bestSimCost = (1LL<<60);\n    vector<pii> bestPath = candidates[0];\n    for(auto &p: candidates){\n        if((int)p.size() != N*N-1) continue;\n        ll bor;\n        ll cst = simulate_cost(p, h, bor);\n        if(cst < bestSimCost){\n            bestSimCost = cst;\n            bestPath = p;\n        }\n    }\n\n    Plan scanPlan = build_path_plan(bestPath, h);\n    Plan greedyPlan = build_greedy_plan(h);\n\n    Plan *bestPlan = nullptr;\n    if(greedyPlan.valid && (!scanPlan.valid || greedyPlan.cost < scanPlan.cost)){\n        bestPlan = &greedyPlan;\n    }else{\n        bestPlan = &scanPlan;\n    }\n\n    for(auto &s: bestPlan->ops){\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int SEED_COUNT = 2 * N * (N - 1); // 60 for N=6\n    vector<array<int, 15>> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; i++) {\n        for (int j = 0; j < M; j++) cin >> seeds[i][j];\n    }\n\n    int SZ = N * N;\n    vector<vector<int>> neighPos(SZ);\n    vector<pair<int,int>> edges;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int p = i * N + j;\n            if (i > 0) neighPos[p].push_back((i - 1) * N + j);\n            if (i + 1 < N) neighPos[p].push_back((i + 1) * N + j);\n            if (j > 0) neighPos[p].push_back(i * N + (j - 1));\n            if (j + 1 < N) neighPos[p].push_back(i * N + (j + 1));\n            if (j + 1 < N) edges.push_back({p, i * N + (j + 1)});\n            if (i + 1 < N) edges.push_back({p, (i + 1) * N + j});\n        }\n    }\n\n    int center_i = N / 2 - 1, center_j = N / 2 - 1;\n    int centerPos = center_i * N + center_j;\n    double cx = (N - 1) / 2.0, cy = (N - 1) / 2.0;\n    vector<double> posDist(SZ);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int p = i * N + j;\n        posDist[p] = fabs(i - cx) + fabs(j - cy);\n    }\n\n    // global maxima per attribute from initial seeds\n    array<int, 15> globalMax{};\n    for (int l = 0; l < M; l++) {\n        int mx = 0;\n        for (int k = 0; k < SEED_COUNT; k++) mx = max(mx, seeds[k][l]);\n        globalMax[l] = mx;\n    }\n\n    std::mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    vector<vector<int>> synergy(SEED_COUNT, vector<int>(SEED_COUNT, 0));\n\n    for (int turn = 0; turn < T; turn++) {\n        // compute value and countMax\n        vector<int> val(SEED_COUNT, 0), cntMax(SEED_COUNT, 0);\n        for (int k = 0; k < SEED_COUNT; k++) {\n            int s = 0, c = 0;\n            for (int l = 0; l < M; l++) {\n                s += seeds[k][l];\n                if (seeds[k][l] == globalMax[l]) c++;\n            }\n            val[k] = s;\n            cntMax[k] = c;\n        }\n        // best seed\n        int best_id = 0;\n        for (int i = 1; i < SEED_COUNT; i++) if (val[i] > val[best_id]) best_id = i;\n\n        // champions per attribute (unique)\n        vector<int> championList;\n        vector<char> seenChamp(SEED_COUNT, 0);\n        for (int l = 0; l < M; l++) {\n            int cid = 0;\n            for (int k = 1; k < SEED_COUNT; k++) {\n                if (seeds[k][l] > seeds[cid][l] ||\n                    (seeds[k][l] == seeds[cid][l] && val[k] > val[cid])) {\n                    cid = k;\n                }\n            }\n            if (!seenChamp[cid]) {\n                seenChamp[cid] = 1;\n                championList.push_back(cid);\n            }\n        }\n\n        // improvers relative to best\n        struct Item { int score, val, id; };\n        vector<Item> improvers;\n        improvers.reserve(SEED_COUNT);\n        for (int k = 0; k < SEED_COUNT; k++) if (k != best_id) {\n            int imp = 0;\n            for (int l = 0; l < M; l++) imp += max(seeds[best_id][l], seeds[k][l]) - seeds[best_id][l];\n            improvers.push_back({imp, val[k], k});\n        }\n        sort(improvers.begin(), improvers.end(), [&](const Item &a, const Item &b) {\n            if (a.score != b.score) return a.score > b.score;\n            return a.val > b.val;\n        });\n\n        // selection of seeds to plant\n        vector<char> used(SEED_COUNT, 0);\n        vector<int> selected;\n        auto add_sel = [&](int id) {\n            if (!used[id]) {\n                used[id] = 1;\n                selected.push_back(id);\n            }\n        };\n        add_sel(best_id);\n        for (int cid : championList) add_sel(cid);\n        int IMP_LIMIT = 12;\n        int impAdded = 0;\n        for (auto &it : improvers) {\n            if (impAdded >= IMP_LIMIT) break;\n            if (!used[it.id]) {\n                add_sel(it.id);\n                impAdded++;\n            }\n        }\n        // fill with high cntMax then val\n        vector<int> fillOrder(SEED_COUNT);\n        iota(fillOrder.begin(), fillOrder.end(), 0);\n        sort(fillOrder.begin(), fillOrder.end(), [&](int a, int b) {\n            if (cntMax[a] != cntMax[b]) return cntMax[a] > cntMax[b];\n            return val[a] > val[b];\n        });\n        for (int id : fillOrder) {\n            if ((int)selected.size() >= SZ) break;\n            add_sel(id);\n        }\n        // if still not full, fill by value\n        if ((int)selected.size() < SZ) {\n            vector<int> byVal(SEED_COUNT);\n            iota(byVal.begin(), byVal.end(), 0);\n            sort(byVal.begin(), byVal.end(), [&](int a, int b){ return val[a] > val[b]; });\n            for (int id : byVal) {\n                if ((int)selected.size() >= SZ) break;\n                add_sel(id);\n            }\n        }\n\n        // trim if oversized: remove non-essential lowest priority\n        vector<char> essential(SEED_COUNT, 0);\n        essential[best_id] = 1;\n        for (int cid : championList) essential[cid] = 1;\n        while ((int)selected.size() > SZ) {\n            int remIdx = -1;\n            int worstCnt = INT_MAX, worstVal = INT_MAX;\n            for (int idx = 0; idx < (int)selected.size(); idx++) {\n                int id = selected[idx];\n                if (essential[id]) continue;\n                if (cntMax[id] < worstCnt || (cntMax[id] == worstCnt && val[id] < worstVal)) {\n                    worstCnt = cntMax[id];\n                    worstVal = val[id];\n                    remIdx = idx;\n                }\n            }\n            if (remIdx == -1) break;\n            used[selected[remIdx]] = 0;\n            selected.erase(selected.begin() + remIdx);\n        }\n\n        // neighbor seeds: top synergy with best among selected\n        // compute synergy matrix\n        for (int a = 0; a < SEED_COUNT; a++) {\n            for (int b = 0; b < SEED_COUNT; b++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(seeds[a][l], seeds[b][l]);\n                synergy[a][b] = s;\n            }\n        }\n        vector<pair<int,int>> neighCand;\n        neighCand.reserve(selected.size());\n        for (int id : selected) if (id != best_id) {\n            neighCand.push_back({synergy[best_id][id], id});\n        }\n        sort(neighCand.begin(), neighCand.end(), [&](const pair<int,int>&a, const pair<int,int>&b){\n            if (a.first != b.first) return a.first > b.first;\n            return val[a.second] > val[b.second];\n        });\n        vector<int> neighborSeeds;\n        for (auto &pr : neighCand) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            neighborSeeds.push_back(pr.second);\n        }\n\n        // positions around center\n        vector<int> centerNbrs;\n        int ci = center_i, cj = center_j;\n        if (cj - 1 >= 0) centerNbrs.push_back(ci * N + (cj - 1));\n        if (cj + 1 < N) centerNbrs.push_back(ci * N + (cj + 1));\n        if (ci - 1 >= 0) centerNbrs.push_back((ci - 1) * N + cj);\n        if (ci + 1 < N) centerNbrs.push_back((ci + 1) * N + cj);\n\n        // multi-start search\n        int BEST_TRIES = 3;\n        vector<int> bestAssign(SZ, -1);\n        int bestScore = -1;\n\n        // precompute posLeft sorted by degree then distance\n        struct PosInfo { int pos; int deg; double dist; };\n        vector<PosInfo> basePosLeft;\n        basePosLeft.reserve(SZ);\n        for (int p = 0; p < SZ; p++) {\n            if (p == centerPos) continue; // center pinned\n            basePosLeft.push_back({p, (int)neighPos[p].size(), posDist[p]});\n        }\n        sort(basePosLeft.begin(), basePosLeft.end(), [&](const PosInfo &a, const PosInfo &b){\n            if (a.deg != b.deg) return a.deg > b.deg;\n            return a.dist < b.dist;\n        });\n\n        for (int trial = 0; trial < BEST_TRIES; trial++) {\n            vector<int> assign(SZ, -1);\n            vector<char> pinned(SZ, 0);\n            assign[centerPos] = best_id;\n            pinned[centerPos] = 1;\n            // shuffle neighborSeeds\n            vector<int> neighShuf = neighborSeeds;\n            shuffle(neighShuf.begin(), neighShuf.end(), rng);\n            for (size_t idx = 0; idx < centerNbrs.size() && idx < neighShuf.size(); idx++) {\n                int pos = centerNbrs[idx];\n                assign[pos] = neighShuf[idx];\n                pinned[pos] = 1;\n            }\n            vector<char> isPinnedSeed(SEED_COUNT, 0);\n            isPinnedSeed[best_id] = 1;\n            for (int id : neighShuf) isPinnedSeed[id] = 1;\n            // seedsLeft\n            vector<int> seedsLeft;\n            for (int id : selected) if (!isPinnedSeed[id]) seedsLeft.push_back(id);\n            shuffle(seedsLeft.begin(), seedsLeft.end(), rng);\n            // positions left\n            vector<PosInfo> posLeft = basePosLeft;\n            // assign seedsLeft in order to posLeft skipping pinned (already set)\n            size_t idxSeed = 0;\n            for (auto &pi : posLeft) {\n                int p = pi.pos;\n                if (pinned[p]) continue;\n                if (idxSeed < seedsLeft.size()) {\n                    assign[p] = seedsLeft[idxSeed++];\n                }\n            }\n\n            // var positions\n            vector<int> varPosList;\n            for (int p = 0; p < SZ; p++) if (!pinned[p]) varPosList.push_back(p);\n\n            auto computeDelta = [&](int p, int q) -> int {\n                int sp = assign[p], sq = assign[q];\n                int delta = 0;\n                for (int n : neighPos[p]) {\n                    if (n == q) continue;\n                    int sn = assign[n];\n                    delta -= synergy[sp][sn];\n                    delta += synergy[sq][sn];\n                }\n                for (int n : neighPos[q]) {\n                    if (n == p) continue;\n                    int sn = assign[n];\n                    delta -= synergy[sq][sn];\n                    delta += synergy[sp][sn];\n                }\n                return delta;\n            };\n\n            // greedy improvement\n            bool improved = true;\n            int vps = varPosList.size();\n            while (improved) {\n                improved = false;\n                for (int i = 0; i < vps; i++) {\n                    for (int j = i + 1; j < vps; j++) {\n                        int p = varPosList[i], q = varPosList[j];\n                        int delta = computeDelta(p, q);\n                        if (delta > 0) {\n                            swap(assign[p], assign[q]);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n\n            // random hillclimb\n            const int RAND_ITERS = 30000;\n            for (int it = 0; it < RAND_ITERS; it++) {\n                int idx1 = rng() % vps;\n                int idx2 = rng() % vps;\n                if (idx1 == idx2) continue;\n                int p = varPosList[idx1], q = varPosList[idx2];\n                int delta = computeDelta(p, q);\n                if (delta > 0) swap(assign[p], assign[q]);\n            }\n\n            // compute total synergy score\n            int total = 0;\n            for (auto &e : edges) {\n                int a = e.first, b = e.second;\n                total += synergy[assign[a]][assign[b]];\n            }\n            if (total > bestScore) {\n                bestScore = total;\n                bestAssign = assign;\n            }\n        }\n\n        // output best assignment grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j) cout << ' ';\n                cout << bestAssign[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // read next generation seeds\n        if (turn != T - 1) {\n            for (int i = 0; i < SEED_COUNT; i++) {\n                for (int j = 0; j < M; j++) cin >> seeds[i][j];\n            }\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\ninline int manh(const Pos &a, const Pos &b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Hungarian algorithm for square cost matrix (n x n)\nvector<int> hungarian(const vector<vector<int>> &a) {\n    int n = (int)a.size();\n    const int INF = 1e9;\n    vector<int> u(n + 1), v(n + 1), p(n + 1), way(n + 1);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(n + 1, INF);\n        vector<char> used(n + 1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= n; j++) if (!used[j]) {\n                int cur = a[i0 - 1][j - 1] - u[i0] - v[j];\n                if (cur < minv[j]) {\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if (minv[j] < delta) {\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for (int j = 0; j <= n; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    vector<int> matchL(n, -1);\n    for (int j = 1; j <= n; j++) {\n        if (p[j] != 0) matchL[p[j] - 1] = j - 1;\n    }\n    return matchL;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    vector<Pos> sources, targets;\n    sources.reserve(M);\n    targets.reserve(M);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1' && t[i][j] == '0') sources.push_back({i, j});\n            else if (s[i][j] == '0' && t[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n    int n = (int)sources.size();\n    cout << 1 << \"\\n\";\n    if (n == 0) {\n        cout << 0 << \" \" << 0 << \"\\n\";\n        return 0;\n    }\n\n    auto startAll = chrono::steady_clock::now();\n    const double TIME_LIMIT = 2.8;\n\n    // assignment\n    vector<vector<int>> costAssign(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            costAssign[i][j] = manh(sources[i], targets[j]);\n    vector<int> matchS = hungarian(costAssign); // target index for each source\n\n    vector<Pos> taskTarget(n);\n    for (int i = 0; i < n; i++) taskTarget[i] = targets[matchS[i]];\n\n    // edgeCost: target of i to source of j\n    vector<vector<int>> edgeCost(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            edgeCost[i][j] = manh(taskTarget[i], sources[j]);\n        }\n    }\n\n    mt19937 rng((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto elapsed = [&]() -> double {\n        chrono::duration<double> diff = chrono::steady_clock::now() - startAll;\n        return diff.count();\n    };\n\n    // initial sequences\n    vector<int> bestSeq;\n    long long bestTrans = (1LL << 60);\n    int numStarts = min(n, 12);\n    vector<int> startCandidates;\n    startCandidates.reserve(numStarts);\n    Pos center{N / 2, N / 2};\n    int bestCenterIdx = 0;\n    int bestCenterDist = 1e9;\n    for (int i = 0; i < n; i++) {\n        int d = manh(sources[i], center);\n        if (d < bestCenterDist) {\n            bestCenterDist = d;\n            bestCenterIdx = i;\n        }\n    }\n    startCandidates.push_back(bestCenterIdx);\n    uniform_int_distribution<int> uid(0, n - 1);\n    while ((int)startCandidates.size() < numStarts) {\n        int v = uid(rng);\n        bool dup = false;\n        for (int x : startCandidates) if (x == v) { dup = true; break; }\n        if (!dup) startCandidates.push_back(v);\n    }\n\n    for (int st : startCandidates) {\n        vector<char> used(n, false);\n        vector<int> seq;\n        seq.reserve(n);\n        int cur = st;\n        used[cur] = true;\n        seq.push_back(cur);\n        for (int k = 1; k < n; k++) {\n            int best = -1, bestd = 1e9;\n            for (int j = 0; j < n; j++) if (!used[j]) {\n                int d = edgeCost[cur][j];\n                if (d < bestd) {\n                    bestd = d;\n                    best = j;\n                }\n            }\n            used[best] = true;\n            seq.push_back(best);\n            cur = best;\n        }\n        long long trans = 0;\n        for (int i = 0; i + 1 < n; i++) trans += edgeCost[seq[i]][seq[i + 1]];\n        if (trans < bestTrans) {\n            bestTrans = trans;\n            bestSeq = seq;\n        }\n    }\n\n    vector<int> seq = bestSeq;\n    long long curCost = bestTrans;\n    long long bestCostAll = curCost;\n    vector<int> bestSeqAll = seq;\n\n    auto swapDelta = [&](int i, int j) -> int {\n        if (i == j) return 0;\n        if (i > j) swap(i, j);\n        int nseq = (int)seq.size();\n        int a = (i > 0) ? seq[i - 1] : -1;\n        int b = seq[i];\n        int c = (i + 1 < nseq) ? seq[i + 1] : -1;\n        int d = (j > 0) ? seq[j - 1] : -1;\n        int e = seq[j];\n        int f = (j + 1 < nseq) ? seq[j + 1] : -1;\n        if (i + 1 == j) {\n            long long oldc = 0, newc = 0;\n            if (a != -1) { oldc += edgeCost[a][b]; newc += edgeCost[a][e]; }\n            oldc += edgeCost[b][e];\n            newc += edgeCost[e][b];\n            if (f != -1) { oldc += edgeCost[e][f]; newc += edgeCost[b][f]; }\n            return (int)(newc - oldc);\n        } else {\n            long long oldc = 0, newc = 0;\n            if (a != -1) { oldc += edgeCost[a][b]; newc += edgeCost[a][e]; }\n            oldc += edgeCost[b][c];\n            newc += edgeCost[e][c];\n            oldc += edgeCost[d][e];\n            newc += edgeCost[d][b];\n            if (f != -1) { oldc += edgeCost[e][f]; newc += edgeCost[b][f]; }\n            return (int)(newc - oldc);\n        }\n    };\n\n    auto relocateDelta = [&](int i, int j) -> int {\n        int nseq = (int)seq.size();\n        if (i == j || i + 1 == j) return 0;\n        int b = seq[i];\n        int prev = (i > 0) ? seq[i - 1] : -1;\n        int nxt = (i + 1 < nseq) ? seq[i + 1] : -1;\n        long long delta = 0;\n        if (prev != -1) delta -= edgeCost[prev][b];\n        if (nxt != -1) delta -= edgeCost[b][nxt];\n        if (prev != -1 && nxt != -1) delta += edgeCost[prev][nxt];\n        int pos = j;\n        if (j > i) pos--;\n        auto getElem = [&](int idx) -> int {\n            if (idx < i) return seq[idx];\n            else return seq[idx + 1];\n        };\n        int prevIns = (pos > 0) ? getElem(pos - 1) : -1;\n        int nextIns = (pos < nseq - 1) ? getElem(pos) : -1;\n        if (prevIns != -1) delta += edgeCost[prevIns][b];\n        if (nextIns != -1) delta += edgeCost[b][nextIns];\n        if (prevIns != -1 && nextIns != -1) delta -= edgeCost[prevIns][nextIns];\n        return (int)delta;\n    };\n\n    // Simulated annealing\n    double T0 = 30.0, T1 = 1e-3;\n    int nseq = n;\n    while (true) {\n        double t = elapsed();\n        if (t > TIME_LIMIT) break;\n        double progress = t / TIME_LIMIT;\n        double Temp = exp(log(T0) * (1.0 - progress) + log(T1) * progress);\n        int moveType = uniform_int_distribution<int>(0, 1)(rng);\n        if (moveType == 0) {\n            int i = uniform_int_distribution<int>(0, nseq - 1)(rng);\n            int j = uniform_int_distribution<int>(0, nseq - 1)(rng);\n            if (i == j) continue;\n            int d = swapDelta(i, j);\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                swap(seq[i], seq[j]);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        } else {\n            int i = uniform_int_distribution<int>(0, nseq - 1)(rng);\n            int j = uniform_int_distribution<int>(0, nseq)(rng);\n            if (i == j || i + 1 == j) continue;\n            int d = relocateDelta(i, j);\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                int node = seq[i];\n                seq.erase(seq.begin() + i);\n                if (j > i) j--;\n                seq.insert(seq.begin() + j, node);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        }\n    }\n\n    seq = bestSeqAll;\n    curCost = bestCostAll;\n\n    // Hill climbing small-range swaps/relocates\n    int range = min(30, nseq - 1);\n    int iterCheck = 0;\n    while (elapsed() < TIME_LIMIT) {\n        iterCheck++;\n        int i = uniform_int_distribution<int>(0, nseq - 1)(rng);\n        int jOff = uniform_int_distribution<int>(-range, range)(rng);\n        int j = i + jOff;\n        if (j < 0) j = 0;\n        if (j >= nseq) j = nseq - 1;\n        if (i != j) {\n            int d = swapDelta(i, j);\n            if (d < 0) {\n                swap(seq[i], seq[j]);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        } else continue;\n\n        if ((iterCheck & 1023) == 0 && elapsed() > TIME_LIMIT) break;\n    }\n    seq = bestSeqAll;\n\n    // initial root position at first source\n    Pos root = sources[seq[0]];\n    cout << root.x << \" \" << root.y << \"\\n\";\n\n    vector<string> cmds;\n    cmds.reserve((size_t)(bestCostAll + n * 2 + 10));\n\n    Pos cur = root;\n    auto moveTo = [&](const Pos &dest, bool doP) {\n        int dx = dest.x - cur.x;\n        int dy = dest.y - cur.y;\n        if (dx != 0) {\n            char mv = (dx > 0) ? 'D' : 'U';\n            int steps = abs(dx);\n            for (int k = 1; k <= steps; k++) {\n                bool last = (k == steps) && (dy == 0) && doP;\n                string s;\n                s.push_back(mv);\n                s.push_back(last ? 'P' : '.');\n                cmds.push_back(std::move(s));\n            }\n        }\n        if (dy != 0) {\n            char mv = (dy > 0) ? 'R' : 'L';\n            int steps = abs(dy);\n            for (int k = 1; k <= steps; k++) {\n                bool last = (k == steps) && doP;\n                string s;\n                s.push_back(mv);\n                s.push_back(last ? 'P' : '.');\n                cmds.push_back(std::move(s));\n            }\n        }\n        if (dx == 0 && dy == 0) {\n            string s;\n            s.push_back('.');\n            s.push_back(doP ? 'P' : '.');\n            cmds.push_back(std::move(s));\n        }\n        cur = dest;\n    };\n\n    // Execute tasks\n    moveTo(sources[seq[0]], true);\n    moveTo(taskTarget[seq[0]], true);\n    for (int idx = 1; idx < n; idx++) {\n        int task = seq[idx];\n        moveTo(sources[task], true);\n        moveTo(taskTarget[task], true);\n    }\n\n    for (auto &c : cmds) cout << c << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x1, x2, y1, y2;\n};\n\nconst int LIM = 100000;\n\ninline Rect normalize(Rect r) {\n    if (r.x1 > r.x2) swap(r.x1, r.x2);\n    if (r.y1 > r.y2) swap(r.y1, r.y2);\n    r.x1 = max(0, min(LIM, r.x1));\n    r.x2 = max(0, min(LIM, r.x2));\n    r.y1 = max(0, min(LIM, r.y1));\n    r.y2 = max(0, min(LIM, r.y2));\n    if (r.x1 == r.x2) {\n        if (r.x2 < LIM) r.x2++;\n        else if (r.x1 > 0) r.x1--;\n        else r.x2 = r.x1 + 1;\n    }\n    if (r.y1 == r.y2) {\n        if (r.y2 < LIM) r.y2++;\n        else if (r.y1 > 0) r.y1--;\n        else r.y2 = r.y1 + 1;\n    }\n    return r;\n}\n\nstruct Evaluator {\n    int tot;\n    const vector<int> &xs, &ys, &ws;\n    Evaluator(const vector<int>& _xs, const vector<int>& _ys, const vector<int>& _ws)\n        : tot((int)_xs.size()), xs(_xs), ys(_ys), ws(_ws) {}\n    inline int evalRect(const Rect& r) const {\n        int s = 0;\n        int x1 = r.x1, x2 = r.x2, y1 = r.y1, y2 = r.y2;\n        for (int i = 0; i < tot; i++) {\n            int x = xs[i];\n            if (x < x1 || x > x2) continue;\n            int y = ys[i];\n            if (y < y1 || y > y2) continue;\n            s += ws[i];\n        }\n        return s;\n    }\n};\n\nRect bestGridRect(int G, const vector<int>& xs, const vector<int>& ys, const vector<int>& ws) {\n    int cell = (LIM + G - 1) / G;\n    vector<vector<int>> diff(G, vector<int>(G, 0));\n    int tot = (int)xs.size();\n    for (int i = 0; i < tot; i++) {\n        int cx = xs[i] / cell; if (cx >= G) cx = G - 1;\n        int cy = ys[i] / cell; if (cy >= G) cy = G - 1;\n        diff[cy][cx] += ws[i];\n    }\n    int best = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n    vector<int> col(G);\n    for (int top = 0; top < G; top++) {\n        fill(col.begin(), col.end(), 0);\n        for (int bottom = top; bottom < G; bottom++) {\n            for (int x = 0; x < G; x++) col[x] += diff[bottom][x];\n            int cur = 0, start = 0;\n            int bestSum = -1e9, bestL = 0, bestR = 0;\n            for (int x = 0; x < G; x++) {\n                if (cur <= 0) {\n                    cur = col[x];\n                    start = x;\n                } else {\n                    cur += col[x];\n                }\n                if (cur > bestSum) {\n                    bestSum = cur;\n                    bestL = start;\n                    bestR = x;\n                }\n            }\n            if (bestSum > best) {\n                best = bestSum;\n                int x1 = bestL * cell;\n                int x2 = min(LIM, (bestR + 1) * cell);\n                int y1 = top * cell;\n                int y2 = min(LIM, (bottom + 1) * cell);\n                bestRect = normalize({x1, x2, y1, y2});\n            }\n        }\n    }\n    return bestRect;\n}\n\nstruct Candidate {\n    int score;\n    Rect rect;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    int TOT = 2 * N;\n    vector<int> xs(TOT), ys(TOT), ws(TOT);\n    for (int i = 0; i < TOT; i++) {\n        int x, y;\n        cin >> x >> y;\n        xs[i] = x;\n        ys[i] = y;\n        ws[i] = (i < N) ? 1 : -1;\n    }\n    Evaluator eval(xs, ys, ws);\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    auto startTime = chrono::steady_clock::now();\n\n    int bestScore = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n\n    vector<Candidate> candList;\n    auto addCandidate = [&](int sc, const Rect& r) {\n        // check duplicates\n        for (auto &c : candList) {\n            if (c.rect.x1 == r.x1 && c.rect.x2 == r.x2 && c.rect.y1 == r.y1 && c.rect.y2 == r.y2) {\n                if (sc > c.score) c.score = sc;\n                return;\n            }\n        }\n        candList.push_back({sc, r});\n        sort(candList.begin(), candList.end(), [](const Candidate& a, const Candidate& b) {\n            return a.score > b.score;\n        });\n        if ((int)candList.size() > 40) candList.resize(40);\n    };\n\n    auto consider = [&](const Rect& r) {\n        Rect nr = normalize(r);\n        int sc = eval.evalRect(nr);\n        addCandidate(sc, nr);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRect = nr;\n        }\n    };\n\n    // bounding box of mackerels\n    int minMx = LIM, maxMx = 0, minMy = LIM, maxMy = 0;\n    for (int i = 0; i < N; i++) {\n        minMx = min(minMx, xs[i]);\n        maxMx = max(maxMx, xs[i]);\n        minMy = min(minMy, ys[i]);\n        maxMy = max(maxMy, ys[i]);\n    }\n    consider({minMx, maxMx, minMy, maxMy});\n\n    // grid search\n    vector<int> Gs = {8, 12, 16, 20, 25, 30, 40, 50};\n    for (int g : Gs) {\n        Rect r = bestGridRect(g, xs, ys, ws);\n        consider(r);\n    }\n\n    // random search\n    vector<int> sizes = {200, 300, 500, 800, 1000, 1200, 1500, 2000, 2500, 3000, 4000, 5000, 6000, 8000, 10000, 12000, 15000, 20000, 25000};\n    const double RAND_TIME = 1.1; // seconds\n    int iter = 0;\n    while (true) {\n        iter++;\n        int t = rng() % 4;\n        if (t == 0) {\n            int idx = rng() % N;\n            int w = sizes[rng() % sizes.size()];\n            int h = sizes[rng() % sizes.size()];\n            Rect r{xs[idx] - w, xs[idx] + w, ys[idx] - h, ys[idx] + h};\n            consider(r);\n        } else if (t == 1) {\n            int i = rng() % TOT;\n            int j = rng() % TOT;\n            int x1 = min(xs[i], xs[j]);\n            int x2 = max(xs[i], xs[j]);\n            int y1 = min(ys[i], ys[j]);\n            int y2 = max(ys[i], ys[j]);\n            int marg = sizes[rng() % sizes.size()] / 2;\n            Rect r{x1 - marg, x2 + marg, y1 - marg, y2 + marg};\n            consider(r);\n        } else if (t == 2) {\n            Rect r = bestRect;\n            int delta = sizes[rng() % sizes.size()] / 2 + 1;\n            int dx1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dx2 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy2 = (int)(rng() % (2 * delta + 1)) - delta;\n            r.x1 += dx1; r.x2 += dx2; r.y1 += dy1; r.y2 += dy2;\n            consider(r);\n        } else {\n            // random thin rectangle\n            int idx = rng() % TOT;\n            int w = sizes[rng() % sizes.size()] / 4 + 1;\n            Rect r{xs[idx] - w, xs[idx] + w, 0, LIM};\n            consider(r);\n            r = {0, LIM, ys[idx] - w, ys[idx] + w};\n            consider(r);\n        }\n        if ((iter & 31) == 0) {\n            double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - startTime).count();\n            if (elapsed > RAND_TIME) break;\n        }\n    }\n\n    // hill climbing around bestRect\n    vector<int> steps = {20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50};\n    Rect cur = bestRect;\n    for (int step : steps) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int edge = 0; edge < 4; edge++) {\n                for (int dir = -1; dir <= 1; dir += 2) {\n                    Rect r = cur;\n                    if (edge == 0) r.x1 += dir * step;\n                    else if (edge == 1) r.x2 += dir * step;\n                    else if (edge == 2) r.y1 += dir * step;\n                    else r.y2 += dir * step;\n                    r = normalize(r);\n                    int sc = eval.evalRect(r);\n                    addCandidate(sc, r);\n                    if (sc > bestScore) {\n                        bestScore = sc;\n                        bestRect = cur = r;\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // evaluate pair connections\n    int bestPairScore = bestScore;\n    Rect bestA = bestRect, bestB = bestRect;\n    bool usePair = false;\n    bool horiz = true;\n    int corridorC = 0;\n    // only top K candidates\n    int K = min<int>(candList.size(), 25);\n    for (int i = 0; i < K; i++) for (int j = i + 1; j < K; j++) {\n        Rect A = candList[i].rect;\n        Rect B = candList[j].rect;\n        // horizontal connection: disjoint in x with y-overlap length>=1\n        if (A.x2 < B.x1 || B.x2 < A.x1) {\n            Rect L = A, R = B;\n            if (B.x2 < A.x1) { L = B; R = A; }\n            int ovL = max(L.y1, R.y1);\n            int ovH = min(L.y2, R.y2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int y1 = c, y2 = c + 1;\n                    int x1 = L.x2, x2 = R.x1;\n                    if (x1 > x2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= L.x1 && x <= L.x2 && y >= L.y1 && y <= L.y2) inside = true;\n                        else if (x >= R.x1 && x <= R.x2 && y >= R.y1 && y <= R.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = L;\n                        bestB = R;\n                        horiz = true;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n        // vertical connection: disjoint in y with x-overlap length>=1\n        if (A.y2 < B.y1 || B.y2 < A.y1) {\n            Rect Lw = A, Up = B;\n            if (B.y2 < A.y1) { Lw = B; Up = A; }\n            int ovL = max(Lw.x1, Up.x1);\n            int ovH = min(Lw.x2, Up.x2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int x1 = c, x2 = c + 1;\n                    int y1 = Lw.y2, y2 = Up.y1;\n                    if (y1 > y2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= Lw.x1 && x <= Lw.x2 && y >= Lw.y1 && y <= Lw.y2) inside = true;\n                        else if (x >= Up.x1 && x <= Up.x2 && y >= Up.y1 && y <= Up.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = Lw;\n                        bestB = Up;\n                        horiz = false;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int,int>> poly;\n    if (usePair) {\n        if (horiz) {\n            Rect L = bestA, R = bestB;\n            int c = corridorC;\n            int ch = 1;\n            vector<pair<int,int>> tmp = {\n                {L.x1, L.y1},\n                {L.x2, L.y1},\n                {L.x2, c},\n                {R.x1, c},\n                {R.x1, R.y1},\n                {R.x2, R.y1},\n                {R.x2, R.y2},\n                {R.x1, R.y2},\n                {R.x1, c + ch},\n                {L.x2, c + ch},\n                {L.x2, L.y2},\n                {L.x1, L.y2}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        } else {\n            Rect Lw = bestA, Up = bestB;\n            int c = corridorC;\n            int cw = 1;\n            vector<pair<int,int>> tmp = {\n                {Lw.x1, Lw.y1},\n                {Lw.x1, Lw.y2},\n                {c, Lw.y2},\n                {c, Up.y1},\n                {Up.x1, Up.y1},\n                {Up.x1, Up.y2},\n                {Up.x2, Up.y2},\n                {Up.x2, Up.y1},\n                {c + cw, Up.y1},\n                {c + cw, Lw.y2},\n                {Lw.x2, Lw.y2},\n                {Lw.x2, Lw.y1}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        }\n    } else {\n        poly = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n    }\n    // compress consecutive duplicates\n    vector<pair<int,int>> comp;\n    comp.reserve(poly.size());\n    for (auto &p : poly) {\n        if (comp.empty() || comp.back() != p) comp.push_back(p);\n    }\n    if (comp.size() >= 2 && comp.front() == comp.back()) comp.pop_back();\n    // check distinct\n    bool okDistinct = true;\n    {\n        unordered_set<long long> st;\n        st.reserve(comp.size() * 2);\n        for (auto &p : comp) {\n            long long key = ((long long)p.first << 32) ^ (unsigned)p.second;\n            if (st.find(key) != st.end()) {\n                okDistinct = false;\n                break;\n            }\n            st.insert(key);\n        }\n    }\n    long long perim = 0;\n    int m = (int)comp.size();\n    for (int i = 0; i < m; i++) {\n        auto [x1, y1] = comp[i];\n        auto [x2, y2] = comp[(i + 1) % m];\n        perim += llabs(x1 - x2) + llabs(y1 - y2);\n    }\n    if (!okDistinct || perim > 400000 || m < 4) {\n        comp = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n        m = 4;\n    }\n    cout << comp.size() << \"\\n\";\n    for (auto &p : comp) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Command {\n    int p;\n    int r;\n    char d;\n    int b;\n};\n\nstruct Candidate {\n    vector<Command> cmds;\n    long long estScore;\n};\n\n// simulate placement given commands and estimated widths/heights\npair<long long, long long> simulate(const vector<Command>& cmds,\n                                    const vector<long long>& w_est,\n                                    const vector<long long>& h_est) {\n    int N = (int)w_est.size();\n    vector<long long> x(N, 0), y(N, 0), ww(N, 0), hh(N, 0);\n    vector<char> placed(N, 0);\n    long long W = 0, H = 0;\n    for (const auto& cmd : cmds) {\n        int i = cmd.p;\n        long long w = (cmd.r == 0 ? w_est[i] : h_est[i]);\n        long long h = (cmd.r == 0 ? h_est[i] : w_est[i]);\n        long long xi, yi;\n        if (cmd.d == 'U') {\n            xi = (cmd.b == -1) ? 0LL : x[cmd.b] + ww[cmd.b];\n            yi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long l1 = xi, r1 = xi + w;\n                long long l2 = x[j], r2 = x[j] + ww[j];\n                if (max(l1, l2) < min(r1, r2)) {\n                    yi = max(yi, y[j] + hh[j]);\n                }\n            }\n        } else { // 'L'\n            yi = (cmd.b == -1) ? 0LL : y[cmd.b] + hh[cmd.b];\n            xi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long t1 = yi, b1 = yi + h;\n                long long t2 = y[j], b2 = y[j] + hh[j];\n                if (max(t1, t2) < min(b1, b2)) {\n                    xi = max(xi, x[j] + ww[j]);\n                }\n            }\n        }\n        x[i] = xi; y[i] = yi; ww[i] = w; hh[i] = h; placed[i] = 1;\n        W = max(W, xi + w);\n        H = max(H, yi + h);\n    }\n    return {W, H};\n}\n\nvector<int> dp_partition(const vector<long long>& w, const vector<long long>& h_eff, long long Wlim) {\n    int M = (int)w.size();\n    const long long INF = (1LL << 60);\n    vector<long long> dp(M + 1, INF);\n    vector<int> prv(M + 1, -1);\n    dp[0] = 0;\n    for (int i = 0; i < M; i++) {\n        long long width = 0;\n        long long height = 0;\n        for (int j = i; j >= 0; j--) {\n            width += w[j];\n            if (width > Wlim) break;\n            if (h_eff[j] > height) height = h_eff[j];\n            if (dp[j] + height < dp[i + 1]) {\n                dp[i + 1] = dp[j] + height;\n                prv[i + 1] = j;\n            }\n        }\n    }\n    if (dp[M] >= INF / 2) prv.clear();\n    return prv;\n}\n\nvector<pair<int,int>> reconstruct_rows(const vector<int>& prv) {\n    vector<pair<int,int>> rows;\n    if (prv.empty()) return rows;\n    int idx = (int)prv.size() - 1;\n    while (idx > 0) {\n        int j = prv[idx];\n        if (j < 0) { rows.clear(); return rows; }\n        rows.push_back({j, idx});\n        idx = j;\n    }\n    reverse(rows.begin(), rows.end());\n    return rows;\n}\n\nvector<long long> build_limits(long long sumV, long long maxV, long long sqrtA, int M) {\n    set<long long> s;\n    s.insert(maxV);\n    s.insert(sumV);\n    s.insert(sqrtA);\n    int Kpart = min(10, M);\n    for (int k = 2; k <= Kpart; k++) {\n        s.insert((sumV + k - 1) / k);\n    }\n    int Kgeo = 10;\n    if (maxV > 0) {\n        long double ratio = (long double)sumV / (long double)maxV;\n        for (int k = 0; k < Kgeo; k++) {\n            long double val = (long double)maxV * pow(ratio, (long double)k / (long double)(Kgeo - 1));\n            long long V = (long long)(val + 0.5);\n            V = max(V, maxV);\n            V = min(V, sumV);\n            s.insert(V);\n        }\n    }\n    vector<long long> res(s.begin(), s.end());\n    return res;\n}\n\nvector<long long> build_width_candidates_base(const vector<long long>& w, const vector<long long>& h) {\n    int N = (int)w.size();\n    long long sumW = 0, maxW = 0;\n    for (int i = 0; i < N; i++) {\n        sumW += w[i];\n        maxW = max(maxW, w[i]);\n    }\n    set<long long> s;\n    s.insert(maxW);\n    s.insert(sumW);\n    int Rmax = min(8, N);\n    for (int R = 2; R <= Rmax; R++) {\n        long long W = (sumW + R - 1) / R;\n        if (W < maxW) W = maxW;\n        s.insert(W);\n    }\n    int K = 6;\n    for (int k = 0; k < K; k++) {\n        double ratio = (K == 1) ? 0.0 : (double)k / (double)(K - 1);\n        double val = (double)maxW * pow((double)sumW / (double)maxW, ratio);\n        long long W = (long long)(val + 0.5);\n        if (W < maxW) W = maxW;\n        if (W > sumW) W = sumW;\n        s.insert(W);\n    }\n    vector<long long> res(s.begin(), s.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; i++) cin >> w_obs[i] >> h_obs[i];\n\n    // orientation patterns\n    vector<vector<int>> orientations;\n    auto add_ori = [&](const vector<int>& o) {\n        for (auto &v : orientations) {\n            if (v == o) return;\n        }\n        orientations.push_back(o);\n    };\n    vector<int> ori_none(N, 0);\n    add_ori(ori_none);\n    vector<int> ori_minH(N), ori_minW(N);\n    for (int i = 0; i < N; i++) {\n        ori_minH[i] = (w_obs[i] < h_obs[i]) ? 1 : 0;\n        ori_minW[i] = (w_obs[i] > h_obs[i]) ? 1 : 0;\n    }\n    add_ori(ori_minH);\n    add_ori(ori_minW);\n    vector<double> lambdas = {0.7, 0.85, 1.0, 1.15, 1.3};\n    for (double lam : lambdas) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            o[i] = ((double)w_obs[i] > lam * (double)h_obs[i]) ? 1 : 0;\n        }\n        add_ori(o);\n    }\n    // orientation adapted to width limits\n    vector<long long> w_cands_base = build_width_candidates_base(w_obs, h_obs);\n    for (long long Wlim : w_cands_base) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            bool fit0 = w_obs[i] <= Wlim;\n            bool fitR = h_obs[i] <= Wlim;\n            if (fit0 && fitR) {\n                o[i] = (h_obs[i] > w_obs[i]) ? 1 : 0;\n            } else if (fit0) {\n                o[i] = 0;\n            } else if (fitR) {\n                o[i] = 1;\n            } else {\n                o[i] = 0;\n            }\n        }\n        add_ori(o);\n    }\n\n    // exclusion sets\n    vector<vector<int>> excl_sets;\n    auto add_excl = [&](const vector<int>& ex) {\n        vector<int> v = ex;\n        sort(v.begin(), v.end());\n        v.erase(unique(v.begin(), v.end()), v.end());\n        for (auto &e : excl_sets) if (e == v) return;\n        excl_sets.push_back(v);\n    };\n    excl_sets.push_back({});\n    vector<int> idx_wh(N), idx_max(N);\n    iota(idx_wh.begin(), idx_wh.end(), 0);\n    iota(idx_max.begin(), idx_max.end(), 0);\n    sort(idx_wh.begin(), idx_wh.end(), [&](int a, int b) {\n        return (w_obs[a] + h_obs[a]) > (w_obs[b] + h_obs[b]);\n    });\n    sort(idx_max.begin(), idx_max.end(), [&](int a, int b) {\n        return max(w_obs[a], h_obs[a]) > max(w_obs[b], h_obs[b]);\n    });\n    if (!idx_wh.empty()) add_excl({idx_wh[0]});\n    if ((int)idx_wh.size() >= 2) add_excl({idx_wh[0], idx_wh[1]});\n    if ((int)idx_wh.size() >= 3) add_excl({idx_wh[0], idx_wh[1], idx_wh[2]});\n    if (!idx_max.empty()) add_excl({idx_max[0]});\n    if ((int)idx_max.size() >= 2) add_excl({idx_max[0], idx_max[1]});\n    if ((int)idx_max.size() >= 3) add_excl({idx_max[0], idx_max[1], idx_max[2]});\n    if (!idx_wh.empty() && !idx_max.empty()) add_excl({idx_wh[0], idx_max[0]});\n\n    vector<long long> margins = {0};\n    vector<Candidate> candidates;\n\n    for (auto &r_choice : orientations) {\n        for (auto &excl : excl_sets) {\n            vector<char> excluded(N, 0);\n            long long sumExcl = 0;\n            for (int idx : excl) {\n                if (idx >= 0 && idx < N) {\n                    excluded[idx] = 1;\n                    sumExcl += w_obs[idx] + h_obs[idx];\n                }\n            }\n            vector<int> active;\n            active.reserve(N);\n            for (int i = 0; i < N; i++) if (!excluded[i]) active.push_back(i);\n            int M = (int)active.size();\n            if (M == 0) {\n                Candidate cand;\n                cand.cmds.clear();\n                cand.estScore = sumExcl;\n                candidates.push_back(cand);\n                continue;\n            }\n            vector<long long> w_rot(M), h_rot(M);\n            long long sumW = 0, maxW = 0;\n            long long sumH = 0, maxH = 0;\n            long double area = 0;\n            for (int k = 0; k < M; k++) {\n                int i = active[k];\n                long long w = (r_choice[i] == 0 ? w_obs[i] : h_obs[i]);\n                long long h = (r_choice[i] == 0 ? h_obs[i] : w_obs[i]);\n                w_rot[k] = w; h_rot[k] = h;\n                sumW += w; sumH += h;\n                maxW = max(maxW, w);\n                maxH = max(maxH, h);\n                area += (long double)w * (long double)h;\n            }\n            long long sqrtA = (long long)(sqrt(area) + 0.5);\n            vector<long long> Wlims = build_limits(sumW, maxW, sqrtA, M);\n            vector<long long> Hlims = build_limits(sumH, maxH, sqrtA, M);\n\n            // row packings\n            for (long long margin : margins) {\n                vector<long long> h_eff(M);\n                for (int i = 0; i < M; i++) h_eff[i] = h_rot[i] + margin;\n                for (long long Wlim : Wlims) {\n                    if (Wlim < maxW) continue;\n                    vector<int> prv = dp_partition(w_rot, h_eff, Wlim);\n                    if (prv.empty()) continue;\n                    vector<pair<int,int>> rows = reconstruct_rows(prv);\n                    if (rows.empty()) continue;\n                    vector<int> ref_idx(rows.size());\n                    for (size_t ri = 0; ri < rows.size(); ri++) {\n                        int l = rows[ri].first;\n                        int r = rows[ri].second;\n                        long long besth = -1;\n                        int pos = l;\n                        for (int i = l; i < r; i++) {\n                            if (h_eff[i] > besth || (h_eff[i] == besth && i > pos)) {\n                                besth = h_eff[i];\n                                pos = i;\n                            }\n                        }\n                        ref_idx[ri] = active[pos];\n                    }\n                    vector<Command> cmds;\n                    cmds.reserve(M);\n                    for (size_t ri = 0; ri < rows.size(); ri++) {\n                        int b = (ri == 0) ? -1 : ref_idx[ri - 1];\n                        int l = rows[ri].first;\n                        int r = rows[ri].second;\n                        for (int i = l; i < r; i++) {\n                            int idx = active[i];\n                            cmds.push_back({idx, r_choice[idx], 'L', b});\n                        }\n                    }\n                    auto est = simulate(cmds, w_obs, h_obs);\n                    Candidate cand;\n                    cand.cmds = move(cmds);\n                    cand.estScore = est.first + est.second + sumExcl;\n                    candidates.push_back(move(cand));\n                }\n            }\n\n            // column packings\n            for (long long margin : margins) {\n                vector<long long> w_eff(M);\n                for (int i = 0; i < M; i++) w_eff[i] = w_rot[i] + margin;\n                for (long long Hlim : Hlims) {\n                    if (Hlim < maxH) continue;\n                    vector<int> prv = dp_partition(h_rot, w_eff, Hlim); // widths=h_rot, heights=w_rot+margin\n                    if (prv.empty()) continue;\n                    vector<pair<int,int>> cols = reconstruct_rows(prv);\n                    if (cols.empty()) continue;\n                    vector<int> ref_idx(cols.size());\n                    for (size_t ci = 0; ci < cols.size(); ci++) {\n                        int l = cols[ci].first;\n                        int r = cols[ci].second;\n                        long long bestw = -1;\n                        int pos = l;\n                        for (int i = l; i < r; i++) {\n                            if (w_rot[i] > bestw || (w_rot[i] == bestw && i > pos)) {\n                                bestw = w_rot[i];\n                                pos = i;\n                            }\n                        }\n                        ref_idx[ci] = active[pos];\n                    }\n                    vector<Command> cmds;\n                    cmds.reserve(M);\n                    for (size_t ci = 0; ci < cols.size(); ci++) {\n                        int b = (ci == 0) ? -1 : ref_idx[ci - 1];\n                        int l = cols[ci].first;\n                        int r = cols[ci].second;\n                        for (int i = l; i < r; i++) {\n                            int idx = active[i];\n                            cmds.push_back({idx, r_choice[idx], 'U', b});\n                        }\n                    }\n                    auto est = simulate(cmds, w_obs, h_obs);\n                    Candidate cand;\n                    cand.cmds = move(cmds);\n                    cand.estScore = est.first + est.second + sumExcl;\n                    candidates.push_back(move(cand));\n                }\n            }\n        }\n    }\n\n    if (candidates.empty()) {\n        vector<Command> cmds;\n        for (int i = 0; i < N; i++) cmds.push_back({i, 0, 'L', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n        return a.estScore < b.estScore;\n    });\n\n    int outCnt = min((int)candidates.size(), T);\n    vector<vector<Command>> outputs;\n    for (int i = 0; i < outCnt; i++) outputs.push_back(candidates[i].cmds);\n    while ((int)outputs.size() < T) outputs.push_back(outputs[0]);\n\n    for (int t = 0; t < T; t++) {\n        const auto& cmds = outputs[t];\n        cout << cmds.size() << \"\\n\";\n        for (auto &cmd : cmds) {\n            cout << cmd.p << \" \" << cmd.r << \" \" << cmd.d << \" \" << cmd.b << \"\\n\";\n        }\n        cout.flush();\n        long long Wm, Hm;\n        if (!(cin >> Wm >> Hm)) break;\n        // ignoring measurement feedback in this heuristic\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    vector<int> parent;\n    long long score;\n};\n\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n\n    auto start_time = chrono::steady_clock::now();\n    auto elapsed_ms = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(\n                   chrono::steady_clock::now() - start_time)\n            .count();\n    };\n    const long long TIME_LIMIT = 1950; // ms\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    // Precompute all-pairs shortest distances\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    queue<int> q;\n    for (int s = 0; s < N; s++) {\n        auto &drow = dist[s];\n        drow[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            int nd = drow[u] + 1;\n            for (int v : adj[u]) {\n                if (drow[v] == INF) {\n                    drow[v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Eccentricity\n    vector<int> ecc(N, 0);\n    for (int i = 0; i < N; i++) {\n        int mx = 0;\n        for (int j = 0; j < N; j++) {\n            if (dist[i][j] > mx) mx = dist[i][j];\n        }\n        ecc[i] = mx;\n    }\n\n    // Neighbor ordering\n    vector<vector<int>> adj_desc(N), adj_asc(N), adj_rand(N);\n    for (int u = 0; u < N; u++) {\n        adj_desc[u] = adj[u];\n        sort(adj_desc[u].begin(), adj_desc[u].end(), [&](int a, int b) {\n            if (A[a] != A[b]) return A[a] > A[b];\n            return a < b;\n        });\n        adj_asc[u] = adj[u];\n        sort(adj_asc[u].begin(), adj_asc[u].end(), [&](int a, int b) {\n            if (A[a] != A[b]) return A[a] < A[b];\n            return a < b;\n        });\n        adj_rand[u] = adj[u];\n        shuffle(adj_rand[u].begin(), adj_rand[u].end(), rng);\n    }\n\n    // Seeds\n    vector<int> seeds;\n    vector<char> seen_seed(N, 0);\n    auto add_seed = [&](int v) {\n        if (!seen_seed[v]) {\n            seen_seed[v] = 1;\n            seeds.push_back(v);\n        }\n    };\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (A[i] != A[j]) return A[i] < A[j];\n        return i < j;\n    });\n    int kLow = min(30, N);\n    for (int i = 0; i < kLow; i++) add_seed(idx[i]);\n\n    int cen = 0;\n    for (int i = 1; i < N; i++) {\n        if (ecc[i] < ecc[cen] || (ecc[i] == ecc[cen] && A[i] < A[cen]))\n            cen = i;\n    }\n    add_seed(cen);\n\n    long long bestd = (long long)(x[0] - 500) * (x[0] - 500) +\n                      (long long)(y[0] - 500) * (y[0] - 500);\n    int centerCoord = 0;\n    for (int i = 1; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d < bestd) {\n            bestd = d;\n            centerCoord = i;\n        }\n    }\n    add_seed(centerCoord);\n\n    long long maxd = bestd;\n    int farCoord = centerCoord;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d > maxd) {\n            maxd = d;\n            farCoord = i;\n        }\n    }\n    add_seed(farCoord);\n\n    uniform_int_distribution<int> uid(0, N - 1);\n    for (int i = 0; i < 25; i++) add_seed(uid(rng));\n\n    auto prune_roots = [&](vector<int> &roots) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int idx_r = 0; idx_r < (int)roots.size(); idx_r++) {\n                vector<int> tmp(N, INF);\n                for (int j = 0; j < (int)roots.size(); j++) {\n                    if (j == idx_r) continue;\n                    int r = roots[j];\n                    for (int i = 0; i < N; i++) {\n                        int d = dist[r][i];\n                        if (d < tmp[i]) tmp[i] = d;\n                    }\n                }\n                int mx = *max_element(tmp.begin(), tmp.end());\n                if (mx <= H) {\n                    roots.erase(roots.begin() + idx_r);\n                    changed = true;\n                    break;\n                }\n            }\n        }\n    };\n\n    auto select_roots_farthest = [&](int seed) {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> minDist = dist[seed];\n        while (true) {\n            int farNode = -1, farDist = -1, farA = 1e9;\n            for (int i = 0; i < N; i++) {\n                if (minDist[i] > farDist ||\n                    (minDist[i] == farDist && A[i] < farA)) {\n                    farDist = minDist[i];\n                    farNode = i;\n                    farA = A[i];\n                }\n            }\n            if (farDist <= H) break;\n            roots.push_back(farNode);\n            for (int i = 0; i < N; i++) {\n                int d = dist[farNode][i];\n                if (d < minDist[i]) minDist[i] = d;\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_cover_greedy = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        while (remaining > 0) {\n            int best = -1, bestCnt = -1, bestA = 1e9;\n            for (int c = 0; c < N; c++) {\n                int cnt = 0;\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[c][i] <= H) cnt++;\n                }\n                if (cnt > bestCnt || (cnt == bestCnt && A[c] < bestA)) {\n                    bestCnt = cnt;\n                    best = c;\n                    bestA = A[c];\n                }\n            }\n            if (best == -1) break;\n            roots.push_back(best);\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[best][i] <= H) {\n                    covered[i] = 1;\n                    remaining--;\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_lowA_cover = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        for (int v : idx) {\n            if (remaining == 0) break;\n            bool useful = false;\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[v][i] <= H) {\n                    useful = true;\n                    break;\n                }\n            }\n            if (useful) {\n                roots.push_back(v);\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[v][i] <= H) {\n                        covered[i] = 1;\n                        remaining--;\n                    }\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto finalize_and_score = [&](vector<int> parent) -> Solution {\n        vector<vector<int>> children(N);\n        vector<int> depth(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        for (int v = 0; v < N; v++) {\n            if (depth[v] == -1 || depth[v] > H) parent[v] = -1;\n        }\n        // recompute depths after fixing\n        children.assign(N, {});\n        depth.assign(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0) d = 0;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    auto leaf_reparent = [&](vector<int> &parent, vector<int> &depth) {\n        vector<int> childCnt(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) childCnt[parent[v]]++;\n        }\n        bool changed = true;\n        int iter = 0;\n        while (changed && iter < H * 2 + 5) {\n            changed = false;\n            iter++;\n            for (int v = 0; v < N; v++) {\n                if (childCnt[v] == 0) {\n                    int bestDepth = depth[v];\n                    int bestPar = -1;\n                    for (int u : adj[v]) {\n                        int nd = depth[u] + 1;\n                        if (nd <= H && nd > bestDepth) {\n                            bestDepth = nd;\n                            bestPar = u;\n                        }\n                    }\n                    if (bestPar != -1 && parent[v] != bestPar) {\n                        int oldp = parent[v];\n                        if (oldp != -1) childCnt[oldp]--;\n                        parent[v] = bestPar;\n                        childCnt[bestPar]++;\n                        depth[v] = bestDepth;\n                        changed = true;\n                    }\n                }\n            }\n        }\n    };\n\n    auto build_solution = [&](const vector<int> &roots, int orderMode,\n                              int neighborMode) -> Solution {\n        const vector<vector<int>> *adj_used;\n        if (neighborMode == 0)\n            adj_used = &adj_desc;\n        else if (neighborMode == 1)\n            adj_used = &adj_asc;\n        else\n            adj_used = &adj_rand;\n        vector<int> parent(N, -2), depth(N, INF);\n        vector<char> visited(N, 0);\n        vector<int> root_order = roots;\n        if (orderMode == 0) {\n            sort(root_order.begin(), root_order.end(),\n                 [&](int a, int b) { return A[a] < A[b]; });\n        } else {\n            shuffle(root_order.begin(), root_order.end(), rng);\n        }\n        for (int r : root_order) {\n            if (visited[r]) continue;\n            parent[r] = -1;\n            depth[r] = 0;\n            visited[r] = 1;\n            vector<pair<int, int>> st;\n            st.reserve(N);\n            st.push_back({r, 0});\n            while (!st.empty()) {\n                int u = st.back().first;\n                int &idxn = st.back().second;\n                if (depth[u] == H) {\n                    st.pop_back();\n                    continue;\n                }\n                if (idxn >= (int)(*adj_used)[u].size()) {\n                    st.pop_back();\n                    continue;\n                }\n                int v = (*adj_used)[u][idxn++];\n                if (visited[v]) continue;\n                parent[v] = u;\n                depth[v] = depth[u] + 1;\n                visited[v] = 1;\n                st.push_back({v, 0});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            if (!visited[i]) {\n                parent[i] = -1;\n                depth[i] = 0;\n                visited[i] = 1;\n                vector<pair<int, int>> st;\n                st.reserve(N);\n                st.push_back({i, 0});\n                while (!st.empty()) {\n                    int u = st.back().first;\n                    int &idxn = st.back().second;\n                    if (depth[u] == H) {\n                        st.pop_back();\n                        continue;\n                    }\n                    if (idxn >= (int)(*adj_used)[u].size()) {\n                        st.pop_back();\n                        continue;\n                    }\n                    int v = (*adj_used)[u][idxn++];\n                    if (visited[v]) continue;\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    visited[v] = 1;\n                    st.push_back({v, 0});\n                }\n            }\n        }\n        leaf_reparent(parent, depth);\n        return finalize_and_score(parent);\n    };\n\n    auto build_growth = [&](int seedCount) -> Solution {\n        vector<int> parent(N, -1), depth(N, -1);\n        vector<char> done(N, 0);\n        int processed = 0;\n        for (int i = 0; i < seedCount && i < N; i++) {\n            int v = idx[i];\n            if (!done[v]) {\n                done[v] = 1;\n                parent[v] = -1;\n                depth[v] = 0;\n                processed++;\n            }\n        }\n        while (processed < N) {\n            bool progress = false;\n            for (int v = 0; v < N; v++) {\n                if (done[v]) continue;\n                int bestPar = -1, bestDepth = -1, bestA = 1e9;\n                for (int u : adj_desc[v]) {\n                    if (!done[u]) continue;\n                    int nd = depth[u] + 1;\n                    if (nd > H) continue;\n                    if (nd > bestDepth || (nd == bestDepth && A[u] < bestA)) {\n                        bestDepth = nd;\n                        bestPar = u;\n                        bestA = A[u];\n                    }\n                }\n                if (bestPar != -1) {\n                    parent[v] = bestPar;\n                    depth[v] = bestDepth;\n                    done[v] = 1;\n                    processed++;\n                    progress = true;\n                }\n            }\n            if (!progress) {\n                int nr = -1, minA = 1e9;\n                for (int v = 0; v < N; v++) {\n                    if (!done[v] && A[v] < minA) {\n                        minA = A[v];\n                        nr = v;\n                    }\n                }\n                if (nr == -1) break;\n                done[nr] = 1;\n                parent[nr] = -1;\n                depth[nr] = 0;\n                processed++;\n            }\n        }\n        leaf_reparent(parent, depth);\n        return finalize_and_score(parent);\n    };\n\n    auto hill_climb = [&](Solution sol) -> Solution {\n        vector<int> &parent = sol.parent;\n        vector<int> depth(N, -1);\n        long long curScore = sol.score;\n        while (true) {\n            if (elapsed_ms() > TIME_LIMIT - 50) break;\n            // build children and depth\n            vector<vector<int>> children(N);\n            for (int v = 0; v < N; v++) {\n                int p = parent[v];\n                if (p >= 0) children[p].push_back(v);\n            }\n            fill(depth.begin(), depth.end(), -1);\n            queue<int> qq;\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) {\n                    depth[v] = 0;\n                    qq.push(v);\n                }\n            }\n            while (!qq.empty()) {\n                int u = qq.front();\n                qq.pop();\n                for (int c : children[u]) {\n                    depth[c] = depth[u] + 1;\n                    qq.push(c);\n                }\n            }\n            // tin/tout\n            vector<int> tin(N, 0), tout(N, 0);\n            int timer = 0;\n            function<void(int)> dfs = [&](int u) {\n                tin[u] = timer++;\n                for (int c : children[u]) dfs(c);\n                tout[u] = timer;\n            };\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) dfs(v);\n            }\n            // order for postorder\n            vector<int> order;\n            order.reserve(N);\n            function<void(int)> dfs2 = [&](int u) {\n                order.push_back(u);\n                for (int c : children[u]) dfs2(c);\n            };\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) dfs2(v);\n            }\n            vector<long long> subSumA(N, 0);\n            vector<int> subMaxDepth(N, 0);\n            for (int i = (int)order.size() - 1; i >= 0; i--) {\n                int v = order[i];\n                long long sum = A[v];\n                int mx = depth[v];\n                for (int c : children[v]) {\n                    sum += subSumA[c];\n                    if (subMaxDepth[c] > mx) mx = subMaxDepth[c];\n                }\n                subSumA[v] = sum;\n                subMaxDepth[v] = mx;\n            }\n\n            long long bestGain = 0;\n            int bestV = -1, bestU = -1, bestDelta = 0;\n            for (int v = 0; v < N; v++) {\n                for (int u : adj[v]) {\n                    if (tin[v] <= tin[u] && tout[u] <= tout[v]) continue; // u in subtree\n                    int delta = depth[u] + 1 - depth[v];\n                    if (delta <= 0) continue;\n                    if (subMaxDepth[v] + delta > H) continue;\n                    long long gain = 1LL * delta * subSumA[v];\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestV = v;\n                        bestU = u;\n                        bestDelta = delta;\n                    }\n                }\n            }\n            if (bestGain <= 0) break;\n            int v = bestV, u = bestU, delta = bestDelta;\n            parent[v] = u;\n            // update depths of subtree v\n            vector<int> st;\n            st.push_back(v);\n            while (!st.empty()) {\n                int w = st.back();\n                st.pop_back();\n                depth[w] += delta;\n                for (int c : children[w]) st.push_back(c);\n            }\n            curScore += bestGain;\n        }\n        // recompute score safely\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        fill(depth.begin(), depth.end(), -1);\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0 || d > H) d = 0;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    vector<vector<int>> rootSets;\n    rootSets.reserve(seeds.size() + 3);\n    for (int sd : seeds) {\n        rootSets.push_back(select_roots_farthest(sd));\n    }\n    rootSets.push_back(select_roots_cover_greedy());\n    rootSets.push_back(select_roots_lowA_cover());\n\n    vector<Solution> candidates;\n    candidates.reserve(rootSets.size() * 4 + 6);\n    for (const auto &roots : rootSets) {\n        if (elapsed_ms() > TIME_LIMIT - 400) break;\n        candidates.push_back(build_solution(roots, 0, 0));\n        candidates.push_back(build_solution(roots, 0, 1));\n        candidates.push_back(build_solution(roots, 1, 0));\n        candidates.push_back(build_solution(roots, 1, 1));\n    }\n    // growth-based\n    candidates.push_back(build_growth(5));\n    candidates.push_back(build_growth(10));\n    candidates.push_back(build_growth(20));\n\n    sort(candidates.begin(), candidates.end(),\n         [](const Solution &a, const Solution &b) {\n             return a.score > b.score;\n         });\n    int topK = min<int>(12, candidates.size());\n\n    long long bestScore = -1;\n    vector<int> bestParent(N, -1);\n    for (int i = 0; i < topK; i++) {\n        if (elapsed_ms() > TIME_LIMIT - 50) break;\n        Solution imp = hill_climb(candidates[i]);\n        if (imp.score > bestScore) {\n            bestScore = imp.score;\n            bestParent = imp.parent;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option {\n    int line; // 0..4N-1\n    int len;  // 1..N\n};\n\nstruct Solver {\n    static const int N = 20;\n    vector<string> board;\n    vector<int> upLim, downLim, leftLim, rightLim;\n    vector<pair<int,int>> oni;               // positions of oni\n    vector<vector<Option>> opts;             // options for each oni\n    int M;                                   // #oni\n\n    // state\n    vector<array<int, N+1>> cnt; // cnt[line][len]\n    vector<int> maxLen;          // max len per line\n    vector<int> assign;          // chosen option index per oni\n    long cost;                   // 2 * sum(maxLen)\n\n    mt19937 rng;\n\n    Solver(const vector<string>& g): board(g) {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n        compute_limits();\n        collect_oni();\n        build_options();\n    }\n\n    void compute_limits() {\n        upLim.assign(N, N);\n        downLim.assign(N, N);\n        leftLim.assign(N, N);\n        rightLim.assign(N, N);\n        // columns\n        for (int j = 0; j < N; j++) {\n            for (int i = 0; i < N; i++) {\n                if (board[i][j] == 'o') { upLim[j] = i; break; }\n            }\n            for (int i = N-1; i >= 0; i--) {\n                if (board[i][j] == 'o') { downLim[j] = N-1 - i; break; }\n            }\n        }\n        // rows\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'o') { leftLim[i] = j; break; }\n            }\n            for (int j = N-1; j >= 0; j--) {\n                if (board[i][j] == 'o') { rightLim[i] = N-1 - j; break; }\n            }\n        }\n    }\n\n    void collect_oni() {\n        oni.clear();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') oni.emplace_back(i,j);\n            }\n        }\n        M = (int)oni.size();\n    }\n\n    void build_options() {\n        opts.assign(M, {});\n        for (int idx = 0; idx < M; idx++) {\n            auto [r,c] = oni[idx];\n            // Up\n            if (r+1 <= upLim[c]) {\n                opts[idx].push_back({c, r+1});\n            }\n            // Down\n            if (N - r <= downLim[c]) {\n                opts[idx].push_back({N + c, N - r});\n            }\n            // Left\n            if (c+1 <= leftLim[r]) {\n                opts[idx].push_back({2*N + r, c+1});\n            }\n            // Right\n            if (N - c <= rightLim[r]) {\n                opts[idx].push_back({3*N + r, N - c});\n            }\n            if (opts[idx].empty()) {\n                // Should not happen\n                opts[idx].push_back({c, r+1}); // dummy\n            }\n        }\n    }\n\n    void rebuild_from_assign() {\n        cnt.assign(4*N, {});\n        maxLen.assign(4*N, 0);\n        cost = 0;\n        for (int i = 0; i < M; i++) {\n            int optIdx = assign[i];\n            const Option &op = opts[i][optIdx];\n            cnt[op.line][op.len] ++;\n            if (op.len > maxLen[op.line]) maxLen[op.line] = op.len;\n        }\n        for (int l = 0; l < 4*N; l++) {\n            cost += 2LL * maxLen[l];\n        }\n    }\n\n    // helpers for delta computation\n    int newMaxAfterRemoval(int line, int len) const {\n        int oldMax = maxLen[line];\n        if (len < oldMax) return oldMax;\n        if (cnt[line][len] >= 2) return oldMax;\n        // len == oldMax and will be removed\n        for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) return l;\n        return 0;\n    }\n\n    int computeDelta(int i, int newOpt) const {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return 0;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        if (cur.line == nxt.line) {\n            int line = cur.line;\n            int oldMax = maxLen[line];\n            int newMax = oldMax;\n            if (cur.len == oldMax && cnt[line][cur.len] == 1) {\n                newMax = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[line][l] > 0) {newMax=l; break;}\n            }\n            if (nxt.len > newMax) newMax = nxt.len;\n            return 2 * (newMax - oldMax);\n        } else {\n            int oldMaxA = maxLen[cur.line];\n            int oldMaxB = maxLen[nxt.line];\n            int newMaxA = oldMaxA;\n            if (cur.len == oldMaxA && cnt[cur.line][cur.len] == 1) {\n                newMaxA = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[cur.line][l] > 0) {newMaxA=l; break;}\n            }\n            int newMaxB = (nxt.len > oldMaxB) ? nxt.len : oldMaxB;\n            return 2 * ((newMaxA - oldMaxA) + (newMaxB - oldMaxB));\n        }\n    }\n\n    void remove_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]--;\n        if (len == oldMax && cnt[line][len] == 0) {\n            int m = 0;\n            for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) {m = l; break;}\n            maxLen[line] = m;\n        }\n        cost += 2LL * maxLen[line];\n    }\n\n    void add_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]++;\n        if (len > oldMax) maxLen[line] = len;\n        cost += 2LL * maxLen[line];\n    }\n\n    void applyMove(int i, int newOpt) {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        remove_assignment(cur.line, cur.len);\n        add_assignment(nxt.line, nxt.len);\n        assign[i] = newOpt;\n    }\n\n    void hillClimb() {\n        while (true) {\n            int bestDelta = 0;\n            int bestI = -1;\n            int bestOpt = -1;\n            for (int i = 0; i < M; i++) {\n                int curOpt = assign[i];\n                for (int k = 0; k < (int)opts[i].size(); k++) {\n                    if (k == curOpt) continue;\n                    int delta = computeDelta(i, k);\n                    if (delta < bestDelta) {\n                        bestDelta = delta;\n                        bestI = i;\n                        bestOpt = k;\n                    }\n                }\n            }\n            if (bestDelta < 0) {\n                applyMove(bestI, bestOpt);\n            } else break;\n        }\n    }\n\n    void simulatedAnnealing(int ITER, double T0, double T1) {\n        vector<int> bestAssignLocal = assign;\n        long bestCostLocal = cost;\n        uniform_real_distribution<double> dist01(0.0, 1.0);\n        for (int it = 0; it < ITER; it++) {\n            double T = T0 + (T1 - T0) * (double)it / (double)ITER;\n            int i = rng() % M;\n            if (opts[i].size() <= 1) continue;\n            int newOpt = rng() % opts[i].size();\n            if (newOpt == assign[i]) continue;\n            int delta = computeDelta(i, newOpt);\n            if (delta <= 0 || exp(-delta / T) > dist01(rng)) {\n                applyMove(i, newOpt);\n                if (cost < bestCostLocal) {\n                    bestCostLocal = cost;\n                    bestAssignLocal = assign;\n                }\n            }\n        }\n        assign = bestAssignLocal;\n        rebuild_from_assign();\n    }\n\n    // Large neighborhood search: reassign a subset exhaustively\n    bool lns_once(int k) {\n        if (M == 0) return false;\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        // sort by current required length descending\n        sort(idx.begin(), idx.end(), [&](int a, int b){\n            int lena = opts[a][assign[a]].len;\n            int lenb = opts[b][assign[b]].len;\n            return lena > lenb;\n        });\n        int candSize = min(M, 10);\n        if (candSize < k) k = candSize;\n        if (k == 0) return false;\n        // choose first candSize then shuffle\n        vector<int> cands(idx.begin(), idx.begin() + candSize);\n        shuffle(cands.begin(), cands.end(), rng);\n        vector<int> subset(cands.begin(), cands.begin() + k);\n\n        vector<int> backupAssign = assign;\n        long originalCost = cost;\n\n        // remove subset assignments\n        for (int id : subset) {\n            const Option &op = opts[id][assign[id]];\n            remove_assignment(op.line, op.len);\n            assign[id] = -1;\n        }\n        long baseCost = cost;\n\n        vector<int> bestChoices(k, 0);\n        long bestCost = (1LL<<60);\n\n        function<void(int)> dfs = [&](int depth){\n            if (depth == k) {\n                if (cost < bestCost) {\n                    bestCost = cost;\n                    for (int t = 0; t < k; t++) {\n                        bestChoices[t] = assign[subset[t]];\n                    }\n                }\n                return;\n            }\n            int oniId = subset[depth];\n            for (int optIdx = 0; optIdx < (int)opts[oniId].size(); optIdx++) {\n                const Option &op = opts[oniId][optIdx];\n                add_assignment(op.line, op.len);\n                assign[oniId] = optIdx;\n                dfs(depth+1);\n                remove_assignment(op.line, op.len);\n                assign[oniId] = -1;\n            }\n        };\n        dfs(0);\n\n        // restore assignment based on result\n        if (bestCost < originalCost) {\n            assign = backupAssign;\n            for (int t = 0; t < k; t++) {\n                assign[subset[t]] = bestChoices[t];\n            }\n            rebuild_from_assign();\n            return true;\n        } else {\n            assign = backupAssign;\n            rebuild_from_assign();\n            return false;\n        }\n    }\n\n    void solve() {\n        int NUM_SEEDS = 8;\n        int SA_ITER = 40000;\n        double T0 = 5.0, T1 = 0.1;\n        int LNS_TRIES = 60;\n        int LNS_K = 5;\n\n        long globalBestCost = (1LL<<60);\n        vector<int> globalBestAssign;\n        vector<int> globalBestMaxLen;\n\n        uniform_int_distribution<int> seedDist(0, 1e9);\n\n        for (int seed = 0; seed < NUM_SEEDS; seed++) {\n            // initial assignment\n            assign.assign(M, 0);\n            for (int i = 0; i < M; i++) {\n                if (seed == 0) {\n                    // choose minimal len (tie random)\n                    int bestLen = 1e9;\n                    vector<int> cand;\n                    for (int k = 0; k < (int)opts[i].size(); k++) {\n                        int len = opts[i][k].len;\n                        if (len < bestLen) {\n                            bestLen = len;\n                            cand.clear();\n                            cand.push_back(k);\n                        } else if (len == bestLen) {\n                            cand.push_back(k);\n                        }\n                    }\n                    assign[i] = cand[rng() % cand.size()];\n                } else {\n                    assign[i] = rng() % opts[i].size();\n                }\n            }\n            rebuild_from_assign();\n            hillClimb();\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n\n            simulatedAnnealing(SA_ITER, T0, T1);\n            hillClimb();\n\n            bool improved = true;\n            int tries = 0;\n            while (improved && tries < LNS_TRIES) {\n                improved = lns_once(LNS_K);\n                tries++;\n            }\n\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n        }\n\n        // use global best\n        assign = globalBestAssign;\n        maxLen = globalBestMaxLen;\n        // output operations\n        vector<pair<char,int>> ops;\n        auto add_ops = [&](char dir, int idx, int len){\n            for (int k = 0; k < len; k++) ops.emplace_back(dir, idx);\n        };\n        // Up then Down for up lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[j];\n            if (len > 0) {\n                add_ops('U', j, len);\n                add_ops('D', j, len);\n            }\n        }\n        // Down then Up for down lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[N + j];\n            if (len > 0) {\n                add_ops('D', j, len);\n                add_ops('U', j, len);\n            }\n        }\n        // Left then Right\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[2*N + i];\n            if (len > 0) {\n                add_ops('L', i, len);\n                add_ops('R', i, len);\n            }\n        }\n        // Right then Left\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[3*N + i];\n            if (len > 0) {\n                add_ops('R', i, len);\n                add_ops('L', i, len);\n            }\n        }\n\n        for (auto &op : ops) {\n            cout << op.first << \" \" << op.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n;\n    if (!(cin >> n)) return 0;\n    vector<string> g(n);\n    for (int i = 0; i < n; i++) cin >> g[i];\n    Solver solver(g);\n    solver.solve();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift {\n    using result_type = uint64_t;\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return UINT64_MAX; }\n    result_type operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint64_t next() { return (*this)(); }\n    int next_int(int l, int r) { return l + (int)(next() % (uint64_t)(r - l + 1)); }\n};\n\nint N, Ltot;\nvector<int> T;\nvector<double> pi;\nvector<long long> prefixT;\nXorShift rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\nint rand_by_target() {\n    uint64_t r = rng.next() % (uint64_t)Ltot;\n    int idx = int(lower_bound(prefixT.begin(), prefixT.end(), (long long)r + 1) - prefixT.begin());\n    if (idx >= N) idx = N - 1;\n    return idx;\n}\n\n// ensure nodes with T>0 have some indegree\nvoid enforce_indegree(vector<int>& a, vector<int>& b) {\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < N; i++) {\n        indeg[a[i]]++;\n        indeg[b[i]]++;\n    }\n    for (int j = 0; j < N; j++) {\n        if (T[j] > 0 && indeg[j] == 0) {\n            int s = rng.next_int(0, N - 1);\n            if (rng.next_int(0, 1) == 0) {\n                indeg[a[s]]--;\n                a[s] = j;\n            } else {\n                indeg[b[s]]--;\n                b[s] = j;\n            }\n            indeg[j]++;\n        }\n    }\n}\n\n// compute indegree distribution summing to 2N\nvoid compute_degrees(int minMode, const vector<double>& desired, vector<int>& deg) {\n    int edges = 2 * N;\n    deg.assign(N, 0);\n    int minSum = 0;\n    for (int i = 0; i < N; i++) {\n        int mv = 0;\n        if (minMode == 1) {\n            if (T[i] > 0) mv = 1;\n        } else if (minMode == 2) {\n            mv = 1;\n        }\n        deg[i] = mv;\n        minSum += mv;\n    }\n    int R = edges - minSum;\n    static double quota[105];\n    double qsum = 0.0;\n    for (int i = 0; i < N; i++) {\n        double q = desired[i] - deg[i];\n        if (q < 0) q = 0;\n        quota[i] = q;\n        qsum += q;\n    }\n    static pair<double, int> fr[105];\n    int sumDeg = minSum;\n    if (qsum > 1e-9) {\n        double scale = (double)R / qsum;\n        for (int i = 0; i < N; i++) {\n            double v = quota[i] * scale;\n            int add = (int)v;\n            deg[i] += add;\n            sumDeg += add;\n            fr[i] = make_pair(v - add, i);\n        }\n    } else {\n        for (int i = 0; i < N; i++) fr[i] = make_pair(0.0, i);\n    }\n    int leftover = edges - sumDeg;\n    for (int i = N - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(fr[i], fr[j]);\n    }\n    sort(fr, fr + N, [](const pair<double, int>& a, const pair<double, int>& b) {\n        return a.first > b.first;\n    });\n    for (int k = 0; k < leftover; k++) deg[fr[k].second]++;\n}\n\n// build candidate using apportionment\nvoid build_apportion(int minMode, const vector<double>& desired, vector<int>& a, vector<int>& b) {\n    vector<int> deg;\n    compute_degrees(minMode, desired, deg);\n    vector<int> slots;\n    slots.reserve(2 * N);\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n    }\n    while ((int)slots.size() < 2 * N) slots.push_back(rand_by_target());\n    while ((int)slots.size() > 2 * N) slots.pop_back();\n    for (int i = (int)slots.size() - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(slots[i], slots[j]);\n    }\n    a.resize(N);\n    b.resize(N);\n    for (int i = 0; i < N; i++) {\n        a[i] = slots[2 * i];\n        b[i] = slots[2 * i + 1];\n    }\n    enforce_indegree(a, b);\n}\n\n// greedy assignment variants\nvoid build_greedy(int variant, vector<int>& a, vector<int>& b) {\n    a.assign(N, -1);\n    b.assign(N, -1);\n    vector<double> r(N);\n    for (int j = 0; j < N; j++) r[j] = 2.0 * pi[j];\n    vector<int> order(2 * N);\n    for (int i = 0; i < N; i++) {\n        order[2 * i] = i;\n        order[2 * i + 1] = i;\n    }\n    if (variant == 0) {\n        sort(order.begin(), order.end(), [&](int i, int j) { return pi[i] > pi[j]; });\n    } else if (variant == 1) {\n        sort(order.begin(), order.end(), [&](int i, int j) { return pi[i] < pi[j]; });\n    } else {\n        for (int i = (int)order.size() - 1; i > 0; --i) {\n            int j = rng.next() % (uint64_t)(i + 1);\n            swap(order[i], order[j]);\n        }\n    }\n    for (int idx = 0; idx < (int)order.size(); idx++) {\n        int s = order[idx];\n        double w = pi[s];\n        int bestJ = 0;\n        if (variant == 2) { // fit residual\n            double bestVal = 1e18;\n            for (int j = 0; j < N; j++) {\n                double v = fabs(r[j] - w);\n                if (v < bestVal) {\n                    bestVal = v;\n                    bestJ = j;\n                }\n            }\n        } else {\n            double bestVal = -1e18;\n            for (int j = 0; j < N; j++) {\n                if (r[j] > bestVal) {\n                    bestVal = r[j];\n                    bestJ = j;\n                }\n            }\n        }\n        r[bestJ] -= w;\n        if (a[s] == -1)\n            a[s] = bestJ;\n        else\n            b[s] = bestJ;\n    }\n    for (int i = 0; i < N; i++) if (b[i] == -1) b[i] = a[i];\n    enforce_indegree(a, b);\n}\n\n// simulate plan, fill cnt array, return error\nlong long simulate(const vector<int>& a, const vector<int>& b, int* cntArr) {\n    for (int i = 0; i < N; i++) cntArr[i] = 0;\n    int cur = 0;\n    for (int step = 0; step < Ltot; step++) {\n        int c = ++cntArr[cur];\n        cur = (c & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)cntArr[i] - (long long)T[i];\n        err += d >= 0 ? d : -d;\n    }\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> Ltot)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    pi.resize(N);\n    for (int i = 0; i < N; i++) pi[i] = (double)T[i] / (double)Ltot;\n    prefixT.resize(N);\n    long long acc = 0;\n    for (int i = 0; i < N; i++) {\n        acc += T[i];\n        prefixT[i] = acc;\n    }\n    vector<double> desiredEdges(N);\n    for (int i = 0; i < N; i++) desiredEdges[i] = pi[i] * 2.0 * N;\n\n    vector<int> bestA(N), bestB(N);\n    long long bestErr = (1LL << 60);\n    static int bestCnt[105];\n\n    vector<int> candA, candB;\n    static int cntArr[105];\n\n    // generate initial candidates\n    build_greedy(0, candA, candB);\n    long long err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    build_greedy(1, candA, candB);\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    build_greedy(2, candA, candB);\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    build_apportion(1, desiredEdges, candA, candB);\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    // random by target\n    candA.resize(N);\n    candB.resize(N);\n    for (int i = 0; i < N; i++) {\n        candA[i] = rand_by_target();\n        candB[i] = rand_by_target();\n    }\n    enforce_indegree(candA, candB);\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    // both edges same by target\n    for (int i = 0; i < N; i++) {\n        int v = rand_by_target();\n        candA[i] = v;\n        candB[i] = v;\n    }\n    enforce_indegree(candA, candB);\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    // cycle + target\n    for (int i = 0; i < N; i++) {\n        candA[i] = (i + 1) % N;\n        candB[i] = rand_by_target();\n    }\n    enforce_indegree(candA, candB);\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n    // top nodes\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return T[i] > T[j]; });\n    int top1 = idx[0], top2 = idx[1];\n    for (int i = 0; i < N; i++) {\n        candA[i] = top1;\n        candB[i] = top2;\n    }\n    err = simulate(candA, candB, cntArr);\n    if (err < bestErr) {\n        bestErr = err;\n        bestA = candA;\n        bestB = candB;\n        memcpy(bestCnt, cntArr, sizeof(int) * N);\n    }\n\n    // hill climbing on best\n    vector<int> curA = bestA, curB = bestB;\n    static int curCnt[105];\n    memcpy(curCnt, bestCnt, sizeof(int) * N);\n    long long curErr = bestErr;\n    static int newCnt[105];\n\n    auto start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9; // seconds\n    int failCount = 0;\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > TIME_LIMIT) break;\n        // compute diff and totals\n        long long totalPos = 0, totalNeg = 0;\n        static long long diff[105];\n        for (int i = 0; i < N; i++) {\n            diff[i] = (long long)curCnt[i] - (long long)T[i];\n            if (diff[i] > 0) totalPos += diff[i];\n            else totalNeg += -diff[i];\n        }\n        if (totalPos == 0 || totalNeg == 0) break;\n        // pick under, over\n        long long rneg = rng.next() % totalNeg;\n        int under = 0;\n        long long accn = 0;\n        for (; under < N; under++) {\n            if (diff[under] < 0) {\n                accn += -diff[under];\n                if (accn > rneg) break;\n            }\n        }\n        if (under >= N) under = rng.next_int(0, N - 1);\n        long long rpos = rng.next() % totalPos;\n        int over = 0;\n        long long accp = 0;\n        for (; over < N; over++) {\n            if (diff[over] > 0) {\n                accp += diff[over];\n                if (accp > rpos) break;\n            }\n        }\n        if (over >= N) over = rng.next_int(0, N - 1);\n        // find source with edge to over\n        int s = -1, edgeIdx = 0;\n        int startIdx = rng.next_int(0, N - 1);\n        for (int k = 0; k < N; k++) {\n            int i = (startIdx + k) % N;\n            if (curA[i] == over) {\n                s = i;\n                edgeIdx = 0;\n                break;\n            }\n            if (curB[i] == over) {\n                s = i;\n                edgeIdx = 1;\n                break;\n            }\n        }\n        if (s == -1) {\n            s = rng.next_int(0, N - 1);\n            edgeIdx = rng.next_int(0, 1);\n        }\n        int old = (edgeIdx == 0) ? curA[s] : curB[s];\n        if (old == under) {\n            failCount++;\n            continue;\n        }\n        if (edgeIdx == 0)\n            curA[s] = under;\n        else\n            curB[s] = under;\n        long long nerr = simulate(curA, curB, newCnt);\n        if (nerr < curErr) {\n            curErr = nerr;\n            memcpy(curCnt, newCnt, sizeof(int) * N);\n            failCount = 0;\n            if (nerr < bestErr) {\n                bestErr = nerr;\n                bestA = curA;\n                bestB = curB;\n            }\n        } else {\n            // revert\n            if (edgeIdx == 0)\n                curA[s] = old;\n            else\n                curB[s] = old;\n            failCount++;\n            // occasional random restart candidate\n            if (failCount > 200) {\n                failCount = 0;\n                build_apportion(1, desiredEdges, curA, curB);\n                long long e2 = simulate(curA, curB, curCnt);\n                curErr = e2;\n                if (e2 < bestErr) {\n                    bestErr = e2;\n                    bestA = curA;\n                    bestB = curB;\n                }\n            }\n        }\n    }\n\n    // output best plan\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << ' ' << bestB[i] << '\\n';\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// XorShift random\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    inline uint64_t rng() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int randint(int l, int r) { // [l, r)\n        return (int)(rng() % (uint64_t)(r - l)) + l;\n    }\n    inline double rand01() {\n        return (double)(rng() & 0xFFFFFFFFULL) / 4294967296.0;\n    }\n} rnd;\n\n// DSU\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a);\n        b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\n// Hilbert order\nuint64_t hilbertOrder(int x, int y, int order_bits, int max_coord) {\n    uint64_t d = 0;\n    for (int s = order_bits - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        d <<= 2;\n        d |= (uint64_t)((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) {\n                x = max_coord - x;\n                y = max_coord - y;\n            }\n            int t = x;\n            x = y;\n            y = t;\n        }\n    }\n    return d;\n}\n\n// Prim cost using distance matrix\ndouble primCost(const vector<int>& nodes, const vector<float>& distMat, int N) {\n    int n = (int)nodes.size();\n    if (n <= 1) return 0.0;\n    vector<float> minD(n, 1e30f);\n    vector<char> used(n, 0);\n    minD[0] = 0.0f;\n    double cost = 0.0;\n    for (int it = 0; it < n; ++it) {\n        int v = -1;\n        float best = 1e30f;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        cost += minD[v];\n        int idv = nodes[v];\n        int base = idv * N;\n        for (int i = 0; i < n; ++i)\n            if (!used[i]) {\n                int idu = nodes[i];\n                float d = distMat[base + idu];\n                if (d < minD[i]) minD[i] = d;\n            }\n    }\n    return cost;\n}\n\n// Prim edges using distance matrix\nvector<pair<int, int>> primEdges(const vector<int>& nodes, const vector<float>& distMat, int N) {\n    int n = (int)nodes.size();\n    if (n <= 1) return {};\n    vector<float> minD(n, 1e30f);\n    vector<int> parent(n, -1);\n    vector<char> used(n, 0);\n    minD[0] = 0.0f;\n    for (int it = 0; it < n; ++it) {\n        int v = -1;\n        float best = 1e30f;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        int idv = nodes[v];\n        int base = idv * N;\n        for (int i = 0; i < n; ++i)\n            if (!used[i]) {\n                int idu = nodes[i];\n                float d = distMat[base + idu];\n                if (d < minD[i]) {\n                    minD[i] = d;\n                    parent[i] = v;\n                }\n            }\n    }\n    vector<pair<int, int>> edges;\n    edges.reserve(n - 1);\n    for (int i = 1; i < n; ++i) edges.emplace_back(nodes[i], nodes[parent[i]]);\n    return edges;\n}\n\n// nearest neighbor order\nvector<int> nearestNeighborOrder(int N, const vector<float>& distMat) {\n    vector<int> order;\n    order.reserve(N);\n    vector<char> used(N, 0);\n    int cur = 0;\n    used[cur] = 1;\n    order.push_back(cur);\n    for (int step = 1; step < N; ++step) {\n        int best = -1;\n        float bestd = 1e30f;\n        int base = cur * N;\n        for (int i = 0; i < N; ++i) {\n            if (used[i]) continue;\n            float d = distMat[base + i];\n            if (d < bestd) {\n                bestd = d;\n                best = i;\n            }\n        }\n        cur = best;\n        used[cur] = 1;\n        order.push_back(cur);\n    }\n    return order;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    vector<double> px(N), py(N);\n    for (int i = 0; i < N; ++i) {\n        px[i] = (lx[i] + rx[i]) * 0.5;\n        py[i] = (ly[i] + ry[i]) * 0.5;\n    }\n\n    // distance matrix\n    vector<float> distMat(N * N);\n    for (int i = 0; i < N; ++i) {\n        distMat[i * N + i] = 0.0f;\n        for (int j = i + 1; j < N; ++j) {\n            double dx = px[i] - px[j];\n            double dy = py[i] - py[j];\n            float d = (float)std::sqrt(dx * dx + dy * dy);\n            distMat[i * N + j] = d;\n            distMat[j * N + i] = d;\n        }\n    }\n\n    const int order_bits = 15;\n    const int max_coord = (1 << order_bits) - 1;\n\n    vector<vector<int>> candidates;\n\n    // Hilbert variants\n    for (int variant = 0; variant < 5; ++variant) {\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            int x = (int)px[i];\n            int y = (int)py[i];\n            switch (variant) {\n                case 0: break;\n                case 1: x = max_coord - x; break;\n                case 2: y = max_coord - y; break;\n                case 3:\n                    x = max_coord - x;\n                    y = max_coord - y;\n                    break;\n                case 4: {\n                    int t = x;\n                    x = y;\n                    y = t;\n                } break;\n            }\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b) { return a.first < b.first; });\n        vector<int> ord;\n        ord.reserve(N);\n        for (auto& p : keys) ord.push_back(p.second);\n        candidates.push_back(move(ord));\n    }\n    // jittered hilbert\n    for (int rep = 0; rep < 3; ++rep) {\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            double nx = px[i] + (rnd.rand01() - 0.5) * W * 0.3;\n            double ny = py[i] + (rnd.rand01() - 0.5) * W * 0.3;\n            int x = max(0, min(max_coord, (int)nx));\n            int y = max(0, min(max_coord, (int)ny));\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b) { return a.first < b.first; });\n        vector<int> ord;\n        ord.reserve(N);\n        for (auto& p : keys) ord.push_back(p.second);\n        candidates.push_back(move(ord));\n    }\n    // simple sorts\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (px[a] == px[b]) return py[a] < py[b];\n            return px[a] < px[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (py[a] == py[b]) return px[a] < px[b];\n            return py[a] < py[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] + py[a], vb = px[b] + py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] - py[a], vb = px[b] - py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    candidates.push_back(nearestNeighborOrder(N, distMat));\n\n    auto evalCost = [&](const vector<int>& ord) -> double {\n        double tot = 0.0;\n        int pos = 0;\n        for (int k = 0; k < M; ++k) {\n            int g = G[k];\n            vector<int> grp;\n            grp.reserve(g);\n            for (int t = 0; t < g; ++t) grp.push_back(ord[pos + t]);\n            pos += g;\n            tot += primCost(grp, distMat, N);\n        }\n        return tot;\n    };\n\n    double bestInit = 1e100;\n    int bestIdx = 0;\n    for (int i = 0; i < (int)candidates.size(); ++i) {\n        double c = evalCost(candidates[i]);\n        if (c < bestInit) {\n            bestInit = c;\n            bestIdx = i;\n        }\n    }\n    const vector<int>& initOrder = candidates[bestIdx];\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int k = 0; k < M; ++k) {\n        int g = G[k];\n        groups[k].reserve(g);\n        for (int t = 0; t < g; ++t) groups[k].push_back(initOrder[pos + t]);\n        pos += g;\n    }\n\n    // neighbor list\n    const int KNEI = 30;\n    vector<vector<int>> neigh(N);\n    vector<int> tmp(N);\n    for (int i = 0; i < N; ++i) {\n        iota(tmp.begin(), tmp.end(), 0);\n        sort(tmp.begin(), tmp.end(), [&](int a, int b) { return distMat[i * N + a] < distMat[i * N + b]; });\n        neigh[i].reserve(KNEI);\n        for (int t = 1; t <= KNEI; ++t) neigh[i].push_back(tmp[t]);\n    }\n\n    vector<double> groupCost(M, 0.0);\n    double totalCost = 0.0;\n    for (int k = 0; k < M; ++k) {\n        double c = primCost(groups[k], distMat, N);\n        groupCost[k] = c;\n        totalCost += c;\n    }\n    vector<vector<int>> bestGroups = groups;\n    double bestCost = totalCost;\n\n    vector<int> belong(N, -1);\n    vector<int> idxInGroup(N, -1);\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < (int)groups[k].size(); ++i) {\n            int v = groups[k][i];\n            belong[v] = k;\n            idxInGroup[v] = i;\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 1.2; // seconds for SA\n    const double T0 = 20.0, Tend = 1e-3;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > timeLimit) break;\n        double t = elapsed / timeLimit;\n        double T = exp(log(T0) * (1.0 - t) + log(Tend) * t);\n\n        int va, vb, ga, gb;\n        if (rnd.rand01() < 0.7) {\n            va = rnd.randint(0, N);\n            int nb = rnd.randint(0, KNEI);\n            vb = neigh[va][nb];\n            ga = belong[va];\n            gb = belong[vb];\n            if (ga == gb) continue;\n        } else {\n            ga = rnd.randint(0, M);\n            gb = rnd.randint(0, M);\n            if (ga == gb || groups[ga].empty() || groups[gb].empty()) continue;\n            va = groups[ga][rnd.randint(0, (int)groups[ga].size())];\n            vb = groups[gb][rnd.randint(0, (int)groups[gb].size())];\n        }\n\n        int ia = idxInGroup[va];\n        int ib = idxInGroup[vb];\n        auto& A = groups[ga];\n        auto& B = groups[gb];\n\n        // swap\n        A[ia] = vb;\n        B[ib] = va;\n        idxInGroup[va] = ib;\n        idxInGroup[vb] = ia;\n\n        double oldSum = groupCost[ga] + groupCost[gb];\n        double newA = primCost(A, distMat, N);\n        double newB = primCost(B, distMat, N);\n        double newSum = newA + newB;\n        double delta = newSum - oldSum;\n        bool accept = false;\n        if (delta < 0)\n            accept = true;\n        else {\n            double prob = exp(-delta / T);\n            if (rnd.rand01() < prob) accept = true;\n        }\n        if (accept) {\n            groupCost[ga] = newA;\n            groupCost[gb] = newB;\n            totalCost += delta;\n            belong[va] = gb;\n            belong[vb] = ga;\n            if (totalCost < bestCost) {\n                bestCost = totalCost;\n                bestGroups = groups;\n            }\n        } else {\n            // revert\n            A[ia] = va;\n            B[ib] = vb;\n            idxInGroup[va] = ia;\n            idxInGroup[vb] = ib;\n        }\n    }\n\n    groups.swap(bestGroups);\n\n    // sort each group by Hilbert\n    for (int k = 0; k < M; ++k) {\n        auto& g = groups[k];\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(g.size());\n        for (int v : g) {\n            int x = (int)px[v], y = (int)py[v];\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, v);\n        }\n        sort(keys.begin(), keys.end(), [](auto& a, auto& b) { return a.first < b.first; });\n        vector<int> ng;\n        ng.reserve(g.size());\n        for (auto& p : keys) ng.push_back(p.second);\n        g.swap(ng);\n    }\n\n    // Query planning: small groups first\n    vector<vector<pair<int, int>>> qEdges(M);\n    int queries_used = 0;\n    // pass 0: groups with size <= L and >=2\n    for (int k = 0; k < M && queries_used < Q; ++k) {\n        int sz = (int)groups[k].size();\n        if (sz < 2 || sz > L) continue;\n        cout << \"? \" << sz;\n        for (int v : groups[k]) cout << ' ' << v;\n        cout << endl;\n        queries_used++;\n        for (int i = 0; i < sz - 1; ++i) {\n            int a, b;\n            if (!(cin >> a >> b)) return 0;\n            qEdges[k].emplace_back(a, b);\n        }\n    }\n    // pass 1: larger groups\n    for (int k = 0; k < M && queries_used < Q; ++k) {\n        int sz = (int)groups[k].size();\n        if (sz <= L || sz < 2) continue;\n        int need = (sz - 1 + (L - 2)) / (L - 1); // ceil((sz-1)/(L-1))\n        int use = min(need, Q - queries_used);\n        if (use <= 0) break;\n        for (int i = 0; i < use; ++i) {\n            int start = (int)round((double)i * (sz - L) / max(1, use - 1));\n            if (start > sz - L) start = sz - L;\n            if (start < 0) start = 0;\n            int len = min(L, sz - start);\n            if (len < 2) continue;\n            cout << \"? \" << len;\n            for (int j = 0; j < len; ++j) cout << ' ' << groups[k][start + j];\n            cout << endl;\n            queries_used++;\n            for (int e = 0; e < len - 1; ++e) {\n                int a, b;\n                if (!(cin >> a >> b)) return 0;\n                qEdges[k].emplace_back(a, b);\n            }\n            if (queries_used >= Q) break;\n        }\n    }\n\n    // Build final edges combining query edges and predicted MST\n    vector<vector<pair<int, int>>> finalEdges(M);\n    vector<int> idxMap(N, -1);\n    for (int k = 0; k < M; ++k) {\n        auto& nodes = groups[k];\n        int gsz = nodes.size();\n        if (gsz <= 1) continue;\n        for (int i = 0; i < gsz; ++i) idxMap[nodes[i]] = i;\n        DSU uf(gsz);\n        vector<pair<int, int>> chosen;\n        chosen.reserve(gsz - 1);\n        for (auto& e : qEdges[k]) {\n            int ia = idxMap[e.first], ib = idxMap[e.second];\n            if (ia < 0 || ib < 0) continue;\n            if (uf.unite(ia, ib)) chosen.push_back(e);\n        }\n        auto preds = primEdges(nodes, distMat, N);\n        for (auto& e : preds) {\n            if ((int)chosen.size() >= gsz - 1) break;\n            int ia = idxMap[e.first], ib = idxMap[e.second];\n            if (uf.unite(ia, ib)) chosen.push_back(e);\n        }\n        finalEdges[k] = move(chosen);\n        for (int v : nodes) idxMap[v] = -1;\n    }\n\n    cout << \"!\\n\";\n    for (int k = 0; k < M; ++k) {\n        auto& nodes = groups[k];\n        for (int i = 0; i < (int)nodes.size(); ++i) {\n            if (i) cout << ' ';\n            cout << nodes[i];\n        }\n        cout << '\\n';\n        for (auto& e : finalEdges[k]) {\n            cout << e.first << ' ' << e.second << '\\n';\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1e9;\nint N, M;\nvector<int> idxs;\nvector<pair<int, int>> pos;\nvector<int> dr = {-1, 1, 0, 0};\nvector<int> dc = {0, 0, -1, 1};\nvector<char> dirChar = {'U', 'D', 'L', 'R'};\nvector<char> isTarget;  // size N*N\n\ninline int slide_stop(int r, int c, int dir, const vector<char> &blocked) {\n    int nr = r, nc = c;\n    while (true) {\n        int tr = nr + dr[dir], tc = nc + dc[dir];\n        if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n        if (blocked[tr * N + tc]) break;\n        nr = tr;\n        nc = tc;\n    }\n    return nr * N + nc;\n}\n\nint dist_between(int s, int g, const vector<char> &blocked) {\n    if (blocked[s] || blocked[g]) return INF;\n    static vector<int> dist;\n    static queue<int> q;\n    if ((int)dist.size() != N * N) dist.resize(N * N);\n    fill(dist.begin(), dist.end(), -1);\n    while (!q.empty()) q.pop();\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front();\n        q.pop();\n        int d = dist[v];\n        if (v == g) return d;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = d + 1;\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = d + 1;\n                q.push(sid);\n            }\n        }\n    }\n    return INF;\n}\n\nvector<pair<char, char>> path_between(int s, int g, const vector<char> &blocked) {\n    vector<int> dist(N * N, -1), prev(N * N, -1);\n    vector<char> prevAct(N * N), prevDir(N * N);\n    queue<int> q;\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front();\n        q.pop();\n        if (v == g) break;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'M';\n                    prevDir[ni] = dirChar[dir];\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = dist[v] + 1;\n                prev[sid] = v;\n                prevAct[sid] = 'S';\n                prevDir[sid] = dirChar[dir];\n                q.push(sid);\n            }\n        }\n    }\n    vector<pair<char, char>> actions;\n    if (dist[g] == -1) return actions;  // unreachable\n    int cur = g;\n    while (cur != s) {\n        actions.push_back({prevAct[cur], prevDir[cur]});\n        cur = prev[cur];\n    }\n    reverse(actions.begin(), actions.end());\n    return actions;\n}\n\n// Adjacent candidate cells per target index\nvector<vector<int>> adjCells;\n\n// evaluate cost of a plan (boolean array size N*N)\nint evaluate_plan(const vector<char> &plan) {\n    vector<char> blocked(N * N, false);\n    int cost = 0;\n    for (int t = 0; t < M - 1; t++) {\n        // place planned blocks adjacent to current target\n        for (int idx : adjCells[t]) {\n            if (plan[idx] && !blocked[idx]) {\n                blocked[idx] = true;\n                cost += 1;  // alter action\n            }\n        }\n        int d = dist_between(idxs[t], idxs[t + 1], blocked);\n        if (d >= INF / 2) return INF;\n        cost += d;\n    }\n    return cost;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> M)) return 0;\n    pos.resize(M);\n    idxs.resize(M);\n    isTarget.assign(N * N, false);\n    for (int k = 0; k < M; k++) {\n        int r, c;\n        cin >> r >> c;\n        pos[k] = {r, c};\n        idxs[k] = r * N + c;\n        isTarget[idxs[k]] = true;\n    }\n\n    adjCells.assign(M, {});\n    vector<char> isCandidate(N * N, false);\n    for (int t = 0; t < M - 1; t++) {  // last target has no outgoing edge\n        int r = pos[t].first, c = pos[t].second;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int idx = nr * N + nc;\n                if (isTarget[idx]) continue;\n                adjCells[t].push_back(idx);\n                isCandidate[idx] = true;\n            }\n        }\n    }\n\n    vector<int> candidates;\n    for (int i = 0; i < N * N; i++) {\n        if (isCandidate[i] && !isTarget[i]) candidates.push_back(i);\n    }\n\n    vector<char> plan(N * N, false);\n    int bestCost = evaluate_plan(plan);\n    vector<char> bestPlan = plan;\n    int curCost = bestCost;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> urd(0.0, 1.0);\n\n    auto start = chrono::steady_clock::now();\n    const double timeLimit = 1.2;  // seconds for optimization\n    int iter = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > timeLimit) break;\n        iter++;\n        int ci = candidates[rng() % candidates.size()];\n        plan[ci] = !plan[ci];\n        int newCost = evaluate_plan(plan);\n        int diff = newCost - curCost;\n        double temp = 1.0 - elapsed / timeLimit;\n        temp = max(temp, 0.01);\n        if (diff <= 0 || exp(-diff / temp) > urd(rng)) {\n            curCost = newCost;\n            if (newCost < bestCost) {\n                bestCost = newCost;\n                bestPlan = plan;\n            }\n        } else {\n            plan[ci] = !plan[ci];\n        }\n    }\n\n    // Use bestPlan\n    plan = bestPlan;\n    if (bestCost >= INF / 2) {\n        fill(plan.begin(), plan.end(), false);\n    }\n\n    vector<char> blocked(N * N, false);\n    vector<pair<char, char>> actions;\n\n    for (int t = 0; t < M - 1; t++) {\n        int r = pos[t].first, c = pos[t].second;\n        // place planned blocks adjacent to current target\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int idx = nr * N + nc;\n                if (plan[idx] && !blocked[idx]) {\n                    actions.push_back({'A', dirChar[dir]});\n                    blocked[idx] = true;\n                }\n            }\n        }\n        int cur = idxs[t];\n        int nxt = idxs[t + 1];\n        int curDist = dist_between(cur, nxt, blocked);\n        // local greedy toggle for immediate next move (skip planned cells and targets)\n        while (true) {\n            int bestGain = 0;\n            int bestDir = -1;\n            bool bestPlace = true;\n            int bestNewDist = curDist;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r + dr[dir], nc = c + dc[dir];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                int idx = nr * N + nc;\n                if (isTarget[idx]) continue;\n                if (plan[idx]) continue;  // don't toggle planned cells\n                if (!blocked[idx]) {\n                    blocked[idx] = true;\n                    int nd = dist_between(cur, nxt, blocked);\n                    blocked[idx] = false;\n                    if (nd < INF / 2) {\n                        int gain = curDist - (1 + nd);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = true;\n                            bestNewDist = nd;\n                        }\n                    }\n                } else {  // remove\n                    blocked[idx] = false;\n                    int nd = dist_between(cur, nxt, blocked);\n                    blocked[idx] = true;\n                    if (nd < INF / 2) {\n                        int gain = curDist - (1 + nd);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = false;\n                            bestNewDist = nd;\n                        }\n                    }\n                }\n            }\n            if (bestGain > 0 && bestDir != -1) {\n                actions.push_back({'A', dirChar[bestDir]});\n                int idx = (r + dr[bestDir]) * N + (c + dc[bestDir]);\n                blocked[idx] = bestPlace;\n                curDist = bestNewDist;\n            } else {\n                break;\n            }\n        }\n        // move to next target\n        auto path = path_between(cur, nxt, blocked);\n        actions.insert(actions.end(), path.begin(), path.end());\n    }\n\n    for (auto &p : actions) {\n        cout << p.first << ' ' << p.second << '\\n';\n    }\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a, b, c, d;\n};\nstruct Move {\n    double diff;\n    int dir;\n    int len;\n    Move(double _d = 0.0, int _dir = -1, int _len = 0) : diff(_d), dir(_dir), len(_len) {}\n};\n\nint n;\nvector<int> x_coord, y_coord;\nvector<long long> r_target;\nvector<Rect> rects;\n\ninline long long area(const Rect &rc) {\n    return 1LL * (rc.c - rc.a) * (rc.d - rc.b);\n}\ninline double compute_p_val(long long ri, long long s) {\n    double mn = (double)min(ri, s);\n    double mx = (double)max(ri, s);\n    double diff = 1.0 - mn / mx;\n    return 1.0 - diff * diff;\n}\n\nvoid compute_max_expands(int idx, int &left, int &right, int &up, int &down) {\n    const Rect &ri = rects[idx];\n    left = ri.a;\n    right = 10000 - ri.c;\n    up = ri.b;\n    down = 10000 - ri.d;\n    for (int j = 0; j < n; j++) if (j != idx) {\n        const Rect &rj = rects[j];\n        if (rj.b < ri.d && rj.d > ri.b) {\n            if (rj.c <= ri.a) {\n                int cand = ri.a - rj.c;\n                if (cand < left) left = cand;\n            }\n            if (rj.a >= ri.c) {\n                int cand = rj.a - ri.c;\n                if (cand < right) right = cand;\n            }\n        }\n        if (rj.a < ri.c && rj.c > ri.a) {\n            if (rj.d <= ri.b) {\n                int cand = ri.b - rj.d;\n                if (cand < up) up = cand;\n            }\n            if (rj.b >= ri.d) {\n                int cand = rj.b - ri.d;\n                if (cand < down) down = cand;\n            }\n        }\n    }\n}\n\nMove find_best_expand(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s >= rt) return best;\n    int left, right, up, down;\n    compute_max_expands(idx, left, right, up, down);\n    int maxLens[4] = {left, right, up, down};\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int deltas[4] = {h, h, w, w};\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(rt - s) / (double)delta;\n        int cand[5]; int cc = 0;\n        auto add = [&](int l){ if (l > 0 && l <= maxLen) cand[cc++] = l; };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf); add(lc); add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff; best.dir = dir; best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\nMove find_best_contract(int idx) {\n    Move best(0.0, -1, 0);\n    Rect &rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s <= rt) return best;\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    int maxLens[4] = {\n        min(x_coord[idx] - rc.a, w - 1),\n        min(rc.c - (x_coord[idx] + 1), w - 1),\n        min(y_coord[idx] - rc.b, h - 1),\n        min(rc.d - (y_coord[idx] + 1), h - 1)\n    };\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n    int deltas[4] = {h, h, w, w};\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n    for (int dir = 0; dir < 4; dir++) {\n        int maxLen = maxLens[dir];\n        if (maxLen <= 0) continue;\n        int delta = deltas[dir];\n        if (delta <= 0) continue;\n        double len_target = (double)(s - rt) / (double)delta;\n        int cand[5]; int cc = 0;\n        auto add = [&](int l){ if (l > 0 && l <= maxLen) cand[cc++] = l; };\n        add(1);\n        int lf = (int)floor(len_target);\n        int lc = (int)ceil(len_target);\n        add(lf); add(lc); add(maxLen);\n        sort(cand, cand + cc);\n        cc = (int)(unique(cand, cand + cc) - cand);\n        for (int k = 0; k < cc; k++) {\n            int l = cand[k];\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            if (diff > best.diff + EPS) {\n                best.diff = diff; best.dir = dir; best.len = l;\n            }\n        }\n    }\n    return best;\n}\n\ninline void apply_move(int idx, const Move &mv, bool expand) {\n    if (mv.dir < 0 || mv.len <= 0) return;\n    Rect &rc = rects[idx];\n    int l = mv.len;\n    if (expand) {\n        if (mv.dir == 0) rc.a -= l;\n        else if (mv.dir == 1) rc.c += l;\n        else if (mv.dir == 2) rc.b -= l;\n        else rc.d += l;\n    } else {\n        if (mv.dir == 0) rc.a += l;\n        else if (mv.dir == 1) rc.c -= l;\n        else if (mv.dir == 2) rc.b += l;\n        else rc.d -= l;\n    }\n}\n\nbool adjust_vertical_edge(int L, int R) {\n    Rect &A = rects[L];\n    Rect &B = rects[R];\n    int H = A.d - A.b;\n    if (H <= 0) return false;\n    long long sA0 = 1LL * (A.c - A.a) * H;\n    long long sB0 = 1LL * (B.c - B.a) * H;\n    int x0 = A.c;\n    int low = max(A.a + 1, x_coord[L] + 1);\n    int high = min(B.c - 1, x_coord[R]);\n    if (low > high) return false;\n    auto eval = [&](int xx)->double{\n        if (xx < low || xx > high) return -1e30;\n        long long sA = sA0 + 1LL * (xx - x0) * H;\n        long long sB = sB0 - 1LL * (xx - x0) * H;\n        return compute_p_val(r_target[L], sA) + compute_p_val(r_target[R], sB);\n    };\n    double cur = eval(x0);\n    double bestVal = cur; int bestX = x0;\n    vector<int> cand; cand.reserve(8);\n    cand.push_back(low); cand.push_back(high);\n    double tA = x0 + (double)(r_target[L] - sA0) / (double)H;\n    double tB = x0 - (double)(r_target[R] - sB0) / (double)H;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB); if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int xx : cand) {\n        double val = eval(xx);\n        if (val > bestVal + EPS) { bestVal = val; bestX = xx; }\n    }\n    if (bestX != x0) {\n        int dx = bestX - x0;\n        A.c += dx; B.a += dx;\n        return true;\n    }\n    return false;\n}\n\nbool adjust_horizontal_edge(int U, int D) {\n    Rect &A = rects[U];\n    Rect &B = rects[D];\n    int W = A.c - A.a;\n    if (W <= 0) return false;\n    long long sA0 = 1LL * (A.d - A.b) * W;\n    long long sB0 = 1LL * (B.d - B.b) * W;\n    int y0 = A.d;\n    int low = max(A.b + 1, y_coord[U] + 1);\n    int high = min(B.d - 1, y_coord[D]);\n    if (low > high) return false;\n    auto eval = [&](int yy)->double{\n        if (yy < low || yy > high) return -1e30;\n        long long sA = sA0 + 1LL * (yy - y0) * W;\n        long long sB = sB0 - 1LL * (yy - y0) * W;\n        return compute_p_val(r_target[U], sA) + compute_p_val(r_target[D], sB);\n    };\n    double cur = eval(y0);\n    double bestVal = cur; int bestY = y0;\n    vector<int> cand; cand.reserve(8);\n    cand.push_back(low); cand.push_back(high);\n    double tA = y0 + (double)(r_target[U] - sA0) / (double)W;\n    double tB = y0 - (double)(r_target[D] - sB0) / (double)W;\n    int v;\n    v = (int)floor(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tA); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)floor(tB); if (v >= low && v <= high) cand.push_back(v);\n    v = (int)ceil(tB); if (v >= low && v <= high) cand.push_back(v);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n    const double EPS = 1e-12;\n    for (int yy : cand) {\n        double val = eval(yy);\n        if (val > bestVal + EPS) { bestVal = val; bestY = yy; }\n    }\n    if (bestY != y0) {\n        int dy = bestY - y0;\n        A.d += dy; B.b += dy;\n        return true;\n    }\n    return false;\n}\n\ndouble compute_total_score() {\n    double tot = 0.0;\n    for (int i = 0; i < n; i++) tot += compute_p_val(r_target[i], area(rects[i]));\n    return tot;\n}\n\nbool shrink_box(int idx) {\n    Rect rc = rects[idx];\n    long long s = area(rc);\n    long long rt = r_target[idx];\n    if (s <= rt) return false;\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    if (w <= 1 && h <= 1) return false;\n    int leftMax = min(x_coord[idx] - rc.a, w - 1);\n    int rightMax = min(rc.c - (x_coord[idx] + 1), w - 1);\n    int upMax = min(y_coord[idx] - rc.b, h - 1);\n    int downMax = min(rc.d - (y_coord[idx] + 1), h - 1);\n    int minW = max(1, w - (leftMax + rightMax));\n    int minH = max(1, h - (upMax + downMax));\n    vector<int> ws, hs;\n    ws.reserve(6); hs.reserve(6);\n    ws.push_back(w);\n    ws.push_back(minW);\n    int sw = (int)floor(sqrt((double)rt));\n    if (sw >= minW && sw <= w) ws.push_back(sw);\n    if (sw + 1 >= minW && sw + 1 <= w) ws.push_back(sw + 1);\n    if (w - (w - minW) / 2 >= minW) ws.push_back(w - (w - minW) / 2);\n    hs.push_back(h);\n    hs.push_back(minH);\n    int sh = (int)floor(sqrt((double)rt));\n    if (sh >= minH && sh <= h) hs.push_back(sh);\n    if (sh + 1 >= minH && sh + 1 <= h) hs.push_back(sh + 1);\n    if (h - (h - minH) / 2 >= minH) hs.push_back(h - (h - minH) / 2);\n    sort(ws.begin(), ws.end()); ws.erase(unique(ws.begin(), ws.end()), ws.end());\n    sort(hs.begin(), hs.end()); hs.erase(unique(hs.begin(), hs.end()), hs.end());\n    double p_cur = compute_p_val(rt, s);\n    const double EPS = 1e-12;\n    double bestDiff = 0.0;\n    Rect bestRect = rc;\n    for (int nw : ws) for (int nh : hs) {\n        if (nw < 1 || nh < 1) continue;\n        if (nw > w || nh > h) continue;\n        int dx = w - nw;\n        int dy = h - nh;\n        int shrinkL = min(leftMax, dx / 2);\n        int shrinkR = dx - shrinkL;\n        if (shrinkR > rightMax) {\n            int over = shrinkR - rightMax;\n            shrinkR = rightMax;\n            shrinkL = min(leftMax, shrinkL + over);\n            dx = shrinkL + shrinkR;\n            nw = w - dx;\n        }\n        int shrinkU = min(upMax, dy / 2);\n        int shrinkD = dy - shrinkU;\n        if (shrinkD > downMax) {\n            int over = shrinkD - downMax;\n            shrinkD = downMax;\n            shrinkU = min(upMax, shrinkU + over);\n            dy = shrinkU + shrinkD;\n            nh = h - dy;\n        }\n        if (nw <= 0 || nh <= 0) continue;\n        Rect cand{rc.a + shrinkL, rc.b + shrinkU, rc.c - shrinkR, rc.d - shrinkD};\n        long long s_new = 1LL * (cand.c - cand.a) * (cand.d - cand.b);\n        double p_new = compute_p_val(rt, s_new);\n        double diff = p_new - p_cur;\n        if (diff > bestDiff + EPS) {\n            bestDiff = diff;\n            bestRect = cand;\n        }\n    }\n    if (bestDiff > EPS) {\n        rects[idx] = bestRect;\n        return true;\n    }\n    return false;\n}\n\nvoid greedy_expand(const vector<int>& order) {\n    const double EPS = 1e-12;\n    for (int idx : order) {\n        for (int iter = 0; iter < 1000; iter++) {\n            Move mv = find_best_expand(idx);\n            if (mv.diff > EPS) apply_move(idx, mv, true);\n            else break;\n        }\n    }\n}\n\nvoid improve_solution_loop(int max_outer, chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    const double EPS = 1e-12;\n    vector<int> idxs(n);\n    for (int outer = 0; outer < max_outer; outer++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        iota(idxs.begin(), idxs.end(), 0);\n        shuffle(idxs.begin(), idxs.end(), rng);\n        for (int id : idxs) {\n            long long s = area(rects[id]);\n            long long rt = r_target[id];\n            if (s > rt) {\n                if (shrink_box(id)) improved = true;\n            }\n            double bestDiff = 0.0; bool doExpand = false;\n            Move mvE = find_best_expand(id);\n            if (mvE.diff > bestDiff) { bestDiff = mvE.diff; doExpand = true; }\n            Move mvC = find_best_contract(id);\n            if (mvC.diff > bestDiff) { bestDiff = mvC.diff; doExpand = false; }\n            if (bestDiff > EPS) {\n                if (doExpand) apply_move(id, mvE, true);\n                else apply_move(id, mvC, false);\n                improved = true;\n            }\n        }\n        elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool pair_improved = false;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (rects[i].b == rects[j].b && rects[i].d == rects[j].d) {\n                    if (rects[i].c == rects[j].a) {\n                        if (adjust_vertical_edge(i, j)) pair_improved = true;\n                    } else if (rects[j].c == rects[i].a) {\n                        if (adjust_vertical_edge(j, i)) pair_improved = true;\n                    }\n                }\n                if (rects[i].a == rects[j].a && rects[i].c == rects[j].c) {\n                    if (rects[i].d == rects[j].b) {\n                        if (adjust_horizontal_edge(i, j)) pair_improved = true;\n                    } else if (rects[j].d == rects[i].b) {\n                        if (adjust_horizontal_edge(j, i)) pair_improved = true;\n                    }\n                }\n            }\n            elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        if (pair_improved) improved = true;\n        if (!improved) break;\n    }\n}\n\nvoid compute_max_contracts(int idx, int maxLens[4]) {\n    Rect &rc = rects[idx];\n    int w = rc.c - rc.a;\n    int h = rc.d - rc.b;\n    maxLens[0] = min(x_coord[idx] - rc.a, w - 1);\n    maxLens[1] = min(rc.c - (x_coord[idx] + 1), w - 1);\n    maxLens[2] = min(y_coord[idx] - rc.b, h - 1);\n    maxLens[3] = min(rc.d - (y_coord[idx] + 1), h - 1);\n    for (int d = 0; d < 4; d++) if (maxLens[d] < 0) maxLens[d] = 0;\n}\n\nvoid simulated_annealing(chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    double duration = TIME_LIMIT - elapsed - 0.08;\n    if (duration <= 0) return;\n    double sa_start = elapsed, sa_end = sa_start + duration;\n    double cur_score = compute_total_score();\n    double best_score = cur_score;\n    vector<Rect> best_rects = rects;\n    const double T0 = 0.6, T1 = 0.02;\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    uniform_int_distribution<int> dist_rect(0, n - 1);\n    int iter = 0;\n    while (true) {\n        iter++;\n        if ((iter & 0x3FF) == 0) {\n            double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (now > sa_end) break;\n        }\n        double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double t = (now - sa_start) / duration;\n        if (t < 0) t = 0; if (t > 1) t = 1;\n        double temp = T0 + (T1 - T0) * t;\n        int i = dist_rect(rng);\n        Rect &rc = rects[i];\n        long long s = area(rc), rt = r_target[i];\n        double p_cur = compute_p_val(rt, s);\n        bool choose_expand;\n        if (s < rt) choose_expand = (urd(rng) < 0.75);\n        else if (s > rt) choose_expand = (urd(rng) < 0.25);\n        else choose_expand = (urd(rng) < 0.5);\n        if (choose_expand) {\n            int left, right, up, down;\n            compute_max_expands(i, left, right, up, down);\n            int maxLens[4] = {left, right, up, down};\n            int w = rc.c - rc.a, h = rc.d - rc.b;\n            int deltas[4] = {h, h, w, w};\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) if (maxLens[d] > 0) dirs.push_back(d);\n            if (dirs.empty()) continue;\n            int dir = dirs[rng() % dirs.size()];\n            int maxLen = maxLens[dir];\n            int delta = deltas[dir];\n            if (delta <= 0) continue;\n            double len_target = (rt > s) ? (double)(rt - s) / (double)delta : 1.0;\n            int l = (int)round(len_target);\n            if (l < 1) l = 1; if (l > maxLen) l = maxLen;\n            int tweak = (int)(urd(rng) * 5.0) - 2; l += tweak;\n            if (l < 1) l = 1; if (l > maxLen) l = maxLen;\n            long long s_new = s + 1LL * l * delta;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            bool accept = diff >= 0 || urd(rng) < exp(diff / temp);\n            if (accept) {\n                if (dir == 0) rc.a -= l;\n                else if (dir == 1) rc.c += l;\n                else if (dir == 2) rc.b -= l;\n                else rc.d += l;\n                cur_score += diff;\n                if (cur_score > best_score) { best_score = cur_score; best_rects = rects; }\n            }\n        } else {\n            int w = rc.c - rc.a, h = rc.d - rc.b;\n            if (w <= 1 && h <= 1) continue;\n            int maxLens[4]; compute_max_contracts(i, maxLens);\n            vector<int> dirs;\n            for (int d = 0; d < 4; d++) if (maxLens[d] > 0) dirs.push_back(d);\n            if (dirs.empty()) continue;\n            int dir = dirs[rng() % dirs.size()];\n            int maxLen = maxLens[dir];\n            int delta = (dir < 2) ? h : w;\n            if (delta <= 0) continue;\n            double len_target = (s > rt) ? (double)(s - rt) / (double)delta : 1.0;\n            int l = (int)round(len_target);\n            if (l < 1) l = 1; if (l > maxLen) l = maxLen;\n            int tweak = (int)(urd(rng) * 5.0) - 2; l += tweak;\n            if (l < 1) l = 1; if (l > maxLen) l = maxLen;\n            long long s_new = s - 1LL * l * delta;\n            if (s_new <= 0) continue;\n            double p_new = compute_p_val(rt, s_new);\n            double diff = p_new - p_cur;\n            bool accept = diff >= 0 || urd(rng) < exp(diff / temp);\n            if (accept) {\n                if (dir == 0) rc.a += l;\n                else if (dir == 1) rc.c -= l;\n                else if (dir == 2) rc.b += l;\n                else rc.d -= l;\n                cur_score += diff;\n                if (cur_score > best_score) { best_score = cur_score; best_rects = rects; }\n            }\n        }\n    }\n    rects = best_rects;\n}\n\nvoid compute_anchor_limits(int idx, int &left_lim, int &right_lim, int &up_lim, int &down_lim) {\n    int xi = x_coord[idx], yi = y_coord[idx];\n    left_lim = xi; right_lim = 10000 - (xi + 1);\n    up_lim = yi; down_lim = 10000 - (yi + 1);\n    for (int j = 0; j < n; j++) if (j != idx) {\n        const Rect &rj = rects[j];\n        if (rj.b < yi + 1 && rj.d > yi) {\n            if (rj.c <= xi) {\n                int d = xi - rj.c; if (d < left_lim) left_lim = d;\n            }\n            if (rj.a >= xi + 1) {\n                int d = rj.a - (xi + 1); if (d < right_lim) right_lim = d;\n            }\n        }\n        if (rj.a < xi + 1 && rj.c > xi) {\n            if (rj.d <= yi) {\n                int d = yi - rj.d; if (d < up_lim) up_lim = d;\n            }\n            if (rj.b >= yi + 1) {\n                int d = rj.b - (yi + 1); if (d < down_lim) down_lim = d;\n            }\n        }\n    }\n}\n\nbool overlap_with_others(const Rect &cand, int skip) {\n    for (int j = 0; j < n; j++) if (j != skip) {\n        const Rect &rj = rects[j];\n        if (cand.a < rj.c && cand.c > rj.a && cand.b < rj.d && cand.d > rj.b) return true;\n    }\n    return false;\n}\n\nvoid random_reassign_worst(chrono::steady_clock::time_point start_time, double TIME_LIMIT, mt19937 &rng) {\n    double remaining = TIME_LIMIT - chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    if (remaining < 0.1) return;\n    vector<pair<double,int>> vals; vals.reserve(n);\n    for (int i = 0; i < n; i++) {\n        vals.emplace_back(compute_p_val(r_target[i], area(rects[i])), i);\n    }\n    sort(vals.begin(), vals.end());\n    int k = min(40, n);\n    uniform_real_distribution<double> urd(0.6, 1.4);\n    for (int idx = 0; idx < k; idx++) {\n        double now = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (now > TIME_LIMIT - 0.05) break;\n        int i = vals[idx].second;\n        double pcur = vals[idx].first;\n        int left_lim, right_lim, up_lim, down_lim;\n        compute_anchor_limits(i, left_lim, right_lim, up_lim, down_lim);\n        int maxW = left_lim + right_lim + 1;\n        int maxH = up_lim + down_lim + 1;\n        if (maxW <= 0 || maxH <= 0) continue;\n        int samples = 60;\n        for (int s = 0; s < samples; s++) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > TIME_LIMIT - 0.05) break;\n            double fac = urd(rng);\n            int w = (int)llround(sqrt((double)r_target[i]) * fac);\n            if (w < 1) w = 1; if (w > maxW) w = maxW;\n            int h = (int)((double)r_target[i] / w);\n            if (h < 1) h = 1; if (h > maxH) h = maxH;\n            int L_min = max(0, w - 1 - right_lim);\n            int L_max = min(left_lim, w - 1);\n            if (L_min > L_max) continue;\n            int L = L_min + rng() % (L_max - L_min + 1);\n            int R = w - 1 - L;\n            int U_min = max(0, h - 1 - down_lim);\n            int U_max = min(up_lim, h - 1);\n            if (U_min > U_max) continue;\n            int U = U_min + rng() % (U_max - U_min + 1);\n            int D = h - 1 - U;\n            Rect cand{x_coord[i] - L, y_coord[i] - U, x_coord[i] - L + w, y_coord[i] - U + h};\n            if (cand.a < 0 || cand.b < 0 || cand.c > 10000 || cand.d > 10000) continue;\n            if (overlap_with_others(cand, i)) continue;\n            double p_new = compute_p_val(r_target[i], 1LL * w * h);\n            if (p_new > pcur + 1e-12) { rects[i] = cand; pcur = p_new; }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> n)) return 0;\n    x_coord.resize(n); y_coord.resize(n); r_target.resize(n); rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        int xi, yi; long long ri; cin >> xi >> yi >> ri;\n        x_coord[i] = xi; y_coord[i] = yi; r_target[i] = ri;\n    }\n    auto start_time = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.9;\n    mt19937 rng(1234567);\n    vector<vector<int>> orders;\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a,int b){ return r_target[a] > r_target[b]; });\n    orders.push_back(order);\n    sort(order.begin(), order.end(), [&](int a,int b){ return r_target[a] < r_target[b]; });\n    orders.push_back(order);\n    sort(order.begin(), order.end(), [&](int a,int b){\n        if (x_coord[a] != x_coord[b]) return x_coord[a] < x_coord[b];\n        return y_coord[a] < y_coord[b];\n    });\n    orders.push_back(order);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    orders.push_back(order);\n    double best_score = -1.0;\n    vector<Rect> best_rects;\n    auto elapsed = [&]()->double{\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n    auto run_candidate = [&](const vector<int>& ord, int outer_limit, double time_cut){\n        for (int i = 0; i < n; i++) rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n        greedy_expand(ord);\n        improve_solution_loop(outer_limit, start_time, time_cut, rng);\n        double sc = compute_total_score();\n        if (sc > best_score) { best_score = sc; best_rects = rects; }\n    };\n    for (auto &ord : orders) {\n        if (elapsed() > TIME_LIMIT * 0.4 && best_score >= 0) break;\n        run_candidate(ord, 8, TIME_LIMIT * 0.55);\n    }\n    while (elapsed() < TIME_LIMIT * 0.45) {\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        run_candidate(order, 6, TIME_LIMIT * 0.55);\n    }\n    if (!best_rects.empty()) rects = best_rects;\n    else for (int i = 0; i < n; i++) rects[i] = {x_coord[i], y_coord[i], x_coord[i] + 1, y_coord[i] + 1};\n    improve_solution_loop(18, start_time, TIME_LIMIT * 0.7, rng);\n    sort(order.begin(), order.end(), [&](int a,int b){ return r_target[a] > r_target[b]; });\n    greedy_expand(order);\n    improve_solution_loop(8, start_time, TIME_LIMIT * 0.78, rng);\n    simulated_annealing(start_time, TIME_LIMIT * 0.97, rng);\n    random_reassign_worst(start_time, TIME_LIMIT * 0.99, rng);\n    improve_solution_loop(6, start_time, TIME_LIMIT, rng);\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << ' ' << rects[i].b << ' ' << rects[i].c << ' ' << rects[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 50;\nconst int W = 50;\nconst int N = H * W;\n\nint Tcell[N];\nint Pcell[N];\n\nint nbCnt[N];\nint nbIdx[N][4];\nchar nbDir[N][4];\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dch[4] = {'U', 'D', 'L', 'R'};\n\nint startIdx;\nint tileCount;\n\nvector<int> visitedTile;\nint currentToken = 1;\n\nstruct XorShift {\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ULL) { x = seed; }\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int n) { return (int)(next() % n); }\n};\nXorShift rng;\n\nenum Mode { MIN_DEG = 0, MAX_DEG = 1, MAX_VALUE = 2 };\n\nstruct Param {\n    int avoidLevel; // -1 for no avoid, otherwise ignore deg<=avoidLevel if a higher deg exists\n    Mode mode;\n    int randProb; // 0..1023 chance to pick random move\n};\n\nstruct Path {\n    string moves;\n    int score;\n    int len;\n};\n\ninline int compute_deg(int idx) {\n    int tid = Tcell[idx];\n    int deg = 0;\n    for (int k = 0; k < nbCnt[idx]; k++) {\n        int nb = nbIdx[idx][k];\n        int nt = Tcell[nb];\n        if (nt == tid) continue;\n        if (visitedTile[nt] == currentToken) continue;\n        deg++;\n    }\n    return deg;\n}\n\nPath run_once(const Param &param) {\n    currentToken++;\n    if (currentToken == 0x3f3f3f3f) { // reset if overflowed\n        currentToken = 1;\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n    }\n    visitedTile[Tcell[startIdx]] = currentToken;\n    int cur = startIdx;\n    int score = Pcell[cur];\n    vector<char> mv;\n    mv.reserve(tileCount);\n    while (true) {\n        int candIdxArr[4];\n        char candDirArr[4];\n        int cnum = 0;\n        for (int k = 0; k < nbCnt[cur]; k++) {\n            int nb = nbIdx[cur][k];\n            if (visitedTile[Tcell[nb]] == currentToken) continue;\n            candIdxArr[cnum] = nb;\n            candDirArr[cnum] = nbDir[cur][k];\n            cnum++;\n        }\n        if (cnum == 0) break;\n\n        int chosen = -1;\n        if (param.randProb > 0 && ((rng.next() & 1023) < param.randProb)) {\n            chosen = rng.nextInt(cnum);\n        } else {\n            int degs[4];\n            int maxDeg = -1;\n            for (int i = 0; i < cnum; i++) {\n                degs[i] = compute_deg(candIdxArr[i]);\n                if (degs[i] > maxDeg) maxDeg = degs[i];\n            }\n            bool filtered = (param.avoidLevel >= 0 && maxDeg > param.avoidLevel);\n\n            if (param.mode == MIN_DEG) {\n                int bestDeg = 1e9, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    if (d < bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int v = Pcell[candIdxArr[i]];\n                        if (v > bestVal) {\n                            bestVal = v;\n                            chosen = i;\n                        } else if (v == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else if (param.mode == MAX_DEG) {\n                int bestDeg = -1, bestVal = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    if (d > bestDeg) {\n                        bestDeg = d;\n                        bestVal = Pcell[candIdxArr[i]];\n                        chosen = i;\n                    } else if (d == bestDeg) {\n                        int v = Pcell[candIdxArr[i]];\n                        if (v > bestVal) {\n                            bestVal = v;\n                            chosen = i;\n                        } else if (v == bestVal && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            } else { // MAX_VALUE\n                int bestVal = -1, bestDeg = -1;\n                for (int i = 0; i < cnum; i++) {\n                    int d = degs[i];\n                    if (filtered && d <= param.avoidLevel) continue;\n                    int v = Pcell[candIdxArr[i]];\n                    if (v > bestVal) {\n                        bestVal = v;\n                        bestDeg = d;\n                        chosen = i;\n                    } else if (v == bestVal) {\n                        if (d > bestDeg) {\n                            bestDeg = d;\n                            chosen = i;\n                        } else if (d == bestDeg && (rng.next() & 1)) {\n                            chosen = i;\n                        }\n                    }\n                }\n            }\n        }\n        if (chosen == -1) chosen = rng.nextInt(cnum);\n        int nxt = candIdxArr[chosen];\n        visitedTile[Tcell[nxt]] = currentToken;\n        score += Pcell[nxt];\n        mv.push_back(candDirArr[chosen]);\n        cur = nxt;\n    }\n    Path res;\n    res.score = score;\n    res.len = (int)mv.size() + 1;\n    res.moves.assign(mv.begin(), mv.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    int maxTid = -1;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Tcell[idx] = x;\n            if (x > maxTid) maxTid = x;\n        }\n    }\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int x;\n            cin >> x;\n            int idx = i * W + j;\n            Pcell[idx] = x;\n        }\n    }\n    tileCount = maxTid + 1;\n    visitedTile.assign(tileCount, 0);\n    startIdx = si * W + sj;\n\n    // Precompute neighbors\n    for (int r = 0; r < H; r++) {\n        for (int c = 0; c < W; c++) {\n            int idx = r * W + c;\n            int cnt = 0;\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 >= H || nc < 0 || nc >= W) continue;\n                nbIdx[idx][cnt] = nr * W + nc;\n                nbDir[idx][cnt] = dch[d];\n                cnt++;\n            }\n            nbCnt[idx] = cnt;\n        }\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    rng = XorShift(seed);\n\n    vector<Param> params = {\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 30},\n        {1, MIN_DEG, 0},\n        {1, MIN_DEG, 50},\n        {0, MAX_DEG, 0},\n        {0, MAX_DEG, 50},\n        {0, MAX_VALUE, 0},\n        {0, MAX_VALUE, 50},\n        {0, MIN_DEG, 200},\n        {2, MIN_DEG, 0},\n        {0, MIN_DEG, 0},\n        {0, MIN_DEG, 0}\n    };\n\n    Path best;\n    best.score = -1;\n    best.len = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeLimit = startTime + chrono::milliseconds(1950);\n\n    size_t pidx = rng.nextInt((int)params.size());\n    while (chrono::steady_clock::now() < timeLimit) {\n        const Param &param = params[pidx];\n        pidx++;\n        if (pidx >= params.size()) pidx = 0;\n        Path curPath = run_once(param);\n        if (curPath.score > best.score || (curPath.score == best.score && curPath.len > best.len)) {\n            best = std::move(curPath);\n        }\n    }\n\n    cout << best.moves << '\\n';\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Neighbor {\n    int to;\n    int edge;\n    char dir;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int H = 30, W = 30;\n    const int N = H * W;\n    const int EH = H * (W - 1);\n    const int EV = (H - 1) * W;\n    const int E = EH + EV;\n\n    // index tables\n    int h_idx[H][W - 1];\n    int v_idx[H - 1][W];\n    int idx = 0;\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            h_idx[i][j] = idx++;\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            v_idx[i][j] = idx++;\n        }\n    }\n\n    vector<vector<Neighbor>> adj(N);\n    // build graph\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W - 1; j++) {\n            int e = h_idx[i][j];\n            int u = i * W + j;\n            int v = i * W + (j + 1);\n            adj[u].push_back({v, e, 'R'});\n            adj[v].push_back({u, e, 'L'});\n        }\n    }\n    for (int i = 0; i < H - 1; i++) {\n        for (int j = 0; j < W; j++) {\n            int e = v_idx[i][j];\n            int u = i * W + j;\n            int v = (i + 1) * W + j;\n            adj[u].push_back({v, e, 'D'});\n            adj[v].push_back({u, e, 'U'});\n        }\n    }\n\n    vector<double> w(E, 5000.0);\n    vector<int> cnt(E, 0);\n\n    vector<int> rowSplit(H, -1), colSplit(W, -1);\n    vector<double> rowMeanAll(H, 5000.0), rowMeanL(H, 5000.0), rowMeanR(H, 5000.0);\n    vector<double> colMeanAll(W, 5000.0), colMeanT(W, 5000.0), colMeanB(W, 5000.0);\n\n    auto recompute_means_splits = [&](int qidx) {\n        double gSumH = 0.0, gSumV = 0.0;\n        int gCntH = 0, gCntV = 0;\n        for (int e = 0; e < EH; e++) if (cnt[e] > 0) { gSumH += w[e]; gCntH++; }\n        for (int e = EH; e < E; e++) if (cnt[e] > 0) { gSumV += w[e]; gCntV++; }\n        double gMeanH = gCntH ? gSumH / gCntH : 5000.0;\n        double gMeanV = gCntV ? gSumV / gCntV : 5000.0;\n\n        // rows\n        for (int i = 0; i < H; i++) {\n            vector<double> ps(W, 0.0);\n            vector<int> pc(W, 0);\n            for (int j = 0; j < W - 1; j++) {\n                ps[j + 1] = ps[j];\n                pc[j + 1] = pc[j];\n                int e = h_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[j + 1] += w[e];\n                    pc[j + 1] += 1;\n                }\n            }\n            double totalSum = ps[W - 1];\n            int totalCnt = pc[W - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanH;\n            rowMeanAll[i] = meanAll;\n            rowMeanL[i] = rowMeanR[i] = meanAll;\n            rowSplit[i] = -1;\n            if (totalCnt >= 4 && qidx >= 60) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int x = 1; x < W - 1; x++) {\n                    int lc = pc[x];\n                    int rc = totalCnt - lc;\n                    if (lc >= 2 && rc >= 2) {\n                        double ls = ps[x];\n                        double rs = totalSum - ls;\n                        double lm = ls / lc;\n                        double rm = rs / rc;\n                        double diff = fabs(lm - rm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = x;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 400.0) {\n                    rowSplit[i] = bestSplit;\n                    int lc = pc[bestSplit];\n                    int rc = totalCnt - lc;\n                    double ls = ps[bestSplit];\n                    double rs = totalSum - ls;\n                    rowMeanL[i] = lc ? ls / lc : meanAll;\n                    rowMeanR[i] = rc ? rs / rc : meanAll;\n                }\n            }\n        }\n\n        // columns\n        for (int j = 0; j < W; j++) {\n            vector<double> ps(H, 0.0);\n            vector<int> pc(H, 0);\n            for (int i = 0; i < H - 1; i++) {\n                ps[i + 1] = ps[i];\n                pc[i + 1] = pc[i];\n                int e = v_idx[i][j];\n                if (cnt[e] > 0) {\n                    ps[i + 1] += w[e];\n                    pc[i + 1] += 1;\n                }\n            }\n            double totalSum = ps[H - 1];\n            int totalCnt = pc[H - 1];\n            double meanAll = totalCnt ? totalSum / totalCnt : gMeanV;\n            colMeanAll[j] = meanAll;\n            colMeanT[j] = colMeanB[j] = meanAll;\n            colSplit[j] = -1;\n            if (totalCnt >= 4 && qidx >= 60) {\n                int bestSplit = -1;\n                double bestDiff = 0.0;\n                for (int y = 1; y < H - 1; y++) {\n                    int tc = pc[y];\n                    int bc = totalCnt - tc;\n                    if (tc >= 2 && bc >= 2) {\n                        double ts = ps[y];\n                        double bs = totalSum - ts;\n                        double tm = ts / tc;\n                        double bm = bs / bc;\n                        double diff = fabs(tm - bm);\n                        if (diff > bestDiff) {\n                            bestDiff = diff;\n                            bestSplit = y;\n                        }\n                    }\n                }\n                if (bestSplit != -1 && bestDiff > 400.0) {\n                    colSplit[j] = bestSplit;\n                    int tc = pc[bestSplit];\n                    int bc = totalCnt - tc;\n                    double ts = ps[bestSplit];\n                    double bs = totalSum - ts;\n                    colMeanT[j] = tc ? ts / tc : meanAll;\n                    colMeanB[j] = bc ? bs / bc : meanAll;\n                }\n            }\n        }\n    };\n\n    auto smooth_edges = [&]() {\n        for (int i = 0; i < H; i++) {\n            for (int j = 0; j < W - 1; j++) {\n                int e = h_idx[i][j];\n                double pred = (rowSplit[i] == -1) ? rowMeanAll[i] : (j < rowSplit[i] ? rowMeanL[i] : rowMeanR[i]);\n                if (cnt[e] == 0) {\n                    w[e] = pred;\n                } else if (cnt[e] <= 2) {\n                    w[e] = 0.5 * w[e] + 0.5 * pred;\n                }\n            }\n        }\n        for (int j = 0; j < W; j++) {\n            for (int i = 0; i < H - 1; i++) {\n                int e = v_idx[i][j];\n                double pred = (colSplit[j] == -1) ? colMeanAll[j] : (i < colSplit[j] ? colMeanT[j] : colMeanB[j]);\n                if (cnt[e] == 0) {\n                    w[e] = pred;\n                } else if (cnt[e] <= 2) {\n                    w[e] = 0.5 * w[e] + 0.5 * pred;\n                }\n            }\n        }\n    };\n\n    const int EXP_END = 350;\n    const double EXP_BONUS = 3000.0;\n\n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        int s = si * W + sj;\n        int t = ti * W + tj;\n\n        if (q == 0 || q % 20 == 0) {\n            recompute_means_splits(q);\n            smooth_edges();\n        }\n\n        double explore_factor = (q < EXP_END) ? (double)(EXP_END - q) / EXP_END : 0.0;\n\n        // Dijkstra\n        const double INF = 1e100;\n        vector<double> dist(N, INF);\n        vector<int> prev(N, -1), prev_e(N, -1);\n        vector<char> prev_d(N, 0);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n        dist[s] = 0.0;\n        pq.push({0.0, s});\n        while (!pq.empty()) {\n            auto [d, v] = pq.top();\n            pq.pop();\n            if (d != dist[v]) continue;\n            if (v == t) break;\n            for (auto &nb : adj[v]) {\n                double cost = w[nb.edge];\n                if (cnt[nb.edge] == 0) {\n                    // if unknown, rely on predicted mean if available\n                    if (nb.edge < EH) {\n                        int ii = v / W;\n                        int jj = v % W;\n                        if (nb.dir == 'R') jj = jj;\n                        else if (nb.dir == 'L') jj = jj - 1;\n                        double pred = (rowSplit[ii] == -1) ? rowMeanAll[ii] : (jj < rowSplit[ii] ? rowMeanL[ii] : rowMeanR[ii]);\n                        cost = pred;\n                    } else {\n                        int ii = v / W;\n                        int jj = v % W;\n                        if (nb.dir == 'D') ii = ii;\n                        else if (nb.dir == 'U') ii = ii - 1;\n                        double pred = (colSplit[jj] == -1) ? colMeanAll[jj] : (ii < colSplit[jj] ? colMeanT[jj] : colMeanB[jj]);\n                        cost = pred;\n                    }\n                }\n                if (explore_factor > 0.0) {\n                    cost -= EXP_BONUS * explore_factor / sqrt((double)cnt[nb.edge] + 1.0);\n                }\n                if (cost < 1.0) cost = 1.0;\n                double nd = d + cost;\n                if (nd < dist[nb.to]) {\n                    dist[nb.to] = nd;\n                    prev[nb.to] = v;\n                    prev_e[nb.to] = nb.edge;\n                    prev_d[nb.to] = nb.dir;\n                    pq.push({nd, nb.to});\n                }\n            }\n        }\n\n        // reconstruct path\n        string path;\n        vector<int> edges_seq;\n        double pred_len = 0.0;\n        double pred_h = 0.0, pred_v = 0.0;\n        int v = t;\n        while (v != s && v != -1) {\n            int e = prev_e[v];\n            char dch = prev_d[v];\n            if (e < 0) break;\n            path.push_back(dch);\n            edges_seq.push_back(e);\n            pred_len += w[e];\n            if (e < EH) pred_h += w[e]; else pred_v += w[e];\n            v = prev[v];\n        }\n        reverse(path.begin(), path.end());\n        reverse(edges_seq.begin(), edges_seq.end());\n\n        cout << path << '\\n' << flush;\n\n        int obs_int;\n        if (!(cin >> obs_int)) break;\n        double obs_len = obs_int;\n        if (pred_len < 1e-6) pred_len = (double)edges_seq.size() * 5000.0;\n        double error = obs_len - pred_len;\n\n        double base_lr = (q < 200) ? 0.55 : (q < 600 ? 0.4 : 0.3);\n        double ph = pred_h, pv = pred_v;\n        double err_h = error, err_v = 0.0;\n        double total_pred = ph + pv;\n        if (total_pred > 1e-9) {\n            if (ph > 0 && pv > 0) {\n                err_h = error * (ph / total_pred);\n                err_v = error - err_h;\n            } else if (ph <= 0) {\n                err_h = 0.0;\n                err_v = error;\n            } else {\n                err_h = error;\n                err_v = 0.0;\n            }\n        }\n        double denom_h = max(ph, 1e-6);\n        double denom_v = max(pv, 1e-6);\n\n        for (int e : edges_seq) {\n            if (e < EH) {\n                double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n                double contrib = w[e] / denom_h;\n                w[e] += lr * err_h * contrib;\n            } else {\n                double lr = base_lr / sqrt((double)cnt[e] + 1.0);\n                double contrib = w[e] / denom_v;\n                w[e] += lr * err_v * contrib;\n            }\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 9500.0) w[e] = 9500.0;\n            cnt[e]++;\n        }\n\n        if (q % 40 == 39) {\n            recompute_means_splits(q);\n            smooth_edges();\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\n// RNG\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    inline uint32_t next_u32() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return static_cast<uint32_t>(x);\n    }\n    inline int next_int(int n) { return static_cast<int>(next_u32() % n); }\n};\n\nconst int N = 20;\nconst int CELLS = N * N;   // 400\nconst int PL = 800;        // placements per string (400 horiz + 400 vert)\n\nint M;\nvector<string> s;\nvector<int> lens;\nvector<vector<uint8_t>> letters;   // letter indices 0..7\nvector<vector<uint16_t>> cells;    // placement cells\nvector<uint16_t*> cellPtrs;\nvector<uint8_t*> letterPtrs;\n\n// counts for current assignment\nstatic int counts[CELLS][8];\nstatic int totalCnt[CELLS];\n\n// assign placements maximizing matches to matVal; rebuild counts; return satisfied count\nint assignAll(const vector<uint8_t>& matVal, XorShift64& rng) {\n    memset(counts, 0, sizeof(counts));\n    memset(totalCnt, 0, sizeof(totalCnt));\n    int satisfied = 0;\n    for (int i = 0; i < M; ++i) {\n        int len = lens[i];\n        const uint16_t* cp = cellPtrs[i];\n        const uint8_t* lp = letterPtrs[i];\n        int bestMatch = -1;\n        int bestPi = 0;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            for (int p = 0; p < len; ++p) {\n                if (matVal[cp[base + p]] == lp[p]) ++matches;\n            }\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        if (bestMatch == len) ++satisfied;\n        int base = bestPi * len;\n        for (int p = 0; p < len; ++p) {\n            int cell = cp[base + p];\n            int li = lp[p];\n            ++counts[cell][li];\n            ++totalCnt[cell];\n        }\n    }\n    return satisfied;\n}\n\n// build majority matrix (numeric) from counts with random tie-break\nvoid buildMajority(vector<uint8_t>& matVal, XorShift64& rng) {\n    matVal.resize(CELLS);\n    for (int cell = 0; cell < CELLS; ++cell) {\n        if (totalCnt[cell] == 0) {\n            matVal[cell] = (uint8_t)rng.next_int(8);\n        } else {\n            int bestC = counts[cell][0];\n            int bestL = 0;\n            int tie = 1;\n            for (int l = 1; l < 8; ++l) {\n                if (counts[cell][l] > bestC) {\n                    bestC = counts[cell][l];\n                    bestL = l;\n                    tie = 1;\n                } else if (counts[cell][l] == bestC) {\n                    ++tie;\n                    if (rng.next_u32() % tie == 0) bestL = l;\n                }\n            }\n            matVal[cell] = (uint8_t)bestL;\n        }\n    }\n}\n\n// greedy placement with '.' wildcard\nvoid greedyTrial(const vector<int>& order, XorShift64& rng, vector<char>& outMat) {\n    vector<char> mat(CELLS, '.');\n    for (int idx : order) {\n        int len = lens[idx];\n        const uint16_t* cp = cellPtrs[idx];\n        const char* sp = s[idx].c_str();\n        int bestMatch = -1;\n        int bestPi = -1;\n        int tie = 0;\n        for (int pi = 0; pi < PL; ++pi) {\n            int base = pi * len;\n            int matches = 0;\n            bool ok = true;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char mc = mat[cell];\n                char sc = sp[p];\n                if (mc == sc) {\n                    ++matches;\n                } else if (mc == '.') {\n                    // ok\n                } else {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            if (matches > bestMatch) {\n                bestMatch = matches;\n                bestPi = pi;\n                tie = 1;\n            } else if (matches == bestMatch) {\n                ++tie;\n                if (rng.next_u32() % tie == 0) bestPi = pi;\n            }\n        }\n        if (bestPi >= 0) {\n            int base = bestPi * len;\n            for (int p = 0; p < len; ++p) {\n                int cell = cp[base + p];\n                char sc = sp[p];\n                if (mat[cell] == '.') mat[cell] = sc;\n            }\n        }\n    }\n    outMat.swap(mat);\n}\n\n// fill '.' with random letters according to freq; produce numeric matrix\nvoid fillDotsToNumeric(vector<char>& mat, const vector<int>& freq, XorShift64& rng, vector<uint8_t>& matVal) {\n    int freqSum = 0;\n    for (int f : freq) freqSum += f;\n    matVal.resize(CELLS);\n    for (int i = 0; i < CELLS; ++i) {\n        char c = mat[i];\n        if (c == '.') {\n            int r = rng.next_int(freqSum);\n            int acc = 0;\n            int l = 0;\n            for (; l < 8; ++l) {\n                acc += freq[l];\n                if (r < acc) break;\n            }\n            if (l >= 8) l = rng.next_int(8);\n            mat[i] = char('A' + l);\n            matVal[i] = (uint8_t)l;\n        } else {\n            matVal[i] = (uint8_t)(c - 'A');\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N_in;\n    if (!(cin >> N_in >> M)) return 0;\n    s.resize(M);\n    lens.resize(M);\n    letters.resize(M);\n    cells.resize(M);\n    vector<int> freq(8, 0);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n        lens[i] = (int)s[i].size();\n        letters[i].resize(lens[i]);\n        for (int p = 0; p < lens[i]; ++p) {\n            letters[i][p] = (uint8_t)(s[i][p] - 'A');\n            ++freq[letters[i][p]];\n        }\n        cells[i].resize(PL * lens[i]);\n        int len = lens[i];\n        // horizontal placements 0..399\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int cc = (c + p) % N;\n                    cells[i][base + p] = (uint16_t)(r * N + cc);\n                }\n            }\n        }\n        // vertical placements 400..799\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                int pi = 400 + r * N + c;\n                int base = pi * len;\n                for (int p = 0; p < len; ++p) {\n                    int rr = (r + p) % N;\n                    cells[i][base + p] = (uint16_t)(rr * N + c);\n                }\n            }\n        }\n    }\n    cellPtrs.resize(M);\n    letterPtrs.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cellPtrs[i] = cells[i].data();\n        letterPtrs[i] = letters[i].data();\n    }\n\n    uint64_t seed = chrono::steady_clock::now().time_since_epoch().count();\n    XorShift64 rng(seed);\n\n    auto timeStart = chrono::steady_clock::now();\n    auto elapsedSec = [&]() -> double {\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - timeStart).count();\n    };\n    const double TIME_LIMIT = 2.9;\n    const double GREEDY_TIME = 1.0;\n\n    vector<uint8_t> bestMatVal(CELLS);\n    int bestSat = -1;\n\n    // Greedy initialization with length-descending order\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (lens[a] != lens[b]) return lens[a] > lens[b];\n        return a < b;\n    });\n    vector<char> matC;\n    vector<uint8_t> matVal;\n    greedyTrial(order, rng, matC);\n    fillDotsToNumeric(matC, freq, rng, matVal);\n    int sat = assignAll(matVal, rng);\n    if (sat > bestSat) {\n        bestSat = sat;\n        bestMatVal = matVal;\n    }\n\n    // Random greedy trials within time budget\n    vector<int> randOrder(M);\n    iota(randOrder.begin(), randOrder.end(), 0);\n    while (elapsedSec() < GREEDY_TIME) {\n        for (int i = M - 1; i > 0; --i) {\n            int j = rng.next_int(i + 1);\n            swap(randOrder[i], randOrder[j]);\n        }\n        greedyTrial(randOrder, rng, matC);\n        fillDotsToNumeric(matC, freq, rng, matVal);\n        sat = assignAll(matVal, rng);\n        if (sat > bestSat) {\n            bestSat = sat;\n            bestMatVal = matVal;\n        }\n    }\n\n    // EM-like iterations until time limit\n    matVal = bestMatVal;\n    sat = assignAll(matVal, rng);\n    if (sat > bestSat) {\n        bestSat = sat;\n        bestMatVal = matVal;\n    }\n    int noImp = 0;\n    while (elapsedSec() < TIME_LIMIT) {\n        vector<uint8_t> newMatVal;\n        buildMajority(newMatVal, rng);\n        if (noImp >= 6) {\n            int changes = 6;\n            for (int k = 0; k < changes; ++k) {\n                int cell = rng.next_int(CELLS);\n                newMatVal[cell] = (uint8_t)rng.next_int(8);\n            }\n            noImp = 0;\n        }\n        matVal.swap(newMatVal);\n        sat = assignAll(matVal, rng);\n        if (sat > bestSat) {\n            bestSat = sat;\n            bestMatVal = matVal;\n            noImp = 0;\n            if (bestSat == M) break;\n        } else {\n            ++noImp;\n        }\n    }\n\n    // Output bestMatVal as characters\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            cout << char('A' + bestMatVal[r * N + c]);\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct CoverState {\n    int coveredCount;\n    vector<char> covered;\n    vector<char> rowCovered, colCovered;\n    vector<int> uncoveredRow, uncoveredCol;\n    CoverState(int R, int rsz, int csz, const vector<int> &rowSize, const vector<int> &colSize) {\n        coveredCount = 0;\n        covered.assign(R, 0);\n        rowCovered.assign(rsz, 0);\n        colCovered.assign(csz, 0);\n        uncoveredRow = rowSize;\n        uncoveredCol = colSize;\n    }\n};\n\nconst int INF = 1e9;\n\nvoid coverFrom(int u,\n               CoverState &st,\n               const vector<int> &row_id,\n               const vector<int> &col_id,\n               const vector<vector<int>> &row_nodes,\n               const vector<vector<int>> &col_nodes) {\n    int rid = row_id[u];\n    if (!st.rowCovered[rid]) {\n        st.rowCovered[rid] = 1;\n        for (int v : row_nodes[rid]) {\n            if (!st.covered[v]) {\n                st.covered[v] = 1;\n                st.coveredCount++;\n                st.uncoveredRow[row_id[v]]--;\n                st.uncoveredCol[col_id[v]]--;\n            }\n        }\n    }\n    int cid = col_id[u];\n    if (!st.colCovered[cid]) {\n        st.colCovered[cid] = 1;\n        for (int v : col_nodes[cid]) {\n            if (!st.covered[v]) {\n                st.covered[v] = 1;\n                st.coveredCount++;\n                st.uncoveredRow[row_id[v]]--;\n                st.uncoveredCol[col_id[v]]--;\n            }\n        }\n    }\n}\n\nvoid dijkstra(int src,\n              const vector<vector<pair<int, int>>> &adj,\n              vector<int> &dist,\n              vector<int> &prev) {\n    int n = adj.size();\n    dist.assign(n, INF);\n    prev.assign(n, -1);\n    dist[src] = 0;\n    using P = pair<int, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            int v = e.first, c = e.second;\n            int nd = d + c;\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                pq.push({nd, v});\n            }\n        }\n    }\n}\n\nvector<int> reconstructPath(int src, int dst, const vector<int> &prev) {\n    vector<int> path;\n    int v = dst;\n    if (v != src && prev[v] == -1) return path;\n    while (true) {\n        path.push_back(v);\n        if (v == src) break;\n        v = prev[v];\n        if (v == -1) {\n            path.clear();\n            return path;\n        }\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nchar dirFromDiff(const pair<int, int> &a, const pair<int, int> &b) {\n    if (b.first == a.first - 1) return 'U';\n    if (b.first == a.first + 1) return 'D';\n    if (b.second == a.second - 1) return 'L';\n    return 'R';\n}\n\nstruct RouteResult {\n    string route;\n    long long cost;\n    bool full;\n};\n\nRouteResult buildRouteGreedy(int start,\n                             int R,\n                             const vector<int> &row_id,\n                             const vector<int> &col_id,\n                             const vector<vector<int>> &row_nodes,\n                             const vector<vector<int>> &col_nodes,\n                             const vector<vector<pair<int, int>>> &adj,\n                             const vector<pair<int, int>> &pos,\n                             const vector<int> &w) {\n    vector<int> rowSize(row_nodes.size()), colSize(col_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) rowSize[i] = (int)row_nodes[i].size();\n    for (size_t i = 0; i < col_nodes.size(); i++) colSize[i] = (int)col_nodes[i].size();\n    CoverState st(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, st, row_id, col_id, row_nodes, col_nodes);\n\n    string route;\n    long long cost = 0;\n    int current = start;\n    vector<int> dist, prev;\n    int iter_limit = 500;\n    int iter = 0;\n    while (st.coveredCount < R && iter < iter_limit) {\n        iter++;\n        dijkstra(current, adj, dist, prev);\n        int best = -1, bestGain = -1, bestDist = INF;\n        double bestScore = -1.0;\n        for (int u = 0; u < R; u++) {\n            int gain = st.uncoveredRow[row_id[u]] + st.uncoveredCol[col_id[u]] - (st.covered[u] ? 0 : 1);\n            if (gain <= 0) continue;\n            int d = dist[u];\n            if (d >= INF) continue;\n            double score = (double)gain / (double)(d + 1);\n            if (score > bestScore || (score == bestScore && (gain > bestGain || (gain == bestGain && d < bestDist)))) {\n                bestScore = score;\n                bestGain = gain;\n                bestDist = d;\n                best = u;\n            }\n        }\n        if (best == -1) break;\n        vector<int> path = reconstructPath(current, best, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n            current = v;\n            coverFrom(v, st, row_id, col_id, row_nodes, col_nodes);\n        }\n    }\n    // fallback nearest uncovered\n    while (st.coveredCount < R) {\n        dijkstra(current, adj, dist, prev);\n        int target = -1, bestD = INF;\n        for (int u = 0; u < R; u++) {\n            if (st.covered[u]) continue;\n            if (dist[u] < bestD) {\n                bestD = dist[u];\n                target = u;\n            }\n        }\n        if (target == -1 || bestD == INF) break;\n        vector<int> path = reconstructPath(current, target, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n            current = v;\n            coverFrom(v, st, row_id, col_id, row_nodes, col_nodes);\n        }\n    }\n    // return to start\n    if (current != start) {\n        dijkstra(current, adj, dist, prev);\n        vector<int> path = reconstructPath(current, start, prev);\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            route.push_back(dirFromDiff(pos[u], pos[v]));\n            cost += w[v];\n        }\n    }\n    return {route, cost, st.coveredCount == R};\n}\n\nRouteResult buildRouteSetCoverTSP(int start,\n                                  int R,\n                                  const vector<int> &row_id,\n                                  const vector<int> &col_id,\n                                  const vector<vector<int>> &row_nodes,\n                                  const vector<vector<int>> &col_nodes,\n                                  const vector<vector<pair<int, int>>> &adj,\n                                  const vector<pair<int, int>> &pos,\n                                  const vector<int> &w) {\n    vector<int> rowSize(row_nodes.size()), colSize(col_nodes.size());\n    for (size_t i = 0; i < row_nodes.size(); i++) rowSize[i] = (int)row_nodes[i].size();\n    for (size_t i = 0; i < col_nodes.size(); i++) colSize[i] = (int)col_nodes[i].size();\n    CoverState stSel(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, stSel, row_id, col_id, row_nodes, col_nodes);\n    vector<int> targets;\n    // greedy set cover\n    while (stSel.coveredCount < R) {\n        int best = -1;\n        int bestGain = -1;\n        for (int u = 0; u < R; u++) {\n            int gain = stSel.uncoveredRow[row_id[u]] + stSel.uncoveredCol[col_id[u]] - (stSel.covered[u] ? 0 : 1);\n            if (gain > bestGain) {\n                bestGain = gain;\n                best = u;\n            }\n        }\n        if (best == -1 || bestGain <= 0) break;\n        targets.push_back(best);\n        coverFrom(best, stSel, row_id, col_id, row_nodes, col_nodes);\n    }\n    // build nodes list\n    vector<char> used(R, 0);\n    vector<int> nodesList;\n    nodesList.push_back(start);\n    used[start] = 1;\n    for (int u : targets) {\n        if (!used[u]) {\n            used[u] = 1;\n            nodesList.push_back(u);\n        }\n    }\n    int M = nodesList.size();\n    if (M == 1) {\n        return {\"\", 0, stSel.coveredCount == R};\n    }\n\n    // distance matrix\n    vector<vector<int>> distMat(M, vector<int>(M, INF));\n    vector<int> dist, prev;\n    for (int i = 0; i < M; i++) {\n        dijkstra(nodesList[i], adj, dist, prev);\n        for (int j = 0; j < M; j++) {\n            distMat[i][j] = dist[nodesList[j]];\n        }\n    }\n\n    // initial tour: nearest neighbor\n    vector<int> tour;\n    tour.reserve(M + 1);\n    vector<char> vis(M, 0);\n    int curIdx = 0;\n    tour.push_back(curIdx);\n    vis[curIdx] = 1;\n    for (int cnt = 1; cnt < M; cnt++) {\n        int nxt = -1, bestD = INF;\n        for (int j = 0; j < M; j++) {\n            if (!vis[j] && distMat[curIdx][j] < bestD) {\n                bestD = distMat[curIdx][j];\n                nxt = j;\n            }\n        }\n        if (nxt == -1) {\n            for (int j = 0; j < M; j++) {\n                if (!vis[j]) {\n                    nxt = j;\n                    break;\n                }\n            }\n        }\n        tour.push_back(nxt);\n        vis[nxt] = 1;\n        curIdx = nxt;\n    }\n    tour.push_back(0);  // return to start\n\n    // 2-opt improvement\n    bool improved = true;\n    int len = tour.size();\n    while (improved) {\n        improved = false;\n        for (int i = 1; i < len - 2; i++) {\n            for (int j = i + 1; j < len - 1; j++) {\n                int a = tour[i - 1], b = tour[i], c = tour[j], d = tour[j + 1];\n                int curCost = distMat[a][b] + distMat[c][d];\n                int newCost = distMat[a][c] + distMat[b][d];\n                if (newCost < curCost) {\n                    reverse(tour.begin() + i, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // build route\n    CoverState stRoute(R, row_nodes.size(), col_nodes.size(), rowSize, colSize);\n    coverFrom(start, stRoute, row_id, col_id, row_nodes, col_nodes);\n    string routeStr;\n    long long costRoute = 0;\n    int currentNode = start;\n    for (size_t idx = 1; idx < tour.size(); idx++) {\n        int nextNode = nodesList[tour[idx]];\n        dijkstra(currentNode, adj, dist, prev);\n        vector<int> path = reconstructPath(currentNode, nextNode, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n            coverFrom(v, stRoute, row_id, col_id, row_nodes, col_nodes);\n        }\n        currentNode = nextNode;\n    }\n\n    // if not fully covered, fallback to greedy nearest uncovered\n    while (stRoute.coveredCount < R) {\n        dijkstra(currentNode, adj, dist, prev);\n        int target = -1, bestD = INF;\n        for (int u = 0; u < R; u++) {\n            if (stRoute.covered[u]) continue;\n            if (dist[u] < bestD) {\n                bestD = dist[u];\n                target = u;\n            }\n        }\n        if (target == -1 || bestD == INF) break;\n        vector<int> path = reconstructPath(currentNode, target, prev);\n        if (path.empty()) break;\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n            coverFrom(v, stRoute, row_id, col_id, row_nodes, col_nodes);\n        }\n        currentNode = target;\n    }\n\n    // ensure return to start\n    if (currentNode != start) {\n        dijkstra(currentNode, adj, dist, prev);\n        vector<int> path = reconstructPath(currentNode, start, prev);\n        for (size_t k = 1; k < path.size(); k++) {\n            int u = path[k - 1], v = path[k];\n            routeStr.push_back(dirFromDiff(pos[u], pos[v]));\n            costRoute += w[v];\n        }\n    }\n\n    return {routeStr, costRoute, stRoute.coveredCount == R};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if (!(cin >> N >> si >> sj)) return 0;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n\n    vector<vector<int>> id(N, vector<int>(N, -1));\n    vector<pair<int, int>> pos;\n    vector<int> w;\n    int R = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                id[i][j] = R++;\n                pos.emplace_back(i, j);\n                w.push_back(grid[i][j] - '0');\n            }\n        }\n    }\n    if (R == 0) {\n        cout << \"\\n\";\n        return 0;\n    }\n\n    // adjacency\n    vector<vector<pair<int, int>>> adj(R);\n    int dx[4] = {-1, 1, 0, 0};\n    int dy[4] = {0, 0, -1, 1};\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = id[i][j];\n            if (u == -1) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int ni = i + dx[dir], nj = j + dy[dir];\n                if (0 <= ni && ni < N && 0 <= nj && nj < N) {\n                    int v = id[ni][nj];\n                    if (v != -1) {\n                        adj[u].push_back({v, w[v]});\n                    }\n                }\n            }\n        }\n    }\n\n    // row segments\n    vector<int> row_id(R, -1);\n    vector<vector<int>> row_nodes;\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (id[i][j] != -1) {\n                int segId = (int)row_nodes.size();\n                vector<int> seg;\n                while (j < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    row_id[u] = segId;\n                    seg.push_back(u);\n                    j++;\n                }\n                row_nodes.push_back(move(seg));\n            } else {\n                j++;\n            }\n        }\n    }\n    // column segments\n    vector<int> col_id(R, -1);\n    vector<vector<int>> col_nodes;\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (id[i][j] != -1) {\n                int segId = (int)col_nodes.size();\n                vector<int> seg;\n                while (i < N && id[i][j] != -1) {\n                    int u = id[i][j];\n                    col_id[u] = segId;\n                    seg.push_back(u);\n                    i++;\n                }\n                col_nodes.push_back(move(seg));\n            } else {\n                i++;\n            }\n        }\n    }\n\n    int start = id[si][sj];\n    RouteResult ra = buildRouteGreedy(start, R, row_id, col_id, row_nodes, col_nodes, adj, pos, w);\n    RouteResult rb = buildRouteSetCoverTSP(start, R, row_id, col_id, row_nodes, col_nodes, adj, pos, w);\n\n    string output;\n    if (ra.full && rb.full) {\n        if (rb.cost < ra.cost) output = rb.route;\n        else output = ra.route;\n    } else if (rb.full) {\n        output = rb.route;\n    } else {\n        output = ra.route;\n    }\n    cout << output << \"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Hungarian algorithm for min-cost assignment (rows <= cols)\nvector<int> hungarian(const vector<vector<double>>& a) {\n    int n = (int)a.size();\n    int m = (int)a[0].size();\n    vector<double> u(n + 1, 0), v(m + 1, 0);\n    vector<int> p(m + 1, 0), way(m + 1, 0);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<double> minv(m + 1, 1e18);\n        vector<char> used(m + 1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0];\n            double delta = 1e18;\n            int j1 = 0;\n            for (int j = 1; j <= m; j++) if (!used[j]) {\n                double cur = a[i0 - 1][j - 1] - u[i0] - v[j];\n                if (cur < minv[j]) {\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if (minv[j] < delta) {\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for (int j = 0; j <= m; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    vector<int> assign(n, -1);\n    for (int j = 1; j <= m; j++) {\n        if (p[j] != 0) assign[p[j] - 1] = j - 1;\n    }\n    return assign;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> diff_sum(N, 0);\n    for (int i = 0; i < N; i++) {\n        int s = 0;\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n            s += d[i][k];\n        }\n        diff_sum[i] = s;\n    }\n    vector<vector<int>> adj(N);\n    vector<int> indeg(N, 0), outdeg(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        --u; --v;\n        adj[u].push_back(v);\n        indeg[v]++;\n        outdeg[u]++;\n    }\n    // compute height (longest path length) and weighted height by diff_sum\n    vector<int> height(N, 0);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return a > b; }); // descending id ~ topological due to u<v\n    for (int idx = 0; idx < N; idx++) {\n        int i = order[idx];\n        int h = 0;\n        for (int v : adj[i]) h = max(h, height[v] + 1);\n        height[i] = h;\n    }\n    vector<int> wheight(N, 0);\n    for (int idx = 0; idx < N; idx++) {\n        int i = order[idx];\n        int w = diff_sum[i];\n        for (int v : adj[i]) w = max(w, diff_sum[i] + wheight[v]);\n        wheight[i] = w;\n    }\n\n    vector<int> task_status(N, 0); // 0 not started,1 working,2 done\n    vector<int> worker_status(M, -1);\n    vector<int> worker_start_day(M, -1);\n    vector<int> completed_count(M, 0);\n\n    // initial skill estimates\n    vector<double> mean_d(K, 0.0);\n    for (int k = 0; k < K; k++) {\n        long long s = 0;\n        for (int i = 0; i < N; i++) s += d[i][k];\n        mean_d[k] = (double)s / N;\n    }\n    std::mt19937 rng(123456789);\n    std::uniform_real_distribution<double> uni_factor(1.2, 1.8);\n    vector<vector<double>> s_hat(M, vector<double>(K, 0.0));\n    for (int j = 0; j < M; j++) {\n        double f = uni_factor(rng);\n        for (int k = 0; k < K; k++) s_hat[j][k] = mean_d[k] * f;\n    }\n    vector<double> bias_mul(M, 1.0);\n\n    int day = 1;\n    const int MAX_CAND = 300;\n    const int EXP_LIMIT = 2;\n    const double OUT_W = 0.45;\n    const double DIFF_W = 0.01;\n    const double WHEIGHT_W = 0.02;\n    const double DENOM_SHIFT = 0.7;\n    const double LR_BASE = 0.45;\n    const double LR_MIN = 0.03;\n    const double BIAS_ALPHA = 0.15;\n\n    while (true) {\n        // gather ready tasks\n        vector<int> ready;\n        ready.reserve(N);\n        for (int i = 0; i < N; i++) {\n            if (task_status[i] == 0 && indeg[i] == 0) {\n                ready.push_back(i);\n            }\n        }\n        sort(ready.begin(), ready.end(), [&](int a, int b) {\n            if (height[a] != height[b]) return height[a] > height[b];\n            if (outdeg[a] != outdeg[b]) return outdeg[a] > outdeg[b];\n            if (diff_sum[a] != diff_sum[b]) return diff_sum[a] > diff_sum[b];\n            return a < b;\n        });\n        if ((int)ready.size() > MAX_CAND) ready.resize(MAX_CAND);\n\n        vector<int> idle_workers;\n        idle_workers.reserve(M);\n        for (int w = 0; w < M; w++) if (worker_status[w] == -1) idle_workers.push_back(w);\n\n        vector<pair<int,int>> assignments;\n        vector<char> used_task(N, 0);\n\n        // exploration for inexperienced workers\n        if (!idle_workers.empty() && !ready.empty()) {\n            vector<int> new_idle;\n            for (int w : idle_workers) {\n                if (completed_count[w] < EXP_LIMIT) {\n                    int best_t = -1;\n                    double best_pred = 1e18;\n                    for (int t : ready) {\n                        if (used_task[t]) continue;\n                        if (task_status[t] != 0) continue;\n                        double pred = 0.0;\n                        for (int k = 0; k < K; k++) {\n                            double diff = d[t][k] - s_hat[w][k];\n                            if (diff > 0) pred += diff;\n                        }\n                        pred *= bias_mul[w];\n                        if (pred < 1.0) pred = 1.0;\n                        if (pred < best_pred) {\n                            best_pred = pred;\n                            best_t = t;\n                        }\n                    }\n                    if (best_t != -1) {\n                        assignments.push_back({w, best_t});\n                        worker_status[w] = best_t;\n                        worker_start_day[w] = day;\n                        task_status[best_t] = 1;\n                        used_task[best_t] = 1;\n                    } else new_idle.push_back(w);\n                } else new_idle.push_back(w);\n            }\n            idle_workers.swap(new_idle);\n        }\n\n        // remaining ready tasks\n        vector<int> ready_remain;\n        ready_remain.reserve(ready.size());\n        for (int t : ready) if (!used_task[t]) ready_remain.push_back(t);\n\n        int W = (int)idle_workers.size();\n        int C = (int)ready_remain.size();\n        if (W > 0 && C > 0) {\n            int cols = max(C, W);\n            vector<vector<double>> cost(W, vector<double>(cols, 0.0));\n            for (int i = 0; i < W; i++) {\n                int w = idle_workers[i];\n                for (int j = 0; j < C; j++) {\n                    int t = ready_remain[j];\n                    double pred = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        double diff = d[t][k] - s_hat[w][k];\n                        if (diff > 0) pred += diff;\n                    }\n                    double t_pred = pred * bias_mul[w];\n                    if (t_pred < 1.0) t_pred = 1.0;\n                    double hterm = height[t] + OUT_W * outdeg[t] + DIFF_W * diff_sum[t] + WHEIGHT_W * wheight[t];\n                    double score = hterm / (t_pred + DENOM_SHIFT);\n                    cost[i][j] = -score;\n                }\n                for (int j = C; j < cols; j++) cost[i][j] = 0.0; // dummy\n            }\n            vector<int> assign_idx = hungarian(cost);\n            for (int i = 0; i < W; i++) {\n                int j = assign_idx[i];\n                if (j >= 0 && j < C) {\n                    int w = idle_workers[i];\n                    int t = ready_remain[j];\n                    if (task_status[t] == 0) {\n                        assignments.push_back({w, t});\n                        worker_status[w] = t;\n                        worker_start_day[w] = day;\n                        task_status[t] = 1;\n                    }\n                }\n            }\n        }\n\n        // output\n        cout << assignments.size();\n        for (auto &p : assignments) {\n            cout << \" \" << (p.first + 1) << \" \" << (p.second + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n\n        // feedback\n        int nfin;\n        if (!(cin >> nfin)) break;\n        if (nfin == -1) break;\n        vector<int> fs(nfin);\n        for (int i = 0; i < nfin; i++) cin >> fs[i];\n        for (int idx = 0; idx < nfin; idx++) {\n            int w = fs[idx] - 1;\n            int tid = worker_status[w];\n            if (tid < 0) continue;\n            int duration = day - worker_start_day[w] + 1;\n            task_status[tid] = 2;\n            completed_count[w]++;\n\n            // update indegrees\n            for (int v : adj[tid]) indeg[v]--;\n\n            double actual_w = max(0.0, (double)duration - 1.0);\n            double w_pred = 0.0;\n            vector<int> active;\n            active.reserve(K);\n            for (int k = 0; k < K; k++) {\n                double diff = d[tid][k] - s_hat[w][k];\n                if (diff > 0) {\n                    w_pred += diff;\n                    active.push_back(k);\n                }\n            }\n            // update bias\n            double ratio = (actual_w + 1.0) / (w_pred + 1.0);\n            if (ratio < 0.5) ratio = 0.5;\n            if (ratio > 2.0) ratio = 2.0;\n            bias_mul[w] = (1.0 - BIAS_ALPHA) * bias_mul[w] + BIAS_ALPHA * ratio;\n\n            double lr = LR_BASE / sqrt((double)completed_count[w]);\n            if (lr < LR_MIN) lr = LR_MIN;\n            if (!active.empty()) {\n                if (w_pred < 1e-9) w_pred = 1e-9;\n                double factor = lr * (w_pred - actual_w);\n                for (int k : active) {\n                    double weight = (d[tid][k] - s_hat[w][k]) / w_pred;\n                    if (weight < 0) weight = 0;\n                    s_hat[w][k] += factor * weight;\n                    if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                    if (s_hat[w][k] > 200) s_hat[w][k] = 200;\n                }\n            } else {\n                if (actual_w > 0.0) {\n                    vector<int> idxs(K);\n                    iota(idxs.begin(), idxs.end(), 0);\n                    sort(idxs.begin(), idxs.end(), [&](int a, int b){ return d[tid][a] > d[tid][b]; });\n                    int use = min(3, K);\n                    double delta = lr * actual_w / use;\n                    for (int i = 0; i < use; i++) {\n                        int k = idxs[i];\n                        s_hat[w][k] -= delta;\n                        if (s_hat[w][k] < 0) s_hat[w][k] = 0;\n                    }\n                }\n            }\n            worker_status[w] = -1;\n        }\n        day++;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int NORD = 1000;\nconst int CHOOSE = 50;\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\n\nconst double TOTAL_LIMIT = 1.90;\nconst double RESERVE_TIME = 0.20;\nconst int GRID_STEP = 100;\nconst int RANDOM_SEEDS = 150;\nconst int POOL_SIZE = 300;\n\nint ax[NORD], byy[NORD], cx[NORD], dy[NORD];\ndouble midx[NORD], midy[NORD];\n\ninline int mdist(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Greedy nearest feasible route cost for a subset (0-based indices)\nlong long nearest_cost(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int done = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    long long total = 0;\n    while (done < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        int tx = 0, ty = 0;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (status[i] == 2) continue;\n            int x = (status[i] == 0 ? px[i] : qx[i]);\n            int y = (status[i] == 0 ? py[i] : qy[i]);\n            int d = abs(curx - x) + abs(cury - y);\n            if (d < bestd) { bestd = d; best = i; tx = x; ty = y; }\n        }\n        total += bestd;\n        curx = tx; cury = ty;\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; done++; }\n    }\n    total += abs(curx - DEPOT_X) + abs(cury - DEPOT_Y);\n    return total;\n}\n\n// Build sequences of node indices (0..99) for various heuristics\nvector<int> route_nearest_seq(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    char status[CHOOSE];\n    memset(status, 0, sizeof(status));\n    int done = 0;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    vector<int> seq;\n    seq.reserve(CHOOSE * 2);\n    while (done < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        int tx = 0, ty = 0;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (status[i] == 2) continue;\n            int x = (status[i] == 0 ? px[i] : qx[i]);\n            int y = (status[i] == 0 ? py[i] : qy[i]);\n            int d = abs(curx - x) + abs(cury - y);\n            if (d < bestd) { bestd = d; best = i; tx = x; ty = y; }\n        }\n        curx = tx; cury = ty;\n        if (status[best] == 0) seq.push_back(best);\n        else seq.push_back(best + CHOOSE);\n        if (status[best] == 0) status[best] = 1;\n        else { status[best] = 2; done++; }\n    }\n    return seq;\n}\n\n// Pickup then immediate delivery\nvector<int> route_immediate_seq(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool rem[CHOOSE];\n    memset(rem, 1, sizeof(bool) * CHOOSE);\n    int remaining = CHOOSE;\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    vector<int> seq;\n    seq.reserve(CHOOSE * 2);\n    while (remaining > 0) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (!rem[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        seq.push_back(best);\n        seq.push_back(best + CHOOSE);\n        curx = qx[best]; cury = qy[best];\n        rem[best] = false;\n        remaining--;\n    }\n    return seq;\n}\n\n// Pick all, then deliver all\nvector<int> route_pickdrop_seq(const array<int, CHOOSE>& subset) {\n    int px[CHOOSE], py[CHOOSE], qx[CHOOSE], qy[CHOOSE];\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = subset[i];\n        px[i] = ax[id];\n        py[i] = byy[id];\n        qx[i] = cx[id];\n        qy[i] = dy[id];\n    }\n    bool picked[CHOOSE], deliv[CHOOSE];\n    memset(picked, 0, sizeof(picked));\n    memset(deliv, 0, sizeof(deliv));\n    int curx = DEPOT_X, cury = DEPOT_Y;\n    vector<int> seq;\n    seq.reserve(CHOOSE * 2);\n    int pcnt = 0, dcnt = 0;\n    while (pcnt < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (picked[i]) continue;\n            int d = abs(curx - px[i]) + abs(cury - py[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        seq.push_back(best);\n        curx = px[best]; cury = py[best];\n        picked[best] = true; pcnt++;\n    }\n    while (dcnt < CHOOSE) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < CHOOSE; i++) {\n            if (deliv[i]) continue;\n            int d = abs(curx - qx[i]) + abs(cury - qy[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        seq.push_back(best + CHOOSE);\n        curx = qx[best]; cury = qy[best];\n        deliv[best] = true; dcnt++;\n    }\n    return seq;\n}\n\n// Cost of a sequence using precomputed matrices\nlong long seq_cost(const vector<int>& seq, const vector<vector<int>>& distMat, const vector<int>& distDepot) {\n    long long cost = 0;\n    int n = (int)seq.size();\n    cost += distDepot[seq[0]];\n    for (int i = 0; i < n - 1; i++) {\n        cost += distMat[seq[i]][seq[i + 1]];\n    }\n    cost += distDepot[seq.back()];\n    return cost;\n}\n\n// Local improvement: relocate pickup-delivery pair\nvoid local_optimize(vector<int>& seq, const vector<vector<int>>& distMat, const vector<int>& distDepot, mt19937& rng, chrono::steady_clock::time_point end_time) {\n    int n = (int)seq.size();\n    vector<int> posPick(CHOOSE), posDrop(CHOOSE);\n    auto recompute = [&]() {\n        for (int i = 0; i < n; i++) {\n            int node = seq[i];\n            if (node < CHOOSE) posPick[node] = i;\n            else posDrop[node - CHOOSE] = i;\n        }\n    };\n    recompute();\n    long long curCost = seq_cost(seq, distMat, distDepot);\n    const int MAX_IT = 7000;\n    for (int it = 0; it < MAX_IT; it++) {\n        if ((it & 0x1FF) == 0) {\n            if (chrono::steady_clock::now() >= end_time) break;\n        }\n        int ord = rng() % CHOOSE;\n        int ppos_old = posPick[ord];\n        int dpos_old = posDrop[ord];\n        if (ppos_old > dpos_old) continue;\n        vector<int> rem;\n        rem.reserve(n - 2);\n        for (int i = 0; i < n; i++) {\n            if (i == ppos_old || i == dpos_old) continue;\n            rem.push_back(seq[i]);\n        }\n        int lenRem = n - 2;\n        int ppos_new = rng() % (lenRem + 1);\n        int dpos_new = rng() % (lenRem + 2);\n        if (dpos_new < ppos_new) dpos_new = ppos_new;\n        vector<int> newSeq;\n        newSeq.reserve(n);\n        bool insP = false, insD = false;\n        for (int i = 0; i <= lenRem; i++) {\n            if (!insP && (int)newSeq.size() == ppos_new) {\n                newSeq.push_back(ord);\n                insP = true;\n            }\n            if (!insD && (int)newSeq.size() == dpos_new) {\n                newSeq.push_back(ord + CHOOSE);\n                insD = true;\n            }\n            if (i == lenRem) break;\n            newSeq.push_back(rem[i]);\n        }\n        if (!insP) newSeq.push_back(ord);\n        if (!insD) newSeq.push_back(ord + CHOOSE);\n        long long newCost = seq_cost(newSeq, distMat, distDepot);\n        if (newCost < curCost) {\n            seq.swap(newSeq);\n            curCost = newCost;\n            recompute();\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for (int i = 0; i < NORD; i++) {\n        if (!(cin >> ax[i] >> byy[i] >> cx[i] >> dy[i])) return 0;\n        midx[i] = 0.5 * (ax[i] + cx[i]);\n        midy[i] = 0.5 * (byy[i] + dy[i]);\n    }\n\n    auto time_start = chrono::steady_clock::now();\n    auto total_end = time_start + chrono::duration_cast<chrono::steady_clock::duration>(chrono::duration<double>(TOTAL_LIMIT));\n    auto sa_end = time_start + chrono::duration_cast<chrono::steady_clock::duration>(chrono::duration<double>(TOTAL_LIMIT - RESERVE_TIME));\n\n    // Base costs\n    vector<long long> baseCost(NORD);\n    for (int i = 0; i < NORD; i++) {\n        baseCost[i] = mdist(DEPOT_X, DEPOT_Y, ax[i], byy[i]) +\n                      mdist(ax[i], byy[i], cx[i], dy[i]) +\n                      mdist(cx[i], dy[i], DEPOT_X, DEPOT_Y);\n    }\n    vector<int> sorted_ids(NORD);\n    iota(sorted_ids.begin(), sorted_ids.end(), 0);\n    sort(sorted_ids.begin(), sorted_ids.end(), [&](int i, int j) { return baseCost[i] < baseCost[j]; });\n\n    int poolN = min(POOL_SIZE, NORD);\n    vector<int> pool(sorted_ids.begin(), sorted_ids.begin() + poolN);\n\n    array<int, CHOOSE> bestSubset;\n    for (int i = 0; i < CHOOSE; i++) bestSubset[i] = pool[i];\n    long long bestEval = nearest_cost(bestSubset);\n\n    // Seeds\n    vector<pair<double, double>> seeds;\n    for (int x = 0; x <= 800; x += GRID_STEP) {\n        for (int y = 0; y <= 800; y += GRID_STEP) {\n            seeds.emplace_back(x, y);\n        }\n    }\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> coordDist(0, 800);\n    for (int i = 0; i < RANDOM_SEEDS; i++) {\n        seeds.emplace_back(coordDist(rng), coordDist(rng));\n    }\n\n    vector<int> tmpIds(poolN);\n    iota(tmpIds.begin(), tmpIds.end(), 0);\n    array<int, CHOOSE> tmpSubset;\n    for (auto &s : seeds) {\n        double sx = s.first, sy = s.second;\n        sort(tmpIds.begin(), tmpIds.end(), [&](int i, int j) {\n            double dx1 = midx[pool[i]] - sx, dy1 = midy[pool[i]] - sy;\n            double dx2 = midx[pool[j]] - sx, dy2 = midy[pool[j]] - sy;\n            return dx1 * dx1 + dy1 * dy1 < dx2 * dx2 + dy2 * dy2;\n        });\n        for (int i = 0; i < CHOOSE; i++) tmpSubset[i] = pool[tmpIds[i]];\n        long long t = nearest_cost(tmpSubset);\n        if (t < bestEval) {\n            bestEval = t;\n            bestSubset = tmpSubset;\n        }\n    }\n\n    // Random sampling\n    array<int, CHOOSE> randomSubset;\n    int random_trials = 200;\n    for (int t = 0; t < random_trials; t++) {\n        shuffle(pool.begin(), pool.end(), rng);\n        for (int i = 0; i < CHOOSE; i++) randomSubset[i] = pool[i];\n        long long val = nearest_cost(randomSubset);\n        if (val < bestEval) {\n            bestEval = val;\n            bestSubset = randomSubset;\n        }\n    }\n\n    // SA over subset (swap selected vs non-selected)\n    array<int, CHOOSE> curSubset = bestSubset;\n    long long curEval = bestEval;\n\n    vector<int> outList;\n    outList.reserve(poolN - CHOOSE);\n    vector<char> inSel(NORD, 0);\n    for (int i = 0; i < CHOOSE; i++) inSel[curSubset[i]] = 1;\n    for (int v : pool) if (!inSel[v]) outList.push_back(v);\n\n    uniform_int_distribution<int> distIn(0, CHOOSE - 1);\n    uniform_real_distribution<double> distReal(0.0, 1.0);\n    if (!outList.empty()) {\n        uniform_int_distribution<int> distOut(0, (int)outList.size() - 1);\n        double startTemp = 3000.0, endTemp = 30.0;\n        while (chrono::steady_clock::now() < sa_end) {\n            int idxIn = distIn(rng);\n            int idxOut = distOut(rng);\n            int oldIn = curSubset[idxIn];\n            int newIn = outList[idxOut];\n            curSubset[idxIn] = newIn;\n            long long newEval = nearest_cost(curSubset);\n            double progress = chrono::duration<double>(chrono::steady_clock::now() - time_start).count() / (TOTAL_LIMIT - RESERVE_TIME);\n            if (progress > 1.0) progress = 1.0;\n            double temp = startTemp * pow(endTemp / startTemp, progress);\n            bool accept = false;\n            if (newEval < curEval) accept = true;\n            else {\n                double diff = double(curEval - newEval);\n                double prob = exp(diff / temp);\n                if (distReal(rng) < prob) accept = true;\n            }\n            if (accept) {\n                curEval = newEval;\n                outList[idxOut] = oldIn;\n                if (newEval < bestEval) {\n                    bestEval = newEval;\n                    bestSubset = curSubset;\n                }\n            } else {\n                curSubset[idxIn] = oldIn;\n            }\n        }\n    }\n\n    // Build coordinates for best subset (nodes 0..99)\n    vector<pair<int, int>> coords;\n    coords.reserve(CHOOSE * 2);\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = bestSubset[i];\n        coords.emplace_back(ax[id], byy[id]);\n    }\n    for (int i = 0; i < CHOOSE; i++) {\n        int id = bestSubset[i];\n        coords.emplace_back(cx[id], dy[id]);\n    }\n    int nodeCount = CHOOSE * 2;\n    vector<vector<int>> distMat(nodeCount, vector<int>(nodeCount));\n    vector<int> distDepot(nodeCount);\n    for (int i = 0; i < nodeCount; i++) {\n        distDepot[i] = mdist(DEPOT_X, DEPOT_Y, coords[i].first, coords[i].second);\n        for (int j = 0; j < nodeCount; j++) {\n            distMat[i][j] = mdist(coords[i].first, coords[i].second, coords[j].first, coords[j].second);\n        }\n    }\n\n    // Build candidate sequences\n    vector<int> seq1 = route_nearest_seq(bestSubset);\n    vector<int> seq2 = route_immediate_seq(bestSubset);\n    vector<int> seq3 = route_pickdrop_seq(bestSubset);\n\n    long long c1 = seq_cost(seq1, distMat, distDepot);\n    long long c2 = seq_cost(seq2, distMat, distDepot);\n    long long c3 = seq_cost(seq3, distMat, distDepot);\n\n    vector<int> bestSeq = seq1;\n    long long bestCost = c1;\n    if (c2 < bestCost) { bestCost = c2; bestSeq = seq2; }\n    if (c3 < bestCost) { bestCost = c3; bestSeq = seq3; }\n\n    // Local optimization with remaining time\n    local_optimize(bestSeq, distMat, distDepot, rng, total_end);\n\n    // Build path for output\n    vector<pair<int, int>> path;\n    path.reserve(nodeCount + 2);\n    path.emplace_back(DEPOT_X, DEPOT_Y);\n    for (int idx : bestSeq) {\n        path.push_back(coords[idx]);\n    }\n    path.emplace_back(DEPOT_X, DEPOT_Y);\n\n    // Output\n    cout << CHOOSE;\n    for (int i = 0; i < CHOOSE; i++) cout << ' ' << (bestSubset[i] + 1); // 1-based\n    cout << '\\n';\n    cout << path.size();\n    for (auto &p : path) cout << ' ' << p.first << ' ' << p.second;\n    cout << '\\n';\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, sz;\n    DSU(int n_=0): n(n_), p(n_), sz(n_,1) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }\n    bool merge(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b];\n        return true;\n    }\n};\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u,v;\n    int d;\n    int tid;\n    bool in_mst;\n};\n\nvector<Edge> edges(M);\nvector<int> xs(N), ys(N);\n\nvector<int> tin, low;\nvector<char> vis, is_bridge;\nvector<vector<pair<int,int>>> adj;\nint timer_dfs;\n\nvoid compute_bridges(const vector<char>& alive){\n    for(int i=0;i<N;i++) adj[i].clear();\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        adj[u].push_back({v,id});\n        adj[v].push_back({u,id});\n    }\n    fill(vis.begin(), vis.end(), 0);\n    fill(is_bridge.begin(), is_bridge.end(), 0);\n    timer_dfs = 0;\n    function<void(int,int)> dfs = [&](int v,int pe){\n        vis[v]=1;\n        tin[v]=low[v]=++timer_dfs;\n        for(auto [to,eid]: adj[v]){\n            if(eid==pe) continue;\n            if(vis[to]){\n                low[v]=min(low[v], tin[to]);\n            }else{\n                dfs(to,eid);\n                low[v]=min(low[v], low[to]);\n                if(low[to] > tin[v]){\n                    is_bridge[eid]=1;\n                }\n            }\n        }\n    };\n    for(int i=0;i<N;i++){\n        if(!vis[i]) dfs(i,-1);\n    }\n}\n\nvoid compute_out_count(const vector<char>& alive, DSU &dsu, vector<int>& out_cnt){\n    fill(out_cnt.begin(), out_cnt.end(), 0);\n    for(int id=0; id<M; id++){\n        if(!alive[id]) continue;\n        int u=edges[id].u, v=edges[id].v;\n        int ru=dsu.find(u), rv=dsu.find(v);\n        if(ru==rv) continue;\n        out_cnt[ru]++; out_cnt[rv]++;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    for(int i=0;i<N;i++){\n        if(!(cin>>xs[i]>>ys[i])) return 0;\n    }\n    for(int i=0;i<M;i++){\n        int u,v;\n        cin>>u>>v;\n        edges[i].u=u;\n        edges[i].v=v;\n        long dx=xs[u]-xs[v];\n        long dy=ys[u]-ys[v];\n        edges[i].d = (int)llround(sqrt((double)(dx*dx + dy*dy)));\n        edges[i].tid = 4;\n        edges[i].in_mst = false;\n    }\n\n    // sort edges by baseline distance\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n        return a < b;\n    });\n    vector<char> used(M, 0);\n    for(int t=0; t<5; t++){\n        DSU dsu(N);\n        int cnt=0;\n        for(int id: ord){\n            if(used[id]) continue;\n            if(dsu.merge(edges[id].u, edges[id].v)){\n                edges[id].tid = t;\n                used[id]=1;\n                cnt++;\n                if(cnt == N-1) break;\n            }\n        }\n    }\n    for(int i=0;i<M;i++){\n        if(edges[i].tid==0) edges[i].in_mst = true;\n    }\n\n    // quantiles of d\n    vector<int> ds;\n    ds.reserve(M);\n    for(auto &e: edges) ds.push_back(e.d);\n    sort(ds.begin(), ds.end());\n    int q1 = ds[M/4];\n    int q3 = ds[(3*M)/4];\n\n    vector<char> alive(M, 1);\n    DSU dsu_conn(N);\n    int comp_cnt = N;\n\n    tin.assign(N,0); low.assign(N,0); vis.assign(N,0);\n    is_bridge.assign(M,0);\n    adj.assign(N, {});\n    vector<int> out_cnt(N,0);\n\n    array<double,5> start = {1.40, 1.32, 1.25, 1.18, 1.10};\n    array<double,5> finish= {1.85, 1.75, 1.65, 1.55, 1.45};\n    const double ALPHA = 0.50;\n\n    unordered_map<long long,int> pairCnt;\n    unordered_map<long long,int> pairMin;\n    pairCnt.reserve(4096);\n    pairMin.reserve(4096);\n\n    for(int iedge=0; iedge<M; iedge++){\n        int l;\n        if(!(cin>>l)) break;\n        double r = (double)l / (double)edges[iedge].d;\n\n        compute_bridges(alive);\n        compute_out_count(alive, dsu_conn, out_cnt);\n\n        pairCnt.clear();\n        pairMin.clear();\n        for(int id=0; id<M; id++){\n            if(!alive[id]) continue;\n            int cu = dsu_conn.find(edges[id].u);\n            int cv = dsu_conn.find(edges[id].v);\n            if(cu==cv) continue;\n            int a = min(cu,cv), b = max(cu,cv);\n            long long key = ((long long)a<<21) | b;\n            auto it = pairCnt.find(key);\n            if(it==pairCnt.end()){\n                pairCnt[key]=1;\n                pairMin[key]=edges[id].d;\n            }else{\n                it->second++;\n                if(edges[id].d < pairMin[key]) pairMin[key]=edges[id].d;\n            }\n        }\n\n        bool accept=false;\n        if(is_bridge[iedge]){\n            accept=true;\n        }else{\n            int ru = dsu_conn.find(edges[iedge].u);\n            int rv = dsu_conn.find(edges[iedge].v);\n            if(ru != rv){\n                double prog = (double)iedge / (double)(M-1);\n                double f = pow(prog, ALPHA);\n                int t = edges[iedge].tid;\n                double thr = start[t] + (finish[t] - start[t]) * f;\n\n                int outm = min(out_cnt[ru], out_cnt[rv]);\n                if(outm <= 2) thr += 0.30;\n                else if(outm <= 4) thr += 0.15;\n                else if(outm <= 6) thr += 0.07;\n\n                int rem = M - iedge - 1;\n                int need = comp_cnt - 1;\n                if(need > 0){\n                    if(rem <= need * 2) thr += 0.50;\n                    else if(rem <= need * 3) thr += 0.20;\n                }\n\n                if(edges[iedge].d <= q1) thr += 0.05;\n                else if(edges[iedge].d >= q3) thr -= 0.05;\n\n                int a=min(ru,rv), b=max(ru,rv);\n                long long key = ((long long)a<<21) | b;\n                int kpair = 0;\n                auto itc = pairCnt.find(key);\n                if(itc!=pairCnt.end()) kpair = itc->second;\n                if(kpair <= 1) thr += 0.20;\n                else if(kpair <= 3) thr += 0.10;\n                else if(kpair >= 8) thr -= 0.05;\n\n                auto itm = pairMin.find(key);\n                if(itm!=pairMin.end()){\n                    double alt_thr = 2.0 * (double)itm->second / (double)edges[iedge].d + 0.15;\n                    if(thr > alt_thr) thr = alt_thr;\n                }\n\n                if(thr > 2.6) thr = 2.6;\n                if(r <= thr) accept = true;\n            }else{\n                accept = false; // never accept cycle edges\n            }\n        }\n\n        if(accept){\n            if(dsu_conn.merge(edges[iedge].u, edges[iedge].v)){\n                comp_cnt--;\n            }\n        }else{\n            alive[iedge]=0;\n        }\n\n        cout << (accept ? 1 : 0) << '\\n';\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet { int x,y,t; };\n\nint N,M;\nvector<Pet> pets;\nvector<int> hx, hy;\nvector<vector<bool>> wall(31, vector<bool>(31,false));\n\nint r1,r2,c1,c2;\nint colWallCol,rowWallRow;\nint builderCol,builderRow;\nchar colDir,rowDir;\nint entryWallX, entryWallY;\npair<int,int> entryDest;\nchar gapOrient; // 'R' for row wall gap, 'C' for col wall gap\nint T_close;\n\ninline int encode(int x,int y){ return x*64 + y; }\n\nint dist_point_to_rect(int px,int py,int r1,int r2,int c1,int c2){\n    int dx=0, dy=0;\n    if(px<r1) dx=r1-px;\n    else if(px>r2) dx=px-r2;\n    if(py<c1) dy=c1-py;\n    else if(py>c2) dy=py-c2;\n    return dx+dy;\n}\n\nbool can_build(int wx,int wy,const vector<Pet>& pets,const vector<int>& hx,const vector<int>& hy){\n    if(wx<1 || wx>30 || wy<1 || wy>30) return false;\n    for(auto &p: pets){\n        if(p.x==wx && p.y==wy) return false;\n        if(abs(p.x-wx)+abs(p.y-wy)<=1) return false;\n    }\n    for(size_t i=0;i<hx.size();i++){\n        if(hx[i]==wx && hy[i]==wy) return false;\n    }\n    return true;\n}\n\nchar bfs_move(int sx,int sy,int tx,int ty,bool regionOnly,const unordered_set<int>& buildTargets){\n    auto blocked=[&](int x,int y)->bool{\n        if(x<1||x>30||y<1||y>30) return true;\n        if(regionOnly && (x<r1 || x>r2 || y<c1 || y>c2)) return true;\n        if(wall[x][y]) return true;\n        if(buildTargets.find(encode(x,y))!=buildTargets.end()) return true;\n        return false;\n    };\n    if(blocked(tx,ty)) return '.';\n    static int dist[31][31];\n    for(int i=1;i<=30;i++) for(int j=1;j<=30;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[tx][ty]=0;\n    q.push({tx,ty});\n    int dxs[4]={-1,1,0,0};\n    int dys[4]={0,0,-1,1};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        int nd=dist[x][y]+1;\n        for(int d=0;d<4;d++){\n            int nx=x+dxs[d], ny=y+dys[d];\n            if(blocked(nx,ny)) continue;\n            if(dist[nx][ny]==-1){\n                dist[nx][ny]=nd;\n                q.push({nx,ny});\n            }\n        }\n    }\n    if(dist[sx][sy]<=0) return '.';\n    char dirc[4]={'U','D','L','R'};\n    for(int d=0;d<4;d++){\n        int nx=sx+dxs[d], ny=sy+dys[d];\n        if(nx<1||nx>30||ny<1||ny>30) continue;\n        if(regionOnly && (nx<r1||nx>r2||ny<c1||ny>c2)) continue;\n        if(blocked(nx,ny)) continue;\n        if(dist[nx][ny]==dist[sx][sy]-1) return dirc[d];\n    }\n    return '.';\n}\n\nvoid select_region(const vector<int>& initHx, const vector<int>& initHy){\n    double bestScore=-1e18;\n    int bestR1=1,bestR2=5,bestC1=1,bestC2=5;\n    bool foundZero=false;\n    for(int k=12;k>=5;k--){\n        for(int corner=0;corner<4;corner++){\n            int rr1,rr2,cc1,cc2;\n            switch(corner){\n                case 0: rr1=1; rr2=k; cc1=1; cc2=k; break;\n                case 1: rr1=1; rr2=k; cc1=30-k+1; cc2=30; break;\n                case 2: rr1=30-k+1; rr2=30; cc1=1; cc2=k; break;\n                default: rr1=30-k+1; rr2=30; cc1=30-k+1; cc2=30; break;\n            }\n            int inside=0;\n            int minDistPet=1000;\n            for(auto &p: pets){\n                if(rr1<=p.x && p.x<=rr2 && cc1<=p.y && p.y<=cc2) inside++;\n                int d=dist_point_to_rect(p.x,p.y,rr1,rr2,cc1,cc2);\n                minDistPet=min(minDistPet,d);\n            }\n            if(pets.empty()) minDistPet=100;\n            int maxHD=0;\n            int midc=(cc1+cc2)/2;\n            int midr=(rr1+rr2)/2;\n            for(size_t i=0;i<initHx.size();i++){\n                int d=abs(initHx[i]-midr)+abs(initHy[i]-midc);\n                maxHD=max(maxHD,d);\n            }\n            double area=k*k;\n            if(!foundZero && inside>0) continue;\n            if(inside==0) foundZero=true;\n            double score = area*1.5 + minDistPet*10.0 - maxHD*2.0 - inside*500.0;\n            if(score>bestScore){\n                bestScore=score;\n                bestR1=rr1; bestR2=rr2; bestC1=cc1; bestC2=cc2;\n            }\n        }\n        if(foundZero) break;\n    }\n    r1=bestR1; r2=bestR2; c1=bestC1; c2=bestC2;\n    if(c1==1){ colWallCol=c2+1; colDir='r'; builderCol=c2; }\n    else { colWallCol=c1-1; colDir='l'; builderCol=c1; }\n    if(r1==1){ rowWallRow=r2+1; rowDir='d'; builderRow=r2; }\n    else { rowWallRow=r1-1; rowDir='u'; builderRow=r1; }\n\n    // select opening (gap) position maximizing distance to nearest pet\n    int bestDist=-1;\n    gapOrient='R';\n    entryWallX=rowWallRow;\n    entryWallY=(c1+c2)/2;\n    entryDest={builderRow, entryWallY};\n    // row candidates\n    for(int y=c1; y<=c2; y++){\n        int gx=rowWallRow, gy=y;\n        int mind=1000;\n        for(auto &p: pets){\n            int d=abs(p.x-gx)+abs(p.y-gy);\n            mind=min(mind,d);\n        }\n        if(mind>bestDist){\n            bestDist=mind;\n            gapOrient='R';\n            entryWallX=gx; entryWallY=gy;\n            entryDest={builderRow, gy};\n        }\n    }\n    // col candidates\n    for(int x=r1; x<=r2; x++){\n        int gx=x, gy=colWallCol;\n        int mind=1000;\n        for(auto &p: pets){\n            int d=abs(p.x-gx)+abs(p.y-gy);\n            mind=min(mind,d);\n        }\n        if(mind>bestDist){\n            bestDist=mind;\n            gapOrient='C';\n            entryWallX=gx; entryWallY=gy;\n            entryDest={x, builderCol};\n        }\n    }\n    // T_close based on human distances\n    int maxD=0;\n    for(size_t i=0;i<initHx.size();i++){\n        int d=abs(initHx[i]-entryDest.first)+abs(initHy[i]-entryDest.second);\n        maxD=max(maxD,d);\n    }\n    int perimeter = (r2-r1+1)+(c2-c1+1);\n    T_close = min(80, max(30, maxD + perimeter/ (int)max(1,M) + 5));\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N;\n    pets.resize(N);\n    for(int i=0;i<N;i++) cin>>pets[i].x>>pets[i].y>>pets[i].t;\n    cin>>M;\n    hx.resize(M); hy.resize(M);\n    for(int i=0;i<M;i++) cin>>hx[i]>>hy[i];\n    vector<int> initHx=hx, initHy=hy;\n    select_region(initHx, initHy);\n\n    vector<pair<int,int>> colCells,rowCells;\n    for(int r=r1; r<=r2; r++) colCells.push_back({r,colWallCol});\n    for(int c=c1; c<=c2; c++) rowCells.push_back({rowWallRow,c});\n\n    for(int turn=0; turn<300; turn++){\n        bool all_inside=true;\n        int insideCnt=0;\n        for(int i=0;i<M;i++){\n            if(r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2) insideCnt++;\n            else all_inside=false;\n        }\n        bool petInside=false;\n        int petGapDist=1000;\n        for(auto &p: pets){\n            if(r1<=p.x && p.x<=r2 && c1<=p.y && p.y<=c2) petInside=true;\n            petGapDist=min(petGapDist, abs(p.x-entryWallX)+abs(p.y-entryWallY));\n        }\n        bool close_condition=false;\n        if(all_inside || turn>=T_close) close_condition=true;\n        if(insideCnt>= (M+1)/2 && petGapDist<=1) close_condition=true;\n\n        // compute missing walls\n        vector<int> colMissingRows;\n        for(auto &p: colCells){\n            if(gapOrient=='C' && p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) colMissingRows.push_back(p.first);\n        }\n        vector<int> rowMissingCols;\n        for(auto &p: rowCells){\n            if(gapOrient=='R' && p.first==entryWallX && p.second==entryWallY && !close_condition) continue;\n            if(!wall[p.first][p.second]) rowMissingCols.push_back(p.second);\n        }\n\n        unordered_set<int> buildTargets;\n        string actions(M,'.');\n\n        // attempt builds\n        for(int i=0;i<M;i++){\n            // col wall build\n            if(r1<=hx[i] && hx[i]<=r2 && hy[i]==builderCol){\n                if(!colMissingRows.empty()){\n                    if(!wall[hx[i]][colWallCol]){\n                        int wx=hx[i], wy=colWallCol;\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=colDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n            // row wall build\n            if(hx[i]==builderRow && hy[i]>=c1 && hy[i]<=c2){\n                if(!rowMissingCols.empty()){\n                    if(!wall[rowWallRow][hy[i]]){\n                        int wx=rowWallRow, wy=hy[i];\n                        int key=encode(wx,wy);\n                        if(buildTargets.find(key)==buildTargets.end() && can_build(wx,wy,pets,hx,hy)){\n                            actions[i]=rowDir;\n                            buildTargets.insert(key);\n                            continue;\n                        }\n                    }\n                }\n            }\n        }\n\n        // movement\n        for(int i=0;i<M;i++){\n            if(actions[i]!='.') continue;\n            bool inside = (r1<=hx[i] && hx[i]<=r2 && c1<=hy[i] && hy[i]<=c2);\n            if(!inside){\n                char mv=bfs_move(hx[i],hy[i],entryDest.first, entryDest.second, false, buildTargets);\n                actions[i]=mv;\n            }else{\n                if(!colMissingRows.empty()){\n                    int bestd=1e9, targRow=colMissingRows[0];\n                    for(int rr: colMissingRows){\n                        int d=abs(rr-hx[i])+abs(builderCol-hy[i]);\n                        if(d<bestd){bestd=d; targRow=rr;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],targRow,builderCol,true,buildTargets);\n                    actions[i]=mv;\n                }else if(!rowMissingCols.empty()){\n                    int bestd=1e9, targCol=rowMissingCols[0];\n                    for(int cc: rowMissingCols){\n                        int d=abs(builderRow-hx[i])+abs(cc-hy[i]);\n                        if(d<bestd){bestd=d; targCol=cc;}\n                    }\n                    char mv=bfs_move(hx[i],hy[i],builderRow,targCol,true,buildTargets);\n                    actions[i]=mv;\n                }else{\n                    actions[i]='.';\n                }\n            }\n        }\n\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // read pet moves\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            if(s==\".\") continue;\n            for(char ch: s){\n                if(ch=='U') pets[i].x--;\n                else if(ch=='D') pets[i].x++;\n                else if(ch=='L') pets[i].y--;\n                else if(ch=='R') pets[i].y++;\n            }\n        }\n        // apply builds\n        for(int key: buildTargets){\n            int wx=key/64, wy=key%64;\n            if(wx>=1 && wx<=30 && wy>=1 && wy<=30) wall[wx][wy]=true;\n        }\n        // move humans\n        for(int i=0;i<M;i++){\n            char ac=actions[i];\n            if(ac=='U') hx[i]--;\n            else if(ac=='D') hx[i]++;\n            else if(ac=='L') hy[i]--;\n            else if(ac=='R') hy[i]++;\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20;\nconst int W = 20;\nconst int N = H * W;\nconst int DIRS = 4;\nconst int L = 200;\nconst double TIME_LIMIT_TOTAL = 1.95;\nconst double TIME_LIMIT_MAIN = 1.85;\n\nint startId, targetId;\ndouble p_forget, q_exec;\n\nint moveTbl[N][DIRS];\ndouble weightArr[L];\ndouble weight_q[L];\nint tieOrd[4];\n\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> uni01(0.0, 1.0);\n\ninline int idx(int i, int j) { return i * W + j; }\n\nvoid build_moves(const vector<string> &h, const vector<string> &v) {\n    for (int i = 0; i < H; i++) {\n        for (int j = 0; j < W; j++) {\n            int id = idx(i, j);\n            // Up\n            if (i == 0 || v[i - 1][j] == '1')\n                moveTbl[id][0] = id;\n            else\n                moveTbl[id][0] = idx(i - 1, j);\n            // Down\n            if (i == H - 1 || v[i][j] == '1')\n                moveTbl[id][1] = id;\n            else\n                moveTbl[id][1] = idx(i + 1, j);\n            // Left\n            if (j == 0 || h[i][j - 1] == '1')\n                moveTbl[id][2] = id;\n            else\n                moveTbl[id][2] = idx(i, j - 1);\n            // Right\n            if (j == W - 1 || h[i][j] == '1')\n                moveTbl[id][3] = id;\n            else\n                moveTbl[id][3] = idx(i, j + 1);\n        }\n    }\n}\n\nvoid set_tie_order(int dv, int dh) {\n    // Prefer directions towards target; fallback order D,R,L,U\n    vector<pair<int,int>> dirs;\n    // pair of priority (smaller better), dir\n    dirs.push_back({-dv, 1}); // Down\n    dirs.push_back({-dh, 3}); // Right\n    dirs.push_back({dh, 2});  // Left\n    dirs.push_back({dv, 0});  // Up\n    sort(dirs.begin(), dirs.end(), [](auto &a, auto &b){\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    for (int k = 0; k < 4; k++) tieOrd[k] = dirs[k].second;\n}\n\nvector<int> bfs_path(bool monotone_only) {\n    vector<int> prev(N, -1), prevDir(N, -1);\n    vector<char> vis(N, 0);\n    queue<int> q;\n    vis[startId] = 1;\n    q.push(startId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        if (u == targetId) break;\n        for (int dir = 0; dir < DIRS; dir++) {\n            if (monotone_only && !(dir == 1 || dir == 3)) continue; // only D or R\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (!vis[nb]) {\n                vis[nb] = 1;\n                prev[nb] = u;\n                prevDir[nb] = dir;\n                q.push(nb);\n            }\n        }\n    }\n    if (!vis[targetId]) return {};\n    vector<int> path;\n    int cur = targetId;\n    while (cur != startId) {\n        int d = prevDir[cur];\n        path.push_back(d);\n        cur = prev[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid compute_distances(vector<double> &dist1, vector<double> &dist2) {\n    dist1.assign(N, 1e9);\n    queue<int> q;\n    dist1[targetId] = 0;\n    q.push(targetId);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        double du = dist1[u];\n        for (int dir = 0; dir < DIRS; dir++) {\n            int nb = moveTbl[u][dir];\n            if (nb == u) continue;\n            if (dist1[nb] > du + 1) {\n                dist1[nb] = du + 1;\n                q.push(nb);\n            }\n        }\n    }\n    dist2.resize(N);\n    for (int i = 0; i < N; i++) dist2[i] = dist1[i] * dist1[i];\n}\n\nvector<int> greedy_seq(const vector<double> &dist, double eps) {\n    vector<double> cur(N, 0.0), nxt(N, 0.0);\n    cur[startId] = 1.0;\n    vector<int> seq(L);\n    for (int t = 0; t < L; t++) {\n        double bestVal = 1e100;\n        int bestDir = tieOrd[0];\n        for (int k = 0; k < 4; k++) {\n            int dir = tieOrd[k];\n            double s = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                s += pu * dist[nb];\n            }\n            if (s < bestVal) {\n                bestVal = s;\n                bestDir = dir;\n            }\n        }\n        if (eps > 0.0 && uni01(rng) < eps) {\n            bestDir = rng() & 3ULL;\n        }\n        seq[t] = bestDir;\n        fill(nxt.begin(), nxt.end(), 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb != targetId) nxt[nb] += mv;\n            nxt[u] += pu * p_forget;\n        }\n        cur.swap(nxt);\n    }\n    return seq;\n}\n\nvector<int> greedy_suffix(const double *dist0, int len, const vector<double> &heuristic) {\n    vector<double> cur(dist0, dist0 + N);\n    vector<double> nxt(N, 0.0);\n    vector<int> seq(len);\n    for (int t = 0; t < len; t++) {\n        double bestVal = 1e100;\n        int bestDir = tieOrd[0];\n        for (int k = 0; k < 4; k++) {\n            int dir = tieOrd[k];\n            double s = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                s += pu * heuristic[nb];\n            }\n            if (s < bestVal) {\n                bestVal = s;\n                bestDir = dir;\n            }\n        }\n        seq[t] = bestDir;\n        fill(nxt.begin(), nxt.end(), 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb != targetId) nxt[nb] += mv;\n            nxt[u] += pu * p_forget;\n        }\n        cur.swap(nxt);\n    }\n    return seq;\n}\n\nvector<int> greedy_from(const vector<double> &dist, int tStart, const vector<double> &heuristic) {\n    int len = L - tStart;\n    return greedy_suffix(dist.data(), len, heuristic);\n}\n\nvector<int> repeat_path_seed(const vector<int> &path, int r) {\n    vector<int> seq;\n    if (path.empty()) return seq;\n    seq.reserve(L);\n    for (int d : path) {\n        for (int k = 0; k < r && (int)seq.size() < L; k++) seq.push_back(d);\n        if ((int)seq.size() >= L) break;\n    }\n    while ((int)seq.size() < L) {\n        for (int d : path) {\n            if ((int)seq.size() >= L) break;\n            seq.push_back(d);\n        }\n    }\n    if ((int)seq.size() > L) seq.resize(L);\n    return seq;\n}\n\nvector<vector<int>> repeat_variants(const vector<int> &path) {\n    vector<vector<int>> res;\n    int len = (int)path.size();\n    if (len == 0) return res;\n    int maxR = max(1, min(15, L / len));\n    for (int r = 1; r <= maxR; r++) {\n        res.push_back(repeat_path_seed(path, r));\n    }\n    return res;\n}\n\nvector<int> ratio_seed(int dv, int dh) {\n    vector<int> seq;\n    seq.reserve(L);\n    int total = max(1, dv + dh);\n    int nD = (int)round((double)L * dv / total);\n    nD = max(0, min(L, nD));\n    int nR = L - nD;\n    int cD = 0, cR = 0;\n    while ((int)seq.size() < L) {\n        double pd = (nD - cD);\n        double pr = (nR - cR);\n        if (pd <= 0) {\n            seq.push_back(3);\n            cR++;\n        } else if (pr <= 0) {\n            seq.push_back(1);\n            cD++;\n        } else {\n            double probD = pd / (pd + pr);\n            if (uni01(rng) < probD) {\n                seq.push_back(1);\n                cD++;\n            } else {\n                seq.push_back(3);\n                cR++;\n            }\n        }\n    }\n    return seq;\n}\n\ndouble eval_seq(const vector<int> &seq) {\n    static double cur[N], nxt[N];\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double score = 0.0;\n    for (int t = 0; t < L; t++) {\n        int dir = seq[t];\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][dir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\nstatic double backVal[L + 1][N];\nstatic double fwdProb[L + 1][N];\n\nvoid compute_backward(const vector<int> &seq) {\n    for (int u = 0; u < N; u++) backVal[L][u] = 0.0;\n    for (int t = L - 1; t >= 0; t--) {\n        int dir = seq[t];\n        double wq = weight_q[t];\n        const double *next = backVal[t + 1];\n        double *cur = backVal[t];\n        for (int u = 0; u < N; u++) {\n            int nb = moveTbl[u][dir];\n            double val = p_forget * next[u];\n            if (nb == targetId) {\n                val += wq;\n            } else {\n                val += q_exec * next[nb];\n            }\n            cur[u] = val;\n        }\n    }\n}\n\nvoid compute_forward(const vector<int> &seq) {\n    for (int u = 0; u < N; u++) fwdProb[0][u] = 0.0;\n    fwdProb[0][startId] = 1.0;\n    for (int t = 0; t < L; t++) {\n        int dir = seq[t];\n        double *cur = fwdProb[t];\n        double *nxt = fwdProb[t + 1];\n        for (int u = 0; u < N; u++) nxt[u] = 0.0;\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            nxt[u] += pu * p_forget;\n            int nb = moveTbl[u][dir];\n            if (nb != targetId) nxt[nb] += pu * q_exec;\n        }\n    }\n}\n\n// Coordinate ascent by single-position mutation using forward/backward\nvoid local_improve(vector<int> &seq, double &bestScore,\n                   const chrono::steady_clock::time_point &time_start) {\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > TIME_LIMIT_TOTAL) break;\n        compute_forward(seq);\n        compute_backward(seq);\n        double baseScore = backVal[0][startId];\n        double bestDelta = 1e-9;\n        int bestT = -1, bestDir = -1;\n        for (int t = 0; t < L; t++) {\n            if ((t & 31) == 0) {\n                elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > TIME_LIMIT_TOTAL) break;\n            }\n            double baseline_chunk = 0.0;\n            for (int u = 0; u < N; u++) {\n                double pu = fwdProb[t][u];\n                if (pu == 0.0) continue;\n                baseline_chunk += pu * backVal[t][u];\n            }\n            for (int dir = 0; dir < 4; dir++) {\n                if (dir == seq[t]) continue;\n                double newChunk = 0.0;\n                for (int u = 0; u < N; u++) {\n                    double pu = fwdProb[t][u];\n                    if (pu == 0.0) continue;\n                    int nb = moveTbl[u][dir];\n                    double v = p_forget * backVal[t + 1][u];\n                    if (nb == targetId) v += weight_q[t];\n                    else v += q_exec * backVal[t + 1][nb];\n                    newChunk += pu * v;\n                }\n                double delta = newChunk - baseline_chunk;\n                if (delta > bestDelta) {\n                    bestDelta = delta;\n                    bestT = t;\n                    bestDir = dir;\n                }\n            }\n        }\n        if (bestT == -1) break;\n        seq[bestT] = bestDir;\n        baseScore += bestDelta;\n        if (baseScore > bestScore) {\n            bestScore = baseScore;\n        }\n    }\n}\n\ndouble build_new_seq([[maybe_unused]] const vector<int> &oldSeq, vector<int> &outSeq) {\n    static double cur[N], nxt[N];\n    fill(cur, cur + N, 0.0);\n    cur[startId] = 1.0;\n    double score = 0.0;\n    for (int t = 0; t < L; t++) {\n        double stay = 0.0;\n        double *nextBack = backVal[t + 1];\n        for (int u = 0; u < N; u++) {\n            stay += cur[u] * nextBack[u];\n        }\n        stay *= p_forget;\n        double bestVal = -1e100;\n        int bestDir = tieOrd[0];\n        for (int ki = 0; ki < 4; ki++) {\n            int dir = tieOrd[ki];\n            double sum = stay;\n            for (int u = 0; u < N; u++) {\n                double pu = cur[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                if (nb == targetId) sum += pu * weight_q[t];\n                else sum += pu * q_exec * nextBack[nb];\n            }\n            if (sum > bestVal) {\n                bestVal = sum;\n                bestDir = dir;\n            }\n        }\n        outSeq[t] = bestDir;\n        fill(nxt, nxt + N, 0.0);\n        for (int u = 0; u < N; u++) {\n            double pu = cur[u];\n            if (pu == 0.0) continue;\n            int nb = moveTbl[u][bestDir];\n            double mv = pu * q_exec;\n            if (nb == targetId) {\n                score += mv * weightArr[t];\n            } else {\n                nxt[nb] += mv;\n            }\n            nxt[u] += pu * p_forget;\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\nstruct BeamState {\n    vector<double> dist;\n    double score;\n    vector<int> seq;\n};\n\nvector<int> beam_seed(int depth, int width, const vector<double> &heuristic) {\n    BeamState init;\n    init.dist.assign(N, 0.0);\n    init.dist[startId] = 1.0;\n    init.score = 0.0;\n    init.seq.clear();\n    vector<BeamState> cur;\n    cur.reserve(width * 4);\n    cur.push_back(move(init));\n    for (int t = 0; t < depth; t++) {\n        vector<BeamState> nxtStates;\n        nxtStates.reserve(width * 4);\n        for (const auto &st : cur) {\n            for (int dir = 0; dir < 4; dir++) {\n                BeamState ns;\n                ns.dist.assign(N, 0.0);\n                ns.seq = st.seq;\n                ns.seq.push_back(dir);\n                double add = 0.0;\n                for (int u = 0; u < N; u++) {\n                    double pu = st.dist[u];\n                    if (pu == 0.0) continue;\n                    int nb = moveTbl[u][dir];\n                    double mv = pu * q_exec;\n                    if (nb == targetId) {\n                        add += mv * weightArr[t];\n                    } else {\n                        ns.dist[nb] += mv;\n                    }\n                    ns.dist[u] += pu * p_forget;\n                }\n                ns.score = st.score + add;\n                nxtStates.push_back(move(ns));\n            }\n        }\n        if ((int)nxtStates.size() > width) {\n            nth_element(nxtStates.begin(), nxtStates.begin() + width, nxtStates.end(),\n                        [](const BeamState &a, const BeamState &b) { return a.score > b.score; });\n            nxtStates.resize(width);\n        }\n        cur.swap(nxtStates);\n    }\n    const BeamState *best = &cur[0];\n    for (const auto &st : cur) {\n        if (st.score > best->score) best = &st;\n    }\n    vector<int> suffix = greedy_from(best->dist, depth, heuristic);\n    vector<int> seq = best->seq;\n    seq.insert(seq.end(), suffix.begin(), suffix.end());\n    if ((int)seq.size() > L) seq.resize(L);\n    return seq;\n}\n\n// Precompute all sequences of length up to 6\nvector<vector<int>> preSeq[7];\nvoid init_preSeq() {\n    for (int len = 1; len <= 6; len++) {\n        int total = 1 << (2 * len);\n        preSeq[len].resize(total, vector<int>(len));\n        for (int code = 0; code < total; code++) {\n            int tmp = code;\n            for (int i = 0; i < len; i++) {\n                preSeq[len][code][i] = tmp & 3;\n                tmp >>= 2;\n            }\n        }\n    }\n}\n\n// Block optimization for small window lengths 6,5,4\nvoid block_optimize(vector<int> &seq, double &bestScore,\n                    const chrono::steady_clock::time_point &time_start) {\n    static double curSim[N], nxtSim[N];\n    auto simulate = [&](const vector<int> &dirs, int pos, const double *dist0, const double *backEnd) {\n        int len = dirs.size();\n        memcpy(curSim, dist0, sizeof(double) * N);\n        double reward = 0.0;\n        for (int s = 0; s < len; s++) {\n            int dir = dirs[s];\n            int tIdx = pos + s;\n            fill(nxtSim, nxtSim + N, 0.0);\n            for (int u = 0; u < N; u++) {\n                double pu = curSim[u];\n                if (pu == 0.0) continue;\n                int nb = moveTbl[u][dir];\n                double mv = pu * q_exec;\n                if (nb == targetId) {\n                    reward += mv * weightArr[tIdx];\n                } else {\n                    nxtSim[nb] += mv;\n                }\n                nxtSim[u] += pu * p_forget;\n            }\n            swap(curSim, nxtSim);\n        }\n        double tail = 0.0;\n        for (int u = 0; u < N; u++) tail += curSim[u] * backEnd[u];\n        return reward + tail;\n    };\n    compute_forward(seq);\n    compute_backward(seq);\n    double totalScore = backVal[0][startId];\n    struct LenTry { int len; int tries; };\n    vector<LenTry> lts = { {6,6}, {5,8}, {4,8} };\n    for (auto lt : lts) {\n        int len = lt.len;\n        int tries = lt.tries;\n        int maxPos = L - len;\n        if (maxPos < 0) continue;\n        for (int it = 0; it < tries; it++) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n            if (elapsed > TIME_LIMIT_TOTAL * 0.97) return;\n            int pos = rng() % (maxPos + 1);\n            const double *dist0 = fwdProb[pos];\n            const double *backEnd = backVal[pos + len];\n            double baseline_chunk = 0.0;\n            for (int u = 0; u < N; u++) baseline_chunk += dist0[u] * backVal[pos][u];\n            double bestChunk = baseline_chunk;\n            int bestIdx = -1;\n            int totalCodes = preSeq[len].size();\n            for (int code = 0; code < totalCodes; code++) {\n                double val = simulate(preSeq[len][code], pos, dist0, backEnd);\n                if (val > bestChunk) {\n                    bestChunk = val;\n                    bestIdx = code;\n                }\n            }\n            if (bestIdx != -1) {\n                for (int s = 0; s < len; s++) {\n                    seq[pos + s] = preSeq[len][bestIdx][s];\n                }\n                compute_forward(seq);\n                compute_backward(seq);\n                totalScore = backVal[0][startId];\n                if (totalScore > bestScore) bestScore = totalScore;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj, ti, tj;\n    if (!(cin >> si >> sj >> ti >> tj >> p_forget)) return 0;\n    startId = idx(si, sj);\n    targetId = idx(ti, tj);\n    q_exec = 1.0 - p_forget;\n    vector<string> h(H), v(H - 1);\n    for (int i = 0; i < H; i++) cin >> h[i];\n    for (int i = 0; i < H - 1; i++) cin >> v[i];\n    for (int t = 0; t < L; t++) {\n        weightArr[t] = 400.0 - t;\n        weight_q[t] = weightArr[t] * q_exec;\n    }\n    auto time_start = chrono::steady_clock::now();\n    init_preSeq();\n\n    build_moves(h, v);\n    set_tie_order(ti - si, tj - sj);\n    vector<double> dist1, dist2;\n    compute_distances(dist1, dist2);\n    vector<int> shortest = bfs_path(false);\n    vector<int> monotone = bfs_path(true);\n\n    vector<vector<int>> seeds;\n    seeds.push_back(greedy_seq(dist1, 0.0));\n    seeds.push_back(greedy_seq(dist2, 0.0));\n    seeds.push_back(greedy_seq(dist1, 0.1));\n    seeds.push_back(greedy_seq(dist1, 0.3));\n    int rep_suggest = max(1, min(10, (int)ceil(log(0.1) / log(max(0.05, p_forget)))));\n    if (!shortest.empty()) seeds.push_back(repeat_path_seed(shortest, rep_suggest));\n    if (!monotone.empty()) seeds.push_back(repeat_path_seed(monotone, rep_suggest));\n    auto rv1 = repeat_variants(shortest);\n    auto rv2 = repeat_variants(monotone);\n    seeds.insert(seeds.end(), rv1.begin(), rv1.end());\n    seeds.insert(seeds.end(), rv2.begin(), rv2.end());\n    seeds.push_back(ratio_seed(ti - si, tj - sj));\n    int beamDepth = 22;\n    int beamWidth = 32;\n    seeds.push_back(beam_seed(beamDepth, beamWidth, dist1));\n    seeds.push_back(beam_seed(beamDepth, beamWidth, dist2));\n\n    vector<pair<double, vector<int>>> seedScores;\n    seedScores.reserve(seeds.size());\n    for (auto &s : seeds) {\n        if ((int)s.size() != L) continue;\n        double sc = eval_seq(s);\n        seedScores.emplace_back(sc, s);\n    }\n    if (seedScores.empty()) return 0;\n    sort(seedScores.begin(), seedScores.end(),\n         [](const auto &a, const auto &b) { return a.first > b.first; });\n\n    double bestScore = -1.0;\n    vector<int> bestSeq;\n\n    int topK = min(5, (int)seedScores.size());\n    for (int i = 0; i < topK; i++) {\n        vector<int> seq = seedScores[i].second;\n        double curScore = seedScores[i].first;\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > TIME_LIMIT_MAIN) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(seq, newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 200) break;\n        }\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > TIME_LIMIT_MAIN) break;\n    }\n\n    // Random restarts with greedy noise\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > TIME_LIMIT_MAIN) break;\n        double eps = uni01(rng) * uni01(rng) * 0.5;\n        const vector<double> &heur = (rng() & 1) ? dist1 : dist2;\n        vector<int> seq = greedy_seq(heur, eps);\n        double curScore = eval_seq(seq);\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestSeq = seq;\n        }\n        int iter = 0;\n        while (true) {\n            if ((iter & 7) == 0) {\n                elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n                if (elapsed > TIME_LIMIT_MAIN) break;\n            }\n            compute_backward(seq);\n            vector<int> newSeq(L);\n            double newScore = build_new_seq(seq, newSeq);\n            if (newScore > bestScore) {\n                bestScore = newScore;\n                bestSeq = newSeq;\n            }\n            if (newSeq == seq) break;\n            seq.swap(newSeq);\n            iter++;\n            if (iter > 50) break;\n        }\n    }\n\n    // Tail regeneration using greedy suffix\n    double regen_limit = TIME_LIMIT_TOTAL - 0.08;\n    if (regen_limit < TIME_LIMIT_MAIN) regen_limit = TIME_LIMIT_MAIN;\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - time_start).count();\n        if (elapsed > regen_limit) break;\n        compute_forward(bestSeq);\n        int k = rng() % L;\n        const vector<double> *heur = (rng() & 1) ? &dist1 : &dist2;\n        int len = L - k;\n        if (len <= 0) break;\n        vector<int> suffix = greedy_suffix(fwdProb[k], len, *heur);\n        vector<int> newSeq;\n        newSeq.reserve(L);\n        newSeq.insert(newSeq.end(), bestSeq.begin(), bestSeq.begin() + k);\n        newSeq.insert(newSeq.end(), suffix.begin(), suffix.end());\n        double newScore = eval_seq(newSeq);\n        if (newScore > bestScore) {\n            bestScore = newScore;\n            bestSeq = move(newSeq);\n        }\n    }\n\n    // Block optimization\n    block_optimize(bestSeq, bestScore, time_start);\n\n    // Final coordinate ascent improvement on the best sequence\n    local_improve(bestSeq, bestScore, time_start);\n\n    string out;\n    out.reserve(L);\n    for (int d : bestSeq) {\n        char c;\n        if (d == 0) c = 'U';\n        else if (d == 1) c = 'D';\n        else if (d == 2) c = 'L';\n        else c = 'R';\n        out.push_back(c);\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOT = N * N * 4;\nconst int di[4] = {0, -1, 0, 1};   // L,U,R,D\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Heuristic weights\nconst int MATCH_REWARD = 3;\nconst int MISMATCH_PENALTY = 2;\nconst int BOUNDARY_PENALTY = 3;\nconst int PAIR_MATCH_REWARD = 5;\nconst int PAIR_MISMATCH_PENALTY = 4;\n\nint toMap[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 usedMask[8];\nint rotMap[8][4];\nvector<array<int, 2>> pairsOfType[8];\n\ninline bool uses(int t, int dir) { return (usedMask[t] >> dir) & 1; }\ninline int apply_rot(int base, int r) { return rotMap[base][r]; }\ninline int idx_of(int i, int j, int d) { return ((i * N + j) << 2) | d; }\n\nint baseType[N][N];\nint rotCnt[N][N];\nint curType[N][N];\n\ninline int edge_contrib(int i, int j, int dir) {\n    int t = curType[i][j];\n    bool a = uses(t, dir);\n    int ni = i + di[dir], nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n        return a ? -BOUNDARY_PENALTY : 0;\n    }\n    bool b = uses(curType[ni][nj], dir ^ 2);\n    if (a && b) return MATCH_REWARD;\n    else if (a || b) return -MISMATCH_PENALTY;\n    else return 0;\n}\n\ninline int calc_edges_counted(int i, int j) {\n    int res = 0;\n    if (j < N - 1) res += edge_contrib(i, j, 2);\n    if (i < N - 1) res += edge_contrib(i, j, 3);\n    if (j == 0) res += edge_contrib(i, j, 0);\n    else res += edge_contrib(i, j - 1, 2);\n    if (i == 0) res += edge_contrib(i, j, 1);\n    else res += edge_contrib(i - 1, j, 3);\n    return res;\n}\n\ninline int compute_tile_pair(int i, int j) {\n    int t = curType[i][j];\n    int res = 0;\n    for (auto &pr : pairsOfType[t]) {\n        int a = pr[0], b = pr[1];\n        bool ma = false, mb = false;\n        int ni = i + di[a], nj = j + dj[a];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            ma = uses(curType[ni][nj], a ^ 2);\n        }\n        ni = i + di[b]; nj = j + dj[b];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            mb = uses(curType[ni][nj], b ^ 2);\n        }\n        if (ma && mb) res += PAIR_MATCH_REWARD;\n        else if (ma || mb) res -= PAIR_MISMATCH_PENALTY;\n    }\n    return res;\n}\n\n// Fast computation of real score (product of two largest cycles)\nint compute_real_score_fast() {\n    static int nextArr[TOT];\n    static unsigned char state[TOT];\n    static int depth[TOT];\n    int idx = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int t = curType[i][j];\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 == -1) {\n                nextArr[idx++] = -1;\n                continue;\n            }\n            int ni = i + di[d2], nj = j + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n                nextArr[idx++] = -1;\n                continue;\n            }\n            int nd = (d2 + 2) & 3;\n            nextArr[idx++] = idx_of(ni, nj, nd);\n        }\n    }\n    memset(state, 0, TOT);\n    int best1 = 0, best2 = 0;\n    static int stack[TOT];\n    for (int v = 0; v < TOT; v++) {\n        if (state[v]) continue;\n        int top = 0;\n        int u = v;\n        while (u != -1 && state[u] == 0) {\n            state[u] = 1;\n            depth[u] = top;\n            stack[top++] = u;\n            u = nextArr[u];\n        }\n        if (u != -1 && state[u] == 1) {\n            int cycLen = top - depth[u];\n            if (cycLen > best1) {\n                best2 = best1;\n                best1 = cycLen;\n            } else if (cycLen > best2) {\n                best2 = cycLen;\n            }\n        }\n        for (int k = 0; k < top; k++) state[stack[k]] = 2;\n    }\n    if (best2 == 0) return 0;\n    return best1 * best2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Precompute masks and rotations and pairs\n    for (int t = 0; t < 8; t++) {\n        int m = 0;\n        for (int d = 0; d < 4; d++) if (toMap[t][d] != -1) m |= (1 << d);\n        usedMask[t] = m;\n    }\n    int nextType[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n    for (int b = 0; b < 8; b++) {\n        rotMap[b][0] = b;\n        for (int r = 1; r < 4; r++) rotMap[b][r] = nextType[rotMap[b][r - 1]];\n    }\n    for (int t = 0; t < 8; t++) {\n        pairsOfType[t].clear();\n        for (int d = 0; d < 4; d++) {\n            int d2 = toMap[t][d];\n            if (d2 != -1 && d < d2) pairsOfType[t].push_back({d, d2});\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) baseType[i][j] = s[j] - '0';\n    }\n\n    // Initial rotation: minimize boundary usage\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int bestR = 0, bestPen = 100;\n        for (int r = 0; r < 4; r++) {\n            int t = apply_rot(baseType[i][j], r);\n            int pen = 0;\n            if (i == 0 && uses(t, 1)) pen++;\n            if (i == N - 1 && uses(t, 3)) pen++;\n            if (j == 0 && uses(t, 0)) pen++;\n            if (j == N - 1 && uses(t, 2)) pen++;\n            if (pen < bestPen) { bestPen = pen; bestR = r; }\n        }\n        rotCnt[i][j] = bestR;\n        curType[i][j] = apply_rot(baseType[i][j], bestR);\n    }\n\n    int edgeScore = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (j < N - 1) edgeScore += edge_contrib(i, j, 2);\n        if (i < N - 1) edgeScore += edge_contrib(i, j, 3);\n        if (j == 0) edgeScore += edge_contrib(i, j, 0);\n        if (i == 0) edgeScore += edge_contrib(i, j, 1);\n    }\n    int pairScore = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        pairScore += compute_tile_pair(i, j);\n    }\n    int heurScore = edgeScore + pairScore;\n    int bestHeur = heurScore;\n    int bestRotHeur[N][N];\n    int bestTypeHeur[N][N];\n    memcpy(bestRotHeur, rotCnt, sizeof(rotCnt));\n    memcpy(bestTypeHeur, curType, sizeof(curType));\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    auto timeStart = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.9;\n    const double SA_DURATION = 1.2;\n    const double T0 = 5.0, T1 = 0.1;\n    double temp = T0;\n    int iter = 0;\n\n    while (true) {\n        iter++;\n        if ((iter & 1023) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - timeStart).count();\n            if (elapsed > SA_DURATION) break;\n            double progress = elapsed / SA_DURATION;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int newRot = rng() & 3;\n        if (newRot == rotCnt[i][j]) continue;\n        int oldType = curType[i][j];\n        int newType = apply_rot(baseType[i][j], newRot);\n\n        int oldEdges = calc_edges_counted(i, j);\n        int oldPairs = compute_tile_pair(i, j);\n        if (i > 0) oldPairs += compute_tile_pair(i - 1, j);\n        if (i + 1 < N) oldPairs += compute_tile_pair(i + 1, j);\n        if (j > 0) oldPairs += compute_tile_pair(i, j - 1);\n        if (j + 1 < N) oldPairs += compute_tile_pair(i, j + 1);\n\n        curType[i][j] = newType;\n\n        int newEdges = calc_edges_counted(i, j);\n        int newPairs = compute_tile_pair(i, j);\n        if (i > 0) newPairs += compute_tile_pair(i - 1, j);\n        if (i + 1 < N) newPairs += compute_tile_pair(i + 1, j);\n        if (j > 0) newPairs += compute_tile_pair(i, j - 1);\n        if (j + 1 < N) newPairs += compute_tile_pair(i, j + 1);\n\n        int delta = (newEdges - oldEdges) + (newPairs - oldPairs);\n        if (delta >= 0) {\n            edgeScore += (newEdges - oldEdges);\n            pairScore += (newPairs - oldPairs);\n            heurScore += delta;\n            rotCnt[i][j] = newRot;\n        } else {\n            double prob = exp(double(delta) / temp);\n            double rnd = (double)rng() / (double)rng.max();\n            if (rnd < prob) {\n                edgeScore += (newEdges - oldEdges);\n                pairScore += (newPairs - oldPairs);\n                heurScore += delta;\n                rotCnt[i][j] = newRot;\n            } else {\n                curType[i][j] = oldType; // revert\n            }\n        }\n        if (heurScore > bestHeur) {\n            bestHeur = heurScore;\n            memcpy(bestRotHeur, rotCnt, sizeof(rotCnt));\n            memcpy(bestTypeHeur, curType, sizeof(curType));\n        }\n    }\n\n    // Start from best heuristic state\n    memcpy(rotCnt, bestRotHeur, sizeof(rotCnt));\n    memcpy(curType, bestTypeHeur, sizeof(curType));\n\n    int curReal = compute_real_score_fast();\n    int bestReal = curReal;\n    int bestRot[N][N];\n    memcpy(bestRot, rotCnt, sizeof(rotCnt));\n    int bestType[N][N];\n    memcpy(bestType, curType, sizeof(curType));\n\n    // Greedy local search using real score\n    int greedyIter = 0;\n    while (true) {\n        greedyIter++;\n        if ((greedyIter & 31) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - timeStart).count();\n            if (elapsed > TIME_LIMIT) break;\n        }\n        int i = rng() % N;\n        int j = rng() % N;\n        int origRot = rotCnt[i][j];\n        int origType = curType[i][j];\n        int bestLocalRot = origRot;\n        int bestLocalScore = curReal;\n\n        for (int r = 0; r < 4; r++) {\n            if (r == origRot) continue;\n            curType[i][j] = apply_rot(baseType[i][j], r);\n            int sc = compute_real_score_fast();\n            if (sc > bestLocalScore) {\n                bestLocalScore = sc;\n                bestLocalRot = r;\n            }\n        }\n        curType[i][j] = origType; // revert\n        if (bestLocalRot != origRot) {\n            rotCnt[i][j] = bestLocalRot;\n            curType[i][j] = apply_rot(baseType[i][j], bestLocalRot);\n            curReal = bestLocalScore;\n            if (curReal > bestReal) {\n                bestReal = curReal;\n                memcpy(bestRot, rotCnt, sizeof(rotCnt));\n                memcpy(bestType, curType, sizeof(curType));\n            }\n        }\n    }\n\n    // Output best rotation counts\n    string out;\n    out.reserve(N * N);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        out.push_back(char('0' + (bestRot[i][j] & 3)));\n    }\n    cout << out << \"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Metric {\n    int tree_size;     // size of largest acyclic component\n    int comp_size;     // size of largest connected component\n    int cycles_large;  // number of cycles in the largest component\n    int good_edges;    // total matched edges\n};\n\nstruct Solver {\n    int N, Tlim, NN;\n    int full_size;\n    int init_zero;\n    vector<uint8_t> init_board;\n    vector<vector<pair<char,int>>> moves_from;\n    mt19937 rng;\n    chrono::steady_clock::time_point end_time;\n\n    Solver() {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n    }\n\n    int hexval(char c){\n        if('0'<=c && c<='9') return c-'0';\n        return 10 + (c-'a');\n    }\n\n    Metric compute_metric(const vector<uint8_t>& b){\n        static uint8_t vis[100];\n        static uint8_t mark[100];\n        memset(vis, 0, NN);\n        memset(mark, 0, NN);\n        int good_edges = 0;\n        for(int r=0; r<N; r++){\n            int base = r*N;\n            for(int c=0; c<N; c++){\n                int idx = base + c;\n                int t = b[idx];\n                if(t==0) continue;\n                if(c+1 < N){\n                    int t2 = b[idx+1];\n                    if(t2!=0 && (t&4) && (t2&1)) good_edges++;\n                }\n                if(r+1 < N){\n                    int t2 = b[idx+N];\n                    if(t2!=0 && (t&8) && (t2&2)) good_edges++;\n                }\n            }\n        }\n        int best_tree = 0;\n        int best_comp = 0;\n        int cycles_of_best = 1000000000;\n        vector<int> q;\n        q.reserve(NN);\n        for(int idx=0; idx<NN; idx++){\n            if(b[idx]==0 || vis[idx]) continue;\n            q.clear();\n            vis[idx]=1;\n            q.push_back(idx);\n            for(int qi=0; qi<(int)q.size(); qi++){\n                int u = q[qi];\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(r>0){\n                    int v = u - N;\n                    if(!vis[v] && b[v]!=0 && (t&2) && (b[v]&8)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(!vis[v] && b[v]!=0 && (t&8) && (b[v]&2)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(c>0){\n                    int v = u - 1;\n                    if(!vis[v] && b[v]!=0 && (t&1) && (b[v]&4)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n                if(c+1<N){\n                    int v = u + 1;\n                    if(!vis[v] && b[v]!=0 && (t&4) && (b[v]&1)){\n                        vis[v]=1;\n                        q.push_back(v);\n                    }\n                }\n            }\n            for(int u: q) mark[u]=1;\n            int edges = 0;\n            for(int u: q){\n                int r = u / N;\n                int c = u - r*N;\n                int t = b[u];\n                if(c+1<N){\n                    int v = u + 1;\n                    if(mark[v] && (t&4) && (b[v]&1)) edges++;\n                }\n                if(r+1<N){\n                    int v = u + N;\n                    if(mark[v] && (t&8) && (b[v]&2)) edges++;\n                }\n            }\n            for(int u: q) mark[u]=0;\n            int sz = (int)q.size();\n            int cycles = edges - sz + 1; // >=0\n            if(cycles==0 && sz > best_tree){\n                best_tree = sz;\n            }\n            if(sz > best_comp){\n                best_comp = sz;\n                cycles_of_best = cycles;\n            }else if(sz == best_comp){\n                cycles_of_best = min(cycles_of_best, cycles);\n            }\n        }\n        if(cycles_of_best==1000000000) cycles_of_best = 0;\n        return {best_tree, best_comp, cycles_of_best, good_edges};\n    }\n\n    char inverse_move(char c){\n        if(c=='U') return 'D';\n        if(c=='D') return 'U';\n        if(c=='L') return 'R';\n        if(c=='R') return 'L';\n        return '?';\n    }\n\n    bool better_metric(const Metric& a, const Metric& b){\n        if(a.tree_size != b.tree_size) return a.tree_size > b.tree_size;\n        if(a.comp_size != b.comp_size) return a.comp_size > b.comp_size;\n        if(a.cycles_large != b.cycles_large) return a.cycles_large < b.cycles_large;\n        return a.good_edges > b.good_edges;\n    }\n\n    string compress_moves(const string& seq){\n        string st;\n        st.reserve(seq.size());\n        for(char c: seq){\n            if(!st.empty() && inverse_move(c) == st.back()){\n                st.pop_back();\n            }else{\n                st.push_back(c);\n            }\n        }\n        return st;\n    }\n\n    // perform one random-greedy walk using depth-2 lookahead in greedy case\n    pair<Metric,string> walk(){\n        vector<uint8_t> board = init_board;\n        int zero = init_zero;\n        string moves;\n        moves.reserve(Tlim);\n        Metric curr = compute_metric(board);\n        Metric best = curr;\n        string best_seq;\n        char prev_move = '?';\n        uniform_real_distribution<double> dist01(0.0,1.0);\n        int stagnate = 0;\n        for(int step=0; step<Tlim; step++){\n            if(chrono::steady_clock::now() > end_time) break;\n            double progress = (double)step / (double)Tlim;\n            double eps = 0.25 + (0.05 - 0.25) * progress; // annealing\n            const auto& opts_all = moves_from[zero];\n            vector<pair<char,int>> opts;\n            opts.reserve(4);\n            char inv = inverse_move(prev_move);\n            for(auto &p: opts_all){\n                if(inv==p.first && (int)opts_all.size()>1) continue;\n                opts.push_back(p);\n            }\n            if(opts.empty()) opts = opts_all;\n            char chosen_move;\n            int chosen_delta;\n            Metric chosen_metric;\n            double rnd = dist01(rng);\n            if(rnd < eps){\n                uniform_int_distribution<int> dist(0, (int)opts.size()-1);\n                int k = dist(rng);\n                chosen_move = opts[k].first;\n                chosen_delta = opts[k].second;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                chosen_metric = compute_metric(board);\n            }else{\n                // depth-2 lookahead\n                Metric best_two = {-1,-1,1000000000,-1};\n                Metric best_first_met = {-1,-1,1000000000,-1};\n                vector<int> best_first_idx;\n                best_first_idx.reserve(4);\n                for(int i=0; i<(int)opts.size(); i++){\n                    int d1 = opts[i].second;\n                    char mv1 = opts[i].first;\n                    swap(board[zero], board[zero+d1]);\n                    int zero1 = zero + d1;\n                    Metric m1 = compute_metric(board);\n                    const auto& opts2_all = moves_from[zero1];\n                    vector<pair<char,int>> opts2;\n                    opts2.reserve(4);\n                    char inv1 = inverse_move(mv1);\n                    for(auto &p2: opts2_all){\n                        if(inv1==p2.first && (int)opts2_all.size()>1) continue;\n                        opts2.push_back(p2);\n                    }\n                    if(opts2.empty()) opts2 = opts2_all;\n                    Metric best_m2 = m1;\n                    for(auto &p2: opts2){\n                        int d2 = p2.second;\n                        swap(board[zero1], board[zero1+d2]);\n                        Metric m2 = compute_metric(board);\n                        swap(board[zero1], board[zero1+d2]);\n                        if(better_metric(m2, best_m2)){\n                            best_m2 = m2;\n                        }\n                    }\n                    if(better_metric(best_m2, best_two)){\n                        best_two = best_m2;\n                        best_first_met = m1;\n                        best_first_idx.clear();\n                        best_first_idx.push_back(i);\n                    }else if(best_m2.tree_size == best_two.tree_size &&\n                             best_m2.comp_size == best_two.comp_size &&\n                             best_m2.cycles_large == best_two.cycles_large &&\n                             best_m2.good_edges == best_two.good_edges){\n                        // tie-break with first metric\n                        if(better_metric(m1, best_first_met)){\n                            best_first_met = m1;\n                            best_first_idx.clear();\n                            best_first_idx.push_back(i);\n                        }else if(m1.tree_size == best_first_met.tree_size &&\n                                 m1.comp_size == best_first_met.comp_size &&\n                                 m1.cycles_large == best_first_met.cycles_large &&\n                                 m1.good_edges == best_first_met.good_edges){\n                            best_first_idx.push_back(i);\n                        }\n                    }\n                    swap(board[zero], board[zero+d1]); // revert first move\n                }\n                int chosen_i;\n                if(!best_first_idx.empty()){\n                    uniform_int_distribution<int> dist(0, (int)best_first_idx.size()-1);\n                    chosen_i = best_first_idx[dist(rng)];\n                }else{\n                    chosen_i = 0;\n                }\n                chosen_move = opts[chosen_i].first;\n                chosen_delta = opts[chosen_i].second;\n                swap(board[zero], board[zero+chosen_delta]);\n                zero += chosen_delta;\n                chosen_metric = compute_metric(board);\n            }\n            moves.push_back(chosen_move);\n            prev_move = chosen_move;\n            curr = chosen_metric;\n            if(better_metric(curr, best)){\n                best = curr;\n                best_seq = moves;\n                stagnate = 0;\n                if(best.tree_size == full_size) break;\n            }else{\n                stagnate++;\n                if(stagnate > 250){\n                    int rand_steps = 3;\n                    for(int t=0; t<rand_steps && (int)moves.size()<Tlim; t++){\n                        const auto& ropts = moves_from[zero];\n                        uniform_int_distribution<int> dist(0, (int)ropts.size()-1);\n                        int k = dist(rng);\n                        char mv = ropts[k].first;\n                        int d = ropts[k].second;\n                        moves.push_back(mv);\n                        swap(board[zero], board[zero+d]);\n                        zero += d;\n                        prev_move = mv;\n                    }\n                    stagnate = 0;\n                    curr = compute_metric(board);\n                }\n            }\n        }\n        return {best, best_seq};\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin >> N >> Tlim;\n        NN = N*N;\n        full_size = NN - 1;\n        init_board.assign(NN, 0);\n        for(int i=0;i<N;i++){\n            string s; cin >> s;\n            for(int j=0;j<N;j++){\n                int v = hexval(s[j]);\n                init_board[i*N + j] = (uint8_t)v;\n                if(v==0) init_zero = i*N + j;\n            }\n        }\n        // precompute moves\n        moves_from.resize(NN);\n        for(int pos=0; pos<NN; pos++){\n            int r = pos / N;\n            int c = pos - r*N;\n            if(r>0) moves_from[pos].push_back({'U', -N});\n            if(r+1<N) moves_from[pos].push_back({'D', N});\n            if(c>0) moves_from[pos].push_back({'L', -1});\n            if(c+1<N) moves_from[pos].push_back({'R', 1});\n        }\n        Metric init_metric = compute_metric(init_board);\n        Metric best_global = init_metric;\n        string best_seq;\n        end_time = chrono::steady_clock::now() + chrono::milliseconds(2800);\n        while(chrono::steady_clock::now() < end_time){\n            auto res = walk();\n            Metric m = res.first;\n            string seq = res.second;\n            if(better_metric(m, best_global)){\n                best_global = m;\n                best_seq = seq;\n            }else if(m.tree_size == best_global.tree_size &&\n                     m.comp_size == best_global.comp_size &&\n                     m.cycles_large == best_global.cycles_large &&\n                     m.good_edges == best_global.good_edges){\n                if(!seq.empty() && (best_seq.empty() || seq.size() < best_seq.size())){\n                    best_seq = seq;\n                }\n            }\n        }\n        best_seq = compress_moves(best_seq);\n        if((int)best_seq.size() > Tlim) best_seq.resize(Tlim);\n        cout << best_seq << \"\\n\";\n    }\n};\n\nint main(){\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    int obj = -1;\n    int V = 0, H = 0;\n    int step1 = 0, step2 = 0;\n    int off1 = 0, off2 = 0;\n    int mode = 0;\n    vector<int> c1, c2; // constants (unshifted)\n};\n\nconst int R = 10000;\nconst int BIG = 1000000000;\nconst double TIME_LIMIT = 2.9;\n\nint N, K;\nint a_need[11];\nvector<pair<int,int>> pts;\n\nvector<pair<int,int>> normals;\nvector<int> norm_range;\nvector<int> norm_shift;\nvector<vector<int>> norm_coords;\n\nstruct Mode { int n1, n2; };\nvector<Mode> modes;\n\nSolution best;\n\nmt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\nauto start_time = chrono::steady_clock::now();\ninline double elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n}\n\nunordered_map<long long, vector<int>> offset_cache;\n\nvector<int> get_best_offsets(int step, int norm_idx) {\n    if (step <= 0) return {0};\n    long long key = (static_cast<long long>(norm_idx) << 20) ^ step;\n    auto it = offset_cache.find(key);\n    if (it != offset_cache.end()) return it->second;\n    vector<int> cnt(step, 0);\n    const vector<int> &vals = norm_coords[norm_idx];\n    for (int v : vals) {\n        int r = v % step;\n        if (r < 0) r += step;\n        cnt[r]++;\n    }\n    int minc = *min_element(cnt.begin(), cnt.end());\n    vector<int> offs;\n    for (int i = 0; i < step && (int)offs.size() < 12; i++) {\n        if (cnt[i] == minc) offs.push_back(i);\n    }\n    if ((int)offs.size() < 8) {\n        int sec = INT_MAX;\n        for (int c : cnt) if (c > minc) sec = min(sec, c);\n        for (int i = 0; i < step && (int)offs.size() < 16; i++) {\n            if (cnt[i] == sec) offs.push_back(i);\n        }\n    }\n    for (int t = 0; t < 4 && (int)offs.size() < 20; t++) offs.push_back((int)(rng() % step));\n    sort(offs.begin(), offs.end());\n    offs.erase(unique(offs.begin(), offs.end()), offs.end());\n    offset_cache[key] = offs;\n    return offs;\n}\n\nint evaluate_grid(int V, int H, int step1, int off1, int step2, int off2, int mode, bool update_best = true) {\n    int rows = V + 1;\n    int cols = H + 1;\n    int sz = rows * cols;\n    static vector<int> cnt;\n    cnt.assign(sz, 0);\n\n    const Mode &m = modes[mode];\n    int nidx1 = m.n1, nidx2 = m.n2;\n    int shift1 = norm_shift[nidx1];\n    int shift2 = norm_shift[nidx2];\n    int first1 = off1 + step1;\n    int first2 = off2 + step2;\n\n    const vector<int> &coord1 = norm_coords[nidx1];\n    const vector<int> &coord2 = norm_coords[nidx2];\n\n    for (int i = 0; i < N; i++) {\n        int t1 = coord1[i];\n        int t2 = coord2[i];\n        int cidx = 0, ridx = 0;\n        if (V > 0) {\n            int diff1 = t1 - first1;\n            if (diff1 >= 0) {\n                int q = diff1 / step1;\n                if (q < V && diff1 % step1 == 0) continue; // on line\n                cidx = q + 1;\n                if (cidx > V) cidx = V;\n            } else cidx = 0;\n        }\n        if (H > 0) {\n            int diff2 = t2 - first2;\n            if (diff2 >= 0) {\n                int q = diff2 / step2;\n                if (q < H && diff2 % step2 == 0) continue; // on line\n                ridx = q + 1;\n                if (ridx > H) ridx = H;\n            } else ridx = 0;\n        }\n        cnt[cidx * cols + ridx]++;\n    }\n    int b[11] = {0};\n    for (int v : cnt) {\n        if (v >= 1 && v <= 10) b[v]++;\n    }\n    int obj = 0;\n    for (int d = 1; d <= 10; d++) obj += min(a_need[d], b[d]);\n\n    if (update_best && obj > best.obj) {\n        best.obj = obj;\n        best.V = V; best.H = H;\n        best.step1 = step1; best.step2 = step2;\n        best.off1 = off1; best.off2 = off2;\n        best.mode = mode;\n        best.c1.resize(V);\n        best.c2.resize(H);\n        for (int i = 0; i < V; i++) {\n            int c = (off1 + step1 * (i + 1)) - shift1;\n            best.c1[i] = c;\n        }\n        for (int j = 0; j < H; j++) {\n            int c = (off2 + step2 * (j + 1)) - shift2;\n            best.c2[j] = c;\n        }\n    }\n    return obj;\n}\n\ndouble expected_obj_pair(int V, int H) {\n    int cells = (V + 1) * (H + 1);\n    double lambda = (double)N / cells;\n    double eexp = exp(-lambda);\n    double sum = 0.0;\n    double lp = 1.0;\n    for (int d = 1; d <= 10; d++) {\n        lp *= lambda;\n        double pd = lp * eexp / tgamma(d + 1);\n        double bd = cells * pd;\n        sum += min((double)a_need[d], bd);\n    }\n    return sum;\n}\n\nvoid optimize_pair(int V, int H, int mode) {\n    const Mode &m = modes[mode];\n    int range1 = norm_range[m.n1];\n    int range2 = norm_range[m.n2];\n    vector<double> factors = {1.0, 0.85, 1.15};\n    int best_step1 = 1, best_step2 = 1;\n    int quick_best = -1;\n    for (double f : factors) {\n        int step1 = max(1, (int)(range1 * f / (V + 1)));\n        int step2 = max(1, (int)(range2 * f / (H + 1)));\n        vector<int> offs1 = get_best_offsets(step1, m.n1);\n        vector<int> offs2 = get_best_offsets(step2, m.n2);\n        int off1 = offs1.empty() ? 0 : offs1[0];\n        int off2 = offs2.empty() ? 0 : offs2[0];\n        int val = evaluate_grid(V, H, step1, off1, step2, off2, mode, true);\n        if (val > quick_best) {\n            quick_best = val;\n            best_step1 = step1;\n            best_step2 = step2;\n        }\n    }\n    int step1 = best_step1;\n    int step2 = best_step2;\n    vector<int> offs1 = get_best_offsets(step1, m.n1);\n    vector<int> offs2 = get_best_offsets(step2, m.n2);\n    if (offs1.empty()) offs1.push_back(0);\n    if (offs2.empty()) offs2.push_back(0);\n\n    // multi-start: top offsets combos\n    int maxO1 = min(3, (int)offs1.size());\n    int maxO2 = min(3, (int)offs2.size());\n    vector<pair<int,int>> starts;\n    for (int i = 0; i < maxO1; i++) {\n        for (int j = 0; j < maxO2; j++) {\n            starts.emplace_back(offs1[i], offs2[j]);\n        }\n    }\n    for (int t = 0; t < 2; t++) {\n        starts.emplace_back((int)(rng() % step1), (int)(rng() % step2));\n    }\n    int best_off1 = offs1[0], best_off2 = offs2[0];\n    int cur_best = -1;\n    for (auto &st : starts) {\n        if (elapsed() > TIME_LIMIT) break;\n        int val = evaluate_grid(V, H, step1, st.first, step2, st.second, mode, true);\n        if (val > cur_best) {\n            cur_best = val;\n            best_off1 = st.first;\n            best_off2 = st.second;\n        }\n    }\n    if (elapsed() > TIME_LIMIT) return;\n    int off1 = best_off1, off2 = best_off2;\n    int cur = cur_best;\n    if (cur < 0) cur = evaluate_grid(V, H, step1, off1, step2, off2, mode, true);\n    const int MAX_SCAN = 800; // slightly smaller for speed\n    bool improved = true;\n    while (improved && elapsed() < TIME_LIMIT) {\n        improved = false;\n        int bo1 = off1, bo2 = off2;\n        int bval = cur;\n        // scan off1\n        if (step1 <= MAX_SCAN) {\n            for (int o1 = 0; o1 < step1; o1++) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, step1, o1, step2, off2, mode, true);\n                if (val > bval) { bval = val; bo1 = o1; }\n            }\n        } else {\n            int stride = max(1, step1 / MAX_SCAN);\n            for (int o1 = 0; o1 < step1; o1 += stride) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, step1, o1, step2, off2, mode, true);\n                if (val > bval) { bval = val; bo1 = o1; }\n            }\n            for (int t = 0; t < 100 && elapsed() < TIME_LIMIT; t++) {\n                int o1 = (int)(rng() % step1);\n                int val = evaluate_grid(V, H, step1, o1, step2, off2, mode, true);\n                if (val > bval) { bval = val; bo1 = o1; }\n            }\n        }\n        if (bo1 != off1) { off1 = bo1; cur = bval; improved = true; }\n        if (elapsed() > TIME_LIMIT) break;\n        // scan off2\n        bo1 = off1; bo2 = off2; bval = cur;\n        if (step2 <= MAX_SCAN) {\n            for (int o2 = 0; o2 < step2; o2++) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, step1, off1, step2, o2, mode, true);\n                if (val > bval) { bval = val; bo2 = o2; }\n            }\n        } else {\n            int stride = max(1, step2 / MAX_SCAN);\n            for (int o2 = 0; o2 < step2; o2 += stride) {\n                if (elapsed() > TIME_LIMIT) break;\n                int val = evaluate_grid(V, H, step1, off1, step2, o2, mode, true);\n                if (val > bval) { bval = val; bo2 = o2; }\n            }\n            for (int t = 0; t < 100 && elapsed() < TIME_LIMIT; t++) {\n                int o2 = (int)(rng() % step2);\n                int val = evaluate_grid(V, H, step1, off1, step2, o2, mode, true);\n                if (val > bval) { bval = val; bo2 = o2; }\n            }\n        }\n        if (bo2 != off2) { off2 = bo2; cur = bval; improved = true; }\n    }\n}\n\nlong long extgcd(long long a, long long b, long long &x, long long &y) {\n    if (b == 0) { x = (a >= 0 ? 1 : -1); y = 0; return llabs(a); }\n    long long x1, y1;\n    long long g = extgcd(b, a % b, x1, y1);\n    x = y1;\n    y = x1 - y1 * (a / b);\n    return g;\n}\n\nvoid output_line(long long a, long long b, long long c) {\n    long long x0, y0;\n    long long g = extgcd(a, b, x0, y0);\n    if (c % g != 0) {\n        if (a != 0) {\n            long long x = c / a;\n            cout << x << \" \" << -BIG << \" \" << x << \" \" << BIG << \"\\n\";\n        } else {\n            long long y = c / b;\n            cout << -BIG << \" \" << y << \" \" << BIG << \" \" << y << \"\\n\";\n        }\n        return;\n    }\n    long long mul = c / g;\n    x0 *= mul;\n    y0 *= mul;\n    long long dx = -b / g;\n    long long dy = a / g;\n    long long L = 1000000;\n    long long x1 = x0 + dx * L;\n    long long y1 = y0 + dy * L;\n    long long x2 = x0 - dx * L;\n    long long y2 = y0 - dy * L;\n    x1 = max(-1LL * BIG, min(1LL * BIG, x1));\n    y1 = max(-1LL * BIG, min(1LL * BIG, y1));\n    x2 = max(-1LL * BIG, min(1LL * BIG, x2));\n    y2 = max(-1LL * BIG, min(1LL * BIG, y2));\n    if (x1 == x2 && y1 == y2) {\n        x2 += (dx == 0 ? 1 : dx);\n        y2 += (dy == 0 ? 1 : dy);\n    }\n    cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> K)) return 0;\n    for (int d = 1; d <= 10; d++) cin >> a_need[d];\n    pts.resize(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].first >> pts[i].second;\n\n    // normals\n    normals = {{1,0},{0,1},{1,1},{1,-1},{1,2},{2,-1}};\n    int M = normals.size();\n    norm_range.resize(M);\n    norm_shift.resize(M);\n    norm_coords.assign(M, vector<int>(N));\n    for (int idx = 0; idx < M; idx++) {\n        int a = normals[idx].first;\n        int b = normals[idx].second;\n        double len = hypot((double)a, (double)b);\n        int range = (int)ceil(2.0 * R * len) + 1;\n        int shift = range / 2;\n        norm_range[idx] = range;\n        norm_shift[idx] = shift;\n        auto &vec = norm_coords[idx];\n        for (int i = 0; i < N; i++) {\n            long long t = 1LL * a * pts[i].first + 1LL * b * pts[i].second;\n            t += shift;\n            vec[i] = (int)t;\n        }\n    }\n    // modes\n    modes.push_back({0,1}); // axis\n    modes.push_back({2,3}); // diag\n    modes.push_back({4,5}); // oblique\n\n    // candidate pairs\n    vector<pair<int,int>> pairs;\n    auto addPair = [&](int v, int h) {\n        if (v < 0 || h < 0) return;\n        if (v + h > K) return;\n        if (v > 100 || h > 100) return;\n        pairs.emplace_back(v, h);\n    };\n    vector<pair<double,double>> lambdaScore;\n    for (double lam = 0.8; lam <= 8.0; lam += 0.2) {\n        double cells = (double)N / lam;\n        double eexp = exp(-lam);\n        double sum = 0.0, lp = 1.0;\n        for (int d = 1; d <= 10; d++) {\n            lp *= lam;\n            double pd = lp * eexp / tgamma(d + 1);\n            double bd = cells * pd;\n            sum += min((double)a_need[d], bd);\n        }\n        lambdaScore.emplace_back(-sum, lam);\n    }\n    sort(lambdaScore.begin(), lambdaScore.end());\n    int topLam = 6;\n    for (int i = 0; i < (int)lambdaScore.size() && i < topLam; i++) {\n        double lam = lambdaScore[i].second;\n        double cells = (double)N / lam;\n        double base = sqrt(max(1.0, cells)) - 1.0;\n        int v0 = max(0, (int)(base + 0.5));\n        for (int dv = -2; dv <= 2; dv++) {\n            int v = v0 + dv;\n            if (v < 0) continue;\n            addPair(v, v);\n            addPair(v, v + 1);\n            addPair(v + 1, v);\n        }\n    }\n    vector<int> fixed = {8,12,16,20,24,28,32,36,40,44,48,52,56,60};\n    for (int v : fixed) if (2 * v <= K) addPair(v, v);\n    for (int v = 20; v <= 60; v += 5) {\n        for (int h = 20; h <= 60; h += 5) addPair(v, h);\n    }\n    vector<double> lamc = {1.2,1.6,2.0,2.4,3.0};\n    for (double lam : lamc) {\n        double target = (double)N / lam;\n        for (int v = 5; v <= 70; v += 5) {\n            int h = (int)(target / (v + 1) - 1);\n            for (int dh = -2; dh <= 2; dh++) addPair(v, h + dh);\n        }\n    }\n    sort(pairs.begin(), pairs.end());\n    pairs.erase(unique(pairs.begin(), pairs.end()), pairs.end());\n\n    vector<pair<double, pair<int,int>>> order;\n    for (auto &pr : pairs) {\n        double eo = expected_obj_pair(pr.first, pr.second);\n        order.push_back({-eo, pr});\n    }\n    sort(order.begin(), order.end());\n\n    int maxMode[3] = {8,6,4};\n    int done[3] = {0,0,0};\n    for (auto &ord : order) {\n        if (elapsed() > TIME_LIMIT) break;\n        int V = ord.second.first;\n        int H = ord.second.second;\n        for (int m = 0; m < (int)modes.size(); m++) {\n            if (done[m] >= maxMode[m]) continue;\n            optimize_pair(V, H, m);\n            done[m]++;\n            if (elapsed() > TIME_LIMIT) break;\n        }\n        bool all = true;\n        for (int m = 0; m < (int)modes.size(); m++) if (done[m] < maxMode[m]) all = false;\n        if (all) break;\n    }\n\n    // local search around best V,H\n    if (best.obj >= 0) {\n        for (int dV = -2; dV <= 2; dV++) {\n            for (int dH = -2; dH <= 2; dH++) {\n                if (dV == 0 && dH == 0) continue;\n                if (elapsed() > TIME_LIMIT) break;\n                int V = best.V + dV;\n                int H = best.H + dH;\n                if (V < 0 || H < 0 || V + H > K) continue;\n                optimize_pair(V, H, best.mode);\n            }\n            if (elapsed() > TIME_LIMIT) break;\n        }\n    }\n\n    // random search\n    while (elapsed() < TIME_LIMIT) {\n        int V = (int)(rng() % 71);\n        int H = (int)(rng() % 71);\n        if (V + H > K) continue;\n        int mode = rng() % modes.size();\n        const Mode &md = modes[mode];\n        int base1 = norm_range[md.n1];\n        int base2 = norm_range[md.n2];\n        double f;\n        int r = rng() % 3;\n        if (r == 0) f = 0.85;\n        else if (r == 1) f = 1.15;\n        else f = 1.0;\n        int step1 = max(1, (int)(base1 * f / (V + 1)));\n        int step2 = max(1, (int)(base2 * f / (H + 1)));\n        int off1 = (int)(rng() % step1);\n        int off2 = (int)(rng() % step2);\n        evaluate_grid(V, H, step1, off1, step2, off2, mode, true);\n    }\n\n    int k = (int)best.c1.size() + (int)best.c2.size();\n    cout << k << \"\\n\";\n    const Mode &bm = modes[best.mode];\n    int a1 = normals[bm.n1].first, b1 = normals[bm.n1].second;\n    int a2 = normals[bm.n2].first, b2 = normals[bm.n2].second;\n    for (int c : best.c1) output_line(a1, b1, c);\n    for (int c : best.c2) output_line(a2, b2, c);\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeIndex {\n    int N;\n    int H, V, D1, D2, E;\n    EdgeIndex(int N_) : N(N_) {\n        H = (N - 1) * N;\n        V = H;\n        D1 = (N - 1) * (N - 1);\n        D2 = D1;\n        E = H + V + D1 + D2;\n    }\n    inline int horizId(int x, int y) const { return x + y * (N - 1); }\n    inline int vertId(int x, int y) const { return H + x * (N - 1) + y; }\n    inline int diag1Id(int x, int y) const { return H + V + x * (N - 1) + y; }       // (x,y)-(x+1,y+1)\n    inline int diag2Id(int x, int y) const { return H + V + D1 + x * (N - 1) + (y - 1); } // (x,y)-(x+1,y-1)\n    inline int id(int x1, int y1, int x2, int y2) const {\n        int dx = x2 - x1, dy = y2 - y1;\n        if (abs(dx) + abs(dy) == 1) {\n            if (dy == 0) return horizId(min(x1, x2), y1);\n            else return vertId(x1, min(y1, y2));\n        } else if (abs(dx) == 1 && abs(dy) == 1) {\n            if (dx == dy) return diag1Id(min(x1, x2), min(y1, y2));\n            else return diag2Id(min(x1, x2), max(y1, y2));\n        }\n        return -1;\n    }\n};\n\nstruct Cand {\n    uint8_t type; //0 rect axis,1 diamond,2 diag-rect\n    uint8_t miss;\n    uint8_t dx, dy; // rect: dx,dy; diamond: dx=r; diag-rect: dx=a, dy=b\n    uint16_t x0, y0; // rect: bottom-left; diamond: center; diag: p0\n    int w;\n    int score;\n};\n\nstruct CompScore {\n    bool operator()(const Cand &a, const Cand &b) const { return a.score < b.score; }\n};\n\nclass Pool {\n    int mode; //0 score,1 fifo,2 random\n    priority_queue<Cand, vector<Cand>, CompScore> pq;\n    deque<Cand> dq;\n    vector<Cand> vec;\n    mt19937 rng;\npublic:\n    Pool(int m, uint32_t seed) : mode(m), rng(seed) {}\n    void push(const Cand &c) {\n        if (mode == 0) pq.push(c);\n        else if (mode == 1) dq.push_back(c);\n        else vec.push_back(c);\n    }\n    bool empty() const {\n        if (mode == 0) return pq.empty();\n        if (mode == 1) return dq.empty();\n        return vec.empty();\n    }\n    Cand pop() {\n        if (mode == 0) { Cand c=pq.top(); pq.pop(); return c; }\n        if (mode == 1) { Cand c=dq.front(); dq.pop_front(); return c; }\n        int idx = (int)(rng()%vec.size());\n        Cand c = vec[idx];\n        vec[idx]=vec.back();\n        vec.pop_back();\n        return c;\n    }\n};\n\nstruct Stage {\n    int maxA; // axis rectangle size\n    int maxD; // diamond radius\n    int maxR; // diag-rect lengths\n    int longA; // thin rect length\n    int longR; // thin diag length\n    int mode; // pool mode\n    int prio; //0 weight,1 ratio\n};\n\nstruct Result {\n    long long total;\n    vector<array<int,8>> ops;\n};\n\ninline int jitterVal(int x0,int y0,int dx,int dy,uint32_t seed){\n    uint32_t h = seed;\n    h ^= (uint32_t)(x0 * 73856093);\n    h ^= (uint32_t)(y0 * 19349663);\n    h ^= (uint32_t)(dx * 83492791);\n    h ^= (uint32_t)(dy * 1234567);\n    h ^= (h >> 16);\n    return (int)(h & 7);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    vector<pair<int,int>> initialDots(M);\n    for (int i=0;i<M;i++){\n        int x,y;cin>>x>>y;\n        initialDots[i]={x,y};\n    }\n    EdgeIndex EI(N);\n    int NN = N*N;\n    vector<int> weight(NN);\n    int c = (N-1)/2;\n    for (int x=0;x<N;x++) for (int y=0;y<N;y++){\n        int dx=x-c, dy=y-c;\n        weight[x*N+y]=dx*dx+dy*dy+1;\n    }\n    vector<char> initialHas(NN,0);\n    long long initSum=0;\n    vector<pair<int,int>> initList;\n    initList.reserve(M+8000);\n    for (auto &p: initialDots){\n        int id=p.first*N+p.second;\n        if (!initialHas[id]){\n            initialHas[id]=1;\n            initSum += weight[id];\n            initList.push_back(p);\n        }\n    }\n    uint64_t seedBase=1234567;\n    seedBase = seedBase*1000003 + N;\n    seedBase = seedBase*1000003 + M;\n    for (auto &p: initialDots){\n        seedBase ^= (uint64_t)(p.first+1)*10007 + (uint64_t)(p.second+1)*1000003 + 12345;\n        seedBase = seedBase*1000003 + 1;\n    }\n\n    vector<vector<Stage>> configList;\n    configList.push_back({{8,4,2,18,6,0,0},{6,3,2,10,4,0,1}});\n    configList.push_back({{6,3,2,12,5,0,1},{10,5,2,14,5,0,0}});\n    configList.push_back({{4,2,3,10,4,1,1},{7,3,3,12,4,0,0},{10,4,2,12,4,0,0}});\n    configList.push_back({{5,2,2,10,4,2,1},{8,3,2,12,4,0,0},{11,5,2,14,4,0,0}});\n    configList.push_back({{12,6,1,16,6,0,0}});\n    configList.push_back({{7,4,3,12,5,2,1},{9,5,2,14,5,2,0}});\n    configList.push_back({{9,4,2,14,5,0,0},{6,3,2,12,4,1,1}});\n\n    const double TIME_LIMIT = 4.95;\n    auto startTime = chrono::steady_clock::now();\n\n    auto simulate = [&](const vector<Stage> &seq, uint32_t baseSeed)->Result{\n        vector<char> has=initialHas;\n        vector<char> used(EI.E,0);\n        vector<pair<int,int>> dotList=initList;\n        long long total=initSum;\n        vector<array<int,8>> ops;\n\n        for (int si=0; si<(int)seq.size(); si++){\n            if (chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>TIME_LIMIT) break;\n            const Stage &st=seq[si];\n            Pool pool(st.mode, baseSeed + si*1000003u);\n\n            auto scoreRect=[&](int w,int per){ if (st.prio==0) return w; return (w*1024)/max(1,per); };\n\n            auto evalRectAxis = [&](int x0,int y0,int dx,int dy){\n                int x1=x0+dx, y1=y0+dy;\n                if (x0<0||y0<0||x1>=N||y1>=N) return;\n                int cid[4]={x0*N+y0, x1*N+y0, x1*N+y1, x0*N+y1};\n                int cnt=has[cid[0]]+has[cid[1]]+has[cid[2]]+has[cid[3]];\n                if (cnt!=3) return;\n                int miss;\n                if (!has[cid[0]]) miss=0;\n                else if (!has[cid[1]]) miss=1;\n                else if (!has[cid[2]]) miss=2;\n                else miss=3;\n                for (int i=0;i<dx;i++){\n                    int e1=EI.horizId(x0+i,y0), e2=EI.horizId(x0+i,y1);\n                    if (used[e1]||used[e2]) return;\n                }\n                for (int j=0;j<dy;j++){\n                    int e1=EI.vertId(x0,y0+j), e2=EI.vertId(x1,y0+j);\n                    if (used[e1]||used[e2]) return;\n                }\n                if (dx>1){\n                    for (int i=1;i<dx;i++){\n                        if (has[(x0+i)*N+y0]) return;\n                        if (has[(x0+i)*N+y1]) return;\n                    }\n                }\n                if (dy>1){\n                    for (int j=1;j<dy;j++){\n                        if (has[x0*N+(y0+j)]) return;\n                        if (has[x1*N+(y0+j)]) return;\n                    }\n                }\n                int w=weight[cid[miss]];\n                Cand cnd; cnd.type=0; cnd.miss=miss; cnd.dx=dx; cnd.dy=dy; cnd.x0=x0; cnd.y0=y0; cnd.w=w;\n                cnd.score=scoreRect(w, 2*(dx+dy)) + jitterVal(x0,y0,dx,dy,baseSeed);\n                pool.push(cnd);\n            };\n\n            auto evalDiamond = [&](int cx,int cy,int r){\n                if (cx-r<0||cx+r>=N||cy-r<0||cy+r>=N) return;\n                int cid[4]={ (cx+r)*N+cy, cx*N+(cy+r), (cx-r)*N+cy, cx*N+(cy-r) };\n                int cnt=has[cid[0]]+has[cid[1]]+has[cid[2]]+has[cid[3]];\n                if (cnt!=3) return;\n                int miss;\n                if (!has[cid[0]]) miss=0;\n                else if (!has[cid[1]]) miss=1;\n                else if (!has[cid[2]]) miss=2;\n                else miss=3;\n                for (int t=0;t<r;t++){\n                    int x,y,e;\n                    x=cx+r-t; y=cy+t; e=EI.id(x,y,x-1,y+1); if (used[e]) return;\n                    x=cx-t; y=cy+r-t; e=EI.id(x,y,x-1,y-1); if (used[e]) return;\n                    x=cx-r+t; y=cy-t; e=EI.id(x,y,x+1,y-1); if (used[e]) return;\n                    x=cx+t; y=cy-r+t; e=EI.id(x,y,x+1,y+1); if (used[e]) return;\n                }\n                for (int t=1;t<r;t++){\n                    if (has[(cx+r-t)*N+(cy+t)]) return;\n                    if (has[(cx-t)*N+(cy+r-t)]) return;\n                    if (has[(cx-r+t)*N+(cy-t)]) return;\n                    if (has[(cx+t)*N+(cy-r+t)]) return;\n                }\n                int w=weight[cid[miss]];\n                Cand cnd; cnd.type=1; cnd.miss=miss; cnd.dx=r; cnd.dy=0; cnd.x0=cx; cnd.y0=cy; cnd.w=w;\n                cnd.score=scoreRect(w, 4*r) + jitterVal(cx,cy,r,0,baseSeed+31);\n                pool.push(cnd);\n            };\n\n            auto evalDiagRect = [&](int x0,int y0,int a,int b){\n                int x1=x0+a, y1=y0+a;\n                int x2=x0+a+b, y2=y0+a-b;\n                int x3=x0+b, y3=y0-b;\n                if (x0<0||y0<0||x2>=N||y1>=N||y3<0) return;\n                int cid[4]={x0*N+y0, x1*N+y1, x2*N+y2, x3*N+y3};\n                int cnt=has[cid[0]]+has[cid[1]]+has[cid[2]]+has[cid[3]];\n                if (cnt!=3) return;\n                int miss;\n                if (!has[cid[0]]) miss=0;\n                else if (!has[cid[1]]) miss=1;\n                else if (!has[cid[2]]) miss=2;\n                else miss=3;\n                for (int i=0;i<a;i++){\n                    int e1=EI.id(x0+i,y0+i,x0+i+1,y0+i+1);\n                    int e2=EI.id(x3+i,y3+i,x3+i+1,y3+i+1);\n                    if (used[e1]||used[e2]) return;\n                }\n                for (int i=0;i<b;i++){\n                    int e1=EI.id(x1+i,y1-i,x1+i+1,y1-i-1);\n                    int e2=EI.id(x0+b - i, y0 - b + i, x0+b - i -1, y0 - b + i +1);\n                    if (used[e1]||used[e2]) return;\n                }\n                for (int i=1;i<a;i++){\n                    if (has[(x0+i)*N+(y0+i)]) return;\n                    if (has[(x3+i)*N+(y3+i)]) return;\n                }\n                for (int i=1;i<b;i++){\n                    if (has[(x1+i)*N+(y1-i)]) return;\n                    if (has[(x0+b - i)*N+(y0 - b + i)]) return;\n                }\n                int w=weight[cid[miss]];\n                Cand cnd; cnd.type=2; cnd.miss=miss; cnd.dx=a; cnd.dy=b; cnd.x0=x0; cnd.y0=y0; cnd.w=w;\n                cnd.score=scoreRect(w, 2*(a+b)) + jitterVal(x0,y0,a,b,baseSeed+97);\n                pool.push(cnd);\n            };\n\n            auto addFromPoint = [&](int x,int y){\n                for (int dx=1; dx<=st.maxA; dx++){\n                    for (int dy=1; dy<=st.maxA; dy++){\n                        evalRectAxis(x,y,dx,dy);\n                        evalRectAxis(x-dx,y,dx,dy);\n                        evalRectAxis(x,y-dy,dx,dy);\n                        evalRectAxis(x-dx,y-dy,dx,dy);\n                    }\n                }\n                if (st.longA>st.maxA){\n                    for (int len=st.maxA+1; len<=st.longA; len++){\n                        int dx=len, dy=1;\n                        evalRectAxis(x,y,dx,dy);\n                        evalRectAxis(x-dx,y,dx,dy);\n                        evalRectAxis(x,y-dy,dx,dy);\n                        evalRectAxis(x-dx,y-dy,dx,dy);\n                        dx=1; dy=len;\n                        evalRectAxis(x,y,dx,dy);\n                        evalRectAxis(x-dx,y,dx,dy);\n                        evalRectAxis(x,y-dy,dx,dy);\n                        evalRectAxis(x-dx,y-dy,dx,dy);\n                    }\n                }\n                for (int r=1; r<=st.maxD; r++){\n                    evalDiamond(x-r,y,r);\n                    evalDiamond(x,y-r,r);\n                    evalDiamond(x+r,y,r);\n                    evalDiamond(x,y+r,r);\n                }\n                for (int a=1; a<=st.maxR; a++){\n                    for (int b=1; b<=st.maxR; b++){\n                        evalDiagRect(x, y, a, b);\n                        evalDiagRect(x-a, y-a, a, b);\n                        evalDiagRect(x-a-b, y-(a-b), a, b);\n                        evalDiagRect(x-b, y+b, a, b);\n                    }\n                }\n                if (st.longR>st.maxR){\n                    for (int len=st.maxR+1; len<=st.longR; len++){\n                        int a=len,b=1;\n                        evalDiagRect(x, y, a, b);\n                        evalDiagRect(x-a, y-a, a, b);\n                        evalDiagRect(x-a-b, y-(a-b), a, b);\n                        evalDiagRect(x-b, y+b, a, b);\n                        a=1; b=len;\n                        evalDiagRect(x, y, a, b);\n                        evalDiagRect(x-a, y-a, a, b);\n                        evalDiagRect(x-a-b, y-(a-b), a, b);\n                        evalDiagRect(x-b, y+b, a, b);\n                    }\n                }\n            };\n\n            for (auto &p: dotList){\n                addFromPoint(p.first,p.second);\n                if (chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>TIME_LIMIT) break;\n            }\n\n            auto tryApplyRectAxis = [&](const Cand &cnd,int &mx,int &my)->bool{\n                int x0=cnd.x0,y0=cnd.y0,dx=cnd.dx,dy=cnd.dy;\n                int x1=x0+dx, y1=y0+dy;\n                if (x0<0||y0<0||x1>=N||y1>=N) return false;\n                int cid[4]={x0*N+y0,x1*N+y0,x1*N+y1,x0*N+y1};\n                if (has[cid[cnd.miss]]) return false;\n                for (int k=0;k<4;k++) if (k!=cnd.miss && !has[cid[k]]) return false;\n                for (int i=0;i<dx;i++){\n                    int e1=EI.horizId(x0+i,y0), e2=EI.horizId(x0+i,y1);\n                    if (used[e1]||used[e2]) return false;\n                }\n                for (int j=0;j<dy;j++){\n                    int e1=EI.vertId(x0,y0+j), e2=EI.vertId(x1,y0+j);\n                    if (used[e1]||used[e2]) return false;\n                }\n                if (dx>1){\n                    for (int i=1;i<dx;i++){\n                        if (has[(x0+i)*N+y0]) return false;\n                        if (has[(x0+i)*N+y1]) return false;\n                    }\n                }\n                if (dy>1){\n                    for (int j=1;j<dy;j++){\n                        if (has[x0*N+(y0+j)]) return false;\n                        if (has[x1*N+(y0+j)]) return false;\n                    }\n                }\n                has[cid[cnd.miss]]=1;\n                total += cnd.w;\n                for (int i=0;i<dx;i++){\n                    used[EI.horizId(x0+i,y0)]=1;\n                    used[EI.horizId(x0+i,y1)]=1;\n                }\n                for (int j=0;j<dy;j++){\n                    used[EI.vertId(x0,y0+j)]=1;\n                    used[EI.vertId(x1,y0+j)]=1;\n                }\n                mx = (cnd.miss==0||cnd.miss==3)?x0:x1;\n                my = (cnd.miss==0||cnd.miss==1)?y0:y1;\n                array<int,8> op;\n                for (int t=0;t<4;t++){\n                    int idx=(cnd.miss+t)%4;\n                    int ox,oy;\n                    if (idx==0){ox=x0;oy=y0;}\n                    else if (idx==1){ox=x1;oy=y0;}\n                    else if (idx==2){ox=x1;oy=y1;}\n                    else {ox=x0;oy=y1;}\n                    op[2*t]=ox; op[2*t+1]=oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx,my);\n                return true;\n            };\n\n            auto tryApplyDiamond = [&](const Cand &cnd,int &mx,int &my)->bool{\n                int cx=cnd.x0, cy=cnd.y0, r=cnd.dx;\n                if (cx-r<0||cx+r>=N||cy-r<0||cy+r>=N) return false;\n                int cid[4]={ (cx+r)*N+cy, cx*N+(cy+r), (cx-r)*N+cy, cx*N+(cy-r) };\n                if (has[cid[cnd.miss]]) return false;\n                for (int k=0;k<4;k++) if (k!=cnd.miss && !has[cid[k]]) return false;\n                for (int t=0;t<r;t++){\n                    int x,y,e;\n                    x=cx+r-t; y=cy+t; e=EI.id(x,y,x-1,y+1); if (used[e]) return false;\n                    x=cx-t; y=cy+r-t; e=EI.id(x,y,x-1,y-1); if (used[e]) return false;\n                    x=cx-r+t; y=cy-t; e=EI.id(x,y,x+1,y-1); if (used[e]) return false;\n                    x=cx+t; y=cy-r+t; e=EI.id(x,y,x+1,y+1); if (used[e]) return false;\n                }\n                for (int t=1;t<r;t++){\n                    if (has[(cx+r-t)*N+(cy+t)]) return false;\n                    if (has[(cx-t)*N+(cy+r-t)]) return false;\n                    if (has[(cx-r+t)*N+(cy-t)]) return false;\n                    if (has[(cx+t)*N+(cy-r+t)]) return false;\n                }\n                has[cid[cnd.miss]]=1;\n                total += cnd.w;\n                for (int t=0;t<r;t++){\n                    int x,y;\n                    x=cx+r-t; y=cy+t; used[EI.id(x,y,x-1,y+1)]=1;\n                    x=cx-t; y=cy+r-t; used[EI.id(x,y,x-1,y-1)]=1;\n                    x=cx-r+t; y=cy-t; used[EI.id(x,y,x+1,y-1)]=1;\n                    x=cx+t; y=cy-r+t; used[EI.id(x,y,x+1,y+1)]=1;\n                }\n                if (cnd.miss==0){mx=cx+r; my=cy;}\n                else if (cnd.miss==1){mx=cx; my=cy+r;}\n                else if (cnd.miss==2){mx=cx-r; my=cy;}\n                else {mx=cx; my=cy-r;}\n                array<int,8> op;\n                for (int t=0;t<4;t++){\n                    int idx=(cnd.miss+t)%4;\n                    int ox,oy;\n                    if (idx==0){ox=cx+r; oy=cy;}\n                    else if (idx==1){ox=cx; oy=cy+r;}\n                    else if (idx==2){ox=cx-r; oy=cy;}\n                    else {ox=cx; oy=cy-r;}\n                    op[2*t]=ox; op[2*t+1]=oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx,my);\n                return true;\n            };\n\n            auto tryApplyDiag = [&](const Cand &cnd,int &mx,int &my)->bool{\n                int x0=cnd.x0, y0=cnd.y0, a=cnd.dx, b=cnd.dy;\n                int x1=x0+a, y1=y0+a;\n                int x2=x0+a+b, y2=y0+a-b;\n                int x3=x0+b, y3=y0-b;\n                if (x0<0||y0<0||x2>=N||y1>=N||y3<0) return false;\n                int cid[4]={x0*N+y0, x1*N+y1, x2*N+y2, x3*N+y3};\n                if (has[cid[cnd.miss]]) return false;\n                for (int k=0;k<4;k++) if (k!=cnd.miss && !has[cid[k]]) return false;\n                for (int i=0;i<a;i++){\n                    int e1=EI.id(x0+i,y0+i,x0+i+1,y0+i+1);\n                    int e2=EI.id(x3+i,y3+i,x3+i+1,y3+i+1);\n                    if (used[e1]||used[e2]) return false;\n                }\n                for (int i=0;i<b;i++){\n                    int e1=EI.id(x1+i,y1-i,x1+i+1,y1-i-1);\n                    int e2=EI.id(x0+b - i, y0 - b + i, x0+b - i -1, y0 - b + i +1);\n                    if (used[e1]||used[e2]) return false;\n                }\n                for (int i=1;i<a;i++){\n                    if (has[(x0+i)*N+(y0+i)]) return false;\n                    if (has[(x3+i)*N+(y3+i)]) return false;\n                }\n                for (int i=1;i<b;i++){\n                    if (has[(x1+i)*N+(y1-i)]) return false;\n                    if (has[(x0+b - i)*N+(y0 - b + i)]) return false;\n                }\n                has[cid[cnd.miss]]=1;\n                total += cnd.w;\n                for (int i=0;i<a;i++){\n                    used[EI.id(x0+i,y0+i,x0+i+1,y0+i+1)] = 1;\n                    used[EI.id(x3+i,y3+i,x3+i+1,y3+i+1)] = 1;\n                }\n                for (int i=0;i<b;i++){\n                    used[EI.id(x1+i,y1-i,x1+i+1,y1-i-1)] = 1;\n                    used[EI.id(x0+b - i, y0 - b + i, x0+b - i -1, y0 - b + i +1)] = 1;\n                }\n                if (cnd.miss==0){mx=x0; my=y0;}\n                else if (cnd.miss==1){mx=x1; my=y1;}\n                else if (cnd.miss==2){mx=x2; my=y2;}\n                else {mx=x3; my=y3;}\n                array<int,8> op;\n                for (int t=0;t<4;t++){\n                    int idx=(cnd.miss+t)%4;\n                    int ox,oy;\n                    if (idx==0){ox=x0; oy=y0;}\n                    else if (idx==1){ox=x1; oy=y1;}\n                    else if (idx==2){ox=x2; oy=y2;}\n                    else {ox=x3; oy=y3;}\n                    op[2*t]=ox; op[2*t+1]=oy;\n                }\n                ops.push_back(op);\n                addFromPoint(mx,my);\n                return true;\n            };\n\n            while (!pool.empty()){\n                if (chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>TIME_LIMIT) break;\n                Cand cand=pool.pop();\n                int mx=-1,my=-1;\n                bool ok=false;\n                if (cand.type==0) ok=tryApplyRectAxis(cand,mx,my);\n                else if (cand.type==1) ok=tryApplyDiamond(cand,mx,my);\n                else ok=tryApplyDiag(cand,mx,my);\n                if (ok) dotList.emplace_back(mx,my);\n            }\n        }\n        return {total, std::move(ops)};\n    };\n\n    Result best{initSum, {}};\n    int runId=0;\n    while (true){\n        double t = chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n        if (t > TIME_LIMIT) break;\n        int ci = runId % (int)configList.size();\n        uint32_t seed = (uint32_t)((seedBase + 1812433253ull * runId) & 0xffffffffu);\n        Result res = simulate(configList[ci], seed);\n        if (res.total > best.total) best = std::move(res);\n        runId++;\n    }\n\n    cout << best.ops.size() << \"\\n\";\n    for (auto &op: best.ops){\n        for (int i=0;i<8;i++){\n            if (i) cout << ' ';\n            cout << op[i];\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Directions: 0 = F(up), 1 = B(down), 2 = L(left), 3 = R(right)\nconst char DIR_CH[4] = {'F', 'B', 'L', 'R'};\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\n\nusing Board = array<array<int, 10>, 10>;\n\nBoard tilt(const Board &b, int dir) {\n    Board res;\n    for (auto &row : res) row.fill(0);\n    if (dir == 0) { // up\n        for (int c = 0; c < 10; c++) {\n            int pos = 0;\n            for (int r = 0; r < 10; r++) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 1) { // down\n        for (int c = 0; c < 10; c++) {\n            int pos = 9;\n            for (int r = 9; r >= 0; r--) {\n                if (b[r][c]) {\n                    res[pos][c] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 2) { // left\n        for (int r = 0; r < 10; r++) {\n            int pos = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos++;\n                }\n            }\n        }\n    } else { // right\n        for (int r = 0; r < 10; r++) {\n            int pos = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[r][c]) {\n                    res[r][pos] = b[r][c];\n                    pos--;\n                }\n            }\n        }\n    }\n    return res;\n}\n\n// return {sum of squares, component count}\npair<int, int> scoreAndComp(const Board &b) {\n    bool vis[10][10] = {};\n    int totalScore = 0;\n    int comps = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            if (b[r][c] == 0 || vis[r][c]) continue;\n            comps++;\n            int col = b[r][c];\n            queue<pair<int, int>> q;\n            q.push({r, c});\n            vis[r][c] = true;\n            int sz = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front();\n                q.pop();\n                sz++;\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dr[k], ny = y + dc[k];\n                    if (nx < 0 || nx >= 10 || ny < 0 || ny >= 10) continue;\n                    if (vis[nx][ny]) continue;\n                    if (b[nx][ny] != col) continue;\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n            totalScore += sz * sz;\n        }\n    }\n    return {totalScore, comps};\n}\n\nint distSum(const Board &b, const array<pair<int, int>, 4> &target) {\n    int s = 0;\n    for (int r = 0; r < 10; r++) {\n        for (int c = 0; c < 10; c++) {\n            int col = b[r][c];\n            if (col == 0) continue;\n            s += abs(r - target[col].first) + abs(c - target[col].second);\n        }\n    }\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> flavor(100);\n    for (int i = 0; i < 100; i++) {\n        if (!(cin >> flavor[i])) return 0;\n    }\n\n    // count flavors\n    array<int, 4> cnt = {0, 0, 0, 0};\n    for (int f : flavor) cnt[f]++;\n\n    // corners\n    array<pair<int, int>, 4> corners = {make_pair(0, 0), make_pair(0, 9), make_pair(9, 0), make_pair(9, 9)};\n    // assign each flavor to a distinct corner maximizing weighted distance\n    array<pair<int, int>, 4> target;\n    target[0] = {0, 0};\n    long long bestMetric = -1;\n    array<int, 4> bestAssign = {0, 0, 0, 0};\n    for (int i = 0; i < 4; i++) {\n        for (int j = 0; j < 4; j++) if (j != i) {\n            for (int k = 0; k < 4; k++) if (k != i && k != j) {\n                long long metric = 0;\n                metric += 1LL * cnt[1] * cnt[2] * (abs(corners[i].first - corners[j].first) + abs(corners[i].second - corners[j].second));\n                metric += 1LL * cnt[1] * cnt[3] * (abs(corners[i].first - corners[k].first) + abs(corners[i].second - corners[k].second));\n                metric += 1LL * cnt[2] * cnt[3] * (abs(corners[j].first - corners[k].first) + abs(corners[j].second - corners[k].second));\n                if (metric > bestMetric) {\n                    bestMetric = metric;\n                    bestAssign[1] = i;\n                    bestAssign[2] = j;\n                    bestAssign[3] = k;\n                }\n            }\n        }\n    }\n    for (int f = 1; f <= 3; f++) {\n        target[f] = corners[bestAssign[f]];\n    }\n\n    Board cur;\n    for (auto &row : cur) row.fill(0);\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        if (!(cin >> p)) break;\n\n        // place new candy at p-th empty cell (row-major)\n        int cntEmpty = 0;\n        int pr = -1, pc = -1;\n        for (int r = 0; r < 10; r++) {\n            for (int c = 0; c < 10; c++) {\n                if (cur[r][c] == 0) {\n                    cntEmpty++;\n                    if (cntEmpty == p) {\n                        pr = r;\n                        pc = c;\n                        goto placed;\n                    }\n                }\n            }\n        }\n    placed:\n        if (pr == -1) { pr = 0; pc = 0; }\n        cur[pr][pc] = flavor[t];\n\n        int distCur = distSum(cur, target);\n\n        int bestDir = 0;\n        int bestScore = -1;\n        int bestDelta = -1e9;\n        int bestComp = 1e9;\n        int bestDist = 1e9;\n        Board bestBoard = cur;\n\n        for (int dir = 0; dir < 4; dir++) {\n            Board nb = tilt(cur, dir);\n            auto [sc, comp] = scoreAndComp(nb);\n            int d = distSum(nb, target);\n            int delta = distCur - d;\n            if (sc > bestScore ||\n                (sc == bestScore && delta > bestDelta) ||\n                (sc == bestScore && delta == bestDelta && comp < bestComp) ||\n                (sc == bestScore && delta == bestDelta && comp == bestComp && d < bestDist)) {\n                bestScore = sc;\n                bestDelta = delta;\n                bestComp = comp;\n                bestDist = d;\n                bestDir = dir;\n                bestBoard = nb;\n            }\n        }\n\n        cout << DIR_CH[bestDir] << '\\n' << flush;\n        cur = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GraphData {\n    int N;\n    vector<vector<uint8_t>> adj; // NxN\n    vector<int> deg, f1, f2, tri;\n    vector<int> sortedDeg;\n};\n\nvoid compute_features(GraphData &g){\n    int N = g.N;\n    g.deg.assign(N,0);\n    g.f1.assign(N,0);\n    g.f2.assign(N,0);\n    g.tri.assign(N,0);\n    // degree\n    for(int i=0;i<N;i++){\n        int d=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) d++;\n        g.deg[i]=d;\n    }\n    // f1\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.deg[j];\n        g.f1[i]=s;\n    }\n    // f2\n    for(int i=0;i<N;i++){\n        int s=0;\n        for(int j=0;j<N;j++) if(g.adj[i][j]) s += g.f1[j];\n        g.f2[i]=s;\n    }\n    // triangles per vertex (naive)\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++) if(g.adj[i][j]){\n            for(int k=j+1;k<N;k++) if(g.adj[i][k] && g.adj[j][k]){\n                g.tri[i]++; g.tri[j]++; g.tri[k]++;\n            }\n        }\n    }\n    g.sortedDeg = g.deg;\n    sort(g.sortedDeg.begin(), g.sortedDeg.end());\n}\n\n// Hungarian algorithm for minimum cost assignment\nvector<int> hungarian(const vector<vector<double>> &a){\n    int n = (int)a.size();\n    int m = n;\n    const double INF = 1e18;\n    vector<double> u(n+1), v(m+1);\n    vector<int> p(m+1), way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;\n        int j0=0;\n        vector<double> minv(m+1, INF);\n        vector<char> used(m+1, false);\n        do{\n            used[j0]=true;\n            int i0 = p[j0];\n            double delta = INF;\n            int j1 = 0;\n            for(int j=1;j<=m;j++) if(!used[j]){\n                double cur = a[i0-1][j-1] - u[i0] - v[j];\n                if(cur < minv[j]){\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if(minv[j] < delta){\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for(int j=0;j<=m;j++){\n                if(used[j]){\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                }else{\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        }while(p[j0]!=0);\n        // augmenting\n        do{\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        }while(j0);\n    }\n    vector<int> assignment(n, -1); // row -> col\n    for(int j=1;j<=m;j++){\n        if(p[j]>0 && p[j]<=n) assignment[p[j]-1] = j-1;\n    }\n    return assignment;\n}\n\nint degree_distance(const vector<int>& a, const vector<int>& b){\n    int n=a.size();\n    int s=0;\n    for(int i=0;i<n;i++) s += abs(a[i]-b[i]);\n    return s;\n}\n\nint compute_mismatch(const vector<vector<uint8_t>>& H, const vector<vector<uint8_t>>& G, const vector<int>& assign, int bestLimit){\n    int n = assign.size();\n    int mism=0;\n    for(int i=0;i<n;i++){\n        int gi = assign[i];\n        for(int j=i+1;j<n;j++){\n            int gj = assign[j];\n            if(H[i][j] != G[gi][gj]) mism++;\n        }\n        if(mism >= bestLimit) return mism;\n    }\n    return mism;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n    // decide N\n    int N = 25 + int(60.0*eps + 0.5);\n    if(M > 80) N += 5;\n    else if(M > 50) N += 2;\n    if(M < 30) N -= 3;\n    if(eps > 0.30) N += 4;\n    N = max(4, min(100, N));\n    int Kcap = 30;\n    int K = min(M, max(5, min(Kcap, (int)(eps*75.0)+5)));\n    // generate graphs\n    mt19937 rng(1234567);\n    vector<GraphData> graphs(M);\n    for(int k=0;k<M;k++){\n        GraphData g;\n        g.N = N;\n        g.adj.assign(N, vector<uint8_t>(N,0));\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                bool e = (rng() & 1);\n                g.adj[i][j]=g.adj[j][i]= e;\n            }\n        }\n        compute_features(g);\n        graphs[k]=move(g);\n    }\n    // output graphs\n    cout<<N<<\"\\n\";\n    int E = N*(N-1)/2;\n    string line;\n    line.reserve(E);\n    for(int k=0;k<M;k++){\n        line.clear();\n        line.reserve(E);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                line.push_back(graphs[k].adj[i][j] ? '1' : '0');\n            }\n        }\n        cout<<line<<\"\\n\";\n    }\n    cout.flush();\n    // process queries\n    vector<vector<uint8_t>> HAdj(N, vector<uint8_t>(N,0));\n    GraphData HG;\n    HG.N = N;\n    for(int qi=0; qi<100; qi++){\n        string hstr;\n        if(!(cin>>hstr)) break;\n        // build adjacency\n        int idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                char c = hstr[idx++];\n                uint8_t v = (c=='1');\n                HAdj[i][j]=HAdj[j][i]=v;\n            }\n        }\n        HG.adj = HAdj;\n        compute_features(HG);\n        // distances for pruning\n        vector<pair<int,int>> distIdx;\n        distIdx.reserve(M);\n        for(int k=0;k<M;k++){\n            int d = degree_distance(HG.sortedDeg, graphs[k].sortedDeg);\n            distIdx.emplace_back(d, k);\n        }\n        nth_element(distIdx.begin(), distIdx.begin()+K, distIdx.end(),\n                    [](auto &a, auto &b){ return a.first < b.first; });\n        distIdx.resize(K);\n        sort(distIdx.begin(), distIdx.end()); // optional\n        int bestMismatch = N*N; // upper bound\n        int bestIdx = distIdx[0].second;\n        // precompute weight factors\n        double s = 1.0 - 2.0*eps;\n        if(s < 0.05) s = 0.05;\n        double w1 = s;\n        double w2 = s*s;\n        double w3 = s;\n        double invN = 1.0 / (double)N;\n        double invNN = 1.0 / ((double)N*(double)N);\n        // candidate evaluation\n        vector<vector<double>> cost(N, vector<double>(N));\n        for(auto &dk : distIdx){\n            int k = dk.second;\n            // build cost matrix\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    double c = abs(HG.deg[i] - graphs[k].deg[j]);\n                    c += w1 * (double)abs(HG.f1[i] - graphs[k].f1[j]) * invN;\n                    c += w2 * (double)abs(HG.f2[i] - graphs[k].f2[j]) * invNN;\n                    c += w3 * (double)abs(HG.tri[i] - graphs[k].tri[j]) * invN;\n                    cost[i][j]=c;\n                }\n            }\n            vector<int> assign = hungarian(cost); // H row -> G col\n            int mism = compute_mismatch(HAdj, graphs[k].adj, assign, bestMismatch);\n            if(mism < bestMismatch){\n                bestMismatch = mism;\n                bestIdx = k;\n            }\n        }\n        cout<<bestIdx<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    int w;\n};\nstruct Adj {\n    int to;\n    int w;\n    int id;\n};\n\n// Dijkstra that skips one edge\nlong long dijkstra_skip(int s, int t, int skip_id,\n                        const vector<vector<Adj>> &adj,\n                        vector<long long> &dist) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        if (u == t) break;\n        for (auto &e : adj[u]) {\n            if (e.id == skip_id) continue;\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n    return dist[t];\n}\n\n// Dijkstra that records one parent edge (shortest path tree)\nvoid dijkstra_parent(int s, const vector<vector<Adj>> &adj,\n                     vector<long long> &dist, vector<int> &parent) {\n    const long long INF = (1LL << 60);\n    fill(dist.begin(), dist.end(), INF);\n    fill(parent.begin(), parent.end(), -1);\n    dist[s] = 0;\n    using P = pair<long long, int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        for (auto &e : adj[u]) {\n            long long nd = d + e.w;\n            if (nd < dist[e.to]) {\n                dist[e.to] = nd;\n                parent[e.to] = e.id;\n                pq.push({nd, e.to});\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<vector<Adj>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u;\n        --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n    // read coordinates (not used)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<long long> dist(N);\n    vector<long long> altDiff(M);\n    for (int i = 0; i < M; i++) {\n        auto &e = edges[i];\n        long long alt = dijkstra_skip(e.u, e.v, i, adj, dist);\n        if (alt >= (1LL << 59)) {\n            altDiff[i] = 0;  // fallback\n        } else {\n            altDiff[i] = alt - e.w;\n            if (altDiff[i] < 0) altDiff[i] = 0;\n        }\n    }\n\n    int S = min(N, 30);\n    vector<int> sources;\n    int step = max(1, N / S);\n    for (int i = 0; i < N && (int)sources.size() < S; i += step) {\n        sources.push_back(i);\n    }\n    while ((int)sources.size() < S) sources.push_back((int)sources.size());\n    vector<int> centrality(M, 0);\n    vector<int> parent(N);\n    for (int s : sources) {\n        dijkstra_parent(s, adj, dist, parent);\n        for (int v = 0; v < N; v++) {\n            if (v == s) continue;\n            int pe = parent[v];\n            if (pe >= 0) centrality[pe]++;\n        }\n    }\n\n    vector<long double> importance(M);\n    long double sumImp = 0;\n    for (int i = 0; i < M; i++) {\n        long double imp = (long double)altDiff[i] * ((long double)centrality[i] + 1.0L);\n        importance[i] = imp;\n        sumImp += imp;\n    }\n    long double avgImp = sumImp / (long double)max(1, M);\n    long double alpha = avgImp * 0.5L;\n    if (alpha < 1e-6) alpha = 1.0L;\n\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (importance[a] == importance[b]) return a < b;\n        return importance[a] > importance[b];\n    });\n\n    vector<int> answer(M, 0);\n    vector<long double> dayLoad(D, 0.0L);\n    vector<int> dayCount(D, 0);\n    vector<vector<uint16_t>> vtxCount(N, vector<uint16_t>(D, 0));\n\n    auto chooseDay = [&](int u, int v) -> int {\n        long double bestCost = 1e100;\n        int bestDay = -1;\n        for (int d = 0; d < D; d++) {\n            if (dayCount[d] >= K) continue;\n            int s1 = (int)vtxCount[u][d] + (int)vtxCount[v][d];\n            long double cost = dayLoad[d] + alpha * (long double)s1;\n            if (cost < bestCost - 1e-9L) {\n                bestCost = cost;\n                bestDay = d;\n            } else if (fabsl(cost - bestCost) <= 1e-9L) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay] ||\n                    (dayCount[d] == dayCount[bestDay] && d < bestDay)) {\n                    bestDay = d;\n                }\n            }\n        }\n        if (bestDay == -1) {\n            // should not happen, but fallback\n            for (int d = 0; d < D; d++) {\n                if (bestDay == -1 || dayCount[d] < dayCount[bestDay]) bestDay = d;\n            }\n        }\n        return bestDay;\n    };\n\n    // initial assignment\n    for (int eid : order) {\n        int u = edges[eid].u;\n        int v = edges[eid].v;\n        int d = chooseDay(u, v);\n        answer[eid] = d + 1;\n        dayLoad[d] += importance[eid];\n        dayCount[d]++;\n        vtxCount[u][d]++;\n        vtxCount[v][d]++;\n    }\n\n    auto start = chrono::steady_clock::now();\n    int improvePasses = 1;\n    for (int pass = 0; pass < improvePasses; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.5) break;  // time guard\n        for (int eid : order) {\n            int curr = answer[eid] - 1;\n            int u = edges[eid].u;\n            int v = edges[eid].v;\n            long double imp = importance[eid];\n            // remove\n            dayLoad[curr] -= imp;\n            dayCount[curr]--;\n            vtxCount[u][curr]--;\n            vtxCount[v][curr]--;\n            // choose best day again\n            int nd = chooseDay(u, v);\n            answer[eid] = nd + 1;\n            dayLoad[nd] += imp;\n            dayCount[nd]++;\n            vtxCount[u][nd]++;\n            vtxCount[v][nd]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << ' ';\n        cout << answer[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> dist, matchL, matchR;\n    HopcroftKarp(int nL=0,int nR=0): nL(nL), nR(nR), adj(nL) {}\n    void addEdge(int u,int v){ adj[u].push_back(v); }\n    bool bfs(){\n        queue<int> q;\n        dist.assign(nL, -1);\n        for(int i=0;i<nL;i++){\n            if(matchL[i]==-1){\n                dist[i]=0;\n                q.push(i);\n            }\n        }\n        bool reachable=false;\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for(int v: adj[u]){\n                int mu=matchR[v];\n                if(mu>=0 && dist[mu]==-1){\n                    dist[mu]=dist[u]+1;\n                    q.push(mu);\n                }\n                if(mu==-1) reachable=true;\n            }\n        }\n        return reachable;\n    }\n    bool dfs(int u){\n        for(int v: adj[u]){\n            int mu=matchR[v];\n            if(mu==-1 || (dist[mu]==dist[u]+1 && dfs(mu))){\n                matchL[u]=v;\n                matchR[v]=u;\n                return true;\n            }\n        }\n        dist[u]=-1;\n        return false;\n    }\n    int maxMatching(){\n        matchL.assign(nL, -1);\n        matchR.assign(nR, -1);\n        int m=0;\n        while(bfs()){\n            for(int i=0;i<nL;i++){\n                if(matchL[i]==-1){\n                    if(dfs(i)) m++;\n                }\n            }\n        }\n        return m;\n    }\n};\n\nstruct SilPack {\n    vector<array<int,8>> cubes;   // 2x2x2 blocks\n    vector<array<int,8>> bars8;   // length 8 bars\n    vector<array<int,4>> bars4;   // length 4 bars\n    vector<pair<int,int>> doms;   // dominoes\n};\n\nstruct VarData {\n    SilPack sp;\n    vector<int> ordC, ord8, ord4, ord2;\n};\n\nstruct Placement {\n    vector<array<int,8>> cubes;\n    vector<array<int,8>> bars8;\n    vector<array<int,4>> bars4;\n    vector<pair<int,int>> doms;\n    vector<int> monos;\n};\n\nstruct Solver {\n    int D, V;\n    vector<string> f[2], r[2];\n    mt19937 rng;\n    Solver(): rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    inline int idx(int x,int y,int z) const { return (x*D + y)*D + z; }\n    inline tuple<int,int,int> decode(int id) const {\n        int z = id % D;\n        int y = (id / D) % D;\n        int x = id / (D*D);\n        return {x,y,z};\n    }\n\n    int score8(const array<int,8>& ids){\n        vector<pair<int,int>> fx, ry;\n        fx.reserve(8); ry.reserve(8);\n        for(int id: ids){\n            auto [x,y,z]=decode(id);\n            fx.push_back({z,x});\n            ry.push_back({z,y});\n        }\n        sort(fx.begin(), fx.end());\n        fx.erase(unique(fx.begin(), fx.end()), fx.end());\n        sort(ry.begin(), ry.end());\n        ry.erase(unique(ry.begin(), ry.end()), ry.end());\n        return (int)fx.size() + (int)ry.size();\n    }\n    int score4(const array<int,4>& ids){\n        vector<pair<int,int>> fx, ry;\n        fx.reserve(4); ry.reserve(4);\n        for(int id: ids){\n            auto [x,y,z]=decode(id);\n            fx.push_back({z,x});\n            ry.push_back({z,y});\n        }\n        sort(fx.begin(), fx.end());\n        fx.erase(unique(fx.begin(), fx.end()), fx.end());\n        sort(ry.begin(), ry.end());\n        ry.erase(unique(ry.begin(), ry.end()), ry.end());\n        return (int)fx.size() + (int)ry.size();\n    }\n    int score2(const pair<int,int>& p){\n        auto [x1,y1,z1]=decode(p.first);\n        auto [x2,y2,z2]=decode(p.second);\n        vector<pair<int,int>> fx={{z1,x1},{z2,x2}};\n        vector<pair<int,int>> ry={{z1,y1},{z2,y2}};\n        sort(fx.begin(), fx.end());\n        fx.erase(unique(fx.begin(), fx.end()), fx.end());\n        sort(ry.begin(), ry.end());\n        ry.erase(unique(ry.begin(), ry.end()), ry.end());\n        return (int)fx.size() + (int)ry.size();\n    }\n\n    void generate_candidates(const vector<char>& allowed,\n                             vector<array<int,8>>& cubes,\n                             vector<array<int,8>>& bars8,\n                             vector<array<int,4>>& bars4){\n        cubes.clear(); bars8.clear(); bars4.clear();\n        for(int x=0; x<=D-2; x++){\n            for(int y=0; y<=D-2; y++){\n                for(int z=0; z<=D-2; z++){\n                    array<int,8> ids;\n                    int t=0;\n                    bool ok=true;\n                    for(int dx=0; dx<2; dx++) for(int dy=0; dy<2; dy++) for(int dz=0; dz<2; dz++){\n                        int id = idx(x+dx, y+dy, z+dz);\n                        ids[t++] = id;\n                        if(!allowed[id]) ok=false;\n                    }\n                    if(ok) cubes.push_back(ids);\n                }\n            }\n        }\n        // bars 8\n        for(int x=0; x<=D-8; x++){\n            for(int y=0; y<D; y++) for(int z=0; z<D; z++){\n                array<int,8> ids; bool ok=true;\n                for(int k=0;k<8;k++){ ids[k]=idx(x+k,y,z); if(!allowed[ids[k]]){ok=false; break;} }\n                if(ok) bars8.push_back(ids);\n            }\n        }\n        for(int x=0; x<D; x++){\n            for(int y=0; y<=D-8; y++) for(int z=0; z<D; z++){\n                array<int,8> ids; bool ok=true;\n                for(int k=0;k<8;k++){ ids[k]=idx(x,y+k,z); if(!allowed[ids[k]]){ok=false; break;} }\n                if(ok) bars8.push_back(ids);\n            }\n        }\n        for(int x=0; x<D; x++){\n            for(int y=0; y<D; y++) for(int z=0; z<=D-8; z++){\n                array<int,8> ids; bool ok=true;\n                for(int k=0;k<8;k++){ ids[k]=idx(x,y,z+k); if(!allowed[ids[k]]){ok=false; break;} }\n                if(ok) bars8.push_back(ids);\n            }\n        }\n        // bars 4\n        for(int x=0; x<=D-4; x++){\n            for(int y=0; y<D; y++) for(int z=0; z<D; z++){\n                array<int,4> ids; bool ok=true;\n                for(int k=0;k<4;k++){ ids[k]=idx(x+k,y,z); if(!allowed[ids[k]]){ok=false; break;} }\n                if(ok) bars4.push_back(ids);\n            }\n        }\n        for(int x=0; x<D; x++){\n            for(int y=0; y<=D-4; y++) for(int z=0; z<D; z++){\n                array<int,4> ids; bool ok=true;\n                for(int k=0;k<4;k++){ ids[k]=idx(x,y+k,z); if(!allowed[ids[k]]){ok=false; break;} }\n                if(ok) bars4.push_back(ids);\n            }\n        }\n        for(int x=0; x<D; x++){\n            for(int y=0; y<D; y++) for(int z=0; z<=D-4; z++){\n                array<int,4> ids; bool ok=true;\n                for(int k=0;k<4;k++){ ids[k]=idx(x,y,z+k); if(!allowed[ids[k]]){ok=false; break;} }\n                if(ok) bars4.push_back(ids);\n            }\n        }\n    }\n\n    SilPack pack_variant(const vector<char>& allowed,\n                         const vector<array<int,8>>& cubesCand,\n                         const vector<array<int,8>>& bars8Cand,\n                         const vector<array<int,4>>& bars4Cand,\n                         int mode){\n        vector<char> used(V,0);\n        SilPack sp;\n        vector<int> ordC(cubesCand.size());\n        iota(ordC.begin(), ordC.end(), 0);\n        if(mode==2) shuffle(ordC.begin(), ordC.end(), rng);\n        else if(mode==1){\n            sort(ordC.begin(), ordC.end(), [&](int a,int b){\n                return score8(cubesCand[a])>score8(cubesCand[b]);\n            });\n        }\n        for(int idxc: ordC){\n            const auto& ids=cubesCand[idxc];\n            bool ok=true;\n            for(int k=0;k<8;k++) if(used[ids[k]]){ok=false; break;}\n            if(ok){\n                for(int k=0;k<8;k++) used[ids[k]]=1;\n                sp.cubes.push_back(ids);\n            }\n        }\n        vector<int> ord8(bars8Cand.size());\n        iota(ord8.begin(), ord8.end(), 0);\n        if(mode==2) shuffle(ord8.begin(), ord8.end(), rng);\n        else if(mode==1){\n            sort(ord8.begin(), ord8.end(), [&](int a,int b){\n                return score8(bars8Cand[a])>score8(bars8Cand[b]);\n            });\n        }\n        for(int idxb: ord8){\n            const auto& ids=bars8Cand[idxb];\n            bool ok=true;\n            for(int k=0;k<8;k++) if(used[ids[k]]){ok=false; break;}\n            if(ok){\n                for(int k=0;k<8;k++) used[ids[k]]=1;\n                sp.bars8.push_back(ids);\n            }\n        }\n        vector<int> ord4(bars4Cand.size());\n        iota(ord4.begin(), ord4.end(), 0);\n        if(mode==2) shuffle(ord4.begin(), ord4.end(), rng);\n        else if(mode==1){\n            sort(ord4.begin(), ord4.end(), [&](int a,int b){\n                return score4(bars4Cand[a])>score4(bars4Cand[b]);\n            });\n        }\n        for(int idxb: ord4){\n            const auto& ids=bars4Cand[idxb];\n            bool ok=true;\n            for(int k=0;k<4;k++) if(used[ids[k]]){ok=false; break;}\n            if(ok){\n                for(int k=0;k<4;k++) used[ids[k]]=1;\n                sp.bars4.push_back(ids);\n            }\n        }\n        // doms via matching\n        vector<int> freeIds;\n        freeIds.reserve(V);\n        for(int id=0; id<V; id++){\n            if(!used[id] && allowed[id]) freeIds.push_back(id);\n        }\n        vector<int> leftId(V,-1), rightId(V,-1);\n        vector<int> leftMap, rightMap;\n        int nL=0,nR=0;\n        for(int id: freeIds){\n            auto [x,y,z]=decode(id);\n            if(((x+y+z)&1)==0){ leftId[id]=nL++; leftMap.push_back(id); }\n            else { rightId[id]=nR++; rightMap.push_back(id); }\n        }\n        HopcroftKarp hk(nL,nR);\n        int dx[6]={1,-1,0,0,0,0};\n        int dy[6]={0,0,1,-1,0,0};\n        int dz[6]={0,0,0,0,1,-1};\n        for(int id: freeIds){\n            auto [x,y,z]=decode(id);\n            if(((x+y+z)&1)!=0) continue;\n            int u=leftId[id];\n            for(int dir=0; dir<6; dir++){\n                int nx=x+dx[dir], ny=y+dy[dir], nz=z+dz[dir];\n                if(nx<0||ny<0||nz<0||nx>=D||ny>=D||nz>=D) continue;\n                int nid=idx(nx,ny,nz);\n                if(!used[nid] && allowed[nid] && rightId[nid]!=-1){\n                    hk.addEdge(u, rightId[nid]);\n                }\n            }\n        }\n        hk.maxMatching();\n        for(int u=0; u<nL; u++){\n            int v=hk.matchL[u];\n            if(v!=-1){\n                sp.doms.push_back({leftMap[u], rightMap[v]});\n            }\n        }\n        return sp;\n    }\n\n    void prepare_orders(VarData& vd){\n        vd.ordC.resize(vd.sp.cubes.size());\n        iota(vd.ordC.begin(), vd.ordC.end(), 0);\n        sort(vd.ordC.begin(), vd.ordC.end(), [&](int a,int b){\n            return score8(vd.sp.cubes[a]) > score8(vd.sp.cubes[b]);\n        });\n        vd.ord8.resize(vd.sp.bars8.size());\n        iota(vd.ord8.begin(), vd.ord8.end(), 0);\n        sort(vd.ord8.begin(), vd.ord8.end(), [&](int a,int b){\n            return score8(vd.sp.bars8[a]) > score8(vd.sp.bars8[b]);\n        });\n        vd.ord4.resize(vd.sp.bars4.size());\n        iota(vd.ord4.begin(), vd.ord4.end(), 0);\n        sort(vd.ord4.begin(), vd.ord4.end(), [&](int a,int b){\n            return score4(vd.sp.bars4[a]) > score4(vd.sp.bars4[b]);\n        });\n        vd.ord2.resize(vd.sp.doms.size());\n        iota(vd.ord2.begin(), vd.ord2.end(), 0);\n        sort(vd.ord2.begin(), vd.ord2.end(), [&](int a,int b){\n            return score2(vd.sp.doms[a]) > score2(vd.sp.doms[b]);\n        });\n    }\n\n    int compute_mono(const VarData& vd, int cC, int c8, int c4, int c2,\n                     const vector<char>& allowed,\n                     const vector<string>& fmat, const vector<string>& rmat){\n        vector<char> used(V,0);\n        for(int i=0;i<cC && i<(int)vd.ordC.size(); i++){\n            for(int id: vd.sp.cubes[vd.ordC[i]]) used[id]=1;\n        }\n        for(int i=0;i<c8 && i<(int)vd.ord8.size(); i++){\n            for(int id: vd.sp.bars8[vd.ord8[i]]) used[id]=1;\n        }\n        for(int i=0;i<c4 && i<(int)vd.ord4.size(); i++){\n            for(int id: vd.sp.bars4[vd.ord4[i]]) used[id]=1;\n        }\n        for(int i=0;i<c2 && i<(int)vd.ord2.size(); i++){\n            auto p=vd.sp.doms[vd.ord2[i]];\n            used[p.first]=used[p.second]=1;\n        }\n        vector<char> coveredF(D*D,0), coveredR(D*D,0);\n        for(int id=0; id<V; id++){\n            if(used[id]){\n                auto [x,y,z]=decode(id);\n                coveredF[z*D + x]=1;\n                coveredR[z*D + y]=1;\n            }\n        }\n        int mono=0;\n        for(int z=0; z<D; z++){\n            for(int x=0; x<D; x++){\n                if(fmat[z][x]=='1' && !coveredF[z*D + x]){\n                    for(int y=0; y<D; y++){\n                        int id=idx(x,y,z);\n                        if(allowed[id] && !used[id]){\n                            used[id]=1;\n                            coveredF[z*D+x]=1;\n                            coveredR[z*D+y]=1;\n                            mono++;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        for(int z=0; z<D; z++){\n            for(int y=0; y<D; y++){\n                if(rmat[z][y]=='1' && !coveredR[z*D + y]){\n                    for(int x=0; x<D; x++){\n                        int id=idx(x,y,z);\n                        if(allowed[id] && !used[id]){\n                            used[id]=1;\n                            coveredR[z*D+y]=1;\n                            coveredF[z*D+x]=1;\n                            mono++;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        return mono;\n    }\n\n    Placement build_place(const VarData& vd, int cC, int c8, int c4, int c2,\n                          const vector<char>& allowed,\n                          const vector<string>& fmat, const vector<string>& rmat,\n                          int targetMono){\n        Placement pl;\n        vector<char> used(V,0);\n        for(int i=0;i<cC && i<(int)vd.ordC.size(); i++){\n            auto arr=vd.sp.cubes[vd.ordC[i]];\n            pl.cubes.push_back(arr);\n            for(int id: arr) used[id]=1;\n        }\n        for(int i=0;i<c8 && i<(int)vd.ord8.size(); i++){\n            auto arr=vd.sp.bars8[vd.ord8[i]];\n            pl.bars8.push_back(arr);\n            for(int id: arr) used[id]=1;\n        }\n        for(int i=0;i<c4 && i<(int)vd.ord4.size(); i++){\n            auto arr=vd.sp.bars4[vd.ord4[i]];\n            pl.bars4.push_back(arr);\n            for(int id: arr) used[id]=1;\n        }\n        for(int i=0;i<c2 && i<(int)vd.ord2.size(); i++){\n            auto p=vd.sp.doms[vd.ord2[i]];\n            pl.doms.push_back(p);\n            used[p.first]=used[p.second]=1;\n        }\n        vector<char> coveredF(D*D,0), coveredR(D*D,0);\n        for(int id=0; id<V; id++){\n            if(used[id]){\n                auto [x,y,z]=decode(id);\n                coveredF[z*D + x]=1;\n                coveredR[z*D + y]=1;\n            }\n        }\n        for(int z=0; z<D; z++){\n            for(int x=0; x<D; x++){\n                if(fmat[z][x]=='1' && !coveredF[z*D + x]){\n                    for(int y=0; y<D; y++){\n                        int id=idx(x,y,z);\n                        if(allowed[id] && !used[id]){\n                            used[id]=1;\n                            pl.monos.push_back(id);\n                            coveredF[z*D+x]=1;\n                            coveredR[z*D+y]=1;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        for(int z=0; z<D; z++){\n            for(int y=0; y<D; y++){\n                if(rmat[z][y]=='1' && !coveredR[z*D + y]){\n                    for(int x=0; x<D; x++){\n                        int id=idx(x,y,z);\n                        if(allowed[id] && !used[id]){\n                            used[id]=1;\n                            pl.monos.push_back(id);\n                            coveredR[z*D+y]=1;\n                            coveredF[z*D+x]=1;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        for(int id=0; id<V && (int)pl.monos.size()<targetMono; id++){\n            if(!used[id] && allowed[id]){\n                used[id]=1;\n                pl.monos.push_back(id);\n            }\n        }\n        return pl;\n    }\n\n    vector<int> make_candidates(int mx){\n        vector<int> v = {0, mx};\n        if(mx>1){\n            v.push_back(mx/2);\n            v.push_back((mx*2)/3);\n        }\n        sort(v.begin(), v.end());\n        v.erase(unique(v.begin(), v.end()), v.end());\n        return v;\n    }\n\n    void solve(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        if(!(cin>>D)) return;\n        V = D*D*D;\n        for(int s=0; s<2; s++){\n            f[s].resize(D);\n            for(int i=0;i<D;i++) cin>>f[s][i];\n            r[s].resize(D);\n            for(int i=0;i<D;i++) cin>>r[s][i];\n        }\n        vector<char> allowed[2];\n        for(int s=0; s<2; s++){\n            allowed[s].assign(V,0);\n            for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0; z<D; z++){\n                if(f[s][z][x]=='1' && r[s][z][y]=='1'){\n                    allowed[s][idx(x,y,z)] = 1;\n                }\n            }\n        }\n        vector<array<int,8>> candC[2], cand8[2];\n        vector<array<int,4>> cand4[2];\n        for(int s=0; s<2; s++){\n            generate_candidates(allowed[s], candC[s], cand8[s], cand4[s]);\n        }\n        int VAR=8;\n        vector<VarData> vars[2];\n        for(int s=0; s<2; s++){\n            vars[s].reserve(VAR);\n            // deterministic, greedy, random variants\n            VarData v0; v0.sp = pack_variant(allowed[s], candC[s], cand8[s], cand4[s], 0); prepare_orders(v0); vars[s].push_back(move(v0));\n            VarData vg; vg.sp = pack_variant(allowed[s], candC[s], cand8[s], cand4[s], 1); prepare_orders(vg); vars[s].push_back(move(vg));\n            for(int t=2; t<VAR; t++){\n                VarData vr; vr.sp = pack_variant(allowed[s], candC[s], cand8[s], cand4[s], 2); prepare_orders(vr); vars[s].push_back(move(vr));\n            }\n        }\n        double bestEval=1e18;\n        Placement bestPl0, bestPl1;\n        int bestC=0,best8=0,best4=0,best2=0,bestMono=0;\n        for(const auto& v0: vars[0]){\n            for(const auto& v1: vars[1]){\n                int maxC = min((int)v0.sp.cubes.size(), (int)v1.sp.cubes.size());\n                int max8 = min((int)v0.sp.bars8.size(), (int)v1.sp.bars8.size());\n                int max4 = min((int)v0.sp.bars4.size(), (int)v1.sp.bars4.size());\n                int max2 = min((int)v0.sp.doms.size(), (int)v1.sp.doms.size());\n                vector<int> candC0 = make_candidates(maxC);\n                vector<int> cand80 = make_candidates(max8);\n                vector<int> cand40 = make_candidates(max4);\n                vector<int> cand20 = make_candidates(max2);\n                for(int cC: candC0){\n                    for(int c8: cand80){\n                        for(int c4: cand40){\n                            for(int c2: cand20){\n                                int mono0 = compute_mono(v0, cC, c8, c4, c2, allowed[0], f[0], r[0]);\n                                int mono1 = compute_mono(v1, cC, c8, c4, c2, allowed[1], f[1], r[1]);\n                                int monoT = max(mono0, mono1);\n                                double eval = monoT + c2*0.5 + c4*0.25 + (c8 + cC)*0.125;\n                                if(eval < bestEval){\n                                    bestEval = eval;\n                                    bestC=cC; best8=c8; best4=c4; best2=c2; bestMono=monoT;\n                                    bestPl0 = build_place(v0, cC, c8, c4, c2, allowed[0], f[0], r[0], bestMono);\n                                    bestPl1 = build_place(v1, cC, c8, c4, c2, allowed[1], f[1], r[1], bestMono);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        int n = bestC + best8 + best4 + best2 + bestMono;\n        vector<int> out0(V,0), out1(V,0);\n        int id=1;\n        for(int i=0;i<bestC;i++,id++){\n            for(int k=0;k<8;k++){\n                out0[bestPl0.cubes[i][k]] = id;\n                out1[bestPl1.cubes[i][k]] = id;\n            }\n        }\n        for(int i=0;i<best8;i++,id++){\n            for(int k=0;k<8;k++){\n                out0[bestPl0.bars8[i][k]] = id;\n                out1[bestPl1.bars8[i][k]] = id;\n            }\n        }\n        for(int i=0;i<best4;i++,id++){\n            for(int k=0;k<4;k++){\n                out0[bestPl0.bars4[i][k]] = id;\n                out1[bestPl1.bars4[i][k]] = id;\n            }\n        }\n        for(int i=0;i<best2;i++,id++){\n            out0[bestPl0.doms[i].first]=id;\n            out0[bestPl0.doms[i].second]=id;\n            out1[bestPl1.doms[i].first]=id;\n            out1[bestPl1.doms[i].second]=id;\n        }\n        for(int i=0;i<bestMono;i++,id++){\n            if(i<(int)bestPl0.monos.size()) out0[bestPl0.monos[i]] = id;\n            if(i<(int)bestPl1.monos.size()) out1[bestPl1.monos[i]] = id;\n        }\n        cout<<n<<\"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout<<' ';\n            cout<<out0[i];\n        }\n        cout<<\"\\n\";\n        for(int i=0;i<V;i++){\n            if(i) cout<<' ';\n            cout<<out1[i];\n        }\n        cout<<\"\\n\";\n    }\n};\n\nint main(){\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct EdgeAdj {\n    int to;\n    int id;\n    long long w;\n};\nstruct DSU {\n    vector<int> p;\n    DSU(int n) : p(n, -1) {}\n    int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (p[a] > p[b]) swap(a, b);\n        p[a] += p[b];\n        p[b] = a;\n        return true;\n    }\n};\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    long long cost;\n    int covered;\n};\nint ceil_sqrt_ll(long long x) {\n    if (x <= 0) return 0;\n    long long r = (long long)std::sqrt((long double)x);\n    while (r * r < x) ++r;\n    while ((r - 1) * (r - 1) >= x) --r;\n    return (int)r;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<long long> W(M);\n    vector<vector<EdgeAdj>> g(N);\n    for (int j = 0; j < M; j++) {\n        int u, v; long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        U[j] = u; V[j] = v; W[j] = w;\n        g[u].push_back({v, j, w});\n        g[v].push_back({u, j, w});\n    }\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n\n    const int LIMIT = 5000;\n    const int LIMIT2 = LIMIT * LIMIT;\n    const long long INFLL = (1LL << 60);\n\n    vector<vector<int>> dist2(N, vector<int>(K));\n    vector<vector<int>> within(N);\n    vector<vector<pair<int, int>>> sortedList(N);\n    for (int i = 0; i < N; i++) {\n        within[i].reserve(K / 4);\n        sortedList[i].reserve(K / 4);\n        for (int k = 0; k < K; k++) {\n            long long dx = (long long)a[k] - x[i];\n            long long dy = (long long)b[k] - y[i];\n            long long d2 = dx * dx + dy * dy;\n            dist2[i][k] = (int)d2;\n            if (d2 <= LIMIT2) {\n                within[i].push_back(k);\n                sortedList[i].push_back({(int)d2, k});\n            }\n        }\n        sort(sortedList[i].begin(), sortedList[i].end(),\n             [](const pair<int, int> &p1, const pair<int, int> &p2) {\n                 if (p1.first != p2.first) return p1.first < p2.first;\n                 return p1.second < p2.second;\n             });\n    }\n\n    vector<vector<long long>> distMat(N, vector<long long>(N, INFLL));\n    vector<vector<int>> parentEdge(N, vector<int>(N, -1));\n    using PLLI = pair<long long, int>;\n    for (int s = 0; s < N; s++) {\n        vector<long long> d(N, INFLL);\n        vector<int> p(N, -1);\n        d[s] = 0;\n        priority_queue<PLLI, vector<PLLI>, greater<PLLI>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [cd, v] = pq.top(); pq.pop();\n            if (cd != d[v]) continue;\n            for (auto &e : g[v]) {\n                long long nd = cd + e.w;\n                if (nd < d[e.to]) {\n                    d[e.to] = nd;\n                    p[e.to] = e.id;\n                    pq.push({nd, e.to});\n                }\n            }\n        }\n        distMat[s] = move(d);\n        parentEdge[s] = move(p);\n    }\n    vector<long long> spCost(N);\n    for (int i = 0; i < N; i++) spCost[i] = distMat[0][i];\n\n    struct EItem { long long w; int id; };\n    vector<EItem> eList;\n    eList.reserve(M);\n    for (int i = 0; i < M; i++) eList.push_back({W[i], i});\n    sort(eList.begin(), eList.end(), [](const EItem &a, const EItem &b){ return a.w < b.w; });\n    DSU dsuFull(N);\n    vector<int> mstFullEdges;\n    mstFullEdges.reserve(N - 1);\n    for (auto &ei : eList) {\n        int id = ei.id;\n        if (dsuFull.unite(U[id], V[id])) {\n            mstFullEdges.push_back(id);\n            if ((int)mstFullEdges.size() == N - 1) break;\n        }\n    }\n\n    auto prune_edges = [&](const vector<int> &Pvec, vector<int> &Bvec) {\n        vector<int> deg(N, 0);\n        vector<vector<int>> inc(N);\n        inc.assign(N, {});\n        for (int e = 0; e < M; e++) if (Bvec[e]) {\n            int a = U[e], b = V[e];\n            deg[a]++; deg[b]++;\n            inc[a].push_back(e);\n            inc[b].push_back(e);\n        }\n        auto isTerminal = [&](int v)->bool {\n            return Pvec[v] > 0 || v == 0;\n        };\n        queue<int> q;\n        vector<char> inq(N, false);\n        for (int i = 0; i < N; i++) {\n            if (!isTerminal(i) && deg[i] == 1) { q.push(i); inq[i] = true; }\n        }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (isTerminal(v) || deg[v] != 1) continue;\n            int eAct = -1;\n            for (int eid : inc[v]) if (Bvec[eid]) { eAct = eid; break; }\n            if (eAct == -1) continue;\n            Bvec[eAct] = 0;\n            int nei = (U[eAct] == v ? V[eAct] : U[eAct]);\n            deg[v]--; deg[nei]--;\n            if (!isTerminal(nei) && deg[nei] == 1 && !inq[nei]) { q.push(nei); inq[nei] = true; }\n        }\n    };\n\n    auto improve_P = [&](vector<int> P) {\n        vector<int> cnt(K, 0);\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                cnt[pr.second]++;\n            }\n        }\n        for (int iter = 0; iter < 2; iter++) {\n            bool changed = false;\n            for (int i = 0; i < N; i++) {\n                if (P[i] == 0) continue;\n                long long curR2 = 1LL * P[i] * P[i];\n                long long needR2 = -1;\n                for (auto &pr : sortedList[i]) {\n                    if (pr.first > curR2) break;\n                    int k = pr.second;\n                    if (cnt[k] == 1 && pr.first > needR2) needR2 = pr.first;\n                }\n                long long newR2 = (needR2 == -1 ? 0 : needR2);\n                if (newR2 < curR2) {\n                    bool ok = true;\n                    for (auto &pr : sortedList[i]) {\n                        if (pr.first > curR2) break;\n                        if (pr.first > newR2) {\n                            int k = pr.second;\n                            if (cnt[k] <= 1) { ok = false; break; }\n                        }\n                    }\n                    if (ok) {\n                        for (auto &pr : sortedList[i]) {\n                            if (pr.first > curR2) break;\n                            if (pr.first > newR2) {\n                                int k = pr.second;\n                                cnt[k]--;\n                            }\n                        }\n                        int newR = (newR2 == 0 ? 0 : ceil_sqrt_ll(newR2));\n                        P[i] = newR;\n                        changed = true;\n                    }\n                }\n            }\n            if (!changed) break;\n        }\n        for (int i = 1; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            bool removable = true;\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                int k = pr.second;\n                if (cnt[k] <= 1) { removable = false; break; }\n            }\n            if (removable) {\n                for (auto &pr : sortedList[i]) {\n                    if (pr.first > r2) break;\n                    int k = pr.second;\n                    cnt[k]--;\n                }\n                P[i] = 0;\n            }\n        }\n        return P;\n    };\n\n    auto eval_with_P = [&](vector<int> P)->Solution {\n        P = improve_P(P);\n        vector<char> covered(K, false);\n        int covcnt = 0;\n        for (int i = 0; i < N; i++) {\n            if (P[i] == 0) continue;\n            int r2 = P[i] * P[i];\n            for (auto &pr : sortedList[i]) {\n                if (pr.first > r2) break;\n                int k = pr.second;\n                if (!covered[k]) { covered[k] = true; covcnt++; }\n            }\n        }\n        long long costP = 0;\n        for (int i = 0; i < N; i++) costP += 1LL * P[i] * P[i];\n\n        vector<int> terminals;\n        terminals.push_back(0);\n        for (int i = 1; i < N; i++) if (P[i] > 0) terminals.push_back(i);\n        int T = terminals.size();\n\n        vector<int> B1(M, 0), B2(M, 0), B3(M, 0);\n        long long costE1 = 0, costE2 = 0, costE3 = 0;\n\n        if (T > 1) {\n            vector<tuple<long long, int, int>> es;\n            es.reserve(T * (T - 1) / 2);\n            for (int i = 0; i < T; i++) {\n                int u = terminals[i];\n                for (int j = i + 1; j < T; j++) {\n                    int v = terminals[j];\n                    es.emplace_back(distMat[u][v], u, v);\n                }\n            }\n            sort(es.begin(), es.end(),\n                 [](const auto &a, const auto &b){ return get<0>(a) < get<0>(b); });\n            DSU dsu(N);\n            int added = 0;\n            for (auto &ed : es) {\n                long long w; int u, v;\n                tie(w, u, v) = ed;\n                if (dsu.unite(u, v)) {\n                    int cur = v;\n                    while (cur != u) {\n                        int e = parentEdge[u][cur];\n                        if (e == -1) break;\n                        B1[e] = 1;\n                        cur = (U[e] == cur ? V[e] : U[e]);\n                    }\n                    if (++added == T - 1) break;\n                }\n            }\n        }\n        prune_edges(P, B1);\n        for (int e = 0; e < M; e++) if (B1[e]) costE1 += W[e];\n\n        for (int eid : mstFullEdges) B2[eid] = 1;\n        prune_edges(P, B2);\n        for (int e = 0; e < M; e++) if (B2[e]) costE2 += W[e];\n\n        for (int v : terminals) {\n            if (v == 0) continue;\n            int cur = v;\n            while (cur != 0) {\n                int e = parentEdge[0][cur];\n                if (e == -1) break;\n                B3[e] = 1;\n                cur = (U[e] == cur ? V[e] : U[e]);\n            }\n        }\n        prune_edges(P, B3);\n        for (int e = 0; e < M; e++) if (B3[e]) costE3 += W[e];\n\n        long long tot1 = costP + costE1;\n        long long tot2 = costP + costE2;\n        long long tot3 = costP + costE3;\n        if (tot1 <= tot2 && tot1 <= tot3) {\n            return Solution{P, B1, tot1, covcnt};\n        } else if (tot2 <= tot1 && tot2 <= tot3) {\n            return Solution{P, B2, tot2, covcnt};\n        } else {\n            return Solution{P, B3, tot3, covcnt};\n        }\n    };\n\n    auto ensure_coverage = [&](vector<int> allowed, const vector<char> *banned = nullptr) {\n        vector<char> inAllowed(N, false);\n        for (int v : allowed) inAllowed[v] = true;\n        vector<char> cov(K, false);\n        int uncovered = K;\n        for (int v : allowed) {\n            for (int k : within[v]) {\n                if (!cov[k]) { cov[k] = true; uncovered--; }\n            }\n        }\n        while (uncovered > 0) {\n            int target = -1;\n            for (int k = 0; k < K; k++) if (!cov[k]) { target = k; break; }\n            if (target == -1) break;\n            int bestv = -1; int bestd = INT_MAX;\n            for (int i = 0; i < N; i++) {\n                if (banned && (*banned)[i]) continue;\n                int d = dist2[i][target];\n                if (d <= LIMIT2 && d < bestd) { bestd = d; bestv = i; }\n            }\n            if (bestv == -1) break;\n            if (!inAllowed[bestv]) {\n                inAllowed[bestv] = true;\n                allowed.push_back(bestv);\n                for (int k : within[bestv]) if (!cov[k]) { cov[k] = true; uncovered--; }\n            } else {\n                break;\n            }\n        }\n        return allowed;\n    };\n\n    auto buildP_nearest = [&](const vector<int> &allowed) {\n        vector<int> maxd2(N, -1);\n        for (int k = 0; k < K; k++) {\n            int best = -1;\n            int bestd = INT_MAX;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < bestd) { bestd = d; best = v; }\n            }\n            if (best == -1) continue;\n            if (bestd > maxd2[best]) maxd2[best] = bestd;\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (maxd2[i] >= 0) {\n                int r = ceil_sqrt_ll(maxd2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto buildP_incAssign = [&](const vector<int> &allowed, double gamma) {\n        vector<long long> cur_r2(N, 0);\n        vector<int> minDist2(K, INT_MAX);\n        for (int k = 0; k < K; k++) {\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d < minDist2[k]) minDist2[k] = d;\n            }\n        }\n        vector<int> order(K);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j){ return minDist2[i] > minDist2[j]; });\n        for (int idx = 0; idx < K; idx++) {\n            int k = order[idx];\n            int best = -1;\n            double bestInc = 1e100;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d > LIMIT2) continue;\n                long long inc = max(cur_r2[v], (long long)d) - cur_r2[v];\n                double incAdj = (double)inc + (cur_r2[v] == 0 ? gamma * spCost[v] : 0.0);\n                if (incAdj < bestInc) {\n                    bestInc = incAdj;\n                    best = v;\n                }\n            }\n            if (best == -1) continue;\n            long long nd = dist2[best][k];\n            if (nd > cur_r2[best]) cur_r2[best] = nd;\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (cur_r2[i] > 0) {\n                int r = ceil_sqrt_ll(cur_r2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto buildP_weighted = [&](const vector<int> &allowed, double alpha) {\n        vector<int> maxd2(N, -1);\n        for (int k = 0; k < K; k++) {\n            int best = -1;\n            double bestVal = 1e100;\n            for (int v : allowed) {\n                int d = dist2[v][k];\n                if (d > LIMIT2) continue;\n                double val = (double)d + alpha * (double)spCost[v];\n                if (val < bestVal) {\n                    bestVal = val;\n                    best = v;\n                }\n            }\n            if (best == -1) continue;\n            if (dist2[best][k] > maxd2[best]) maxd2[best] = dist2[best][k];\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (maxd2[i] >= 0) {\n                int r = ceil_sqrt_ll(maxd2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto expansion_greedy = [&](double beta) {\n        vector<long long> cur_r2(N, 0);\n        vector<char> covered(K, false);\n        int uncovered = K;\n        while (uncovered > 0) {\n            int bestStation = -1;\n            double bestRatio = 1e100;\n            long long bestR2 = 0;\n            for (int i = 0; i < N; i++) {\n                long long rcur = cur_r2[i];\n                int cnt = 0;\n                long long lastd = -1;\n                double bestLocalRatio = 1e100;\n                long long bestLocalR2 = -1;\n                for (auto &pr : sortedList[i]) {\n                    int d2 = pr.first;\n                    if (d2 <= rcur) continue;\n                    int res = pr.second;\n                    if (!covered[res]) cnt++;\n                    if (d2 != lastd) {\n                        if (cnt > 0) {\n                            double incCost = (double)(d2 - rcur);\n                            if (rcur == 0) incCost += beta * (double)spCost[i];\n                            double ratio = incCost / cnt;\n                            if (ratio < bestLocalRatio) {\n                                bestLocalRatio = ratio;\n                                bestLocalR2 = d2;\n                            }\n                        }\n                        lastd = d2;\n                    }\n                }\n                if (bestLocalR2 != -1 && bestLocalRatio < bestRatio) {\n                    bestRatio = bestLocalRatio;\n                    bestStation = i;\n                    bestR2 = bestLocalR2;\n                }\n            }\n            if (bestStation == -1) break;\n            cur_r2[bestStation] = bestR2;\n            for (auto &pr : sortedList[bestStation]) {\n                if (pr.first > bestR2) break;\n                int res = pr.second;\n                if (!covered[res]) {\n                    covered[res] = true;\n                    uncovered--;\n                }\n            }\n        }\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++) {\n            if (cur_r2[i] > 0) {\n                int r = ceil_sqrt_ll(cur_r2[i]);\n                if (r > LIMIT) r = LIMIT;\n                P[i] = r;\n            }\n        }\n        return P;\n    };\n\n    auto greedy_cover_allowed = [&]() {\n        vector<char> covered(K, false);\n        int uncovered = K;\n        vector<char> sel(N, false);\n        sel[0] = true;\n        while (uncovered > 0) {\n            int best = -1;\n            int bestCnt = 0;\n            for (int i = 0; i < N; i++) {\n                if (sel[i]) continue;\n                int cnt = 0;\n                for (int k : within[i]) if (!covered[k]) cnt++;\n                if (cnt > bestCnt) { bestCnt = cnt; best = i; }\n            }\n            if (best == -1 || bestCnt == 0) break;\n            sel[best] = true;\n            for (int k : within[best]) if (!covered[k]) { covered[k] = true; uncovered--; }\n        }\n        vector<int> res;\n        for (int i = 0; i < N; i++) if (sel[i]) res.push_back(i);\n        return res;\n    };\n\n    vector<int> allowedSel = greedy_cover_allowed();\n    vector<int> allowedAug;\n    {\n        int TH = 3500, TH2 = TH * TH;\n        vector<char> flag(N, false);\n        for (int v : allowedSel) flag[v] = true;\n        for (int k = 0; k < K; k++) {\n            int bestd = INT_MAX;\n            for (int v : allowedSel) {\n                int d = dist2[v][k];\n                if (d < bestd) bestd = d;\n            }\n            if (bestd > TH2) {\n                int bestv = -1; int bestdv = INT_MAX;\n                for (int i = 0; i < N; i++) {\n                    int d = dist2[i][k];\n                    if (d < bestdv) { bestdv = d; bestv = i; }\n                }\n                if (bestv != -1) flag[bestv] = true;\n            }\n        }\n        for (int i = 0; i < N; i++) if (flag[i]) allowedAug.push_back(i);\n    }\n    vector<int> allSet(N);\n    iota(allSet.begin(), allSet.end(), 0);\n\n    vector<int> allowedCheap;\n    {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j){ return spCost[i] < spCost[j]; });\n        vector<char> cov(K, false);\n        int uncovered = K;\n        allowedCheap.push_back(0);\n        for (int v : order) {\n            if (v == 0) continue;\n            int cnt = 0;\n            for (int k : within[v]) if (!cov[k]) cnt++;\n            if (cnt == 0) continue;\n            allowedCheap.push_back(v);\n            for (int k : within[v]) if (!cov[k]) { cov[k] = true; uncovered--; }\n            if (uncovered == 0) break;\n        }\n        if (uncovered > 0) {\n            for (int i = 0; i < N; i++) if (find(allowedCheap.begin(), allowedCheap.end(), i) == allowedCheap.end()) allowedCheap.push_back(i);\n        }\n    }\n\n    vector<Solution> candidates;\n    vector<int> allowed1 = ensure_coverage(allowedSel);\n    vector<int> allowed2 = ensure_coverage(allowedAug);\n    vector<int> allowedAll = ensure_coverage(allSet);\n    vector<int> allowedC = ensure_coverage(allowedCheap);\n\n    candidates.push_back(eval_with_P(buildP_nearest(allowed1)));\n    candidates.push_back(eval_with_P(buildP_nearest(allowed2)));\n    candidates.push_back(eval_with_P(buildP_nearest(allowedAll)));\n    candidates.push_back(eval_with_P(buildP_nearest(allowedC)));\n\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedAll, 0.1)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedAll, 0.5)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedAll, 0.05)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowed1, 0.1)));\n    candidates.push_back(eval_with_P(buildP_incAssign(allowedC, 0.1)));\n\n    candidates.push_back(eval_with_P(buildP_weighted(allowedAll, 30.0)));\n    candidates.push_back(eval_with_P(buildP_weighted(allowed2, 20.0)));\n    candidates.push_back(eval_with_P(buildP_weighted(allowed2, 10.0)));\n\n    vector<double> betas = {0.0, 0.2, 0.6, 1.5};\n    for (double beta : betas) candidates.push_back(eval_with_P(expansion_greedy(beta)));\n\n    long long maxd2root = 0;\n    for (int k = 0; k < K; k++) if (dist2[0][k] > maxd2root) maxd2root = dist2[0][k];\n    if (maxd2root <= LIMIT2) {\n        int r = ceil_sqrt_ll(maxd2root);\n        vector<int> P(N, 0);\n        P[0] = r;\n        candidates.push_back(eval_with_P(P));\n    }\n\n    Solution best;\n    best.cost = (long long)4e18;\n    best.covered = 0;\n    for (auto &sol : candidates) {\n        if (sol.covered == K) {\n            if (sol.cost < best.cost) best = sol;\n        } else if (best.covered < K) {\n            if (sol.covered > best.covered || (sol.covered == best.covered && sol.cost < best.cost)) {\n                best = sol;\n            }\n        }\n    }\n\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    auto startTime = chrono::steady_clock::now();\n    double TIME_LIMIT = 0.5;\n    uniform_real_distribution<double> probDist(0.15, 0.45);\n    uniform_real_distribution<double> gammaDist(0.0, 0.4);\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        double p = probDist(rng);\n        vector<int> allowed;\n        allowed.push_back(0);\n        for (int i = 1; i < N; i++) {\n            double r = std::generate_canonical<double, 10>(rng);\n            if (r < p) allowed.push_back(i);\n        }\n        allowed = ensure_coverage(allowed);\n        double gamma = gammaDist(rng);\n        Solution sol = eval_with_P(buildP_incAssign(allowed, gamma));\n        if (sol.covered == K) {\n            if (sol.cost < best.cost) best = sol;\n        } else if (best.covered < K) {\n            if (sol.covered > best.covered || (sol.covered == best.covered && sol.cost < best.cost)) {\n                best = sol;\n            }\n        }\n    }\n\n    auto refine_solution = [&](Solution sol) {\n        if (sol.covered < K) return sol;\n        vector<int> used;\n        for (int i = 1; i < N; i++) if (sol.P[i] > 0) used.push_back(i);\n        sort(used.begin(), used.end(), [&](int a, int b){ return sol.P[a] * sol.P[a] > sol.P[b] * sol.P[b]; });\n        int limit = min<int>(10, used.size());\n        for (int idx = 0; idx < limit; idx++) {\n            int v = used[idx];\n            vector<int> allowed;\n            allowed.push_back(0);\n            for (int i = 1; i < N; i++) if (sol.P[i] > 0 && i != v) allowed.push_back(i);\n            vector<char> banned(N, false);\n            banned[v] = true;\n            allowed = ensure_coverage(allowed, &banned);\n            Solution cand = eval_with_P(buildP_incAssign(allowed, 0.1));\n            if (cand.covered == K && cand.cost < sol.cost) {\n                sol = cand;\n                break;\n            }\n        }\n        return sol;\n    };\n\n    best = refine_solution(best);\n\n    for (int i = 0; i < N; i++) {\n        cout << best.P[i] << (i + 1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (best.B[j] ? 1 : 0) << (j + 1 == M ? '\\n' : ' ');\n    }\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    static constexpr int N = 30;\n    static constexpr int TOT = N * (N + 1) / 2; // 465\n\n    vector<int> xs, ys;\n    vector<array<int, 2>> children; // -1 if none\n    vector<array<int, 2>> parents;  // -1 if none\n    vector<pair<int, int>> adj_edges; // undirected adjacency edges\n\n    Solver() {\n        xs.resize(TOT);\n        ys.resize(TOT);\n        children.assign(TOT, array<int, 2>{-1, -1});\n        parents.assign(TOT, array<int, 2>{-1, -1});\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                int id = x * (x + 1) / 2 + y;\n                xs[id] = x;\n                ys[id] = y;\n                if (x + 1 < N) {\n                    int c1 = (x + 1) * (x + 2) / 2 + y;\n                    int c2 = c1 + 1;\n                    children[id][0] = c1;\n                    children[id][1] = c2;\n                }\n                if (x > 0) {\n                    int p0 = (x - 1) * x / 2 + (y - 1); // upper-left\n                    int p1 = (x - 1) * x / 2 + y;       // upper-right\n                    parents[id][0] = (y > 0 ? p0 : -1);\n                    parents[id][1] = (y < x ? p1 : -1);\n                }\n            }\n        }\n        adj_edges.reserve(1305);\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                int id = x * (x + 1) / 2 + y;\n                if (y + 1 <= x) {\n                    int nid = id + 1;\n                    adj_edges.emplace_back(id, nid);\n                }\n                if (x + 1 < N) {\n                    int dl = (x + 1) * (x + 2) / 2 + y;\n                    int dr = dl + 1;\n                    adj_edges.emplace_back(id, dl);\n                    adj_edges.emplace_back(id, dr);\n                }\n            }\n        }\n    }\n\n    inline int computeE(const vector<int> &val) const {\n        int e = 0;\n        for (int i = 0; i < TOT; i++) {\n            int c1 = children[i][0], c2 = children[i][1];\n            if (c1 != -1 && val[i] > val[c1]) e++;\n            if (c2 != -1 && val[i] > val[c2]) e++;\n        }\n        return e;\n    }\n\n    inline int computeDelta(const vector<int> &val, int u, int v) const {\n        int ep[10], ec[10];\n        int cnt = 0;\n        auto addEdge = [&](int p, int c) {\n            if (p == -1 || c == -1) return;\n            for (int i = 0; i < cnt; i++) {\n                if (ep[i] == p && ec[i] == c) return;\n            }\n            ep[cnt] = p;\n            ec[cnt] = c;\n            cnt++;\n        };\n        addEdge(u, children[u][0]);\n        addEdge(u, children[u][1]);\n        addEdge(v, children[v][0]);\n        addEdge(v, children[v][1]);\n        addEdge(parents[u][0], u);\n        addEdge(parents[u][1], u);\n        addEdge(parents[v][0], v);\n        addEdge(parents[v][1], v);\n\n        int oldE = 0, newE = 0;\n        for (int i = 0; i < cnt; i++) {\n            int p = ep[i], c = ec[i];\n            int vp_old = val[p], vc_old = val[c];\n            int vp_new = vp_old, vc_new = vc_old;\n            if (p == u) vp_new = val[v];\n            else if (p == v) vp_new = val[u];\n            if (c == u) vc_new = val[v];\n            else if (c == v) vc_new = val[u];\n            oldE += (vp_old > vc_old);\n            newE += (vp_new > vc_new);\n        }\n        return newE - oldE;\n    }\n\n    void heapify(vector<int> &val, vector<array<int, 4>> &moves, int moveLimit) const {\n        int last_internal = TOT - N - 1; // last node with children\n        for (int i = last_internal; i >= 0; i--) {\n            int cur = i;\n            while (children[cur][0] != -1) {\n                int c1 = children[cur][0];\n                int c2 = children[cur][1];\n                int c = (val[c2] < val[c1] ? c2 : c1);\n                if (val[cur] <= val[c]) break;\n                swap(val[cur], val[c]);\n                moves.push_back({xs[cur], ys[cur], xs[c], ys[c]});\n                cur = c;\n                if ((int)moves.size() >= moveLimit) return;\n            }\n        }\n    }\n\n    void prepass(vector<int> &val, vector<array<int, 4>> &moves, int maxSteps, int moveLimit, int threshold, mt19937 &rng) const {\n        for (int step = 0; step < maxSteps; step++) {\n            int bestDelta = 0;\n            int bestA = -1, bestB = -1;\n            for (auto &e : adj_edges) {\n                int a = e.first, b = e.second;\n                int d = computeDelta(val, a, b);\n                if (d < bestDelta || (d == bestDelta && d < 0 && (rng() & 1))) {\n                    bestDelta = d;\n                    bestA = a;\n                    bestB = b;\n                }\n            }\n            if (bestDelta >= threshold) break;\n            swap(val[bestA], val[bestB]);\n            moves.push_back({xs[bestA], ys[bestA], xs[bestB], ys[bestB]});\n            if ((int)moves.size() >= moveLimit) break;\n        }\n    }\n\n    vector<array<int, 4>> produceCandidate(const vector<int> &initVal, bool mirrored, int preType, uint64_t seed, int moveLimit = 10000) const {\n        vector<int> val(TOT);\n        auto mirrorCoord = [&](int id) {\n            int x = xs[id], y = ys[id];\n            int my = x - y;\n            return x * (x + 1) / 2 + my;\n        };\n        if (!mirrored) {\n            val = initVal;\n        } else {\n            for (int id = 0; id < TOT; id++) {\n                int mid = mirrorCoord(id);\n                val[mid] = initVal[id];\n            }\n        }\n        vector<array<int, 4>> moves;\n        moves.reserve(4000);\n        mt19937 rng((unsigned)seed);\n        if (preType > 0) {\n            int maxSteps = 0;\n            int threshold = -1;\n            if (preType == 1) { // strict\n                maxSteps = 300;\n                threshold = -2;\n            } else if (preType == 2) { // relaxed\n                maxSteps = 700;\n                threshold = -1;\n            } else { // mild (preType==3)\n                maxSteps = 1000;\n                threshold = 0;\n            }\n            prepass(val, moves, maxSteps, moveLimit, threshold, rng);\n            if ((int)moves.size() >= moveLimit) {\n                if (mirrored) {\n                    for (auto &op : moves) {\n                        op[1] = op[0] - op[1];\n                        op[3] = op[2] - op[3];\n                    }\n                }\n                return moves;\n            }\n        }\n        heapify(val, moves, moveLimit);\n        if (mirrored) {\n            for (auto &op : moves) {\n                op[1] = op[0] - op[1];\n                op[3] = op[2] - op[3];\n            }\n        }\n        return moves;\n    }\n\n    int simulateE(const vector<int> &initVal, const vector<array<int, 4>> &moves) const {\n        vector<int> val = initVal;\n        for (auto &op : moves) {\n            int id1 = op[0] * (op[0] + 1) / 2 + op[1];\n            int id2 = op[2] * (op[2] + 1) / 2 + op[3];\n            swap(val[id1], val[id2]);\n        }\n        return computeE(val);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    vector<int> initVal(Solver::TOT);\n    for (int x = 0; x < Solver::N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int v;\n            if (!(cin >> v)) return 0;\n            int id = x * (x + 1) / 2 + y;\n            initVal[id] = v;\n        }\n    }\n    uint64_t seedBase = 0x9e3779b97f4a7c15ULL;\n    for (int i = 0; i < 8 && i < Solver::TOT; i++) {\n        seedBase ^= (uint64_t)(initVal[i] + 1) * 0xbf58476d1ce4e5b9ULL;\n        seedBase = (seedBase << 13) ^ (seedBase >> 7);\n    }\n\n    const int MOVE_LIMIT = 10000;\n    vector<vector<array<int, 4>>> candidates;\n    candidates.reserve(8);\n    int seedIdx = 0;\n    for (bool mirrored : {false, true}) {\n        for (int preType = 0; preType <= 3; preType++) {\n            candidates.push_back(solver.produceCandidate(initVal, mirrored, preType, seedBase + seedIdx * 101, MOVE_LIMIT));\n            seedIdx++;\n        }\n    }\n\n    int bestIdx = -1;\n    int bestLen = INT_MAX;\n    for (int i = 0; i < (int)candidates.size(); i++) {\n        auto &mv = candidates[i];\n        if ((int)mv.size() > MOVE_LIMIT) continue;\n        int E = solver.simulateE(initVal, mv);\n        if (E != 0) continue;\n        if ((int)mv.size() < bestLen) {\n            bestLen = (int)mv.size();\n            bestIdx = i;\n        }\n    }\n    if (bestIdx == -1) bestIdx = 0; // fallback\n    auto &bestMoves = candidates[bestIdx];\n    cout << bestMoves.size() << \"\\n\";\n    for (auto &op : bestMoves) {\n        cout << op[0] << \" \" << op[1] << \" \" << op[2] << \" \" << op[3] << \"\\n\";\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int label;\n    int idx;\n    int r, c;\n};\nstruct Comp {\n    bool operator()(const Node &a, const Node &b) const {\n        if (a.label != b.label) return a.label > b.label;\n        return a.idx > b.idx;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D, N;\n    if (!(cin >> D >> N)) return 0;\n    const int er = 0, ec = (D - 1) / 2;\n    vector<vector<bool>> obstacle(D, vector<bool>(D, false));\n    for (int k = 0; k < N; k++) {\n        int r, c;\n        cin >> r >> c;\n        obstacle[r][c] = true;\n    }\n    const int dr[4] = {1, -1, 0, 0};\n    const int dc[4] = {0, 0, 1, -1};\n\n    /* distance from entrance */\n    vector<vector<int>> dist0(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    dist0[er][ec] = 0;\n    q.push({er, ec});\n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n            if (obstacle[nr][nc]) continue;\n            if (dist0[nr][nc] != -1) continue;\n            dist0[nr][nc] = dist0[r][c] + 1;\n            q.push({nr, nc});\n        }\n    }\n\n    /* list of usable cells sorted by distance */\n    vector<pair<int, int>> cells;\n    cells.reserve(D * D);\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (obstacle[i][j]) continue;\n            if (i == er && j == ec) continue;\n            cells.push_back({i, j});\n        }\n    }\n    sort(cells.begin(), cells.end(), [&](auto a, auto b) {\n        int da = dist0[a.first][a.second];\n        int db = dist0[b.first][b.second];\n        if (da != db) return da < db;\n        if (a.first != b.first) return a.first < b.first;\n        return a.second < b.second;\n    });\n    int K = (int)cells.size();\n    vector<int> idx_of(D * D, -1);\n    for (int idx = 0; idx < K; idx++) {\n        idx_of[cells[idx].first * D + cells[idx].second] = idx;\n    }\n\n    vector<vector<bool>> filled(D, vector<bool>(D, false));\n    vector<vector<int>> label_grid(D, vector<int>(D, -1));\n    int empties_count = K;\n\n    auto is_safe = [&](int r, int c) -> bool {\n        filled[r][c] = true;\n        bool vis[9][9] = {};\n        queue<pair<int, int>> qq;\n        qq.push({er, ec});\n        vis[er][ec] = true;\n        int cnt = 0;\n        while (!qq.empty()) {\n            auto [cr, cc] = qq.front();\n            qq.pop();\n            for (int k = 0; k < 4; k++) {\n                int nr = cr + dr[k], nc = cc + dc[k];\n                if (nr < 0 || nr >= D || nc < 0 || nc >= D) continue;\n                if (obstacle[nr][nc]) continue;\n                if (filled[nr][nc]) continue;\n                if (vis[nr][nc]) continue;\n                vis[nr][nc] = true;\n                cnt++;\n                qq.push({nr, nc});\n            }\n        }\n        filled[r][c] = false;\n        return cnt == empties_count - 1;\n    };\n\n    /* placement phase */\n    for (int step = 0; step < K; step++) {\n        int t;\n        cin >> t;\n        int chosen = -1;\n\n        /* prefer smallest available safe idx >= t */\n        for (int idx = t; idx < K; idx++) {\n            auto [r, c] = cells[idx];\n            if (filled[r][c]) continue;\n            if (is_safe(r, c)) {\n                chosen = idx;\n                break;\n            }\n        }\n        if (chosen == -1) {\n            /* fallback: largest available safe idx < t */\n            for (int idx = t - 1; idx >= 0; idx--) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    chosen = idx;\n                    break;\n                }\n            }\n        }\n        if (chosen == -1) {\n            /* final fallback */\n            for (int idx = 0; idx < K; idx++) {\n                auto [r, c] = cells[idx];\n                if (filled[r][c]) continue;\n                if (is_safe(r, c)) {\n                    chosen = idx;\n                    break;\n                }\n            }\n        }\n        auto [pr, pc] = cells[chosen];\n        filled[pr][pc] = true;\n        label_grid[pr][pc] = t;\n        empties_count--;\n        cout << pr << \" \" << pc << '\\n';\n        cout.flush();\n    }\n\n    /* retrieval phase */\n    vector<vector<bool>> present(D, vector<bool>(D, false));\n    for (int i = 0; i < D; i++) for (int j = 0; j < D; j++) {\n        if (label_grid[i][j] != -1) present[i][j] = true;\n    }\n\n    priority_queue<Node, vector<Node>, Comp> pq;\n    auto push_if_present = [&](int r, int c) {\n        if (r < 0 || r >= D || c < 0 || c >= D) return;\n        if (obstacle[r][c]) return;\n        if (present[r][c]) {\n            int idx = idx_of[r * D + c];\n            pq.push({label_grid[r][c], idx, r, c});\n        }\n    };\n    push_if_present(er + 1, ec);\n    push_if_present(er - 1, ec);\n    push_if_present(er, ec + 1);\n    push_if_present(er, ec - 1);\n\n    int removed = 0;\n    while (removed < K) {\n        if (pq.empty()) {\n            bool done = false;\n            for (int i = 0; i < D && !done; i++) {\n                for (int j = 0; j < D && !done; j++) {\n                    if (!present[i][j]) continue;\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dr[k], nj = j + dc[k];\n                        if (ni < 0 || ni >= D || nj < 0 || nj >= D) continue;\n                        if (obstacle[ni][nj]) continue;\n                        if (!present[ni][nj] || (ni == er && nj == ec)) {\n                            int idx = idx_of[i * D + j];\n                            pq.push({label_grid[i][j], idx, i, j});\n                            done = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        auto cur = pq.top();\n        pq.pop();\n        int r = cur.r, c = cur.c;\n        if (!present[r][c]) continue;\n        present[r][c] = false;\n        removed++;\n        cout << r << \" \" << c << '\\n';\n        for (int k = 0; k < 4; k++) {\n            int nr = r + dr[k], nc = c + dc[k];\n            push_if_present(nr, nc);\n        }\n    }\n\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastRNG {\n    uint64_t x = 88172645463325252ull;\n    inline uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int nextInt(int mod) {\n        return int(next() % mod);\n    }\n};\n\nstruct Solver {\n    int n, m, C;\n    vector<int> orig;              // flattened grid\n    vector<vector<char>> adjOrig;\n    vector<char> boundary;\n    const int dr[4] = {1, -1, 0, 0};\n    const int dc[4] = {0, 0, 1, -1};\n\n    Solver(int n_, int m_, const vector<int> &g) : n(n_), m(m_), orig(g) {\n        C = m + 1;\n        computeAdjOrig();\n    }\n\n    void computeAdjOrig() {\n        adjOrig.assign(C, vector<char>(C, 0));\n        auto addEdge = [&](int a, int b) {\n            if (a == b) return;\n            adjOrig[a][b] = adjOrig[b][a] = 1;\n        };\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                int a = orig[i * n + j];\n                if (i + 1 < n) addEdge(a, orig[(i + 1) * n + j]);\n                if (j + 1 < n) addEdge(a, orig[i * n + j + 1]);\n                if (i == 0) addEdge(0, a);\n                if (i == n - 1) addEdge(0, a);\n                if (j == 0) addEdge(0, a);\n                if (j == n - 1) addEdge(0, a);\n            }\n        }\n        boundary.assign(C, 0);\n        boundary[0] = 1;\n        for (int c = 1; c <= m; c++) if (adjOrig[0][c]) boundary[c] = 1;\n    }\n\n    // Check connectivity of color col after removing cell idx\n    bool connectedAfterRemoval(int idx, int col, const vector<int> &g, const vector<int> &sz, vector<int> &vis, int &curMark) {\n        if (sz[col] <= 1) return false;\n        int r0 = idx / n, c0 = idx % n;\n        int start = -1;\n        for (int k = 0; k < 4; k++) {\n            int nr = r0 + dr[k], nc = c0 + dc[k];\n            if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n            int nb = nr * n + nc;\n            if (g[nb] == col) { start = nb; break; }\n        }\n        if (start == -1) {\n            for (int i = 0; i < n * n; i++) {\n                if (i == idx) continue;\n                if (g[i] == col) { start = i; break; }\n            }\n        }\n        if (start == -1) return false;\n        curMark++;\n        queue<int> q;\n        q.push(start);\n        vis[start] = curMark;\n        int cnt = 1;\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int r = v / n, c = v % n;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                if (nr < 0 || nr >= n || nc < 0 || nc >= n) continue;\n                int nb = nr * n + nc;\n                if (nb == idx) continue;\n                if (g[nb] != col) continue;\n                if (vis[nb] == curMark) continue;\n                vis[nb] = curMark;\n                q.push(nb);\n                cnt++;\n            }\n        }\n        return cnt == sz[col] - 1;\n    }\n\n    pair<int, vector<int>> runWithOrder(const vector<int> &startGrid, const vector<int> &order) {\n        vector<int> g = startGrid;\n        vector<int> sz(C, 0);\n        for (int v : g) sz[v]++;\n\n        // adjacency counts flat\n        vector<int> adjCnt(C * C, 0);\n        auto addEdge = [&](int a, int b) {\n            if (a == b) return;\n            adjCnt[a * C + b]++;\n            adjCnt[b * C + a]++;\n        };\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                int a = g[i * n + j];\n                if (i + 1 < n) addEdge(a, g[(i + 1) * n + j]);\n                if (j + 1 < n) addEdge(a, g[i * n + j + 1]);\n                if (i == 0) addEdge(0, a);\n                if (i == n - 1) addEdge(0, a);\n                if (j == 0) addEdge(0, a);\n                if (j == n - 1) addEdge(0, a);\n            }\n        }\n\n        vector<int> vis(n * n, 0);\n        int curMark = 0;\n        vector<int> remEdges(C, 0);\n\n        auto isAdjZero = [&](int idx, const vector<int> &grid) -> bool {\n            int r = idx / n, c = idx % n;\n            if (r == 0 || r == n - 1 || c == 0 || c == n - 1) return true;\n            for (int k = 0; k < 4; k++) {\n                int nr = r + dr[k], nc = c + dc[k];\n                int nb = nr * n + nc;\n                if (grid[nb] == 0) return true;\n            }\n            return false;\n        };\n\n        while (true) {\n            bool removed = false;\n            for (int idx : order) {\n                int col = g[idx];\n                if (col == 0) continue;\n                if (!boundary[col]) continue; // internal colors untouched\n                if (sz[col] <= 1) continue;\n                if (!isAdjZero(idx, g)) continue; // ensure 0 connectivity\n                int r = idx / n, c = idx % n;\n                int num0 = 0, numSame = 0;\n                vector<int> touched;\n                bool bad = false;\n                for (int k = 0; k < 4; k++) {\n                    int nr = r + dr[k], nc = c + dc[k];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) {\n                        num0++;\n                        continue;\n                    }\n                    int d = g[nr * n + nc];\n                    if (d == 0) num0++;\n                    else if (d == col) numSame++;\n                    else {\n                        if (remEdges[d] == 0) touched.push_back(d);\n                        remEdges[d]++;\n                        if (!boundary[d]) { bad = true; break; } // would create 0-adj for internal\n                    }\n                }\n                if (bad) {\n                    for (int d : touched) remEdges[d] = 0;\n                    continue;\n                }\n                bool ok = true;\n                for (int d : touched) {\n                    if (adjOrig[col][d]) {\n                        if (adjCnt[col * C + d] - remEdges[d] <= 0) { ok = false; break; }\n                    }\n                }\n                if (ok) {\n                    int predicted0c = adjCnt[0 * C + col] - num0 + numSame;\n                    if (predicted0c <= 0) ok = false;\n                }\n                if (ok && numSame >= 2) {\n                    if (!connectedAfterRemoval(idx, col, g, sz, vis, curMark)) ok = false;\n                }\n                for (int d : touched) remEdges[d] = 0;\n                if (!ok) continue;\n                // perform removal\n                for (int k = 0; k < 4; k++) {\n                    int nr = r + dr[k], nc = c + dc[k];\n                    if (nr < 0 || nr >= n || nc < 0 || nc >= n) {\n                        adjCnt[0 * C + col]--; adjCnt[col * C + 0]--;\n                    } else {\n                        int d = g[nr * n + nc];\n                        if (d == col) {\n                            adjCnt[0 * C + col]++; adjCnt[col * C + 0]++;\n                        } else if (d == 0) {\n                            adjCnt[0 * C + col]--; adjCnt[col * C + 0]--;\n                        } else {\n                            adjCnt[col * C + d]--; adjCnt[d * C + col]--;\n                            adjCnt[0 * C + d]++; adjCnt[d * C + 0]++;\n                        }\n                    }\n                }\n                g[idx] = 0;\n                sz[col]--;\n                removed = true;\n                break;\n            }\n            if (!removed) break;\n        }\n        int zeros = 0;\n        for (int v : g) if (v == 0) zeros++;\n        return {zeros, move(g)};\n    }\n};\n\nvoid fastShuffle(vector<int> &v, FastRNG &rng) {\n    for (int i = (int)v.size() - 1; i > 0; --i) {\n        int j = rng.nextInt(i + 1);\n        swap(v[i], v[j]);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<int> g(n * n);\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { int c; cin >> c; g[i * n + j] = c; }\n\n    Solver solver(n, m, g);\n\n    vector<int> base(n * n);\n    iota(base.begin(), base.end(), 0);\n\n    vector<vector<int>> initialOrders;\n    vector<int> ord0 = base;\n    initialOrders.push_back(ord0);\n    vector<int> ord1 = base;\n    reverse(ord1.begin(), ord1.end());\n    initialOrders.push_back(ord1);\n    vector<int> ord2 = base;\n    sort(ord2.begin(), ord2.end(), [&](int a, int b) {\n        int ra = a / n, ca = a % n;\n        int rb = b / n, cb = b % n;\n        int da = min({ra, n - 1 - ra, ca, n - 1 - ca});\n        int db = min({rb, n - 1 - rb, cb, n - 1 - cb});\n        if (da != db) return da < db;\n        return a < b;\n    });\n    initialOrders.push_back(ord2);\n    vector<int> ord3 = base;\n    sort(ord3.begin(), ord3.end(), [&](int a, int b) {\n        int ra = a / n, ca = a % n;\n        int rb = b / n, cb = b % n;\n        int da = max({ra, n - 1 - ra, ca, n - 1 - ca});\n        int db = max({rb, n - 1 - rb, cb, n - 1 - cb});\n        if (da != db) return da < db;\n        return a < b;\n    });\n    initialOrders.push_back(ord3);\n\n    int bestZeros = -1;\n    vector<int> bestGrid = g;\n\n    for (auto &ord : initialOrders) {\n        auto res = solver.runWithOrder(g, ord);\n        if (res.first > bestZeros) {\n            bestZeros = res.first;\n            bestGrid = move(res.second);\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    const double TIME_LIMIT = 1.6; // seconds per test\n    FastRNG rng;\n    vector<int> order = base;\n\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n        if (elapsed > TIME_LIMIT) break;\n        fastShuffle(order, rng);\n        const vector<int> &startGrid = (rng.next() & 1) ? g : bestGrid;\n        auto res = solver.runWithOrder(startGrid, order);\n        if (res.first > bestZeros) {\n            bestZeros = res.first;\n            bestGrid = move(res.second);\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j) cout << ' ';\n            cout << bestGrid[i * n + j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, D, Q;\n    mt19937 rng;\n    int used = 0;\n    vector<vector<char>> cmp; // 0 unknown, 1 i>j, 2 equal, 3 i<j\n    vector<double> wins;\n    vector<int> comps;\n    string resp;\n\n    Solver(int n, int d, int q)\n        : N(n), D(d), Q(q), rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count()) {\n        cmp.assign(N, vector<char>(N, 0));\n        wins.assign(N, 0.0);\n        comps.assign(N, 0);\n    }\n\n    // Compare item i vs j, return true if i > j (heavier)\n    bool compare(int i, int j) {\n        if (cmp[i][j]) return cmp[i][j] == 1;\n        if (used >= Q) return false; // safety\n        cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << \"\\n\";\n        cout.flush();\n        if (!(cin >> resp)) exit(0);\n        char c = resp[0];\n        used++;\n        comps[i]++; comps[j]++;\n        if (c == '>') {\n            cmp[i][j] = 1; cmp[j][i] = 3;\n            wins[i] += 1.0;\n            return true;\n        } else if (c == '<') {\n            cmp[i][j] = 3; cmp[j][i] = 1;\n            wins[j] += 1.0;\n            return false;\n        } else {\n            cmp[i][j] = cmp[j][i] = 2;\n            wins[i] += 0.5; wins[j] += 0.5;\n            return false;\n        }\n    }\n\n    vector<int> merge_sort(const vector<int>& arr) {\n        int n = (int)arr.size();\n        if (n <= 1) return arr;\n        int mid = n / 2;\n        vector<int> left(arr.begin(), arr.begin() + mid);\n        vector<int> right(arr.begin() + mid, arr.end());\n        left = merge_sort(left);\n        right = merge_sort(right);\n        vector<int> res;\n        res.reserve(n);\n        int i = 0, j = 0;\n        while (i < (int)left.size() && j < (int)right.size()) {\n            int a = left[i], b = right[j];\n            if (compare(a, b)) {\n                res.push_back(a);\n                i++;\n            } else {\n                res.push_back(b);\n                j++;\n            }\n        }\n        while (i < (int)left.size()) res.push_back(left[i++]);\n        while (j < (int)right.size()) res.push_back(right[j++]);\n        return res;\n    }\n\n    int ceil_log2(int x) {\n        int r = 0; x--;\n        while (x > 0) { r++; x >>= 1; }\n        return r;\n    }\n\n    int cost_sort(int n) {\n        if (n <= 1) return 0;\n        int cl = ceil_log2(n);\n        return n * cl - (1 << cl) + 1;\n    }\n\n    void fill_queries_random() {\n        uniform_int_distribution<int> uid(0, N - 1);\n        while (used < Q) {\n            int a = uid(rng), b = uid(rng);\n            if (a == b) continue;\n            compare(a, b);\n        }\n    }\n\n    void solve() {\n        // Choose anchor size if possible\n        int bestA = -1;\n        for (int a = 2; a <= N; a++) {\n            int cl = ceil_log2(a);\n            long long cost = (long long)cost_sort(a) + (long long)(N - a) * cl;\n            if (cost <= Q) bestA = a;\n        }\n\n        vector<double> rank_est(N, 0.0);\n\n        if (bestA != -1) {\n            vector<int> anchors(bestA);\n            iota(anchors.begin(), anchors.end(), 0);\n            shuffle(anchors.begin(), anchors.end(), rng);\n            vector<char> isAnchor(N, 0);\n            for (int a : anchors) isAnchor[a] = 1;\n            vector<int> others;\n            others.reserve(N - bestA);\n            for (int i = 0; i < N; i++) if (!isAnchor[i]) others.push_back(i);\n\n            // Sort anchors exactly (heaviest first)\n            vector<int> anchor_order = merge_sort(anchors);\n            int A = (int)anchor_order.size();\n\n            for (int pos = 0; pos < A; pos++) {\n                double est = (double)pos * (double)N / (double)A;\n                rank_est[anchor_order[pos]] = est;\n            }\n\n            // Insert others by binary search among anchors\n            for (int item : others) {\n                int low = 0, high = A;\n                while (low < high) {\n                    int mid = (low + high) >> 1;\n                    int anchor = anchor_order[mid];\n                    if (compare(item, anchor)) {\n                        high = mid;\n                    } else {\n                        low = mid + 1;\n                    }\n                }\n                double est = (double)low * (double)N / (double)A;\n                rank_est[item] = est;\n            }\n\n            // Use remaining queries to gather more wins/comps\n            fill_queries_random();\n        } else {\n            // Fallback: random pair comparisons\n            vector<pair<int,int>> pairs;\n            pairs.reserve(N * (N - 1) / 2);\n            for (int i = 0; i < N; i++) {\n                for (int j = i + 1; j < N; j++) {\n                    pairs.emplace_back(i, j);\n                }\n            }\n            shuffle(pairs.begin(), pairs.end(), rng);\n            int pidx = 0;\n            while (used < Q) {\n                if (pidx >= (int)pairs.size()) {\n                    shuffle(pairs.begin(), pairs.end(), rng);\n                    pidx = 0;\n                }\n                auto pr = pairs[pidx++];\n                compare(pr.first, pr.second);\n            }\n            for (int i = 0; i < N; i++) {\n                double p = (comps[i] == 0) ? 0.5 : (wins[i] + 1.0) / (comps[i] + 2.0);\n                rank_est[i] = (1.0 - p) * (double)N;\n            }\n        }\n\n        // Estimate weights\n        double lambda = 1e-5;\n        double M = 100000.0 * N / D;\n        double ex = exp(-lambda * M);\n        vector<double> west(N, 0.0);\n        for (int i = 0; i < N; i++) {\n            double p_rank = (N - rank_est[i] - 0.5) / N;\n            if (p_rank < 0) p_rank = 0;\n            if (p_rank > 1) p_rank = 1;\n            double p_win = (comps[i] == 0) ? 0.5 : (wins[i] + 1.0) / (comps[i] + 2.0);\n            if (p_win < 0) p_win = 0;\n            if (p_win > 1) p_win = 1;\n            double p = 0.7 * p_rank + 0.3 * p_win;\n            if (p <= 1e-9) p = 1e-9;\n            if (p >= 1 - 1e-9) p = 1 - 1e-9;\n            double w = -log(1.0 - p * (1.0 - ex)) / lambda;\n            if (w > M) w = M;\n            west[i] = w;\n        }\n\n        // Initial greedy assignment\n        vector<int> ord(N);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) {\n            if (west[a] == west[b]) return a < b;\n            return west[a] > west[b];\n        });\n        vector<double> sum(D, 0.0);\n        vector<int> assign(N, 0);\n        for (int id : ord) {\n            int best = 0;\n            double bestsum = sum[0];\n            for (int d = 1; d < D; d++) {\n                if (sum[d] < bestsum) {\n                    bestsum = sum[d];\n                    best = d;\n                }\n            }\n            assign[id] = best;\n            sum[best] += west[id];\n        }\n\n        double total = accumulate(west.begin(), west.end(), 0.0);\n        double mean = total / D;\n        double curVar = 0.0;\n        for (int d = 0; d < D; d++) {\n            double diff = sum[d] - mean;\n            curVar += diff * diff;\n        }\n\n        // Hill-climbing (move/swap) to reduce variance\n        int ITER = 200000;\n        for (int it = 0; it < ITER; it++) {\n            if ((rng() & 1) == 0) {\n                int i = rng() % N;\n                int gi = assign[i];\n                int gj = rng() % D;\n                if (gi == gj) continue;\n                double w = west[i];\n                double si = sum[gi], sj = sum[gj];\n                double nsi = si - w, nsj = sj + w;\n                double newVar = curVar\n                    - (si - mean) * (si - mean) - (sj - mean) * (sj - mean)\n                    + (nsi - mean) * (nsi - mean) + (nsj - mean) * (nsj - mean);\n                if (newVar < curVar) {\n                    curVar = newVar;\n                    assign[i] = gj;\n                    sum[gi] = nsi;\n                    sum[gj] = nsj;\n                }\n            } else {\n                int i = rng() % N;\n                int j = rng() % N;\n                if (assign[i] == assign[j]) continue;\n                int gi = assign[i], gj = assign[j];\n                double wi = west[i], wj = west[j];\n                double si = sum[gi], sj = sum[gj];\n                double nsi = si - wi + wj;\n                double nsj = sj - wj + wi;\n                double newVar = curVar\n                    - (si - mean) * (si - mean) - (sj - mean) * (sj - mean)\n                    + (nsi - mean) * (nsi - mean) + (nsj - mean) * (nsj - mean);\n                if (newVar < curVar) {\n                    curVar = newVar;\n                    swap(assign[i], assign[j]);\n                    sum[gi] = nsi;\n                    sum[gj] = nsj;\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (i) cout << ' ';\n            cout << assign[i];\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n    Solver solver(N, D, Q);\n    solver.solve();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N_CONST = 200;\nconst int M_CONST = 10;\nconst int BUCKET_SIZE = 20;\nconst int INF_INT = 1e9;\n\nstruct Param {\n    int block_threshold; // if boxes above >= threshold, consider chunk/block move\n    int indiv_mode;      // 0: patience(top>=x), 1: bucket, 2: largestTop, 3: minHeight\n    int block_mode;      // 0: minHeight, 1: largestTop, 2: bucket, 3: patience(minVal), 4: maxMinStack, 5: safeMinStack>cur\n    int limit_block;     // 0 => move all above (until cur), else max chunk size to move\n    int safe_margin;     // if min(chunk) < cur + safe_margin, restrict chunk size\n    bool random_tie;     // random tie-breaking\n};\n\nstruct Result {\n    int cost;\n    int op_count;\n    vector<pair<int,int>> ops;\n    bool success;\n};\n\nchrono::steady_clock::time_point g_start;\ndouble TIME_LIMIT = 1.95;\n\ndouble elapsed_sec() {\n    return chrono::duration<double>(chrono::steady_clock::now() - g_start).count();\n}\n\n// destination for individual move of box x from src\nint select_dest_individual(int x, int src, const vector<vector<int>>& st, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.indiv_mode == 2) { // largestTop\n        int best = -1, bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.indiv_mode == 1) { // bucket preference\n        int target = (x - 1) / BUCKET_SIZE;\n        if (target != src) {\n            if (st[target].empty() || st[target].back() >= x) return target;\n        }\n    }\n    if (p.indiv_mode == 3) { // minHeight\n        int best = -1, bestSz = INF_INT, bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int sz = (int)st[i].size();\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n                bestSz = sz; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    // patience\n    int bestTop = INF_INT;\n    vector<int> cand;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top >= x) {\n            if (top < bestTop) {\n                bestTop = top; cand.clear(); cand.push_back(i);\n            } else if (top == bestTop) cand.push_back(i);\n        }\n    }\n    if (!cand.empty()) {\n        if (p.random_tie && cand.size() > 1) {\n            uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n            return cand[dist(rng)];\n        } else {\n            int best = cand[0], bestSz = (int)st[best].size();\n            for (int id = 1; id < (int)cand.size(); id++) {\n                int i = cand[id];\n                int sz = (int)st[i].size();\n                if (sz < bestSz) { bestSz = sz; best = i; }\n            }\n            return best;\n        }\n    }\n    // fallback largest top\n    bestTop = -INF_INT; cand.clear();\n    for (int i = 0; i < m; i++) if (i != src) {\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (top > bestTop) {\n            bestTop = top; cand.clear(); cand.push_back(i);\n        } else if (top == bestTop) cand.push_back(i);\n    }\n    if (p.random_tie && cand.size() > 1) {\n        uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n        return cand[dist(rng)];\n    } else {\n        int best = cand[0], bestSz = (int)st[best].size();\n        for (int id = 1; id < (int)cand.size(); id++) {\n            int i = cand[id];\n            int sz = (int)st[i].size();\n            if (sz < bestSz) { bestSz = sz; best = i; }\n        }\n        return best;\n    }\n}\n\n// destination for block/chunk move given minVal in chunk, current target cur, from src\nint select_dest_block(int minVal, int cur, int src, const vector<vector<int>>& st,\n                      const vector<int>& minStack, const Param& p, mt19937& rng) {\n    int m = (int)st.size();\n    if (p.block_mode == 1) { // largestTop\n        int best = -1, bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestTop || (top == bestTop && st[i].size() < st[best].size())) {\n                bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.block_mode == 2) { // bucket on minVal\n        int target = (minVal - 1) / BUCKET_SIZE;\n        if (target != src) return target;\n        // fallback to minHeight\n    }\n    if (p.block_mode == 3) { // patience on minVal\n        int bestTop = INF_INT;\n        vector<int> cand;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top >= minVal) {\n                if (top < bestTop) {\n                    bestTop = top; cand.clear(); cand.push_back(i);\n                } else if (top == bestTop) cand.push_back(i);\n            }\n        }\n        if (!cand.empty()) {\n            if (p.random_tie && cand.size() > 1) {\n                uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n                return cand[dist(rng)];\n            } else {\n                int best = cand[0], bestSz = (int)st[best].size();\n                for (int id = 1; id < (int)cand.size(); id++) {\n                    int i = cand[id];\n                    int sz = (int)st[i].size();\n                    if (sz < bestSz) { bestSz = sz; best = i; }\n                }\n                return best;\n            }\n        }\n        // fallback largestTop\n        int best = -1, bestT = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (top > bestT || (top == bestT && st[i].size() < st[best].size())) {\n                bestT = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.block_mode == 4) { // choose stack with maximum current minimum element\n        int best = -1;\n        int bestMin = -INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int mn = minStack[i];\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (mn > bestMin || (mn == bestMin && top > bestTop)) {\n                bestMin = mn; bestTop = top; best = i;\n            }\n        }\n        return best;\n    }\n    if (p.block_mode == 5) { // prefer stacks with minStack > cur\n        int best = -1;\n        int bestMin = -INF_INT;\n        int bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int mn = minStack[i];\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (mn > cur) {\n                if (mn > bestMin || (mn == bestMin && top > bestTop)) {\n                    bestMin = mn; bestTop = top; best = i;\n                }\n            }\n        }\n        if (best != -1) return best;\n        // fallback to block_mode 4\n        int b2 = -1; bestMin = -INF_INT; bestTop = -INF_INT;\n        for (int i = 0; i < m; i++) if (i != src) {\n            int mn = minStack[i];\n            int top = st[i].empty() ? INF_INT : st[i].back();\n            if (mn > bestMin || (mn == bestMin && top > bestTop)) {\n                bestMin = mn; bestTop = top; b2 = i;\n            }\n        }\n        return b2;\n    }\n    // minHeight\n    int best = -1, bestSz = INF_INT, bestTop = -INF_INT;\n    for (int i = 0; i < m; i++) if (i != src) {\n        int sz = (int)st[i].size();\n        int top = st[i].empty() ? INF_INT : st[i].back();\n        if (sz < bestSz || (sz == bestSz && top > bestTop)) {\n            bestSz = sz; bestTop = top; best = i;\n        }\n    }\n    return best;\n}\n\nResult simulate(const vector<vector<int>>& init, const Param& p, uint64_t seed, bool record_ops, int best_cost_so_far) {\n    mt19937 rng(seed);\n    vector<vector<int>> st = init;\n    vector<int> pos(N_CONST + 1, -1);\n    int m = (int)st.size();\n    vector<int> minStack(m, INF_INT);\n    for (int i = 0; i < m; i++) {\n        int mn = INF_INT;\n        for (int v : st[i]) { pos[v] = i; mn = min(mn, v); }\n        minStack[i] = mn;\n    }\n    int energy = 0, op_cnt = 0;\n    vector<pair<int,int>> ops;\n    if (record_ops) ops.reserve(3000);\n\n    for (int cur = 1; cur <= N_CONST; cur++) {\n        while (true) {\n            int s = pos[cur];\n            if (s < 0) return {INF_INT, op_cnt, ops, false};\n            if (!st[s].empty() && st[s].back() == cur) {\n                st[s].pop_back();\n                pos[cur] = -1;\n                op_cnt++;\n                if (record_ops) ops.emplace_back(cur, 0);\n                if (st[s].empty()) minStack[s] = INF_INT;\n                else if (cur == minStack[s]) {\n                    int mn = INF_INT;\n                    for (int v : st[s]) mn = min(mn, v);\n                    minStack[s] = mn;\n                }\n                break;\n            } else {\n                int d = 0;\n                for (int idx = (int)st[s].size() - 1; idx >= 0; idx--) {\n                    if (st[s][idx] == cur) break;\n                    d++;\n                }\n                bool did_block = false;\n                if (d > 0 && d >= p.block_threshold) {\n                    // compute min of all above\n                    int minAbove = INF_INT;\n                    for (int idx = (int)st[s].size() - d; idx < (int)st[s].size(); idx++) {\n                        minAbove = min(minAbove, st[s][idx]);\n                    }\n                    int move_k;\n                    if (p.safe_margin > 0 && minAbove < cur + p.safe_margin) {\n                        // risky, move only a small chunk\n                        if (p.limit_block > 0) move_k = min(d, p.limit_block);\n                        else move_k = p.block_threshold; // small chunk\n                    } else {\n                        move_k = d;\n                        if (p.limit_block > 0) move_k = min(move_k, p.limit_block);\n                    }\n                    // compute minVal of chunk to move (top move_k)\n                    int start_idx = (int)st[s].size() - move_k;\n                    int rep = st[s][start_idx];\n                    int minVal = INF_INT;\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        minVal = min(minVal, st[s][idx]);\n                    }\n                    int dest = select_dest_block(minVal, cur, s, st, minStack, p, rng);\n                    for (int idx = start_idx; idx < (int)st[s].size(); idx++) {\n                        int val = st[s][idx];\n                        st[dest].push_back(val);\n                        pos[val] = dest;\n                        minStack[dest] = min(minStack[dest], val);\n                    }\n                    st[s].resize(start_idx);\n                    if (st[s].empty()) minStack[s] = INF_INT;\n                    else {\n                        int mn = INF_INT;\n                        for (int v : st[s]) mn = min(mn, v);\n                        minStack[s] = mn;\n                    }\n                    energy += move_k + 1;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(rep, dest + 1);\n                    did_block = true;\n                }\n                if (!did_block) {\n                    int x = st[s].back();\n                    int dest = select_dest_individual(x, s, st, p, rng);\n                    st[s].pop_back();\n                    st[dest].push_back(x);\n                    pos[x] = dest;\n                    if (x == minStack[s]) {\n                        if (st[s].empty()) minStack[s] = INF_INT;\n                        else {\n                            int mn = INF_INT;\n                            for (int v : st[s]) mn = min(mn, v);\n                            minStack[s] = mn;\n                        }\n                    }\n                    minStack[dest] = min(minStack[dest], x);\n                    energy += 2;\n                    op_cnt++;\n                    if (record_ops) ops.emplace_back(x, dest + 1);\n                }\n                if (op_cnt > 5000) return {INF_INT, op_cnt, ops, false};\n                if (!record_ops && energy >= best_cost_so_far) {\n                    return {INF_INT, op_cnt, ops, false};\n                }\n            }\n        }\n    }\n    return {energy, op_cnt, ops, true};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    vector<vector<int>> init(m);\n    for (int i = 0; i < m; i++) {\n        init[i].reserve(n / m);\n        for (int j = 0; j < n / m; j++) {\n            int v; cin >> v;\n            init[i].push_back(v);\n        }\n    }\n\n    g_start = chrono::steady_clock::now();\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    vector<Param> base;\n    // diverse parameter candidates including safe_margin and block_mode=5\n    base.push_back({2, 0, 5, 0, 5, true});\n    base.push_back({3, 0, 5, 0, 5, true});\n    base.push_back({2, 1, 5, 0, 5, true});\n    base.push_back({2, 3, 5, 0, 5, true});\n    base.push_back({2, 0, 4, 0, 0, false});\n    base.push_back({3, 0, 4, 0, 0, false});\n    base.push_back({2, 0, 4, 5, 3, true});\n    base.push_back({3, 0, 4, 5, 3, true});\n    base.push_back({2, 0, 3, 0, 3, true});\n    base.push_back({2, 0, 2, 0, 0, false});\n    base.push_back({2, 0, 1, 0, 0, false});\n    base.push_back({1, 0, 5, 0, 5, true});\n    base.push_back({1, 0, 4, 0, 3, true});\n    base.push_back({2, 2, 5, 0, 5, true});\n    base.push_back({2, 0, 5, 5, 5, true});\n    base.push_back({2, 0, 5, 8, 5, true});\n    base.push_back({2, 0, 4, 8, 3, true});\n    base.push_back({3, 0, 4, 8, 3, true});\n    base.push_back({2, 0, 0, 0, 0, false}); // patience classic\n    base.push_back({3, 0, 0, 0, 0, false});\n    base.push_back({2, 1, 0, 0, 0, false});\n    base.push_back({2, 3, 0, 0, 0, false});\n\n    int best_cost = INF_INT;\n    vector<pair<int,int>> best_ops;\n\n    // evaluate base params quickly\n    for (const auto &p : base) {\n        if (elapsed_sec() > TIME_LIMIT) break;\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    // random exploration within time limit\n    vector<int> limits = {0, 5, 8, 10};\n    while (elapsed_sec() < TIME_LIMIT) {\n        Param p = base[rng() % base.size()];\n        p.random_tie = true;\n        int delta = (int)(rng() % 3) - 1; // -1,0,1\n        p.block_threshold = max(1, p.block_threshold + delta);\n        p.limit_block = limits[rng() % limits.size()];\n        // vary safe_margin slightly\n        int smd = (int)(rng() % 3) - 1;\n        p.safe_margin = max(0, p.safe_margin + smd);\n        uint64_t seed = rng();\n        Result r = simulate(init, p, seed, false, best_cost);\n        if (r.success && r.cost < best_cost) {\n            Result r2 = simulate(init, p, seed, true, best_cost);\n            if (r2.success && r2.cost < best_cost) {\n                best_cost = r2.cost;\n                best_ops.swap(r2.ops);\n            }\n        }\n    }\n\n    if (best_ops.empty()) {\n        // fallback simple strategy\n        Param p{2, 0, 4, 0, 3, true};\n        Result r = simulate(init, p, 1234567, true, INF_INT);\n        best_ops.swap(r.ops);\n    }\n\n    for (auto &op : best_ops) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, V;\nvector<string> hwall, vwall;\nvector<int> dflat;\nvector<vector<int>> adj;\nvector<short> distMat;\nvector<int> parMat;\n\ninline int id(int i, int j) { return i * N + j; }\n\nchar dirChar(int a, int b) {\n    int ai = a / N, aj = a % N;\n    int bi = b / N, bj = b % N;\n    if (bi == ai + 1) return 'D';\n    if (bi == ai - 1) return 'U';\n    if (bj == aj + 1) return 'R';\n    if (bj == aj - 1) return 'L';\n    return '?';\n}\n\nvoid bfs_all_pairs() {\n    distMat.assign(V * V, 0);\n    parMat.assign(V * V, -1);\n    vector<int> dist(V);\n    queue<int> q;\n    for (int s = 0; s < V; s++) {\n        fill(dist.begin(), dist.end(), -1);\n        dist[s] = 0;\n        parMat[s * V + s] = -1;\n        q.push(s);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int nb : adj[v]) {\n                if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    parMat[s * V + nb] = v;\n                    q.push(nb);\n                }\n            }\n        }\n        short *row = &distMat[s * V];\n        for (int i = 0; i < V; i++) row[i] = (short)dist[i];\n    }\n}\n\nvector<int> build_nn(bool randomized, mt19937 &rng) {\n    vector<int> ord(V);\n    vector<char> used(V, 0);\n    ord[0] = 0;\n    used[0] = 1;\n    for (int idx = 1; idx < V; idx++) {\n        int cur = ord[idx - 1];\n        int best = -1;\n        int bestd = INT_MAX;\n        const short *row = &distMat[cur * V];\n        if (randomized) {\n            vector<pair<int,int>> cand;\n            cand.reserve(10);\n            for (int v = 0; v < V; v++) if (!used[v]) {\n                int d = row[v];\n                if ((int)cand.size() < 10) {\n                    cand.emplace_back(d, v);\n                    push_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                } else if (d < cand.front().first) {\n                    pop_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                    cand.back() = {d, v};\n                    push_heap(cand.begin(), cand.end(), [](auto &a, auto &b){ return a.first < b.first; });\n                }\n            }\n            if (cand.empty()) break;\n            uniform_int_distribution<int> dist(0, (int)cand.size() - 1);\n            best = cand[dist(rng)].second;\n        } else {\n            for (int v = 0; v < V; v++) if (!used[v]) {\n                int d = row[v];\n                if (d < bestd) { bestd = d; best = v; }\n            }\n        }\n        if (best == -1) break;\n        ord[idx] = best;\n        used[best] = 1;\n    }\n    return ord;\n}\n\nvector<int> build_cheapest_insertion() {\n    vector<int> cycle;\n    vector<char> used(V, 0);\n    cycle.push_back(0);\n    used[0] = 1;\n    int nearest = -1, bestd = INT_MAX;\n    const short *row0 = &distMat[0];\n    for (int v = 1; v < V; v++) {\n        int d = row0[v];\n        if (d < bestd) { bestd = d; nearest = v; }\n    }\n    if (nearest == -1) nearest = 0;\n    cycle.push_back(nearest);\n    used[nearest] = 1;\n    while ((int)cycle.size() < V) {\n        int bestNode = -1, bestPos = -1, bestInc = INT_MAX;\n        int m = (int)cycle.size();\n        for (int v = 0; v < V; v++) if (!used[v]) {\n            for (int i = 0; i < m; i++) {\n                int a = cycle[i];\n                int b = cycle[(i + 1) % m];\n                int inc = (int)distMat[a * V + v] + (int)distMat[v * V + b] - (int)distMat[a * V + b];\n                if (inc < bestInc) {\n                    bestInc = inc;\n                    bestNode = v;\n                    bestPos = i;\n                }\n            }\n        }\n        if (bestNode == -1) break;\n        cycle.insert(cycle.begin() + bestPos + 1, bestNode);\n        used[bestNode] = 1;\n    }\n    return cycle;\n}\n\nvector<int> build_mst_preorder() {\n    vector<int> parent(V, -1);\n    vector<int> key(V, INT_MAX);\n    vector<char> inMST(V, 0);\n    key[0] = 0;\n    for (int cnt = 0; cnt < V; cnt++) {\n        int u = -1, minKey = INT_MAX;\n        for (int v = 0; v < V; v++) if (!inMST[v] && key[v] < minKey) {\n            minKey = key[v]; u = v;\n        }\n        if (u == -1) break;\n        inMST[u] = 1;\n        const short *row = &distMat[u * V];\n        for (int v = 0; v < V; v++) if (!inMST[v]) {\n            int w = row[v];\n            if (w < key[v]) {\n                key[v] = w;\n                parent[v] = u;\n            }\n        }\n    }\n    vector<vector<int>> tree(V);\n    for (int v = 1; v < V; v++) if (parent[v] >= 0) tree[parent[v]].push_back(v);\n    vector<int> order;\n    order.reserve(V);\n    function<void(int)> dfs = [&](int u) {\n        order.push_back(u);\n        for (int v : tree[u]) dfs(v);\n    };\n    dfs(0);\n    return order;\n}\n\nlong long tour_length(const vector<int> &ord) {\n    long long len = 0;\n    for (int i = 0; i < V; i++) {\n        int a = ord[i];\n        int b = ord[(i + 1) % V];\n        len += (int)distMat[a * V + b];\n    }\n    return len;\n}\n\nvoid rotate_to_start(vector<int> &ord, int start = 0) {\n    int pos = -1;\n    for (int i = 0; i < V; i++) if (ord[i] == start) { pos = i; break; }\n    if (pos > 0) rotate(ord.begin(), ord.begin() + pos, ord.end());\n}\n\nvoid two_opt(vector<int> &ord, long long &curLen, double timeLimit, chrono::steady_clock::time_point startTime) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < V; i++) {\n            int a = ord[i];\n            int b = ord[(i + 1) % V];\n            for (int j = i + 2; j < V; j++) {\n                if (i == 0 && j == V - 1) continue;\n                int c = ord[j];\n                int d = ord[(j + 1) % V];\n                int delta = (int)distMat[a * V + c] + (int)distMat[b * V + d] - (int)distMat[a * V + b] - (int)distMat[c * V + d];\n                if (delta < 0) {\n                    reverse(ord.begin() + i + 1, ord.begin() + j + 1);\n                    curLen += delta;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n            if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > timeLimit) return;\n        }\n    }\n}\n\nvector<int> path_nodes(int s, int t) {\n    vector<int> path;\n    int cur = t;\n    while (cur != s) {\n        path.push_back(cur);\n        cur = parMat[s * V + cur];\n        if (cur == -1) { path.clear(); return path; }\n    }\n    path.push_back(s);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring moves_from_path(const vector<int> &path) {\n    string res;\n    for (int i = 1; i < (int)path.size(); i++) {\n        res.push_back(dirChar(path[i - 1], path[i]));\n    }\n    return res;\n}\n\nstring build_route_from_order(const vector<int> &ord) {\n    string moves;\n    moves.reserve((size_t)tour_length(ord) + 5);\n    for (int i = 0; i < V; i++) {\n        int s = ord[i];\n        int t = ord[(i + 1) % V];\n        if (s == t) continue;\n        vector<int> path = path_nodes(s, t);\n        if (path.empty()) return \"\";\n        for (int k = 1; k < (int)path.size(); k++) {\n            moves.push_back(dirChar(path[k - 1], path[k]));\n        }\n    }\n    return moves;\n}\n\nstring build_dfs_route() {\n    string res;\n    vector<vector<char>> vis(N, vector<char>(N, 0));\n    int di[4] = {0, 1, 0, -1};\n    int dj[4] = {1, 0, -1, 0};\n    char dc[4] = {'R', 'D', 'L', 'U'};\n    function<void(int, int)> dfs = [&](int i, int j) {\n        vis[i][j] = 1;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            bool wall = false;\n            if (dir == 0) wall = (vwall[i][j] == '1');\n            else if (dir == 2) wall = (vwall[i][j - 1] == '1');\n            else if (dir == 1) wall = (hwall[i][j] == '1');\n            else wall = (hwall[i - 1][j] == '1');\n            if (wall) continue;\n            if (!vis[ni][nj]) {\n                res.push_back(dc[dir]);\n                dfs(ni, nj);\n                res.push_back(dc[(dir + 2) % 4]);\n            }\n        }\n    };\n    dfs(0, 0);\n    return res;\n}\n\ndouble compute_average(const string &route) {\n    int L = (int)route.size();\n    int i = 0, j = 0;\n    vector<vector<int>> times(V);\n    times.reserve(V);\n    for (int t = 0; t < L; t++) {\n        char c = route[t];\n        int ni = i, nj = j;\n        if (c == 'U') {\n            ni--;\n            if (ni < 0 || hwall[ni][nj] == '1') return 1e100;\n        } else if (c == 'D') {\n            if (i >= N - 1 || hwall[i][j] == '1') return 1e100;\n            ni++;\n        } else if (c == 'L') {\n            if (j <= 0 || vwall[i][j - 1] == '1') return 1e100;\n            nj--;\n        } else if (c == 'R') {\n            if (j >= N - 1 || vwall[i][j] == '1') return 1e100;\n            nj++;\n        } else {\n            return 1e100;\n        }\n        i = ni; j = nj;\n        times[i * N + j].push_back(t);\n    }\n    if (i != 0 || j != 0) return 1e100;\n    double total = 0.0;\n    for (int v = 0; v < V; v++) {\n        if (times[v].empty()) return 1e100;\n        const auto &vec = times[v];\n        int k = (int)vec.size();\n        for (int idx = 0; idx < k; idx++) {\n            int t1 = vec[idx];\n            int t2 = (idx + 1 < k) ? vec[idx + 1] : vec[0] + L;\n            long long len = (long long)t2 - t1;\n            total += (double)dflat[v] * (double)(len * (len - 1) / 2.0);\n        }\n    }\n    return total / (double)L;\n}\n\nchar invertDir(char c) {\n    if (c == 'U') return 'D';\n    if (c == 'D') return 'U';\n    if (c == 'L') return 'R';\n    if (c == 'R') return 'L';\n    return c;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin >> N)) return 0;\n    hwall.resize(N - 1);\n    for (int i = 0; i < N - 1; i++) cin >> hwall[i];\n    vwall.resize(N);\n    for (int i = 0; i < N; i++) cin >> vwall[i];\n    dflat.resize(N * N);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int x; cin >> x;\n        dflat[id(i, j)] = x;\n    }\n    V = N * N;\n    adj.assign(V, {});\n    auto add_edge = [&](int i1, int j1, int i2, int j2) {\n        int a = id(i1, j1), b = id(i2, j2);\n        adj[a].push_back(b);\n        adj[b].push_back(a);\n    };\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i + 1 < N && hwall[i][j] == '0') add_edge(i, j, i + 1, j);\n            if (j + 1 < N && vwall[i][j] == '0') add_edge(i, j, i, j + 1);\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    bfs_all_pairs();\n    mt19937 rng(1234567);\n\n    vector<vector<int>> candOrders;\n    candOrders.push_back(build_nn(false, rng));\n    candOrders.push_back(build_nn(true, rng));\n    candOrders.push_back(build_cheapest_insertion());\n    candOrders.push_back(build_mst_preorder());\n\n    long long bestLen = (1LL << 60);\n    vector<int> bestOrder;\n    double timeLimit = 1.0; // seconds for optimization\n    for (auto &ord : candOrders) {\n        rotate_to_start(ord, 0);\n        long long len = tour_length(ord);\n        two_opt(ord, len, timeLimit, startTime);\n        rotate_to_start(ord, 0);\n        len = tour_length(ord);\n        if (len < bestLen) {\n            bestLen = len;\n            bestOrder = ord;\n        }\n        if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > 1.0) break;\n    }\n\n    string baseRoute;\n    if (!bestOrder.empty()) baseRoute = build_route_from_order(bestOrder);\n    if (baseRoute.empty() || baseRoute.size() > 100000) {\n        baseRoute = build_dfs_route();\n        if (baseRoute.size() > 100000) {\n            baseRoute = baseRoute.substr(0, 100000);\n        }\n        cout << baseRoute << \"\\n\";\n        return 0;\n    }\n\n    double bestAvg = compute_average(baseRoute);\n    string bestRoute = baseRoute;\n\n    // Build loop candidates\n    vector<int> idx(V);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int a, int b){ return dflat[a] > dflat[b]; });\n    int K = min(8, V - 1);\n    vector<int> top;\n    for (int i = 0; i < K; i++) top.push_back(idx[i]);\n    vector<string> loopCandidates;\n\n    for (int v : top) {\n        vector<int> path = path_nodes(0, v);\n        if (path.empty()) continue;\n        string moves = moves_from_path(path);\n        string loop = moves;\n        for (int i = (int)moves.size() - 1; i >= 0; i--) loop.push_back(invertDir(moves[i]));\n        if (!loop.empty()) loopCandidates.push_back(loop);\n    }\n    auto build_cluster_loop = [&](int cnt) {\n        cnt = min(cnt, (int)top.size());\n        if (cnt == 0) return;\n        vector<int> sel(top.begin(), top.begin() + cnt);\n        vector<char> used(V, 0);\n        int cur = 0;\n        vector<int> orderNodes;\n        orderNodes.push_back(0);\n        while (!sel.empty()) {\n            int best = -1, bestd = INT_MAX, bestIdx = -1;\n            for (int i = 0; i < (int)sel.size(); i++) {\n                int v = sel[i];\n                int d = distMat[cur * V + v];\n                if (d < bestd) { bestd = d; best = v; bestIdx = i; }\n            }\n            if (best == -1) break;\n            orderNodes.push_back(best);\n            cur = best;\n            sel.erase(sel.begin() + bestIdx);\n        }\n        orderNodes.push_back(0);\n        string moves;\n        bool fail = false;\n        for (int i = 1; i < (int)orderNodes.size(); i++) {\n            vector<int> path = path_nodes(orderNodes[i - 1], orderNodes[i]);\n            if (path.empty()) { fail = true; break; }\n            moves += moves_from_path(path);\n        }\n        if (!fail && !moves.empty()) loopCandidates.push_back(moves);\n    };\n    build_cluster_loop(3);\n    build_cluster_loop(5);\n\n    int baseLen = (int)baseRoute.size();\n    for (const string &loop : loopCandidates) {\n        int lLen = (int)loop.size();\n        if (lLen == 0) continue;\n        int maxReps = (100000 - baseLen) / lLen;\n        if (maxReps <= 0) continue;\n        int repsToTest = min(maxReps, 12);\n        string temp = baseRoute;\n        for (int r = 1; r <= repsToTest; r++) {\n            temp += loop;\n            double avg = compute_average(temp);\n            if (avg < bestAvg) {\n                bestAvg = avg;\n                bestRoute = temp;\n            }\n            if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > 1.8) break;\n        }\n        if (chrono::duration<double>(chrono::steady_clock::now() - startTime).count() > 1.8) break;\n    }\n\n    cout << bestRoute << \"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random generator\nstruct XorShift {\n    uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    uint32_t operator()() {\n        uint32_t t = x ^ (x << 11);\n        x = y; y = z; z = w;\n        w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n        return w;\n    }\n    int nextInt(int n) { return (*this)() % n; }\n    double nextDouble() { return (*this)() * (1.0 / 4294967296.0); }\n} rng;\n\n// Overlap between suffix of a and prefix of b (general length)\ninline int overlapGeneral(const string &a, const string &b) {\n    int maxk = min((int)a.size(), (int)b.size());\n    for (int k = maxk; k >= 1; k--) {\n        bool ok = true;\n        const char *pa = a.data() + a.size() - k;\n        const char *pb = b.data();\n        for (int t = 0; t < k; t++) {\n            if (pa[t] != pb[t]) { ok = false; break; }\n        }\n        if (ok) return k;\n    }\n    return 0;\n}\n\n// Greedy pairwise merge; if randomize, tie-breaking is random. costAware: score uses letter distance.\nstring greedyMerge(vector<string> v, const vector<vector<int>> &letterDist, bool randomize, bool costAware, int W) {\n    while (v.size() > 1) {\n        int n = (int)v.size();\n        int bestScore = INT_MIN;\n        vector<pair<int,int>> cand;\n        for (int i = 0; i < n; i++) {\n            const string &ai = v[i];\n            int lastC = ai.back() - 'A';\n            for (int j = 0; j < n; j++) if (i != j) {\n                int o = overlapGeneral(ai, v[j]);\n                int sc = o;\n                if (costAware) {\n                    int firstC = v[j][0]-'A';\n                    sc = o * W - letterDist[lastC][firstC];\n                }\n                if (sc > bestScore) {\n                    bestScore = sc;\n                    cand.clear();\n                    cand.emplace_back(i, j);\n                } else if (sc == bestScore) {\n                    cand.emplace_back(i, j);\n                }\n            }\n        }\n        pair<int,int> chosen = cand[randomize ? rng.nextInt((int)cand.size()) : 0];\n        int i = chosen.first, j = chosen.second;\n        int o = overlapGeneral(v[i], v[j]);\n        string merged = v[i] + v[j].substr(o);\n        vector<string> nv;\n        nv.reserve(n - 1);\n        for (int k = 0; k < n; k++) {\n            if (k == i || k == j) continue;\n            nv.push_back(std::move(v[k]));\n        }\n        nv.push_back(std::move(merged));\n        v.swap(nv);\n    }\n    return v[0];\n}\n\n// Compute minimal typing cost of string S (DP over positions)\nint computeCost(const string &S, const array<vector<pair<int,int>>,26> &posList, int si, int sj) {\n    const int INF = 1e9;\n    static int prevCost[230];\n    static int currCost[230];\n    int prevSize = 0, currSize = 0;\n    int L = (int)S.size();\n    int c0 = S[0]-'A';\n    const auto &v0 = posList[c0];\n    prevSize = (int)v0.size();\n    for (int i = 0; i < prevSize; i++) {\n        prevCost[i] = abs(v0[i].first - si) + abs(v0[i].second - sj) + 1;\n    }\n    for (int k = 1; k < L; k++) {\n        int c = S[k]-'A';\n        const auto &cv = posList[c];\n        currSize = (int)cv.size();\n        int pc = S[k-1]-'A';\n        const auto &pv = posList[pc];\n        for (int ci = 0; ci < currSize; ci++) {\n            int best = INF;\n            int x2 = cv[ci].first, y2 = cv[ci].second;\n            for (int pi = 0; pi < prevSize; pi++) {\n                int cand = prevCost[pi] + abs(pv[pi].first - x2) + abs(pv[pi].second - y2) + 1;\n                if (cand < best) best = cand;\n            }\n            currCost[ci] = best;\n        }\n        prevSize = currSize;\n        for (int i = 0; i < prevSize; i++) prevCost[i] = currCost[i];\n    }\n    int res = INF;\n    for (int i = 0; i < prevSize; i++) if (prevCost[i] < res) res = prevCost[i];\n    return res;\n}\n\n// Compute optimal path (positions) for string S\nvector<pair<int,int>> computePath(const string &S, const array<vector<pair<int,int>>,26> &posList, int si, int sj) {\n    const int INF = 1e9;\n    int L = (int)S.size();\n    vector<vector<int>> dp(L);\n    vector<vector<int>> parent(L);\n    int c0 = S[0]-'A';\n    const auto &v0 = posList[c0];\n    dp[0].assign(v0.size(), INF);\n    parent[0].assign(v0.size(), -1);\n    for (size_t i = 0; i < v0.size(); i++) {\n        dp[0][i] = abs(v0[i].first - si) + abs(v0[i].second - sj) + 1;\n    }\n    for (int k = 1; k < L; k++) {\n        int c = S[k]-'A';\n        int pc = S[k-1]-'A';\n        const auto &cv = posList[c];\n        const auto &pv = posList[pc];\n        dp[k].assign(cv.size(), INF);\n        parent[k].assign(cv.size(), -1);\n        for (size_t ci = 0; ci < cv.size(); ci++) {\n            int best = INF;\n            int bestIdx = -1;\n            int x2 = cv[ci].first, y2 = cv[ci].second;\n            for (size_t pi = 0; pi < pv.size(); pi++) {\n                int cand = dp[k-1][pi] + abs(pv[pi].first - x2) + abs(pv[pi].second - y2) + 1;\n                if (cand < best) {\n                    best = cand;\n                    bestIdx = (int)pi;\n                }\n            }\n            dp[k][ci] = best;\n            parent[k][ci] = bestIdx;\n        }\n    }\n    int endIdx = (int)(min_element(dp[L-1].begin(), dp[L-1].end()) - dp[L-1].begin());\n    vector<pair<int,int>> path(L);\n    int idx = endIdx;\n    for (int k = L-1; k >= 0; k--) {\n        int c = S[k]-'A';\n        path[k] = posList[c][idx];\n        idx = parent[k][idx];\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    vector<string> words(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n\n    // positions for each letter\n    array<vector<pair<int,int>>,26> posList;\n    for (int c = 0; c < 26; c++) posList[c].clear();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int c = grid[i][j]-'A';\n            posList[c].push_back({i,j});\n        }\n    }\n\n    // letter distance matrix (min manhattan)\n    const int INF = 1e9;\n    vector<vector<int>> letterDist(26, vector<int>(26, INF));\n    for (int a = 0; a < 26; a++) {\n        for (int b = 0; b < 26; b++) {\n            int best = INF;\n            for (auto &p1 : posList[a]) {\n                for (auto &p2 : posList[b]) {\n                    int d = abs(p1.first - p2.first) + abs(p1.second - p2.second);\n                    if (d < best) best = d;\n                }\n            }\n            letterDist[a][b] = best;\n        }\n    }\n\n    // overlap matrix for original words (length 5)\n    vector<vector<int>> ov(M, vector<int>(M,0));\n    vector<int> firstChar(M), lastChar(M);\n    for (int i = 0; i < M; i++) {\n        firstChar[i] = words[i][0]-'A';\n        lastChar[i] = words[i].back()-'A';\n    }\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < M; j++) if (i != j) {\n            int best_o = 0;\n            for (int k = 5; k >= 1; k--) {\n                bool ok = true;\n                for (int t = 0; t < k; t++) {\n                    if (words[i][5 - k + t] != words[j][t]) { ok = false; break; }\n                }\n                if (ok) { best_o = k; break; }\n            }\n            ov[i][j] = best_o;\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 1.9; // seconds\n\n    vector<string> candidates;\n\n    // Some deterministic greedy merges\n    candidates.push_back(greedyMerge(words, letterDist, false, false, 10));\n    candidates.push_back(greedyMerge(words, letterDist, false, true, 10));\n\n    // Random greedy merges for variety\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > timeLimit * 0.5) break;\n        bool costAware = rng.nextInt(2);\n        int W = 8 + rng.nextInt(5); // 8..12\n        candidates.push_back(greedyMerge(words, letterDist, true, costAware, W));\n    }\n\n    // Build initial order starting from closest first letter\n    int bestStart = 0, minDist = INF;\n    for (int i = 0; i < M; i++) {\n        int c = firstChar[i];\n        for (auto &p : posList[c]) {\n            int d = abs(p.first - si) + abs(p.second - sj);\n            if (d < minDist) {\n                minDist = d;\n                bestStart = i;\n            }\n        }\n    }\n\n    auto buildOrder = [&](int W)->vector<int>{\n        vector<int> ord;\n        vector<char> used(M,0);\n        ord.reserve(M);\n        ord.push_back(bestStart);\n        used[bestStart]=1;\n        for(int step=1; step<M; step++){\n            int cur = ord.back();\n            int best=-1;\n            int bestScore=-INF;\n            for(int j=0;j<M;j++) if(!used[j]){\n                int sc = ov[cur][j]*W - letterDist[lastChar[cur]][firstChar[j]];\n                if(sc > bestScore){\n                    bestScore = sc;\n                    best = j;\n                }\n            }\n            if(best==-1){\n                for(int j=0;j<M;j++) if(!used[j]){ best=j; break; }\n            }\n            used[best]=1;\n            ord.push_back(best);\n        }\n        return ord;\n    };\n    auto edgeScore = [&](const vector<int>&ord,int idx,int W)->int{\n        if(idx<0 || idx+1>=(int)ord.size()) return 0;\n        return ov[ord[idx]][ord[idx+1]]*W - letterDist[lastChar[ord[idx]]][firstChar[ord[idx+1]]];\n    };\n    auto buildStringFromOrder = [&](const vector<int>&ord)->string{\n        string s = words[ord[0]];\n        s.reserve(5*ord.size());\n        for(int i=1;i<(int)ord.size();i++){\n            int o = ov[ord[i-1]][ord[i]];\n            s += words[ord[i]].substr(o);\n        }\n        return s;\n    };\n\n    vector<int> weights = {8,10,12};\n    for(int W: weights){\n        vector<int> ord = buildOrder(W);\n        int curScore = 0;\n        for(int i=0;i+1<M;i++) curScore += edgeScore(ord,i,W);\n        int bestScore = curScore;\n        vector<int> bestOrd = ord;\n        // hill climb for some time\n        while (true) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > timeLimit * 0.8) break;\n            int a = 1 + rng.nextInt(M-1);\n            int b = 1 + rng.nextInt(M-1);\n            if (a==b) continue;\n            if (a>b) swap(a,b);\n            int old = edgeScore(ord,a-1,W)+edgeScore(ord,a,W);\n            if (b!=a+1) old += edgeScore(ord,b-1,W)+edgeScore(ord,b,W);\n            swap(ord[a], ord[b]);\n            int neu = edgeScore(ord,a-1,W)+edgeScore(ord,a,W);\n            if (b!=a+1) neu += edgeScore(ord,b-1,W)+edgeScore(ord,b,W);\n            int delta = neu - old;\n            if (delta >= 0 || rng.nextDouble() < 0.01) {\n                curScore += delta;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestOrd = ord;\n                }\n            } else {\n                swap(ord[a], ord[b]);\n            }\n        }\n        candidates.push_back(buildStringFromOrder(bestOrd));\n    }\n\n    // Evaluate candidates and pick best by cost\n    int bestCost = INF;\n    string bestString;\n    for (auto &s : candidates) {\n        int cst = computeCost(s, posList, si, sj);\n        if (cst < bestCost) {\n            bestCost = cst;\n            bestString = s;\n        }\n    }\n\n    // Compute path for bestString\n    auto path = computePath(bestString, posList, si, sj);\n    for (auto &p : path) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    vector<int> cells;\n};\n\nclass Solver {\npublic:\n    int N, M;\n    double eps;\n    vector<vector<pair<int,int>>> shapes;\n\n    vector<vector<Placement>> placements;\n    vector<vector<vector<int>>> cellToPlacements;\n    vector<vector<char>> alive;\n    vector<int> domainSize;\n    vector<vector<int>> cellCoverCount;\n    vector<int> totalCoverage;\n    vector<int> fieldCoverage;\n\n    vector<int> obs;\n    vector<int> drilledIds, drilledVals;\n\n    vector<int> minCoverCell, maxCoverCell;\n\n    chrono::steady_clock::time_point startTime;\n    int searchTimeUsed = 0;\n    int searchTimeCap = 2200; // ms\n\n    Solver(int N_, int M_, double eps_) : N(N_), M(M_), eps(eps_) {}\n\n    int cellId(int i,int j) const { return i*N + j; }\n    pair<int,int> cellCoord(int id) const { return {id / N, id % N}; }\n\n    void readInput() {\n        shapes.resize(M);\n        for (int k=0;k<M;k++) {\n            int d; cin>>d;\n            shapes[k].resize(d);\n            for (int t=0;t<d;t++) {\n                int i,j; cin>>i>>j;\n                shapes[k][t] = {i,j};\n            }\n        }\n    }\n\n    void buildPlacements() {\n        placements.resize(M);\n        cellToPlacements.resize(M, vector<vector<int>>(N*N));\n        alive.resize(M);\n        domainSize.resize(M);\n        cellCoverCount.assign(M, vector<int>(N*N, 0));\n        totalCoverage.assign(N*N, 0);\n        fieldCoverage.assign(N*N, 0);\n\n        for (int f=0; f<M; f++) {\n            int maxI=0, maxJ=0;\n            for (auto &p: shapes[f]) { maxI = max(maxI, p.first); maxJ = max(maxJ, p.second); }\n            int h = maxI+1;\n            int w = maxJ+1;\n            for (int di=0; di<=N-h; di++) {\n                for (int dj=0; dj<=N-w; dj++) {\n                    Placement pl;\n                    pl.cells.reserve(shapes[f].size());\n                    for (auto &p: shapes[f]) {\n                        int ni = p.first + di;\n                        int nj = p.second + dj;\n                        pl.cells.push_back(cellId(ni,nj));\n                    }\n                    int idx = placements[f].size();\n                    placements[f].push_back(std::move(pl));\n                    for (int c: placements[f].back().cells) {\n                        cellToPlacements[f][c].push_back(idx);\n                    }\n                }\n            }\n            int sz = placements[f].size();\n            alive[f].assign(sz, 1);\n            domainSize[f] = sz;\n            for (int idx=0; idx<sz; idx++) {\n                for (int c: placements[f][idx].cells) {\n                    totalCoverage[c]++;\n                    cellCoverCount[f][c]++;\n                }\n            }\n        }\n        for (int c=0; c<N*N; c++) {\n            int cnt=0;\n            for (int f=0; f<M; f++) if (cellCoverCount[f][c]>0) cnt++;\n            fieldCoverage[c] = cnt;\n        }\n        minCoverCell.assign(N*N, 0);\n        maxCoverCell.assign(N*N, 0);\n    }\n\n    bool removePlacement(int f,int p) {\n        if (!alive[f][p]) return false;\n        alive[f][p]=0;\n        domainSize[f]--;\n        for (int c: placements[f][p].cells) {\n            totalCoverage[c]--;\n            cellCoverCount[f][c]--;\n            if (cellCoverCount[f][c]==0) {\n                fieldCoverage[c]--;\n            }\n        }\n        return true;\n    }\n\n    bool placementCoversCell(int f,int p,int cell) {\n        for (int c: placements[f][p].cells) if (c==cell) return true;\n        return false;\n    }\n\n    bool removePlacementsCovering(int f,int cell) {\n        bool changed=false;\n        for (int p: cellToPlacements[f][cell]) {\n            if (alive[f][p]) {\n                removePlacement(f,p);\n                changed=true;\n            }\n        }\n        return changed;\n    }\n\n    bool removePlacementsNotCovering(int f,int cell) {\n        bool changed=false;\n        int sz = placements[f].size();\n        for (int p=0; p<sz; p++) if (alive[f][p]) {\n            if (!placementCoversCell(f,p,cell)) {\n                removePlacement(f,p);\n                changed=true;\n            }\n        }\n        return changed;\n    }\n\n    void recomputeCoverBounds() {\n        for (int c=0; c<N*N; c++) {\n            int minC=0, maxC=0;\n            for (int f=0; f<M; f++) {\n                if (domainSize[f]==0) continue;\n                int cc = cellCoverCount[f][c];\n                if (cc>0) maxC++;\n                if (cc==domainSize[f] && cc>0) minC++;\n            }\n            minCoverCell[c]=minC;\n            maxCoverCell[c]=maxC;\n        }\n    }\n\n    bool prunePlacementsBounds() {\n        recomputeCoverBounds();\n        bool changed=false;\n        for (int f=0; f<M; f++) if (domainSize[f]>0) {\n            int sz = placements[f].size();\n            for (int p=0; p<sz; p++) if (alive[f][p]) {\n                bool ok=true;\n                for (size_t idx=0; idx<drilledIds.size(); idx++) {\n                    int cell = drilledIds[idx];\n                    int v = drilledVals[idx];\n                    bool covers=false;\n                    for (int c: placements[f][p].cells) { if (c==cell){covers=true;break;} }\n                    int minOthers = minCoverCell[cell];\n                    int maxOthers = maxCoverCell[cell];\n                    if (covers) {\n                        minOthers -= (cellCoverCount[f][cell]==domainSize[f]) ? 1 : 0;\n                        maxOthers -= (cellCoverCount[f][cell]>0) ? 1 : 0;\n                        if (v < minOthers+1 || v > maxOthers+1) { ok=false; break; }\n                    } else {\n                        if (v < minOthers || v > maxOthers) { ok=false; break; }\n                    }\n                }\n                if (!ok) {\n                    removePlacement(f,p);\n                    changed=true;\n                }\n            }\n        }\n        return changed;\n    }\n\n    void propagateConstraints() {\n        bool changed;\n        do {\n            changed=false;\n            for (size_t idx=0; idx<drilledIds.size(); idx++) {\n                int cell = drilledIds[idx];\n                int val = drilledVals[idx];\n                if (val<0) continue;\n                int maxCov=0, minCov=0;\n                for (int f=0; f<M; f++) {\n                    if (domainSize[f]==0) continue;\n                    int cnt = cellCoverCount[f][cell];\n                    if (cnt>0) maxCov++;\n                    if (cnt==domainSize[f] && cnt>0) minCov++;\n                }\n                if (val==0) {\n                    for (int f=0; f<M; f++) {\n                        if (cellCoverCount[f][cell]>0) {\n                            if (removePlacementsCovering(f,cell)) changed=true;\n                        }\n                    }\n                    continue;\n                }\n                if (val==maxCov && maxCov>0) {\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0) {\n                            if (cellCoverCount[f][cell] < domainSize[f]) {\n                                if (removePlacementsNotCovering(f,cell)) changed=true;\n                            }\n                        }\n                    }\n                } else if (val==minCov) {\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0 && cellCoverCount[f][cell]<domainSize[f]) {\n                            if (removePlacementsCovering(f,cell)) changed=true;\n                        }\n                    }\n                }\n            }\n        } while (changed);\n        // additional pruning\n        int iter=0;\n        while (iter<2) {\n            bool ch = prunePlacementsBounds();\n            if (!ch) break;\n            iter++;\n            bool c2=false;\n            for (size_t idx=0; idx<drilledIds.size(); idx++) {\n                int cell = drilledIds[idx];\n                int val = drilledVals[idx];\n                int maxCov=0, minCov=0;\n                for (int f=0; f<M; f++) {\n                    if (domainSize[f]==0) continue;\n                    int cnt = cellCoverCount[f][cell];\n                    if (cnt>0) maxCov++;\n                    if (cnt==domainSize[f] && cnt>0) minCov++;\n                }\n                if (val==0) {\n                    for (int f=0; f<M; f++) {\n                        if (cellCoverCount[f][cell]>0) {\n                            if (removePlacementsCovering(f,cell)) c2=true;\n                        }\n                    }\n                } else if (val==maxCov && maxCov>0) {\n                    for (int f=0; f<M; f++) {\n                        if (domainSize[f]>0 && cellCoverCount[f][cell]>0) {\n                            if (cellCoverCount[f][cell] < domainSize[f]) {\n                                if (removePlacementsNotCovering(f,cell)) c2=true;\n                            }\n                        }\n                    }\n                }\n            }\n            if (!c2) break;\n        }\n    }\n\n    int drillCell(int cell) {\n        auto [i,j] = cellCoord(cell);\n        cout << \"q 1 \" << i << \" \" << j << \"\\n\" << flush;\n        int resp;\n        if (!(cin >> resp)) exit(0);\n        obs[cell]=resp;\n        drilledIds.push_back(cell);\n        drilledVals.push_back(resp);\n        if (resp==0) {\n            for (int f=0; f<M; f++) {\n                if (cellCoverCount[f][cell]>0) {\n                    removePlacementsCovering(f,cell);\n                }\n            }\n        }\n        return resp;\n    }\n\n    bool allDomainsSingleton() const {\n        for (int f=0; f<M; f++) if (domainSize[f]!=1) return false;\n        return true;\n    }\n\n    vector<int> computeUnionFromDomains() const {\n        vector<char> oil(N*N,0);\n        for (int f=0; f<M; f++) {\n            int pidx=-1;\n            for (int p=0; p<(int)placements[f].size(); p++) if (alive[f][p]) { pidx=p; break; }\n            if (pidx==-1) continue;\n            for (int c: placements[f][pidx].cells) oil[c]=1;\n        }\n        vector<int> res;\n        for (int c=0; c<N*N; c++) if (oil[c]) res.push_back(c);\n        return res;\n    }\n\n    struct DFSState {\n        const vector<vector<int>> *domains;\n        const vector<vector<vector<int>>> *placementDrilled;\n        const vector<vector<char>> *fieldCanCover;\n        const vector<int> *obsVals;\n        vector<int> order;\n        vector<int> curCov;\n        vector<int> remCan;\n        vector<int> assignment;\n        int solutions=0;\n        vector<int> solAssign;\n        chrono::steady_clock::time_point deadline;\n        bool timedOut=false;\n\n        void dfs(int idx) {\n            if (timedOut) return;\n            if (chrono::steady_clock::now() > deadline) { timedOut=true; return; }\n            if (solutions>=2) return;\n            int D = obsVals->size();\n            if (idx==(int)order.size()) {\n                for (int d=0; d<D; d++) {\n                    if (curCov[d]!=(*obsVals)[d]) return;\n                }\n                solutions++;\n                solAssign = assignment;\n                return;\n            }\n            int f = order[idx];\n            for (int d=0; d<D; d++) {\n                if ((*fieldCanCover)[f][d]) remCan[d]--;\n            }\n            const auto &dom = (*domains)[f];\n            for (int pi=0; pi<(int)dom.size(); pi++) {\n                int pidx = dom[pi];\n                bool ok=true;\n                for (int d: (*placementDrilled)[f][pi]) {\n                    curCov[d]++;\n                    if (curCov[d] > (*obsVals)[d]) { ok=false; }\n                }\n                if (ok) {\n                    for (int d=0; d<D; d++) {\n                        if (curCov[d] + remCan[d] < (*obsVals)[d]) { ok=false; break; }\n                    }\n                }\n                if (ok) {\n                    assignment[f]=pidx;\n                    dfs(idx+1);\n                }\n                for (int d: (*placementDrilled)[f][pi]) curCov[d]--;\n                if (solutions>=2 || timedOut) break;\n            }\n            for (int d=0; d<D; d++) {\n                if ((*fieldCanCover)[f][d]) remCan[d]++;\n            }\n        }\n    };\n\n    int solveComponent(const vector<int> &fields, const vector<int> &dIdxs,\n                      vector<int> &assignOut, int timeLimitMs) {\n        int F = fields.size();\n        int D = dIdxs.size();\n\n        vector<vector<int>> domains(F);\n        for (int i=0;i<F;i++) {\n            int f = fields[i];\n            for (int p=0;p<(int)placements[f].size();p++) if (alive[f][p]) domains[i].push_back(p);\n            if (domains[i].empty()) return 0;\n        }\n\n        if (D==0) {\n            for (int i=0;i<F;i++) {\n                if ((int)domains[i].size() != 1) return 2;\n            }\n            assignOut.resize(F);\n            for (int i=0;i<F;i++) assignOut[i] = domains[i][0];\n            return 1;\n        }\n\n        vector<int> drilledIndexByCell(N*N, -1);\n        for (int idx=0; idx<(int)drilledIds.size(); idx++) {\n            drilledIndexByCell[drilledIds[idx]] = idx;\n        }\n        vector<int> cellToLocal(drilledIds.size(), -1);\n        for (int i=0;i<D;i++) cellToLocal[dIdxs[i]] = i;\n\n        vector<vector<vector<int>>> placementDrilled(F);\n        vector<vector<char>> fieldCanCover(F, vector<char>(D, 0));\n        for (int i=0;i<F;i++) {\n            int f = fields[i];\n            int ds = domains[i].size();\n            placementDrilled[i].resize(ds);\n            for (int idx=0; idx<ds; idx++) {\n                int pidx = domains[i][idx];\n                for (int c: placements[f][pidx].cells) {\n                    int dg = drilledIndexByCell[c];\n                    if (dg<0) continue;\n                    int dl = cellToLocal[dg];\n                    if (dl>=0) {\n                        placementDrilled[i][idx].push_back(dl);\n                        fieldCanCover[i][dl]=1;\n                    }\n                }\n            }\n        }\n\n        vector<int> obsComp(D);\n        for (int i=0;i<D;i++) obsComp[i] = drilledVals[dIdxs[i]];\n\n        DFSState st;\n        st.domains = &domains;\n        st.placementDrilled = &placementDrilled;\n        st.fieldCanCover = &fieldCanCover;\n        st.obsVals = &obsComp;\n        st.order.resize(F);\n        iota(st.order.begin(), st.order.end(), 0);\n        sort(st.order.begin(), st.order.end(), [&](int a,int b){\n            return domains[a].size() < domains[b].size();\n        });\n        st.curCov.assign(D, 0);\n        st.remCan.assign(D, 0);\n        st.assignment.assign(F, -1);\n        for (int d=0; d<D; d++) {\n            int cnt=0;\n            for (int i=0;i<F;i++) if (fieldCanCover[i][d]) cnt++;\n            st.remCan[d]=cnt;\n        }\n        st.deadline = chrono::steady_clock::now() + chrono::milliseconds(timeLimitMs);\n        st.dfs(0);\n        if (st.timedOut) return 2;\n        if (st.solutions==1) {\n            assignOut.resize(F);\n            for (int i=0;i<F;i++) assignOut[i]=st.solAssign[i];\n            return 1;\n        }\n        if (st.solutions==0) return 0;\n        return 2;\n    }\n\n    int solveUnique(vector<int> &solution, int timeLimitMs) {\n        int D = drilledIds.size();\n        if (D==0) return 2;\n        int V = M + D;\n        vector<vector<int>> adj(V);\n        for (int f=0; f<M; f++) {\n            for (int di=0; di<D; di++) {\n                int cell = drilledIds[di];\n                if (cellCoverCount[f][cell] > 0) {\n                    adj[f].push_back(M+di);\n                    adj[M+di].push_back(f);\n                }\n            }\n        }\n        vector<char> vis(V,0);\n        vector<vector<int>> compsF, compsD;\n        for (int v=0; v<V; v++) if (!vis[v]) {\n            queue<int> q;\n            q.push(v); vis[v]=1;\n            vector<int> cf, cd;\n            while(!q.empty()) {\n                int u=q.front(); q.pop();\n                if (u < M) cf.push_back(u);\n                else cd.push_back(u-M);\n                for (int to: adj[u]) if (!vis[to]) {\n                    vis[to]=1; q.push(to);\n                }\n            }\n            compsF.push_back(cf);\n            compsD.push_back(cd);\n        }\n        solution.assign(M, -1);\n        int comps = compsF.size();\n        int timeLeft = timeLimitMs;\n        for (int idx=0; idx<comps; idx++) {\n            auto tstart = chrono::steady_clock::now();\n            int alloc = max(5, timeLeft / (comps - idx));\n            vector<int> assignComp;\n            int status = solveComponent(compsF[idx], compsD[idx], assignComp, alloc);\n            auto tused = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-tstart).count();\n            timeLeft -= min(timeLeft, (int)tused);\n            if (status==0) return 0;\n            if (status==2) return 2;\n            for (int i=0;i<(int)compsF[idx].size();i++) {\n                solution[compsF[idx][i]] = assignComp[i];\n            }\n        }\n        return 1;\n    }\n\n    void outputAnswer(const vector<int> &cells) {\n        cout << \"a \" << cells.size();\n        for (int id: cells) {\n            auto [i,j] = cellCoord(id);\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << \"\\n\" << flush;\n        int res;\n        if (!(cin >> res)) exit(0);\n    }\n\n    void trySearchAndAnswer(int extraTimeBudgetMs=0) {\n        int elapsed = (int)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n        int remain = 2950 - elapsed;\n        remain = max(remain, 0);\n        int budget = min(remain, 200 + extraTimeBudgetMs);\n        budget = max(20, budget);\n        if (searchTimeUsed + budget > searchTimeCap) {\n            budget = max(10, searchTimeCap - searchTimeUsed);\n        }\n        if (budget <= 0) return;\n        vector<int> solAssign;\n        int status = solveUnique(solAssign, budget);\n        searchTimeUsed += budget;\n        if (status==1) {\n            vector<char> oil(N*N,0);\n            for (int f=0; f<M; f++) {\n                int pidx = solAssign[f];\n                for (int c: placements[f][pidx].cells) oil[c]=1;\n            }\n            vector<int> ans;\n            for (int c=0; c<N*N; c++) if (oil[c]) ans.push_back(c);\n            outputAnswer(ans);\n            exit(0);\n        }\n    }\n\n    int selectBestCell() {\n        int best=-1;\n        double bestEntropy=-1.0;\n        int bestCov=-1;\n        for (int c=0; c<N*N; c++) if (obs[c]==-1) {\n            vector<double> dist(M+1, 0.0);\n            dist[0]=1.0;\n            int contributors=0;\n            for (int f=0; f<M; f++) {\n                if (domainSize[f]==0) continue;\n                int A = cellCoverCount[f][c];\n                if (A==0) continue;\n                double p = (double)A / (double)domainSize[f];\n                contributors++;\n                vector<double> ndist(contributors+1, 0.0);\n                for (int k=0;k<contributors;k++) {\n                    if (dist[k]==0.0) continue;\n                    ndist[k] += dist[k]*(1.0-p);\n                    ndist[k+1] += dist[k]*p;\n                }\n                dist.swap(ndist);\n            }\n            if (contributors==0) continue;\n            double H=0.0;\n            for (double p: dist) if (p>1e-12) H -= p*log(p);\n            if (H > bestEntropy + 1e-12 || (fabs(H-bestEntropy)<1e-12 && contributors>bestCov)) {\n                best=c; bestEntropy=H; bestCov=contributors;\n            }\n        }\n        return best;\n    }\n\n    void solve() {\n        startTime = chrono::steady_clock::now();\n        obs.assign(N*N, -1);\n        propagateConstraints();\n        int steps=0;\n        while (true) {\n            if (allDomainsSingleton()) {\n                vector<int> ans = computeUnionFromDomains();\n                outputAnswer(ans);\n                return;\n            }\n            int elapsed = (int)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n            if (elapsed > 2700) break;\n            trySearchAndAnswer();\n            int best = selectBestCell();\n            if (best==-1) break;\n            drillCell(best);\n            steps++;\n            propagateConstraints();\n            if (steps >= 2*N*N) break;\n        }\n        // Additional heuristic drills before full fallback\n        for (int extra=0; extra<10; extra++) {\n            trySearchAndAnswer();\n            int best = selectBestCell();\n            if (best==-1) break;\n            drillCell(best);\n            propagateConstraints();\n            if (allDomainsSingleton()) {\n                vector<int> ans = computeUnionFromDomains();\n                outputAnswer(ans);\n                return;\n            }\n            int elapsed = (int)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n            if (elapsed > 2950) break;\n        }\n        trySearchAndAnswer(200);\n        for (int c=0; c<N*N; c++) if (obs[c]==-1) {\n            drillCell(c);\n        }\n        vector<int> ans;\n        for (int c=0; c<N*N; c++) if (obs[c]>0) ans.push_back(c);\n        outputAnswer(ans);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M; double eps;\n    if (!(cin>>N>>M>>eps)) return 0;\n    Solver solver(N,M,eps);\n    solver.readInput();\n    solver.buildPlacements();\n    solver.solve();\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct PQItem {\n    int ben;\n    int idx;\n    bool operator<(const PQItem &o) const {\n        if (ben != o.ben) return ben < o.ben; // max-heap\n        return idx > o.idx;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int W, D, N;\n    if (!(cin >> W >> D >> N)) return 0; // W is always 1000\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++) cin >> a[d][k];\n    }\n\n    vector<int> prev_p; // previous boundary positions (size N-1)\n\n    for (int d = 0; d < D; d++) {\n        // sort requests descending with original indices\n        vector<pair<int, int>> reqs;\n        reqs.reserve(N);\n        for (int k = 0; k < N; k++) reqs.emplace_back(a[d][k], k);\n        sort(reqs.begin(), reqs.end(), [&](const auto &p1, const auto &p2) {\n            if (p1.first != p2.first) return p1.first > p2.first;\n            return p1.second < p2.second;\n        });\n\n        vector<int> r(N);\n        for (int i = 0; i < N; i++) r[i] = reqs[i].first;\n\n        vector<int> heights(N, 0);\n        if (N == 1) {\n            heights[0] = W;\n        } else {\n            vector<int> hmin(N);\n            int sum_min = 0;\n            for (int i = 0; i < N; i++) {\n                hmin[i] = (r[i] + W - 1) / W;\n                sum_min += hmin[i];\n            }\n\n            if (sum_min <= W) {\n                int slack = W - sum_min;\n                int m = N - 1;\n                vector<int> low(m);\n                int pref = 0;\n                for (int j = 0; j < m; j++) {\n                    pref += hmin[j];\n                    low[j] = pref; // minimal position of boundary j\n                }\n\n                vector<int> target(m, -1);\n                if (d == 0) {\n                    for (int j = 0; j < m; j++) {\n                        target[j] = (long long)(slack) * (j + 1) / N;\n                    }\n                } else {\n                    for (int j = 0; j < m; j++) {\n                        int t = prev_p[j] - low[j];\n                        if (0 <= t && t <= slack) target[j] = t;\n                        else target[j] = -1;\n                    }\n                }\n\n                // DP to find nondecreasing sequence x_j in [0, slack] maximizing matches to target\n                vector<vector<int>> dp(m, vector<int>(slack + 1, -1e9));\n                vector<vector<int>> pre(m, vector<int>(slack + 1, -1));\n                for (int v = 0; v <= slack; v++) {\n                    dp[0][v] = (target[0] != -1 && v == target[0]) ? 1 : 0;\n                }\n                for (int j = 1; j < m; j++) {\n                    int best = -1e9;\n                    int bestv = 0;\n                    for (int v = 0; v <= slack; v++) {\n                        if (dp[j - 1][v] > best) {\n                            best = dp[j - 1][v];\n                            bestv = v;\n                        }\n                        int add = (target[j] != -1 && v == target[j]) ? 1 : 0;\n                        dp[j][v] = best + add;\n                        pre[j][v] = bestv;\n                    }\n                }\n                int best = -1e9, bestv = 0;\n                for (int v = 0; v <= slack; v++) {\n                    if (dp[m - 1][v] > best) {\n                        best = dp[m - 1][v];\n                        bestv = v;\n                    }\n                }\n                vector<int> x(m);\n                int curv = bestv;\n                for (int j = m - 1; j >= 0; j--) {\n                    x[j] = curv;\n                    curv = pre[j][curv];\n                    if (curv < 0) curv = 0;\n                }\n\n                vector<int> delta(N, 0);\n                delta[0] = x[0];\n                for (int i = 1; i < m; i++) {\n                    delta[i] = x[i] - x[i - 1];\n                }\n                delta[N - 1] = slack - x[m - 1];\n                for (int i = 0; i < N; i++) {\n                    heights[i] = hmin[i] + delta[i];\n                }\n            } else {\n                // fallback: greedy allocation of extra rows to minimize deficiency for this day\n                heights.assign(N, 1);\n                vector<int> caps(N, W); // current capacity per stripe\n                int rem = W - N;\n                priority_queue<PQItem> pq;\n                for (int i = 0; i < N; i++) {\n                    int deficiency = max(0, r[i] - caps[i]);\n                    int ben = min(W, deficiency);\n                    pq.push({ben, i});\n                }\n                while (rem > 0) {\n                    auto it = pq.top();\n                    pq.pop();\n                    int i = it.idx;\n                    heights[i] += 1;\n                    caps[i] += W;\n                    rem--;\n                    int deficiency = max(0, r[i] - caps[i]);\n                    int ben = min(W, deficiency);\n                    pq.push({ben, i});\n                }\n                // ensure sum == W\n                int s = 0;\n                for (int h : heights) s += h;\n                if (s != W) heights[N - 1] += (W - s);\n            }\n        }\n\n        // build stripes coordinates and boundaries\n        vector<array<int, 4>> stripes(N);\n        vector<int> cur_p;\n        cur_p.reserve(max(0, N - 1));\n        int y = 0;\n        for (int i = 0; i < N; i++) {\n            int h = heights[i];\n            stripes[i] = {y, 0, y + h, W};\n            y += h;\n            if (i < N - 1) cur_p.push_back(y);\n        }\n        // adjust last stripe if rounding error\n        if (y != W && N > 0) {\n            stripes[N - 1][2] += (W - y);\n            if (!cur_p.empty()) cur_p.back() = W;\n        }\n\n        // map to original indices\n        vector<array<int, 4>> out(N);\n        for (int i = 0; i < N; i++) {\n            int idx = reqs[i].second;\n            out[idx] = stripes[i];\n        }\n\n        for (int k = 0; k < N; k++) {\n            auto &rct = out[k];\n            cout << rct[0] << \" \" << rct[1] << \" \" << rct[2] << \" \" << rct[3] << \"\\n\";\n        }\n\n        prev_p = cur_p; // update boundaries for next day\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconst ll MOD = 998244353LL;\nconst double TIME_LIMIT = 1.95;\n\nstruct OpInfo {\n    int m, p, q;\n    int idx[9];\n    int inc[9];\n};\n\nuint64_t rng_state;\ninline uint64_t rng64() {\n    rng_state ^= rng_state << 7;\n    rng_state ^= rng_state >> 9;\n    return rng_state;\n}\ninline int rand_int(int n) { return int(rng64() % n); }\ninline double rand_double() { return (rng64() >> 11) * (1.0 / 9007199254740992.0); }\n\n// delta if we add op\ninline ll delta_add(const OpInfo& op, const vector<ll>& modv) {\n    ll delta = 0;\n    ll nv;\n    nv = modv[op.idx[0]] + op.inc[0]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[0]];\n    nv = modv[op.idx[1]] + op.inc[1]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[1]];\n    nv = modv[op.idx[2]] + op.inc[2]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[2]];\n    nv = modv[op.idx[3]] + op.inc[3]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[3]];\n    nv = modv[op.idx[4]] + op.inc[4]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[4]];\n    nv = modv[op.idx[5]] + op.inc[5]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[5]];\n    nv = modv[op.idx[6]] + op.inc[6]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[6]];\n    nv = modv[op.idx[7]] + op.inc[7]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[7]];\n    nv = modv[op.idx[8]] + op.inc[8]; if (nv >= MOD) nv -= MOD; delta += nv - modv[op.idx[8]];\n    return delta;\n}\n// delta if we remove op\ninline ll delta_remove(const OpInfo& op, const vector<ll>& modv) {\n    ll delta = 0;\n    ll nv;\n    nv = modv[op.idx[0]] - op.inc[0]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[0]];\n    nv = modv[op.idx[1]] - op.inc[1]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[1]];\n    nv = modv[op.idx[2]] - op.inc[2]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[2]];\n    nv = modv[op.idx[3]] - op.inc[3]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[3]];\n    nv = modv[op.idx[4]] - op.inc[4]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[4]];\n    nv = modv[op.idx[5]] - op.inc[5]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[5]];\n    nv = modv[op.idx[6]] - op.inc[6]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[6]];\n    nv = modv[op.idx[7]] - op.inc[7]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[7]];\n    nv = modv[op.idx[8]] - op.inc[8]; if (nv < 0) nv += MOD; delta += nv - modv[op.idx[8]];\n    return delta;\n}\n\n// greedy addition of positive delta ops\nvoid greedy_fill(const vector<OpInfo>& opsInfo, int totalOps, int K,\n                 vector<ll>& modv, ll& score, vector<int>& opsVec, int maxAdd) {\n    int canAdd = K - (int)opsVec.size();\n    if (maxAdd > canAdd) maxAdd = canAdd;\n    for (int step = 0; step < maxAdd; step++) {\n        ll bestDelta = 0;\n        int bestId = -1;\n        for (int opId = 0; opId < totalOps; opId++) {\n            ll delta = delta_add(opsInfo[opId], modv);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestId = opId;\n            }\n        }\n        if (bestDelta > 0 && bestId != -1) {\n            const auto& op = opsInfo[bestId];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] + op.inc[t];\n                if (nv >= MOD) nv -= MOD;\n                score += nv - modv[pos];\n                modv[pos] = nv;\n            }\n            opsVec.push_back(bestId);\n        } else break;\n    }\n}\n\n// hill climb with addition/removal/replacement until no improvement or time limit reached\nvoid hill_climb_full(const vector<OpInfo>& opsInfo, int totalOps, int K,\n                     vector<ll>& modv, ll& score, vector<int>& opsVec,\n                     chrono::steady_clock::time_point start_time) {\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        int L = (int)opsVec.size();\n\n        if (L < K) {\n            ll bestDeltaAdd = 0;\n            int bestIdAdd = -1;\n            for (int opId = 0; opId < totalOps; opId++) {\n                ll delta = delta_add(opsInfo[opId], modv);\n                if (delta > bestDeltaAdd) {\n                    bestDeltaAdd = delta;\n                    bestIdAdd = opId;\n                }\n            }\n            if (bestDeltaAdd > 0 && bestIdAdd != -1) {\n                const auto& op = opsInfo[bestIdAdd];\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modv[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    score += nv - modv[pos];\n                    modv[pos] = nv;\n                }\n                opsVec.push_back(bestIdAdd);\n                improved = true;\n                continue;\n            }\n        }\n\n        ll bestDelta = 0;\n        int bestIdx = -1;\n        int bestNewOp = -2; // -1 removal, >=0 replacement\n\n        // Removal\n        for (int idx = 0; idx < L; idx++) {\n            ll delta = delta_remove(opsInfo[opsVec[idx]], modv);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestIdx = idx;\n                bestNewOp = -1;\n            }\n        }\n\n        // Replacement\n        for (int idx = 0; idx < L; idx++) {\n            int oldId = opsVec[idx];\n            const auto& oldOp = opsInfo[oldId];\n            for (int newId = 0; newId < totalOps; newId++) {\n                if (newId == oldId) continue;\n                const auto& newOp = opsInfo[newId];\n                int idxs[18];\n                ll dadd[18];\n                int cnt = 0;\n                auto add_d = [&](int pos, ll d) {\n                    for (int t = 0; t < cnt; t++) {\n                        if (idxs[t] == pos) { dadd[t] += d; return; }\n                    }\n                    idxs[cnt] = pos;\n                    dadd[cnt] = d;\n                    cnt++;\n                };\n                for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n                for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n                ll delta = 0;\n                for (int t = 0; t < cnt; t++) {\n                    int pos = idxs[t];\n                    ll nv = modv[pos] + dadd[t];\n                    if (nv >= MOD) nv -= MOD;\n                    else if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                }\n                if (delta > bestDelta) {\n                    bestDelta = delta;\n                    bestIdx = idx;\n                    bestNewOp = newId;\n                }\n            }\n        }\n\n        if (bestDelta > 0 && bestIdx != -1) {\n            if (bestNewOp == -1) {\n                const auto& op = opsInfo[opsVec[bestIdx]];\n                ll newVals[9];\n                ll delta = 0;\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modv[pos] - op.inc[t];\n                    if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                    newVals[t] = nv;\n                }\n                score += delta;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newVals[t];\n                opsVec[bestIdx] = opsVec.back();\n                opsVec.pop_back();\n                improved = true;\n            } else {\n                const auto& oldOp = opsInfo[opsVec[bestIdx]];\n                const auto& newOp = opsInfo[bestNewOp];\n                int idxs[18];\n                ll dadd[18];\n                int cnt = 0;\n                auto add_d = [&](int pos, ll d) {\n                    for (int t = 0; t < cnt; t++) {\n                        if (idxs[t] == pos) { dadd[t] += d; return; }\n                    }\n                    idxs[cnt] = pos;\n                    dadd[cnt] = d;\n                    cnt++;\n                };\n                for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n                for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n                ll delta = 0;\n                ll newVals[18];\n                for (int t = 0; t < cnt; t++) {\n                    int pos = idxs[t];\n                    ll nv = modv[pos] + dadd[t];\n                    if (nv >= MOD) nv -= MOD;\n                    else if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                    newVals[t] = nv;\n                }\n                score += delta;\n                for (int t = 0; t < cnt; t++) modv[idxs[t]] = newVals[t];\n                opsVec[bestIdx] = bestNewOp;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\n\n// lighter hill climb: additions, removals, sampled replacements\nvoid hill_climb_light(const vector<OpInfo>& opsInfo, int totalOps, int K,\n                      vector<ll>& modv, ll& score, vector<int>& opsVec,\n                      chrono::steady_clock::time_point start_time) {\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n        bool improved = false;\n        int L = (int)opsVec.size();\n\n        if (L < K) {\n            ll bestDelta = 0;\n            int bestId = -1;\n            for (int opId = 0; opId < totalOps; opId++) {\n                ll delta = delta_add(opsInfo[opId], modv);\n                if (delta > bestDelta) {\n                    bestDelta = delta;\n                    bestId = opId;\n                }\n            }\n            if (bestDelta > 0 && bestId != -1) {\n                const auto& op = opsInfo[bestId];\n                for (int t = 0; t < 9; t++) {\n                    int pos = op.idx[t];\n                    ll nv = modv[pos] + op.inc[t];\n                    if (nv >= MOD) nv -= MOD;\n                    score += nv - modv[pos];\n                    modv[pos] = nv;\n                }\n                opsVec.push_back(bestId);\n                improved = true;\n                continue;\n            }\n        }\n\n        // removal\n        ll bestDelta = 0;\n        int bestIdx = -1;\n        for (int idx = 0; idx < L; idx++) {\n            ll delta = delta_remove(opsInfo[opsVec[idx]], modv);\n            if (delta > bestDelta) {\n                bestDelta = delta;\n                bestIdx = idx;\n            }\n        }\n        if (bestDelta > 0 && bestIdx != -1) {\n            const auto& op = opsInfo[opsVec[bestIdx]];\n            ll newVals[9];\n            ll delta = 0;\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] - op.inc[t];\n                if (nv < 0) nv += MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            score += delta;\n            for (int t = 0; t < 9; t++) modv[op.idx[t]] = newVals[t];\n            opsVec[bestIdx] = opsVec.back();\n            opsVec.pop_back();\n            improved = true;\n            continue;\n        }\n\n        int bestNew = -1;\n        bestDelta = 0;\n        bestIdx = -1;\n        for (int idx = 0; idx < L; idx++) {\n            int oldId = opsVec[idx];\n            const auto& oldOp = opsInfo[oldId];\n            int samples = 100;\n            for (int s = 0; s < samples; s++) {\n                int newId = rand_int(totalOps);\n                if (newId == oldId) continue;\n                const auto& newOp = opsInfo[newId];\n                int idxs[18];\n                ll dadd[18];\n                int cnt = 0;\n                auto add_d = [&](int pos, ll d) {\n                    for (int t = 0; t < cnt; t++) {\n                        if (idxs[t] == pos) { dadd[t] += d; return; }\n                    }\n                    idxs[cnt] = pos;\n                    dadd[cnt] = d;\n                    cnt++;\n                };\n                for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n                for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n                ll delta = 0;\n                for (int t = 0; t < cnt; t++) {\n                    int pos = idxs[t];\n                    ll nv = modv[pos] + dadd[t];\n                    if (nv >= MOD) nv -= MOD;\n                    else if (nv < 0) nv += MOD;\n                    delta += nv - modv[pos];\n                }\n                if (delta > bestDelta) {\n                    bestDelta = delta;\n                    bestIdx = idx;\n                    bestNew = newId;\n                }\n            }\n        }\n        if (bestDelta > 0 && bestIdx != -1) {\n            const auto& oldOp = opsInfo[opsVec[bestIdx]];\n            const auto& newOp = opsInfo[bestNew];\n            int idxs[18];\n            ll dadd[18];\n            int cnt = 0;\n            auto add_d = [&](int pos, ll d) {\n                for (int t = 0; t < cnt; t++) {\n                    if (idxs[t] == pos) { dadd[t] += d; return; }\n                }\n                idxs[cnt] = pos;\n                dadd[cnt] = d;\n                cnt++;\n            };\n            for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n            for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n            ll delta = 0;\n            ll newVals[18];\n            for (int t = 0; t < cnt; t++) {\n                int pos = idxs[t];\n                ll nv = modv[pos] + dadd[t];\n                if (nv >= MOD) nv -= MOD;\n                else if (nv < 0) nv += MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            score += delta;\n            for (int t = 0; t < cnt; t++) modv[idxs[t]] = newVals[t];\n            opsVec[bestIdx] = bestNew;\n            improved = true;\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    rng_state = chrono::high_resolution_clock::now().time_since_epoch().count();\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n    vector<ll> base(N * N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            ll v; cin >> v;\n            base[i * N + j] = v;\n        }\n    }\n    vector<vector<vector<int>>> s(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int v; cin >> v;\n                s[m][i][j] = v;\n            }\n        }\n    }\n\n    // precompute operations\n    vector<OpInfo> opsInfo;\n    opsInfo.reserve(M * (N - 2) * (N - 2));\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                OpInfo op;\n                op.m = m; op.p = p; op.q = q;\n                int t = 0;\n                for (int di = 0; di < 3; di++) {\n                    for (int dj = 0; dj < 3; dj++) {\n                        op.idx[t] = (p + di) * N + (q + dj);\n                        op.inc[t] = s[m][di][dj];\n                        t++;\n                    }\n                }\n                opsInfo.push_back(op);\n            }\n        }\n    }\n    int totalOps = (int)opsInfo.size(); // 980\n\n    auto start_time = chrono::steady_clock::now();\n\n    // initial board mod values\n    vector<ll> modv(N * N);\n    ll score = 0;\n    for (int i = 0; i < N * N; i++) {\n        modv[i] = base[i] % MOD;\n        score += modv[i];\n    }\n\n    vector<int> curOps;\n    curOps.reserve(K);\n\n    // initial greedy and hill climb\n    greedy_fill(opsInfo, totalOps, K, modv, score, curOps, K);\n    hill_climb_full(opsInfo, totalOps, K, modv, score, curOps, start_time);\n\n    vector<int> bestOps = curOps;\n    ll bestScore = score;\n    vector<ll> bestModv = modv;\n\n    // short simulated annealing\n    const double SA_LIMIT = 0.5;\n    const double T0 = 1e8;\n    const double T1 = 1e5;\n    double temp = T0;\n    int iter = 0;\n    const int CHECK_MASK = 1023;\n\n    while (true) {\n        if ((iter & CHECK_MASK) == 0) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            if (elapsed > SA_LIMIT) break;\n            double progress = elapsed / SA_LIMIT;\n            temp = T0 + (T1 - T0) * progress;\n        }\n        iter++;\n        int L = (int)curOps.size();\n        int moveType;\n        uint64_t rstate = rng64();\n        if (L == 0) moveType = 1;\n        else if (L == K) moveType = (rstate & 7) ? 0 : 2;\n        else {\n            int v = (int)(rstate % 100);\n            if (v < 65) moveType = 0;\n            else if (v < 85) moveType = 1;\n            else moveType = 2;\n        }\n\n        if (moveType == 0) {\n            int idx = (int)(rstate % L);\n            int oldId = curOps[idx];\n            int newId = rand_int(totalOps);\n            if (newId == oldId) continue;\n            const auto& oldOp = opsInfo[oldId];\n            const auto& newOp = opsInfo[newId];\n            int idxs[18];\n            ll dadd[18];\n            int cnt = 0;\n            auto add_d = [&](int pos, ll d) {\n                for (int t = 0; t < cnt; t++) {\n                    if (idxs[t] == pos) { dadd[t] += d; return; }\n                }\n                idxs[cnt] = pos;\n                dadd[cnt] = d;\n                cnt++;\n            };\n            for (int t = 0; t < 9; t++) add_d(oldOp.idx[t], - (ll)oldOp.inc[t]);\n            for (int t = 0; t < 9; t++) add_d(newOp.idx[t], (ll)newOp.inc[t]);\n            ll delta = 0;\n            ll newVals[18];\n            for (int t = 0; t < cnt; t++) {\n                int pos = idxs[t];\n                ll nv = modv[pos] + dadd[t];\n                if (nv >= MOD) nv -= MOD;\n                else if (nv < 0) nv += MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp((double)delta / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += delta;\n                for (int t = 0; t < cnt; t++) modv[idxs[t]] = newVals[t];\n                curOps[idx] = newId;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                    bestModv = modv;\n                }\n            }\n        } else if (moveType == 1) {\n            if (L >= K) continue;\n            int newId = (int)(rstate % totalOps);\n            const auto& op = opsInfo[newId];\n            ll delta = 0;\n            ll newVals[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] + op.inc[t];\n                if (nv >= MOD) nv -= MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp((double)delta / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += delta;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newVals[t];\n                curOps.push_back(newId);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                    bestModv = modv;\n                }\n            }\n        } else {\n            int idx = (int)(rstate % L);\n            int oldId = curOps[idx];\n            const auto& op = opsInfo[oldId];\n            ll delta = 0;\n            ll newVals[9];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = modv[pos] - op.inc[t];\n                if (nv < 0) nv += MOD;\n                delta += nv - modv[pos];\n                newVals[t] = nv;\n            }\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double prob = exp((double)delta / temp);\n                if (prob > rand_double()) accept = true;\n            }\n            if (accept) {\n                score += delta;\n                for (int t = 0; t < 9; t++) modv[op.idx[t]] = newVals[t];\n                curOps[idx] = curOps.back();\n                curOps.pop_back();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestOps = curOps;\n                    bestModv = modv;\n                }\n            }\n        }\n    }\n\n    // reconstruct best state\n    {\n        vector<ll> tmpMod(N * N);\n        ll tmpScore = 0;\n        for (int i = 0; i < N * N; i++) {\n            tmpMod[i] = base[i] % MOD;\n            tmpScore += tmpMod[i];\n        }\n        for (int opId : bestOps) {\n            const auto& op = opsInfo[opId];\n            for (int t = 0; t < 9; t++) {\n                int pos = op.idx[t];\n                ll nv = tmpMod[pos] + op.inc[t];\n                if (nv >= MOD) nv -= MOD;\n                tmpScore += nv - tmpMod[pos];\n                tmpMod[pos] = nv;\n            }\n        }\n        bestModv.swap(tmpMod);\n        bestScore = tmpScore;\n    }\n    greedy_fill(opsInfo, totalOps, K, bestModv, bestScore, bestOps, K - (int)bestOps.size());\n    hill_climb_full(opsInfo, totalOps, K, bestModv, bestScore, bestOps, start_time);\n\n    // ruin & recreate loop\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > TIME_LIMIT) break;\n\n        vector<ll> curModv = bestModv;\n        ll curScore = bestScore;\n        vector<int> curOps = bestOps;\n\n        int removeCnt = 3 + rand_int(6); // 3..8 removals\n        for (int t = 0; t < removeCnt && !curOps.empty(); t++) {\n            int idx = rand_int((int)curOps.size());\n            const auto& op = opsInfo[curOps[idx]];\n            for (int k = 0; k < 9; k++) {\n                int pos = op.idx[k];\n                ll nv = curModv[pos] - op.inc[k];\n                if (nv < 0) nv += MOD;\n                curScore += nv - curModv[pos];\n                curModv[pos] = nv;\n            }\n            curOps[idx] = curOps.back();\n            curOps.pop_back();\n        }\n\n        greedy_fill(opsInfo, totalOps, K, curModv, curScore, curOps, K - (int)curOps.size());\n        hill_climb_light(opsInfo, totalOps, K, curModv, curScore, curOps, start_time);\n\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n            bestModv = curModv;\n        }\n    }\n\n    cout << bestOps.size() << \"\\n\";\n    for (int opId : bestOps) {\n        const auto& op = opsInfo[opId];\n        cout << op.m << ' ' << op.p << ' ' << op.q << '\\n';\n    }\n\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;\n    int hold;   // -1 if empty\n    bool alive;\n};\n\nstruct Candidate {\n    vector<string> ops;\n    long long M0, M1, M2, M3;\n    long long score() const {\n        return M0 + 100LL * M1 + 10000LL * M2 + 1000000LL * M3;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n\n    const int base = N + 1; // 6\n    const int POS = N + 1;  // 6 (0..4 rows, 5 = undefined/start)\n    int totalStates = 1;\n    for (int i = 0; i < N; i++) totalStates *= base; // 6^5 = 7776\n\n    vector<int> powBase(N);\n    powBase[N - 1] = 1;\n    for (int k = N - 2; k >= 0; k--) powBase[k] = powBase[k + 1] * base;\n\n    // decode all states and group by sum\n    vector<array<int,5>> pvec(totalStates);\n    vector<int> sumPtr(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        int tmp = code, sum = 0;\n        array<int,5> p{};\n        for (int i = N - 1; i >= 0; i--) {\n            p[i] = tmp % base;\n            tmp /= base;\n            sum += p[i];\n        }\n        pvec[code] = p;\n        sumPtr[code] = sum;\n    }\n    vector<vector<int>> codesBySum(N * N + 1);\n    for (int code = 0; code < totalStates; code++) {\n        codesBySum[sumPtr[code]].push_back(code);\n    }\n\n    vector<vector<int>> destRow(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) destRow[i][j] = A[i][j] / N;\n\n    vector<array<int,5>> invAddTable(totalStates);\n    for (int code = 0; code < totalStates; code++) {\n        const auto &p = pvec[code];\n        for (int s = 0; s < N; s++) {\n            if (p[s] >= N) { invAddTable[code][s] = 0; continue; }\n            int cid = A[s][p[s]];\n            int dr = cid / N;\n            int cnt = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < p[i]; j++) {\n                    int cid2 = A[i][j];\n                    if (cid2 / N == dr && cid2 > cid) cnt++;\n                }\n            }\n            invAddTable[code][s] = cnt;\n        }\n    }\n\n    auto plan_dp = [&](int weight) -> Candidate {\n        const long long INF = (1LL << 60);\n        int stateSize = totalStates * POS;\n        vector<long long> dp(stateSize, INF);\n        vector<int> parent(stateSize, -1);\n        vector<int> parentSrc(stateSize, -1);\n\n        int startIdx = 0 * POS + (POS - 1); // code=0, pos=start\n        dp[startIdx] = 0;\n\n        for (int total = 0; total <= N * N; total++) {\n            for (int code : codesBySum[total]) {\n                const auto &p = pvec[code];\n                for (int pos = 0; pos < POS; pos++) {\n                    int idx = code * POS + pos;\n                    long long curCost = dp[idx];\n                    if (curCost == INF) continue;\n                    for (int s = 0; s < N; s++) {\n                        if (p[s] >= N) continue;\n                        int dr = destRow[s][p[s]];\n                        int dist1 = (pos == POS - 1) ? abs(0 - s) : 4 + abs(pos - s);\n                        int dist2 = 4 + abs(s - dr);\n                        int moveCost = dist1 + dist2 + 2; // pick+drop\n                        int invAdd = invAddTable[code][s];\n                        long long newCost = curCost + moveCost + 1LL * weight * invAdd;\n                        int nextCode = code + powBase[s];\n                        int nextPos = dr;\n                        int nextIdx = nextCode * POS + nextPos;\n                        if (newCost < dp[nextIdx]) {\n                            dp[nextIdx] = newCost;\n                            parent[nextIdx] = idx;\n                            parentSrc[nextIdx] = s;\n                        }\n                    }\n                }\n            }\n        }\n\n        int fullCode = 0;\n        for (int i = 0; i < N; i++) fullCode = fullCode * base + N;\n        int bestIdx = fullCode * POS;\n        long long bestCost = dp[bestIdx];\n        for (int pos = 1; pos < POS; pos++) {\n            int idx = fullCode * POS + pos;\n            if (dp[idx] < bestCost) { bestCost = dp[idx]; bestIdx = idx; }\n        }\n\n        // reconstruct sequence of sources\n        vector<int> seqSources;\n        int curIdx = bestIdx;\n        while (curIdx != startIdx) {\n            int s = parentSrc[curIdx];\n            seqSources.push_back(s);\n            curIdx = parent[curIdx];\n        }\n        reverse(seqSources.begin(), seqSources.end());\n\n        vector<int> ptr(N, 0);\n        vector<pair<int,int>> tasks;\n        tasks.reserve(N * N);\n        for (int s : seqSources) {\n            tasks.emplace_back(s, A[s][ptr[s]]);\n            ptr[s]++;\n        }\n\n        // simulation\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        int dispatched = 0, task_idx = 0, turn = 0;\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        const int TURN_LIMIT = 10000;\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) { blocked = true; break; }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            Crane &lc = cranes[0];\n            char a0 = '.';\n            if (lc.hold == -1) {\n                if (task_idx < (int)tasks.size()) {\n                    int sr = tasks[task_idx].first;\n                    if (lc.r < sr) a0 = 'D';\n                    else if (lc.r > sr) a0 = 'U';\n                    else if (lc.c > 0) a0 = 'L';\n                    else {\n                        if (grid[lc.r][lc.c] != -1) a0 = 'P';\n                        else a0 = '.';\n                    }\n                } else a0 = '.';\n            } else {\n                int destR = lc.hold / N;\n                if (lc.c < N - 1) a0 = 'R';\n                else if (lc.r < destR) a0 = 'D';\n                else if (lc.r > destR) a0 = 'U';\n                else {\n                    if (grid[lc.r][lc.c] == -1) a0 = 'Q';\n                    else a0 = '.';\n                }\n            }\n            act[0] = a0;\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            vector<pair<int,int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') { cranes[i].alive = false; continue; }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) { cranes[i].hold = grid[r][c]; grid[r][c] = -1; }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                        if (i == 0) task_idx++;\n                    }\n                }\n            }\n\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn, M1 = 0, M2 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                if (seq[j] / N != i) M2++;\n                for (int k = j + 1; k < len; k++) if (seq[j] > seq[k]) M1++;\n            }\n        }\n        long long M3 = N * N - dispatched;\n        return Candidate{ops, M0, M1, M2, M3};\n    };\n\n    auto plan_buffer = [&]() -> Candidate {\n        vector<int> id2row(N * N);\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) id2row[A[i][j]] = i;\n\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<Crane> cranes(N);\n        for (int i = 0; i < N; i++) cranes[i] = {i, 0, -1, true};\n        vector<int> idxSpawn(N, 0);\n        vector<string> ops(N);\n        vector<vector<int>> dispatchedList(N);\n        vector<bool> dispatchedId(N * N, false);\n        vector<int> nextNeeded(N);\n        for (int i = 0; i < N; i++) nextNeeded[i] = i * N;\n\n        int dispatched = 0, turn = 0;\n        const int TURN_LIMIT = 10000;\n\n        auto chooseBuffer = [&](const Crane &lc, int cid) -> pair<int,int> {\n            int dr = cid / N;\n            vector<int> cols = {3, 2, 1};\n            for (int c : cols) if (grid[dr][c] == -1) return {dr, c};\n            for (int c : cols) for (int r = 0; r < N; r++) if (grid[r][c] == -1) return {r, c};\n            for (int r = 0; r < N; r++) for (int c = 0; c < N - 1; c++) if (grid[r][c] == -1) return {r, c};\n            return {lc.r, lc.c};\n        };\n\n        auto manhattan = [&](int r1, int c1, int r2, int c2) {\n            return abs(r1 - r2) + abs(c1 - c2);\n        };\n\n        while (dispatched < N * N && turn < TURN_LIMIT) {\n            // spawn\n            for (int i = 0; i < N; i++) {\n                if (idxSpawn[i] >= N) continue;\n                if (grid[i][0] != -1) continue;\n                bool blocked = false;\n                for (int k = 0; k < N; k++) {\n                    if (!cranes[k].alive) continue;\n                    if (cranes[k].hold != -1 && cranes[k].r == i && cranes[k].c == 0) { blocked = true; break; }\n                }\n                if (blocked) continue;\n                grid[i][0] = A[i][idxSpawn[i]];\n                idxSpawn[i]++;\n            }\n\n            vector<char> act(N, '.');\n            for (int i = 1; i < N; i++) act[i] = (turn == 0 ? 'B' : '.');\n\n            Crane &lc = cranes[0];\n            // find ready containers\n            vector<pair<int,int>> readyPos;\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int id = grid[r][c];\n                    if (id == -1) continue;\n                    int dr = id / N;\n                    if (nextNeeded[dr] < (dr + 1) * N && id == nextNeeded[dr]) {\n                        readyPos.emplace_back(r, c);\n                    }\n                }\n            }\n\n            char a0 = '.';\n            if (lc.hold != -1) {\n                int cid = lc.hold;\n                int dr = cid / N;\n                bool ready = (nextNeeded[dr] < (dr + 1) * N && cid == nextNeeded[dr]);\n                if (ready) {\n                    int tr = dr, tc = N - 1;\n                    if (lc.r == tr && lc.c == tc) {\n                        if (grid[tr][tc] == -1) a0 = 'Q';\n                        else a0 = '.';\n                    } else {\n                        if (lc.r < tr) a0 = 'D';\n                        else if (lc.r > tr) a0 = 'U';\n                        else if (lc.c < tc) a0 = 'R';\n                        else if (lc.c > tc) a0 = 'L';\n                    }\n                } else {\n                    auto buf = chooseBuffer(lc, cid);\n                    int tr = buf.first, tc = buf.second;\n                    if (lc.r == tr && lc.c == tc) {\n                        if (grid[tr][tc] == -1) a0 = 'Q';\n                        else a0 = '.';\n                    } else {\n                        if (lc.r < tr) a0 = 'D';\n                        else if (lc.r > tr) a0 = 'U';\n                        else if (lc.c < tc) a0 = 'R';\n                        else if (lc.c > tc) a0 = 'L';\n                    }\n                }\n            } else {\n                if (!readyPos.empty()) {\n                    int bestd = 1e9, br = -1, bc = -1;\n                    for (auto [r, c] : readyPos) {\n                        int d = manhattan(lc.r, lc.c, r, c);\n                        if (d < bestd) { bestd = d; br = r; bc = c; }\n                    }\n                    if (lc.r == br && lc.c == bc) a0 = 'P';\n                    else {\n                        if (lc.r < br) a0 = 'D';\n                        else if (lc.r > br) a0 = 'U';\n                        else if (lc.c < bc) a0 = 'R';\n                        else if (lc.c > bc) a0 = 'L';\n                    }\n                } else {\n                    // approach nearest receiving gate with container\n                    int bestd = 1e9, br = -1;\n                    for (int r = 0; r < N; r++) {\n                        if (grid[r][0] != -1) {\n                            int d = manhattan(lc.r, lc.c, r, 0);\n                            if (d < bestd) { bestd = d; br = r; }\n                        }\n                    }\n                    if (br == -1) a0 = '.';\n                    else {\n                        int tr = br, tc = 0;\n                        if (lc.r == tr && lc.c == tc) a0 = 'P';\n                        else {\n                            if (lc.r < tr) a0 = 'D';\n                            else if (lc.r > tr) a0 = 'U';\n                            else if (lc.c < tc) a0 = 'R';\n                            else if (lc.c > tc) a0 = 'L';\n                        }\n                    }\n                }\n            }\n\n            act[0] = a0;\n            for (int i = 0; i < N; i++) ops[i].push_back(act[i]);\n\n            vector<pair<int,int>> newpos(N);\n            for (int i = 0; i < N; i++) newpos[i] = {cranes[i].r, cranes[i].c};\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'U') newpos[i].first--;\n                else if (ac == 'D') newpos[i].first++;\n                else if (ac == 'L') newpos[i].second--;\n                else if (ac == 'R') newpos[i].second++;\n            }\n\n            for (int i = 0; i < N; i++) {\n                if (!cranes[i].alive) continue;\n                char ac = act[i];\n                if (ac == 'B') { cranes[i].alive = false; continue; }\n                if (ac == 'U' || ac == 'D' || ac == 'L' || ac == 'R') {\n                    cranes[i].r = newpos[i].first;\n                    cranes[i].c = newpos[i].second;\n                } else if (ac == 'P') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold == -1 && grid[r][c] != -1) { cranes[i].hold = grid[r][c]; grid[r][c] = -1; }\n                } else if (ac == 'Q') {\n                    int r = cranes[i].r, c = cranes[i].c;\n                    if (cranes[i].hold != -1 && grid[r][c] == -1) {\n                        grid[r][c] = cranes[i].hold;\n                        cranes[i].hold = -1;\n                    }\n                }\n            }\n\n            // dispatch\n            for (int i = 0; i < N; i++) {\n                if (grid[i][N - 1] != -1) {\n                    int id = grid[i][N - 1];\n                    dispatchedId[id] = true;\n                    dispatchedList[i].push_back(id);\n                    grid[i][N - 1] = -1;\n                    dispatched++;\n                    while (nextNeeded[i] < (i + 1) * N && dispatchedId[nextNeeded[i]]) nextNeeded[i]++;\n                }\n            }\n            turn++;\n        }\n\n        long long M0 = turn;\n        long long M1 = 0, M2 = 0;\n        for (int i = 0; i < N; i++) {\n            const auto &seq = dispatchedList[i];\n            int len = seq.size();\n            for (int j = 0; j < len; j++) {\n                if (seq[j] / N != i) M2++;\n                for (int k = j + 1; k < len; k++) if (seq[j] > seq[k]) M1++;\n            }\n        }\n        long long M3 = N * N - dispatched;\n        return Candidate{ops, M0, M1, M2, M3};\n    };\n\n    vector<int> weights = {80, 120, 160, 200};\n    Candidate best;\n    best.M0 = best.M1 = best.M2 = best.M3 = (1LL << 60);\n    bool init = false;\n    for (int w : weights) {\n        Candidate cand = plan_dp(w);\n        if (!init || cand.score() < best.score()) { best = cand; init = true; }\n    }\n    Candidate candBuf = plan_buffer();\n    if (!init || candBuf.score() < best.score()) { best = candBuf; init = true; }\n\n    for (int i = 0; i < N; i++) cout << best.ops[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing pii = pair<int,int>;\n\nstruct Plan {\n    vector<string> ops;\n    ll cost;\n    bool valid;\n};\n\n// ----- Path generators -----\nvector<pii> build_path_down_serp_rows(int N){\n    vector<pii> p;\n    for(int r=1;r<N;r++) p.push_back({r,0});\n    for(int r=N-1;r>=0;r--){\n        if(r%2==1){\n            for(int c=1;c<N;c++) p.push_back({r,c});\n        }else{\n            for(int c=N-1;c>=1;c--) p.push_back({r,c});\n        }\n    }\n    return p;\n}\n\nvector<pii> build_path_right_serp_cols(int N){\n    vector<pii> p;\n    for(int c=1;c<N;c++) p.push_back({0,c});\n    for(int c=N-1;c>=0;c--){\n        int parity = (N-1 - c);\n        if(parity%2==0){\n            for(int r=1;r<N;r++) p.push_back({r,c});\n        }else{\n            for(int r=N-1;r>=1;r--) p.push_back({r,c});\n        }\n    }\n    return p;\n}\n\nvector<pii> build_row_snake(int N){\n    vector<pii> p;\n    for(int r=0;r<N;r++){\n        if(r%2==0){\n            for(int c=0;c<N;c++){\n                if(r==0 && c==0) continue;\n                p.push_back({r,c});\n            }\n        }else{\n            for(int c=N-1;c>=0;c--){\n                p.push_back({r,c});\n            }\n        }\n    }\n    return p;\n}\n\nvector<pii> build_col_snake(int N){\n    vector<pii> p;\n    for(int c=0;c<N;c++){\n        if(c%2==0){\n            for(int r=0;r<N;r++){\n                if(r==0 && c==0) continue;\n                p.push_back({r,c});\n            }\n        }else{\n            for(int r=N-1;r>=0;r--){\n                p.push_back({r,c});\n            }\n        }\n    }\n    return p;\n}\n\nvector<pii> build_spiral(int N){\n    vector<pii> order;\n    int top=0,bottom=N-1,left=0,right=N-1;\n    while(top<=bottom && left<=right){\n        for(int c=left;c<=right;c++) order.push_back({top,c});\n        top++;\n        for(int r=top;r<=bottom;r++) order.push_back({r,right});\n        right--;\n        if(top<=bottom){\n            for(int c=right;c>=left;c--) order.push_back({bottom,c});\n            bottom--;\n        }\n        if(left<=right){\n            for(int r=bottom;r>=top;r--) order.push_back({r,left});\n            left++;\n        }\n    }\n    vector<pii> p;\n    p.reserve(order.size()-1);\n    for(auto &co: order){\n        if(co.first==0 && co.second==0) continue;\n        p.push_back(co);\n    }\n    return p;\n}\n\nvector<pii> reverse_if_adjacent(const vector<pii>& path){\n    vector<pii> rev;\n    if(path.empty()) return rev;\n    auto last = path.back();\n    if(abs(last.first) + abs(last.second) != 1) return rev;\n    rev.reserve(path.size());\n    for(int i=(int)path.size()-1;i>=0;i--){\n        rev.push_back(path[i]);\n    }\n    return rev;\n}\n\n// Simulate cost for path (excluding start)\nll simulate_cost(const vector<pii>& path, const vector<vector<int>>& h, ll& outBorrow){\n    ll pref=0, minPref=0;\n    for(auto [r,c]: path){\n        pref += h[r][c];\n        if(pref < minPref) minPref = pref;\n    }\n    ll borrow = -minPref;\n    outBorrow = borrow;\n    ll cost=0;\n    ll load = borrow;\n    if(borrow>0) cost += borrow;\n    int cr=0, cc=0;\n    for(auto [r,c]: path){\n        int dist = abs(r-cr) + abs(c-cc);\n        cost += (100 + load) * 1LL * dist;\n        int val = h[r][c];\n        cost += llabs((ll)val);\n        load += val;\n        cr = r; cc = c;\n    }\n    int distback = abs(cr) + abs(cc);\n    cost += (100 + load) * 1LL * distback;\n    cost += llabs(load); // final adjust at start\n    return cost;\n}\n\n// Build plan for a given path\nPlan build_path_plan(const vector<pii>& path, const vector<vector<int>>& h){\n    Plan res;\n    res.cost = 0;\n    res.valid = true;\n    vector<vector<int>> g = h;\n    ll pref=0, minPref=0;\n    for(auto [r,c]: path){\n        pref += h[r][c];\n        minPref = min(minPref, pref);\n    }\n    ll borrow = -minPref;\n    ll load = 0;\n    vector<string> ops;\n    if(borrow > 0){\n        ops.push_back(\"+\" + to_string(borrow));\n        res.cost += borrow;\n        load += borrow;\n        g[0][0] -= (int)borrow;\n    }\n\n    int cr=0, cc=0;\n    for(auto [r,c]: path){\n        int dr = r - cr;\n        int dc = c - cc;\n        while(dr > 0){ ops.push_back(\"D\"); res.cost += 100 + load; cr++; dr--; }\n        while(dr < 0){ ops.push_back(\"U\"); res.cost += 100 + load; cr--; dr++; }\n        while(dc > 0){ ops.push_back(\"R\"); res.cost += 100 + load; cc++; dc--; }\n        while(dc < 0){ ops.push_back(\"L\"); res.cost += 100 + load; cc--; dc++; }\n        int val = g[cr][cc];\n        if(val > 0){\n            ops.push_back(\"+\" + to_string(val));\n            res.cost += val;\n            load += val;\n            g[cr][cc] = 0;\n        }else if(val < 0){\n            int d = -val;\n            ops.push_back(\"-\" + to_string(d));\n            res.cost += d;\n            load -= d;\n            g[cr][cc] = 0;\n        }\n    }\n\n    // Return to origin\n    while(cr > 0){ ops.push_back(\"U\"); res.cost += 100 + load; cr--; }\n    while(cc > 0){ ops.push_back(\"L\"); res.cost += 100 + load; cc--; }\n\n    // Final adjust start\n    int sval = g[0][0];\n    if(sval > 0){\n        ops.push_back(\"+\" + to_string(sval));\n        res.cost += sval;\n        load += sval;\n        g[0][0] = 0;\n    }else if(sval < 0){\n        int d = -sval;\n        ops.push_back(\"-\" + to_string(d));\n        res.cost += d;\n        load -= d;\n        g[0][0] = 0;\n    }\n\n    if((int)ops.size() > 100000) res.valid = false;\n    res.ops.swap(ops);\n    return res;\n}\n\n// Greedy transport plan\nPlan build_greedy_plan(const vector<vector<int>>& h){\n    int N = h.size();\n    vector<vector<int>> a = h;\n    ll total_nonzero = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) total_nonzero += llabs((ll)a[i][j]);\n\n    Plan res;\n    res.cost = 0;\n    res.valid = true;\n    vector<string> ops;\n    ll load = 0;\n    int r=0, c=0;\n\n    auto move_steps = [&](int nr, int nc){\n        int dr = nr - r;\n        int dc = nc - c;\n        while(dr > 0){ ops.push_back(\"D\"); res.cost += 100 + load; r++; dr--; }\n        while(dr < 0){ ops.push_back(\"U\"); res.cost += 100 + load; r--; dr++; }\n        while(dc > 0){ ops.push_back(\"R\"); res.cost += 100 + load; c++; dc--; }\n        while(dc < 0){ ops.push_back(\"L\"); res.cost += 100 + load; c--; dc++; }\n    };\n\n    int iter=0;\n    while(total_nonzero > 0 && (int)ops.size() < 100000){\n        iter++;\n        if(load == 0){\n            int bestR=-1,bestC=-1,bestD=1e9, bestVal=0;\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    int val = a[i][j];\n                    if(val > 0){\n                        int d = abs(i-r) + abs(j-c);\n                        if(d < bestD || (d == bestD && val > bestVal)){\n                            bestD = d; bestR = i; bestC = j; bestVal = val;\n                        }\n                    }\n                }\n            }\n            if(bestR==-1){\n                // no positive, should not happen\n                res.valid = false;\n                break;\n            }\n            move_steps(bestR, bestC);\n            int val = a[r][c];\n            ops.push_back(\"+\" + to_string(val));\n            res.cost += val;\n            load += val;\n            total_nonzero -= val;\n            a[r][c] = 0;\n        }else{\n            int bestR=-1,bestC=-1,bestD=1e9, bestNeed=0;\n            for(int i=0;i<N;i++){\n                for(int j=0;j<N;j++){\n                    int val = a[i][j];\n                    if(val < 0){\n                        int d = abs(i-r) + abs(j-c);\n                        int need = -val;\n                        if(d < bestD || (d == bestD && need > bestNeed)){\n                            bestD = d; bestR = i; bestC = j; bestNeed = need;\n                        }\n                    }\n                }\n            }\n            if(bestR==-1){\n                // no negative, should not happen if load>0\n                res.valid = false;\n                break;\n            }\n            move_steps(bestR, bestC);\n            int need = -a[r][c];\n            int t = (int)min<ll>(load, need);\n            ops.push_back(\"-\" + to_string(t));\n            res.cost += t;\n            load -= t;\n            a[r][c] += t;\n            total_nonzero -= t;\n        }\n    }\n\n    if(total_nonzero != 0 || (int)ops.size()>100000) res.valid = false;\n    res.ops.swap(ops);\n    return res;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cin>>h[i][j];\n        }\n    }\n\n    vector<vector<pii>> candidates;\n    auto pA = build_path_down_serp_rows(N);\n    auto pB = build_path_right_serp_cols(N);\n    auto pRow = build_row_snake(N);\n    auto pCol = build_col_snake(N);\n    auto pSp = build_spiral(N);\n    candidates.push_back(pA);\n    candidates.push_back(pB);\n    candidates.push_back(pRow);\n    candidates.push_back(pCol);\n    candidates.push_back(pSp);\n    auto revA = reverse_if_adjacent(pA);\n    if(!revA.empty()) candidates.push_back(revA);\n    auto revB = reverse_if_adjacent(pB);\n    if(!revB.empty()) candidates.push_back(revB);\n    auto revSp = reverse_if_adjacent(pSp);\n    if(!revSp.empty()) candidates.push_back(revSp);\n\n    ll bestSimCost = (1LL<<60);\n    vector<pii> bestPath = candidates[0];\n    for(auto &p: candidates){\n        if((int)p.size() != N*N-1) continue;\n        ll bor;\n        ll cst = simulate_cost(p, h, bor);\n        if(cst < bestSimCost){\n            bestSimCost = cst;\n            bestPath = p;\n        }\n    }\n\n    Plan scanPlan = build_path_plan(bestPath, h);\n    Plan greedyPlan = build_greedy_plan(h);\n\n    Plan *bestPlan = nullptr;\n    if(greedyPlan.valid && (!scanPlan.valid || greedyPlan.cost < scanPlan.cost)){\n        bestPlan = &greedyPlan;\n    }else{\n        bestPlan = &scanPlan;\n    }\n\n    for(auto &s: bestPlan->ops){\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, T;\n    if (!(cin >> N >> M >> T)) return 0;\n    const int SEED_COUNT = 2 * N * (N - 1); // 60 for N=6\n    vector<array<int, 15>> seeds(SEED_COUNT);\n    for (int i = 0; i < SEED_COUNT; i++) {\n        for (int j = 0; j < M; j++) cin >> seeds[i][j];\n    }\n\n    int SZ = N * N;\n    vector<vector<int>> neighPos(SZ);\n    vector<pair<int, int>> edges;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int p = i * N + j;\n            if (i > 0) neighPos[p].push_back((i - 1) * N + j);\n            if (i + 1 < N) neighPos[p].push_back((i + 1) * N + j);\n            if (j > 0) neighPos[p].push_back(i * N + (j - 1));\n            if (j + 1 < N) neighPos[p].push_back(i * N + (j + 1));\n            if (j + 1 < N) edges.push_back({p, i * N + (j + 1)});\n            if (i + 1 < N) edges.push_back({p, (i + 1) * N + j});\n        }\n    }\n\n    int center_i = N / 2 - 1, center_j = N / 2 - 1;\n    int centerPos = center_i * N + center_j;\n    vector<char> isCenterNbr(SZ, 0);\n    if (center_j - 1 >= 0) isCenterNbr[center_i * N + (center_j - 1)] = 1;\n    if (center_j + 1 < N) isCenterNbr[center_i * N + (center_j + 1)] = 1;\n    if (center_i - 1 >= 0) isCenterNbr[(center_i - 1) * N + center_j] = 1;\n    if (center_i + 1 < N) isCenterNbr[(center_i + 1) * N + center_j] = 1;\n\n    double cx = (N - 1) / 2.0, cy = (N - 1) / 2.0;\n    vector<double> posDist(SZ);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        int p = i * N + j;\n        posDist[p] = fabs(i - cx) + fabs(j - cy);\n    }\n\n    // global maxima per attribute from initial seeds\n    array<int, 15> globalMax{};\n    for (int l = 0; l < M; l++) {\n        int mx = 0;\n        for (int k = 0; k < SEED_COUNT; k++) mx = max(mx, seeds[k][l]);\n        globalMax[l] = mx;\n    }\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    vector<vector<int>> synergy(SEED_COUNT, vector<int>(SEED_COUNT, 0));\n    vector<vector<long long>> synergy3(SEED_COUNT, vector<long long>(SEED_COUNT, 0));\n\n    // base position list (excluding center), degree desc then distance asc\n    struct PosInfo { int pos; int deg; double dist; };\n    vector<PosInfo> basePosLeft;\n    basePosLeft.reserve(SZ);\n    for (int p = 0; p < SZ; p++) {\n        if (p == centerPos) continue;\n        basePosLeft.push_back({p, (int)neighPos[p].size(), posDist[p]});\n    }\n    sort(basePosLeft.begin(), basePosLeft.end(), [&](const PosInfo &a, const PosInfo &b){\n        if (a.deg != b.deg) return a.deg > b.deg;\n        return a.dist < b.dist;\n    });\n\n    auto edgeWeight = [&](int a, int b) -> int {\n        if (a == centerPos || b == centerPos) return 40;\n        if (isCenterNbr[a] || isCenterNbr[b]) return 20;\n        return 10;\n    };\n\n    for (int turn = 0; turn < T; turn++) {\n        // compute value and cntMax\n        vector<int> val(SEED_COUNT, 0), cntMax(SEED_COUNT, 0);\n        for (int k = 0; k < SEED_COUNT; k++) {\n            int s = 0, c = 0;\n            for (int l = 0; l < M; l++) {\n                s += seeds[k][l];\n                if (seeds[k][l] == globalMax[l]) c++;\n            }\n            val[k] = s;\n            cntMax[k] = c;\n        }\n        // best seed\n        int best_id = 0;\n        for (int i = 1; i < SEED_COUNT; i++) if (val[i] > val[best_id]) best_id = i;\n\n        // champions per attribute (unique)\n        vector<int> championList;\n        vector<char> seenChamp(SEED_COUNT, 0);\n        for (int l = 0; l < M; l++) {\n            int cid = 0;\n            for (int k = 1; k < SEED_COUNT; k++) {\n                if (seeds[k][l] > seeds[cid][l] ||\n                    (seeds[k][l] == seeds[cid][l] && val[k] > val[cid])) {\n                    cid = k;\n                }\n            }\n            if (!seenChamp[cid]) {\n                seenChamp[cid] = 1;\n                championList.push_back(cid);\n            }\n        }\n\n        // improvers relative to best\n        struct Item { int score, val, id; };\n        vector<Item> improvers;\n        improvers.reserve(SEED_COUNT);\n        for (int k = 0; k < SEED_COUNT; k++) if (k != best_id) {\n            int imp = 0;\n            for (int l = 0; l < M; l++) imp += max(seeds[best_id][l], seeds[k][l]) - seeds[best_id][l];\n            improvers.push_back({imp, val[k], k});\n        }\n        sort(improvers.begin(), improvers.end(), [&](const Item &a, const Item &b) {\n            if (a.score != b.score) return a.score > b.score;\n            return a.val > b.val;\n        });\n\n        // selection of seeds to plant\n        vector<char> used(SEED_COUNT, 0);\n        vector<int> selected;\n        auto add_sel = [&](int id) {\n            if (!used[id]) {\n                used[id] = 1;\n                selected.push_back(id);\n            }\n        };\n        add_sel(best_id);\n        for (int cid : championList) add_sel(cid);\n        int IMP_LIMIT = 15;\n        int impAdded = 0;\n        for (auto &it : improvers) {\n            if (impAdded >= IMP_LIMIT) break;\n            if (!used[it.id]) {\n                add_sel(it.id);\n                impAdded++;\n            }\n        }\n        // fill with high cntMax then val\n        vector<int> fillOrder(SEED_COUNT);\n        iota(fillOrder.begin(), fillOrder.end(), 0);\n        sort(fillOrder.begin(), fillOrder.end(), [&](int a, int b) {\n            if (cntMax[a] != cntMax[b]) return cntMax[a] > cntMax[b];\n            return val[a] > val[b];\n        });\n        for (int id : fillOrder) {\n            if ((int)selected.size() >= SZ) break;\n            add_sel(id);\n        }\n        if ((int)selected.size() < SZ) {\n            vector<int> byVal(SEED_COUNT);\n            iota(byVal.begin(), byVal.end(), 0);\n            sort(byVal.begin(), byVal.end(), [&](int a, int b){ return val[a] > val[b]; });\n            for (int id : byVal) {\n                if ((int)selected.size() >= SZ) break;\n                add_sel(id);\n            }\n        }\n\n        // trim if oversized\n        vector<char> essential(SEED_COUNT, 0);\n        essential[best_id] = 1;\n        for (int cid : championList) essential[cid] = 1;\n        while ((int)selected.size() > SZ) {\n            int remIdx = -1;\n            int worstCnt = INT_MAX, worstVal = INT_MAX;\n            for (int idx = 0; idx < (int)selected.size(); idx++) {\n                int id = selected[idx];\n                if (essential[id]) continue;\n                if (cntMax[id] < worstCnt || (cntMax[id] == worstCnt && val[id] < worstVal)) {\n                    worstCnt = cntMax[id];\n                    worstVal = val[id];\n                    remIdx = idx;\n                }\n            }\n            if (remIdx == -1) break;\n            used[selected[remIdx]] = 0;\n            selected.erase(selected.begin() + remIdx);\n        }\n\n        // compute synergy matrix and cube\n        for (int a = 0; a < SEED_COUNT; a++) {\n            for (int b = 0; b < SEED_COUNT; b++) {\n                int s = 0;\n                for (int l = 0; l < M; l++) s += max(seeds[a][l], seeds[b][l]);\n                synergy[a][b] = s;\n                long long sq = 1LL * s * s;\n                synergy3[a][b] = sq * s;\n            }\n        }\n\n        // neighbor seeds: prioritize covering missing maxima and synergy\n        vector<int> missing;\n        for (int l = 0; l < M; l++) if (seeds[best_id][l] != globalMax[l]) missing.push_back(l);\n        vector<pair<int,int>> neighCand;\n        for (int id : selected) if (id != best_id) {\n            int cover = 0;\n            for (int l : missing) if (seeds[id][l] == globalMax[l]) cover++;\n            int score = cover * 2000 + synergy[best_id][id];\n            neighCand.push_back({score, id});\n        }\n        sort(neighCand.begin(), neighCand.end(), [&](const pair<int,int>&a, const pair<int,int>&b){\n            if (a.first != b.first) return a.first > b.first;\n            return val[a.second] > val[b.second];\n        });\n        vector<int> neighborSeeds;\n        for (auto &pr : neighCand) {\n            if ((int)neighborSeeds.size() >= 4) break;\n            neighborSeeds.push_back(pr.second);\n        }\n\n        // positions around center\n        vector<int> centerNbrs;\n        int ci = center_i, cj = center_j;\n        if (cj - 1 >= 0) centerNbrs.push_back(ci * N + (cj - 1));\n        if (cj + 1 < N) centerNbrs.push_back(ci * N + (cj + 1));\n        if (ci - 1 >= 0) centerNbrs.push_back((ci - 1) * N + cj);\n        if (ci + 1 < N) centerNbrs.push_back((ci + 1) * N + cj);\n\n        int BEST_TRIES = 5;\n        vector<int> bestAssign(SZ, -1);\n        long long bestScore = LLONG_MIN;\n\n        for (int trial = 0; trial < BEST_TRIES; trial++) {\n            vector<int> assign(SZ, -1);\n            vector<char> pinned(SZ, 0);\n            assign[centerPos] = best_id;\n            pinned[centerPos] = 1;\n            // shuffle neighborSeeds\n            vector<int> neighShuf = neighborSeeds;\n            shuffle(neighShuf.begin(), neighShuf.end(), rng);\n            for (size_t idx = 0; idx < centerNbrs.size() && idx < neighShuf.size(); idx++) {\n                int pos = centerNbrs[idx];\n                assign[pos] = neighShuf[idx];\n                pinned[pos] = 1;\n            }\n            vector<char> isPinnedSeed(SEED_COUNT, 0);\n            isPinnedSeed[best_id] = 1;\n            for (int id : neighShuf) isPinnedSeed[id] = 1;\n            // seedsLeft ordered by cntMax then val\n            vector<int> seedsLeft;\n            for (int id : selected) if (!isPinnedSeed[id]) seedsLeft.push_back(id);\n            sort(seedsLeft.begin(), seedsLeft.end(), [&](int a, int b){\n                if (cntMax[a] != cntMax[b]) return cntMax[a] > cntMax[b];\n                return val[a] > val[b];\n            });\n            // positions left fill\n            size_t idxSeed = 0;\n            for (auto &pi : basePosLeft) {\n                int p = pi.pos;\n                if (pinned[p]) continue;\n                if (idxSeed < seedsLeft.size()) {\n                    assign[p] = seedsLeft[idxSeed++];\n                }\n            }\n\n            // variable positions\n            vector<int> varPosList;\n            for (int p = 0; p < SZ; p++) if (!pinned[p]) varPosList.push_back(p);\n\n            auto computeDelta = [&](int p, int q) -> long long {\n                int sp = assign[p], sq = assign[q];\n                long long delta = 0;\n                for (int n : neighPos[p]) {\n                    if (n == q) continue;\n                    int sn = assign[n];\n                    long long w = edgeWeight(p, n);\n                    delta -= w * synergy3[sp][sn];\n                    delta += w * synergy3[sq][sn];\n                }\n                for (int n : neighPos[q]) {\n                    if (n == p) continue;\n                    int sn = assign[n];\n                    long long w = edgeWeight(q, n);\n                    delta -= w * synergy3[sq][sn];\n                    delta += w * synergy3[sp][sn];\n                }\n                return delta;\n            };\n\n            // initial score\n            long long curScore = 0;\n            for (auto &e : edges) {\n                int a = e.first, b = e.second;\n                long long w = edgeWeight(a, b);\n                curScore += w * synergy3[assign[a]][assign[b]];\n            }\n            long long bestLocalScore = curScore;\n            vector<int> bestLocalAssign = assign;\n\n            const int ITERS = 70000;\n            double tempStart = 200.0, tempEnd = 1.0;\n            int vps = varPosList.size();\n            for (int it = 0; it < ITERS; it++) {\n                int idx1 = rng() % vps;\n                int idx2 = rng() % vps;\n                if (idx1 == idx2) continue;\n                int p = varPosList[idx1], q = varPosList[idx2];\n                long long delta = computeDelta(p, q);\n                double temp = tempStart + (tempEnd - tempStart) * (double)it / (double)ITERS;\n                if (delta > 0 || exp(delta / temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                    swap(assign[p], assign[q]);\n                    curScore += delta;\n                    if (curScore > bestLocalScore) {\n                        bestLocalScore = curScore;\n                        bestLocalAssign = assign;\n                    }\n                }\n            }\n\n            if (bestLocalScore > bestScore) {\n                bestScore = bestLocalScore;\n                bestAssign = bestLocalAssign;\n            }\n        }\n\n        // output best assignment grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (j) cout << ' ';\n                cout << bestAssign[i * N + j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // read next generation seeds\n        if (turn != T - 1) {\n            for (int i = 0; i < SEED_COUNT; i++) {\n                for (int j = 0; j < M; j++) cin >> seeds[i][j];\n            }\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n};\ninline int manh(const Pos &a, const Pos &b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Hungarian algorithm (min-cost perfect matching) for square matrix\nvector<int> hungarian(const vector<vector<int>> &a) {\n    int n = (int)a.size();\n    const int INF = 1e9;\n    vector<int> u(n + 1), v(n + 1), p(n + 1), way(n + 1);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i;\n        int j0 = 0;\n        vector<int> minv(n + 1, INF);\n        vector<char> used(n + 1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], delta = INF, j1 = 0;\n            for (int j = 1; j <= n; j++) if (!used[j]) {\n                int cur = a[i0 - 1][j - 1] - u[i0] - v[j];\n                if (cur < minv[j]) {\n                    minv[j] = cur;\n                    way[j] = j0;\n                }\n                if (minv[j] < delta) {\n                    delta = minv[j];\n                    j1 = j;\n                }\n            }\n            for (int j = 0; j <= n; j++) {\n                if (used[j]) {\n                    u[p[j]] += delta;\n                    v[j] -= delta;\n                } else {\n                    minv[j] -= delta;\n                }\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do {\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        } while (j0);\n    }\n    vector<int> matchL(n, -1);\n    for (int j = 1; j <= n; j++) if (p[j] != 0) {\n        matchL[p[j] - 1] = j - 1;\n    }\n    return matchL;\n}\n\n// Morton (Z-order) index for ordering points, N<=30 fits 6 bits\ninline uint32_t mortonIndex(int x, int y) {\n    uint32_t res = 0;\n    for (int i = 0; i < 6; i++) {\n        res |= ((x >> i) & 1u) << (2 * i);\n        res |= ((y >> i) & 1u) << (2 * i + 1);\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, V;\n    if (!(cin >> N >> M >> V)) return 0;\n    vector<string> s(N), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n\n    vector<Pos> sources, targets;\n    sources.reserve(M);\n    targets.reserve(M);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s[i][j] == '1' && t[i][j] == '0') sources.push_back({i, j});\n            else if (s[i][j] == '0' && t[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n    int n = (int)sources.size();\n    cout << 1 << \"\\n\";\n    if (n == 0) {\n        cout << 0 << \" \" << 0 << \"\\n\";\n        return 0;\n    }\n\n    auto startAll = chrono::steady_clock::now();\n    auto elapsed = [&]() -> double {\n        chrono::duration<double> diff = chrono::steady_clock::now() - startAll;\n        return diff.count();\n    };\n    const double TIME_LIMIT = 2.8;\n    const double SA_LIMIT = 1.0;\n    const double LS_LIMIT = 2.3;\n\n    mt19937 rng((unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> uid(0, n - 1);\n\n    // Assignment via Hungarian\n    vector<vector<int>> costAssign(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            costAssign[i][j] = manh(sources[i], targets[j]);\n    vector<int> matchS = hungarian(costAssign); // target index for each source\n\n    vector<Pos> taskTarget(n);\n    for (int i = 0; i < n; i++) taskTarget[i] = targets[matchS[i]];\n\n    // edgeCost: target of i -> source of j\n    vector<vector<int>> edgeCost(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            edgeCost[i][j] = manh(taskTarget[i], sources[j]);\n        }\n    }\n\n    auto transCost = [&](const vector<int> &seq) -> long long {\n        long long res = 0;\n        for (int i = 0; i + 1 < (int)seq.size(); i++) res += edgeCost[seq[i]][seq[i + 1]];\n        return res;\n    };\n\n    // initial sequences: Z-order and NN from several starts\n    vector<int> bestSeq;\n    long long bestCost = (1LL << 60);\n\n    vector<int> idxZ(n);\n    iota(idxZ.begin(), idxZ.end(), 0);\n    sort(idxZ.begin(), idxZ.end(), [&](int a, int b) {\n        return mortonIndex(sources[a].x, sources[a].y) < mortonIndex(sources[b].x, sources[b].y);\n    });\n    long long cZ = transCost(idxZ);\n    bestSeq = idxZ;\n    bestCost = cZ;\n\n    int numStarts = min(n, 12);\n    vector<int> startCandidates;\n    startCandidates.reserve(numStarts);\n    Pos center{N / 2, N / 2};\n    int bestCenterIdx = 0, bestCenterDist = 1e9;\n    for (int i = 0; i < n; i++) {\n        int d = manh(sources[i], center);\n        if (d < bestCenterDist) {\n            bestCenterDist = d;\n            bestCenterIdx = i;\n        }\n    }\n    startCandidates.push_back(bestCenterIdx);\n    while ((int)startCandidates.size() < numStarts) {\n        int v = uid(rng);\n        bool dup = false;\n        for (int x : startCandidates) if (x == v) { dup = true; break; }\n        if (!dup) startCandidates.push_back(v);\n    }\n\n    for (int st : startCandidates) {\n        vector<char> used(n, false);\n        vector<int> seq;\n        seq.reserve(n);\n        int cur = st;\n        used[cur] = true;\n        seq.push_back(cur);\n        for (int k = 1; k < n; k++) {\n            int best = -1, bestd = 1e9;\n            for (int j = 0; j < n; j++) if (!used[j]) {\n                int d = edgeCost[cur][j];\n                if (d < bestd) {\n                    bestd = d;\n                    best = j;\n                }\n            }\n            used[best] = true;\n            seq.push_back(best);\n            cur = best;\n        }\n        long long c = transCost(seq);\n        if (c < bestCost) {\n            bestCost = c;\n            bestSeq = seq;\n        }\n    }\n\n    vector<int> seq = bestSeq;\n    long long curCost = bestCost;\n    vector<int> bestSeqAll = seq;\n    long long bestCostAll = curCost;\n\n    auto swapDelta = [&](int i, int j) -> int {\n        if (i == j) return 0;\n        if (i > j) swap(i, j);\n        int nseq = (int)seq.size();\n        int a = (i > 0) ? seq[i - 1] : -1;\n        int b = seq[i];\n        int c = (i + 1 < nseq) ? seq[i + 1] : -1;\n        int d = (j > 0) ? seq[j - 1] : -1;\n        int e = seq[j];\n        int f = (j + 1 < nseq) ? seq[j + 1] : -1;\n        if (i + 1 == j) {\n            long long oldc = 0, newc = 0;\n            if (a != -1) { oldc += edgeCost[a][b]; newc += edgeCost[a][e]; }\n            oldc += edgeCost[b][e];\n            newc += edgeCost[e][b];\n            if (f != -1) { oldc += edgeCost[e][f]; newc += edgeCost[b][f]; }\n            return (int)(newc - oldc);\n        } else {\n            long long oldc = 0, newc = 0;\n            if (a != -1) { oldc += edgeCost[a][b]; newc += edgeCost[a][e]; }\n            oldc += edgeCost[b][c];\n            newc += edgeCost[e][c];\n            oldc += edgeCost[d][e];\n            newc += edgeCost[d][b];\n            if (f != -1) { oldc += edgeCost[e][f]; newc += edgeCost[b][f]; }\n            return (int)(newc - oldc);\n        }\n    };\n\n    auto relocateLenDelta = [&](int i, int len, int j) -> int {\n        int nseq = (int)seq.size();\n        if (i + len > nseq) return 0;\n        if (j >= i && j <= i + len) return 0;\n        int first = seq[i];\n        int last = seq[i + len - 1];\n        int prev = (i > 0) ? seq[i - 1] : -1;\n        int next = (i + len < nseq) ? seq[i + len] : -1;\n        int jpos = j;\n        if (j > i) jpos -= len;\n        auto getElem = [&](int idx) -> int {\n            if (idx < i) return seq[idx];\n            else return seq[idx + len];\n        };\n        int reduced = nseq - len;\n        int prevIns = (jpos > 0) ? getElem(jpos - 1) : -1;\n        int nextIns = (jpos < reduced) ? getElem(jpos) : -1;\n        long long delta = 0;\n        if (prev != -1) delta -= edgeCost[prev][first];\n        if (next != -1) delta -= edgeCost[last][next];\n        if (prev != -1 && next != -1) delta += edgeCost[prev][next];\n        if (prevIns != -1 && nextIns != -1) delta -= edgeCost[prevIns][nextIns];\n        if (prevIns != -1) delta += edgeCost[prevIns][first];\n        if (nextIns != -1) delta += edgeCost[last][nextIns];\n        return (int)delta;\n    };\n\n    const int LREV = 40;\n    auto reverseDelta = [&](int i, int j) -> int {\n        if (i >= j) return 0;\n        int len = j - i + 1;\n        if (len > LREV) return 0;\n        int nseq = (int)seq.size();\n        int prev = (i > 0) ? seq[i - 1] : -1;\n        int next = (j + 1 < nseq) ? seq[j + 1] : -1;\n        long long oldc = 0, newc = 0;\n        if (prev != -1) {\n            oldc += edgeCost[prev][seq[i]];\n            newc += edgeCost[prev][seq[j]];\n        }\n        if (next != -1) {\n            oldc += edgeCost[seq[j]][next];\n            newc += edgeCost[seq[i]][next];\n        }\n        for (int k = i; k < j; k++) {\n            oldc += edgeCost[seq[k]][seq[k + 1]];\n            newc += edgeCost[seq[k + 1]][seq[k]];\n        }\n        return (int)(newc - oldc);\n    };\n\n    // Simulated annealing\n    double T0 = 30.0, T1 = 1e-3;\n    while (elapsed() < SA_LIMIT) {\n        double prog = elapsed() / SA_LIMIT;\n        double Temp = exp(log(T0) * (1.0 - prog) + log(T1) * prog);\n        int moveType = uniform_int_distribution<int>(0, 4)(rng);\n        if (moveType == 0) {\n            int i = uid(rng);\n            int j = uid(rng);\n            if (i == j) continue;\n            int d = swapDelta(i, j);\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                swap(seq[i], seq[j]);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        } else if (moveType == 4) {\n            if (n < 2) continue;\n            int i = uid(rng);\n            if (i == n - 1) continue;\n            int j = uniform_int_distribution<int>(i + 1, min(n - 1, i + LREV))(rng);\n            int d = reverseDelta(i, j);\n            if (d == 0) continue;\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                reverse(seq.begin() + i, seq.begin() + j + 1);\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        } else {\n            int len = moveType; // 1,2,3\n            if (n < len) continue;\n            int i = uniform_int_distribution<int>(0, n - len)(rng);\n            int j = uniform_int_distribution<int>(0, n)(rng);\n            if (j >= i && j <= i + len) continue;\n            int d = relocateLenDelta(i, len, j);\n            if (d < 0 || exp(-d / Temp) > uniform_real_distribution<double>(0.0, 1.0)(rng)) {\n                vector<int> block(seq.begin() + i, seq.begin() + i + len);\n                seq.erase(seq.begin() + i, seq.begin() + i + len);\n                if (j > i) j -= len;\n                seq.insert(seq.begin() + j, block.begin(), block.end());\n                curCost += d;\n                if (curCost < bestCostAll) {\n                    bestCostAll = curCost;\n                    bestSeqAll = seq;\n                }\n            }\n        }\n    }\n\n    seq = bestSeqAll;\n    curCost = bestCostAll;\n\n    // Local search with limited window and len 1..3 relocations and reverse\n    int W = min(40, n - 1);\n    bool improved = true;\n    while (improved && elapsed() < LS_LIMIT) {\n        improved = false;\n        for (int i = 0; i < n && elapsed() < LS_LIMIT; i++) {\n            int l = max(0, i - W);\n            int r = min(n - 1, i + W);\n            for (int j = l; j <= r; j++) if (j != i) {\n                int d = swapDelta(i, j);\n                if (d < 0) {\n                    swap(seq[i], seq[j]);\n                    curCost += d;\n                    if (curCost < bestCostAll) {\n                        bestCostAll = curCost;\n                        bestSeqAll = seq;\n                    }\n                    improved = true;\n                    goto next_phase;\n                }\n            }\n        }\n        next_phase:\n        if (improved) continue;\n        for (int len = 1; len <= 3 && elapsed() < LS_LIMIT; len++) {\n            for (int i = 0; i + len <= n && elapsed() < LS_LIMIT; i++) {\n                int l = max(0, i - W);\n                int r = min(n, i + W);\n                for (int j = l; j <= r; j++) {\n                    if (j >= i && j <= i + len) continue;\n                    int d = relocateLenDelta(i, len, j);\n                    if (d < 0) {\n                        vector<int> block(seq.begin() + i, seq.begin() + i + len);\n                        seq.erase(seq.begin() + i, seq.begin() + i + len);\n                        if (j > i) j -= len;\n                        seq.insert(seq.begin() + j, block.begin(), block.end());\n                        curCost += d;\n                        if (curCost < bestCostAll) {\n                            bestCostAll = curCost;\n                            bestSeqAll = seq;\n                        }\n                        improved = true;\n                        goto next_iter;\n                    }\n                }\n            }\n        }\n        if (improved) continue;\n        for (int i = 0; i < n && elapsed() < LS_LIMIT; i++) {\n            int jmax = min(n - 1, i + LREV);\n            for (int j = i + 1; j <= jmax; j++) {\n                int d = reverseDelta(i, j);\n                if (d < 0) {\n                    reverse(seq.begin() + i, seq.begin() + j + 1);\n                    curCost += d;\n                    if (curCost < bestCostAll) {\n                        bestCostAll = curCost;\n                        bestSeqAll = seq;\n                    }\n                    improved = true;\n                    goto next_iter;\n                }\n            }\n        }\n        next_iter: ;\n    }\n\n    seq = bestSeqAll;\n\n    // Target optimization\n    vector<int> targetIdx = matchS;\n    vector<int> nextTask(n, -1);\n    for (int i = 0; i + 1 < n; i++) nextTask[seq[i]] = seq[i + 1];\n\n    auto deltaSwapTargets = [&](int a, int b) -> int {\n        int tA = targetIdx[a], tB = targetIdx[b];\n        if (tA == tB) return 0;\n        Pos dA = targets[tA], dB = targets[tB];\n        int nA = nextTask[a], nB = nextTask[b];\n        int oldPick = manh(sources[a], dA) + manh(sources[b], dB);\n        int newPick = manh(sources[a], dB) + manh(sources[b], dA);\n        int oldTrans = 0, newTrans = 0;\n        if (nA != -1) {\n            oldTrans += manh(dA, sources[nA]);\n            newTrans += manh(dB, sources[nA]);\n        }\n        if (nB != -1) {\n            oldTrans += manh(dB, sources[nB]);\n            newTrans += manh(dA, sources[nB]);\n        }\n        return (newPick + newTrans) - (oldPick + oldTrans);\n    };\n\n    auto optimizeWindow = [&](int l, int k) {\n        if (l + k > n) return;\n        vector<int> tasks(k);\n        for (int i = 0; i < k; i++) tasks[i] = seq[l + i];\n        vector<int> subset(k);\n        for (int i = 0; i < k; i++) subset[i] = targetIdx[tasks[i]];\n        vector<int> sorted = subset;\n        sort(sorted.begin(), sorted.end());\n        Pos prevTargetPos;\n        bool hasPrev = false;\n        if (l > 0) {\n            int prevTask = seq[l - 1];\n            prevTargetPos = targets[targetIdx[prevTask]];\n            hasPrev = true;\n        }\n        Pos nextSourcePos;\n        bool hasNext = false;\n        if (l + k < n) {\n            int nextTask = seq[l + k];\n            nextSourcePos = sources[nextTask];\n            hasNext = true;\n        }\n        auto calcCost = [&](const vector<int> &perm) -> int {\n            int cost = 0;\n            if (hasPrev) cost += manh(prevTargetPos, sources[tasks[0]]);\n            for (int i = 0; i < k; i++) {\n                cost += manh(sources[tasks[i]], targets[perm[i]]);\n                if (i + 1 < k) cost += manh(targets[perm[i]], sources[tasks[i + 1]]);\n            }\n            if (hasNext) cost += manh(targets[perm[k - 1]], nextSourcePos);\n            return cost;\n        };\n        int currentCost = calcCost(subset);\n        int bestC = currentCost;\n        vector<int> bestP = subset;\n        do {\n            int c = calcCost(sorted);\n            if (c < bestC) {\n                bestC = c;\n                bestP = sorted;\n            }\n        } while (next_permutation(sorted.begin(), sorted.end()));\n        if (bestC < currentCost) {\n            for (int i = 0; i < k; i++) {\n                targetIdx[tasks[i]] = bestP[i];\n            }\n        }\n    };\n\n    while (elapsed() < TIME_LIMIT) {\n        double r = uniform_real_distribution<double>(0.0, 1.0)(rng);\n        if (r < 0.3) {\n            int k = uniform_int_distribution<int>(3, 6)(rng);\n            if (k <= n) {\n                int l = uniform_int_distribution<int>(0, n - k)(rng);\n                optimizeWindow(l, k);\n            }\n        } else {\n            int a = uid(rng);\n            int b = uid(rng);\n            if (a == b) continue;\n            int delta = deltaSwapTargets(a, b);\n            if (delta < 0) {\n                swap(targetIdx[a], targetIdx[b]);\n            }\n        }\n    }\n\n    // output initial root position\n    Pos root = sources[seq[0]];\n    cout << root.x << \" \" << root.y << \"\\n\";\n\n    vector<string> cmds;\n    cmds.reserve((size_t)(bestCostAll + n * 2 + 10));\n\n    Pos curPos = root;\n    auto moveTo = [&](const Pos &dest, bool doP) {\n        int dx = dest.x - curPos.x;\n        int dy = dest.y - curPos.y;\n        if (dx != 0) {\n            char mv = (dx > 0) ? 'D' : 'U';\n            int steps = abs(dx);\n            for (int k = 1; k <= steps; k++) {\n                bool last = (k == steps) && (dy == 0) && doP;\n                string cmd;\n                cmd.push_back(mv);\n                cmd.push_back(last ? 'P' : '.');\n                cmds.push_back(std::move(cmd));\n            }\n        }\n        if (dy != 0) {\n            char mv = (dy > 0) ? 'R' : 'L';\n            int steps = abs(dy);\n            for (int k = 1; k <= steps; k++) {\n                bool last = (k == steps) && doP;\n                string cmd;\n                cmd.push_back(mv);\n                cmd.push_back(last ? 'P' : '.');\n                cmds.push_back(std::move(cmd));\n            }\n        }\n        if (dx == 0 && dy == 0) {\n            string cmd;\n            cmd.push_back('.');\n            cmd.push_back(doP ? 'P' : '.');\n            cmds.push_back(std::move(cmd));\n        }\n        curPos = dest;\n    };\n\n    // Execute tasks\n    moveTo(sources[seq[0]], true);\n    moveTo(targets[targetIdx[seq[0]]], true);\n    for (int idx2 = 1; idx2 < n; idx2++) {\n        int task = seq[idx2];\n        moveTo(sources[task], true);\n        moveTo(targets[targetIdx[task]], true);\n    }\n\n    for (auto &c : cmds) cout << c << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x1, x2, y1, y2;\n};\n\nconst int LIM = 100000;\n\ninline Rect normalize(Rect r) {\n    if (r.x1 > r.x2) swap(r.x1, r.x2);\n    if (r.y1 > r.y2) swap(r.y1, r.y2);\n    r.x1 = max(0, min(LIM, r.x1));\n    r.x2 = max(0, min(LIM, r.x2));\n    r.y1 = max(0, min(LIM, r.y1));\n    r.y2 = max(0, min(LIM, r.y2));\n    if (r.x1 == r.x2) {\n        if (r.x2 < LIM) r.x2++;\n        else if (r.x1 > 0) r.x1--;\n        else r.x2 = r.x1 + 1;\n    }\n    if (r.y1 == r.y2) {\n        if (r.y2 < LIM) r.y2++;\n        else if (r.y1 > 0) r.y1--;\n        else r.y2 = r.y1 + 1;\n    }\n    return r;\n}\n\nstruct Evaluator {\n    int tot;\n    const vector<int> &xs, &ys, &ws;\n    Evaluator(const vector<int>& _xs, const vector<int>& _ys, const vector<int>& _ws)\n        : tot((int)_xs.size()), xs(_xs), ys(_ys), ws(_ws) {}\n    inline int evalRect(const Rect& r) const {\n        int s = 0;\n        int x1 = r.x1, x2 = r.x2, y1 = r.y1, y2 = r.y2;\n        for (int i = 0; i < tot; i++) {\n            int x = xs[i];\n            if (x < x1 || x > x2) continue;\n            int y = ys[i];\n            if (y < y1 || y > y2) continue;\n            s += ws[i];\n        }\n        return s;\n    }\n};\n\nRect bestGridRect(int G, const vector<int>& xs, const vector<int>& ys, const vector<int>& ws) {\n    int cell = (LIM + G - 1) / G;\n    vector<vector<int>> diff(G, vector<int>(G, 0));\n    int tot = (int)xs.size();\n    for (int i = 0; i < tot; i++) {\n        int cx = xs[i] / cell; if (cx >= G) cx = G - 1;\n        int cy = ys[i] / cell; if (cy >= G) cy = G - 1;\n        diff[cy][cx] += ws[i];\n    }\n    int best = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n    vector<int> col(G);\n    for (int top = 0; top < G; top++) {\n        fill(col.begin(), col.end(), 0);\n        for (int bottom = top; bottom < G; bottom++) {\n            for (int x = 0; x < G; x++) col[x] += diff[bottom][x];\n            int cur = 0, start = 0;\n            int bestSum = -1e9, bestL = 0, bestR = 0;\n            for (int x = 0; x < G; x++) {\n                if (cur <= 0) {\n                    cur = col[x];\n                    start = x;\n                } else {\n                    cur += col[x];\n                }\n                if (cur > bestSum) {\n                    bestSum = cur;\n                    bestL = start;\n                    bestR = x;\n                }\n            }\n            if (bestSum > best) {\n                best = bestSum;\n                int x1 = bestL * cell;\n                int x2 = min(LIM, (bestR + 1) * cell);\n                int y1 = top * cell;\n                int y2 = min(LIM, (bottom + 1) * cell);\n                bestRect = normalize({x1, x2, y1, y2});\n            }\n        }\n    }\n    return bestRect;\n}\n\nstruct Candidate {\n    int score;\n    Rect rect;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    int TOT = 2 * N;\n    vector<int> xs(TOT), ys(TOT), ws(TOT);\n    for (int i = 0; i < TOT; i++) {\n        int x, y;\n        cin >> x >> y;\n        xs[i] = x;\n        ys[i] = y;\n        ws[i] = (i < N) ? 1 : -1;\n    }\n    Evaluator eval(xs, ys, ws);\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    auto startTime = chrono::steady_clock::now();\n\n    int bestScore = -1e9;\n    Rect bestRect{0, LIM, 0, LIM};\n\n    vector<Candidate> candList;\n    auto addCandidate = [&](int sc, const Rect& r) {\n        // check duplicates\n        for (auto &c : candList) {\n            if (c.rect.x1 == r.x1 && c.rect.x2 == r.x2 && c.rect.y1 == r.y1 && c.rect.y2 == r.y2) {\n                if (sc > c.score) c.score = sc;\n                return;\n            }\n        }\n        candList.push_back({sc, r});\n        sort(candList.begin(), candList.end(), [](const Candidate& a, const Candidate& b) {\n            return a.score > b.score;\n        });\n        if ((int)candList.size() > 40) candList.resize(40);\n    };\n\n    auto consider = [&](const Rect& r) {\n        Rect nr = normalize(r);\n        int sc = eval.evalRect(nr);\n        addCandidate(sc, nr);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRect = nr;\n        }\n    };\n\n    // bounding box of mackerels\n    int minMx = LIM, maxMx = 0, minMy = LIM, maxMy = 0;\n    for (int i = 0; i < N; i++) {\n        minMx = min(minMx, xs[i]);\n        maxMx = max(maxMx, xs[i]);\n        minMy = min(minMy, ys[i]);\n        maxMy = max(maxMy, ys[i]);\n    }\n    consider({minMx, maxMx, minMy, maxMy});\n\n    // grid search\n    vector<int> Gs = {8, 12, 16, 20, 25, 30, 40, 50};\n    for (int g : Gs) {\n        Rect r = bestGridRect(g, xs, ys, ws);\n        consider(r);\n    }\n\n    // random search\n    vector<int> sizes = {200, 300, 500, 800, 1000, 1200, 1500, 2000, 2500, 3000, 4000, 5000, 6000, 8000, 10000, 12000, 15000, 20000, 25000};\n    const double RAND_TIME = 1.1; // seconds\n    int iter = 0;\n    while (true) {\n        iter++;\n        int t = rng() % 4;\n        if (t == 0) {\n            int idx = rng() % N;\n            int w = sizes[rng() % sizes.size()];\n            int h = sizes[rng() % sizes.size()];\n            Rect r{xs[idx] - w, xs[idx] + w, ys[idx] - h, ys[idx] + h};\n            consider(r);\n        } else if (t == 1) {\n            int i = rng() % TOT;\n            int j = rng() % TOT;\n            int x1 = min(xs[i], xs[j]);\n            int x2 = max(xs[i], xs[j]);\n            int y1 = min(ys[i], ys[j]);\n            int y2 = max(ys[i], ys[j]);\n            int marg = sizes[rng() % sizes.size()] / 2;\n            Rect r{x1 - marg, x2 + marg, y1 - marg, y2 + marg};\n            consider(r);\n        } else if (t == 2) {\n            Rect r = bestRect;\n            int delta = sizes[rng() % sizes.size()] / 2 + 1;\n            int dx1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dx2 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy1 = (int)(rng() % (2 * delta + 1)) - delta;\n            int dy2 = (int)(rng() % (2 * delta + 1)) - delta;\n            r.x1 += dx1; r.x2 += dx2; r.y1 += dy1; r.y2 += dy2;\n            consider(r);\n        } else {\n            // random thin rectangle\n            int idx = rng() % TOT;\n            int w = sizes[rng() % sizes.size()] / 4 + 1;\n            Rect r{xs[idx] - w, xs[idx] + w, 0, LIM};\n            consider(r);\n            r = {0, LIM, ys[idx] - w, ys[idx] + w};\n            consider(r);\n        }\n        if ((iter & 31) == 0) {\n            double elapsed = chrono::duration_cast<chrono::duration<double>>(chrono::steady_clock::now() - startTime).count();\n            if (elapsed > RAND_TIME) break;\n        }\n    }\n\n    // hill climbing around bestRect\n    vector<int> steps = {20000, 10000, 5000, 2000, 1000, 500, 200, 100, 50};\n    Rect cur = bestRect;\n    for (int step : steps) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int edge = 0; edge < 4; edge++) {\n                for (int dir = -1; dir <= 1; dir += 2) {\n                    Rect r = cur;\n                    if (edge == 0) r.x1 += dir * step;\n                    else if (edge == 1) r.x2 += dir * step;\n                    else if (edge == 2) r.y1 += dir * step;\n                    else r.y2 += dir * step;\n                    r = normalize(r);\n                    int sc = eval.evalRect(r);\n                    addCandidate(sc, r);\n                    if (sc > bestScore) {\n                        bestScore = sc;\n                        bestRect = cur = r;\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // evaluate pair connections\n    int bestPairScore = bestScore;\n    Rect bestA = bestRect, bestB = bestRect;\n    bool usePair = false;\n    bool horiz = true;\n    int corridorC = 0;\n    // only top K candidates\n    int K = min<int>(candList.size(), 25);\n    for (int i = 0; i < K; i++) for (int j = i + 1; j < K; j++) {\n        Rect A = candList[i].rect;\n        Rect B = candList[j].rect;\n        // horizontal connection: disjoint in x with y-overlap length>=1\n        if (A.x2 < B.x1 || B.x2 < A.x1) {\n            Rect L = A, R = B;\n            if (B.x2 < A.x1) { L = B; R = A; }\n            int ovL = max(L.y1, R.y1);\n            int ovH = min(L.y2, R.y2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int y1 = c, y2 = c + 1;\n                    int x1 = L.x2, x2 = R.x1;\n                    if (x1 > x2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= L.x1 && x <= L.x2 && y >= L.y1 && y <= L.y2) inside = true;\n                        else if (x >= R.x1 && x <= R.x2 && y >= R.y1 && y <= R.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = L;\n                        bestB = R;\n                        horiz = true;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n        // vertical connection: disjoint in y with x-overlap length>=1\n        if (A.y2 < B.y1 || B.y2 < A.y1) {\n            Rect Lw = A, Up = B;\n            if (B.y2 < A.y1) { Lw = B; Up = A; }\n            int ovL = max(Lw.x1, Up.x1);\n            int ovH = min(Lw.x2, Up.x2);\n            if (ovH - ovL >= 1) {\n                vector<int> cs;\n                cs.push_back(ovL);\n                cs.push_back(ovH - 1);\n                cs.push_back((ovL + ovH - 1) / 2);\n                for (int c : cs) {\n                    if (c < 0) c = 0;\n                    if (c > LIM - 1) c = LIM - 1;\n                    int x1 = c, x2 = c + 1;\n                    int y1 = Lw.y2, y2 = Up.y1;\n                    if (y1 > y2) continue;\n                    int sc = 0;\n                    for (int idx = 0; idx < TOT; idx++) {\n                        int x = xs[idx], y = ys[idx];\n                        bool inside = false;\n                        if (x >= Lw.x1 && x <= Lw.x2 && y >= Lw.y1 && y <= Lw.y2) inside = true;\n                        else if (x >= Up.x1 && x <= Up.x2 && y >= Up.y1 && y <= Up.y2) inside = true;\n                        else if (x >= x1 && x <= x2 && y >= y1 && y <= y2) inside = true;\n                        if (inside) sc += ws[idx];\n                    }\n                    if (sc > bestPairScore) {\n                        bestPairScore = sc;\n                        bestA = Lw;\n                        bestB = Up;\n                        horiz = false;\n                        corridorC = c;\n                        usePair = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<pair<int,int>> poly;\n    if (usePair) {\n        if (horiz) {\n            Rect L = bestA, R = bestB;\n            int c = corridorC;\n            int ch = 1;\n            vector<pair<int,int>> tmp = {\n                {L.x1, L.y1},\n                {L.x2, L.y1},\n                {L.x2, c},\n                {R.x1, c},\n                {R.x1, R.y1},\n                {R.x2, R.y1},\n                {R.x2, R.y2},\n                {R.x1, R.y2},\n                {R.x1, c + ch},\n                {L.x2, c + ch},\n                {L.x2, L.y2},\n                {L.x1, L.y2}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        } else {\n            Rect Lw = bestA, Up = bestB;\n            int c = corridorC;\n            int cw = 1;\n            vector<pair<int,int>> tmp = {\n                {Lw.x1, Lw.y1},\n                {Lw.x1, Lw.y2},\n                {c, Lw.y2},\n                {c, Up.y1},\n                {Up.x1, Up.y1},\n                {Up.x1, Up.y2},\n                {Up.x2, Up.y2},\n                {Up.x2, Up.y1},\n                {c + cw, Up.y1},\n                {c + cw, Lw.y2},\n                {Lw.x2, Lw.y2},\n                {Lw.x2, Lw.y1}\n            };\n            for (auto &p : tmp) poly.push_back(p);\n        }\n    } else {\n        poly = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n    }\n    // compress consecutive duplicates\n    vector<pair<int,int>> comp;\n    comp.reserve(poly.size());\n    for (auto &p : poly) {\n        if (comp.empty() || comp.back() != p) comp.push_back(p);\n    }\n    if (comp.size() >= 2 && comp.front() == comp.back()) comp.pop_back();\n    // check distinct\n    bool okDistinct = true;\n    {\n        unordered_set<long long> st;\n        st.reserve(comp.size() * 2);\n        for (auto &p : comp) {\n            long long key = ((long long)p.first << 32) ^ (unsigned)p.second;\n            if (st.find(key) != st.end()) {\n                okDistinct = false;\n                break;\n            }\n            st.insert(key);\n        }\n    }\n    long long perim = 0;\n    int m = (int)comp.size();\n    for (int i = 0; i < m; i++) {\n        auto [x1, y1] = comp[i];\n        auto [x2, y2] = comp[(i + 1) % m];\n        perim += llabs(x1 - x2) + llabs(y1 - y2);\n    }\n    if (!okDistinct || perim > 400000 || m < 4) {\n        comp = {\n            {bestRect.x1, bestRect.y1},\n            {bestRect.x2, bestRect.y1},\n            {bestRect.x2, bestRect.y2},\n            {bestRect.x1, bestRect.y2}\n        };\n        m = 4;\n    }\n    cout << comp.size() << \"\\n\";\n    for (auto &p : comp) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Command {\n    int p;\n    int r;\n    char d;\n    int b;\n};\n\nstruct Candidate {\n    vector<Command> cmds;\n    long long estScore;\n};\n\n// simulate placement given commands and estimated widths/heights\npair<long long, long long> simulate(const vector<Command>& cmds,\n                                    const vector<long long>& w_est,\n                                    const vector<long long>& h_est) {\n    int N = (int)w_est.size();\n    vector<long long> x(N, 0), y(N, 0), ww(N, 0), hh(N, 0);\n    vector<char> placed(N, 0);\n    long long W = 0, H = 0;\n    for (const auto& cmd : cmds) {\n        int i = cmd.p;\n        long long w = (cmd.r == 0 ? w_est[i] : h_est[i]);\n        long long h = (cmd.r == 0 ? h_est[i] : w_est[i]);\n        long long xi, yi;\n        if (cmd.d == 'U') {\n            xi = (cmd.b == -1) ? 0LL : x[cmd.b] + ww[cmd.b];\n            yi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long l1 = xi, r1 = xi + w;\n                long long l2 = x[j], r2 = x[j] + ww[j];\n                if (max(l1, l2) < min(r1, r2)) {\n                    yi = max(yi, y[j] + hh[j]);\n                }\n            }\n        } else { // 'L'\n            yi = (cmd.b == -1) ? 0LL : y[cmd.b] + hh[cmd.b];\n            xi = 0;\n            for (int j = 0; j < N; j++) if (placed[j]) {\n                long long t1 = yi, b1 = yi + h;\n                long long t2 = y[j], b2 = y[j] + hh[j];\n                if (max(t1, t2) < min(b1, b2)) {\n                    xi = max(xi, x[j] + ww[j]);\n                }\n            }\n        }\n        x[i] = xi; y[i] = yi; ww[i] = w; hh[i] = h; placed[i] = 1;\n        W = max(W, xi + w);\n        H = max(H, yi + h);\n    }\n    return {W, H};\n}\n\nvector<int> dp_partition(const vector<long long>& w, const vector<long long>& h_eff, long long Wlim) {\n    int M = (int)w.size();\n    const long long INF = (1LL << 60);\n    vector<long long> dp(M + 1, INF);\n    vector<int> prv(M + 1, -1);\n    dp[0] = 0;\n    for (int i = 0; i < M; i++) {\n        long long width = 0;\n        long long height = 0;\n        for (int j = i; j >= 0; j--) {\n            width += w[j];\n            if (width > Wlim) break;\n            if (h_eff[j] > height) height = h_eff[j];\n            if (dp[j] + height < dp[i + 1]) {\n                dp[i + 1] = dp[j] + height;\n                prv[i + 1] = j;\n            }\n        }\n    }\n    if (dp[M] >= INF / 2) prv.clear();\n    return prv;\n}\n\nvector<pair<int,int>> reconstruct_rows(const vector<int>& prv) {\n    vector<pair<int,int>> rows;\n    if (prv.empty()) return rows;\n    int idx = (int)prv.size() - 1;\n    while (idx > 0) {\n        int j = prv[idx];\n        if (j < 0) { rows.clear(); return rows; }\n        rows.push_back({j, idx});\n        idx = j;\n    }\n    reverse(rows.begin(), rows.end());\n    return rows;\n}\n\nvector<long long> build_limits(long long sumV, long long maxV, long long sqrtA, int M) {\n    set<long long> s;\n    s.insert(maxV);\n    s.insert(sumV);\n    s.insert(sqrtA);\n    int Kpart = min(10, M);\n    for (int k = 2; k <= Kpart; k++) {\n        s.insert((sumV + k - 1) / k);\n    }\n    int Kgeo = 10;\n    if (maxV > 0) {\n        long double ratio = (long double)sumV / (long double)maxV;\n        for (int k = 0; k < Kgeo; k++) {\n            long double val = (long double)maxV * pow(ratio, (long double)k / (long double)(Kgeo - 1));\n            long long V = (long long)(val + 0.5);\n            V = max(V, maxV);\n            V = min(V, sumV);\n            s.insert(V);\n        }\n    }\n    vector<long long> res(s.begin(), s.end());\n    return res;\n}\n\nvector<long long> build_width_candidates_base(const vector<long long>& w, const vector<long long>& h) {\n    int N = (int)w.size();\n    long long sumW = 0, maxW = 0;\n    for (int i = 0; i < N; i++) {\n        sumW += w[i];\n        maxW = max(maxW, w[i]);\n    }\n    set<long long> s;\n    s.insert(maxW);\n    s.insert(sumW);\n    int Rmax = min(8, N);\n    for (int R = 2; R <= Rmax; R++) {\n        long long W = (sumW + R - 1) / R;\n        if (W < maxW) W = maxW;\n        s.insert(W);\n    }\n    int K = 6;\n    for (int k = 0; k < K; k++) {\n        double ratio = (K == 1) ? 0.0 : (double)k / (double)(K - 1);\n        double val = (double)maxW * pow((double)sumW / (double)maxW, ratio);\n        long long W = (long long)(val + 0.5);\n        if (W < maxW) W = maxW;\n        if (W > sumW) W = sumW;\n        s.insert(W);\n    }\n    vector<long long> res(s.begin(), s.end());\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> w_obs(N), h_obs(N);\n    for (int i = 0; i < N; i++) cin >> w_obs[i] >> h_obs[i];\n\n    // orientation patterns\n    vector<vector<int>> orientations;\n    auto add_ori = [&](const vector<int>& o) {\n        for (auto &v : orientations) {\n            if (v == o) return;\n        }\n        orientations.push_back(o);\n    };\n    vector<int> ori_none(N, 0);\n    add_ori(ori_none);\n    vector<int> ori_minH(N), ori_minW(N);\n    for (int i = 0; i < N; i++) {\n        ori_minH[i] = (w_obs[i] < h_obs[i]) ? 1 : 0;\n        ori_minW[i] = (w_obs[i] > h_obs[i]) ? 1 : 0;\n    }\n    add_ori(ori_minH);\n    add_ori(ori_minW);\n    vector<double> lambdas = {0.7, 0.85, 1.0, 1.15, 1.3};\n    for (double lam : lambdas) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            o[i] = ((double)w_obs[i] > lam * (double)h_obs[i]) ? 1 : 0;\n        }\n        add_ori(o);\n    }\n    // orientation adapted to width limits\n    vector<long long> w_cands_base = build_width_candidates_base(w_obs, h_obs);\n    for (long long Wlim : w_cands_base) {\n        vector<int> o(N);\n        for (int i = 0; i < N; i++) {\n            bool fit0 = w_obs[i] <= Wlim;\n            bool fitR = h_obs[i] <= Wlim;\n            if (fit0 && fitR) {\n                o[i] = (h_obs[i] > w_obs[i]) ? 1 : 0;\n            } else if (fit0) {\n                o[i] = 0;\n            } else if (fitR) {\n                o[i] = 1;\n            } else {\n                o[i] = 0;\n            }\n        }\n        add_ori(o);\n    }\n\n    // exclusion sets\n    vector<vector<int>> excl_sets;\n    auto add_excl = [&](const vector<int>& ex) {\n        vector<int> v = ex;\n        sort(v.begin(), v.end());\n        v.erase(unique(v.begin(), v.end()), v.end());\n        for (auto &e : excl_sets) if (e == v) return;\n        excl_sets.push_back(v);\n    };\n    excl_sets.push_back({});\n    vector<int> idx_wh(N), idx_max(N);\n    iota(idx_wh.begin(), idx_wh.end(), 0);\n    iota(idx_max.begin(), idx_max.end(), 0);\n    sort(idx_wh.begin(), idx_wh.end(), [&](int a, int b) {\n        return (w_obs[a] + h_obs[a]) > (w_obs[b] + h_obs[b]);\n    });\n    sort(idx_max.begin(), idx_max.end(), [&](int a, int b) {\n        return max(w_obs[a], h_obs[a]) > max(w_obs[b], h_obs[b]);\n    });\n    if (!idx_wh.empty()) add_excl({idx_wh[0]});\n    if ((int)idx_wh.size() >= 2) add_excl({idx_wh[0], idx_wh[1]});\n    if ((int)idx_wh.size() >= 3) add_excl({idx_wh[0], idx_wh[1], idx_wh[2]});\n    if (!idx_max.empty()) add_excl({idx_max[0]});\n    if ((int)idx_max.size() >= 2) add_excl({idx_max[0], idx_max[1]});\n    if ((int)idx_max.size() >= 3) add_excl({idx_max[0], idx_max[1], idx_max[2]});\n    if (!idx_wh.empty() && !idx_max.empty()) add_excl({idx_wh[0], idx_max[0]});\n\n    vector<long long> margins = {0};\n    vector<Candidate> candidates;\n\n    for (auto &r_choice : orientations) {\n        for (auto &excl : excl_sets) {\n            vector<char> excluded(N, 0);\n            long long sumExcl = 0;\n            for (int idx : excl) {\n                if (idx >= 0 && idx < N) {\n                    excluded[idx] = 1;\n                    sumExcl += w_obs[idx] + h_obs[idx];\n                }\n            }\n            vector<int> active;\n            active.reserve(N);\n            for (int i = 0; i < N; i++) if (!excluded[i]) active.push_back(i);\n            int M = (int)active.size();\n            if (M == 0) {\n                Candidate cand;\n                cand.cmds.clear();\n                cand.estScore = sumExcl;\n                candidates.push_back(cand);\n                continue;\n            }\n            vector<long long> w_rot(M), h_rot(M);\n            long long sumW = 0, maxW = 0;\n            long long sumH = 0, maxH = 0;\n            long double area = 0;\n            for (int k = 0; k < M; k++) {\n                int i = active[k];\n                long long w = (r_choice[i] == 0 ? w_obs[i] : h_obs[i]);\n                long long h = (r_choice[i] == 0 ? h_obs[i] : w_obs[i]);\n                w_rot[k] = w; h_rot[k] = h;\n                sumW += w; sumH += h;\n                maxW = max(maxW, w);\n                maxH = max(maxH, h);\n                area += (long double)w * (long double)h;\n            }\n            long long sqrtA = (long long)(sqrt(area) + 0.5);\n            vector<long long> Wlims = build_limits(sumW, maxW, sqrtA, M);\n            vector<long long> Hlims = build_limits(sumH, maxH, sqrtA, M);\n\n            // row packings\n            for (long long margin : margins) {\n                vector<long long> h_eff(M);\n                for (int i = 0; i < M; i++) h_eff[i] = h_rot[i] + margin;\n                for (long long Wlim : Wlims) {\n                    if (Wlim < maxW) continue;\n                    vector<int> prv = dp_partition(w_rot, h_eff, Wlim);\n                    if (prv.empty()) continue;\n                    vector<pair<int,int>> rows = reconstruct_rows(prv);\n                    if (rows.empty()) continue;\n                    vector<int> ref_idx(rows.size());\n                    for (size_t ri = 0; ri < rows.size(); ri++) {\n                        int l = rows[ri].first;\n                        int r = rows[ri].second;\n                        long long besth = -1;\n                        int pos = l;\n                        for (int i = l; i < r; i++) {\n                            if (h_eff[i] > besth || (h_eff[i] == besth && i > pos)) {\n                                besth = h_eff[i];\n                                pos = i;\n                            }\n                        }\n                        ref_idx[ri] = active[pos];\n                    }\n                    vector<Command> cmds;\n                    cmds.reserve(M);\n                    for (size_t ri = 0; ri < rows.size(); ri++) {\n                        int b = (ri == 0) ? -1 : ref_idx[ri - 1];\n                        int l = rows[ri].first;\n                        int r = rows[ri].second;\n                        for (int i = l; i < r; i++) {\n                            int idx = active[i];\n                            cmds.push_back({idx, r_choice[idx], 'L', b});\n                        }\n                    }\n                    auto est = simulate(cmds, w_obs, h_obs);\n                    Candidate cand;\n                    cand.cmds = move(cmds);\n                    cand.estScore = est.first + est.second + sumExcl;\n                    candidates.push_back(move(cand));\n                }\n            }\n\n            // column packings\n            for (long long margin : margins) {\n                vector<long long> w_eff(M);\n                for (int i = 0; i < M; i++) w_eff[i] = w_rot[i] + margin;\n                for (long long Hlim : Hlims) {\n                    if (Hlim < maxH) continue;\n                    vector<int> prv = dp_partition(h_rot, w_eff, Hlim); // widths=h_rot, heights=w_rot+margin\n                    if (prv.empty()) continue;\n                    vector<pair<int,int>> cols = reconstruct_rows(prv);\n                    if (cols.empty()) continue;\n                    vector<int> ref_idx(cols.size());\n                    for (size_t ci = 0; ci < cols.size(); ci++) {\n                        int l = cols[ci].first;\n                        int r = cols[ci].second;\n                        long long bestw = -1;\n                        int pos = l;\n                        for (int i = l; i < r; i++) {\n                            if (w_rot[i] > bestw || (w_rot[i] == bestw && i > pos)) {\n                                bestw = w_rot[i];\n                                pos = i;\n                            }\n                        }\n                        ref_idx[ci] = active[pos];\n                    }\n                    vector<Command> cmds;\n                    cmds.reserve(M);\n                    for (size_t ci = 0; ci < cols.size(); ci++) {\n                        int b = (ci == 0) ? -1 : ref_idx[ci - 1];\n                        int l = cols[ci].first;\n                        int r = cols[ci].second;\n                        for (int i = l; i < r; i++) {\n                            int idx = active[i];\n                            cmds.push_back({idx, r_choice[idx], 'U', b});\n                        }\n                    }\n                    auto est = simulate(cmds, w_obs, h_obs);\n                    Candidate cand;\n                    cand.cmds = move(cmds);\n                    cand.estScore = est.first + est.second + sumExcl;\n                    candidates.push_back(move(cand));\n                }\n            }\n        }\n    }\n\n    if (candidates.empty()) {\n        vector<Command> cmds;\n        for (int i = 0; i < N; i++) cmds.push_back({i, 0, 'L', -1});\n        auto est = simulate(cmds, w_obs, h_obs);\n        candidates.push_back({cmds, est.first + est.second});\n    }\n\n    sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n        return a.estScore < b.estScore;\n    });\n\n    int outCnt = min((int)candidates.size(), T);\n    vector<vector<Command>> outputs;\n    for (int i = 0; i < outCnt; i++) outputs.push_back(candidates[i].cmds);\n    while ((int)outputs.size() < T) outputs.push_back(outputs[0]);\n\n    for (int t = 0; t < T; t++) {\n        const auto& cmds = outputs[t];\n        cout << cmds.size() << \"\\n\";\n        for (auto &cmd : cmds) {\n            cout << cmd.p << \" \" << cmd.r << \" \" << cmd.d << \" \" << cmd.b << \"\\n\";\n        }\n        cout.flush();\n        long long Wm, Hm;\n        if (!(cin >> Wm >> Hm)) break;\n        // ignoring measurement feedback in this heuristic\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solution {\n    vector<int> parent;\n    long long score;\n};\n\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n\n    auto start_time = chrono::steady_clock::now();\n    auto elapsed_ms = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(\n                   chrono::steady_clock::now() - start_time)\n            .count();\n    };\n    const long long TIME_LIMIT = 1950; // ms\n\n    mt19937 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    // Precompute all-pairs shortest distances\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    queue<int> q;\n    for (int s = 0; s < N; s++) {\n        auto &drow = dist[s];\n        drow[s] = 0;\n        q.push(s);\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            int nd = drow[u] + 1;\n            for (int v : adj[u]) {\n                if (drow[v] == INF) {\n                    drow[v] = nd;\n                    q.push(v);\n                }\n            }\n        }\n    }\n\n    // Eccentricity\n    vector<int> ecc(N, 0);\n    for (int i = 0; i < N; i++) {\n        int mx = 0;\n        for (int j = 0; j < N; j++) {\n            if (dist[i][j] > mx) mx = dist[i][j];\n        }\n        ecc[i] = mx;\n    }\n\n    // Neighbor ordering\n    vector<vector<int>> adj_desc(N), adj_asc(N), adj_rand(N);\n    for (int u = 0; u < N; u++) {\n        adj_desc[u] = adj[u];\n        sort(adj_desc[u].begin(), adj_desc[u].end(), [&](int a, int b) {\n            if (A[a] != A[b]) return A[a] > A[b];\n            return a < b;\n        });\n        adj_asc[u] = adj[u];\n        sort(adj_asc[u].begin(), adj_asc[u].end(), [&](int a, int b) {\n            if (A[a] != A[b]) return A[a] < A[b];\n            return a < b;\n        });\n        adj_rand[u] = adj[u];\n        shuffle(adj_rand[u].begin(), adj_rand[u].end(), rng);\n    }\n\n    // Seeds\n    vector<int> seeds;\n    vector<char> seen_seed(N, 0);\n    auto add_seed = [&](int v) {\n        if (!seen_seed[v]) {\n            seen_seed[v] = 1;\n            seeds.push_back(v);\n        }\n    };\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        if (A[i] != A[j]) return A[i] < A[j];\n        return i < j;\n    });\n    int kLow = min(30, N);\n    for (int i = 0; i < kLow; i++) add_seed(idx[i]);\n\n    int cen = 0;\n    for (int i = 1; i < N; i++) {\n        if (ecc[i] < ecc[cen] || (ecc[i] == ecc[cen] && A[i] < A[cen]))\n            cen = i;\n    }\n    add_seed(cen);\n\n    long long bestd = (long long)(x[0] - 500) * (x[0] - 500) +\n                      (long long)(y[0] - 500) * (y[0] - 500);\n    int centerCoord = 0;\n    for (int i = 1; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d < bestd) {\n            bestd = d;\n            centerCoord = i;\n        }\n    }\n    add_seed(centerCoord);\n\n    long long maxd = bestd;\n    int farCoord = centerCoord;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)(x[i] - 500) * (x[i] - 500) +\n                      (long long)(y[i] - 500) * (y[i] - 500);\n        if (d > maxd) {\n            maxd = d;\n            farCoord = i;\n        }\n    }\n    add_seed(farCoord);\n\n    uniform_int_distribution<int> uid(0, N - 1);\n    for (int i = 0; i < 25; i++) add_seed(uid(rng));\n\n    auto prune_roots = [&](vector<int> &roots) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int idx_r = 0; idx_r < (int)roots.size(); idx_r++) {\n                vector<int> tmp(N, INF);\n                for (int j = 0; j < (int)roots.size(); j++) {\n                    if (j == idx_r) continue;\n                    int r = roots[j];\n                    for (int i = 0; i < N; i++) {\n                        int d = dist[r][i];\n                        if (d < tmp[i]) tmp[i] = d;\n                    }\n                }\n                int mx = *max_element(tmp.begin(), tmp.end());\n                if (mx <= H) {\n                    roots.erase(roots.begin() + idx_r);\n                    changed = true;\n                    break;\n                }\n            }\n        }\n    };\n\n    auto select_roots_farthest = [&](int seed) {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> minDist = dist[seed];\n        while (true) {\n            int farNode = -1, farDist = -1, farA = 1e9;\n            for (int i = 0; i < N; i++) {\n                if (minDist[i] > farDist ||\n                    (minDist[i] == farDist && A[i] < farA)) {\n                    farDist = minDist[i];\n                    farNode = i;\n                    farA = A[i];\n                }\n            }\n            if (farDist <= H) break;\n            roots.push_back(farNode);\n            for (int i = 0; i < N; i++) {\n                int d = dist[farNode][i];\n                if (d < minDist[i]) minDist[i] = d;\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_cover_greedy = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        while (remaining > 0) {\n            int best = -1, bestCnt = -1, bestA = 1e9;\n            for (int c = 0; c < N; c++) {\n                int cnt = 0;\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[c][i] <= H) cnt++;\n                }\n                if (cnt > bestCnt || (cnt == bestCnt && A[c] < bestA)) {\n                    bestCnt = cnt;\n                    best = c;\n                    bestA = A[c];\n                }\n            }\n            if (best == -1) break;\n            roots.push_back(best);\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[best][i] <= H) {\n                    covered[i] = 1;\n                    remaining--;\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto select_roots_lowA_cover = [&]() {\n        vector<int> roots;\n        vector<char> covered(N, 0);\n        int remaining = N;\n        for (int v : idx) {\n            if (remaining == 0) break;\n            bool useful = false;\n            for (int i = 0; i < N; i++) {\n                if (!covered[i] && dist[v][i] <= H) {\n                    useful = true;\n                    break;\n                }\n            }\n            if (useful) {\n                roots.push_back(v);\n                for (int i = 0; i < N; i++) {\n                    if (!covered[i] && dist[v][i] <= H) {\n                        covered[i] = 1;\n                        remaining--;\n                    }\n                }\n            }\n        }\n        prune_roots(roots);\n        return roots;\n    };\n\n    auto finalize_and_score = [&](vector<int> parent) -> Solution {\n        vector<vector<int>> children(N);\n        vector<int> depth(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        for (int v = 0; v < N; v++) {\n            if (depth[v] == -1 || depth[v] > H) parent[v] = -1;\n        }\n        // recompute depths after fixing\n        children.assign(N, {});\n        depth.assign(N, -1);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0) d = 0;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    auto leaf_reparent = [&](vector<int> &parent, vector<int> &depth) {\n        vector<int> childCnt(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) childCnt[parent[v]]++;\n        }\n        bool changed = true;\n        int iter = 0;\n        while (changed && iter < H * 2 + 5) {\n            changed = false;\n            iter++;\n            for (int v = 0; v < N; v++) {\n                if (childCnt[v] == 0) {\n                    int bestDepth = depth[v];\n                    int bestPar = -1;\n                    for (int u : adj[v]) {\n                        int nd = depth[u] + 1;\n                        if (nd <= H && nd > bestDepth) {\n                            bestDepth = nd;\n                            bestPar = u;\n                        }\n                    }\n                    if (bestPar != -1 && parent[v] != bestPar) {\n                        int oldp = parent[v];\n                        if (oldp != -1) childCnt[oldp]--;\n                        parent[v] = bestPar;\n                        childCnt[bestPar]++;\n                        depth[v] = bestDepth;\n                        changed = true;\n                    }\n                }\n            }\n        }\n    };\n\n    auto build_solution = [&](const vector<int> &roots, int orderMode,\n                              int neighborMode) -> Solution {\n        const vector<vector<int>> *adj_used;\n        if (neighborMode == 0)\n            adj_used = &adj_desc;\n        else if (neighborMode == 1)\n            adj_used = &adj_asc;\n        else\n            adj_used = &adj_rand;\n        vector<int> parent(N, -2), depth(N, INF);\n        vector<char> visited(N, 0);\n        vector<int> root_order = roots;\n        if (orderMode == 0) {\n            sort(root_order.begin(), root_order.end(),\n                 [&](int a, int b) { return A[a] < A[b]; });\n        } else {\n            shuffle(root_order.begin(), root_order.end(), rng);\n        }\n        for (int r : root_order) {\n            if (visited[r]) continue;\n            parent[r] = -1;\n            depth[r] = 0;\n            visited[r] = 1;\n            vector<pair<int, int>> st;\n            st.reserve(N);\n            st.push_back({r, 0});\n            while (!st.empty()) {\n                int u = st.back().first;\n                int &idxn = st.back().second;\n                if (depth[u] == H) {\n                    st.pop_back();\n                    continue;\n                }\n                if (idxn >= (int)(*adj_used)[u].size()) {\n                    st.pop_back();\n                    continue;\n                }\n                int v = (*adj_used)[u][idxn++];\n                if (visited[v]) continue;\n                parent[v] = u;\n                depth[v] = depth[u] + 1;\n                visited[v] = 1;\n                st.push_back({v, 0});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            if (!visited[i]) {\n                parent[i] = -1;\n                depth[i] = 0;\n                visited[i] = 1;\n                vector<pair<int, int>> st;\n                st.reserve(N);\n                st.push_back({i, 0});\n                while (!st.empty()) {\n                    int u = st.back().first;\n                    int &idxn = st.back().second;\n                    if (depth[u] == H) {\n                        st.pop_back();\n                        continue;\n                    }\n                    if (idxn >= (int)(*adj_used)[u].size()) {\n                        st.pop_back();\n                        continue;\n                    }\n                    int v = (*adj_used)[u][idxn++];\n                    if (visited[v]) continue;\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    visited[v] = 1;\n                    st.push_back({v, 0});\n                }\n            }\n        }\n        leaf_reparent(parent, depth);\n        return finalize_and_score(parent);\n    };\n\n    auto build_growth = [&](int seedCount) -> Solution {\n        vector<int> parent(N, -1), depth(N, -1);\n        vector<char> done(N, 0);\n        int processed = 0;\n        for (int i = 0; i < seedCount && i < N; i++) {\n            int v = idx[i];\n            if (!done[v]) {\n                done[v] = 1;\n                parent[v] = -1;\n                depth[v] = 0;\n                processed++;\n            }\n        }\n        while (processed < N) {\n            bool progress = false;\n            for (int v = 0; v < N; v++) {\n                if (done[v]) continue;\n                int bestPar = -1, bestDepth = -1, bestA = 1e9;\n                for (int u : adj_desc[v]) {\n                    if (!done[u]) continue;\n                    int nd = depth[u] + 1;\n                    if (nd > H) continue;\n                    if (nd > bestDepth || (nd == bestDepth && A[u] < bestA)) {\n                        bestDepth = nd;\n                        bestPar = u;\n                        bestA = A[u];\n                    }\n                }\n                if (bestPar != -1) {\n                    parent[v] = bestPar;\n                    depth[v] = bestDepth;\n                    done[v] = 1;\n                    processed++;\n                    progress = true;\n                }\n            }\n            if (!progress) {\n                int nr = -1, minA = 1e9;\n                for (int v = 0; v < N; v++) {\n                    if (!done[v] && A[v] < minA) {\n                        minA = A[v];\n                        nr = v;\n                    }\n                }\n                if (nr == -1) break;\n                done[nr] = 1;\n                parent[nr] = -1;\n                depth[nr] = 0;\n                processed++;\n            }\n        }\n        leaf_reparent(parent, depth);\n        return finalize_and_score(parent);\n    };\n\n    auto hill_climb = [&](Solution sol) -> Solution {\n        vector<int> &parent = sol.parent;\n        vector<int> depth(N, -1);\n        long long curScore = sol.score;\n        while (true) {\n            if (elapsed_ms() > TIME_LIMIT - 50) break;\n            // build children and depth\n            vector<vector<int>> children(N);\n            for (int v = 0; v < N; v++) {\n                int p = parent[v];\n                if (p >= 0) children[p].push_back(v);\n            }\n            fill(depth.begin(), depth.end(), -1);\n            queue<int> qq;\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) {\n                    depth[v] = 0;\n                    qq.push(v);\n                }\n            }\n            while (!qq.empty()) {\n                int u = qq.front();\n                qq.pop();\n                for (int c : children[u]) {\n                    depth[c] = depth[u] + 1;\n                    qq.push(c);\n                }\n            }\n            // tin/tout\n            vector<int> tin(N, 0), tout(N, 0);\n            int timer = 0;\n            function<void(int)> dfs = [&](int u) {\n                tin[u] = timer++;\n                for (int c : children[u]) dfs(c);\n                tout[u] = timer;\n            };\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) dfs(v);\n            }\n            // order for postorder\n            vector<int> order;\n            order.reserve(N);\n            function<void(int)> dfs2 = [&](int u) {\n                order.push_back(u);\n                for (int c : children[u]) dfs2(c);\n            };\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) dfs2(v);\n            }\n            vector<long long> subSumA(N, 0);\n            vector<int> subMaxDepth(N, 0);\n            for (int i = (int)order.size() - 1; i >= 0; i--) {\n                int v = order[i];\n                long long sum = A[v];\n                int mx = depth[v];\n                for (int c : children[v]) {\n                    sum += subSumA[c];\n                    if (subMaxDepth[c] > mx) mx = subMaxDepth[c];\n                }\n                subSumA[v] = sum;\n                subMaxDepth[v] = mx;\n            }\n\n            long long bestGain = 0;\n            int bestV = -1, bestU = -1, bestDelta = 0;\n            for (int v = 0; v < N; v++) {\n                for (int u : adj[v]) {\n                    if (tin[v] <= tin[u] && tout[u] <= tout[v]) continue; // u in subtree\n                    int delta = depth[u] + 1 - depth[v];\n                    if (delta <= 0) continue;\n                    if (subMaxDepth[v] + delta > H) continue;\n                    long long gain = 1LL * delta * subSumA[v];\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestV = v;\n                        bestU = u;\n                        bestDelta = delta;\n                    }\n                }\n            }\n            if (bestGain <= 0) break;\n            int v = bestV, u = bestU, delta = bestDelta;\n            parent[v] = u;\n            // update depths of subtree v\n            vector<int> st;\n            st.push_back(v);\n            while (!st.empty()) {\n                int w = st.back();\n                st.pop_back();\n                depth[w] += delta;\n                for (int c : children[w]) st.push_back(c);\n            }\n            curScore += bestGain;\n        }\n        // recompute score safely\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++) {\n            int p = parent[v];\n            if (p >= 0) children[p].push_back(v);\n        }\n        fill(depth.begin(), depth.end(), -1);\n        queue<int> qq;\n        for (int v = 0; v < N; v++) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                qq.push(v);\n            }\n        }\n        while (!qq.empty()) {\n            int u = qq.front();\n            qq.pop();\n            for (int c : children[u]) {\n                depth[c] = depth[u] + 1;\n                qq.push(c);\n            }\n        }\n        long long score = 0;\n        for (int v = 0; v < N; v++) {\n            int d = depth[v];\n            if (d < 0 || d > H) d = 0;\n            score += 1LL * (d + 1) * A[v];\n        }\n        return Solution{parent, score};\n    };\n\n    vector<vector<int>> rootSets;\n    rootSets.reserve(seeds.size() + 3);\n    for (int sd : seeds) {\n        rootSets.push_back(select_roots_farthest(sd));\n    }\n    rootSets.push_back(select_roots_cover_greedy());\n    rootSets.push_back(select_roots_lowA_cover());\n\n    vector<Solution> candidates;\n    candidates.reserve(rootSets.size() * 4 + 6);\n    for (const auto &roots : rootSets) {\n        if (elapsed_ms() > TIME_LIMIT - 400) break;\n        candidates.push_back(build_solution(roots, 0, 0));\n        candidates.push_back(build_solution(roots, 0, 1));\n        candidates.push_back(build_solution(roots, 1, 0));\n        candidates.push_back(build_solution(roots, 1, 1));\n    }\n    // growth-based\n    candidates.push_back(build_growth(5));\n    candidates.push_back(build_growth(10));\n    candidates.push_back(build_growth(20));\n\n    sort(candidates.begin(), candidates.end(),\n         [](const Solution &a, const Solution &b) {\n             return a.score > b.score;\n         });\n    int topK = min<int>(12, candidates.size());\n\n    long long bestScore = -1;\n    vector<int> bestParent(N, -1);\n    for (int i = 0; i < topK; i++) {\n        if (elapsed_ms() > TIME_LIMIT - 50) break;\n        Solution imp = hill_climb(candidates[i]);\n        if (imp.score > bestScore) {\n            bestScore = imp.score;\n            bestParent = imp.parent;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option {\n    int line; // 0..4N-1\n    int len;  // 1..N\n};\n\nstruct Solver {\n    static const int N = 20;\n    vector<string> board;\n    vector<int> upLim, downLim, leftLim, rightLim;\n    vector<pair<int,int>> oni;               // positions of oni\n    vector<vector<Option>> opts;             // options for each oni\n    int M;                                   // #oni\n\n    // state\n    vector<array<int, N+1>> cnt; // cnt[line][len]\n    vector<int> maxLen;          // max len per line\n    vector<int> assign;          // chosen option index per oni\n    long cost;                   // 2 * sum(maxLen)\n\n    mt19937 rng;\n\n    Solver(const vector<string>& g): board(g) {\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n        compute_limits();\n        collect_oni();\n        build_options();\n    }\n\n    void compute_limits() {\n        upLim.assign(N, N);\n        downLim.assign(N, N);\n        leftLim.assign(N, N);\n        rightLim.assign(N, N);\n        // columns\n        for (int j = 0; j < N; j++) {\n            for (int i = 0; i < N; i++) {\n                if (board[i][j] == 'o') { upLim[j] = i; break; }\n            }\n            for (int i = N-1; i >= 0; i--) {\n                if (board[i][j] == 'o') { downLim[j] = N-1 - i; break; }\n            }\n        }\n        // rows\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'o') { leftLim[i] = j; break; }\n            }\n            for (int j = N-1; j >= 0; j--) {\n                if (board[i][j] == 'o') { rightLim[i] = N-1 - j; break; }\n            }\n        }\n    }\n\n    void collect_oni() {\n        oni.clear();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') oni.emplace_back(i,j);\n            }\n        }\n        M = (int)oni.size();\n    }\n\n    void build_options() {\n        opts.assign(M, {});\n        for (int idx = 0; idx < M; idx++) {\n            auto [r,c] = oni[idx];\n            // Up\n            if (r+1 <= upLim[c]) {\n                opts[idx].push_back({c, r+1});\n            }\n            // Down\n            if (N - r <= downLim[c]) {\n                opts[idx].push_back({N + c, N - r});\n            }\n            // Left\n            if (c+1 <= leftLim[r]) {\n                opts[idx].push_back({2*N + r, c+1});\n            }\n            // Right\n            if (N - c <= rightLim[r]) {\n                opts[idx].push_back({3*N + r, N - c});\n            }\n            if (opts[idx].empty()) {\n                // Should not happen\n                opts[idx].push_back({c, r+1}); // dummy\n            }\n        }\n    }\n\n    void rebuild_from_assign() {\n        cnt.assign(4*N, {});\n        maxLen.assign(4*N, 0);\n        cost = 0;\n        for (int i = 0; i < M; i++) {\n            int optIdx = assign[i];\n            const Option &op = opts[i][optIdx];\n            cnt[op.line][op.len] ++;\n            if (op.len > maxLen[op.line]) maxLen[op.line] = op.len;\n        }\n        for (int l = 0; l < 4*N; l++) {\n            cost += 2LL * maxLen[l];\n        }\n    }\n\n    // helpers for delta computation\n    int newMaxAfterRemoval(int line, int len) const {\n        int oldMax = maxLen[line];\n        if (len < oldMax) return oldMax;\n        if (cnt[line][len] >= 2) return oldMax;\n        // len == oldMax and will be removed\n        for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) return l;\n        return 0;\n    }\n\n    int computeDelta(int i, int newOpt) const {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return 0;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        if (cur.line == nxt.line) {\n            int line = cur.line;\n            int oldMax = maxLen[line];\n            int newMax = oldMax;\n            if (cur.len == oldMax && cnt[line][cur.len] == 1) {\n                newMax = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[line][l] > 0) {newMax=l; break;}\n            }\n            if (nxt.len > newMax) newMax = nxt.len;\n            return 2 * (newMax - oldMax);\n        } else {\n            int oldMaxA = maxLen[cur.line];\n            int oldMaxB = maxLen[nxt.line];\n            int newMaxA = oldMaxA;\n            if (cur.len == oldMaxA && cnt[cur.line][cur.len] == 1) {\n                newMaxA = 0;\n                for (int l = cur.len-1; l >= 1; --l) if (cnt[cur.line][l] > 0) {newMaxA=l; break;}\n            }\n            int newMaxB = (nxt.len > oldMaxB) ? nxt.len : oldMaxB;\n            return 2 * ((newMaxA - oldMaxA) + (newMaxB - oldMaxB));\n        }\n    }\n\n    void remove_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]--;\n        if (len == oldMax && cnt[line][len] == 0) {\n            int m = 0;\n            for (int l = len-1; l >= 1; --l) if (cnt[line][l] > 0) {m = l; break;}\n            maxLen[line] = m;\n        }\n        cost += 2LL * maxLen[line];\n    }\n\n    void add_assignment(int line, int len) {\n        int oldMax = maxLen[line];\n        cost -= 2LL * oldMax;\n        cnt[line][len]++;\n        if (len > oldMax) maxLen[line] = len;\n        cost += 2LL * maxLen[line];\n    }\n\n    void applyMove(int i, int newOpt) {\n        int curOpt = assign[i];\n        if (curOpt == newOpt) return;\n        const Option &cur = opts[i][curOpt];\n        const Option &nxt = opts[i][newOpt];\n        remove_assignment(cur.line, cur.len);\n        add_assignment(nxt.line, nxt.len);\n        assign[i] = newOpt;\n    }\n\n    void hillClimb() {\n        while (true) {\n            int bestDelta = 0;\n            int bestI = -1;\n            int bestOpt = -1;\n            for (int i = 0; i < M; i++) {\n                int curOpt = assign[i];\n                for (int k = 0; k < (int)opts[i].size(); k++) {\n                    if (k == curOpt) continue;\n                    int delta = computeDelta(i, k);\n                    if (delta < bestDelta) {\n                        bestDelta = delta;\n                        bestI = i;\n                        bestOpt = k;\n                    }\n                }\n            }\n            if (bestDelta < 0) {\n                applyMove(bestI, bestOpt);\n            } else break;\n        }\n    }\n\n    void simulatedAnnealing(int ITER, double T0, double T1) {\n        vector<int> bestAssignLocal = assign;\n        long bestCostLocal = cost;\n        uniform_real_distribution<double> dist01(0.0, 1.0);\n        for (int it = 0; it < ITER; it++) {\n            double T = T0 + (T1 - T0) * (double)it / (double)ITER;\n            int i = rng() % M;\n            if (opts[i].size() <= 1) continue;\n            int newOpt = rng() % opts[i].size();\n            if (newOpt == assign[i]) continue;\n            int delta = computeDelta(i, newOpt);\n            if (delta <= 0 || exp(-delta / T) > dist01(rng)) {\n                applyMove(i, newOpt);\n                if (cost < bestCostLocal) {\n                    bestCostLocal = cost;\n                    bestAssignLocal = assign;\n                }\n            }\n        }\n        assign = bestAssignLocal;\n        rebuild_from_assign();\n    }\n\n    // Large neighborhood search: reassign a subset exhaustively\n    bool lns_once(int k) {\n        if (M == 0) return false;\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        // sort by current required length descending\n        sort(idx.begin(), idx.end(), [&](int a, int b){\n            int lena = opts[a][assign[a]].len;\n            int lenb = opts[b][assign[b]].len;\n            return lena > lenb;\n        });\n        int candSize = min(M, 10);\n        if (candSize < k) k = candSize;\n        if (k == 0) return false;\n        // choose first candSize then shuffle\n        vector<int> cands(idx.begin(), idx.begin() + candSize);\n        shuffle(cands.begin(), cands.end(), rng);\n        vector<int> subset(cands.begin(), cands.begin() + k);\n\n        vector<int> backupAssign = assign;\n        long originalCost = cost;\n\n        // remove subset assignments\n        for (int id : subset) {\n            const Option &op = opts[id][assign[id]];\n            remove_assignment(op.line, op.len);\n            assign[id] = -1;\n        }\n        long baseCost = cost;\n\n        vector<int> bestChoices(k, 0);\n        long bestCost = (1LL<<60);\n\n        function<void(int)> dfs = [&](int depth){\n            if (depth == k) {\n                if (cost < bestCost) {\n                    bestCost = cost;\n                    for (int t = 0; t < k; t++) {\n                        bestChoices[t] = assign[subset[t]];\n                    }\n                }\n                return;\n            }\n            int oniId = subset[depth];\n            for (int optIdx = 0; optIdx < (int)opts[oniId].size(); optIdx++) {\n                const Option &op = opts[oniId][optIdx];\n                add_assignment(op.line, op.len);\n                assign[oniId] = optIdx;\n                dfs(depth+1);\n                remove_assignment(op.line, op.len);\n                assign[oniId] = -1;\n            }\n        };\n        dfs(0);\n\n        // restore assignment based on result\n        if (bestCost < originalCost) {\n            assign = backupAssign;\n            for (int t = 0; t < k; t++) {\n                assign[subset[t]] = bestChoices[t];\n            }\n            rebuild_from_assign();\n            return true;\n        } else {\n            assign = backupAssign;\n            rebuild_from_assign();\n            return false;\n        }\n    }\n\n    void solve() {\n        int NUM_SEEDS = 8;\n        int SA_ITER = 40000;\n        double T0 = 5.0, T1 = 0.1;\n        int LNS_TRIES = 60;\n        int LNS_K = 5;\n\n        long globalBestCost = (1LL<<60);\n        vector<int> globalBestAssign;\n        vector<int> globalBestMaxLen;\n\n        uniform_int_distribution<int> seedDist(0, 1e9);\n\n        for (int seed = 0; seed < NUM_SEEDS; seed++) {\n            // initial assignment\n            assign.assign(M, 0);\n            for (int i = 0; i < M; i++) {\n                if (seed == 0) {\n                    // choose minimal len (tie random)\n                    int bestLen = 1e9;\n                    vector<int> cand;\n                    for (int k = 0; k < (int)opts[i].size(); k++) {\n                        int len = opts[i][k].len;\n                        if (len < bestLen) {\n                            bestLen = len;\n                            cand.clear();\n                            cand.push_back(k);\n                        } else if (len == bestLen) {\n                            cand.push_back(k);\n                        }\n                    }\n                    assign[i] = cand[rng() % cand.size()];\n                } else {\n                    assign[i] = rng() % opts[i].size();\n                }\n            }\n            rebuild_from_assign();\n            hillClimb();\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n\n            simulatedAnnealing(SA_ITER, T0, T1);\n            hillClimb();\n\n            bool improved = true;\n            int tries = 0;\n            while (improved && tries < LNS_TRIES) {\n                improved = lns_once(LNS_K);\n                tries++;\n            }\n\n            if (cost < globalBestCost) {\n                globalBestCost = cost;\n                globalBestAssign = assign;\n                globalBestMaxLen = maxLen;\n            }\n        }\n\n        // use global best\n        assign = globalBestAssign;\n        maxLen = globalBestMaxLen;\n        // output operations\n        vector<pair<char,int>> ops;\n        auto add_ops = [&](char dir, int idx, int len){\n            for (int k = 0; k < len; k++) ops.emplace_back(dir, idx);\n        };\n        // Up then Down for up lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[j];\n            if (len > 0) {\n                add_ops('U', j, len);\n                add_ops('D', j, len);\n            }\n        }\n        // Down then Up for down lengths\n        for (int j = 0; j < N; j++) {\n            int len = maxLen[N + j];\n            if (len > 0) {\n                add_ops('D', j, len);\n                add_ops('U', j, len);\n            }\n        }\n        // Left then Right\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[2*N + i];\n            if (len > 0) {\n                add_ops('L', i, len);\n                add_ops('R', i, len);\n            }\n        }\n        // Right then Left\n        for (int i = 0; i < N; i++) {\n            int len = maxLen[3*N + i];\n            if (len > 0) {\n                add_ops('R', i, len);\n                add_ops('L', i, len);\n            }\n        }\n\n        for (auto &op : ops) {\n            cout << op.first << \" \" << op.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n;\n    if (!(cin >> n)) return 0;\n    vector<string> g(n);\n    for (int i = 0; i < n; i++) cin >> g[i];\n    Solver solver(g);\n    solver.solve();\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct XorShift {\n    using result_type = uint64_t;\n    uint64_t x;\n    XorShift(uint64_t seed = 88172645463325252ull) : x(seed) {}\n    static constexpr result_type min() { return 0; }\n    static constexpr result_type max() { return UINT64_MAX; }\n    result_type operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint64_t next() { return (*this)(); }\n    int next_int(int l, int r) { return l + (int)(next() % (uint64_t)(r - l + 1)); }\n} rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n\nint N, Ltot;\nvector<int> T;\nvector<double> pi;\nvector<long long> prefixT;\n\nint rand_by_target() {\n    uint64_t r = rng.next() % (uint64_t)Ltot;\n    int idx = int(lower_bound(prefixT.begin(), prefixT.end(), (long long)r + 1) - prefixT.begin());\n    if (idx >= N) idx = N - 1;\n    return idx;\n}\n\nvoid enforce_indegree(vector<int>& a, vector<int>& b) {\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < N; i++) {\n        indeg[a[i]]++;\n        indeg[b[i]]++;\n    }\n    for (int j = 0; j < N; j++) {\n        if (T[j] > 0 && indeg[j] == 0) {\n            int s = rng.next_int(0, N - 1);\n            if (rng.next_int(0, 1) == 0) {\n                indeg[a[s]]--;\n                a[s] = j;\n            } else {\n                indeg[b[s]]--;\n                b[s] = j;\n            }\n            indeg[j]++;\n        }\n    }\n}\n\nvoid compute_degrees(int minMode, const vector<double>& desired, vector<int>& deg) {\n    int edges = 2 * N;\n    deg.assign(N, 0);\n    int minSum = 0;\n    for (int i = 0; i < N; i++) {\n        int mv = 0;\n        if (minMode == 1) {\n            if (T[i] > 0) mv = 1;\n        } else if (minMode == 2) {\n            mv = 1;\n        }\n        deg[i] = mv;\n        minSum += mv;\n    }\n    int R = edges - minSum;\n    static double quota[105];\n    double qsum = 0.0;\n    for (int i = 0; i < N; i++) {\n        double q = desired[i] - deg[i];\n        if (q < 0) q = 0;\n        quota[i] = q;\n        qsum += q;\n    }\n    static pair<double, int> fr[105];\n    int sumDeg = minSum;\n    if (qsum > 1e-9) {\n        double scale = (double)R / qsum;\n        for (int i = 0; i < N; i++) {\n            double v = quota[i] * scale;\n            int add = (int)v;\n            deg[i] += add;\n            sumDeg += add;\n            fr[i] = make_pair(v - add, i);\n        }\n    } else {\n        for (int i = 0; i < N; i++) fr[i] = make_pair(0.0, i);\n    }\n    int leftover = edges - sumDeg;\n    for (int i = N - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(fr[i], fr[j]);\n    }\n    sort(fr, fr + N, [](const pair<double, int>& a, const pair<double, int>& b) {\n        return a.first > b.first;\n    });\n    for (int k = 0; k < leftover; k++) deg[fr[k].second]++;\n}\n\nvoid build_apportion(int minMode, const vector<double>& desired, vector<int>& a, vector<int>& b) {\n    vector<int> deg;\n    compute_degrees(minMode, desired, deg);\n    vector<int> slots;\n    slots.reserve(2 * N);\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < deg[i]; k++) slots.push_back(i);\n    }\n    while ((int)slots.size() < 2 * N) slots.push_back(rand_by_target());\n    while ((int)slots.size() > 2 * N) slots.pop_back();\n    for (int i = (int)slots.size() - 1; i > 0; --i) {\n        int j = rng.next() % (uint64_t)(i + 1);\n        swap(slots[i], slots[j]);\n    }\n    a.resize(N);\n    b.resize(N);\n    for (int i = 0; i < N; i++) {\n        a[i] = slots[2 * i];\n        b[i] = slots[2 * i + 1];\n    }\n    enforce_indegree(a, b);\n}\n\nvoid build_greedy(int variant, vector<int>& a, vector<int>& b) {\n    a.assign(N, -1);\n    b.assign(N, -1);\n    vector<double> r(N);\n    for (int j = 0; j < N; j++) r[j] = 2.0 * pi[j];\n    vector<int> order(2 * N);\n    for (int i = 0; i < N; i++) {\n        order[2 * i] = i;\n        order[2 * i + 1] = i;\n    }\n    if (variant == 0) {\n        sort(order.begin(), order.end(), [&](int i, int j) { return pi[i] > pi[j]; });\n    } else if (variant == 1) {\n        sort(order.begin(), order.end(), [&](int i, int j) { return pi[i] < pi[j]; });\n    } else {\n        for (int i = (int)order.size() - 1; i > 0; --i) {\n            int j = rng.next() % (uint64_t)(i + 1);\n            swap(order[i], order[j]);\n        }\n    }\n    for (int idx = 0; idx < (int)order.size(); idx++) {\n        int s = order[idx];\n        double w = pi[s];\n        int bestJ = 0;\n        if (variant == 2) {\n            double bestVal = 1e18;\n            for (int j = 0; j < N; j++) {\n                double v = fabs(r[j] - w);\n                if (v < bestVal) {\n                    bestVal = v;\n                    bestJ = j;\n                }\n            }\n        } else {\n            double bestVal = -1e18;\n            for (int j = 0; j < N; j++) {\n                if (r[j] > bestVal) {\n                    bestVal = r[j];\n                    bestJ = j;\n                }\n            }\n        }\n        r[bestJ] -= w;\n        if (a[s] == -1)\n            a[s] = bestJ;\n        else\n            b[s] = bestJ;\n    }\n    for (int i = 0; i < N; i++) if (b[i] == -1) b[i] = a[i];\n    enforce_indegree(a, b);\n}\n\ndouble approx_error(const vector<int>& a, const vector<int>& b, vector<double>* outCnt = nullptr) {\n    static double d0[105], d1[105];\n    double inv = 1.0 / N;\n    for (int i = 0; i < N; i++) d0[i] = inv;\n    double* cur = d0;\n    double* nxt = d1;\n    const int ITER = 28;\n    for (int it = 0; it < ITER; it++) {\n        for (int j = 0; j < N; j++) nxt[j] = 0.0;\n        for (int i = 0; i < N; i++) {\n            double v = cur[i];\n            int ai = a[i], bi = b[i];\n            if (ai == bi) {\n                nxt[ai] += v;\n            } else {\n                double h = 0.5 * v;\n                nxt[ai] += h;\n                nxt[bi] += h;\n            }\n        }\n        swap(cur, nxt);\n    }\n    double err = 0.0;\n    if (outCnt) outCnt->assign(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        double c = cur[i] * Ltot;\n        if (outCnt) (*outCnt)[i] = c;\n        err += fabs(c - (double)T[i]);\n    }\n    return err;\n}\n\nlong long simulate(const vector<int>& a, const vector<int>& b, int* cntArr) {\n    for (int i = 0; i < N; i++) cntArr[i] = 0;\n    int cur = 0;\n    for (int step = 0; step < Ltot; step++) {\n        int c = ++cntArr[cur];\n        cur = (c & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) {\n        long long d = (long long)cntArr[i] - (long long)T[i];\n        err += d >= 0 ? d : -d;\n    }\n    return err;\n}\n\nstruct Candidate {\n    double approxErr;\n    vector<int> a, b;\n    vector<double> counts;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> Ltot)) return 0;\n    T.resize(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    pi.resize(N);\n    for (int i = 0; i < N; i++) pi[i] = (double)T[i] / (double)Ltot;\n    prefixT.resize(N);\n    long long acc = 0;\n    for (int i = 0; i < N; i++) {\n        acc += T[i];\n        prefixT[i] = acc;\n    }\n    vector<double> desiredEdges(N);\n    for (int i = 0; i < N; i++) desiredEdges[i] = pi[i] * 2.0 * N;\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return T[i] > T[j]; });\n    int top1 = idx[0], top2 = idx[1];\n\n    vector<Candidate> topList;\n    const int TOPK = 60;\n\n    auto add_candidate = [&](const vector<int>& a, const vector<int>& b) {\n        Candidate c;\n        c.a = a;\n        c.b = b;\n        c.approxErr = approx_error(c.a, c.b, &c.counts);\n        topList.push_back(move(c));\n        if ((int)topList.size() > TOPK * 3) {\n            nth_element(topList.begin(), topList.begin() + TOPK, topList.end(),\n                        [](const Candidate& x, const Candidate& y) { return x.approxErr < y.approxErr; });\n            topList.resize(TOPK);\n        }\n    };\n\n    vector<int> a, b;\n\n    build_greedy(0, a, b);\n    add_candidate(a, b);\n    build_greedy(1, a, b);\n    add_candidate(a, b);\n    build_greedy(2, a, b);\n    add_candidate(a, b);\n    build_apportion(1, desiredEdges, a, b);\n    add_candidate(a, b);\n\n    a.resize(N); b.resize(N);\n    for (int i = 0; i < N; i++) {\n        a[i] = rand_by_target();\n        b[i] = rand_by_target();\n    }\n    enforce_indegree(a, b);\n    add_candidate(a, b);\n    for (int i = 0; i < N; i++) {\n        int v = rand_by_target();\n        a[i] = v; b[i] = v;\n    }\n    enforce_indegree(a, b);\n    add_candidate(a, b);\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = rand_by_target();\n    }\n    enforce_indegree(a, b);\n    add_candidate(a, b);\n    for (int i = 0; i < N; i++) {\n        a[i] = top1; b[i] = top2;\n    }\n    add_candidate(a, b);\n\n    auto start = chrono::steady_clock::now();\n    const double TOTAL_LIMIT = 1.85;\n    double genLimit = 0.9;\n    double lsLimit = 1.4;\n\n    // generation loop\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > genLimit) break;\n        int mode = rng.next_int(0, 7);\n        switch (mode) {\n            case 0: {\n                a.resize(N); b.resize(N);\n                for (int i = 0; i < N; i++) {\n                    a[i] = rand_by_target();\n                    b[i] = rand_by_target();\n                }\n                enforce_indegree(a, b);\n                break;\n            }\n            case 1: {\n                a.resize(N); b.resize(N);\n                for (int i = 0; i < N; i++) {\n                    int v = rand_by_target();\n                    a[i] = v; b[i] = v;\n                }\n                enforce_indegree(a, b);\n                break;\n            }\n            case 2: {\n                build_apportion(0, desiredEdges, a, b);\n                break;\n            }\n            case 3: {\n                build_apportion(2, desiredEdges, a, b);\n                break;\n            }\n            case 4: {\n                build_greedy(2, a, b);\n                break;\n            }\n            case 5: {\n                a.resize(N); b.resize(N);\n                for (int i = 0; i < N; i++) {\n                    a[i] = rng.next_int(0, N - 1);\n                    b[i] = rng.next_int(0, N - 1);\n                }\n                enforce_indegree(a, b);\n                break;\n            }\n            case 6: {\n                a.resize(N); b.resize(N);\n                for (int p = 0; p < N; p++) {\n                    a[idx[p]] = idx[(p + 1) % N];\n                    b[idx[p]] = idx[(p + 2) % N];\n                }\n                break;\n            }\n            case 7: {\n                a.resize(N); b.resize(N);\n                for (int i = 0; i < N; i++) {\n                    a[i] = (i + 1) % N;\n                    b[i] = rand_by_target();\n                }\n                enforce_indegree(a, b);\n                break;\n            }\n        }\n        add_candidate(a, b);\n    }\n\n    nth_element(topList.begin(), topList.begin(), topList.end(),\n                [](const Candidate& x, const Candidate& y) { return x.approxErr < y.approxErr; });\n    Candidate bestApprox = topList[0];\n\n    // approximate local search on top candidates\n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > lsLimit) break;\n        int baseIdx = rng.next_int(0, min<int>(20, topList.size()) - 1);\n        Candidate cur = topList[baseIdx];\n        double totalNeg = 0, totalPos = 0;\n        static double diff[105];\n        for (int i = 0; i < N; i++) {\n            diff[i] = cur.counts[i] - (double)T[i];\n            if (diff[i] > 0) totalPos += diff[i];\n            else totalNeg += -diff[i];\n        }\n        if (totalPos < 1e-9 || totalNeg < 1e-9) continue;\n        int changes = 1 + (rng.next() % 2);\n        for (int cstep = 0; cstep < changes; cstep++) {\n            int under = rng.next_int(0, N - 1);\n            double rneg = (double)(rng.next()) / (double)UINT64_MAX * totalNeg;\n            double accn = 0;\n            for (int i = 0; i < N; i++) {\n                if (diff[i] < 0) {\n                    accn += -diff[i];\n                    if (accn >= rneg) {\n                        under = i;\n                        break;\n                    }\n                }\n            }\n            int s = rng.next_int(0, N - 1);\n            int edgeIdx = rng.next_int(0, 1);\n            if (edgeIdx == 0)\n                cur.a[s] = under;\n            else\n                cur.b[s] = under;\n        }\n        Candidate cand;\n        cand.a = cur.a;\n        cand.b = cur.b;\n        cand.approxErr = approx_error(cand.a, cand.b, &cand.counts);\n        if (cand.approxErr + 1e-6 < topList[0].approxErr) {\n            topList.push_back(cand);\n        } else if (cand.approxErr < topList.back().approxErr) {\n            topList.push_back(cand);\n        }\n        if ((int)topList.size() > TOPK * 3) {\n            nth_element(topList.begin(), topList.begin() + TOPK, topList.end(),\n                        [](const Candidate& x, const Candidate& y) { return x.approxErr < y.approxErr; });\n            topList.resize(TOPK);\n        }\n    }\n\n    sort(topList.begin(), topList.end(), [](const Candidate& x, const Candidate& y) {\n        return x.approxErr < y.approxErr;\n    });\n\n    long long bestActualErr = (1LL << 60);\n    vector<int> bestA, bestB;\n    static int cntArrExact[105];\n    int evalK = min<int>(30, topList.size());\n    for (int i = 0; i < evalK; i++) {\n        long long e = simulate(topList[i].a, topList[i].b, cntArrExact);\n        if (e < bestActualErr) {\n            bestActualErr = e;\n            bestA = topList[i].a;\n            bestB = topList[i].b;\n        }\n    }\n    if (bestA.empty()) {\n        bestA = bestApprox.a;\n        bestB = bestApprox.b;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << ' ' << bestB[i] << '\\n';\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n// ---------- Random ----------\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    inline uint64_t rng() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    inline int randint(int l, int r) { // [l, r)\n        return (int)(rng() % (uint64_t)(r - l)) + l;\n    }\n    inline double rand01() {\n        return (double)(rng() & 0xFFFFFFFFULL) / 4294967296.0;\n    }\n} rnd;\n\n// ---------- DSU ----------\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a);\n        b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\n// ---------- Hilbert ----------\nuint64_t hilbertOrder(int x, int y, int order_bits, int max_coord) {\n    uint64_t d = 0;\n    for (int s = order_bits - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        d <<= 2;\n        d |= (uint64_t)((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) {\n                x = max_coord - x;\n                y = max_coord - y;\n            }\n            int t = x;\n            x = y;\n            y = t;\n        }\n    }\n    return d;\n}\n\n// ---------- Prim using dist matrix ----------\ndouble primCost(const vector<int> &nodes, const vector<float> &distMat, int N) {\n    int n = (int)nodes.size();\n    if (n <= 1) return 0.0;\n    vector<float> minD(n, 1e30f);\n    vector<char> used(n, 0);\n    minD[0] = 0.0f;\n    double cost = 0.0;\n    for (int it = 0; it < n; ++it) {\n        int v = -1;\n        float best = 1e30f;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        cost += minD[v];\n        int idv = nodes[v];\n        int base = idv * N;\n        for (int i = 0; i < n; ++i)\n            if (!used[i]) {\n                int idu = nodes[i];\n                float d = distMat[base + idu];\n                if (d < minD[i]) minD[i] = d;\n            }\n    }\n    return cost;\n}\n\nvector<pair<int, int>> primEdges(const vector<int> &nodes, const vector<float> &distMat, int N) {\n    int n = (int)nodes.size();\n    if (n <= 1) return {};\n    vector<float> minD(n, 1e30f);\n    vector<int> parent(n, -1);\n    vector<char> used(n, 0);\n    minD[0] = 0.0f;\n    for (int it = 0; it < n; ++it) {\n        int v = -1;\n        float best = 1e30f;\n        for (int i = 0; i < n; ++i) {\n            if (!used[i] && minD[i] < best) {\n                best = minD[i];\n                v = i;\n            }\n        }\n        used[v] = 1;\n        int idv = nodes[v];\n        int base = idv * N;\n        for (int i = 0; i < n; ++i)\n            if (!used[i]) {\n                int idu = nodes[i];\n                float d = distMat[base + idu];\n                if (d < minD[i]) {\n                    minD[i] = d;\n                    parent[i] = v;\n                }\n            }\n    }\n    vector<pair<int, int>> edges;\n    edges.reserve(n - 1);\n    for (int i = 1; i < n; ++i) edges.emplace_back(nodes[i], nodes[parent[i]]);\n    return edges;\n}\n\n// ---------- NN order ----------\nvector<int> nearestNeighborOrder(int N, const vector<float> &distMat) {\n    vector<int> order;\n    order.reserve(N);\n    vector<char> used(N, 0);\n    int cur = 0;\n    used[cur] = 1;\n    order.push_back(cur);\n    for (int step = 1; step < N; ++step) {\n        int best = -1;\n        float bestd = 1e30f;\n        int base = cur * N;\n        for (int i = 0; i < N; ++i) {\n            if (used[i]) continue;\n            float d = distMat[base + i];\n            if (d < bestd) {\n                bestd = d;\n                best = i;\n            }\n        }\n        cur = best;\n        used[cur] = 1;\n        order.push_back(cur);\n    }\n    return order;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Q, L, W;\n    if (!(cin >> N >> M >> Q >> L >> W)) return 0;\n    vector<int> G(M);\n    for (int i = 0; i < M; ++i) cin >> G[i];\n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; ++i) cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n\n    vector<double> px(N), py(N);\n    vector<double> unc(N);\n    for (int i = 0; i < N; ++i) {\n        px[i] = (lx[i] + rx[i]) * 0.5;\n        py[i] = (ly[i] + ry[i]) * 0.5;\n        unc[i] = max(rx[i] - lx[i], ry[i] - ly[i]);\n    }\n\n    // distance matrix\n    vector<float> distMat(N * N);\n    for (int i = 0; i < N; ++i) {\n        distMat[i * N + i] = 0.0f;\n        for (int j = i + 1; j < N; ++j) {\n            double dx = px[i] - px[j];\n            double dy = py[i] - py[j];\n            float d = (float)std::sqrt(dx * dx + dy * dy);\n            distMat[i * N + j] = d;\n            distMat[j * N + i] = d;\n        }\n    }\n\n    const int order_bits = 15;\n    const int max_coord = (1 << order_bits) - 1;\n\n    vector<vector<int>> candidates;\n\n    // Hilbert variants\n    for (int variant = 0; variant < 5; ++variant) {\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            int x = (int)px[i];\n            int y = (int)py[i];\n            switch (variant) {\n                case 0: break;\n                case 1: x = max_coord - x; break;\n                case 2: y = max_coord - y; break;\n                case 3:\n                    x = max_coord - x;\n                    y = max_coord - y;\n                    break;\n                case 4: {\n                    int t = x;\n                    x = y;\n                    y = t;\n                } break;\n            }\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto &a, auto &b) { return a.first < b.first; });\n        vector<int> ord;\n        ord.reserve(N);\n        for (auto &p : keys) ord.push_back(p.second);\n        candidates.push_back(move(ord));\n    }\n    // jittered Hilbert\n    for (int rep = 0; rep < 3; ++rep) {\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(N);\n        for (int i = 0; i < N; ++i) {\n            double nx = px[i] + (rnd.rand01() - 0.5) * W * 0.3;\n            double ny = py[i] + (rnd.rand01() - 0.5) * W * 0.3;\n            int x = max(0, min(max_coord, (int)nx));\n            int y = max(0, min(max_coord, (int)ny));\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, i);\n        }\n        sort(keys.begin(), keys.end(), [](auto &a, auto &b) { return a.first < b.first; });\n        vector<int> ord;\n        ord.reserve(N);\n        for (auto &p : keys) ord.push_back(p.second);\n        candidates.push_back(move(ord));\n    }\n    // simple sorts\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (px[a] == px[b]) return py[a] < py[b];\n            return px[a] < px[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            if (py[a] == py[b]) return px[a] < px[b];\n            return py[a] < py[b];\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] + py[a], vb = px[b] + py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    {\n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        sort(ids.begin(), ids.end(), [&](int a, int b) {\n            double va = px[a] - py[a], vb = px[b] - py[b];\n            if (va == vb) {\n                if (px[a] == px[b]) return py[a] < py[b];\n                return px[a] < px[b];\n            }\n            return va < vb;\n        });\n        candidates.push_back(move(ids));\n    }\n    candidates.push_back(nearestNeighborOrder(N, distMat));\n\n    auto evalCost = [&](const vector<int> &ord) -> double {\n        double tot = 0.0;\n        int pos = 0;\n        for (int k = 0; k < M; ++k) {\n            int g = G[k];\n            vector<int> grp;\n            grp.reserve(g);\n            for (int t = 0; t < g; ++t) grp.push_back(ord[pos + t]);\n            pos += g;\n            tot += primCost(grp, distMat, N);\n        }\n        return tot;\n    };\n\n    double bestInit = 1e100;\n    int bestIdx = 0;\n    for (int i = 0; i < (int)candidates.size(); ++i) {\n        double c = evalCost(candidates[i]);\n        if (c < bestInit) {\n            bestInit = c;\n            bestIdx = i;\n        }\n    }\n    const vector<int> &initOrder = candidates[bestIdx];\n\n    vector<vector<int>> groups(M);\n    int pos = 0;\n    for (int k = 0; k < M; ++k) {\n        int g = G[k];\n        groups[k].reserve(g);\n        for (int t = 0; t < g; ++t) groups[k].push_back(initOrder[pos + t]);\n        pos += g;\n    }\n\n    // neighbor list\n    const int KNEI = 30;\n    vector<vector<int>> neigh(N);\n    vector<int> tmp(N);\n    for (int i = 0; i < N; ++i) {\n        iota(tmp.begin(), tmp.end(), 0);\n        sort(tmp.begin(), tmp.end(), [&](int a, int b) { return distMat[i * N + a] < distMat[i * N + b]; });\n        neigh[i].reserve(KNEI);\n        for (int t = 1; t <= KNEI; ++t) neigh[i].push_back(tmp[t]);\n    }\n\n    vector<double> groupCost(M, 0.0);\n    double totalCost = 0.0;\n    for (int k = 0; k < M; ++k) {\n        double c = primCost(groups[k], distMat, N);\n        groupCost[k] = c;\n        totalCost += c;\n    }\n    vector<vector<int>> bestGroups = groups;\n    double bestCost = totalCost;\n\n    vector<int> belong(N, -1), idxInGroup(N, -1);\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < (int)groups[k].size(); ++i) {\n            int v = groups[k][i];\n            belong[v] = k;\n            idxInGroup[v] = i;\n        }\n    }\n\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 1.2; // seconds for SA\n    const double T0 = 15.0, Tend = 1e-3;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > timeLimit) break;\n        double t = elapsed / timeLimit;\n        double T = exp(log(T0) * (1.0 - t) + log(Tend) * t);\n\n        int va, vb, ga, gb;\n        if (rnd.rand01() < 0.7) {\n            va = rnd.randint(0, N);\n            int nb = rnd.randint(0, KNEI);\n            vb = neigh[va][nb];\n            ga = belong[va];\n            gb = belong[vb];\n            if (ga == gb) continue;\n        } else {\n            ga = rnd.randint(0, M);\n            gb = rnd.randint(0, M);\n            if (ga == gb || groups[ga].empty() || groups[gb].empty()) continue;\n            va = groups[ga][rnd.randint(0, (int)groups[ga].size())];\n            vb = groups[gb][rnd.randint(0, (int)groups[gb].size())];\n        }\n\n        int ia = idxInGroup[va];\n        int ib = idxInGroup[vb];\n        auto &A = groups[ga];\n        auto &B = groups[gb];\n\n        A[ia] = vb;\n        B[ib] = va;\n        idxInGroup[va] = ib;\n        idxInGroup[vb] = ia;\n\n        double oldSum = groupCost[ga] + groupCost[gb];\n        double newA = primCost(A, distMat, N);\n        double newB = primCost(B, distMat, N);\n        double newSum = newA + newB;\n        double delta = newSum - oldSum;\n        bool accept = false;\n        if (delta < 0)\n            accept = true;\n        else {\n            double prob = exp(-delta / T);\n            if (rnd.rand01() < prob) accept = true;\n        }\n        if (accept) {\n            groupCost[ga] = newA;\n            groupCost[gb] = newB;\n            totalCost += delta;\n            belong[va] = gb;\n            belong[vb] = ga;\n            if (totalCost < bestCost) {\n                bestCost = totalCost;\n                bestGroups = groups;\n            }\n        } else {\n            // revert\n            A[ia] = va;\n            B[ib] = vb;\n            idxInGroup[va] = ia;\n            idxInGroup[vb] = ib;\n        }\n    }\n\n    groups.swap(bestGroups);\n\n    // sort each group by Hilbert\n    for (int k = 0; k < M; ++k) {\n        auto &g = groups[k];\n        vector<pair<uint64_t, int>> keys;\n        keys.reserve(g.size());\n        for (int v : g) {\n            int x = (int)px[v], y = (int)py[v];\n            uint64_t h = hilbertOrder(x, y, order_bits, max_coord);\n            keys.emplace_back(h, v);\n        }\n        sort(keys.begin(), keys.end(), [](auto &a, auto &b) { return a.first < b.first; });\n        vector<int> ng;\n        ng.reserve(g.size());\n        for (auto &p : keys) ng.push_back(p.second);\n        g.swap(ng);\n    }\n\n    // priority for queries based on uncertainty\n    vector<double> groupPriority(M, 0.0);\n    for (int k = 0; k < M; ++k) {\n        double sum = 0.0;\n        for (int v : groups[k]) sum += unc[v];\n        double avg = groups[k].empty() ? 0.0 : sum / groups[k].size();\n        groupPriority[k] = avg * sqrt((double)groups[k].size());\n    }\n\n    vector<vector<pair<int, int>>> qEdges(M);\n    int queries_used = 0;\n\n    // small groups 2..L sorted by priority\n    vector<int> smallList;\n    for (int k = 0; k < M; ++k) {\n        int sz = (int)groups[k].size();\n        if (2 <= sz && sz <= L) smallList.push_back(k);\n    }\n    sort(smallList.begin(), smallList.end(), [&](int a, int b) {\n        return groupPriority[a] > groupPriority[b];\n    });\n    for (int k : smallList) {\n        if (queries_used >= Q) break;\n        int sz = (int)groups[k].size();\n        cout << \"? \" << sz;\n        for (int v : groups[k]) cout << ' ' << v;\n        cout << endl;\n        queries_used++;\n        for (int i = 0; i < sz - 1; ++i) {\n            int a, b;\n            if (!(cin >> a >> b)) return 0;\n            qEdges[k].emplace_back(a, b);\n        }\n    }\n\n    // large groups > L sorted by priority\n    vector<int> largeList;\n    for (int k = 0; k < M; ++k) {\n        int sz = (int)groups[k].size();\n        if (sz > L) largeList.push_back(k);\n    }\n    sort(largeList.begin(), largeList.end(), [&](int a, int b) {\n        return groupPriority[a] > groupPriority[b];\n    });\n    for (int k : largeList) {\n        if (queries_used >= Q) break;\n        int sz = (int)groups[k].size();\n        int need = (sz - 1 + (L - 2)) / (L - 1);\n        int use = min(need, Q - queries_used);\n        if (use <= 0) break;\n        for (int i = 0; i < use; ++i) {\n            int start = (int)round((double)i * (sz - L) / max(1, use - 1));\n            if (start > sz - L) start = sz - L;\n            if (start < 0) start = 0;\n            int len = min(L, sz - start);\n            if (len < 2) continue;\n            cout << \"? \" << len;\n            for (int j = 0; j < len; ++j) cout << ' ' << groups[k][start + j];\n            cout << endl;\n            queries_used++;\n            for (int e = 0; e < len - 1; ++e) {\n                int a, b;\n                if (!(cin >> a >> b)) return 0;\n                qEdges[k].emplace_back(a, b);\n            }\n            if (queries_used >= Q) break;\n        }\n    }\n\n    // remaining queries random on high priority groups\n    while (queries_used < Q && !largeList.empty()) {\n        int k = largeList[rnd.randint(0, (int)largeList.size())];\n        int sz = (int)groups[k].size();\n        if (sz < 2) {\n            largeList.pop_back();\n            continue;\n        }\n        int len = min(L, sz);\n        int start = rnd.randint(0, sz - len + 1);\n        cout << \"? \" << len;\n        for (int j = 0; j < len; ++j) cout << ' ' << groups[k][start + j];\n        cout << endl;\n        queries_used++;\n        for (int e = 0; e < len - 1; ++e) {\n            int a, b;\n            if (!(cin >> a >> b)) return 0;\n            qEdges[k].emplace_back(a, b);\n        }\n    }\n\n    // Build final edges\n    vector<vector<pair<int, int>>> finalEdges(M);\n    vector<int> idxMap(N, -1);\n    for (int k = 0; k < M; ++k) {\n        auto &nodes = groups[k];\n        int gsz = nodes.size();\n        if (gsz <= 1) continue;\n        for (int i = 0; i < gsz; ++i) idxMap[nodes[i]] = i;\n        DSU uf(gsz);\n        vector<pair<int, int>> chosen;\n        chosen.reserve(gsz - 1);\n        for (auto &e : qEdges[k]) {\n            int ia = idxMap[e.first], ib = idxMap[e.second];\n            if (ia < 0 || ib < 0) continue;\n            if (uf.unite(ia, ib)) chosen.push_back(e);\n        }\n        auto preds = primEdges(nodes, distMat, N);\n        for (auto &e : preds) {\n            if ((int)chosen.size() >= gsz - 1) break;\n            int ia = idxMap[e.first], ib = idxMap[e.second];\n            if (uf.unite(ia, ib)) chosen.push_back(e);\n        }\n        finalEdges[k] = move(chosen);\n        for (int v : nodes) idxMap[v] = -1;\n    }\n\n    cout << \"!\\n\";\n    for (int k = 0; k < M; ++k) {\n        auto &nodes = groups[k];\n        for (int i = 0; i < (int)nodes.size(); ++i) {\n            if (i) cout << ' ';\n            cout << nodes[i];\n        }\n        cout << '\\n';\n        for (auto &e : finalEdges[k]) {\n            cout << e.first << ' ' << e.second << '\\n';\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int INF = 1e9;\nint N, M;\nvector<int> idxs;\nvector<pair<int, int>> pos;\nvector<int> dr = {-1, 1, 0, 0};\nvector<int> dc = {0, 0, -1, 1};\nvector<char> dirChar = {'U', 'D', 'L', 'R'};\nvector<char> isTarget;  // size N*N\n\ninline int slide_stop(int r, int c, int dir, const vector<char> &blocked) {\n    int nr = r, nc = c;\n    while (true) {\n        int tr = nr + dr[dir], tc = nc + dc[dir];\n        if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n        if (blocked[tr * N + tc]) break;\n        nr = tr;\n        nc = tc;\n    }\n    return nr * N + nc;\n}\n\nint dist_between(int s, int g, const vector<char> &blocked) {\n    if (blocked[s] || blocked[g]) return INF;\n    static vector<int> dist;\n    static queue<int> q;\n    if ((int)dist.size() != N * N) dist.resize(N * N);\n    fill(dist.begin(), dist.end(), -1);\n    while (!q.empty()) q.pop();\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front();\n        q.pop();\n        int d = dist[v];\n        if (v == g) return d;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = d + 1;\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = d + 1;\n                q.push(sid);\n            }\n        }\n    }\n    return INF;\n}\n\nvector<pair<char, char>> path_between(int s, int g, const vector<char> &blocked) {\n    vector<int> dist(N * N, -1), prev(N * N, -1);\n    vector<char> prevAct(N * N), prevDir(N * N);\n    queue<int> q;\n    dist[s] = 0;\n    q.push(s);\n    while (!q.empty()) {\n        int v = q.front();\n        q.pop();\n        if (v == g) break;\n        int r = v / N, c = v % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int ni = nr * N + nc;\n                if (!blocked[ni] && dist[ni] == -1) {\n                    dist[ni] = dist[v] + 1;\n                    prev[ni] = v;\n                    prevAct[ni] = 'M';\n                    prevDir[ni] = dirChar[dir];\n                    q.push(ni);\n                }\n            }\n            int sid = slide_stop(r, c, dir, blocked);\n            if (sid != v && dist[sid] == -1) {\n                dist[sid] = dist[v] + 1;\n                prev[sid] = v;\n                prevAct[sid] = 'S';\n                prevDir[sid] = dirChar[dir];\n                q.push(sid);\n            }\n        }\n    }\n    vector<pair<char, char>> actions;\n    if (dist[g] == -1) return actions;  // unreachable\n    int cur = g;\n    while (cur != s) {\n        actions.push_back({prevAct[cur], prevDir[cur]});\n        cur = prev[cur];\n    }\n    reverse(actions.begin(), actions.end());\n    return actions;\n}\n\n// Adjacent candidate cells per target index\nvector<vector<int>> adjCells;\n\n// evaluate cost of a plan (boolean array size N*N)\nint evaluate_plan(const vector<char> &plan) {\n    vector<char> blocked(N * N, false);\n    int cost = 0;\n    for (int t = 0; t < M - 1; t++) {\n        // place planned blocks adjacent to current target\n        for (int idx : adjCells[t]) {\n            if (plan[idx] && !blocked[idx]) {\n                blocked[idx] = true;\n                cost += 1;  // alter action\n            }\n        }\n        int d = dist_between(idxs[t], idxs[t + 1], blocked);\n        if (d >= INF / 2) return INF;\n        cost += d;\n    }\n    return cost;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if (!(cin >> N >> M)) return 0;\n    pos.resize(M);\n    idxs.resize(M);\n    isTarget.assign(N * N, false);\n    for (int k = 0; k < M; k++) {\n        int r, c;\n        cin >> r >> c;\n        pos[k] = {r, c};\n        idxs[k] = r * N + c;\n        isTarget[idxs[k]] = true;\n    }\n\n    adjCells.assign(M, {});\n    vector<char> isCandidate(N * N, false);\n    for (int t = 0; t < M - 1; t++) {  // last target has no outgoing edge\n        int r = pos[t].first, c = pos[t].second;\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int idx = nr * N + nc;\n                if (isTarget[idx]) continue;\n                adjCells[t].push_back(idx);\n                isCandidate[idx] = true;\n            }\n        }\n    }\n\n    vector<int> candidates;\n    for (int i = 0; i < N * N; i++) {\n        if (isCandidate[i] && !isTarget[i]) candidates.push_back(i);\n    }\n\n    vector<char> plan(N * N, false);\n    int bestCost = evaluate_plan(plan);\n    vector<char> bestPlan = plan;\n    int curCost = bestCost;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> urd(0.0, 1.0);\n\n    auto start = chrono::steady_clock::now();\n    const double timeLimit = 1.2;  // seconds for optimization\n    int iter = 0;\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > timeLimit) break;\n        iter++;\n        int ci = candidates[rng() % candidates.size()];\n        plan[ci] = !plan[ci];\n        int newCost = evaluate_plan(plan);\n        int diff = newCost - curCost;\n        double temp = 1.0 - elapsed / timeLimit;\n        temp = max(temp, 0.01);\n        if (diff <= 0 || exp(-diff / temp) > urd(rng)) {\n            curCost = newCost;\n            if (newCost < bestCost) {\n                bestCost = newCost;\n                bestPlan = plan;\n            }\n        } else {\n            plan[ci] = !plan[ci];\n        }\n    }\n\n    // Use bestPlan\n    plan = bestPlan;\n    if (bestCost >= INF / 2) {\n        fill(plan.begin(), plan.end(), false);\n    }\n\n    vector<char> blocked(N * N, false);\n    vector<pair<char, char>> actions;\n\n    for (int t = 0; t < M - 1; t++) {\n        int r = pos[t].first, c = pos[t].second;\n        // place planned blocks adjacent to current target\n        for (int dir = 0; dir < 4; dir++) {\n            int nr = r + dr[dir], nc = c + dc[dir];\n            if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                int idx = nr * N + nc;\n                if (plan[idx] && !blocked[idx]) {\n                    actions.push_back({'A', dirChar[dir]});\n                    blocked[idx] = true;\n                }\n            }\n        }\n        int cur = idxs[t];\n        int nxt = idxs[t + 1];\n        int curDist = dist_between(cur, nxt, blocked);\n        // local greedy toggle for immediate next move (skip planned cells and targets)\n        while (true) {\n            int bestGain = 0;\n            int bestDir = -1;\n            bool bestPlace = true;\n            int bestNewDist = curDist;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r + dr[dir], nc = c + dc[dir];\n                if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                int idx = nr * N + nc;\n                if (isTarget[idx]) continue;\n                if (plan[idx]) continue;  // don't toggle planned cells\n                if (!blocked[idx]) {\n                    blocked[idx] = true;\n                    int nd = dist_between(cur, nxt, blocked);\n                    blocked[idx] = false;\n                    if (nd < INF / 2) {\n                        int gain = curDist - (1 + nd);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = true;\n                            bestNewDist = nd;\n                        }\n                    }\n                } else {  // remove\n                    blocked[idx] = false;\n                    int nd = dist_between(cur, nxt, blocked);\n                    blocked[idx] = true;\n                    if (nd < INF / 2) {\n                        int gain = curDist - (1 + nd);\n                        if (gain > bestGain) {\n                            bestGain = gain;\n                            bestDir = dir;\n                            bestPlace = false;\n                            bestNewDist = nd;\n                        }\n                    }\n                }\n            }\n            if (bestGain > 0 && bestDir != -1) {\n                actions.push_back({'A', dirChar[bestDir]});\n                int idx = (r + dr[bestDir]) * N + (c + dc[bestDir]);\n                blocked[idx] = bestPlace;\n                curDist = bestNewDist;\n            } else {\n                break;\n            }\n        }\n        // move to next target\n        auto path = path_between(cur, nxt, blocked);\n        actions.insert(actions.end(), path.begin(), path.end());\n    }\n\n    for (auto &p : actions) {\n        cout << p.first << ' ' << p.second << '\\n';\n    }\n    return 0;\n}"}}}