You are playing Battleships in a large ocean with large ships. More precisely, there is a large square grid of size at most $1 0 0 \times 1 0 0$ and inside it are up to 10 of the largest type of ship in Battleships – the aircraft carrier – which has a length of five tiles, placed either horizontally or vertically. The ships do not overlap, but they are allowed to be adjacent to each other. See Figure L.1 for an example.

Unfortunately, your opponent appears to bend the rules to their liking. It looks like they do not always determine the placement of their ships before you start shooting. You are not impressed by their attempt at cheating, and decide to try and win the game anyway.

![](images/508b533007e7a80874db8d7841af000e2cb15b725419376f34a0a2393b0e9927.jpg)

![](images/bf5ec4ed303829fb07ab28c50253fe1af2e96176b5528049201c3bae34f5682e.jpg)
Figure L.1: Illustration of Sample Interaction 1 after the first four shots were fired.

Your goal is to locate and sink all your opponent’s aircraft carriers in at most 2500 shots, that is, you must hit each of the five tiles of all their ships.

# Interaction

This is an interactive problem. Your submission will be run against an interactor, which reads from the standard output of your submission and writes to the standard input of your submission. This interaction needs to follow a specific protocol:

The interactor first sends one line with two integers $n$ and $k$ $( 5 \leq n \leq 1 0 0 , 1 \leq k \leq 1 0 )$ ), the size of the grid and the number of ships. It is guaranteed that it is possible to place $k$ aircraft carriers in the grid without overlap.

Then, your program needs to start firing shots. Each shot is fired by printing one line of the form “ $\cdot _ { x }$ y” $( 1 \leq x , y \leq n )$ , indicating you shoot at position $( x , y )$ . The interactor will respond with “hit” if the shot was a hit, “sunk” if the shot caused an aircraft carrier to sink, and “miss” otherwise. If you have shot the same location before, the response will be “miss”.

Once you sink the last aircraft carrier, the interaction will stop and your program must exit.

The interactor is adaptive: the positions of the ships may be determined during the interaction, and may depend on where you decide to shoot.

Make sure you flush the buffer after each write.

A testing tool is provided to help you develop your solution.

Firing more than 2500 shots will result in a wrong answer.

Read                                   Sample Interaction 1                                  Write72

72

	61

miss

	63

hit

	73

miss

	53

hit

	43

hit

	33

hit

	23

hit

	13

sunk

	67

miss

	67

miss

	62

hit

	62

miss

	64

hit

	65

hit

	66

sunk

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

using namespace std;

const int MAXN = 105;
int N, K;
int grid[MAXN][MAXN];
int ship_health[15];
bool shot[MAXN][MAXN];
int sunk_count = 0;

long long queries = 0;
long long query_limit = 2500;

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

    }
}

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

int parse_int(const string& s) {
    try {
        size_t pos;
        long long val = stoll(s, &pos);
        if (pos != s.size()) return -1;
        if (val < -1000000 || val > 1000000) return -1;
        return (int)val;
    } catch (...) {
        return -1;
    }
}

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

    N = inf.readInt(5, 100, "N");
    K = inf.readInt(1, 10, "K");

    memset(grid, 0, sizeof(grid));
    memset(shot, false, sizeof(shot));
    for (int i = 1; i <= K; i++) ship_health[i] = 5;

    for (int i = 1; i <= K; i++) {
        int r = inf.readInt(1, N, "r");
        int c = inf.readInt(1, N, "c");
        string dToken = inf.readToken();

        char dir = ' ';
        if (dToken == "h") dir = 'h';
        else if (dToken == "v") dir = 'v';
        else quitf(_fail, "Invalid direction token in input: %s", dToken.c_str());

        if (dir == 'h') {
            for (int k = 0; k < 5; k++) {
                if (c + k > N) quitf(_fail, "Ship out of bounds (input)");
                grid[r][c + k] = i;
            }
        } else {
            for (int k = 0; k < 5; k++) {
                if (r + k > N) quitf(_fail, "Ship out of bounds (input)");
                grid[r + k][c] = i;
            }
        }
    }

    cout << N << " " << K << endl;
    log_metrics();

    long long hard_cap = 30000;

    while (true) {

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

        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded");
        }

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

        int x = -1, y = -1;

        if (token == "?") {
            string sx, sy;
            if (!(cin >> sx >> sy)) finish(_wa, "Expected x y after ?");
            x = parse_int(sx);
            y = parse_int(sy);
        } else if (token == "!") {
             finish(_wa, "Protocol violation: unexpected '!'");
        } else {

            x = parse_int(token);
            string sy;
            if (!(cin >> sy)) finish(_wa, "Expected y");
            y = parse_int(sy);
        }

        if (x < 1 || x > N || y < 1 || y > N) {
            finish(_wa, "Coordinates out of bounds: " + to_string(x) + " " + to_string(y));
        }

        queries++;

        string response = "miss";

        if (shot[x][y]) {
            response = "miss";
        } else {
            shot[x][y] = true;
            if (grid[x][y] == 0) {
                response = "miss";
            } else {
                int id = grid[x][y];
                ship_health[id]--;
                if (ship_health[id] == 0) {
                    response = "sunk";
                    sunk_count++;
                } else {
                    response = "hit";
                }
            }
        }

        cout << response << endl;

        if (sunk_count == K) {
            finish(_ok, "All ships sunk");
        }
    }

    return 0;
}

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

using namespace std;

static long long queries = 0;
static long long query_limit = 2500;
static const long long HARD_CAP = 25000;

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());
}

int N, K;
enum CellState { UNKNOWN = 0, MISS_LOG = 1, HIT_LOG = 2 };

vector<vector<int>> history_grid;
vector<vector<int>> ship_occupancy;

struct Ship {
    int id;
    int r, c;
    int dir;
    vector<pair<int,int>> hits;
};
vector<Ship> ships;

struct Pos {
    int r, c, dir;
};
vector<Pos> all_positions;

mt19937 rng(589214);

bool is_valid_placement(int r, int c, int dir, int ignore_ship_id = -1) {
    if (dir == 0) {
        if (r < 1 || r > N) return false;
        if (c < 1 || c + 4 > N) return false;
    } else {
        if (r < 1 || r + 4 > N) return false;
        if (c < 1 || c > N) return false;
    }

    for (int i = 0; i < 5; ++i) {
        int nr = (dir == 0) ? r : r + i;
        int nc = (dir == 0) ? c + i : c;

        int occ = ship_occupancy[nr][nc];
        if (occ != -1 && occ != ignore_ship_id) return false;

        if (history_grid[nr][nc] == MISS_LOG) return false;
    }
    return true;
}

void place_ship_on_board(const Ship& s) {
    for (int i = 0; i < 5; ++i) {
        int nr = (s.dir == 0) ? s.r : s.r + i;
        int nc = (s.dir == 0) ? s.c + i : s.c;
        ship_occupancy[nr][nc] = s.id;
    }
}

void remove_ship_from_board(const Ship& s) {
    for (int i = 0; i < 5; ++i) {
        int nr = (s.dir == 0) ? s.r : s.r + i;
        int nc = (s.dir == 0) ? s.c + i : s.c;
        ship_occupancy[nr][nc] = -1;
    }
}

void init_all_positions() {
    for (int r = 1; r <= N; ++r) {
        for (int c = 1; c <= N; ++c) {
            if (c + 4 <= N) all_positions.push_back({r, c, 0});
            if (r + 4 <= N) all_positions.push_back({r, c, 1});
        }
    }
    shuffle(all_positions.begin(), all_positions.end(), rng);
}

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

    N = inf.readInt(5, 100, "N");
    K = inf.readInt(1, 10, "K");

    cout << N << " " << K << endl;

    history_grid.assign(N + 2, vector<int>(N + 2, UNKNOWN));
    ship_occupancy.assign(N + 2, vector<int>(N + 2, -1));
    init_all_positions();

    ships.resize(K);
    for (int i = 0; i < K; ++i) {
        ships[i].id = i;
        bool placed = false;

        for (int att = 0; att < 2000; ++att) {
            int dir = rng() % 2;
            int r = (rng() % N) + 1;
            int c = (rng() % N) + 1;
            if (is_valid_placement(r, c, dir, i)) {
                ships[i].r = r; ships[i].c = c; ships[i].dir = dir;
                place_ship_on_board(ships[i]);
                placed = true;
                break;
            }
        }

        if (!placed) {
            for (const auto& p : all_positions) {
                if (is_valid_placement(p.r, p.c, p.dir, i)) {
                    ships[i].r = p.r; ships[i].c = p.c; ships[i].dir = p.dir;
                    place_ship_on_board(ships[i]);
                    placed = true;
                    break;
                }
            }
        }
        if (!placed) finish(_fail, "Cannot place ships initially");
    }

    log_metrics();

    int sunk_count = 0;

    while (true) {
        if (queries > HARD_CAP) finish(_pe, "Hard query limit exceeded");

        string token;
        if (!(cin >> token)) break;

        int r, c;
        try {
            r = stoi(token);
            if (!(cin >> c)) break;
        } catch (...) {
            finish(_pe, "Expected integer coordinates");
            return 0;
        }

        queries++;
        if (r < 1 || r > N || c < 1 || c > N) finish(_pe, "Coordinates out of bounds");

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

        if (history_grid[r][c] != UNKNOWN) {
            cout << "miss" << endl;
            continue;
        }

        int sid = ship_occupancy[r][c];

        if (sid == -1) {

            history_grid[r][c] = MISS_LOG;
            cout << "miss" << endl;
        } else {

            Ship& s = ships[sid];
            remove_ship_from_board(s);

            bool dodged = false;

            if (s.hits.empty()) {

                for (const auto& p : all_positions) {

                    bool covers_target = false;
                    if (p.dir == 0) {
                        if (p.r == r && c >= p.c && c < p.c + 5) covers_target = true;
                    } else {
                        if (p.c == c && r >= p.r && r < p.r + 5) covers_target = true;
                    }
                    if (covers_target) continue;

                    if (is_valid_placement(p.r, p.c, p.dir, s.id)) {
                        s.r = p.r; s.c = p.c; s.dir = p.dir;
                        place_ship_on_board(s);
                        dodged = true;
                        break;
                    }
                }
            } else {

                int hr = s.hits[0].first;
                int hc = s.hits[0].second;

                vector<Pos> candidates;
                for (int start_c = hc - 4; start_c <= hc; ++start_c) candidates.push_back({hr, start_c, 0});
                for (int start_r = hr - 4; start_r <= hr; ++start_r) candidates.push_back({start_r, hc, 1});

                shuffle(candidates.begin(), candidates.end(), rng);

                for (const auto& p : candidates) {

                    bool covers_target = false;
                    if (p.dir == 0) {
                        if (p.r == r && c >= p.c && c < p.c + 5) covers_target = true;
                    } else {
                        if (p.c == c && r >= p.r && r < p.r + 5) covers_target = true;
                    }
                    if (covers_target) continue;

                    if (!is_valid_placement(p.r, p.c, p.dir, s.id)) continue;

                    bool all_hits = true;
                    for (auto& h : s.hits) {
                        bool hit_ok = false;
                        if (p.dir == 0) {
                            if (h.first == p.r && h.second >= p.c && h.second < p.c + 5) hit_ok = true;
                        } else {
                            if (h.second == p.c && h.first >= p.r && h.first < p.r + 5) hit_ok = true;
                        }
                        if (!hit_ok) { all_hits = false; break; }
                    }

                    if (all_hits) {
                        s.r = p.r; s.c = p.c; s.dir = p.dir;
                        place_ship_on_board(s);
                        dodged = true;
                        break;
                    }
                }
            }

            if (dodged) {
                history_grid[r][c] = MISS_LOG;
                cout << "miss" << endl;
            } else {

                place_ship_on_board(s);
                history_grid[r][c] = HIT_LOG;
                s.hits.push_back({r, c});

                if (s.hits.size() == 5) {
                    sunk_count++;
                    cout << "sunk" << endl;
                    if (sunk_count == K) finish(_ok, "All ships sunk");
                } else {
                    cout << "hit" << endl;
                }
            }
        }
    }

    finish(_wa, "Solution exited before sinking all ships");
}

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

using namespace std;

struct Ship {
    int r, c;
    char dir;
};

bool can_place(int N, int r, int c, char dir, const vector<vector<bool>>& grid) {
    if (dir == 'h') {
        if (c + 4 > N) return false;
        for (int k = 0; k < 5; k++) {
            if (grid[r][c + k]) return false;
        }
    } else {
        if (r + 4 > N) return false;
        for (int k = 0; k < 5; k++) {
            if (grid[r + k][c]) return false;
        }
    }
    return true;
}

void place_ship(int r, int c, char dir, vector<vector<bool>>& grid) {
    if (dir == 'h') {
        for (int k = 0; k < 5; k++) grid[r][c + k] = true;
    } else {
        for (int k = 0; k < 5; k++) grid[r + k][c] = true;
    }
}

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

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

    int seed_val = atoi(argv[1]);

    int N, K;

    if (seed_val == 1) {

        N = 5; K = 1;
    } else if (seed_val == 2) {

        N = 100; K = 10;
    } else if (seed_val == 3) {

        N = 10; K = 10;
    } else if (seed_val == 4) {

        N = 5; K = 5;
    } else {

        N = rnd.next(5, 100);

        int limit_k = min(10, N);

        int p = rnd.next(1, 100);
        if (p <= 10) K = 1;
        else if (p <= 40) K = rnd.next(1, limit_k);
        else K = limit_k;
    }

    if (mode == "adp") {

        cout << N << " " << K << endl;
    } else {

        vector<Ship> ships;
        vector<vector<bool>> grid(N + 1, vector<bool>(N + 1, false));

        bool success = false;

        for (int attempt = 0; attempt < 50; attempt++) {
            ships.clear();
            for (int i = 1; i <= N; i++) fill(grid[i].begin(), grid[i].end(), false);

            int placed_count = 0;
            for (int i = 0; i < K; i++) {
                bool placed = false;

                for (int t = 0; t < 2000; t++) {
                    char dir = (rnd.next(2) ? 'h' : 'v');
                    int r, c;
                    if (dir == 'h') {
                        r = rnd.next(1, N);
                        c = rnd.next(1, N - 4);
                    } else {
                        r = rnd.next(1, N - 4);
                        c = rnd.next(1, N);
                    }

                    if (can_place(N, r, c, dir, grid)) {
                        place_ship(r, c, dir, grid);
                        ships.push_back({r, c, dir});
                        placed = true;
                        placed_count++;
                        break;
                    }
                }
                if (!placed) break;
            }
            if (placed_count == K) {
                success = true;
                break;
            }
        }

        if (!success) {
            ships.clear();
            for (int i = 1; i <= N; i++) fill(grid[i].begin(), grid[i].end(), false);
            int placed_count = 0;

            vector<int> rows(N);
            iota(rows.begin(), rows.end(), 1);
            shuffle(rows.begin(), rows.end());

            for (int r : rows) {
                if (placed_count >= K) break;

                int c = rnd.next(1, N - 4);
                if (can_place(N, r, c, 'h', grid)) {
                    place_ship(r, c, 'h', grid);
                    ships.push_back({r, c, 'h'});
                    placed_count++;
                }
            }

            K = placed_count;
        }

        for (int i = 0; i < (int)ships.size(); i++) {
            int j = rnd.next(i, (int)ships.size() - 1);
            swap(ships[i], ships[j]);
        }

        cout << N << " " << K << endl;
        for (const auto& s : ships) {
            cout << s.r << " " << s.c << " " << s.dir << endl;
        }
    }

    return 0;
}


This is an interactive task.

Scientists are about to invent a new optimization for the Floyd-Warshall algorithm, which will allow it to work in linear time. There is only one part of the optimization still unfinished.

It is well known that the Floyd-Warshall algorithm takes a graph with $n$ nodes and exactly one edge between each pair of nodes. The scientists have this graph, what is more, they have directed each edge in one of the two possible directions.

To optimize the algorithm, exactly $m$ edges are colored in pink color and all the rest are colored in green. You know the direction of all $m$ pink edges, but the direction of green edges is unknown to you. In one query you can ask the scientists about the direction of exactly one green edge, however, you can perform at most $2 \cdot n$ such queries.

Your task is to find the node from which every other node can be reached by a path consisting of edges of same color. Be aware that the scientists may have lied that they had fixed the direction of all edges beforehand, so their answers may depend on your queries.

Input

The first line contains two integers $n$ and $m$ ($1 \le n \le 100\,000$, $0 \le m \le 100\,000$) — the number of nodes and the number of pink edges.

The next $m$ lines describe the pink edges, the $i$-th of these lines contains two integers $u_i$, $v_i$ ($1 \le u_i, v_i \le n$, $u_i \ne v_i$) — the start and the end of the $i$-th pink edge. It is guaranteed, that all unordered pairs $(u_i, v_i)$ are distinct.

Output

When you found the answer, print "!" and the number of the node from which every other node can be reached by a single-colored path.

Interaction

To ask the direction of the green edge between nodes $a$ and $b$, print "?", $a$ and $b$ in single line, separated by the space characters.

In answer to this read a single integer, which will be $1$ if the edge is directed from $a$ to $b$ and $0$ if the edge is directed from $b$ to $a$.

You can ask at most $2 \cdot n$ queries, otherwise you will get Wrong Answer.

After printing a query do not forget to output end of 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 documentation for other languages.

Answer $-1$ instead of $0$ or $1$ means that you made an invalid query or exceeded the query limit. Exit immediately after receiving $-1$ and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

Example

Input

```
4 2
1 2
3 4
0
1
1
```

Output

```
? 1 3
? 4 2
? 3 2
! 3
```

Note

In the example above the answer for the query "? 1 3" is 0, so the edge is directed from 3 to 1. The answer for the query "? 4 2" is 1, so the edge is directed from 4 to 2. The answer for the query "? 3 2" is 1, so the edge is directed from 3 to 2. So there are green paths from node 3 to nodes 1 and 2 and there is a pink path from node 3 to node 4.

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

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

static int n = 0, m = 0;
static unsigned long long seed64 = 0;
static int root = -1;

static unordered_set<unsigned long long> pinkPairs;
static vector<pair<int,int>> pinkEdges;

static void log_metrics() {
    try {
        tout << "queries=" << queries << '\n';
        tout << "query_limit=" << query_limit << '\n';
        tout.flush();
    } catch (...) {

    }
}

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

static unsigned long long pairKeyU64(int a, int b) {
    int x = min(a, b), y = max(a, b);
    return (static_cast<unsigned long long>(static_cast<unsigned int>(x)) << 32) |
           static_cast<unsigned long long>(static_cast<unsigned int>(y));
}

static unsigned long long mix64(unsigned long long x) {

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

static bool greenDir(int a, int b) {
    if (a == b) return false;
    if (root != -1 && (a == root || b == root)) {

        return a == root;
    }
    int x = min(a, b), y = max(a, b);
    unsigned long long k = pairKeyU64(x, y);
    unsigned long long h = mix64(seed64 ^ (k * 0x9e3779b97f4a7c15ULL));
    bool minToMax = (h & 1ULL) != 0ULL;
    if (a == x) return minToMax;
    return !minToMax;
}

static vector<int> computeAllSolutionsBruteforce() {

    int N = n;
    int words = (N + 63) / 64;

    auto makeBits = [&]() { return vector<unsigned long long>(words, 0ULL); };
    vector<vector<unsigned long long>> pinkReach(N + 1), greenReach(N + 1);
    for (int i = 1; i <= N; i++) {
        pinkReach[i] = makeBits();
        greenReach[i] = makeBits();
        pinkReach[i][(i - 1) >> 6] |= 1ULL << ((i - 1) & 63);
        greenReach[i][(i - 1) >> 6] |= 1ULL << ((i - 1) & 63);
    }

    for (auto &e : pinkEdges) {
        int u = e.first, v = e.second;
        pinkReach[u][(v - 1) >> 6] |= 1ULL << ((v - 1) & 63);
    }

    for (int i = 1; i <= N; i++) {
        for (int j = i + 1; j <= N; j++) {
            unsigned long long k = pairKeyU64(i, j);
            if (pinkPairs.find(k) != pinkPairs.end()) continue;
            bool iToJ = greenDir(i, j);
            if (iToJ) greenReach[i][(j - 1) >> 6] |= 1ULL << ((j - 1) & 63);
            else greenReach[j][(i - 1) >> 6] |= 1ULL << ((i - 1) & 63);
        }
    }

    auto closure = [&](vector<vector<unsigned long long>> &reach) {
        for (int k = 1; k <= N; k++) {
            int kw = (k - 1) >> 6;
            unsigned long long kmask = 1ULL << ((k - 1) & 63);
            for (int i = 1; i <= N; i++) {
                if ((reach[i][kw] & kmask) == 0ULL) continue;
                for (int w = 0; w < words; w++) reach[i][w] |= reach[k][w];
            }
        }
    };

    closure(pinkReach);
    closure(greenReach);

    vector<int> sols;
    for (int s = 1; s <= N; s++) {
        bool ok = true;
        for (int v = 1; v <= N; v++) {
            int w = (v - 1) >> 6;
            unsigned long long mask = 1ULL << ((v - 1) & 63);
            bool pr = (pinkReach[s][w] & mask) != 0ULL;
            bool gr = (greenReach[s][w] & mask) != 0ULL;
            if (!pr && !gr) {
                ok = false;
                break;
            }
        }
        if (ok) sols.push_back(s);
    }
    return sols;
}

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

    try {
        n = inf.readInt(1, 100000, "n");
        m = inf.readInt(0, 100000, "m");
        query_limit = 2LL * n;

        pinkEdges.reserve(m);
        pinkPairs.reserve(static_cast<size_t>(m) * 2 + 10);

        vector<int> pinkInc(n + 1, 0);

        for (int i = 0; i < m; i++) {
            int u = inf.readInt(1, n, "u");
            int v = inf.readInt(1, n, "v");
            if (u == v) finish(_fail, "Invalid hidden input: self-loop pink edge");
            unsigned long long k = pairKeyU64(u, v);
            if (pinkPairs.find(k) != pinkPairs.end())
                finish(_fail, "Invalid hidden input: duplicated unordered pink pair");
            pinkPairs.insert(k);
            pinkEdges.push_back({u, v});
            pinkInc[u]++;
            pinkInc[v]++;
        }

        long long last = inf.readLong();
        if (last < 0) last = -last;
        seed64 = static_cast<unsigned long long>(last);

        root = -1;
        for (int i = 1; i <= n; i++) {
            if (pinkInc[i] == 0) {
                root = i;
                break;
            }
        }

        log_metrics();

        cout << n << " " << m << "\n";
        for (auto &e : pinkEdges) cout << e.first << " " << e.second << "\n";
        cout.flush();

        vector<int> acceptable;
        if (root != -1) {

            acceptable.push_back(root);
        } else {

            acceptable = computeAllSolutionsBruteforce();
        }

        auto isAcceptable = [&](int x) -> bool {
            for (int v : acceptable) if (v == x) return true;
            return false;
        };

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

        string op;
        while (cin >> op) {
            if (op == "?") {
                long long a_ll, b_ll;
                if (!(cin >> a_ll >> b_ll)) finish(_pe, "Malformed query: missing a b");
                if (a_ll < 1 || a_ll > n || b_ll < 1 || b_ll > n || a_ll == b_ll) {
                    cout << -1 << "\n";
                    cout.flush();
                    finish(_wa, "Invalid query parameters");
                }
                int a = (int)a_ll, b = (int)b_ll;
                unsigned long long k = pairKeyU64(a, b);
                if (pinkPairs.find(k) != pinkPairs.end()) {
                    cout << -1 << "\n";
                    cout.flush();
                    finish(_wa, "Queried a pink edge");
                }

                queries++;
                if (queries > hard_cap) finish(_pe, "Hard cap exceeded");

                int ans = greenDir(a, b) ? 1 : 0;
                cout << ans << "\n";
                cout.flush();
            } else if (op == "!") {
                long long x_ll;
                if (!(cin >> x_ll)) finish(_pe, "Malformed answer: missing vertex");
                if (x_ll < 1 || x_ll > n) finish(_wa, "Answer out of range");
                int x = (int)x_ll;

                if (acceptable.empty()) {
                    finish(_wa, "No acceptable answers (invalid hidden instance)");
                }
                if (isAcceptable(x)) finish(_ok, "OK");
                finish(_wa, "Wrong answer");
            } else {
                finish(_pe, "Unexpected token (expected '?' or '!')");
            }
        }

        finish(_wa, "EOF without final answer");
    } catch (const std::exception& e) {
        finish(_fail, string("Exception: ") + e.what());
    } catch (...) {
        finish(_fail, "Unknown exception");
    }
}

#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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {

    }
}

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

static long long pairKey(int a, int b) {
    int x = min(a, b), y = max(a, b);
    return (static_cast<long long>(x) << 32) ^ static_cast<unsigned long long>(y);
}

static bool parseLL(const string& s, long long& out) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[i] == '-') {
        neg = true;
        i++;
        if (i == (int)s.size()) return false;
    }
    long long val = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

static bool readToken(string& tok) {
    if (!(cin >> tok)) return false;
    return true;
}

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

    int n = inf.readInt(1, 100000, "n");
    int m = inf.readInt(0, 100000, "m");

    vector<pair<int,int>> pinkEdges;
    pinkEdges.reserve(m);

    unordered_set<long long> pinkPairs;
    pinkPairs.reserve((size_t)m * 2 + 10);

    for (int i = 0; i < m; i++) {
        int u = inf.readInt(1, n, "u");
        int v = inf.readInt(1, n, "v");
        if (u == v) finish(_fail, "invalid pink edge in input (self-loop)");
        long long k = pairKey(u, v);
        if (pinkPairs.find(k) != pinkPairs.end()) finish(_fail, "duplicate pink unordered pair in input");
        pinkPairs.insert(k);
        pinkEdges.push_back({u, v});
    }

    int x = 1;
    if (!inf.seekEof()) {
        string tail = inf.readToken();
        long long z;
        if (!parseLL(tail, z)) finish(_fail, "invalid trailing token in input");
        if (1 <= z && z <= n) {
            x = (int)z;
        } else {
            long long zz = z;
            if (zz < 0) zz = -zz;
            x = (int)(zz % n) + 1;
        }
    }

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

    cout << n << " " << m << "\n";
    for (auto &e : pinkEdges) cout << e.first << " " << e.second << "\n";
    cout.flush();

    log_metrics();

    unordered_map<long long, unsigned char> greenDirMinToMax;
    greenDirMinToMax.reserve((size_t)min(hard_cap, 400000LL) * 2 + 10);

    auto rankOf = [&](int v) -> int {
        if (v == x) return n + 1;
        return v;
    };

    auto getDirMinToMax = [&](int a, int b) -> unsigned char {
        int mn = min(a, b), mx = max(a, b);
        long long k = pairKey(mn, mx);
        auto it = greenDirMinToMax.find(k);
        if (it != greenDirMinToMax.end()) return it->second;

        int ra = rankOf(mn);
        int rb = rankOf(mx);
        unsigned char dir = (ra > rb) ? 1 : 0;
        greenDirMinToMax.emplace(k, dir);
        return dir;
    };

    string cmd;
    while (true) {
        if (!readToken(cmd)) finish(_pe, "unexpected EOF (no final answer)");
        if (cmd == "?") {
            string sa, sb;
            if (!readToken(sa) || !readToken(sb)) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "incomplete query");
            }
            long long la, lb;
            if (!parseLL(sa, la) || !parseLL(sb, lb)) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "non-integer in query");
            }
            if (la < 1 || la > n || lb < 1 || lb > n || la == lb) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "query out of range or self-loop");
            }
            int a = (int)la, b = (int)lb;

            long long k = pairKey(a, b);
            if (pinkPairs.find(k) != pinkPairs.end()) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "queried a pink edge");
            }

            queries++;
            if (queries > hard_cap) finish(_pe, "too many queries (hard cap exceeded)");

            int mn = min(a, b), mx = max(a, b);
            unsigned char dirMnToMx = getDirMinToMax(a, b);

            int ans = 0;
            if (a == mn && b == mx) ans = (dirMnToMx ? 1 : 0);
            else ans = (dirMnToMx ? 0 : 1);

            cout << ans << "\n";
            cout.flush();
        } else if (cmd == "!") {
            string sv;
            if (!readToken(sv)) finish(_pe, "missing answer vertex after '!'");
            long long lv;
            if (!parseLL(sv, lv) || lv < 1 || lv > n) finish(_wa, "invalid answer vertex");
            int v = (int)lv;

            if (v == x) finish(_ok, "correct");
            finish(_wa, "wrong vertex");
        } else {
            finish(_pe, "invalid command token");
        }
    }
}

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

static long long pairKey(int a, int b) {
    int x = min(a, b), y = max(a, b);
    return (static_cast<long long>(x) << 32) ^ static_cast<unsigned long long>(y);
}

static vector<pair<int,int>> buildPinkEdges(int n, int m, int avoid) {
    vector<int> nodes;
    nodes.reserve(n - (avoid ? 1 : 0));
    for (int i = 1; i <= n; i++) if (i != avoid) nodes.push_back(i);

    unordered_set<long long> used;
    used.reserve(static_cast<size_t>(m) * 2 + 10);

    vector<pair<int,int>> edges;
    edges.reserve(m);

    auto tryAdd = [&](int u, int v, bool uToV) -> bool {
        if (u == v) return false;
        long long k = pairKey(u, v);
        if (used.find(k) != used.end()) return false;
        used.insert(k);
        edges.push_back(uToV ? make_pair(u, v) : make_pair(v, u));
        return true;
    };

    int L = (int)nodes.size();

    for (int i = 0; i + 1 < L && (int)edges.size() < m; i++) {
        int a = nodes[i], b = nodes[i + 1];
        bool aToB = (i % 2 == 0);
        tryAdd(a, b, aToB);
    }

    int half = L / 2;
    for (int i = 0; i < half && (int)edges.size() < m; i++) {
        int a = nodes[i], b = nodes[i + half];
        bool aToB = ((i % 3) == 0);
        tryAdd(a, b, aToB);
    }

    while ((int)edges.size() < m) {
        int ia = rnd.next(0, L - 1);
        int ib = rnd.next(0, L - 1);
        if (ia == ib) continue;
        int a = nodes[ia], b = nodes[ib];
        bool aToB = (rnd.next(0, 1) == 1);
        tryAdd(a, b, aToB);
    }

    return edges;
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

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

    int n = opt<int>("n", 100000);
    int m = opt<int>("m", 100000);

    if (seedNum == 1) {
        n = 1; m = 0;
        if (mode == "non") {
            cout << n << " " << m << "\n";
            long long S = rnd.next(1LL, 4000000000000000000LL);
            cout << S << "\n";
        } else if (mode == "adp") {
            cout << n << " " << m << "\n";
            cout << 1 << "\n";
        } else {
            quitf(_fail, "Unknown mode: %s", mode.c_str());
        }
        return 0;
    }

    if (seedNum == 2) {

        n = 3; m = 3;
        if (mode == "non") {
            cout << n << " " << m << "\n";
            cout << 1 << " " << 2 << "\n";
            cout << 2 << " " << 3 << "\n";
            cout << 3 << " " << 1 << "\n";
            long long S = rnd.next(1LL, 4000000000000000000LL);
            cout << S << "\n";
        } else if (mode == "adp") {
            cout << n << " " << m << "\n";
            cout << 1 << " " << 2 << "\n";
            cout << 2 << " " << 3 << "\n";
            cout << 3 << " " << 1 << "\n";
            cout << 1 << "\n";
        } else {
            quitf(_fail, "Unknown mode: %s", mode.c_str());
        }
        return 0;
    }

    if (seedNum == 3) {

        n = 100000;
        m = 100000;
    }

    if (n < 1) n = 1;
    if (m < 0) m = 0;
    long long maxPairs = 1LL * n * (n - 1) / 2;
    if (m > maxPairs) m = (int)maxPairs;

    if (mode == "non") {
        int avoid = (n == 1 ? 0 : rnd.next(1, n));

        if (n >= 2 && m > 0) {
            long long maxPairsAvoid = 1LL * (n - 1) * (n - 2) / 2;
            if (m > maxPairsAvoid) avoid = 0;
        }
        auto edges = buildPinkEdges(n, m, avoid);

        cout << n << " " << m << "\n";
        for (auto &e : edges) cout << e.first << " " << e.second << "\n";
        long long S = rnd.next(1LL, 4000000000000000000LL);
        cout << S << "\n";
    } else if (mode == "adp") {
        int x = (n == 1 ? 1 : rnd.next(1, n));

        int avoid = x;
        if (n >= 2 && m > 0) {
            long long maxPairsAvoid = 1LL * (n - 1) * (n - 2) / 2;
            if (m > maxPairsAvoid) avoid = 0;
        }
        auto edges = buildPinkEdges(n, m, avoid);

        cout << n << " " << m << "\n";
        for (auto &e : edges) cout << e.first << " " << e.second << "\n";
        cout << x << "\n";
    } else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}


The only difference between the versions of this problem is the maximum value of $n$.

Professor Vector is preparing to teach her Arithmancy class. She needs to prepare $n$ distinct magic words for the class. Each magic word is a string consisting of characters X and O. A spell is a string created by concatenating two magic words together. The power of a spell is equal to the number of its different non-empty substrings. For example, the power of the spell XOXO is equal to 7, because it has 7 different substrings: X, O, XO, OX, XOX, OXO and XOXO.

Each student will create their own spell by concatenating two magic words. Since the students are not very good at magic yet, they will choose each of the two words independently and uniformly at random from the $n$ words provided by Professor Vector. It is therefore also possible that the two words a student chooses are the same. Each student will then compute the power of their spell, and tell it to Professor Vector. In order to check their work, and of course to impress the students, Professor Vector needs to find out which two magic words and in which order were concatenated by each student.

Your program needs to perform the role of Professor Vector: first, create $n$ distinct magic words, and then handle multiple requests where it is given the spell power and needs to determine the indices of the two magic words, in the correct order, that were used to create the corresponding spell.

Interaction

This is an interactive problem.

First, your program should read a single integer $n$ ($1 \le n \le 30$), the number of magic words to prepare. Then, it should print $n$ magic words it has created, one per line. The magic words must be distinct, each magic word must have at least 1 and at most $30\cdot n$ characters, and each character must be either X or O. We will denote the $i$-th magic word you printed as $w_i$ ($1 \le i \le n$).

Then, your program should read a single integer $q$ ($1 \le q \le 1000$), the number of students in the class. Then, it should repeat the following process $q$ times, one per student.

For the $j$-th student, it should first read a single integer $p_j$, the power of their spell. It is guaranteed that this number is computed by choosing two indices $u_j$ and $v_j$ independently and uniformly at random between 1 and $n$ inclusive, concatenating $w_{u_j}$ and $w_{v_j}$, and finding the number of different non-empty substrings of the resulting string. Then, your program must print the numbers $u_j$ and $v_j$, in this order ($1 \le u_j, v_j \le n$).

Note that it is not enough to find any two magic words that concatenate into a spell with the given power. You must find the exact words used by the student in the exact order.

Remember to flush the output stream after printing all magic words and after printing $u_j$ and $v_j$ for each student.

Example

Input

```
2

2
15

11
```

Output

```
XOXO
X

1 1

2 1
```

#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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {

    }
}

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

static bool isValidIntToken(const string& s) {
    if (s.empty()) return false;
    int i = 0;
    if (s[0] == '+' || s[0] == '-') {
        if (s.size() == 1) return false;
        i = 1;
    }
    for (; i < (int)s.size(); i++) if (s[i] < '0' || s[i] > '9') return false;
    return true;
}

static bool parseLL(const string& tok, long long& out) {
    if (!isValidIntToken(tok)) return false;
    try {
        size_t idx = 0;
        long long v = stoll(tok, &idx, 10);
        if (idx != tok.size()) return false;
        out = v;
        return true;
    } catch (...) {
        return false;
    }
}

struct SAM {
    vector<array<int, 2>> next;
    vector<int> link;
    vector<int> length;
    int last = 0;

    void init(int maxLen) {
        next.assign(2 * maxLen + 1, array<int, 2>{-1, -1});
        link.assign(2 * maxLen + 1, -1);
        length.assign(2 * maxLen + 1, 0);
        last = 0;
        next[0] = {-1, -1};
        link[0] = -1;
        length[0] = 0;
        sz = 1;
    }

    int sz = 1;

    void extend(int c) {
        int cur = sz++;
        length[cur] = length[last] + 1;
        next[cur] = {-1, -1};

        int p = last;
        while (p != -1 && next[p][c] == -1) {
            next[p][c] = cur;
            p = link[p];
        }
        if (p == -1) {
            link[cur] = 0;
        } else {
            int q = next[p][c];
            if (length[p] + 1 == length[q]) {
                link[cur] = q;
            } else {
                int clone = sz++;
                next[clone] = next[q];
                length[clone] = length[p] + 1;
                link[clone] = link[q];

                while (p != -1 && next[p][c] == q) {
                    next[p][c] = clone;
                    p = link[p];
                }
                link[q] = link[cur] = clone;
            }
        }
        last = cur;
    }

    long long distinctSubstringsNonEmpty() const {
        long long ans = 0;
        for (int v = 1; v < sz; v++) {
            int parent = link[v];
            int parentLen = (parent == -1 ? 0 : length[parent]);
            ans += (long long)length[v] - (long long)parentLen;
        }
        return ans;
    }
};

static long long spellPower(const string& s) {
    SAM sam;
    sam.init((int)s.size());
    for (char ch : s) {
        int c = (ch == 'O') ? 0 : 1;
        sam.extend(c);
    }
    return sam.distinctSubstringsNonEmpty();
}

static bool readTokenFromContestant(string& tok) {
    if (!(cin >> tok)) return false;
    return true;
}

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

    try {
        int n = inf.readInt(1, 30, "n");
        int q = inf.readInt(1, 1000, "q");

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

        query_limit = q;
        log_metrics();

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

        const int maxLen = 30 * n;
        vector<string> words(n + 1);
        set<string> seen;

        for (int i = 1; i <= n; i++) {
            string w;
            if (!readTokenFromContestant(w)) {
                finish(_pe, "EOF while reading magic words");
            }
            if ((int)w.size() < 1 || (int)w.size() > maxLen) {
                finish(_pe, "Magic word length out of bounds");
            }
            for (char ch : w) {
                if (ch != 'X' && ch != 'O') {
                    finish(_pe, "Magic word contains invalid character");
                }
            }
            if (seen.count(w)) {
                finish(_pe, "Magic words must be distinct");
            }
            seen.insert(w);
            words[i] = w;
        }

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

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

        for (int i = 0; i < q; i++) {
            int u = hiddenPairs[i].first;
            int v = hiddenPairs[i].second;

            string s = words[u] + words[v];
            long long p = spellPower(s);

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

            queries++;
            if (queries > hard_cap) finish(_pe, "Hard cap exceeded (too many interactions)");

            string tokU, tokV;
            if (!readTokenFromContestant(tokU) || !readTokenFromContestant(tokV)) {
                finish(_pe, "EOF while reading contestant answer");
            }
            long long ansU, ansV;
            if (!parseLL(tokU, ansU) || !parseLL(tokV, ansV)) {
                finish(_pe, "Non-integer contestant answer");
            }
            if (ansU < 1 || ansU > n || ansV < 1 || ansV > n) {
                finish(_pe, "Contestant answer indices out of range");
            }
            if ((int)ansU != u || (int)ansV != v) {
                finish(_wa, "Wrong pair");
            }
        }

        finish(_ok, "OK");
    } catch (const std::exception& e) {
        finish(_pe, string("Exception: ") + e.what());
    } catch (...) {
        finish(_pe, "Unknown exception");
    }
}

#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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {

    }
}

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

struct SAM {
    struct State {
        int link = -1;
        int len = 0;
        array<int, 2> next{{-1, -1}};
    };

    vector<State> st;
    int last = 0;

    SAM(int maxLen = 0) {
        st.reserve(max(1, 2 * maxLen));
        st.push_back(State());
        last = 0;
    }

    void extend(int c) {
        int cur = (int)st.size();
        st.push_back(State());
        st[cur].len = st[last].len + 1;

        int p = last;
        while (p != -1 && st[p].next[c] == -1) {
            st[p].next[c] = cur;
            p = st[p].link;
        }
        if (p == -1) {
            st[cur].link = 0;
        } else {
            int q = st[p].next[c];
            if (st[p].len + 1 == st[q].len) {
                st[cur].link = q;
            } else {
                int clone = (int)st.size();
                st.push_back(st[q]);
                st[clone].len = st[p].len + 1;
                while (p != -1 && st[p].next[c] == q) {
                    st[p].next[c] = clone;
                    p = st[p].link;
                }
                st[q].link = st[cur].link = clone;
            }
        }
        last = cur;
    }

    long long distinctSubstrings() const {
        long long ans = 0;
        for (int i = 1; i < (int)st.size(); i++) {
            int parent = st[i].link;
            int parentLen = (parent == -1 ? 0 : st[parent].len);
            ans += (long long)st[i].len - parentLen;
        }
        return ans;
    }
};

static bool isXO(const string& s) {
    for (char ch : s) if (ch != 'X' && ch != 'O') return false;
    return true;
}

static long long powerOfConcat(const string& a, const string& b) {
    string s;
    s.reserve(a.size() + b.size());
    s += a;
    s += b;
    SAM sam((int)s.size());
    for (char ch : s) sam.extend(ch == 'X' ? 0 : 1);
    return sam.distinctSubstrings();
}

static bool readTokenSafe(string& out) {
    out.clear();
    if (!(cin >> out)) return false;
    return true;
}

static bool readLongLongSafe(long long& out) {
    out = 0;
    string tok;
    if (!readTokenSafe(tok)) return false;
    int i = 0;
    bool neg = false;
    if (tok[i] == '+' || tok[i] == '-') {
        neg = (tok[i] == '-');
        i++;
    }
    if (i >= (int)tok.size()) return false;
    long long val = 0;
    for (; i < (int)tok.size(); i++) {
        if (tok[i] < '0' || tok[i] > '9') return false;
        int d = tok[i] - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

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

    int n = inf.readInt(1, 30, "n");
    int q = inf.readInt(1, 1000, "q");
    query_limit = q;

    vector<int> rem;
    while (!inf.seekEof()) rem.push_back(inf.readInt());

    bool fixedPairsMode = false;
    vector<pair<int,int>> fixedPairs;
    if ((int)rem.size() >= 2 * q) {
        fixedPairsMode = true;
        fixedPairs.reserve(q);
        for (int i = 0; i < q; i++) {
            int u = rem[2 * i];
            int v = rem[2 * i + 1];
            if (u < 1 || u > n || v < 1 || v > n) {
                finish(_pe, "invalid (u,v) in hidden input");
            }
            fixedPairs.push_back({u, v});
        }
    } else {

        fixedPairsMode = false;
    }

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

    log_metrics();

    vector<string> w(n + 1);
    unordered_set<string> seen;
    seen.reserve(n * 2);

    int maxLen = 30 * n;

    for (int i = 1; i <= n; i++) {
        string s;
        if (!readTokenSafe(s)) finish(_pe, "unexpected EOF while reading magic words");
        if ((int)s.size() < 1 || (int)s.size() > maxLen) finish(_pe, "magic word length out of range");
        if (!isXO(s)) finish(_pe, "magic word contains invalid characters");
        if (seen.count(s)) finish(_pe, "magic words must be distinct");
        seen.insert(s);
        w[i] = s;
    }

    vector<vector<long long>> pw(n + 1, vector<long long>(n + 1, 0));
    map<long long, vector<pair<int,int>>> groups;
    for (int u = 1; u <= n; u++) {
        for (int v = 1; v <= n; v++) {
            long long p = powerOfConcat(w[u], w[v]);
            pw[u][v] = p;
            groups[p].push_back({u, v});
        }
    }

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

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

    if (fixedPairsMode) {
        for (int i = 0; i < q; i++) {
            int u = fixedPairs[i].first;
            int v = fixedPairs[i].second;
            long long p = pw[u][v];

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

            long long ru, rv;
            if (!readLongLongSafe(ru) || !readLongLongSafe(rv)) finish(_pe, "unexpected EOF while reading answer");
            if (ru < 1 || ru > n || rv < 1 || rv > n) finish(_pe, "answer indices out of range");

            queries++;
            if (queries > hard_cap) finish(_pe, "too many queries (hard cap exceeded)");

            if ((int)ru != u || (int)rv != v) finish(_wa, "wrong (u,v) for non-adaptive case");
        }
        finish(_ok, "ok");
    } else {

        for (int i = 0; i < q; i++) {
            long long bestP = -1;
            int bestSz = -1;
            for (const auto& kv : groups) {
                int sz = (int)kv.second.size();
                if (sz > bestSz || (sz == bestSz && (bestP == -1 || kv.first < bestP))) {
                    bestSz = sz;
                    bestP = kv.first;
                }
            }
            if (bestP == -1) finish(_pe, "internal error: no possible powers");

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

            long long ru, rv;
            if (!readLongLongSafe(ru) || !readLongLongSafe(rv)) finish(_pe, "unexpected EOF while reading answer");
            if (ru < 1 || ru > n || rv < 1 || rv > n) finish(_pe, "answer indices out of range");

            queries++;
            if (queries > hard_cap) finish(_pe, "too many queries (hard cap exceeded)");

            const auto& cls = groups[bestP];
            bool inClass = false;
            for (const auto& pr : cls) {
                if (pr.first == (int)ru && pr.second == (int)rv) {
                    inClass = true;
                    break;
                }
            }
            if (!inClass) finish(_wa, "answer does not match the given power");

            if ((int)cls.size() >= 2) finish(_wa, "power collision: multiple pairs consistent with the same power");

        }
        finish(_ok, "ok");
    }
}

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

static vector<pair<int,int>> shuffledAllPairs(int n) {
    vector<pair<int,int>> all;
    all.reserve(n * n);
    for (int u = 1; u <= n; u++) {
        for (int v = 1; v <= n; v++) all.push_back({u, v});
    }
    for (int i = (int)all.size() - 1; i > 0; i--) {
        int j = rnd.next(0, i);
        swap(all[i], all[j]);
    }
    return all;
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 0);
    int qOpt = opt<int>("q", 0);

    int n, q;

    int seedTag = 0;
    if (argc >= 2) {
        string s = argv[1];
        bool ok = !s.empty();
        int sign = 1, pos = 0;
        if (ok && (s[0] == '-' || s[0] == '+')) { sign = (s[0] == '-') ? -1 : 1; pos = 1; }
        long long val = 0;
        for (int i = pos; i < (int)s.size(); i++) {
            if (s[i] < '0' || s[i] > '9') { ok = false; break; }
            val = val * 10 + (s[i] - '0');
            if (val > 2000000000LL) break;
        }
        if (ok) seedTag = (int)(val * sign);
    }

    if (nOpt > 0) n = nOpt;
    else {
        if (seedTag == 1) n = 1;
        else if (seedTag == 2) n = 30;
        else if (seedTag == 3) n = 30;
        else n = 30;
    }
    if (qOpt > 0) q = qOpt;
    else {
        if (seedTag == 1) q = 1;
        else if (seedTag == 2) q = 1;
        else if (seedTag == 3) q = 1000;
        else q = 1000;
    }

    n = max(1, min(30, n));
    q = max(1, min(1000, q));

    if (mode == "non") {
        cout << n << "\n";
        cout << q << "\n";

        vector<pair<int,int>> pairs;
        pairs.reserve(q);

        if (seedTag >= 1 && seedTag <= 3) {
            for (int i = 0; i < q; i++) {
                int u = rnd.next(1, n);
                int v = rnd.next(1, n);
                pairs.push_back({u, v});
            }
        } else {
            vector<pair<int,int>> all = shuffledAllPairs(n);
            int take = min(q, (int)all.size());
            for (int i = 0; i < take; i++) pairs.push_back(all[i]);

            while ((int)pairs.size() < q) {
                int u = rnd.next(1, n);
                int v = rnd.next(1, n);
                pairs.push_back({u, v});
            }
        }

        for (auto &e : pairs) {
            cout << e.first << " " << e.second << "\n";
        }
    } else if (mode == "adp") {
        cout << n << "\n";
        cout << q << "\n";
        int interactorSeed = rnd.next(1, 1000000000);
        cout << interactorSeed << "\n";
    } else {
        quitf(_fail, "unknown --mode (expected non/adp), got: %s", mode.c_str());
    }

    return 0;
}


The only difference between this problem and the hard version is the maximum number of questions.

This is an interactive problem.

There is a hidden integer $1 \le x \le n$ which you have to find. In order to find it you can ask at most $\mathbf{53}$ questions.

In each question you can choose a non-empty integer set $S$ and ask if $x$ belongs to $S$ or not, after each question, if $x$ belongs to $S$, you'll receive "YES", otherwise "NO".

But the problem is that not all answers are necessarily true (some of them are joking), it's just guaranteed that for each two consecutive questions, at least one of them is answered correctly.

Additionally to the questions, you can make at most $2$ guesses for the answer $x$. Each time you make a guess, if you guess $x$ correctly, you receive ":)" and your program should terminate, otherwise you'll receive ":(".

As a part of the joking, we will not fix the value of $x$ in the beginning. Instead, it can change throughout the interaction as long as all the previous responses are valid as described above.

Note that your answer guesses are always answered correctly. If you ask a question before and after a guess, at least one of these two questions is answered correctly, as normal.

Input

The only line of the input contains a single integer $n$ ($1 \le n \le 10^5$), the maximum possible value of $x$.

Interaction

For each question, if you want to ask about a set $S$, first print the character '?', then print the size of $S$ and then print the elements of $S$ one by one. Each element should be an integer between $1$ and $n$, the elements must be distinct. After each question, read a string "YES" or "NO", as explained in the statement. You can make at most $53$ such questions.

If you want to guess for $x$, first print the character '!' and then print your guess. After each guess, read ":)" or ":(". If you guess $x$ correctly, the answer is ":)" and your program should terminate immediately, otherwise you'll receive ":(". You can make at most $2$ such guesses.

After printing a query do not forget to output end of 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 documentation for other languages.

Example

Input

```
6

NO

:(

NO

:)
```

Output

```
? 5 1 2 5 4 3

! 6

? 4 1 2 3 4

! 5
```

Note

If the answer of the first question were correct, then $x$ would have been equal to $6$, but as we can see in the first guess, $6$ is not the answer.

So the answer of the first question is joking. As we know, the answer of at least one of our two questions is correct, since the answer of the first question was joking, the answer of the second question should be correct.

So we will understand that $x$ is not equal to $1, 2, 3$ or $4$, and we also knew that $x$ is not equal to $6$ either. Hence $x$ should be equal to $5$.

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

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

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());
}

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

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

    int n = inf.readInt(1, 100000, "n");
    int x = inf.readInt(1, n, "x");

    cout << n << endl;

    log_metrics();

    string token;
    long long interactions = 0;
    const long long HARD_CAP = 200000;
    int guesses = 0;

    while (true) {
        if (interactions++ > HARD_CAP) {
            finish(_pe, "Interaction hard cap exceeded");
        }

        if (!(cin >> token)) {

            finish(_wa, "Unexpected EOF (did not find answer)");
        }

        if (token == "?") {
            if (queries >= query_limit) {
                finish(_wa, "Query limit exceeded");
            }

            int k;
            if (!(cin >> k)) {
                finish(_wa, "Expected set size after '?'");
            }
            if (k < 1 || k > n) {
                finish(_wa, format("Invalid set size: %d", k));
            }

            vector<char> seen(n + 1, 0);
            bool has_x = false;
            for (int i = 0; i < k; i++) {
                int val;
                if (!(cin >> val)) {
                    finish(_wa, "Expected set element");
                }
                if (val < 1 || val > n) {
                    finish(_wa, "Set element out of range");
                }
                if (seen[val]) {
                    finish(_wa, "Duplicate element in set");
                }
                seen[val] = 1;
                if (val == x) has_x = true;
            }

            cout << (has_x ? "YES" : "NO") << endl;
            queries++;
            if (queries % 10 == 0) log_metrics();
            continue;
        }

        if (token == "!") {

            int guess;
            if (!(cin >> guess)) {
                finish(_wa, "Expected integer guess after '!'");
            }
            guesses++;
            if (guesses > 2) {
                finish(_wa, "Too many guesses");
            }

            if (guess == x) {
                cout << ":)" << endl;
                finish(_ok, "Guessed correctly");
            } else {
                cout << ":(" << endl;
            }
            continue;
        }

        finish(_wa, "Unknown query type");
    }

    return 0;
}

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

enum State {
    VALID = 0,
    WARNING = 1,
    ELIMINATED = 2
};

int n;
vector<State> states;
int alive_count = 0;

long long queries = 0;
const int QUERY_LIMIT = 53;
int guesses = 0;
const int GUESS_LIMIT = 2;

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

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

pair<int, int> simulate(const vector<bool>& in_set, bool ans_yes) {
    int next_alive = 0;
    int next_valid = 0;

    for (int i = 1; i <= n; i++) {
        if (states[i] == ELIMINATED) continue;

        bool inS = in_set[i];
        State current = states[i];
        State next_st = ELIMINATED;

        if (ans_yes) {

            if (inS) {

                next_st = VALID;
            } else {

                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            }
        } else {

            if (inS) {

                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            } else {

                next_st = VALID;
            }
        }

        if (next_st != ELIMINATED) {
            next_alive++;
            if (next_st == VALID) next_valid++;
        }
    }
    return {next_alive, next_valid};
}

void apply_transition(const vector<bool>& in_set, bool ans_yes) {
    alive_count = 0;
    for (int i = 1; i <= n; i++) {
        if (states[i] == ELIMINATED) continue;

        bool inS = in_set[i];
        State current = states[i];
        State next_st = ELIMINATED;

        if (ans_yes) {
            if (inS) next_st = VALID;
            else {
                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            }
        } else {
            if (inS) {
                if (current == VALID) next_st = WARNING;
                else next_st = ELIMINATED;
            } else {
                next_st = VALID;
            }
        }

        states[i] = next_st;
        if (next_st != ELIMINATED) alive_count++;
    }
}

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

    n = inf.readInt();

    log_metrics();

    cout << n << endl;

    states.assign(n + 1, VALID);
    alive_count = n;

    int operations = 0;
    const int HARD_CAP = 400;

    vector<bool> in_set(n + 1, false);

    while (true) {
        operations++;
        if (operations > HARD_CAP) {
            finish(_pe, "Too many operations (hard cap)");
        }

        string type;
        if (!(cin >> type)) {

            finish(_wa, "Solution exited without correct guess");
        }

        if (type == "?") {
            queries++;

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

            int k;
            if (!(cin >> k)) finish(_wa, "Expected set size");
            if (k < 1 || k > n) finish(_wa, "Invalid set size");

            vector<int> elements;
            elements.reserve(k);
            for (int i = 0; i < k; i++) {
                int val;
                if (!(cin >> val)) finish(_wa, "Expected element");
                if (val < 1 || val > n) finish(_wa, "Element out of range");
                elements.push_back(val);
            }

            for (int x : elements) {
                if (in_set[x]) finish(_wa, "Duplicate element in query set");
                in_set[x] = true;
            }

            pair<int, int> res_yes = simulate(in_set, true);
            pair<int, int> res_no = simulate(in_set, false);

            bool say_yes = false;

            if (res_yes.first > res_no.first) {
                say_yes = true;
            } else if (res_no.first > res_yes.first) {
                say_yes = false;
            } else {

                if (res_yes.second >= res_no.second) {
                    say_yes = true;
                } else {
                    say_yes = false;
                }
            }

            apply_transition(in_set, say_yes);
            cout << (say_yes ? "YES" : "NO") << endl;

            for (int x : elements) in_set[x] = false;

        } else if (type == "!") {
            guesses++;
            if (guesses > GUESS_LIMIT) finish(_pe, "Too many guesses");

            int guess_val;
            if (!(cin >> guess_val)) finish(_wa, "Expected guess value");

            bool possible = (guess_val >= 1 && guess_val <= n && states[guess_val] != ELIMINATED);

            if (!possible) {

                cout << ":(" << endl;
            } else {

                if (alive_count > 1) {
                    cout << ":(" << endl;
                    states[guess_val] = ELIMINATED;
                    alive_count--;
                } else {
                    cout << ":)" << endl;
                    finish(_ok, "Guessed correctly");
                }
            }
        } else {
            finish(_wa, "Unknown query type");
        }
    }
    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 n = opt<int>("n", -1);

    if (n == -1) {
        long long seedVal = 0;

        if (argc > 1) {
            try {
                seedVal = stoll(argv[1]);
            } catch (...) {
                seedVal = 0;
            }
        }

        if (seedVal == 1) n = 100000;
        else if (seedVal == 2) n = 1;
        else if (seedVal == 3) n = 2;
        else if (seedVal == 4) n = 3;
        else if (seedVal == 5) n = 4;
        else if (seedVal == 6) n = 10;
        else if (seedVal == 7) n = 100;
        else {

            if (rnd.next(10) == 0) {
                n = rnd.next(1, 100);
            } else {
                n = rnd.next(100, 100000);
            }
        }
    }

    if (mode == "non") {

        int x = rnd.next(1, n);
        println(n, x);
    } else if (mode == "adp") {

        println(n);
    } else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}


This is an interactive problem.

Now Serval is a senior high school student in Japari Middle School. However, on the way to the school, he must go across a pond, in which there is a dangerous snake. The pond can be represented as a $n \times n$ grid. The snake has a head and a tail in different cells, and its body is a series of adjacent cells connecting the head and the tail without self-intersecting. If Serval hits its head or tail, the snake will bite him and he will die.

Luckily, he has a special device which can answer the following question: you can pick a rectangle, it will tell you the number of times one needs to cross the border of the rectangle walking cell by cell along the snake from the head to the tail. The pictures below show a possible snake and a possible query to it, which will get an answer of $4$.

 ![](https://espresso.codeforces.com/95652ffad46f36bf8dda20ad0e718e2278b1096b.png)  ![](https://espresso.codeforces.com/fc4f7627830cbe45738e7543a046cae6f1f858da.png)

Today Serval got up too late and only have time to make $2019$ queries. As his best friend, can you help him find the positions of the head and the tail?

Note that two cells are adjacent if and only if they have a common edge in the grid, and a snake can have a body of length $0$, that means it only has adjacent head and tail.

Also note that the snake is sleeping, so it won't move while Serval using his device. And what's obvious is that the snake position does not depend on your queries.

Input

The first line contains a single integer $n$ ($2\leq n \leq 1000$) — the size of the grid.

Output

When you are ready to answer, you should print ! x1 y1 x2 y2, where $(x_1, y_1)$ represents the position of the head and $(x_2,y_2)$ represents the position of the tail. You can print head and tail in any order.

Interaction

To make a query, you should print ? x1 y1 x2 y2 ($1 \leq x_1 \leq x_2 \leq n$, $1\leq y_1 \leq y_2 \leq n$), representing a rectangle consisting of all cells $(x,y)$ such that $x_1 \leq x \leq x_2$ and $y_1 \leq y \leq y_2$. You will get a single integer as the answer.

After printing a query, do not forget to output the end of 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 documentation for other languages.

Answer $-1$ instead of a valid answer means that you made an invalid query or exceeded the maximum number of queries. Exit immediately after receiving $-1$ and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

If your program cannot find out the head and tail of the snake correctly, you will also get a Wrong Answer verdict.

Examples

Input

```
2

1

0

0
```

Output

```
? 1 1 1 1

? 1 2 1 2

? 2 2 2 2

! 1 1 2 1
```

Input

```
3

2

0
```

Output

```
? 2 2 2 2

? 2 1 2 3

! 2 1 2 3
```

Note

 ![](https://espresso.codeforces.com/e99f68d2bd9d49b9944f0e1f2441a371b15c9231.png)  ![](https://espresso.codeforces.com/c2d364b093a2d4e05b4e085cd1690a6d69954840.png)  ![](https://espresso.codeforces.com/4ddccf6f38769989691d1f0ea9ad6066929a41fe.png)  ![](https://espresso.codeforces.com/3d1ed786478ab08f799467e9cc458aa2de75696b.png)

The pictures above show our queries and the answers in the first example. We first made a query for $(1,1)$ and got an answer $1$, then found that it must be connected to exactly one other cell. Then we made a query for $(1,2)$ and got an answer of $0$, then knew that the snake never entered it. So the cell connected to $(1,1)$ must be $(2,1)$. Then we made a query for $(2,2)$ and got an answer $0$, then knew that it never entered $(2,2)$ as well. So the snake cannot leave $(2,1)$, which implies that the answer is $(1,1)$ and $(2,1)$.

 ![](https://espresso.codeforces.com/0576a29dc4d6548b5fd63f165ecfad387b220334.png)  ![](https://espresso.codeforces.com/8fb34e3007b66c3443c47b37b5c8e14f0ed1b33b.png)  ![](https://espresso.codeforces.com/e73a4b234db4f1566ef5d032a8f83bab23fb2273.png)

The pictures above show our queries and the answers in the second example. By making query to $(2,2)$ and receiving $2$, we found that the snake occupies $(2,2)$. And by making query to rectangle from $(2,1)$ to $(2,3)$ and receiving answer $0$, we knew that it never goes out of the rectangle from $(2,1)$ to $(2,3)$. Since the first answer is $2$, both $(2,1)$ and $(2,3)$ must be occupied but none of others, so the answer is $(2,1)$ and $(2,3)$.

#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 << "\n";
        tout << "query_limit=" << query_limit << "\n";
        tout.flush();
    } catch (...) {

    }
}

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

static bool parseLongLongStrict(const string& s, long long& out) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[i] == '+' || s[i] == '-') {
        neg = (s[i] == '-');
        i++;
        if (i == (int)s.size()) return false;
    }
    long long val = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

static bool readToken(string& tok) {
    tok.clear();
    if (!(cin >> tok)) return false;
    return true;
}

static bool readIntToken(long long& x) {
    string s;
    if (!readToken(s)) return false;
    return parseLongLongStrict(s, x);
}

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

    int n = 0;
    int m = 0;

    try {
        n = inf.readInt(2, 1000, "n");
        m = inf.readInt(2, n * n, "m");
    } catch (...) {
        query_limit = 2019;
        log_metrics();
        finish(_pe, "invalid hidden input header");
    }

    query_limit = 2019;
    log_metrics();

    vector<pair<int,int>> snake;
    snake.reserve(m);
    try {
        for (int i = 0; i < m; i++) {
            int x = inf.readInt(1, n, "x");
            int y = inf.readInt(1, n, "y");
            snake.push_back({x, y});
        }
    } catch (...) {
        finish(_pe, "invalid hidden input snake");
    }

    for (int i = 0; i + 1 < m; i++) {
        int x1 = snake[i].first, y1 = snake[i].second;
        int x2 = snake[i + 1].first, y2 = snake[i + 1].second;
        int dist = abs(x1 - x2) + abs(y1 - y2);
        if (dist != 1) finish(_pe, "hidden snake is not a simple adjacent path");
    }

    const int VCols = max(0, n - 1);
    const int HRows = max(0, n - 1);

    vector<int> prefV((size_t)VCols * (n + 1), 0);
    vector<int> prefH((size_t)HRows * (n + 1), 0);

    auto idxV = [&](int c, int x) -> size_t {
        return (size_t)(c - 1) * (n + 1) + (size_t)x;
    };
    auto idxH = [&](int r, int y) -> size_t {
        return (size_t)(r - 1) * (n + 1) + (size_t)y;
    };

    for (int i = 0; i + 1 < m; i++) {
        int x1 = snake[i].first, y1 = snake[i].second;
        int x2 = snake[i + 1].first, y2 = snake[i + 1].second;
        if (x1 == x2) {
            int c = min(y1, y2);
            if (1 <= c && c <= n - 1) prefV[idxV(c, x1)] += 1;
        } else if (y1 == y2) {
            int r = min(x1, x2);
            if (1 <= r && r <= n - 1) prefH[idxH(r, y1)] += 1;
        } else {
            finish(_pe, "hidden snake has non-grid edge");
        }
    }

    for (int c = 1; c <= n - 1; c++) {
        for (int x = 1; x <= n; x++) {
            prefV[idxV(c, x)] += prefV[idxV(c, x - 1)];
        }
    }
    for (int r = 1; r <= n - 1; r++) {
        for (int y = 1; y <= n; y++) {
            prefH[idxH(r, y)] += prefH[idxH(r, y - 1)];
        }
    }

    auto sumV = [&](int c, int x1, int x2) -> long long {
        if (c < 1 || c > n - 1) return 0;
        if (x1 > x2) return 0;
        return (long long)prefV[idxV(c, x2)] - (long long)prefV[idxV(c, x1 - 1)];
    };
    auto sumH = [&](int r, int y1, int y2) -> long long {
        if (r < 1 || r > n - 1) return 0;
        if (y1 > y2) return 0;
        return (long long)prefH[idxH(r, y2)] - (long long)prefH[idxH(r, y1 - 1)];
    };

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

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

    while (true) {
        string op;
        if (!readToken(op)) finish(_pe, "unexpected EOF (no final answer)");

        if (op == "?") {
            long long X1, Y1, X2, Y2;
            if (!readIntToken(X1) || !readIntToken(Y1) || !readIntToken(X2) || !readIntToken(Y2)) {
                cout << -1 << "\n";
                cout.flush();
                finish(_pe, "malformed query arguments");
            }

            queries++;
            if (queries > hard_cap) {
                cout << -1 << "\n";
                cout.flush();
                finish(_pe, "hard cap exceeded");
            }

            if (!(1 <= X1 && X1 <= X2 && X2 <= n && 1 <= Y1 && Y1 <= Y2 && Y2 <= n)) {
                cout << -1 << "\n";
                cout.flush();
                finish(_pe, "invalid query rectangle");
            }

            int x1 = (int)X1, y1 = (int)Y1, x2 = (int)X2, y2 = (int)Y2;

            long long ans = 0;
            if (y1 > 1) ans += sumV(y1 - 1, x1, x2);
            if (y2 < n) ans += sumV(y2, x1, x2);
            if (x1 > 1) ans += sumH(x1 - 1, y1, y2);
            if (x2 < n) ans += sumH(x2, y1, y2);

            cout << ans << "\n";
            cout.flush();
        } else if (op == "!") {
            long long X1, Y1, X2, Y2;
            if (!readIntToken(X1) || !readIntToken(Y1) || !readIntToken(X2) || !readIntToken(Y2)) {
                finish(_pe, "malformed answer arguments");
            }
            if (!(1 <= X1 && X1 <= n && 1 <= Y1 && Y1 <= n && 1 <= X2 && X2 <= n && 1 <= Y2 && Y2 <= n)) {
                finish(_wa, "answer coordinates out of bounds");
            }

            pair<int,int> a = {(int)X1, (int)Y1};
            pair<int,int> b = {(int)X2, (int)Y2};
            pair<int,int> head = snake.front();
            pair<int,int> tail = snake.back();

            if ((a == head && b == tail) || (a == tail && b == head)) {
                finish(_ok, "correct");
            } else {
                finish(_wa, "incorrect head/tail");
            }
        } else {
            finish(_pe, "unknown operation token");
        }
    }
}

#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 << '\n';
        tout << "query_limit=" << query_limit << '\n';
        tout.flush();
    } catch (...) {

    }
}

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

static inline bool inRect(int x, int y, int x1, int y1, int x2, int y2) {
    return x1 <= x && x <= x2 && y1 <= y && y <= y2;
}

static inline int serpentineX(int n, int idx0) { return idx0 / n + 1; }
static inline int serpentineY(int n, int idx0) {
    int x = serpentineX(n, idx0);
    int pos = idx0 % n;
    if (x & 1) return pos + 1;
    return n - pos;
}

static inline int serpentineIdx(int n, int x, int y) {

    if (x & 1) return (x - 1) * n + (y - 1);
    return (x - 1) * n + (n - y);
}

static inline long long popcount_vec(const vector<uint64_t>& a) {
    long long s = 0;
    for (uint64_t w : a) s += __builtin_popcountll(w);
    return s;
}

static inline long long popcount_and(const vector<uint64_t>& a, const vector<uint64_t>& b) {
    long long s = 0;
    size_t W = a.size();
    for (size_t i = 0; i < W; i++) s += __builtin_popcountll(a[i] & b[i]);
    return s;
}

static inline void set_bit(vector<uint64_t>& bs, int idx) {
    bs[(unsigned)idx >> 6] |= (1ULL << (idx & 63));
}

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

    int n = inf.readInt(2, 1000, "n");
    int m = inf.readInt(2, n * n, "m");
    vector<pair<int,int>> cells;
    cells.reserve(m);
    for (int i = 0; i < m; i++) {
        int x = inf.readInt(1, n, "x");
        int y = inf.readInt(1, n, "y");
        cells.push_back({x, y});
    }

    int edges = m - 1;
    if (edges <= 0) finish(_pe, "bad hidden input: m < 2");

    query_limit = 2019;
    log_metrics();

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

    bool isSerpentineFull = (m == n * n);
    if (isSerpentineFull) {
        for (int i = 0; i < m; i++) {
            int ex = serpentineX(n, i);
            int ey = serpentineY(n, i);
            if (cells[i].first != ex || cells[i].second != ey) {
                isSerpentineFull = false;
                break;
            }
        }
    }

    size_t W = (edges + 63) / 64;
    uint64_t lastMask = (edges % 64 == 0) ? ~0ULL : ((1ULL << (edges % 64)) - 1ULL);

    vector<uint64_t> cand(W, ~0ULL);
    cand.back() &= lastMask;
    long long cand_count = edges;

    cout << n << endl;

    string cmd;
    while (true) {
        if (!(cin >> cmd)) {
            finish(_wa, "unexpected EOF from contestant");
        }

        if (cmd == "?") {
            long long x1ll, y1ll, x2ll, y2ll;
            if (!(cin >> x1ll >> y1ll >> x2ll >> y2ll)) finish(_pe, "malformed query arguments");

            if (x1ll < 1 || y1ll < 1 || x2ll < 1 || y2ll < 1 ||
                x1ll > x2ll || y1ll > y2ll || x2ll > n || y2ll > n) {
                finish(_pe, "query rectangle out of range");
            }
            int x1 = (int)x1ll, y1 = (int)y1ll, x2 = (int)x2ll, y2 = (int)y2ll;

            queries++;
            if (queries > hard_cap) finish(_pe, "too many queries (hard cap)");

            vector<uint64_t> trans(W, 0ULL);

            if (isSerpentineFull) {

                for (int x = x1; x <= x2; x++) {
                    if (x & 1) {
                        if (y1 > 1) {
                            int i = (x - 1) * n + (y1 - 2);
                            if (0 <= i && i < edges) set_bit(trans, i);
                        }
                        if (y2 < n) {
                            int i = (x - 1) * n + (y2 - 1);
                            if (0 <= i && i < edges) set_bit(trans, i);
                        }
                    } else {
                        if (y2 < n) {
                            int i = (x - 1) * n + (n - (y2 + 1));
                            if (0 <= i && i < edges) set_bit(trans, i);
                        }
                        if (y1 > 1) {
                            int i = (x - 1) * n + (n - y1);
                            if (0 <= i && i < edges) set_bit(trans, i);
                        }
                    }
                }

                for (int x = 1; x <= n - 1; x++) {
                    int c = (x & 1) ? n : 1;
                    bool inside1 = inRect(x, c, x1, y1, x2, y2);
                    bool inside2 = inRect(x + 1, c, x1, y1, x2, y2);
                    if (inside1 != inside2) {
                        int i = x * n - 1;
                        if (0 <= i && i < edges) set_bit(trans, i);
                    }
                }
            } else {

                bool prev = inRect(cells[0].first, cells[0].second, x1, y1, x2, y2);
                for (int i = 0; i < edges; i++) {
                    bool cur = inRect(cells[i + 1].first, cells[i + 1].second, x1, y1, x2, y2);
                    if (prev != cur) set_bit(trans, i);
                    prev = cur;
                }
            }

            trans.back() &= lastMask;

            long long count1 = popcount_and(cand, trans);
            long long count0 = cand_count - count1;

            int ans = 0;
            if (count1 > count0) ans = 1;

            if (ans == 1) {
                for (size_t i = 0; i < W; i++) cand[i] &= trans[i];
            } else {
                for (size_t i = 0; i < W; i++) cand[i] &= ~trans[i];
                cand.back() &= lastMask;
            }

            cand_count = popcount_vec(cand);
            if (cand_count <= 0) finish(_wa, "no feasible hidden instances remain (internal)");

            cout << ans << endl;
        } else if (cmd == "!") {
            long long axll, ayll, bxll, byll;
            if (!(cin >> axll >> ayll >> bxll >> byll)) finish(_pe, "malformed final answer arguments");
            if (axll < 1 || axll > n || ayll < 1 || ayll > n || bxll < 1 || bxll > n || byll < 1 || byll > n) {
                finish(_pe, "final answer out of range");
            }
            int ax = (int)axll, ay = (int)ayll, bx = (int)bxll, by = (int)byll;
            if (ax == bx && ay == by) finish(_pe, "final answer uses identical cells");

            bool any = false;
            for (size_t wi = 0; wi < W; wi++) {
                uint64_t w = cand[wi];
                while (w) {
                    int b = __builtin_ctzll(w);
                    int i = (int)(wi * 64 + b);
                    w &= (w - 1);
                    if (i < 0 || i >= edges) continue;

                    any = true;
                    auto p = cells[i];
                    auto q = cells[i + 1];

                    bool ok =
                        (p.first == ax && p.second == ay && q.first == bx && q.second == by) ||
                        (p.first == bx && p.second == by && q.first == ax && q.second == ay);

                    if (!ok) finish(_wa, "wrong head/tail for at least one feasible instance");
                }
            }
            if (!any) finish(_wa, "no feasible instances at final check");

            finish(_ok, "OK");
        } else {
            finish(_pe, "invalid command token");
        }
    }
}

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

static vector<pair<int,int>> buildSerpentine(int n) {
    vector<pair<int,int>> p;
    p.reserve(1LL * n * n);
    for (int i = 1; i <= n; i++) {
        if (i & 1) {
            for (int j = 1; j <= n; j++) p.push_back({i, j});
        } else {
            for (int j = n; j >= 1; j--) p.push_back({i, j});
        }
    }
    return p;
}

static vector<pair<int,int>> takeSegment(const vector<pair<int,int>>& p, int l, int r, bool rev) {
    vector<pair<int,int>> s;
    s.reserve(r - l + 1);
    if (!rev) {
        for (int i = l; i <= r; i++) s.push_back(p[i]);
    } else {
        for (int i = r; i >= l; i--) s.push_back(p[i]);
    }
    return s;
}

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

    string mode = opt<string>("mode", "non");
    int seed = 1;
    if (argc >= 2) seed = atoi(argv[1]);

    int nOpt = opt<int>("n", 1000);
    int n = max(2, min(1000, nOpt));

    if (mode == "adp") {

        vector<pair<int,int>> base = buildSerpentine(n);
        cout << n << "\n";
        cout << (int)base.size() << "\n";
        for (auto &c : base) cout << c.first << " " << c.second << "\n";
        return 0;
    }

    vector<pair<int,int>> snake;

    if (seed == 1) {
        n = 2;
        snake = {{1, 1}, {2, 1}};
    } else if (seed == 2) {
        n = 3;

        snake = {
            {2, 2}, {2, 1}, {1, 1}, {1, 2}, {1, 3}, {2, 3}, {3, 3}, {3, 2}, {3, 1}
        };
    } else if (seed == 3) {
        n = 1000;
        snake = buildSerpentine(n);
    } else {
        vector<pair<int,int>> base = buildSerpentine(n);
        int N = (int)base.size();

        int style = rnd.next(0, 99);
        bool rev = (rnd.next(0, 1) == 1);

        if (N == 2) {
            snake = base;
        } else if (style < 60) {

            int maxTrim = min(5000, N - 2);
            int leftTrim = rnd.next(0, maxTrim);
            int rightTrim = rnd.next(0, maxTrim);

            int l = leftTrim;
            int r = N - 1 - rightTrim;
            if (r - l + 1 < 2) {
                l = 0;
                r = N - 1;
            }
            snake = takeSegment(base, l, r, rev);
        } else if (style < 80) {

            int maxLen = min(50, N);
            int len = rnd.next(2, maxLen);
            int l = rnd.next(0, N - len);
            int r = l + len - 1;
            snake = takeSegment(base, l, r, rev);
        } else {

            int centerL = N / 3;
            int centerR = (2 * N) / 3;

            int wiggle = min(20000, N / 6);
            int l = max(0, centerL - rnd.next(0, wiggle));
            int r = min(N - 1, centerR + rnd.next(0, wiggle));
            if (r - l + 1 < 2) {
                l = 0;
                r = N - 1;
            }
            snake = takeSegment(base, l, r, rev);
        }
    }

    cout << n << "\n";
    cout << (int)snake.size() << "\n";
    for (auto &c : snake) cout << c.first << " " << c.second << "\n";
    return 0;
}


This is the simple version of the problem. The only difference between the versions is the limit on the number of queries. In this version, you can make no more than 100 queries.

This is an interactive problem!

salyg1n has given you a positive integer $k$ and wants to play a game with you. He has chosen an array of $n$ integers $a_1, a_2, \ldots, a_n$ ($1 \leq a_i \leq 10^9$). You must print $a_1 \oplus a_2 \oplus \ldots \oplus a_n$, where $\oplus$ denotes the bitwise XOR operation. You can make queries of the following type:

* $?$ $i$: in response to this query, you will receive $a_i \oplus a_{i + 1} \oplus \ldots \oplus a_{i + k - 1}$. Also, after this query, the subarray $a_i, a_{i + 1}, \ldots, a_{i + k - 1}$ will be reversed, i.e., the chosen array $a$ will become: $a_1, a_2, \ldots a_{i - 1}, a_{i + k - 1}, a_{i + k - 2}, \ldots, a_{i + 1}, a_i, a_{i + k}, \ldots, a_n$.

You can make no more than $100$ queries to answer the problem.

Input

The first line contains a single integer $t$ ($1 \leq t \leq 1000$) – the number of test cases.

Interaction

The interaction between your program and the jury's program begins with reading two positive even integers $n$ and $k$ ($1 \leq k \leq n \leq k^2 \leq 2500$) – the length of the chosen array and the length of the query subarray, respectively.

To find the value of $a_i \oplus a_{i + 1} \oplus \ldots \oplus a_{i + k - 1}$, print the query in the format $?$ $i$ ($1 \leq i \leq n - k + 1$). Then read a single integer – the answer to your query.

You can make no more than $100$ queries. When you are ready to print the answer, output it in the format $!$ $x$. After that, proceed to process the next test case or terminate the program if it was the last test case. Printing the answer does not count as one of the $100$ queries.

If your program makes more than $100$ queries for one set of input data, or makes an invalid query, then the response to the query will be -1. After receiving such a response, your program should immediately terminate to receive the verdict Wrong Answer. Otherwise, it may receive any other verdict.

After printing a query do not forget to output the end of 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.

It is guaranteed that the sum of $n$ over all test cases does not exceed $10000$. The interactor in this problem is not adaptive.

Example

Input

```
2
4 2

6

4

6 6

4
```

Output

```? 1? 3! 2? 1! 4
```

Note

In the first test case, the jury has chosen the array $a$ $=$ $[4, 2, 5, 1]$

In the second test case, the jury has chosen the array $a$ $=$ $[5, 7, 1, 3, 3, 7]$

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

static int current_queries = 0;
static int max_queries_seen = 0;
static const int QUERY_LIMIT = 100;

void finish(TResult verdict, const string& msg);

static int smallest_even_sqrt_at_least(int n) {
    int r = (int)ceil(sqrt((long double)n));
    if (r % 2 != 0) r++;
    return r;
}

static int sanitize_k(int n, int k_in) {
    auto is_valid = [&](int k) -> bool {
        return k >= 1 && k <= n && k % 2 == 0 && 1LL * k * k >= n && 1LL * k * k <= 2500;
    };

    if (is_valid(k_in)) return k_in;

    int k = min(n, 50);
    if (k % 2 != 0) k--;
    if (k < 2) k = 2;
    if (k > n) k = n - (n % 2);

    if (is_valid(k)) return k;

    int min_k = smallest_even_sqrt_at_least(n);
    if (min_k > 50) {

        finish(_fail, format("Invalid test constraints: n=%d cannot satisfy n<=k^2<=2500", n));
    }
    if (min_k > n) {
        finish(_fail, format("Invalid test constraints: n=%d cannot satisfy k<=n with even k", n));
    }
    return min_k;
}

void log_metrics() {

    int q = max(max_queries_seen, current_queries);
    try {
        tout << "queries=" << q << endl;
        tout << "query_limit=" << QUERY_LIMIT << endl;
    } catch (...) {

    }
}

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

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

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

    int t = inf.readInt();

    cout << t << endl;

    for (int cas = 1; cas <= t; ++cas) {

        current_queries = 0;

        int n = inf.readInt();
        int k_in = inf.readInt();

        vector<int> a(n);
        long long initial_xor_sum = 0;
        for (int i = 0; i < n; ++i) {
            a[i] = inf.readInt();
            initial_xor_sum ^= a[i];
        }

        int k = sanitize_k(n, k_in);

        cout << n << " " << k << endl;

        bool case_active = true;
        while (case_active) {
            string token;
            if (!(cin >> token)) {
                finish(_pe, format("Unexpected end of file while reading query/answer in case %d", cas));
            }

            if (token == "!") {

                long long ans;
                if (!(cin >> ans)) {
                    finish(_pe, "Expected integer answer after '!'");
                }

                if (ans != initial_xor_sum) {
                    finish(_wa, format("Wrong answer in case %d: expected %lld, found %lld", cas, initial_xor_sum, ans));
                }

                if (current_queries > max_queries_seen) {
                    max_queries_seen = current_queries;
                }
                case_active = false;
            } else if (token == "?") {

                int i;
                if (!(cin >> i)) {
                    finish(_pe, "Expected integer index after '?'");
                }

                current_queries++;

                if (current_queries > QUERY_LIMIT) {
                    cout << -1 << endl;
                    finish(_wa, format("Query limit exceeded (>%d) in test case %d", QUERY_LIMIT, cas));
                }

                if (i < 1 || i > n - k + 1) {
                    cout << -1 << endl;
                    finish(_wa, format("Invalid query index %d in case %d (n=%d, k=%d)", i, cas, n, k));
                }

                long long subarray_xor = 0;
                for (int j = 0; j < k; ++j) {
                    subarray_xor ^= a[i - 1 + j];
                }

                reverse(a.begin() + (i - 1), a.begin() + (i - 1) + k);

                cout << subarray_xor << endl;
            } else {
                finish(_pe, format("Invalid protocol token '%s' in case %d (expected '?' or '!')", token.c_str(), cas));
            }
        }
    }

    finish(_ok, "All cases passed");
    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");

    vector<pair<int, int>> cases;
    long long sum_n = 0;
    const int MAX_SUM_N = 10000;

    auto try_add = [&](int n, int k) -> bool {
        if (n % 2 != 0) return false;
        if (k % 2 != 0) return false;
        if (k > n) return false;
        if (1LL * k * k < n) return false;
        if (1LL * k * k > 2500) return false;
        if (n > 2500) return false;
        if (sum_n + n > MAX_SUM_N) return false;

        cases.push_back({n, k});
        sum_n += n;
        return true;
    };

    if (string(argv[1]) == "1") {
        try_add(2, 2);
        try_add(4, 2);
        try_add(6, 2);
        try_add(4, 4);
        try_add(6, 4);
        try_add(10, 4);
        try_add(16, 4);

        try_add(100, 10);
        try_add(100, 12);
        try_add(50, 50);

        try_add(2500, 50);
        try_add(2400, 50);

        try_add(2350, 50);
    }

    while (sum_n < MAX_SUM_N) {
        int remaining = (int)(MAX_SUM_N - sum_n);
        if (remaining < 2) break;

        int limit_n = min(2500, remaining);
        if (limit_n < 2) break;

        int n;
        int n_type = rnd.next(1, 10);

        if (n_type <= 2) {

            n = rnd.next(2, min(limit_n, 50));
        } else if (n_type <= 8) {

            n = rnd.next(2, limit_n);
        } else {

            int lower = max(2, limit_n - 200);
            n = rnd.next(lower, limit_n);
        }

        if (n % 2 != 0) n--;
        if (n < 2) n = 2;

        int min_k = ceil(sqrt(n));
        if (min_k % 2 != 0) min_k++;

        if (min_k > n) {

            continue;
        }

        int max_k = min(n, 50);
        if (max_k % 2 != 0) max_k--;
        int k_range_steps = (max_k - min_k) / 2;
        int k;

        if (k_range_steps == 0) {
            k = min_k;
        } else {
            int k_type = rnd.next(1, 5);
            if (k_type == 1) k = min_k;
            else if (k_type == 2) k = max_k;
            else if (k_type == 3) {
                int step = rnd.next(1, min(5, k_range_steps));
                k = min_k + 2 * step;
            } else if (k_type == 4) {
                int step = rnd.next(1, min(5, k_range_steps));
                k = max_k - 2 * step;
            } else {
                int step = rnd.next(0, k_range_steps);
                k = min_k + 2 * step;
            }
        }

        if (!try_add(n, k)) {

            if (limit_n <= 4) break;
        }
    }

    println(cases.size());
    for (const auto& p : cases) {
        int n = p.first;
        int k = p.second;
        println(n, k);

        if (mode == "non") {

            vector<int> a(n);
            for (int i = 0; i < n; i++) {
                a[i] = rnd.next(1, 1000000000);
            }
            println(a);
        }

    }

    return 0;
}