This problem is different with hard version only by constraints on total answers length

It is an interactive problem

Venya joined a tour to the madhouse, in which orderlies play with patients the following game. Orderlies pick a string $s$ of length $n$, consisting only of lowercase English letters. The player can ask two types of queries:

* ? l r – ask to list all substrings of $s[l..r]$. Substrings will be returned in random order, and in every substring, all characters will be randomly shuffled.
* ! s – guess the string picked by the orderlies. This query can be asked exactly once, after that the game will finish. If the string is guessed correctly, the player wins, otherwise he loses.

The player can ask no more than $3$ queries of the first type.

To make it easier for the orderlies, there is an additional limitation: the total number of returned substrings in all queries of the first type must not exceed $(n+1)^2$.

Venya asked you to write a program, which will guess the string by interacting with the orderlies' program and acting by the game's rules.

Your program should immediately terminate after guessing the string using a query of the second type. In case your program guessed the string incorrectly, or it violated the game rules, it will receive verdict Wrong answer.

Note that in every test case the string is fixed beforehand and will not change during the game, which means that the interactor is not adaptive.

Input

First line contains number $n$ ($1 \le n \le 100$) — the length of the picked string.

Interaction

You start the interaction by reading the number $n$.

To ask a query about a substring from $l$ to $r$ inclusively ($1 \le l \le r \le n$), you should output

? l r

on a separate line. After this, all substrings of $s[l..r]$ will be returned in random order, each substring exactly once. In every returned substring all characters will be randomly shuffled.

In the case, if you ask an incorrect query, ask more than $3$ queries of the first type or there will be more than $(n+1)^2$ substrings returned in total, you will receive verdict Wrong answer.

To guess the string $s$, you should output

! s

on a separate line.

After printing each query, do not forget to flush the output. Otherwise, you will get Idleness limit exceeded. To flush the output, you can use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see documentation for other languages.

If you received - (dash) as an answer to any query, you need to terminate your program with exit code 0 (for example, by calling exit(0)). This means that there was an error in the interaction protocol. If you don't terminate with exit code 0, you can receive any unsuccessful verdict.

Example

Input

```
4

a
aa
a

cb
b
c

c
```

Output

```
? 1 2

? 3 4

? 4 4

! aabc
```

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;

static long long total_returned = 0;
static long long hard_cap_queries = 0;
static long long hard_cap_returned = 0;

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

static uint64_t fnv1a64(const string& s) {
    uint64_t h = 1469598103934665603ULL;
    for (unsigned char c : s) {
        h ^= (uint64_t)c;
        h *= 1099511628211ULL;
    }
    return h;
}

static uint64_t splitmix64_next(uint64_t& x) {
    x += 0x9e3779b97f4a7c15ULL;
    uint64_t z = x;
    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
    z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
    return z ^ (z >> 31);
}

static uint64_t mix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15ULL;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;
    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;
    return x ^ (x >> 31);
}

static string shuffle_chars_deterministic(string t, uint64_t seed) {

    for (int i = (int)t.size() - 1; i > 0; --i) {
        uint64_t r = splitmix64_next(seed);
        int j = (int)(r % (uint64_t)(i + 1));
        swap(t[i], t[j]);
    }
    return t;
}

static bool is_lowercase_word(const string& s) {
    for (char c : s) if (c < 'a' || c > 'z') return false;
    return true;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    try {
        int n = inf.readInt(1, 100, "n");
        string hidden = inf.readToken();
        if ((int)hidden.size() != n) finish(_fail, "Hidden input: string length mismatch");
        if (!is_lowercase_word(hidden)) finish(_fail, "Hidden input: string is not lowercase");

        query_limit = 3;
        hard_cap_queries = max(200000LL, 10LL * query_limit);
        long long substr_budget = 1LL * (n + 1) * (n + 1);
        hard_cap_returned = max(200000LL, 10LL * substr_budget);

        log_metrics();

        cout << n << "\n";
        cout.flush();

        uint64_t global_seed = fnv1a64(hidden) ^ mix64((uint64_t)n) ^ 0x243f6a8885a308d3ULL;

        while (true) {
            string cmd;
            if (!(cin >> cmd)) {
                finish(_pe, "Unexpected EOF from contestant (no final answer)");
            }

            if (cmd == "?") {
                long long l, r;
                if (!(cin >> l >> r)) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Malformed query: expected '? l r'");
                }

                queries++;
                if (queries > hard_cap_queries) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Hard cap exceeded: too many queries");
                }

                if (l < 1 || r < 1 || l > r || r > n) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Query out of bounds");
                }

                int L = (int)l - 1;
                int R = (int)r - 1;
                int k = R - L + 1;
                long long cnt = 1LL * k * (k + 1) / 2;
                total_returned += cnt;
                if (total_returned > hard_cap_returned) {
                    cout << "-\n";
                    cout.flush();
                    finish(_pe, "Hard cap exceeded: too many substrings returned");
                }

                vector<pair<uint64_t, pair<int,int>>> pos;
                pos.reserve((size_t)cnt);
                for (int i = L; i <= R; ++i) {
                    for (int j = i; j <= R; ++j) {
                        uint64_t key = mix64(global_seed ^ (uint64_t)(i + 1) * 0x9e3779b97f4a7c15ULL ^
                                             (uint64_t)(j + 1) * 0xbf58476d1ce4e5b9ULL);
                        pos.push_back({key, {i, j}});
                    }
                }
                stable_sort(pos.begin(), pos.end(), [](const auto& a, const auto& b) {
                    if (a.first != b.first) return a.first < b.first;
                    if (a.second.first != b.second.first) return a.second.first < b.second.first;
                    return a.second.second < b.second.second;
                });

                for (const auto& it : pos) {
                    int i = it.second.first, j = it.second.second;
                    string t = hidden.substr(i, j - i + 1);
                    uint64_t seed = global_seed ^ (uint64_t)(i + 1) * 0x94d049bb133111ebULL ^
                                    (uint64_t)(j + 1) * 0xbf58476d1ce4e5b9ULL ^
                                    (uint64_t)t.size() * 0x9e3779b97f4a7c15ULL ^
                                    it.first;
                    t = shuffle_chars_deterministic(std::move(t), seed);
                    cout << t << "\n";
                }
                cout.flush();
            } else if (cmd == "!") {
                string guess;
                if (!(cin >> guess)) {
                    finish(_pe, "Malformed answer: expected '! s'");
                }
                if ((int)guess.size() != n) {
                    finish(_wa, "Wrong answer");
                }
                if (!is_lowercase_word(guess)) {
                    finish(_pe, "Answer contains non-lowercase letters");
                }
                if (guess == hidden) finish(_ok, "OK");
                finish(_wa, "Wrong answer");
            } else {
                cout << "-\n";
                cout.flush();
                finish(_pe, "Unknown command");
            }
        }
    } catch (const std::exception& e) {
        log_metrics();
        quitf(_fail, "Interactor exception: %s", e.what());
    } catch (...) {
        log_metrics();
        quitf(_fail, "Interactor exception");
    }
}

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static string make_non_instance(int n, long long seedHint, int alphabet) {
    auto clampAlpha = [&](int x) { return max(1, min(26, x)); };
    alphabet = clampAlpha(alphabet);
    n = max(1, min(100, n));

    auto randChar = [&]() -> char {
        return char('a' + rnd.next(0, alphabet - 1));
    };

    if (seedHint == 1) {
        return string(1, 'a');
    }
    if (seedHint == 2) {
        return string(n, 'a');
    }
    if (seedHint == 3) {
        string s;
        s.reserve(n);
        for (int i = 0; i < n; i++) s.push_back((i % 2 == 0) ? 'a' : 'b');
        if (n >= 3) {
            s[0] = 'c';
            s[n - 1] = 'c';
            s[n / 2] = 'c';
        }
        return s;
    }

    int scheme = rnd.next(1, 4);
    string s;
    s.reserve(n);

    if (scheme == 1) {
        for (int i = 0; i < n; i++) s.push_back(randChar());
        return s;
    }

    if (scheme == 2) {
        vector<char> base;
        base.reserve(alphabet);
        for (int i = 0; i < alphabet; i++) base.push_back(char('a' + i));

        int pos = 0;
        while (pos < n) {
            int shift = rnd.next(0, alphabet - 1);
            for (int i = 0; i < alphabet && pos < n; i++, pos++) {
                char c = base[(i + shift) % alphabet];
                if (rnd.next(1, 10) == 1) c = randChar();
                s.push_back(c);
            }
        }
        return s;
    }

    if (scheme == 3) {
        for (int i = 0; i < n; i++) {
            int v = (i % alphabet);
            s.push_back(char('a' + v));
        }
        int swaps = max(1, n / 3);
        for (int t = 0; t < swaps; t++) {
            int i = rnd.next(0, n - 1);
            int j = rnd.next(0, n - 1);
            swap(s[i], s[j]);
        }
        for (int t = 0; t < max(1, n / 10); t++) {
            int i = rnd.next(0, n - 1);
            s[i] = randChar();
        }
        return s;
    }

    {
        int pos = 0;
        while (pos < n) {
            int remaining = n - pos;
            int len = rnd.next(1, min(remaining, 15));
            char c;
            if (rnd.next(1, 4) == 1) c = char('a' + (pos % alphabet));
            else c = randChar();
            for (int i = 0; i < len; i++) s.push_back(c);
            pos += len;
        }
        for (int t = 0; t < max(1, n / 12); t++) {
            int i = rnd.next(0, n - 1);
            s[i] = randChar();
        }
        return s;
    }
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 100);
    int alphabet = opt<int>("alphabet", 26);

    long long seedHint = 0;
    if (argc >= 2) {
        try {
            seedHint = stoll(string(argv[1]));
        } catch (...) {
            seedHint = 0;
        }
    }

    if (mode == "adp") {
        int n = max(1, min(100, nOpt));
        if (seedHint >= 1 && seedHint <= 3) {
            if (seedHint == 1) n = 1;
            else n = 100;
        } else {
            if (nOpt == 100) n = rnd.next(80, 100);
        }
        cout << n << "\n";
        return 0;
    }

    if (mode != "non") {

        mode = "non";
    }

    int n = max(1, min(100, nOpt));
    if (seedHint >= 1 && seedHint <= 3) {
        if (seedHint == 1) n = 1;
        else n = 100;
    } else {
        if (nOpt == 100) n = rnd.next(80, 100);
    }

    string s = make_non_instance(n, seedHint, alphabet);
    n = (int)s.size();

    cout << n << "\n" << s << "\n";
    return 0;
}


This is an interactive problem.

Alice and Bob are playing a game on the chessboard of size $n \times m$ where $n$ and $m$ are even. The rows are numbered from $1$ to $n$ and the columns are numbered from $1$ to $m$. There are two knights on the chessboard. A white one initially is on the position $(x_1, y_1)$, while the black one is on the position $(x_2, y_2)$. Alice will choose one of the knights to play with, and Bob will use the other one.

The Alice and Bob will play in turns and whoever controls the white knight starts the game. During a turn, the player must move their knight adhering the chess rules. That is, if the knight is currently on the position $(x, y)$, it can be moved to any of those positions (as long as they are inside the chessboard):

 $(x+1, y+2)$, $(x+1, y-2)$, $(x-1, y+2)$, $(x-1, y-2)$,

$(x+2, y+1)$, $(x+2, y-1)$, $(x-2, y+1)$, $(x-2, y-1)$.

We all know that knights are strongest in the middle of the board. Both knight have a single position they want to reach:

* the owner of the white knight wins if it captures the black knight or if the white knight is at $(n/2, m/2)$ and this position is not under attack of the black knight at this moment;
* The owner of the black knight wins if it captures the white knight or if the black knight is at $(n/2+1, m/2)$ and this position is not under attack of the white knight at this moment.

Formally, the player who captures the other knight wins. The player who is at its target square ($(n/2, m/2)$ for white, $(n/2+1, m/2)$ for black) and this position is not under opponent's attack, also wins.

A position is under attack of a knight if it can move into this position. Capturing a knight means that a player moves their knight to the cell where the opponent's knight is.

If Alice made $350$ moves and nobody won, the game is a draw.

Alice is unsure in her chess skills, so she asks you for a help. Choose a knight and win the game for her. It can be shown, that Alice always has a winning strategy.

Interaction

The interaction starts with two integers $n$ and $m$ ($6 \le n,m \le 1000$, $n$ and $m$ are even) — the dimensions of the chessboard.

The second line contains four integers $x_1, y_1, x_2, y_2$ ($1 \le x_1, x_2 \le n$, $1 \le y_1, y_2 \le m$) — the positions of the white and the black knight. It is guaranteed that the two knights have different starting positions. It is also guaranteed that none of the knights are in their own target square in the beginning of the game (however, they can be on the opponent's target position).

Your program should reply with either "WHITE" or "BLACK", depending on the knight you want to play with. In case you select the white knight, you start the game.

During every your turn, you need to print two integers: $x$ and $y$, the position to move the knight. If you won the game by this turn, you must terminate your program immediately.

After every turn of the opponent, you will receive two integers: $x$ and $y$, the position where Bob moved his knight.

If your last move was illegal or you lost the game after jury's turn, or you made $350$ moves, and haven't won, you will receive "-1 -1". In such cases, you should terminate your program and then you will get a Wrong Answer verdict.

After printing anything, do not forget to output the end of line and flush the output. Otherwise, you might get Idleness limit exceeded. To do this, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see documentation for other languages.

Jury's program is adaptive: the moves of jury may depend on the moves made by your program.

Examples

Input

```
8 8
2 3 1 8
```

Output

```
WHITE
4 4
```

Input

```
6 6
4 4 2 2
6 3
```

Output

```
BLACK
4 3
```

Note

In the first example, the white knight can reach it's target square in one move.

In the second example black knight wins, no matter what white knight moves.

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static int contestant_moves = 0;
static const int MOVE_LIMIT = 350;

struct Point {
    int x, y;
    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
    bool operator!=(const Point& other) const {
        return !(*this == other);
    }
};

int n, m;
Point white_start, black_start;
Point white_target, black_target;

vector<vector<int>> dist_white_target;
vector<vector<int>> dist_black_target;

int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[] = {-1, 1, -2, 2, -2, 2, -1, 1};

bool in_bounds(int r, int c) {
    return r >= 1 && r <= n && c >= 1 && c <= m;
}

vector<vector<int>> bfs(Point start) {
    vector<vector<int>> d(n + 1, vector<int>(m + 1, -1));
    queue<Point> q;
    d[start.x][start.y] = 0;
    q.push(start);
    while (!q.empty()) {
        Point u = q.front();
        q.pop();
        for (int i = 0; i < 8; i++) {
            int nx = u.x + dx[i];
            int ny = u.y + dy[i];
            if (in_bounds(nx, ny) && d[nx][ny] == -1) {
                d[nx][ny] = d[u.x][u.y] + 1;
                q.push({nx, ny});
            }
        }
    }
    return d;
}

void log_metrics() {
    try {
        tout << "queries=" << contestant_moves << endl;
        tout << "query_limit=" << MOVE_LIMIT << endl;
    } catch (...) {}
}

void finish(TResult verdict, string msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

bool is_attacked(Point p, Point attacker_pos) {
    for (int i = 0; i < 8; i++) {
        if (p.x == attacker_pos.x + dx[i] && p.y == attacker_pos.y + dy[i]) return true;
    }
    return false;
}

Point get_jury_move(Point my_pos, Point opp_pos, bool i_am_white,
                    const vector<vector<int>>& my_target_dist,
                    const vector<vector<int>>& opp_target_dist,
                    Point my_target, Point opp_target) {

    vector<Point> candidates;
    for (int i = 0; i < 8; i++) {
        int nx = my_pos.x + dx[i];
        int ny = my_pos.y + dy[i];
        if (in_bounds(nx, ny)) candidates.push_back({nx, ny});
    }

    for (const auto& mv : candidates) {
        if (mv == opp_pos) return mv;
        if (mv == my_target && !is_attacked(mv, opp_pos)) return mv;
    }

    vector<Point> safe_moves;
    for (const auto& mv : candidates) {
        if (!is_attacked(mv, opp_pos)) safe_moves.push_back(mv);
    }

    const vector<Point>& search_space = (safe_moves.empty() ? candidates : safe_moves);

    int my_d = my_target_dist[my_pos.x][my_pos.y];
    int opp_d = opp_target_dist[opp_pos.x][opp_pos.y];

    bool race_mode = false;
    if (i_am_white) {
        if (my_d <= opp_d) race_mode = true;
    } else {
        if (my_d < opp_d) race_mode = true;
    }

    Point best_move = search_space[0];
    long long best_score = 1e18;

    for (const auto& mv : search_space) {
        long long score;
        if (race_mode) score = my_target_dist[mv.x][mv.y];
        else score = opp_target_dist[mv.x][mv.y];

        if (score < best_score) {
            best_score = score;
            best_move = mv;
        } else if (score == best_score) {

            if (mv.x < best_move.x || (mv.x == best_move.x && mv.y < best_move.y)) {
                best_move = mv;
            }
        }
    }

    return best_move;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    n = inf.readInt();
    m = inf.readInt();
    white_start.x = inf.readInt();
    white_start.y = inf.readInt();
    black_start.x = inf.readInt();
    black_start.y = inf.readInt();

    white_target = {n / 2, m / 2};
    black_target = {n / 2 + 1, m / 2};

    dist_white_target = bfs(white_target);
    dist_black_target = bfs(black_target);

    cout << n << " " << m << endl;
    cout << white_start.x << " " << white_start.y << " " << black_start.x << " " << black_start.y << endl;

    string color_token;
    if (!(cin >> color_token)) finish(_pe, "No color token");

    string color_upper = "";
    for(char c : color_token) color_upper += toupper(c);

    bool contestant_white = (color_upper == "WHITE");
    if (!contestant_white && color_upper != "BLACK") finish(_pe, "Invalid color: " + color_token);

    Point my_pos = (contestant_white ? black_start : white_start);
    Point contest_pos = (contestant_white ? white_start : black_start);
    Point my_target = (contestant_white ? black_target : white_target);
    Point contest_target = (contestant_white ? white_target : black_target);

    const vector<vector<int>>& my_bfs = (contestant_white ? dist_black_target : dist_white_target);
    const vector<vector<int>>& contest_bfs = (contestant_white ? dist_white_target : dist_black_target);

    bool my_turn = !contestant_white;

    while (true) {

        if (contest_pos == contest_target && !is_attacked(contest_pos, my_pos)) {
            finish(_ok, "Contestant reached target safe");
        }
        if (my_pos == my_target && !is_attacked(my_pos, contest_pos)) {
            cout << "-1 -1" << endl;
            finish(_wa, "Jury reached target safe");
        }

        if (my_turn) {
            Point move = get_jury_move(my_pos, contest_pos, !contestant_white, my_bfs, contest_bfs, my_target, contest_target);

            if (move == contest_pos) {
                cout << "-1 -1" << endl;
                finish(_wa, "Jury captured contestant");
            }
            if (move == my_target && !is_attacked(move, contest_pos)) {
                cout << "-1 -1" << endl;
                finish(_wa, "Jury reached target safe");
            }

            cout << move.x << " " << move.y << endl;
            my_pos = move;
            my_turn = false;
        } else {
            string token;
            if (!(cin >> token)) finish(_pe, "Unexpected end of stream");

            if (token == "!") finish(_pe, "Unexpected '!' token");
            if (token == "?") {
                if (!(cin >> token)) finish(_pe, "Broken query");
            }

            int cx, cy;
            try { cx = stoi(token); } catch(...) { finish(_pe, "Token not number: " + token); }
            if (!(cin >> cy)) finish(_pe, "Missing y");

            if (!in_bounds(cx, cy)) {
                cout << "-1 -1" << endl;
                finish(_wa, "Move out of bounds");
            }

            bool valid = false;
            for(int i=0; i<8; i++) {
                if(contest_pos.x + dx[i] == cx && contest_pos.y + dy[i] == cy) { valid = true; break; }
            }
            if (!valid) {
                cout << "-1 -1" << endl;
                finish(_wa, "Invalid knight move");
            }

            contest_pos = {cx, cy};
            contestant_moves++;
            log_metrics();

            if (contest_pos == my_pos) finish(_ok, "Contestant captured jury");

            if (contestant_moves > MOVE_LIMIT) {
                cout << "-1 -1" << endl;
                finish(_wa, "Move limit exceeded");
            }

            my_turn = true;
        }
    }
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

int queries = 0;
const int query_limit = 350;

int N, M;
int TW_x, TW_y;
int TB_x, TB_y;

vector<vector<int>> dist_TW;
vector<vector<int>> dist_TB;

const int dx[] = {1, 1, -1, -1, 2, 2, -2, -2};
const int dy[] = {2, -2, 2, -2, 1, -1, 1, -1};

void log_metrics() {
    tout << "queries=" << queries << endl;
    tout << "query_limit=" << query_limit << endl;
}

void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

void on_exit() {
    log_metrics();
}

bool valid(int x, int y) {
    return x >= 1 && x <= N && y >= 1 && y <= M;
}

bool attacks(int ax, int ay, int tx, int ty) {
    for (int i = 0; i < 8; i++) {
        if (ax + dx[i] == tx && ay + dy[i] == ty) return true;
    }
    return false;
}

vector<vector<int>> bfs(int tx, int ty) {
    vector<vector<int>> d(N + 1, vector<int>(M + 1, -1));
    queue<pair<int, int>> q;

    if (valid(tx, ty)) {
        d[tx][ty] = 0;
        q.push({tx, ty});
    }

    while (!q.empty()) {
        auto [cx, cy] = q.front();
        q.pop();

        for (int i = 0; i < 8; i++) {
            int nx = cx + dx[i];
            int ny = cy + dy[i];
            if (valid(nx, ny) && d[nx][ny] == -1) {
                d[nx][ny] = d[cx][cy] + 1;
                q.push({nx, ny});
            }
        }
    }
    return d;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(on_exit);

    N = inf.readInt();
    M = inf.readInt();
    int x1 = inf.readInt();
    int y1 = inf.readInt();
    int x2 = inf.readInt();
    int y2 = inf.readInt();

    TW_x = N / 2;
    TW_y = M / 2;
    TB_x = N / 2 + 1;
    TB_y = M / 2;

    cout << N << " " << M << endl;
    cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl;

    log_metrics();

    dist_TW = bfs(TW_x, TW_y);
    dist_TB = bfs(TB_x, TB_y);

    string s = ouf.readToken();
    bool user_is_white = (s == "WHITE");

    int wx = x1, wy = y1;
    int bx = x2, by = y2;

    int turn = 0;
    int user_moves_count = 0;

    while (true) {
        bool is_user_turn = (user_is_white ? (turn == 0) : (turn == 1));

        if (is_user_turn) {

            if (user_moves_count >= 350) {
                cout << "-1 -1" << endl;
                finish(_wa, "Limit of 350 moves exceeded");
            }

            int ux = ouf.readInt();
            int uy = ouf.readInt();
            user_moves_count++;
            queries = user_moves_count;
            log_metrics();

            if (ux == -1 && uy == -1) {
                finish(_wa, "User output -1 -1 (resigned)");
            }

            int my_x = (turn == 0) ? wx : bx;
            int my_y = (turn == 0) ? wy : by;

            if (!valid(ux, uy)) {
                cout << "-1 -1" << endl;
                finish(_wa, "Move out of bounds");
            }
            if (!attacks(my_x, my_y, ux, uy)) {
                cout << "-1 -1" << endl;
                finish(_wa, "Invalid knight move");
            }

            if (turn == 0) { wx = ux; wy = uy; }
            else { bx = ux; by = uy; }

            int op_x = (turn == 0) ? bx : wx;
            int op_y = (turn == 0) ? by : wy;
            int my_tx = (turn == 0) ? TW_x : TB_x;
            int my_ty = (turn == 0) ? TW_y : TB_y;

            if (wx == bx && wy == by) finish(_ok, "User captured opponent");

            if ((turn == 0 ? wx : bx) == my_tx && (turn == 0 ? wy : by) == my_ty) {

                if (!attacks(op_x, op_y, (turn == 0 ? wx : bx), (turn == 0 ? wy : by))) {
                    finish(_ok, "User reached target safely");
                }
            }

        } else {

            int my_x = (turn == 0) ? wx : bx;
            int my_y = (turn == 0) ? wy : by;
            int op_x = (turn == 0) ? bx : wx;
            int op_y = (turn == 0) ? by : wy;

            int my_tx = (turn == 0) ? TW_x : TB_x;
            int my_ty = (turn == 0) ? TW_y : TB_y;

            const auto& my_d = (turn == 0) ? dist_TW : dist_TB;
            const auto& op_d = (turn == 0) ? dist_TB : dist_TW;

            vector<pair<int, int>> moves;
            for (int i = 0; i < 8; i++) {
                int nx = my_x + dx[i];
                int ny = my_y + dy[i];
                if (valid(nx, ny)) moves.push_back({nx, ny});
            }

            pair<int, int> best_move = {-1, -1};

            for (auto p : moves) {

                if (p.first == op_x && p.second == op_y) {
                    best_move = p;
                    break;
                }

                if (p.first == my_tx && p.second == my_ty) {
                    if (!attacks(op_x, op_y, p.first, p.second)) {
                        best_move = p;
                        break;
                    }
                }
            }

            if (best_move.first == -1) {

                vector<pair<int, int>> safe_moves;
                for (auto p : moves) {

                    if (!attacks(op_x, op_y, p.first, p.second)) {
                        safe_moves.push_back(p);
                    }
                }

                vector<pair<int, int>>& candidates = safe_moves.empty() ? moves : safe_moves;

                int d_me = my_d[my_x][my_y];
                int d_opp = op_d[op_x][op_y];

                bool race = (turn == 0) ? (d_me <= d_opp) : (d_me < d_opp);

                best_move = candidates[0];
                tuple<int, int, int> best_score = {1e9, 1e9, 1e9};

                for (auto p : candidates) {
                    int v1 = my_d[p.first][p.second];
                    int v2 = op_d[p.first][p.second];

                    tuple<int, int, int> score;
                    if (race) {

                        score = {v1, v2, 0};
                    } else {

                        score = {v2, v1, 0};
                    }

                    if (score < best_score) {
                        best_score = score;
                        best_move = p;
                    }
                }
            }

            cout << best_move.first << " " << best_move.second << endl;

            if (turn == 0) { wx = best_move.first; wy = best_move.second; }
            else { bx = best_move.first; by = best_move.second; }

            if (wx == bx && wy == by) {
                cout << "-1 -1" << endl;
                finish(_wa, "Interactor captured user");
            }
            if ((turn == 0 ? wx : bx) == my_tx && (turn == 0 ? wy : by) == my_ty) {
                int op_nx = (turn == 0) ? bx : wx;
                int op_ny = (turn == 0) ? by : wy;
                if (!attacks(op_nx, op_ny, best_move.first, best_move.second)) {
                    cout << "-1 -1" << endl;
                    finish(_wa, "Interactor reached target safe");
                }
            }
        }

        turn = 1 - turn;
    }

    return 0;
}


All problems in this contest share the same statement, the only difference is the test your solution runs on. For further information on scoring please refer to "Scoring" section of the statement.

This is an interactive problem.

Imagine you are a treasure hunter, a very skillful one. One day you came across an ancient map which could help you to become rich. The map shows multiple forestry roads, and at each junction there is a treasure. So, you start your journey hoping to retrieve all the hidden treasures, but you don't know yet that there is a wicked wizard standing against you and craving to tangle up these roads and impede your achievements.

The treasure map is represented as an undirected graph in which vertices correspond to junctions and edges correspond to roads. Your path begins at a certain fixed vertex with a label known to you. Every time you come to a vertex that you have not been to before, you dig up a treasure chest and put a flag in this vertex. At the initial vertex you'll find a treasure chest immediately and, consequently, you'll put a flag there immediately as well.

When you are standing at the junction you can see for each of the adjacent vertices its degree and if there is a flag there. There are no other things you can see from there. Besides, the power of the wicked wizard is so great that he is able to change the location of the roads and junctions on the map without changing the graph structure. Therefore, the sequence of the roads coming from the junction $v$ might be different each time you come in the junction $v$. However, keep in mind that the set of adjacent crossroads does not change, and you are well aware of previously dug treasures at each adjacent to $v$ vertex.

Your goal is to collect treasures from all vertices of the graph as fast as you can. Good luck in hunting!

Interaction

On the first line the interactor prints an integer $t$ ($1 \leq t \leq 5$) — the number of maps for which you need to solve the problem.

Then for each of the $t$ maps interactor firstly prints the graph description and after that interaction on this map starts. The map description is given in the following format.

The first line contains four integers $n, m, start, base\_move\_count$ ($2 \leq n \leq 300$, $1 \leq m \leq min(\frac{n(n-1)}{2}, 25n)$, $1 \leq start \leq n$, $1000 \leq base\_move\_count \leq 30000$) — the number of vertices and edges in the graph, the label of the vertex where you start the journey and some base move count, on which the score for the map depends. It's guaranteed that the jury has a solution traversing the map using not more than $base\_move\_count$ moves with high probability.

The next $m$ lines contain descriptions of the edges of the graph $u, v$ ($1 \leq u, v \leq n$, $u \neq v$). It is guaranteed that the graph is connected, does not contain multiple edges and the degrees of all vertices do not exceed 50.

You can find map descriptions for all tests in the archive 'map\_descriptions.zip' which you can find in any of the archives 'problem-X-materials.zip' in the section "Contest materials" — they are all the same.

After that the interaction begins. The interactor prints vertex descriptions in the following format:

R~d~deg\_1~flag\_1~deg\_2~flag\_2 \ldots deg\_d~flag\_d, where $d$ is the degree of the current vertex, $deg_i$ is the degree of the $i$-th vertex adjacent to the current one, and $flag_i$ (0 or 1) is an indicator if the $i$-th adjacent vertex contains a flag. The order of neighbors in the vertex description is chosen by the interactor uniformly at random independently each time. Please keep in mind that you are not given the actual labels of adajacent vertices.

In response to the description of the vertex you should print a single integer $i$ ($1 \leq i \leq d$), which means that you have chosen the vertex with description $deg_i~flag_i$. Remember to use the flush operation after each output. If your output is invalid, you will get a "Wrong Answer" verdict.

When you have visited all the vertices of the graph at least once, the interactor prints the string "AC" instead of the vertex description. If you use more than $2 \cdot base\_move\_count$ moves, the interactor prints the string "F". In both cases, you have to either start reading the description of the next map, or terminate the program, if it has been the last map in the test.

Below the example of interaction is presented. Note that the test from the example is not the same that your solution will be tested on.

```
|  |  |
| --- | --- |
| Interactor | Solution |
| 1 |  |
| 3 3 1 1000 |  |
| 1 2 |  |
| 2 3 |  |
| 3 1 |  |
| R 2 2 0 2 0 |  |
|  | 1 |
| R 2 2 0 2 1 |  |
|  | 2 |
| R 2 2 0 2 1 |  |
|  | 1 |
| AC |  |
```

Scoring

All problems of this contest share the same statement and differ only in the test. Each problem contains one test. Map descriptions for the test are available to look at in the archive.

Each test consists of several maps.

The solution score for the problem will be $0$ in case your solution for some map failed to get an answer "AC" or "F". If the solution correctly interacted with the interactor on all $t$ maps, the score for the task will be equal to the sum of the scores for each of the maps.

If you have successfully passed all vertices of a graph with $n$ vertices using $moves$ moves, the score for the map is calculated as follows. Denote

base\\_fraction=\frac{base\\_move\\_count + 1}{n},sol\\_fraction=\frac{moves+1}{n},c=\frac{90}{\sqrt{base\\_fraction - 1}}.

Then:

* if $moves \leq base\_move\_count$, you get $100-c \sqrt{sol\_fraction - 1}$ points.
* if $base\_move\_count < moves \leq 2 \cdot base\_move\_count$, you get $20 - \frac{10\cdot(moves + 1)}{base\_move\_count + 1}$ points.

If you use more than $2 \cdot base\_move\_count$ moves, you get 0 points for the map.

For each problem the solution with the highest score is chosen. Please note that the maximum is chosen for the entire test as a whole, not for each separate map.

The final result of the participant is the sum of points for each of the problems.

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static mt19937 rng(42);

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

static int read_choice_index() {
    string token;
    if (!(cin >> token)) {
        finish(_wa, "Unexpected EOF while reading move");
    }
    if (token.empty()) {
        finish(_wa, "Invalid move token");
    }
    for (char ch : token) {
        if (ch < '0' || ch > '9') {
            finish(_wa, "Invalid move token");
        }
    }
    try {
        size_t pos = 0;
        long long v = stoll(token, &pos);
        if (pos != token.size() || v > numeric_limits<int>::max()) {
            finish(_wa, "Invalid move token");
        }
        return (int)v;
    } catch (...) {
        finish(_wa, "Invalid move token");
    }
    return -1;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = inf.readInt(1, 5, "t");
    cout << t << endl;
    cout.flush();

    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt(2, 300, "n");
        int max_m = (int)min(1LL * n * (n - 1) / 2, 25LL * n);
        int m = inf.readInt(1, max_m, "m");
        int start = inf.readInt(1, n, "start");
        int base_move_count = inf.readInt(1000, 30000, "base_move_count");

        long long map_limit = 2LL * base_move_count;
        query_limit += map_limit;
        if (tc == 0) log_metrics();

        vector<vector<int>> adj(n + 1);
        vector<int> deg(n + 1, 0);
        vector<pair<int, int>> edges;
        edges.reserve(m);

        for (int i = 0; i < m; ++i) {
            int u = inf.readInt(1, n, "u");
            int v = inf.readInt(1, n, "v");
            adj[u].push_back(v);
            adj[v].push_back(u);
            deg[u]++;
            deg[v]++;
            edges.push_back({u, v});
        }

        cout << n << " " << m << " " << start << " " << base_move_count << endl;
        for (const auto& e : edges) {
            cout << e.first << " " << e.second << endl;
        }
        cout.flush();

        vector<char> visited(n + 1, 0);
        visited[start] = 1;
        int visited_count = 1;
        int cur = start;
        long long moves = 0;

        while (true) {
            if (visited_count == n) {
                cout << "AC" << endl;
                cout.flush();
                break;
            }
            if (moves > map_limit) {
                cout << "F" << endl;
                cout.flush();
                break;
            }

            vector<int> neighbors = adj[cur];
            shuffle(neighbors.begin(), neighbors.end(), rng);

            cout << "R " << neighbors.size();
            for (int v : neighbors) {
                cout << " " << deg[v] << " " << (visited[v] ? 1 : 0);
            }
            cout << endl;
            cout.flush();

            int choice = read_choice_index();
            if (choice < 1 || choice > (int)neighbors.size()) {
                finish(_wa, format("Invalid choice %d (expected 1..%d)", choice, (int)neighbors.size()));
            }

            cur = neighbors[choice - 1];
            moves++;
            queries++;
            if (queries % 200 == 0) log_metrics();

            if (!visited[cur]) {
                visited[cur] = 1;
                visited_count++;
            }
        }
    }

    finish(_ok, "All maps processed");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static mt19937 rng(239);

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

static int read_choice_index() {
    string token;
    if (!(cin >> token)) {
        finish(_wa, "Unexpected EOF while reading move");
    }
    if (token.empty()) {
        finish(_wa, "Invalid move token");
    }
    for (char ch : token) {
        if (ch < '0' || ch > '9') {
            finish(_wa, "Invalid move token");
        }
    }
    try {
        size_t pos = 0;
        long long v = stoll(token, &pos);
        if (pos != token.size() || v > numeric_limits<int>::max()) {
            finish(_wa, "Invalid move token");
        }
        return (int)v;
    } catch (...) {
        finish(_wa, "Invalid move token");
    }
    return -1;
}

struct DisplayEntry {
    int v;
    int degree;
    int flag;
};

static void run_map(int n, int m, int start, int base_move_count, const vector<pair<int, int>>& edges) {
    vector<vector<int>> adj(n + 1);
    vector<int> deg(n + 1, 0);
    for (const auto& e : edges) {
        adj[e.first].push_back(e.second);
        adj[e.second].push_back(e.first);
        deg[e.first]++;
        deg[e.second]++;
    }

    cout << n << " " << m << " " << start << " " << base_move_count << endl;
    for (const auto& e : edges) {
        cout << e.first << " " << e.second << endl;
    }
    cout.flush();

    long long map_limit = 2LL * base_move_count;
    vector<char> visited(n + 1, 0);
    visited[start] = 1;
    int visited_count = 1;
    int cur = start;
    long long moves = 0;

    while (true) {
        if (visited_count == n) {
            cout << "AC" << endl;
            cout.flush();
            return;
        }
        if (moves > map_limit) {
            cout << "F" << endl;
            cout.flush();
            return;
        }

        const vector<int>& neighbors = adj[cur];
        int d = (int)neighbors.size();

        vector<DisplayEntry> display;
        display.reserve(d);
        for (int v : neighbors) {
            display.push_back({v, deg[v], visited[v] ? 1 : 0});
        }
        shuffle(display.begin(), display.end(), rng);

        cout << "R " << d;
        for (const auto& e : display) {
            cout << " " << e.degree << " " << e.flag;
        }
        cout << endl;
        cout.flush();

        int choice = read_choice_index();
        if (choice < 1 || choice > d) {
            finish(_wa, format("Invalid choice %d (expected 1..%d)", choice, d));
        }

        cur = display[choice - 1].v;
        if (!visited[cur]) {
            visited[cur] = 1;
            visited_count++;
        }

        moves++;
        queries++;
        if (queries % 200 == 0) log_metrics();
        if (queries > 2000000) finish(_pe, "Hard query cap exceeded");
    }
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = inf.readInt(1, 5, "t");
    cout << t << endl;
    cout.flush();

    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt(2, 300, "n");
        int max_m = (int)min(1LL * n * (n - 1) / 2, 25LL * n);
        int m = inf.readInt(1, max_m, "m");
        int start = inf.readInt(1, n, "start");
        int base_move_count = inf.readInt(1000, 30000, "base_move_count");

        query_limit += 2LL * base_move_count;
        if (tc == 0) log_metrics();

        vector<pair<int, int>> edges;
        edges.reserve(m);
        for (int i = 0; i < m; ++i) {
            int u = inf.readInt(1, n, "u");
            int v = inf.readInt(1, n, "v");
            edges.push_back({u, v});
        }

        run_map(n, m, start, base_move_count, edges);
    }

    finish(_ok, "All maps processed");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char* argv[]) {

    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");
    int seed_val = atoi(argv[1]);

    cout << 1 << endl;

    int n;
    vector<pair<int, int>> edges;

    if (seed_val <= 5) {

        if (seed_val == 1) {

            n = 2;
            edges.push_back({1, 2});
        } else if (seed_val == 2) {

            n = 300;
            for (int i = 1; i < n; i++) edges.push_back({i, i + 1});
        } else if (seed_val == 3) {

            n = 300;
            for (int i = 1; i < n; i++) edges.push_back({i, i + 1});
            edges.push_back({n, 1});
        } else if (seed_val == 4) {

            n = 51;
            for (int i = 2; i <= n; i++) edges.push_back({1, i});
        } else {

            n = 127;
            for (int i = 2; i <= n; i++) edges.push_back({i / 2, i});
        }
    } else {

        n = rnd.next(100, 300);

        set<pair<int, int>> edge_set;
        vector<int> deg(n + 1, 0);

        vector<int> p(n);
        iota(p.begin(), p.end(), 1);
        shuffle(p.begin(), p.end());

        for (int i = 1; i < n; i++) {

            bool hooked = false;

            int attempts = 0;
            while (attempts < 5) {
                int parent_idx = rnd.next(0, i - 1);
                int u = p[i];
                int v = p[parent_idx];
                if (deg[v] < 50) {
                    if (u > v) swap(u, v);
                    edge_set.insert({u, v});
                    deg[u]++;
                    deg[v]++;
                    hooked = true;
                    break;
                }
                attempts++;
            }

            if (!hooked) {
                for (int j = 0; j < i; j++) {
                    int u = p[i];
                    int v = p[j];
                    if (deg[v] < 50) {
                        if (u > v) swap(u, v);
                        edge_set.insert({u, v});
                        deg[u]++;
                        deg[v]++;
                        hooked = true;
                        break;
                    }
                }
            }

        }

        int max_possible_edges = min(n * (n - 1) / 2, 25 * n);
        int current_m = edge_set.size();
        int target_m;

        if (mode == "adp") {

            target_m = rnd.next(max(current_m, max_possible_edges - 500), max_possible_edges);
        } else {

            target_m = rnd.next(current_m, min(max_possible_edges, current_m + 4 * n));
        }

        int attempts = 0;
        while (current_m < target_m && attempts < 200000) {
            attempts++;
            int u = rnd.next(1, n);
            int v = rnd.next(1, n);
            if (u == v) continue;
            if (u > v) swap(u, v);

            if (deg[u] >= 50 || deg[v] >= 50) continue;
            if (edge_set.count({u, v})) continue;

            edge_set.insert({u, v});
            deg[u]++;
            deg[v]++;
            current_m++;
        }

        for (auto e : edge_set) edges.push_back(e);
    }

    int start = rnd.next(1, n);

    int base_moves = rnd.next(1000, max(1000, 10 * n));
    if (base_moves > 30000) base_moves = 30000;

    cout << n << " " << edges.size() << " " << start << " " << base_moves << endl;
    for (const auto& e : edges) {
        cout << e.first << " " << e.second << endl;
    }

    return 0;
}


What walks on four feet in the morning, two in the afternoon, and three at night?

This is an interactive problem.

Sphinx's duty is to guard the city of Thebes by making sure that no unworthy traveler crosses its gates. Only the ones who answer her riddle timely and correctly (or get an acc for short) are allowed to pass. As of those who fail, no one heard of them ever again...

So you don't have a choice but to solve the riddle. Sphinx has an array $a_1, a_2, \ldots, a_n$ of nonnegative integers strictly smaller than $2^b$ and asked you to find the maximum value among its elements. Of course, she will not show you the array, but she will give you $n$ and $b$. As it is impossible to answer this riddle blindly, you can ask her some questions. For given $i, y$, she'll answer you whether $a_i$ is bigger than $y$. As sphinxes are not very patient, you can ask at most $3 \cdot (n + b) $ such questions.

Although cunning, sphinxes are honest. Even though the array can change between your queries, answers to the previously asked questions will remain valid.

Input

The first line contains two integers $n$ and $b$ ($1 \leq n, b \leq 200$). The remaining parts of the input will be given throughout the interaction process.

Interaction

In each round your program must output a single line with an integer $i$ ($0 \leq i \leq n$) and a binary string of length exactly $b$ denoting the binary representation of $y$ (most significant bit first).

If $i > 0$, this line encodes the question: Is $a_i$ bigger than $y$?. There should be at most $3 \cdot (n+b)$ such lines; after each of them, the interactor will print yes or no in a single line.

If $i = 0$, this is the last round of interaction, after which your program should terminate, and $y$ should be the maximal value among the elements of Sphinx's array. Note that this round does not count to the query limit.

Note that the interactor is adaptive.

After printing a query, do not forget to output the end of the line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* see the documentation for other languages.

If your solution does not correctly follow the interaction guideline above, it may receive an arbitrary verdict. Otherwise, your program will receive the Wrong Answer judgment if it reports the wrong maximum.

Examples

Input

```
5 3

yes

no

no

no

no

yes
```

Output

```
5 101

5 110

4 100

3 101

2 001

1 000

0 110
```

Input

```
4 3

no

no

no

no
```

Output

```
1 000

2 000

3 000

4 000

0 000
```

Input

```
1 1
```

Output

```
0 0
```

Note

In all examples, the sequence is fixed beforehand.

In the first example, the sequence is $2, 1, 4, 0, 6$.

In the second example, the sequence is $0, 0, 0, 0$.

In the third example, the sequence is $0$.

Note that if the interactor was adaptive, then the interaction in the first and the third example would not be sufficient to return the correct value of maximum.

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static bool finished = false;

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    finished = true;
    quitf(verdict, "%s", msg.c_str());
}

string div2(string s, int &rem) {
    string res = "";
    rem = 0;
    bool leading_zeros = true;
    for (char c : s) {
        int d = c - '0';
        int val = d + rem * 10;
        int q = val / 2;
        rem = val % 2;

        if (q != 0) leading_zeros = false;
        if (!leading_zeros) res += to_string(q);
    }
    if (res.empty()) return "0";
    return res;
}

string toBin(string s, int b) {
    string bin = "";
    if (s == "0") return string(b, '0');

    while (s != "0") {
        int rem;
        s = div2(s, rem);
        bin += (char)('0' + rem);
    }

    while ((int)bin.size() < b) bin += '0';

    reverse(bin.begin(), bin.end());

    if ((int)bin.size() > b) bin = bin.substr(bin.size() - b);

    return bin;
}

int main(int argc, char* argv[]) {
    registerInteraction(argc, argv);

    atexit([](){ if (!finished) log_metrics(); });

    int n = inf.readInt(1, 200, "n");
    int b = inf.readInt(1, 200, "b");

    query_limit = 3LL * (n + b);

    log_metrics();

    vector<string> A(n);
    string true_max = "";

    for (int i = 0; i < n; i++) {
        string dec = inf.readToken();
        A[i] = toBin(dec, b);

        if (true_max == "" || A[i] > true_max) {
            true_max = A[i];
        }
    }

    cout << n << " " << b << endl;

    long long hard_cap = max(200000LL, 10 * query_limit);

    while (true) {
        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded (potential infinite loop)");
        }

        string token;
        if (!(cin >> token)) {
            finish(_pe, "Unexpected EOF while reading query");
        }

        int idx = -1;
        string y_str = "";

        if (token == "?") {
            if (!(cin >> idx >> y_str)) finish(_pe, "Invalid query format after '?'");
        } else if (token == "!") {
            if (!(cin >> y_str)) finish(_pe, "Invalid answer format after '!'");
            idx = 0;
        } else {

            try {
                size_t pos;
                idx = stoi(token, &pos);
                if (pos != token.size()) finish(_pe, "First token is not a valid integer");
            } catch (...) {
                finish(_pe, "First token is not a valid integer");
            }
            if (!(cin >> y_str)) finish(_pe, "Expected binary string as second parameter");
        }

        if (idx == 0) {

            if ((int)y_str.size() != b) {
                finish(_pe, format("Answer string length must be %d", b));
            }
            for (char c : y_str) {
                if (c != '0' && c != '1') finish(_pe, "Answer string must be binary");
            }

            if (y_str == true_max) {
                finish(_ok, "Correct maximum found");
            } else {
                finish(_wa, format("Incorrect maximum. Expected %s, got %s", true_max.c_str(), y_str.c_str()));
            }
        } else {

            if (idx < 1 || idx > n) {
                finish(_pe, format("Index %d out of range [1, %d]", idx, n));
            }
            if ((int)y_str.size() != b) {
                finish(_pe, format("Query string length must be %d", b));
            }
            for (char c : y_str) {
                if (c != '0' && c != '1') finish(_pe, "Query string must be binary");
            }

            queries++;

            if (queries % 10 == 0) log_metrics();

            bool result = (A[idx - 1] > y_str);
            cout << (result ? "yes" : "no") << endl;
        }
    }

    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 0;

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

struct BigInt {
    vector<int> d;

    BigInt() {}

    BigInt(string s) {
        for (int i = (int)s.size() - 1; i >= 0; i--) {
            if (s[i] == '1') d.push_back(1);
            else d.push_back(0);
        }
        trim();
    }

    BigInt(int v) {
        if (v > 0) d.push_back(1);
        else d.push_back(0);
    }

    void trim() {
        while (d.size() > 1 && d.back() == 0) d.pop_back();
        if (d.empty()) d.push_back(0);
    }

    bool operator<(const BigInt& o) const {
        if (d.size() != o.d.size()) return d.size() < o.d.size();
        for (int i = (int)d.size() - 1; i >= 0; i--)
            if (d[i] != o.d[i]) return d[i] < o.d[i];
        return false;
    }
    bool operator<=(const BigInt& o) const { return !(o < *this); }
    bool operator>(const BigInt& o) const { return o < *this; }
    bool operator>=(const BigInt& o) const { return !(*this < o); }
    bool operator==(const BigInt& o) const { return d == o.d; }
    bool operator!=(const BigInt& o) const { return d != o.d; }

    BigInt operator+(const BigInt& o) const {
        BigInt res; res.d.clear();
        int carry = 0;
        size_t n = max(d.size(), o.d.size());
        for (size_t i = 0; i < n || carry; i++) {
            int val = carry + (i < d.size() ? d[i] : 0) + (i < o.d.size() ? o.d[i] : 0);
            res.d.push_back(val % 2);
            carry = val / 2;
        }
        return res;
    }

    BigInt operator-(const BigInt& o) const {
        BigInt res; res.d.clear();
        int borrow = 0;
        for (size_t i = 0; i < d.size(); i++) {
            int val = d[i] - borrow - (i < o.d.size() ? o.d[i] : 0);
            if (val < 0) {
                val += 2;
                borrow = 1;
            } else {
                borrow = 0;
            }
            res.d.push_back(val);
        }
        res.trim();
        return res;
    }
};

BigInt one(1);

int main(int argc, char** argv) {

    registerInteraction(argc, argv);
    atexit(log_metrics);

    int n = inf.readInt();
    int b = inf.readInt();
    query_limit = 3LL * (n + b);

    bool fixed_mode = false;
    vector<BigInt> fixed_arr;
    if (!inf.seekEof()) {
        fixed_mode = true;
        for(int i=0; i<n; i++) {
            string s = inf.readToken();
            fixed_arr.push_back(BigInt(s));
        }
    }

    string all_ones(b, '1');
    string all_zeros(b, '0');
    BigInt max_val(all_ones);
    BigInt min_val(all_zeros);

    vector<BigInt> L(n + 1, min_val);
    vector<BigInt> R(n + 1, max_val);

    cout << n << " " << b << endl;

    while (true) {

        if (queries > max(20000LL, 10 * query_limit)) {
            finish(_pe, "Hard query limit exceeded");
        }

        int i;
        if (!(cin >> i)) break;

        string y_str;
        cin >> y_str;

        if (i < 0 || i > n) finish(_pe, "Index i out of range");
        if (y_str.size() != (size_t)b) finish(_pe, "Binary string y wrong length");
        for(char c : y_str) if(c != '0' && c != '1') finish(_pe, "y not binary");

        BigInt y(y_str);

        if (i == 0) {

            if (fixed_mode) {
                BigInt true_max = fixed_arr[0];
                for(int k=1; k<n; k++) if(fixed_arr[k] > true_max) true_max = fixed_arr[k];
                if (y == true_max) finish(_ok, "Correct maximum (fixed)");
                else finish(_wa, "Wrong maximum (fixed)");
            } else {

                for(int k=1; k<=n; k++) {
                     if (R[k] > y) {

                         finish(_wa, "Found feasible array with maximum > y");
                     }
                }

                bool forced_at_y = false;
                for(int k=1; k<=n; k++) {
                    if (L[k] == y) {
                        forced_at_y = true;
                        break;
                    }
                }

                if (!forced_at_y) {

                    finish(_wa, "Found feasible array with maximum < y");
                }

                finish(_ok, "Correct");
            }
        }

        queries++;
        log_metrics();

        bool ans_yes = false;

        if (fixed_mode) {
            if (fixed_arr[i-1] > y) ans_yes = true;
            else ans_yes = false;
        } else {

            bool yes_possible = (y < R[i]);

            bool no_possible = (L[i] <= y);

            if (!yes_possible && !no_possible) {
                finish(_pe, "Inconsistent state (interactor error)");
            } else if (!yes_possible) {
                ans_yes = false;
            } else if (!no_possible) {
                ans_yes = true;
            } else {

                BigInt size_yes = R[i] - y;
                BigInt size_no = (y - L[i]) + one;

                if (size_yes > size_no) ans_yes = true;
                else ans_yes = false;
            }

            if (ans_yes) {

                L[i] = y + one;
            } else {

                R[i] = y;
            }
        }

        if (ans_yes) cout << "yes" << endl;
        else cout << "no" << endl;
    }

    finish(_pe, "Unexpected EOF from contestant");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

string bitsToDecimal(const vector<int>& bits) {
    if (bits.empty()) return "0";
    vector<int> digits;
    digits.push_back(0);

    for (int b : bits) {
        int carry = b;
        for (int &d : digits) {
            int val = d * 2 + carry;
            d = val % 10;
            carry = val / 10;
        }
        while (carry) {
            digits.push_back(carry % 10);
            carry /= 10;
        }
    }

    if (digits.empty()) return "0";
    string res = "";
    for (auto it = digits.rbegin(); it != digits.rend(); ++it) {
        res += to_string(*it);
    }
    return res;
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");

    int n = opt<int>("n", -1);
    int b = opt<int>("b", -1);

    long long seedVal = 0;
    if (argc > 1) seedVal = atoll(argv[1]);

    if (n == -1 && b == -1) {
        if (seedVal == 1) { n = 5; b = 3; }
        else if (seedVal == 2) { n = 4; b = 3; }
        else if (seedVal == 3) { n = 1; b = 1; }
        else if (seedVal == 4) { n = 200; b = 200; }
        else if (seedVal == 5) { n = 200; b = 1; }
        else if (seedVal == 6) { n = 1; b = 200; }
    }

    if (n == -1) {
        int r = rnd.next(3);
        if (r == 0) n = rnd.next(1, 10);
        else n = rnd.next(100, 200);
    }
    if (b == -1) {
        int r = rnd.next(3);
        if (r == 0) b = rnd.next(1, 10);
        else b = rnd.next(100, 200);
    }

    cout << n << " " << b << endl;

    if (mode == "adp") {

        return 0;
    }

    vector<string> a;

    int type = rnd.next(100);

    if (seedVal == 1) type = 0;
    else if (seedVal == 2) type = 55;
    else if (seedVal == 3) type = 0;

    if (type < 50) {

        for(int i = 0; i < n; i++) {
            vector<int> bits(b);
            for(int j = 0; j < b; j++) bits[j] = rnd.next(0, 1);
            a.push_back(bitsToDecimal(bits));
        }
    } else if (type < 60) {

        for(int i = 0; i < n; i++) a.push_back("0");
    } else if (type < 70) {

        vector<int> bits(b, 1);
        string mx = bitsToDecimal(bits);
        for(int i = 0; i < n; i++) a.push_back(mx);
    } else if (type < 85) {

        int p = rnd.next(1, max(1, b - 1));
        vector<int> prefix(p);
        for(int j = 0; j < p; j++) prefix[j] = rnd.next(0, 1);
        for(int i = 0; i < n; i++) {
            vector<int> bits = prefix;
            for(int j = p; j < b; j++) bits.push_back(rnd.next(0, 1));
            a.push_back(bitsToDecimal(bits));
        }
    } else {

        vector<int> mx_bits(b);
        for(int j = 0; j < b; j++) mx_bits[j] = rnd.next(0, 1);
        string mx_s = bitsToDecimal(mx_bits);
        a.push_back(mx_s);

        for(int i = 1; i < n; i++) {
            if (rnd.next(2)) {

                vector<int> bits(b);
                for(int j = 0; j < b; j++) bits[j] = rnd.next(0, 1);
                a.push_back(bitsToDecimal(bits));
            } else {

                vector<int> sm = mx_bits;
                vector<int> ones;
                for(int k = 0; k < b; k++) if(sm[k]) ones.push_back(k);
                if(!ones.empty()) {
                    int idx = ones[rnd.next(ones.size())];
                    sm[idx] = 0;
                    for(int k = idx + 1; k < b; k++) sm[k] = rnd.next(0, 1);
                }
                a.push_back(bitsToDecimal(sm));
            }
        }
        shuffle(a.begin(), a.end());
    }

    for(int i = 0; i < n; i++) {
        cout << a[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;

    return 0;
}


There's no such thing as luck in this world. The victor is decided before the game even starts.

— No Game No Life

This is an interactive problem.

One day, Sora and Shiro feel bored again, so they decide to settle it with a game.

At the beginning, Sora gives Shiro a permutation$$$^{\text{∗}}$$$ $$$p\_1,p\_2,\ldots,p\_n$$$ of length $$$n$$$. In each operation, Shiro may select two distinct indices $$$x$$$ and $$$y$$$ ($$$1\le x\ne y\le n$$$). Then Sora flips a fair coin:

* With probability $$$0.5$$$, Sora swaps $$$p\_x$$$ and $$$p\_y$$$;
* With probability $$$0.5$$$, Sora swaps $$$p\_{n-x+1}$$$ and $$$p\_{n-y+1}$$$.

After the operation, Sora replies with the actual pair of indices that were swapped, so that Shiro can update her local permutation accordingly.

Shiro's goal is to sort the permutation $$$p$$$ in ascending order by using at most $$$\lfloor 2.5n+800\rfloor$$$ operations. Help her!

$$$^{\text{∗}}$$$A permutation of length $$$n$$$ is an array consisting of $$$n$$$ distinct integers from $$$1$$$ to $$$n$$$ in arbitrary order. For example, $$$[2,3,1,5,4]$$$ is a permutation, but $$$[1,2,2]$$$ is not a permutation ($$$2$$$ appears twice in the array), and $$$[1,3,4]$$$ is also not a permutation ($$$n=3$$$ but there is $$$4$$$ in the array).

Input

Each test contains multiple test cases. The first line contains the number of test cases $$$t$$$ ($$$1 \le t \le 100$$$). The description of the test cases follows.

The first line of each test case contains a single integer $$$n$$$ ($$$1\le n\le 4000$$$) — the length of $$$p$$$.

The second line contains $$$n$$$ integers $$$p\_1,p\_2,\ldots,p\_n$$$ — the elements of $$$p$$$.

It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$2\cdot 10^4$$$.

It is guaranteed that there are $$$50$$$ tests in this problem.

Interaction

For each test case, you can use at most $$$\lfloor 2.5n+800\rfloor$$$ moves to sort the permutation $$$p$$$ in ascending order.

To make a move, you should print a new line in the following format:

* $$$\mathtt{?}\; x\; y$$$ ($$$1 \le x \ne y \le n$$$) — the two indices that Shiro selects in this move.

As a response to the move, you will receive two integers $$$u$$$ and $$$v$$$ — the actual pair of indices that Sora swapped. It is guaranteed that $$$(u, v)$$$ is randomly selected from $$$(x, y)$$$ and $$$(n-x+1, n-y+1)$$$ with equal probability.

To report that the permutation has been sorted in ascending order, you should print a new line with a single character $$$\mathtt{!}$$$. This does not count as one of the $$$\lfloor 2.5n+800\rfloor$$$ moves.

After that, proceed to the next test case or terminate the program if it was the last test case.

After printing each query do not forget to output the end of line and flush$$$^{\text{∗}}$$$ the output. Otherwise, you will get Idleness limit exceeded verdict.

If, at any interaction step, you read $$$-1$$$ instead of valid data, your solution must exit immediately. This means that your solution will receive Wrong answer because of an invalid query or any other mistake. Failing to exit can result in an arbitrary verdict because your solution will continue to read from a closed stream.

$$$^{\text{∗}}$$$To flush, use:

* fflush(stdout) or cout.flush() in C++;
* sys.stdout.flush() in Python;
* see the documentation for other languages.

Example

Input

```
2
5
5 1 3 4 2

1 5

2 1

2
1 2
```

Output

```
? 1 5

? 4 5

!

!
```

Note

In the first test case, $$$n=5$$$ and the initial permutation is $$$[5,1,3,4,2]$$$.

* We print ? 1 5. The judge replies 1 5, meaning positions $$$1$$$ and $$$5$$$ are swapped (no mirroring). The array becomes $$$[2,1,3,4,5]$$$.
* We print ? 4 5. The judge replies 2 1, which is the mirror of $$${4,5}$$$ because with $$$n=5$$$ we have $$$n-4+1=2$$$ and $$$n-5+1=1$$$. Thus we must swap positions $$$2$$$ and $$$1$$$. The array becomes $$$[1,2,3,4,5]$$$.
* The permutation is now sorted, so we print !. The answer line does not count toward the operation limit.

In the second test case, the given permutation is already increasing, so we just need to output !.

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

static uint64_t splitmix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15ULL;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;
    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;
    return x ^ (x >> 31);
}

struct TestCase {
    int n;
    vector<int> p;
    vector<int> pos;
    uint64_t seed;
};

static bool isSorted(const vector<int>& p) {
    for (int i = 1; i < (int)p.size(); ++i) {
        if (p[i] != i) return false;
    }
    return true;
}

static uint64_t hashPermutation(int n, const vector<int>& p) {
    uint64_t h = 0x243f6a8885a308d3ULL ^ (uint64_t)n * 0x9e3779b97f4a7c15ULL;
    for (int i = 1; i <= n; ++i) {
        uint64_t x = (uint64_t)p[i];
        uint64_t mix = x + 0x9e3779b97f4a7c15ULL * (uint64_t)i;
        h = splitmix64(h ^ mix);
    }
    return h;
}

static int coinFlip(const TestCase& tc, long long qidx1based) {

    uint64_t v = splitmix64(tc.seed + (uint64_t)qidx1based * 0x9e3779b97f4a7c15ULL);
    return (int)((v >> 63) & 1ULL);
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    int t = inf.readInt(1, 100, "t");
    vector<TestCase> tests;
    tests.reserve(t);

    long long total_limit = 0;
    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt(1, 4000, "n");
        vector<int> p(n + 1), pos(n + 1, 0);
        vector<char> seen(n + 1, 0);
        for (int i = 1; i <= n; ++i) {
            int v = inf.readInt(1, n, "p[i]");
            if (seen[v]) finish(_fail, "Invalid hidden input: not a permutation");
            seen[v] = 1;
            p[i] = v;
            pos[v] = i;
        }
        TestCase cs;
        cs.n = n;
        cs.p = std::move(p);
        cs.pos = std::move(pos);
        cs.seed = hashPermutation(n, cs.p);

        long long B = (5LL * n) / 2LL + 800LL;
        total_limit += B;
        tests.push_back(std::move(cs));
    }

    query_limit = total_limit;
    log_metrics();

    long long hard_cap = max(200000LL, 10LL * query_limit);

    cout << t << endl;
    cout.flush();

    for (int tc = 0; tc < t; ++tc) {
        TestCase& cs = tests[tc];
        int n = cs.n;

        cout << n << endl;
        for (int i = 1; i <= n; ++i) {
            if (i > 1) cout << ' ';
            cout << cs.p[i];
        }
        cout << endl;
        cout.flush();

        long long qidx = 0;
        while (true) {
            string cmd;
            if (!(cin >> cmd)) finish(_pe, "Unexpected EOF from contestant");

            if (cmd == "!") {
                if (!isSorted(cs.p)) finish(_wa, "Contestant finished but permutation is not sorted");
                break;
            }

            if (cmd != "?") finish(_pe, "Invalid command (expected '?' or '!')");

            long long xll, yll;
            if (!(cin >> xll >> yll)) finish(_pe, "Malformed query: expected two integers after '?'");
            if (xll < 1 || xll > n || yll < 1 || yll > n) finish(_wa, "Query indices out of range");
            if (xll == yll) finish(_wa, "Query indices must be distinct");

            ++queries;
            ++qidx;
            if (queries > hard_cap) finish(_pe, "Hard cap exceeded (likely infinite loop/output spam)");

            int x = (int)xll, y = (int)yll;
            int u = x, v = y;
            if (coinFlip(cs, qidx) == 1) {
                u = n - x + 1;
                v = n - y + 1;
            }

            int a = cs.p[u];
            int b = cs.p[v];
            cs.p[u] = b;
            cs.p[v] = a;
            cs.pos[a] = v;
            cs.pos[b] = u;

            cout << u << " " << v << endl;
            cout.flush();

            if ((queries & 1023LL) == 0) log_metrics();
        }
    }

    {
        string extra;
        if (cin >> extra) finish(_pe, "Extra output after finishing all test cases");
    }

    finish(_ok, "OK");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static void fyShuffle(vector<int>& a) {
    for (int i = (int)a.size() - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(a[i], a[j]);
    }
}

static vector<int> buildHandCrafted(int seed) {
    if (seed == 1) {
        return vector<int>{1};
    }
    if (seed == 2) {
        return vector<int>{2, 1};
    }

    int n = 3999;
    int m = n / 2;
    vector<int> p(n, 0);

    for (int i = 1; i <= m; ++i) p[i - 1] = (m + 1) + i;
    p[m] = m + 1;
    for (int i = 1; i <= m; ++i) p[m + i] = i;

    swap(p[0], p[m]);

    for (int r = 0; r < 700; ++r) {
        int i = rnd.next(1, n);
        int j = n - i + 1;
        if (i == j) continue;
        swap(p[i - 1], p[j - 1]);
    }

    int shift = rnd.next(1, n - 1);
    rotate(p.begin(), p.begin() + shift, p.end());
    return p;
}

static vector<int> buildHardRandom(int n) {
    int m = n / 2;
    vector<int> p(n, 0);

    if (n % 2 == 0) {
        vector<int> A(m), B(m);
        for (int i = 0; i < m; ++i) A[i] = i + 1;
        for (int i = 0; i < m; ++i) B[i] = m + 1 + i;

        fyShuffle(A);
        fyShuffle(B);

        for (int i = 0; i < m; ++i) {
            p[i] = B[i];
            p[i + m] = A[i];
        }
    } else {

        vector<int> A(m), B(m);
        for (int i = 0; i < m; ++i) A[i] = i + 1;
        for (int i = 0; i < m; ++i) B[i] = (m + 2) + i;

        fyShuffle(A);
        fyShuffle(B);

        for (int i = 0; i < m; ++i) p[i] = B[i];
        p[m] = m + 1;
        for (int i = 0; i < m; ++i) p[m + 1 + i] = A[i];

        int pos = (rnd.next(0, 1) == 0 ? 0 : n - 1);
        swap(p[m], p[pos]);
    }

    int mirrorOps = min(1200, n);
    for (int r = 0; r < mirrorOps; ++r) {
        int i = rnd.next(1, n);
        int j = n - i + 1;
        if (i == j) continue;
        swap(p[i - 1], p[j - 1]);
    }

    int extraOps = min(1800, n);
    for (int r = 0; r < extraOps; ++r) {
        int i = rnd.next(1, n);
        int j = rnd.next(1, n);
        if (i == j) continue;
        swap(p[i - 1], p[j - 1]);
    }

    int shift = rnd.next(0, n - 1);
    rotate(p.begin(), p.begin() + shift, p.end());
    return p;
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    int seed = 1;
    if (argc > 1) seed = atoi(argv[1]);

    string mode = opt<string>("mode", "non");
    int forcedN = opt<int>("n", -1);

    int n;
    vector<int> p;

    if (seed >= 1 && seed <= 3 && forcedN == -1) {
        p = buildHandCrafted(seed);
        n = (int)p.size();
    } else {
        if (forcedN != -1) {
            n = forcedN;
        } else {

            int lo = opt<int>("nmin", 3500);
            int hi = opt<int>("nmax", 4000);
            lo = max(lo, 1);
            hi = min(hi, 4000);
            if (lo > hi) lo = hi;
            n = rnd.next(lo, hi);
            if (n >= 3 && rnd.next(0, 3) == 0) {
                if (n % 2 == 0) n -= 1;
            }
        }
        n = max(1, min(4000, n));
        if (n == 1) {
            p = vector<int>{1};
        } else if (n == 2) {
            p = vector<int>{2, 1};
        } else {
            p = buildHardRandom(n);
        }
    }

    if (mode == "non") {
        cout << 1 << "\n";
        cout << n << "\n";
        for (int i = 0; i < n; ++i) {
            if (i) cout << ' ';
            cout << p[i];
        }
        cout << "\n";
    } else if (mode == "adp") {
        cout << 1 << "\n";
        cout << n << "\n";
        for (int i = 0; i < n; ++i) {
            if (i) cout << ' ';
            cout << p[i];
        }
        cout << "\n";
    } else {
        quitf(_fail, "Unknown --mode (expected 'non' or 'adp')");
    }

    return 0;
}


# This is an interactive problem.

Chinese chess is a two-player strategy board game that is very popular in China. There are 10 rows and 9 columns on a Chinese chess board. We denote the point on the $r$ -th row from bottom to top and on the $c$ -th column from left to right by $( r , c )$ ( $0 \leq r \leq 9$ , $0 \leq c \leq 8$ ).

![](images/621a04bc2ab7e1ff02c5ccc9d77b9e91209d170939652dd48d595c20c0facb85.jpg)

There are six types of pieces in this problem: kings, mandarins, rooks, knights, bishops, and pawns. Note that cannons are not considered. Additionally, all pieces can be moved anywhere on the board, which differs slightly from the original rules. The movement rules for each piece are as follows (assuming the current position is $( r , c )$ ):

Chess	Symbol	Possible positions in one move

King	J	(r+1,c)(r-1,c)(r,c+1)(r,c-1)

Mandarin	S	(r+1,c+1)(r+1,c-1)(r-1,c+1)(r-1,c-1)

Rook	C	all (r',c') such that r' = r or c = c except (r,c) itself

Knight	M	(r+2,c+1)(r+2,c-1)(r-2,c+1)(r-2,c-1)(r+1,c+2) (r+1,c-2)(r-1,c+2) (r-1,c-2)

Bishop	X	(r+2,c+2)(r+2,c-2)(r-2,c+2)(r-2,c-2)

Pawn	B	(r+1,c) if r≤4,otherwise (r+1,c) (r,c+1) (r,c-1)

Of course, pieces cannot move outside the board’s boundaries. Now that you understand the rules, let’s play a game.

I have placed a piece on the board, and you cannot see its position or type. However, I will provide a set $A$ of $n$ possible positions where the piece might be located. Your goal is to determine the type of the piece using the minimum number of queries. For each query, you can select a position on the board, and I will tell you the minimum number of moves required for the piece to move to that position, or I will tell you if it is impossible for the piece to reach that position.

Interesting, isn’t it? What is even more interesting is that I am actually gaming against you in secret. Truth be told, although set $A$ is fixed, I have not fixed the type and position of this piece from the start. My strategy is to adjust the answer to each of your queries in a way that maximizes the number of queries you make, without contradicting the information already given. In the case where both of our strategies are optimal, your number of queries $m$ is actually determinable. I am sure you are smart enough to figure it out. Let the game begin!

# Interaction Protocol

Firstly, you should read an integer $n$ ( $1 \leq n \leq 9 0$ ) from standard input, indicating the size of the set $A$ .

Then, read $n$ lines. Each line contains two integers $r$ and $c$ , indicating a position in the set $A$ . All positions are guaranteed to be distinct.

After reading these $n + 1$ lines, you should output an integer $m$ to standard output, indicating the number of queries. If your output $m$ is incorrect, you will get a Wrong answer verdict. You must then make exactly $m$ queries.

To make a query, output $\texttt { ? r c }$ ( $0 \leq r \leq 9 , 0 \leq c \leq 8$ ) in a single line. Then you should read an integer from standard input, indicating the minimum number of moves required for the piece to reach the selected position, or $- 1$ if the piece cannot move to that position. If your program makes an invalid query or exceeds the number of queries, the interactor will terminate immediately, and you will receive a Wrong answer verdict.

To output your guess about the type of the piece, you need to output ! ch, where ch means the symbol representing the piece that is shown in the statement.

After you make a query or output your answer, including the $m$ and the type of the piece, do not forget to output the End of Line \n and flush the output. To do this, use:

• fflush(stdout) or cout.flush() in C++;
• System.out.flush() in Java;
• stdout.flush() in Python;

# Examples

standard input	standard output

1

90

	1 ？36

6

	！S

4

21

23

25

27

	2 ？00

3

1	？20

# Note

For the first example, the number of moves required for each of the six types of pieces to move from position $( 9 , 0 )$ to $( 3 , 6 )$ is as follows:

King (J)	Mandarins (S)	Rooks (C)	Knights (M)	Bishops (X)	Pawns (B)

12	6	2	4	3	-1

Thus, you only need to make one query to determine the answer.

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;

static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

template <typename... Args>
static void finish(TResult verdict, const char* fmt, Args... args) {
    log_metrics();
    quitf(verdict, fmt, args...);
}

struct Point {
    int r, c;
};

bool isValid(int r, int c) {
    return r >= 0 && r <= 9 && c >= 0 && c <= 8;
}

int dist[10][9];

void run_bfs(char type, Point start) {

    for(int i=0; i<10; ++i)
        for(int j=0; j<9; ++j)
            dist[i][j] = -1;

    queue<Point> q;
    q.push(start);
    dist[start.r][start.c] = 0;

    while(!q.empty()){
        Point u = q.front();
        q.pop();
        int r = u.r;
        int c = u.c;
        int d = dist[r][c];

        vector<Point> next_moves;
        next_moves.reserve(16);

        if (type == 'J') {
            int dr[] = {1, -1, 0, 0};
            int dc[] = {0, 0, 1, -1};
            for(int k=0; k<4; ++k) next_moves.push_back({r + dr[k], c + dc[k]});
        }
        else if (type == 'S') {
            int dr[] = {1, 1, -1, -1};
            int dc[] = {1, -1, 1, -1};
            for(int k=0; k<4; ++k) next_moves.push_back({r + dr[k], c + dc[k]});
        }
        else if (type == 'C') {

            for(int nc=0; nc<9; ++nc) if(nc != c) next_moves.push_back({r, nc});

            for(int nr=0; nr<10; ++nr) if(nr != r) next_moves.push_back({nr, c});
        }
        else if (type == 'M') {
            int dr[] = {2, 2, -2, -2, 1, 1, -1, -1};
            int dc[] = {1, -1, 1, -1, 2, -2, 2, -2};
            for(int k=0; k<8; ++k) next_moves.push_back({r + dr[k], c + dc[k]});
        }
        else if (type == 'X') {
            int dr[] = {2, 2, -2, -2};
            int dc[] = {2, -2, 2, -2};
            for(int k=0; k<4; ++k) next_moves.push_back({r + dr[k], c + dc[k]});
        }
        else if (type == 'B') {

            next_moves.push_back({r + 1, c});

            if (r > 4) {
                next_moves.push_back({r, c + 1});
                next_moves.push_back({r, c - 1});
            }
        }

        for(auto& v : next_moves) {
            if(isValid(v.r, v.c)) {
                if(dist[v.r][v.c] == -1) {
                    dist[v.r][v.c] = d + 1;
                    q.push(v);
                }
            }
        }
    }
}

int main(int argc, char* argv[]) {

    registerInteraction(argc, argv);
    atexit(log_metrics);

    int n = inf.readInt();
    vector<Point> A(n);
    for(int i=0; i<n; ++i) {
        A[i].r = inf.readInt();
        A[i].c = inf.readInt();
    }

    string typeStr = inf.readToken();
    char hiddenType = typeStr[0];
    int hiddenR = inf.readInt();
    int hiddenC = inf.readInt();

    run_bfs(hiddenType, {hiddenR, hiddenC});

    cout << n << endl;
    for(const auto& p : A) {
        cout << p.r << " " << p.c << endl;
    }
    cout.flush();

    long long m;
    if (!(cin >> m)) {
        finish(_wa, "Failed to read m from contestant");
    }

    query_limit = m;
    log_metrics();

    int safety_cap = 200000;

    while(true) {

        if (queries > safety_cap) {
            finish(_pe, "Hard query limit exceeded (safety cap %d)", safety_cap);
        }

        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF while reading query/answer");
        }

        if (token == "!") {
            string ans;
            if (!(cin >> ans)) {
                finish(_wa, "Failed to read answer type after '!'");
            }
            char ansType = ans[0];
            if (ansType == hiddenType) {
                finish(_ok, "Correct guess");
            } else {
                finish(_wa, "Incorrect guess: expected %c, got %c", hiddenType, ansType);
            }
        } else if (token.size() > 1 && token[0] == '!') {
            char ansType = token[1];
            if (ansType == hiddenType) {
                finish(_ok, "Correct guess");
            } else {
                finish(_wa, "Incorrect guess: expected %c, got %c", hiddenType, ansType);
            }
        } else {

            int r, c;
            if (token == "?") {
                if (!(cin >> r >> c)) {
                    finish(_wa, "Failed to read coordinates after '?'");
                }
            } else {

                try {
                    r = stoi(token);
                } catch (...) {
                    finish(_wa, "Invalid token '%s'", token.c_str());
                }
                if (!(cin >> c)) {
                    finish(_wa, "Failed to read c after r");
                }
            }

            queries++;

            if (queries > query_limit) {
                finish(_wa, "Query limit exceeded (used %lld, limit %lld)", queries, query_limit);
            }

            if (!isValid(r, c)) {
                finish(_wa, "Invalid query coordinates (%d, %d)", r, c);
            }

            cout << dist[r][c] << endl;

        }
    }

    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static bool metrics_logged = false;

static void log_metrics() {
    if (metrics_logged) return;
    metrics_logged = true;
    try {
        if (query_limit < 0) query_limit = 0;
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {}
}

static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

const int ROWS = 10;
const int COLS = 9;
const string PIECE_CHARS = "JSCMXB";

int get_piece_idx(char c) {
    auto pos = PIECE_CHARS.find(c);
    if (pos == string::npos) return -1;
    return (int)pos;
}

struct Pos {
    int r, c;
};

int dist_matrix[6][90][90];

bool valid(int r, int c) {
    return r >= 0 && r < ROWS && c >= 0 && c < COLS;
}

int get_id(int r, int c) {
    return r * COLS + c;
}

void bfs(int type, int start_r, int start_c) {
    int start_id = get_id(start_r, start_c);
    int* d = dist_matrix[type][start_id];
    fill(d, d + 90, -1);

    d[start_id] = 0;
    queue<pair<int, int>> q;
    q.push({start_r, start_c});

    while (!q.empty()) {
        auto [r, c] = q.front();
        q.pop();
        int curr_dist = d[get_id(r, c)];

        vector<pair<int, int>> next_moves;

        if (type == 0) {
            int dr[] = {1, -1, 0, 0};
            int dc[] = {0, 0, 1, -1};
            for (int i = 0; i < 4; i++) next_moves.push_back({r + dr[i], c + dc[i]});
        }
        else if (type == 1) {
            int dr[] = {1, 1, -1, -1};
            int dc[] = {1, -1, 1, -1};
            for (int i = 0; i < 4; i++) next_moves.push_back({r + dr[i], c + dc[i]});
        }
        else if (type == 2) {

            for (int nr = 0; nr < ROWS; nr++) if (nr != r) next_moves.push_back({nr, c});
            for (int nc = 0; nc < COLS; nc++) if (nc != c) next_moves.push_back({r, nc});
        }
        else if (type == 3) {
            int dr[] = {2, 2, -2, -2, 1, 1, -1, -1};
            int dc[] = {1, -1, 1, -1, 2, -2, 2, -2};
            for (int i = 0; i < 8; i++) next_moves.push_back({r + dr[i], c + dc[i]});
        }
        else if (type == 4) {
            int dr[] = {2, 2, -2, -2};
            int dc[] = {2, -2, 2, -2};
            for (int i = 0; i < 4; i++) next_moves.push_back({r + dr[i], c + dc[i]});
        }
        else if (type == 5) {
            if (r <= 4) {
                next_moves.push_back({r + 1, c});
            } else {
                next_moves.push_back({r + 1, c});
                next_moves.push_back({r, c + 1});
                next_moves.push_back({r, c - 1});
            }
        }

        for (auto p : next_moves) {
            if (valid(p.first, p.second)) {
                int nid = get_id(p.first, p.second);
                if (d[nid] == -1) {
                    d[nid] = curr_dist + 1;
                    q.push(p);
                }
            }
        }
    }
}

void precompute() {
    for (int t = 0; t < 6; t++) {
        for (int r = 0; r < ROWS; r++) {
            for (int c = 0; c < COLS; c++) {
                bfs(t, r, c);
            }
        }
    }
}

struct Candidate {
    int type;
    int r, c;
};

int main(int argc, char* argv[]) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    precompute();

    int n = inf.readInt();
    vector<Pos> A(n);
    for (int i = 0; i < n; i++) {
        A[i].r = inf.readInt();
        A[i].c = inf.readInt();
    }

    cout << n << endl;
    for (int i = 0; i < n; i++) {
        cout << A[i].r << " " << A[i].c << endl;
    }
    cout.flush();

    vector<Candidate> candidates;
    for (int t = 0; t < 6; t++) {
        for (const auto& p : A) {
            candidates.push_back({t, p.r, p.c});
        }
    }

    long long m_contestant;
    if (!(cin >> m_contestant)) {
        finish(_wa, "Failed to read m");
    }
    query_limit = m_contestant;
    log_metrics();

    for (int k = 0; k < m_contestant; k++) {
        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF expecting query");
        }

        if (token != "?") {
            finish(_wa, "Expected '?'");
        }

        int r, c;
        if (!(cin >> r >> c)) {
            finish(_wa, "Failed to read coordinates");
        }

        if (!valid(r, c)) {
            finish(_wa, "Invalid coordinates");
        }

        queries++;

        map<int, vector<Candidate>> groups;
        int target_id = get_id(r, c);

        for (const auto& cand : candidates) {
            int start_id = get_id(cand.r, cand.c);
            int d = dist_matrix[cand.type][start_id][target_id];
            groups[d].push_back(cand);
        }

        int best_d = -2;
        size_t best_size = 0;

        for (auto const& [d, group] : groups) {
            if (group.size() > best_size) {
                best_size = group.size();
                best_d = d;
            }
        }

        if (best_d == -2) {

            finish(_fail, "Internal logic error: no candidates");
        }

        candidates = groups[best_d];

        cout << best_d << endl;
    }

    string token;
    if (!(cin >> token)) {
        finish(_wa, "Unexpected EOF expecting answer");
    }

    if (token != "!") {
        finish(_wa, "Expected '!'");
    }

    string type_str;
    if (!(cin >> type_str)) {
        finish(_wa, "Failed to read piece type");
    }

    if (type_str.size() != 1) {
        finish(_wa, "Invalid piece type format");
    }

    int guessed_idx = get_piece_idx(type_str[0]);
    if (guessed_idx == -1) {
        finish(_wa, "Unknown piece symbol");
    }

    bool possible = true;
    for (const auto& cand : candidates) {
        if (cand.type != guessed_idx) {
            possible = false;
            break;
        }
    }

    if (possible) {
        finish(_ok, "Correct");
    } else {
        finish(_wa, "Wrong guess (ambiguous)");
    }

    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

const string PIECES = "JSCMXB";

struct Point {
    int r, c;
};

int main(int argc, char* argv[]) {

    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");

    int seed = atoi(argv[1]);

    int R = 10;
    int C = 9;

    vector<Point> all_points;
    all_points.reserve(R * C);
    for (int r = 0; r < R; ++r) {
        for (int c = 0; c < C; ++c) {
            all_points.push_back({r, c});
        }
    }

    int n;
    vector<Point> A;

    if (seed == 1) {

        n = 1;
        A.push_back(all_points[rnd.next((int)all_points.size())]);
    } else if (seed == 2) {

        n = 90;
        A = all_points;
        shuffle(A.begin(), A.end());
    } else if (seed == 3) {

        n = 45;
        shuffle(all_points.begin(), all_points.end());
        for (int i = 0; i < n; ++i) {
            A.push_back(all_points[i]);
        }
    } else {

        int strategy = rnd.next(3);
        if (strategy == 0) {

            n = rnd.next(2, 10);
        } else if (strategy == 1) {

            n = rnd.next(75, 89);
        } else {

            n = rnd.next(1, 90);
        }

        shuffle(all_points.begin(), all_points.end());
        for (int i = 0; i < n; ++i) {
            A.push_back(all_points[i]);
        }
    }

    println(n);

    for (const auto& p : A) {
        println(p.r, p.c);
    }

    if (mode == "non") {

        int idx = rnd.next(n);
        Point secretPos = A[idx];
        char secretType = PIECES[rnd.next((int)PIECES.size())];

        println(secretType, secretPos.r, secretPos.c);
    }

    return 0;
}