This is an interactive problem.

Misha likes to play cooperative games with incomplete information. Today he suggested ten his friends to play a cooperative game "Lake".

Misha has already come up with a field for the upcoming game. The field for this game is a directed graph consisting of two parts. The first part is a road along the coast of the lake which is a cycle of $c$ vertices. The second part is a path from home to the lake which is a chain of $t$ vertices, and there is an edge from the last vertex of this chain to the vertex of the road along the coast which has the most beautiful view of the lake, also known as the finish vertex. Misha decided to keep the field secret, so nobody knows neither $t$ nor $c$.

 ![](https://espresso.codeforces.com/af92f1219aedcbc53b754b15118dfe4ce5a1be84.png)

Note that each vertex of the field has exactly one outgoing edge and all the vertices except the home vertex and the finish vertex have exactly one ingoing edge. The home vertex has no incoming edges, the finish vertex has two incoming edges.

At the beginning of the game pieces of all the ten players, indexed with consecutive integers from $0$ to $9$, are at the home vertex. After that on each turn some of the players can ask Misha to simultaneously move their pieces along the corresponding edges. Misha will not answer more than $q$ such queries. After each move Misha will tell players whose pieces are at the same vertices and whose pieces are at different vertices.

The goal of the game is to move all the pieces to the finish vertex. Misha's friends have no idea how to win in such a game without knowledge of $c$, $t$ and $q$, but luckily they are your friends. Help them: coordinate their actions to win the game.

Misha has drawn such a field that $1 \le t, c$, $(t+c) \leq 1000$ and $q = 3 \cdot (t+c)$.

Input

There is no input — go to the interaction part straight away.

Output

After all friends gather at the finish vertex, print "done" and terminate your program.

Interaction

To give a command to move the friends, print "next" and then space-separated indices of the friends you want to move. For example, to give the command to move the friends with indices $0$, $2$, $5$ and $9$ print "next 0 2 5 9". At each turn, you must move at least one of your friends.

As an answer, first read an integer $k$, and then $10$ digits divided into $k$ space-separated groups. The friends that correspond to the indices in the same group are in the same vertex. The friends that correspond to indices in different groups are in different vertices. The indices in each group follow in ascending order.

For example, the answer "2 05 12346789" means that the friends with indices $0$ and $5$ are in one vertex, and all other friends are in the same but different vertex. The answer "4 01 567 234 89" means that Misha's friends are in four different vertices: the friends with indices $0$ and $1$ are in the first, the friends with indices $5$, $6$ and $7$ are in the second, the friends with indices $2$, $3$ and $4$ are in the third, and the friends with indices $8$ and $9$ are in the fourth.

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 "stop" instead of a valid one means that you made an invalid query. Exit immediately after receiving "stop" 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

```
2 05 12346789

3 246789 135 0

3 246789 0 135

3 246789 0 135

2 135 0246789

1 0123456789
```

Output

```
next 0 5

next 0 1 3

next 2 3 0 1 4 5 6 7 8 9

next 9 8 7 6 5 4 3 2 1 0

next 0 1 3 5

next 1 3 5

done
```

Note

In the sample input and output values are aligned only for simplicity of interpreting them chronologically. In real interaction no "extra" line breaks should appear.

In the example, the friends move as follows:

 ![](https://espresso.codeforces.com/5e7369269b460f4d6497aee10638d37077d49e30.png)

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

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

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

    }
}

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

static bool isAllDigits(const string& s) {
    if (s.empty()) return false;
    for (char ch : s) if (ch < '0' || ch > '9') return false;
    return true;
}

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

    int t = inf.readInt(1, 1000, "t");
    int c = inf.readInt(1, 1000, "c");
    ensuref(t + c <= 1000, "t+c must be <= 1000");

    query_limit = 3LL * (t + c);
    log_metrics();

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

    const int finishVertex = t;
    const int cycleStart = t;
    const int cycleLen = c;

    vector<int> pos(10, 0);

    auto nextVertex = [&](int v) -> int {
        if (v < t - 1) return v + 1;
        if (v == t - 1) return finishVertex;

        int k = v - cycleStart;
        k = (k + 1) % cycleLen;
        return cycleStart + k;
    };

    auto allAtFinish = [&]() -> bool {
        for (int i = 0; i < 10; i++) if (pos[i] != finishVertex) return false;
        return true;
    };

    auto replyPartition = [&]() {
        map<int, vector<int>> groupsByVertex;
        for (int i = 0; i < 10; i++) groupsByVertex[pos[i]].push_back(i);

        cout << (int)groupsByVertex.size();
        for (auto& [v, ids] : groupsByVertex) {
            sort(ids.begin(), ids.end());
            string grp;
            grp.reserve(ids.size());
            for (int id : ids) grp.push_back(char('0' + id));
            cout << " " << grp;
        }
        cout << endl;
    };

    string line;
    while (true) {
        if (!std::getline(cin, line)) {
            finish(_pe, "Unexpected EOF from contestant");
        }

        bool anyNonSpace = false;
        for (char ch : line) if (!isspace((unsigned char)ch)) { anyNonSpace = true; break; }
        if (!anyNonSpace) continue;

        stringstream ss(line);
        string cmd;
        ss >> cmd;
        if (cmd == "done") {
            string extra;
            if (ss >> extra) {
                cout << "stop" << endl;
                finish(_wa, "Extra tokens after 'done'");
            }
            if (allAtFinish()) finish(_ok, "OK");
            finish(_wa, "Printed 'done' before all pieces reached finish vertex");
        }

        if (cmd != "next") {
            cout << "stop" << endl;
            finish(_wa, "Unknown command (expected 'next' or 'done')");
        }

        vector<int> movers;
        string tok;
        while (ss >> tok) {
            if (!isAllDigits(tok)) {
                cout << "stop" << endl;
                finish(_wa, "Invalid token in 'next' command");
            }
            long long v = 0;
            for (char ch : tok) {
                v = v * 10 + (ch - '0');
                if (v > 1000000) break;
            }
            if (v < 0 || v > 9) {
                cout << "stop" << endl;
                finish(_wa, "Moved index out of range (0..9)");
            }
            movers.push_back((int)v);
        }

        if (movers.empty()) {
            cout << "stop" << endl;
            finish(_wa, "Must move at least one friend");
        }

        {
            bool seen[10] = {false};
            for (int x : movers) {
                if (seen[x]) {
                    cout << "stop" << endl;
                    finish(_wa, "Duplicate index in one query");
                }
                seen[x] = true;
            }
        }

        queries++;
        log_metrics();
        if (queries > hard_cap) {
            finish(_pe, "Hard cap exceeded (possible infinite loop / spam)");
        }

        for (int x : movers) pos[x] = nextVertex(pos[x]);

        replyPartition();
    }
}

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

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

static int N_total = 0;
static vector<int> feasible_t;
static array<long long, 10> moves_cnt;

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 vector<string> split_tokens(const string& s) {
    vector<string> toks;
    string cur;
    for (char ch : s) {
        if (isspace((unsigned char)ch)) {
            if (!cur.empty()) {
                toks.push_back(cur);
                cur.clear();
            }
        } else {
            cur.push_back(ch);
        }
    }
    if (!cur.empty()) toks.push_back(cur);
    return toks;
}

static inline int vertex_key_for(int t, int c, long long mv) {
    if (mv < t) return (int)mv;
    long long r = mv - t;
    int cyc = (int)(r % c);
    return t + cyc;
}

static inline bool is_finish_for(int t, int c, long long mv) {
    if (mv < t) return false;
    return ((mv - t) % c) == 0;
}

static uint64_t signature_code_for_t(int t) {
    int c = N_total - t;
    int keys[10];
    for (int i = 0; i < 10; i++) keys[i] = vertex_key_for(t, c, moves_cnt[i]);

    int gid[10];
    for (int i = 0; i < 10; i++) gid[i] = -1;

    int k = 0;
    for (int i = 0; i < 10; i++) {
        if (gid[i] != -1) continue;
        int mykey = keys[i];
        for (int j = i; j < 10; j++) {
            if (gid[j] == -1 && keys[j] == mykey) gid[j] = k;
        }
        k++;
    }

    uint64_t code = (uint64_t)k;
    for (int i = 0; i < 10; i++) {
        code |= (uint64_t)gid[i] << (4 * (i + 1));
    }
    return code;
}

static vector<string> build_groups_for_t(int t) {
    int c = N_total - t;
    int keys[10];
    for (int i = 0; i < 10; i++) keys[i] = vertex_key_for(t, c, moves_cnt[i]);

    int gid[10];
    for (int i = 0; i < 10; i++) gid[i] = -1;

    vector<vector<int>> groups;
    for (int i = 0; i < 10; i++) {
        if (gid[i] != -1) continue;
        int mykey = keys[i];
        vector<int> g;
        for (int j = i; j < 10; j++) {
            if (gid[j] == -1 && keys[j] == mykey) {
                gid[j] = (int)groups.size();
                g.push_back(j);
            }
        }
        groups.push_back(std::move(g));
    }

    vector<string> out;
    out.reserve(groups.size());
    for (auto& g : groups) {
        sort(g.begin(), g.end());
        string s;
        s.reserve(g.size());
        for (int idx : g) s.push_back(char('0' + idx));
        out.push_back(s);
    }
    return out;
}

static void send_partition_reply(int t) {
    vector<string> groups = build_groups_for_t(t);
    cout << (int)groups.size();
    for (const string& g : groups) cout << " " << g;
    cout << endl;
}

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

    moves_cnt.fill(0);

    int a = inf.readInt(1, 1000, "a");
    if (!inf.seekEof()) {
        int b = inf.readInt(1, 1000, "b");
        inf.readEof();
        int t = a, c = b;
        ensuref(t + c >= 2 && t + c <= 1000, "t+c out of range");
        N_total = t + c;
        query_limit = 3LL * N_total;
        feasible_t.clear();
        feasible_t.push_back(t);
    } else {
        int maxN = a;
        ensuref(maxN >= 2 && maxN <= 1000, "maxN out of range");
        N_total = maxN;
        query_limit = 3LL * N_total;
        feasible_t.clear();
        feasible_t.reserve(max(0, N_total - 1));
        for (int t = 1; t <= N_total - 1; t++) feasible_t.push_back(t);
    }

    log_metrics();

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

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

        if (cmd == "done") {
            if (feasible_t.empty()) finish(_pe, "internal: empty feasible set at done");

            for (int t : feasible_t) {
                int c = N_total - t;
                bool all_ok = true;
                for (int i = 0; i < 10; i++) {
                    if (!is_finish_for(t, c, moves_cnt[i])) {
                        all_ok = false;
                        break;
                    }
                }
                if (!all_ok) finish(_wa, "done claimed but not guaranteed");
            }
            finish(_ok, "ok");
        }

        if (cmd != "next") {
            cout << "stop" << endl;
            finish(_wa, "unknown command");
        }

        string rest;
        getline(cin, rest);
        vector<string> toks = split_tokens(rest);

        if (toks.empty()) {
            cout << "stop" << endl;
            finish(_wa, "empty move set");
        }

        bool used[10];
        memset(used, 0, sizeof(used));
        vector<int> idx;
        idx.reserve(toks.size());

        for (const string& tok : toks) {
            if (tok.size() != 1 || tok[0] < '0' || tok[0] > '9') {
                cout << "stop" << endl;
                finish(_wa, "invalid index token");
            }
            int v = tok[0] - '0';
            if (used[v]) {
                cout << "stop" << endl;
                finish(_wa, "duplicate index");
            }
            used[v] = true;
            idx.push_back(v);
        }

        for (int v : idx) moves_cnt[v]++;

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

        if (feasible_t.empty()) finish(_pe, "internal: empty feasible set before reply");

        map<uint64_t, pair<int, int>> info;
        for (int t : feasible_t) {
            uint64_t code = signature_code_for_t(t);
            auto& entry = info[code];
            entry.first++;
            if (entry.second == 0) entry.second = t;
            else entry.second = min(entry.second, t);
        }

        int bestCount = -1;
        uint64_t bestCode = 0;
        int bestRepT = -1;

        for (const auto& it : info) {
            uint64_t code = it.first;
            int cnt = it.second.first;
            int repT = it.second.second;
            if (cnt > bestCount || (cnt == bestCount && code < bestCode)) {
                bestCount = cnt;
                bestCode = code;
                bestRepT = repT;
            }
        }

        if (bestRepT < 1) finish(_pe, "internal: failed to choose reply");

        vector<int> next_feasible;
        next_feasible.reserve(feasible_t.size());
        for (int t : feasible_t) {
            if (signature_code_for_t(t) == bestCode) next_feasible.push_back(t);
        }
        feasible_t.swap(next_feasible);

        if (feasible_t.empty()) finish(_pe, "internal: reply made feasible set empty");

        send_partition_reply(bestRepT);
    }
}

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

static bool isPrimeInt(int x) {
    if (x < 2) return false;
    for (int d = 2; d * d <= x; d++) {
        if (x % d == 0) return false;
    }
    return true;
}

static int nearestPrimeClamped(int target, int lo, int hi) {
    target = max(lo, min(hi, target));
    if (isPrimeInt(target)) return target;
    for (int delta = 1; delta <= hi - lo; delta++) {
        int a = target - delta;
        if (a >= lo && isPrimeInt(a)) return a;
        int b = target + delta;
        if (b <= hi && isPrimeInt(b)) return b;
    }
    for (int x = lo; x <= hi; x++) if (isPrimeInt(x)) return x;
    return lo;
}

static long long parseSeedFromArgv(int argc, char** argv) {
    if (argc < 2) return 1;
    string s = argv[1];
    bool neg = false;
    int i = 0;
    if (!s.empty() && (s[0] == '-' || s[0] == '+')) {
        neg = (s[0] == '-');
        i = 1;
    }
    long long v = 0;
    for (; i < (int)s.size(); i++) {
        if (s[i] < '0' || s[i] > '9') break;
        v = v * 10 + (s[i] - '0');
        if (v > (long long)4e18) break;
    }
    return neg ? -v : v;
}

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 seed = parseSeedFromArgv(argc, argv);

    if (mode == "non") {
        int forcedT = opt<int>("t", -1);
        int forcedC = opt<int>("c", -1);
        int forcedN = opt<int>("n", -1);

        int t = -1, c = -1;

        if (seed == 1) {
            t = 1; c = 1;
        } else if (seed == 2) {
            t = 999; c = 1;
        } else if (seed == 3) {
            t = 1; c = 999;
        } else if (forcedT >= 1 && forcedC >= 1 && forcedT + forcedC <= 1000) {
            t = forcedT;
            c = forcedC;
        } else {
            int n;
            if (forcedN >= 2 && forcedN <= 1000) n = forcedN;
            else n = rnd.next(950, 1000);

            int kind = rnd.next(0, 5);
            if (kind == 0) {
                int target = n / 2 + rnd.next(-25, 25);
                c = nearestPrimeClamped(target, 1, n - 1);
            } else if (kind == 1) {
                int target = (2 * n) / 3 + rnd.next(-25, 25);
                c = nearestPrimeClamped(target, 1, n - 1);
            } else if (kind == 2) {
                int target = n - 3 - rnd.next(0, 10);
                c = nearestPrimeClamped(target, 1, n - 1);
            } else if (kind == 3) {
                static const int hardCycles[] = {511, 513, 255, 257, 127, 129, 63, 65, 999, 997, 991, 983};
                int pick = hardCycles[rnd.next(0, (int)(sizeof(hardCycles) / sizeof(hardCycles[0])) - 1)];
                c = max(1, min(n - 1, pick));
                if (c == n) c = n - 1;
            } else {
                c = rnd.next(1, n - 1);
            }

            t = n - c;
            if (t < 1) { t = 1; c = n - 1; }
            if (c < 1) { c = 1; t = n - 1; }

            if (!isPrimeInt(c) && rnd.next(0, 1) == 1) {
                int c2 = nearestPrimeClamped(c, 1, n - 1);
                if (c2 >= 1 && c2 <= n - 1) {
                    c = c2;
                    t = n - c;
                    if (t < 1) { t = 1; c = n - 1; }
                }
            }
        }

        if (t < 1) t = 1;
        if (c < 1) c = 1;
        if (t + c > 1000) {
            int n = 1000;
            if (t >= n) t = n - 1;
            c = n - t;
            if (c < 1) { c = 1; t = n - 1; }
        }

        cout << t << " " << c << "\n";
        return 0;
    }

    if (mode == "adp") {
        int maxN = opt<int>("n", 1000);

        if (seed == 1) maxN = 2;
        else if (seed == 2) maxN = 1000;
        else if (seed == 3) maxN = 17;
        else maxN = max(2, min(1000, maxN));

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

    quitf(_fail, "unknown --mode (expected non/adp)");
    return 0;
}


### Problem Statement

PCT has a permutation $(P_1,P_2,\dots,P_N)$ of $(1,2,\dots,N)$. You are only informed of $N$.

You can ask him at most $25000$ questions of the following form.

* Specify a triple of integers $(i,j,k)$ such that $1 \le i,j,k \le N$ and ask whether $P_i + P_j > P_k$.

Find all of $P_1,P_2,\dots,P_N$.

### Constraints

* $1 \le N \le 2000$
* $P$ is decided before the start of the interaction of your program and the judge.

### Input and Output

**This is an interactive task**, where your program and the judge interact via input and output.

First, your program is given $N$, the length of the permutation, from Standard Input:

```
$N$
```

Then, you get to ask questions.
Print your question to Standard Output in the following format: (There should be a newline at the end.)

```
? $i$ $j$ $k$
```

If the question is valid, the answer $ans$ will be given from Standard Input:

```
$ans$
```

Here, $ans$ is `Yes` or `No`.

If the question is malformed or judged invalid because you have asked more questions than allowed, `-1` will be given from Standard Input:

```
-1
```

Here, the submission has already been judged incorrect. The judge will end the interaction at this point; preferably, your program should also quit.

Once you have identified all of $P_1, P_2, \dots, P_N$, print them to Standard Output in the following format: (There should be a newline at the end.)

```
! $P_1$ $P_2$ $\dots$ $P_N$
```

### Judging

* **Each time you print something, end it with a newline and flush Standard Output. Otherwise, you might get a TLE verdict.**
* After printing the answer (or receiving `-1`), immediately terminate the program normally. Otherwise, the verdict will be indeterminate.
* Note that unnecessary newlines will be considered as malformed output.

### Sample Interaction

Below is an interaction with $N = 4$ and $P=(3,1,2,4)$.

| Input | Output | Description |
| --- | --- | --- |
| `4` |  | $N$ is given. |
|  | `?` `1` `2` `3` | As the first question, you ask whether $P_1 + P_2 > P_3$. |
| `Yes` |  | We have $P_1 + P_2=4$ and $P_3=2$, so the answer is `Yes`. |
|
|  | `?` `2` `3` `3` | As the second question, you ask whether $P_2 + P_3 > P_3$. |
| `Yes` |  | We have $P_2 + P_3=3$ and $P_3=2$, so the answer is `Yes`. |
|
|  | `?` `2` `3` `4` | As the third question, you ask whether $P_2 + P_3 > P_4$. |
| `No` |  | We have $P_2 + P_3=3$ and $P_4=4$, so the answer is `No`. |
|
|  | `!` `3` `1` `2` `4` | You print $P_1,P_2,P_3,P_4$. We do have $P=(3,1,2,4)$, so you get an AC. |
|

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

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

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, 2000, "N");
    vector<int> p(n);
    for (int i = 0; i < n; ++i) {
        p[i] = inf.readInt(1, n, format("P[%d]", i + 1));
    }

    {
        vector<int> sorted_p = p;
        sort(sorted_p.begin(), sorted_p.end());
        for (int i = 0; i < n; ++i) {
            if (sorted_p[i] != i + 1) {
                quitf(_fail, "Hidden input is not a valid permutation of 1..N");
            }
        }
    }

    cout << n << endl;

    string token;
    while (cin >> token) {
        if (token == "!") {

            vector<int> guess(n);
            bool read_ok = true;
            for (int i = 0; i < n; ++i) {
                if (!(cin >> guess[i])) {
                    read_ok = false;
                    break;
                }
            }
            if (!read_ok) {
                finish(_pe, "Could not read complete permutation answer after '!'");
            }

            if (guess == p) {
                finish(_ok, "Correct permutation");
            } else {
                finish(_wa, "Incorrect permutation");
            }
        } else {

            queries++;

            if (queries % 100 == 0) {
                log_metrics();
            }

            if (queries > HARD_CAP) {
                finish(_pe, "Query limit hard cap exceeded");
            }

            int i, j, k;

            if (token == "?") {

                if (!(cin >> i >> j >> k)) {
                    finish(_pe, "Invalid query format (expected 3 ints after ?)");
                }
            } else {

                try {
                    size_t pos;
                    i = stoi(token, &pos);
                    if (pos != token.size()) {
                        throw invalid_argument("trailing chars");
                    }
                } catch (...) {
                    finish(_pe, format("Expected integer or '?', found '%s'", token.c_str()));
                }
                if (!(cin >> j >> k)) {
                    finish(_pe, "Invalid query format (expected 2 more ints)");
                }
            }

            if (i < 1 || i > n || j < 1 || j > n || k < 1 || k > n) {
                finish(_pe, format("Query indices out of bounds: %d %d %d", i, j, k));
            }

            long long val_i = p[i - 1];
            long long val_j = p[j - 1];
            long long val_k = p[k - 1];

            if (val_i + val_j > val_k) {
                cout << "Yes" << endl;
            } else {
                cout << "No" << endl;
            }
        }
    }

    finish(_pe, "Unexpected EOF (did not receive answer)");
    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_arg = opt<int>("n", 0);

    long long seed = atoll(argv[1]);

    int n;
    if (n_arg > 0) {
        n = n_arg;
    } else {

        if (seed == 1) n = 4;
        else if (seed == 2) n = 2000;
        else if (seed == 3) n = 2000;
        else if (seed == 4) n = 2000;
        else if (seed == 5) n = 2000;
        else if (seed == 6) n = 1;
        else if (seed == 7) n = 2;
        else {

            n = rnd.wnext(2000, 20) + 1;
        }
    }

    if (mode == "adp") {
        cout << n << endl;
        return 0;
    }

    vector<int> p;
    if (n_arg > 0) {

        p = rnd.perm(n, 1);
    } else {

        if (seed == 1 && n == 4) {
            p = {3, 1, 2, 4};
        } else if (seed == 3) {

            p.resize(n);
            iota(p.begin(), p.end(), 1);
        } else if (seed == 4) {

            p.resize(n);
            iota(p.begin(), p.end(), 1);
            reverse(p.begin(), p.end());
        } else if (seed == 5) {

            p.resize(n);
            iota(p.begin(), p.end(), 1);
            rotate(p.begin(), p.begin() + 1, p.end());
        } else {

            p = rnd.perm(n, 1);
        }
    }

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

    return 0;
}


This is an interactive problem.

Kostyanych has chosen a complete undirected graph$^{\dagger}$ with $n$ vertices, and then removed exactly $(n - 2)$ edges from it. You can ask queries of the following type:

* "? $d$" — Kostyanych tells you the number of vertex $v$ with a degree at least $d$. Among all possible such vertices, he selects the vertex with the minimum degree, and if there are several such vertices, he selects the one with the minimum number. He also tells you the number of another vertex in the graph, with which $v$ is not connected by an edge (if none is found, then $0$ is reported). Among all possible such vertices, he selects the one with the minimum number. Then he removes the vertex $v$ and all edges coming out of it. If the required vertex $v$ is not found, then "$0\ 0$" is reported.

Find a Hamiltonian path$^{\ddagger}$ in the original graph in at most $n$ queries. It can be proven that under these constraints, a Hamiltonian path always exists.

$^{\dagger}$A complete undirected graph is a graph in which there is exactly one undirected edge between any pair of distinct vertices. Thus, a complete undirected graph with $n$ vertices contains $\frac{n(n-1)}{2}$ edges.

$^{\ddagger}$A Hamiltonian path in a graph is a path that passes through each vertex exactly once.

Input

Each test consists of multiple test cases. The first line contains a single integer $t$ ($1 \le t \le 1000$) — the number of test cases. The description of the test cases follows.

The only line of each test case contains a single integer $n$ ($2 \le n \le 10^5$) — the number of vertices in the graph.

It is guaranteed that the sum of $n$ over all test cases does not exceed $10^5$.

Interaction

Interaction for each test case begins with reading the integer $n$.

Then you can make no more than $n$ queries.

To make a query, output a line in the format "? $d$" (without quotes) ($0 \le d \le n - 1$). After each query, read two integers — the answer to your query.

When you are ready to report the answer, output a line in the format "! $v_1\ v_2 \ldots v_n$" (without quotes) — the vertices in the order of their occurrence in the Hamiltonian path. Outputting the answer does not count as one of the $n$ queries. After solving one test case, the program should immediately move on to the next one. After solving all test cases, the program should be terminated immediately.

If your program makes more than $n$ queries for one test case or makes an incorrect query, then the response to the query will be $-1$, and after receiving such a response, your program should immediately terminate to receive the verdict Wrong answer. Otherwise, it may receive any other verdict.

After outputting a query, do not forget to output an end of line and flush the output buffer. Otherwise, you will receive the verdict 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.

The interactor is non-adaptive. The graph does not change during the interaction.

Example

Input

```
3
4

0 0

1 4

2 3

4

1 0

4 2

2

1 0
```

Output

```
? 3

? 2

? 1

! 4 3 1 2

? 3

? 0

! 4 1 2 3

? 0

! 2 1
```

Note

In the first test case, the original graph looks as follows:

 ![](https://espresso.codeforces.com/48cb83028bac1f1c139784ad109fc3e06bf4a5f1.png)

Consider the queries:

* There are no vertices with a degree of at least $3$ in the graph, so "$0\ 0$" is reported.
* There are four vertices with a degree of at least $2$, and all of them have a degree of exactly $2$: $1$, $2$, $3$, $4$. Vertex $1$ is reported, because it has the minimum number, and vertex $4$ is reported, because it is the only one not connected to vertex $1$. After this, vertex $1$ is removed from the graph.
* There are three vertices with a degree of at least $1$, among them vertices $2$ and $3$ have a minimum degree of $1$ (vertex $4$ has a degree of $2$). Vertex $2$ is reported, because it has the minimum number, and vertex $3$ is reported, because it is the only one not connected to vertex $2$. After this, vertex $2$ is removed from the graph.

The path $4 - 3 - 1 - 2$ is a Hamiltonian path.

In the second test case, the original graph looks as follows:

 ![](https://espresso.codeforces.com/ab25c6dbc743e9a0313a5df3399b331f0b6a54da.png)

Consider the queries:

* Vertex $1$ has a degree of at least $3$, but it is connected to all vertices, so "$1\ 0$" is reported. After this, vertex $1$ is removed from the graph.
* The remaining vertices $2$, $3$, and $4$ have a degree of at least $0$, but among them vertex $4$ has the minimum degree of $0$ (vertices $2$ and $3$ have a degree of $1$). Vertex $4$ is not connected to both vertices $2$ and $3$, so vertex $2$ is reported (as it has the minimum number). After this, vertex $4$ is removed from the graph.

The path $4 - 1 - 2 - 3$ is a Hamiltonian path.

In the third test case, the graph consists of $2$ vertices connected by an edge.

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

static long long global_queries = 0;
static long long global_query_limit = 0;

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

    }
}

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

int n;
vector<vector<int>> adj_comp;
vector<int> deg_comp;
vector<bool> active;
int current_n;
set<int> present_degrees;
vector<set<int>> buckets;
set<pair<int,int>> complement_edges;

void solve_testcase() {

    n = inf.readInt();

    cout << n << endl;

    global_query_limit += n;

    log_metrics();

    current_n = n;
    adj_comp.assign(n + 1, vector<int>());
    deg_comp.assign(n + 1, 0);
    active.assign(n + 1, true);

    buckets.assign(n + 1, set<int>());
    present_degrees.clear();
    complement_edges.clear();

    int m = n - 2;
    for (int i = 0; i < m; ++i) {
        int u = inf.readInt();
        int v = inf.readInt();
        if (u > v) swap(u, v);

        complement_edges.insert({u, v});
        adj_comp[u].push_back(v);
        adj_comp[v].push_back(u);
        deg_comp[u]++;
        deg_comp[v]++;
    }

    for (int i = 1; i <= n; ++i) {
        sort(adj_comp[i].begin(), adj_comp[i].end());
        buckets[deg_comp[i]].insert(i);
        present_degrees.insert(deg_comp[i]);
    }

    int queries_this_case = 0;

    while (true) {
        string token;
        cin >> token;

        if (cin.fail()) {
            finish(_pe, "Unexpected end of input from solution");
        }

        if (token == "!") {

            vector<int> path;
            path.reserve(n);
            vector<bool> visited(n + 1, false);

            for (int i = 0; i < n; ++i) {
                int v_node;
                cin >> v_node;
                if (cin.fail()) finish(_pe, "Failed to read path vertex");
                path.push_back(v_node);
            }

            for (int x : path) {
                if (x < 1 || x > n) finish(_wa, "Vertex in path out of range");
                if (visited[x]) finish(_wa, "Duplicate vertex in path");
                visited[x] = true;
            }

            for (int i = 0; i < n - 1; ++i) {
                int u = path[i];
                int v = path[i+1];
                if (u > v) swap(u, v);
                if (complement_edges.count({u, v})) {
                    finish(_wa, format("Edge %d-%d is missing in the graph (it is in the removed set)", path[i], path[i+1]));
                }
            }

            break;
        }
        else {

            int d;
            if (token == "?") {

                cin >> d;
            } else {

                try {
                    size_t pos;
                    d = stoi(token, &pos);
                    if (pos != token.size()) throw invalid_argument("");
                } catch (...) {
                    finish(_pe, format("Invalid query format: unexpected token '%s'", token.c_str()));
                }
            }
            if (cin.fail()) finish(_pe, "Failed to read query parameter d");

            queries_this_case++;
            global_queries++;

            if (global_queries > 500000) {
                 finish(_pe, "Global hard query limit exceeded");
            }

            if (queries_this_case > n) {
                cout << -1 << endl;
                finish(_wa, "Query limit exceeded for test case");
            }

            if (d < 0 || d >= n) {
                cout << -1 << endl;
                finish(_wa, format("Query parameter d=%d out of range [0, %d]", d, n-1));
            }

            int K = (current_n - 1) - d;
            int v_res = 0;
            int u_res = 0;

            if (K >= 0) {

                auto it = present_degrees.upper_bound(K);
                if (it != present_degrees.begin()) {
                    it--;
                    int k = *it;

                    if (!buckets[k].empty()) {

                        v_res = *buckets[k].begin();

                        for (int neighbor : adj_comp[v_res]) {
                            if (active[neighbor]) {
                                u_res = neighbor;
                                break;
                            }
                        }
                    }
                }
            }

            cout << v_res << " " << u_res << endl;

            if (v_res != 0) {

                active[v_res] = false;
                current_n--;

                int old_d = deg_comp[v_res];
                buckets[old_d].erase(v_res);
                if (buckets[old_d].empty()) present_degrees.erase(old_d);

                for (int w : adj_comp[v_res]) {
                    if (active[w]) {
                        int w_d = deg_comp[w];
                        buckets[w_d].erase(w);
                        if (buckets[w_d].empty()) present_degrees.erase(w_d);

                        deg_comp[w]--;
                        w_d = deg_comp[w];
                        buckets[w_d].insert(w);
                        present_degrees.insert(w_d);
                    }
                }
            }
        }
    }
}

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

    int t = inf.readInt();
    cout << t << endl;

    for (int i = 0; i < t; ++i) {
        solve_testcase();
    }

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

    const int MAX_TOTAL_N = 100000;
    const int MAX_T = 1000;

    int target_n = rnd.next(MAX_TOTAL_N / 2, MAX_TOTAL_N);

    vector<int> cases;

    cases.push_back(2);
    cases.push_back(3);
    cases.push_back(4);
    cases.push_back(4);
    cases.push_back(5);

    int current_n = 0;
    for (int x : cases) current_n += x;

    while (current_n < target_n && (int)cases.size() < MAX_T) {
        int rem = target_n - current_n;
        if (rem < 2) break;

        int type = rnd.next(100);
        int n;

        if (type < 40) {
            n = rnd.next(2, min(rem, 50));
        } else if (type < 80) {
            n = rnd.next(min(rem, 51), min(rem, 1000));
        } else {
            n = rnd.next(min(rem, 1001), min(rem, 5000));
        }

        if (n < 2) n = 2;
        if (n > rem) n = rem;

        cases.push_back(n);
        current_n += n;
    }

    shuffle(cases.begin(), cases.end());

    println(cases.size());

    for (int n : cases) {
        println(n);

        if (mode == "adp") {
            continue;
        }

        int m = n - 2;
        vector<pair<int, int>> edges;

        int gtype = rnd.next(5);
        if (n < 5) gtype = 0;

        if (gtype == 0) {

            set<pair<int, int>> s;
            while ((int)s.size() < m) {
                int u = rnd.next(1, n);
                int v = rnd.next(1, n);
                if (u == v) continue;
                if (u > v) swap(u, v);
                s.insert({u, v});
            }
            for (auto p : s) edges.push_back(p);
        }
        else if (gtype == 1) {

            int c = rnd.next(1, n);
            vector<int> nodes;
            for (int i = 1; i <= n; ++i) if (i != c) nodes.push_back(i);
            shuffle(nodes.begin(), nodes.end());

            for (int i = 0; i < m; ++i) {
                int u = c, v = nodes[i];
                if (u > v) swap(u, v);
                edges.push_back({u, v});
            }
        }
        else if (gtype == 2) {

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

            for (int i = 0; i < m; ++i) {
                int u = p[i], v = p[i + 1];
                if (u > v) swap(u, v);
                edges.push_back({u, v});
            }
        }
        else if (gtype == 3) {

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

            for (int i = 0; i + 1 < n && (int)s.size() < m; i += 2) {
                int u = p[i], v = p[i + 1];
                if (u > v) swap(u, v);
                s.insert({u, v});
            }

            while ((int)s.size() < m) {
                int u = rnd.next(1, n);
                int v = rnd.next(1, n);
                if (u == v) continue;
                if (u > v) swap(u, v);
                s.insert({u, v});
            }
            for (auto e : s) edges.push_back(e);
        }
        else {

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

            for (int i = 1; i < n; ++i) {
                int u = p[i];
                int v = p[rnd.next(i)];
                if (u > v) swap(u, v);
                tree_edges.push_back({u, v});
            }
            shuffle(tree_edges.begin(), tree_edges.end());
            for (int i = 0; i < m; ++i) edges.push_back(tree_edges[i]);
        }

        shuffle(edges.begin(), edges.end());
        for (auto e : edges) {
            println(e.first, e.second);
        }
    }

    return 0;
}


Who am I? What am I? Why am I? These are all diffcult questions that have kept philosophers reliably busy over the past millennia. But when it comes to “Where am I?",then, well modern smartphones and GPS satellites have pretty much taken the excitement out of that question.

But what if you have no GPS at hand? In one of the World Finals 2O21 problems,the Instant Cartographic Positioning Company (ICPC) demonstrated a way to determine your current location using spiral movements and observing your surroundings. Unfortunately, their method can only be used in open areas where you can move freely without any obstacles. What if you need to locate your exact position in a closed space? How can you do it? Well, now is the time to find out.

You are given a map of an area consisting of unit squares, where each square is either open or occupied by a wall. At the beginning,you are placed in one of the open unit squares,but you do not know which square it is or what direction you face. Any two individual open spaces are indistinguishable, and likewise for walls. You may walk around the area, at each step observing the distance to the next wall in the direction you face. The goal is to determine your exact position on the map.

# Interaction

The first line of input contains two integers $r$ and $c \left( 1 \leq r , c \leq 1 0 0 \right)$ specifying the size of the map. This is followed by $r$ lines, each containing $c$ characters. Each of these characters is either a dot (.） denoting an open square, or a number sign $( \# )$ denoting a square occupied by a wall.

At least one of the squares is open. You know you start in one of the open squares on the map, facing one of the four cardinal directions, but your position and direction is not given in the input. Allsquares outside the map area are considered walls.

Interaction then proceeds in rounds. In each round, one line becomes available, containing a single integer $d$ $0 \leq d \leq 9 9$ ) indicating that you see a wall in front of you at distance $d$ .This means there are exactly $d$ open squares between your square and the closest wall in the current direction. You should then output a line containing one of the following:

· le ft to turn 90 degrees to the left,
· right to turn 90 degrees to the right,
· step to move one square forward in your current direction,
·yes i $j$ to claim that your current position is row $i$ ,column $j$ $\dot { \iota } \left( 1 \leq i \leq r , 1 \leq j \leq c \right)$ ， · no to claim that no mater what you do, it willnot be possible to reliably determine your position.

If you output yes or no, interaction stops and your program should terminate. Otherwise, a new interaction round begins. In order to be accepted, your solution must never step into a wall,and can run for at most lOo OoO interaction rounds (the final round where you only report yes or no counts towards this limit).

![](images/f945920d1b6f58bc78e3a9ac0d90729518e9da37862f43f498877195367acb01.jpg)

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

static long long queries = 0;
static const long long query_limit = 100000;

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 R, C;
vector<string> grid;

const int DR[] = {-1, 0, 1, 0};
const int DC[] = {0, 1, 0, -1};

struct State {
    int r, c, dir;

    bool operator<(const State& o) const {
        if (r != o.r) return r < o.r;
        if (c != o.c) return c < o.c;
        return dir < o.dir;
    }
    bool operator==(const State& o) const {
        return r == o.r && c == o.c && dir == o.dir;
    }
};

bool is_valid(int r, int c) {
    return r >= 0 && r < R && c >= 0 && c < C && grid[r][c] == '.';
}

int get_wall_dist(const State& s) {
    int dist = 0;
    int cr = s.r;
    int cc = s.c;
    while (true) {
        int nr = cr + DR[s.dir];
        int nc = cc + DC[s.dir];
        if (!is_valid(nr, nc)) break;
        dist++;
        cr = nr;
        cc = nc;
    }
    return dist;
}

State move_state(State s, const string& action) {
    if (action == "left") {
        s.dir = (s.dir + 3) % 4;
    } else if (action == "right") {
        s.dir = (s.dir + 1) % 4;
    } else if (action == "step") {
        int nr = s.r + DR[s.dir];
        int nc = s.c + DC[s.dir];
        if (is_valid(nr, nc)) {
            s.r = nr;
            s.c = nc;
        } else {
            s.r = -1;
        }
    }
    return s;
}

State actual_state;

vector<State> candidates;

bool are_candidates_indistinguishable() {
    if (candidates.empty()) return true;

    vector<State> all_states;
    map<State, int> state_to_id;
    for (int r = 0; r < R; ++r) {
        for (int c = 0; c < C; ++c) {
            if (grid[r][c] == '.') {
                for (int d = 0; d < 4; ++d) {
                    State s = {r, c, d};
                    state_to_id[s] = (int)all_states.size();
                    all_states.push_back(s);
                }
            }
        }
    }

    int N = (int)all_states.size();
    vector<int> group(N);

    for (int i = 0; i < N; ++i) {
        group[i] = get_wall_dist(all_states[i]);
    }

    vector<vector<int>> trans(N, vector<int>(3));
    for (int i = 0; i < N; ++i) {
        State sl = move_state(all_states[i], "left");
        trans[i][0] = state_to_id[sl];

        State sr = move_state(all_states[i], "right");
        trans[i][1] = state_to_id[sr];

        State ss = move_state(all_states[i], "step");
        if (ss.r == -1) trans[i][2] = -1;
        else trans[i][2] = state_to_id[ss];
    }

    while (true) {
        vector<pair<vector<int>, int>> sigs(N);
        for (int i = 0; i < N; ++i) {
            sigs[i].second = i;

            sigs[i].first = {group[i]};
            for (int k = 0; k < 3; ++k) {
                int next_id = trans[i][k];
                if (next_id == -1) sigs[i].first.push_back(-1);
                else sigs[i].first.push_back(group[next_id]);
            }
        }

        sort(sigs.begin(), sigs.end());

        vector<int> new_group(N);
        int g_cnt = 0;
        for (int i = 0; i < N; ++i) {
            if (i > 0 && sigs[i].first != sigs[i-1].first) {
                g_cnt++;
            }
            new_group[sigs[i].second] = g_cnt;
        }

        int max_g = -1;
        for (int g : group) max_g = max(max_g, g);
        if (g_cnt == max_g) break;

        group = new_group;
    }

    int first_group = -1;
    bool first = true;
    for (const auto& c : candidates) {
        auto it = state_to_id.find(c);
        if (it != state_to_id.end()) {
            int g = group[it->second];
            if (first) {
                first_group = g;
                first = false;
            } else {
                if (g != first_group) return false;
            }
        }
    }
    return true;
}

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

    R = inf.readInt();
    C = inf.readInt();
    grid.resize(R);
    for (int i = 0; i < R; ++i) {
        grid[i] = inf.readToken();
    }

    int start_r = inf.readInt();
    int start_c = inf.readInt();
    int start_dir = inf.readInt();

    actual_state = {start_r - 1, start_c - 1, start_dir};

    for (int r = 0; r < R; ++r) {
        for (int c = 0; c < C; ++c) {
            if (grid[r][c] == '.') {
                for (int d = 0; d < 4; ++d) {
                    candidates.push_back({r, c, d});
                }
            }
        }
    }

    cout << R << " " << C << endl;
    for (int i = 0; i < R; ++i) {
        cout << grid[i] << endl;
    }
    cout.flush();

    while (true) {

        int d = get_wall_dist(actual_state);
        cout << d << endl;

        queries++;
        if (queries > query_limit) {
            finish(_pe, "Query limit exceeded");
        }

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

        vector<State> next_cands;
        next_cands.reserve(candidates.size());
        for (const auto& c : candidates) {
            if (get_wall_dist(c) == d) {
                next_cands.push_back(c);
            }
        }
        candidates = next_cands;
        if (candidates.empty()) {
            finish(_wa, "System error: Valid state filtered out (logic bug or inconsistent map)");
        }

        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF or invalid output format");
        }

        for (auto &ch : token) ch = tolower(ch);

        if (token == "left" || token == "right" || token == "step") {

            if (token == "step") {
                State next_s = move_state(actual_state, "step");
                if (next_s.r == -1) {
                    finish(_wa, "Stepped into a wall");
                }
                actual_state = next_s;
            } else {
                actual_state = move_state(actual_state, token);
            }

            vector<State> survivors;
            survivors.reserve(candidates.size());
            for (const auto& c : candidates) {
                if (token == "step") {
                    State s_next = move_state(c, "step");
                    if (s_next.r != -1) {
                        survivors.push_back(s_next);
                    }
                } else {
                    survivors.push_back(move_state(c, token));
                }
            }
            candidates = survivors;

        } else if (token == "yes") {
            int r, c;
            if (!(cin >> r >> c)) finish(_wa, "Invalid format for 'yes' command");

            if (candidates.empty()) finish(_wa, "No valid candidates");

            bool unique_pos = true;
            for (const auto& cand : candidates) {
                if (cand.r != r - 1 || cand.c != c - 1) {
                    unique_pos = false;
                    break;
                }
            }

            if (!unique_pos) {
                finish(_wa, "Position not uniquely determined yet (ambiguous candidates remain)");
            } else {

                if (actual_state.r == r - 1 && actual_state.c == c - 1) {
                    finish(_ok, "Correct position");
                } else {
                    finish(_wa, "Incorrect position");
                }
            }

        } else if (token == "no") {

            bool position_unique = true;
            if (!candidates.empty()) {
                int r0 = candidates[0].r;
                int c0 = candidates[0].c;
                for (size_t k = 1; k < candidates.size(); ++k) {
                    if (candidates[k].r != r0 || candidates[k].c != c0) {
                        position_unique = false;
                        break;
                    }
                }
            }
            if (position_unique) {
                finish(_wa, "Position is already uniquely determined, you should answer 'yes'");
            }

            if (are_candidates_indistinguishable()) {
                finish(_ok, "Correctly identified indistinguishable state");
            } else {
                finish(_wa, "Positions are distinguishable; further moves can resolve ambiguity");
            }

        } else {
            finish(_wa, "Unknown command: " + token);
        }
    }

    return 0;
}

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

static long long queries = 0;
static const long long query_limit = 100000;
static const long long hard_cap = 200000;

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 R, C;
vector<string> grid_map;

const int MAX_STATES = 40005;

int dr[] = {-1, 0, 1, 0};
int dc[] = {0, 1, 0, -1};

int wall_dist[MAX_STATES];
int next_state[MAX_STATES][3];
int eq_class[MAX_STATES];

vector<int> candidates;

vector<int> group_buckets[205];

int encode_state(int r, int c, int dir) {
    return (r * C + c) * 4 + dir;
}

void decode_state(int id, int &r, int &c, int &dir) {
    dir = id % 4;
    int tmp = id / 4;
    c = tmp % C;
    r = tmp / C;
}

int compute_dist(int r, int c, int dir) {
    int d = 0;
    while (true) {
        int nr = r + dr[dir] * (d + 1);
        int nc = c + dc[dir] * (d + 1);
        if (nr < 0 || nr >= R || nc < 0 || nc >= C || grid_map[nr][nc] == '#') {
            return d;
        }
        d++;
    }
}

void precompute() {
    vector<int> valid_ids;
    valid_ids.reserve(MAX_STATES);

    for (int r = 0; r < R; r++) {
        for (int c = 0; c < C; c++) {
            if (grid_map[r][c] == '.') {
                for (int dir = 0; dir < 4; dir++) {
                    int id = encode_state(r, c, dir);
                    valid_ids.push_back(id);
                    candidates.push_back(id);

                    wall_dist[id] = compute_dist(r, c, dir);

                    next_state[id][0] = encode_state(r, c, (dir + 3) % 4);

                    next_state[id][1] = encode_state(r, c, (dir + 1) % 4);

                    if (wall_dist[id] > 0) {
                        next_state[id][2] = encode_state(r + dr[dir], c + dc[dir], dir);
                    } else {

                        next_state[id][2] = id;
                    }
                }
            }
        }
    }

    for (int id : valid_ids) eq_class[id] = wall_dist[id];

    bool changed = true;
    vector<pair<tuple<int, int, int, int>, int>> sorter;
    sorter.reserve(valid_ids.size());

    while (changed) {
        changed = false;
        sorter.clear();
        for (int id : valid_ids) {

            int c_curr = eq_class[id];
            int c_left = eq_class[next_state[id][0]];
            int c_right = eq_class[next_state[id][1]];
            int c_step = eq_class[next_state[id][2]];
            sorter.push_back({{c_curr, c_left, c_right, c_step}, id});
        }

        sort(sorter.begin(), sorter.end());

        int new_c = 0;
        for (size_t i = 0; i < sorter.size(); i++) {
            if (i > 0 && sorter[i].first != sorter[i-1].first) {
                new_c++;
            }
            int id = sorter[i].second;
            if (eq_class[id] != new_c) {
                eq_class[id] = new_c;
                changed = true;
            }
        }
    }
}

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

    log_metrics();

    R = inf.readInt();
    C = inf.readInt();
    for (int i = 0; i < R; i++) {
        string s = inf.readToken();
        grid_map.push_back(s);
    }

    cout << R << " " << C << endl;
    for (int i = 0; i < R; i++) {
        cout << grid_map[i] << endl;
    }
    cout.flush();

    precompute();

    while (true) {
        if (candidates.empty()) {
            finish(_wa, "System error: no consistent states left");
        }

        int max_d_seen = 0;
        for (int id : candidates) {
            int d = wall_dist[id];

            if (d >= 200) d = 200;
            if (d < 0) d = 0;

            group_buckets[d].push_back(id);
            if (d > max_d_seen) max_d_seen = d;
        }

        int best_d = -1;
        size_t max_sz = 0;
        for (int d = 0; d <= max_d_seen; d++) {
            if (group_buckets[d].size() > max_sz) {
                max_sz = group_buckets[d].size();
                best_d = d;
            }
        }

        candidates.swap(group_buckets[best_d]);

        for (int d = 0; d <= max_d_seen; d++) {
            group_buckets[d].clear();
        }

        cout << best_d << endl;

        string type;
        if (!(cin >> type)) {
            finish(_wa, "Unexpected EOF (solution exited without verdict)");
        }

        queries++;
        if (queries % 1000 == 0) log_metrics();

        if (type == "left") {
            for (int &id : candidates) id = next_state[id][0];
        } else if (type == "right") {
            for (int &id : candidates) id = next_state[id][1];
        } else if (type == "step") {
            if (best_d == 0) {

                finish(_wa, "Stepped into wall");
            }
            for (int &id : candidates) id = next_state[id][2];
        } else if (type == "yes") {
            int r, c;
            if (!(cin >> r >> c)) finish(_wa, "Invalid format for yes");

            bool ok = true;
            for (int id : candidates) {
                int cr, cc, cdir;
                decode_state(id, cr, cc, cdir);

                if ((cr + 1) != r || (cc + 1) != c) {
                    ok = false;
                    break;
                }
            }

            if (ok) finish(_ok, "Correct position");
            else finish(_wa, "Position not uniquely determined or wrong guess");

        } else if (type == "no") {

            int c0 = eq_class[candidates[0]];
            bool distinct_classes = false;
            set<pair<int, int>> distinct_locs;

            for (int id : candidates) {
                if (eq_class[id] != c0) distinct_classes = true;
                int cr, cc, cdir;
                decode_state(id, cr, cc, cdir);
                distinct_locs.insert({cr, cc});
            }

            if (distinct_classes) {
                finish(_wa, "Position is determinable (candidates are distinguishable)");
            } else {
                if (distinct_locs.size() > 1) {
                    finish(_ok, "Correctly identified as indistinguishable");
                } else {
                    finish(_wa, "Position is uniquely determined (should say yes)");
                }
            }

        } else {
            finish(_wa, "Unknown command: " + type);
        }

        if (queries > hard_cap) {
            finish(_pe, "Too many queries (hard cap exceeded)");
        }
    }

    return 0;
}

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

using namespace std;

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

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

    int seed_val = atoi(argv[1]);

    int R, C;
    vector<string> grid;

    if (seed_val == 1) {

        R = 1; C = 1;
        grid.assign(R, string(C, '.'));
    } else if (seed_val == 2) {

        R = 100; C = 100;
        grid.assign(R, string(C, '.'));
    } else if (seed_val == 3) {

        R = 21; C = 21;
        grid.assign(R, string(C, '#'));

        for (int r = 1; r < R - 1; r += 2) {
            for (int c = 1; c < C - 1; ++c) grid[r][c] = '.';

            if (r + 2 < R - 1) {
                if (((r - 1) / 2) % 2 == 0) {

                    grid[r + 1][C - 2] = '.';
                } else {

                    grid[r + 1][1] = '.';
                }
            }
        }
    } else {

        int type = rnd.next(4);

        if (type == 0) {

            R = rnd.next(2, 50);
            C = rnd.next(2, 50);
            grid.assign(R, string(C, '.'));
            double density = rnd.next(0.1, 0.4);
            for (int i = 0; i < R; ++i) {
                for (int j = 0; j < C; ++j) {
                    if (rnd.next(1.0) < density) {
                        grid[i][j] = '#';
                    }
                }
            }
        } else if (type == 1) {

            R = rnd.next(10, 60);
            C = rnd.next(10, 60);
            grid.assign(R, string(C, '#'));

            int r = R / 2;
            int c = C / 2;
            int steps = R * C * 3;

            int dr[] = {-1, 1, 0, 0};
            int dc[] = {0, 0, -1, 1};

            for (int k = 0; k < steps; ++k) {
                grid[r][c] = '.';
                int d = rnd.next(4);
                int nr = r + dr[d];
                int nc = c + dc[d];

                if (nr >= 1 && nr < R - 1 && nc >= 1 && nc < C - 1) {
                    r = nr;
                    c = nc;
                }
            }
        } else if (type == 2) {

            R = rnd.next(10, 40);
            C = rnd.next(10, 40);
            grid.assign(R, string(C, '#'));

            int num_rooms = rnd.next(3, 8);
            for (int k = 0; k < num_rooms; ++k) {
                int h = rnd.next(3, 8);
                int w = rnd.next(3, 8);

                int r0 = rnd.next(1, max(1, R - h - 1));
                int c0 = rnd.next(1, max(1, C - w - 1));

                for (int rr = 0; rr < h; ++rr) {
                    if (r0 + rr >= R - 1) break;
                    for (int cc = 0; cc < w; ++cc) {
                        if (c0 + cc >= C - 1) break;
                        grid[r0 + rr][c0 + cc] = '.';
                    }
                }
            }

            int noise = R * C / 10;
            for (int k = 0; k < noise; ++k) {
                grid[rnd.next(1, R - 2)][rnd.next(1, C - 2)] = '.';
            }
        } else {

            R = rnd.next(5, 50);
            C = rnd.next(5, 50);
            grid.assign(R, string(C, '.'));
            int walls = rnd.next(R * C / 5);
            for (int k = 0; k < walls; ++k) {
                grid[rnd.next(R)][rnd.next(C)] = '#';
            }
        }
    }

    vector<pair<int, int>> opens;
    for (int i = 0; i < R; ++i) {
        for (int j = 0; j < C; ++j) {
            if (grid[i][j] == '.') {
                opens.push_back({i, j});
            }
        }
    }

    if (opens.empty()) {
        int r = rnd.next(R);
        int c = rnd.next(C);
        grid[r][c] = '.';
        opens.push_back({r, c});
    }

    cout << R << " " << C << "\n";
    for (int i = 0; i < R; ++i) {
        cout << grid[i] << "\n";
    }

    if (mode == "non") {
        pair<int, int> start = opens[rnd.next(opens.size())];

        int dir = rnd.next(4);

        cout << (start.first + 1) << " " << (start.second + 1) << " " << dir << "\n";
    }

    return 0;
}


This is an interactive problem.

There exists a matrix $a$ of size $n \times m$ ($n$ rows and $m$ columns), you know only numbers $n$ and $m$. The rows of the matrix are numbered from $1$ to $n$ from top to bottom, and columns of the matrix are numbered from $1$ to $m$ from left to right. The cell on the intersection of the $x$-th row and the $y$-th column is denoted as $(x, y)$.

You are asked to find the number of pairs $(r, c)$ ($1 \le r \le n$, $1 \le c \le m$, $r$ is a divisor of $n$, $c$ is a divisor of $m$) such that if we split the matrix into rectangles of size $r \times c$ (of height $r$ rows and of width $c$ columns, each cell belongs to exactly one rectangle), all those rectangles are pairwise equal.

You can use queries of the following type:

* ? $h$ $w$ $i_1$ $j_1$ $i_2$ $j_2$ ($1 \le h \le n$, $1 \le w \le m$, $1 \le i_1, i_2 \le n$, $1 \le j_1, j_2 \le m$) — to check if non-overlapping subrectangles of height $h$ rows and of width $w$ columns of matrix $a$ are equal or not. The upper left corner of the first rectangle is $(i_1, j_1)$. The upper left corner of the second rectangle is $(i_2, j_2)$. Subrectangles overlap, if they have at least one mutual cell. If the subrectangles in your query have incorrect coordinates (for example, they go beyond the boundaries of the matrix) or overlap, your solution will be considered incorrect.

You can use at most $ 3 \cdot \left \lfloor{ \log_2{(n+m)} } \right \rfloor$ queries. All elements of the matrix $a$ are fixed before the start of your program and do not depend on your queries.

Input

The first line contains two integers $n$ and $m$ ($1 \le n, m \le 1000$) — the number of rows and columns, respectively.

Output

When ready, print a line with an exclamation mark ('!') and then the answer — the number of suitable pairs $(r, c)$. After that your program should terminate.

Interaction

To make a query, print a line with the format "? $h$ $w$ $i_1$ $j_1$ $i_2$ $j_2$ ", where the integers are the height and width and the coordinates of upper left corners of non-overlapping rectangles, about which you want to know if they are equal or not.

After each query read a single integer $t$ ($t$ is $0$ or $1$): if the subrectangles are equal, $t=1$, otherwise $t=0$.

In case your query is of incorrect format or you asked more than $3 \cdot \left \lfloor{ \log_2{(n+m)} } \right \rfloor$ queries, you will receive the Wrong Answer verdict.

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.

It is guaranteed that the matrix $a$ is fixed and won't change during the interaction process.

Example

Input

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

Output

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

Note

In the example test the matrix $a$ of size $3 \times 4$ is equal to:

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

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

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

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

struct Hasher {
    long long MOD;
    long long B1, B2;
    vector<long long> pow1, pow2;
    vector<vector<long long>> pref;
    int N, M;

    Hasher(int n, int m, long long mod, long long b1, long long b2, const vector<vector<int>>& mat)
        : N(n), M(m), MOD(mod), B1(b1), B2(b2) {

        pow1.resize(N + 1);
        pow2.resize(M + 1);
        pow1[0] = 1;
        for(int i=1; i<=N; ++i) pow1[i] = (pow1[i-1] * B1) % MOD;
        pow2[0] = 1;
        for(int i=1; i<=M; ++i) pow2[i] = (pow2[i-1] * B2) % MOD;

        pref.assign(N + 1, vector<long long>(M + 1, 0));
        for(int i=1; i<=N; ++i) {
            for(int j=1; j<=M; ++j) {
                long long val = mat[i-1][j-1];
                val %= MOD;
                long long term = (val * pow1[i]) % MOD;
                term = (term * pow2[j]) % MOD;

                long long res = (pref[i-1][j] + pref[i][j-1]) % MOD;
                res = (res - pref[i-1][j-1] + MOD) % MOD;
                res = (res + term) % MOD;
                pref[i][j] = res;
            }
        }
    }

    long long get(int r, int c, int h, int w) {
        int r2 = r + h - 1;
        int c2 = c + w - 1;
        long long res = (pref[r2][c2] - pref[r-1][c2] + MOD) % MOD;
        res = (res - pref[r2][c-1] + MOD) % MOD;
        res = (res + pref[r-1][c-1]) % MOD;
        return res;
    }

    bool equal(int r1, int c1, int r2, int c2, int h, int w) {
        long long h1 = get(r1, c1, h, w);
        long long h2 = get(r2, c2, h, w);

        long long left = (h1 * pow1[r2]) % MOD;
        left = (left * pow2[c2]) % MOD;

        long long right = (h2 * pow1[r1]) % MOD;
        right = (right * pow2[c1]) % MOD;

        return left == right;
    }
};

vector<vector<int>> mat;
int N, M;

bool overlap(int r1, int c1, int r2, int c2, int h, int w) {
    int r1_end = r1 + h;
    int r2_end = r2 + h;
    int c1_end = c1 + w;
    int c2_end = c2 + w;

    int r_start = max(r1, r2);
    int r_end = min(r1_end, r2_end);
    int c_start = max(c1, c2);
    int c_end = min(c1_end, c2_end);

    return (r_start < r_end && c_start < c_end);
}

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

    N = inf.readInt();
    M = inf.readInt();
    mat.assign(N, vector<int>(M));
    for(int i=0; i<N; ++i) {
        for(int j=0; j<M; ++j) {
            mat[i][j] = inf.readInt();
        }
    }

    Hasher H1(N, M, 1000000007, 1009, 1013, mat);
    Hasher H2(N, M, 1000000009, 1019, 1021, mat);

    int v_cnt = 0;
    for (int r = 1; r <= N; ++r) {
        if (N % r == 0) {
            if (r == N) {
                v_cnt++;
            } else {

                if (H1.equal(1, 1, 1+r, 1, N-r, M) && H2.equal(1, 1, 1+r, 1, N-r, M)) {
                    v_cnt++;
                }
            }
        }
    }

    int h_cnt = 0;
    for (int c = 1; c <= M; ++c) {
        if (M % c == 0) {
            if (c == M) {
                h_cnt++;
            } else {

                if (H1.equal(1, 1, 1, 1+c, N, M-c) && H2.equal(1, 1, 1, 1+c, N, M-c)) {
                    h_cnt++;
                }
            }
        }
    }

    long long ans = (long long)v_cnt * h_cnt;

    query_limit = 3LL * (long long)floor(log2(N + M));

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

    while (true) {
        string token;
        if (!(cin >> token)) {
             finish(_pe, "Unexpected EOF (expected '?' or '!')");
        }

        if (token == "!") {
             long long user_ans;
             if (!(cin >> user_ans)) finish(_pe, "Expected answer after '!'");
             if (user_ans == ans) {
                 finish(_ok, "Correct answer");
             } else {
                 finish(_wa, "Wrong answer. Expected " + to_string(ans) + ", found " + to_string(user_ans));
             }
        } else {
             int h, w, i1, j1, i2, j2;

             if (token == "?") {
                 if (!(cin >> h >> w >> i1 >> j1 >> i2 >> j2)) finish(_pe, "Invalid query format");
             } else {
                 try {
                     h = stoi(token);
                 } catch (...) {
                     finish(_pe, "Invalid token (expected integer or '?'/'!')");
                 }
                 if (!(cin >> w >> i1 >> j1 >> i2 >> j2)) finish(_pe, "Invalid query format");
             }

             queries++;
             if (queries > 200000) finish(_pe, "Hard query limit exceeded");

             if (h < 1 || h > N || w < 1 || w > M) finish(_wa, "Dimensions out of bounds");
             if (i1 < 1 || i1 > N || j1 < 1 || j1 > M) finish(_wa, "Coords 1 out of bounds");
             if (i2 < 1 || i2 > N || j2 < 1 || j2 > M) finish(_wa, "Coords 2 out of bounds");

             if (i1 + h - 1 > N || j1 + w - 1 > M) finish(_wa, "Rect 1 out of bounds");
             if (i2 + h - 1 > N || j2 + w - 1 > M) finish(_wa, "Rect 2 out of bounds");

             if (overlap(i1, j1, i2, j2, h, w)) finish(_wa, "Rectangles overlap");

             bool eq = H1.equal(i1, j1, i2, j2, h, w) && H2.equal(i1, j1, i2, j2, h, w);
             cout << (eq ? 1 : 0) << endl;

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

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

using namespace std;

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

void log_metrics() {
    if (query_limit == 0) return;
    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 count_divisors(int x) {
    int cnt = 0;
    for (int i = 1; i * i <= x; i++) {
        if (x % i == 0) {
            cnt++;
            if (i * i != x) cnt++;
        }
    }
    return cnt;
}

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

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

    query_limit = 3LL * (long long)floor(log2(n + m));

    vector<long long> rest;
    while (!inf.seekEof()) {
        rest.push_back(inf.readLong());
    }

    int R = -1, C = -1;
    vector<vector<int>> mat;

    if (rest.size() == (size_t)n * m) {

        mat.assign(n, vector<int>(m));
        int idx = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                mat[i][j] = (int)rest[idx++];
            }
        }

        R = n;
        vector<int> divs_n;
        for (int i = 1; i * i <= n; i++) {
            if (n % i == 0) {
                divs_n.push_back(i);
                if (i * i != n) divs_n.push_back(n / i);
            }
        }
        sort(divs_n.begin(), divs_n.end());

        for (int r : divs_n) {
            bool ok = true;

            for (int i = 0; i < n - r; i++) {
                for (int j = 0; j < m; j++) {
                    if (mat[i][j] != mat[i + r][j]) {
                        ok = false; break;
                    }
                }
                if (!ok) break;
            }
            if (ok) { R = r; break; }
        }

        C = m;
        vector<int> divs_m;
        for (int i = 1; i * i <= m; i++) {
            if (m % i == 0) {
                divs_m.push_back(i);
                if (i * i != m) divs_m.push_back(m / i);
            }
        }
        sort(divs_m.begin(), divs_m.end());

        for (int c : divs_m) {
            bool ok = true;

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m - c; j++) {
                    if (mat[i][j] != mat[i][j + c]) {
                        ok = false; break;
                    }
                }
                if (!ok) break;
            }
            if (ok) { C = c; break; }
        }

    } else if (rest.size() == 2) {

        R = (int)rest[0];
        C = (int)rest[1];
    } else {
        finish(_fail, "Invalid input format in hidden file (token count mismatch)");
    }

    long long correct_ans = (long long)count_divisors(n / R) * count_divisors(m / C);

    atexit(log_metrics);
    log_metrics();

    cout << n << " " << m << endl;

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

            finish(_wa, "Unexpected EOF (no answer provided)");
        }

        if (type == "!") {
            long long user_ans;
            if (!(cin >> user_ans)) {
                finish(_wa, "Expected integer answer after '!'");
            }
            if (user_ans == correct_ans) {
                finish(_ok, "Correct");
            } else {
                finish(_wa, "Wrong answer: expected " + to_string(correct_ans) + ", found " + to_string(user_ans));
            }
        } else if (type == "?") {
            queries++;

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

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

            int h, w, i1, j1, i2, j2;
            if (!(cin >> h >> w >> i1 >> j1 >> i2 >> j2)) {
                finish(_wa, "Invalid query format");
            }

            if (h < 1 || h > n || w < 1 || w > m) finish(_wa, "Invalid rectangle size");

            if (i1 < 1 || i1 > n - h + 1 || j1 < 1 || j1 > m - w + 1) finish(_wa, "Rectangle 1 out of bounds");
            if (i2 < 1 || i2 > n - h + 1 || j2 < 1 || j2 > m - w + 1) finish(_wa, "Rectangle 2 out of bounds");

            int r_start = max(i1, i2);
            int r_end = min(i1 + h - 1, i2 + h - 1);
            int c_start = max(j1, j2);
            int c_end = min(j1 + w - 1, j2 + w - 1);

            if (r_start <= r_end && c_start <= c_end) {
                finish(_wa, "Rectangles overlap");
            }

            bool eq = false;
            if (!mat.empty()) {

                eq = true;
                for (int r_off = 0; r_off < h; r_off++) {
                    for (int c_off = 0; c_off < w; c_off++) {
                        if (mat[i1 + r_off - 1][j1 + c_off - 1] != mat[i2 + r_off - 1][j2 + c_off - 1]) {
                            eq = false;
                            break;
                        }
                    }
                    if (!eq) break;
                }
            } else {

                if (abs(i1 - i2) % R == 0 && abs(j1 - j2) % C == 0) {
                    eq = true;
                }
            }

            cout << (eq ? 1 : 0) << endl;
        } else {
            finish(_wa, "Unknown token '" + type + "' (expected '?' or '!')");
        }
    }

    return 0;
}

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

using namespace std;

vector<int> get_divisors(int n) {
    vector<int> divs;
    for (int i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            divs.push_back(i);
            if (i * i != n) divs.push_back(n / i);
        }
    }
    return divs;
}

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

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

    int n, m, r, c;
    long long seed_val = atoll(argv[1]);

    if (seed_val == 1) {

        n = 1000; m = 1000;
        r = n; c = m;
    } else if (seed_val == 2) {

        n = 1000; m = 1000;
        r = 1; c = 1;
    } else if (seed_val == 3) {

        n = 997; m = 991;
        r = n; c = m;
    } else if (seed_val == 4) {

        n = 10; m = 10;
        r = 10; c = 10;
    } else if (seed_val <= 10) {

        int hcn[] = {12, 24, 36, 48, 60, 120, 240, 360, 720, 840};
        int sz = sizeof(hcn)/sizeof(hcn[0]);
        n = hcn[rnd.next(sz)];
        m = hcn[rnd.next(sz)];
        vector<int> dn = get_divisors(n);
        vector<int> dm = get_divisors(m);
        r = dn[rnd.next(dn.size())];
        c = dm[rnd.next(dm.size())];
    } else {

        n = rnd.next(1, 1000);
        m = rnd.next(1, 1000);

        vector<int> dn = get_divisors(n);
        vector<int> dm = get_divisors(m);
        r = dn[rnd.next(dn.size())];
        c = dm[rnd.next(dm.size())];
    }

    if (mode == "adp") {

        cout << n << " " << m << endl;
        cout << r << " " << c << endl;
    } else {

        cout << n << " " << m << endl;

        vector<vector<int>> base(r, vector<int>(c));
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                base[i][j] = rnd.next(1, 1000000000);
            }
        }

        int temp_r = r;
        for (int i = 2; i * i <= temp_r; i++) {
            if (temp_r % i == 0) {
                int p = i;
                while (temp_r % i == 0) temp_r /= i;

                int step = r / p;

                int row = rnd.next(step);
                int col = rnd.next(c);
                if (base[row][col] == base[row + step][col]) {
                    base[row][col]++;
                }
            }
        }
        if (temp_r > 1) {
            int p = temp_r;
            int step = r / p;
            int row = rnd.next(step);
            int col = rnd.next(c);
            if (base[row][col] == base[row + step][col]) {
                base[row][col]++;
            }
        }

        int temp_c = c;
        for (int i = 2; i * i <= temp_c; i++) {
            if (temp_c % i == 0) {
                int p = i;
                while (temp_c % i == 0) temp_c /= i;

                int step = c / p;
                int row = rnd.next(r);
                int col = rnd.next(step);
                if (base[row][col] == base[row][col + step]) {
                    base[row][col]++;
                }
            }
        }
        if (temp_c > 1) {
            int p = temp_c;
            int step = c / p;
            int row = rnd.next(r);
            int col = rnd.next(step);
            if (base[row][col] == base[row][col + step]) {
                base[row][col]++;
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cout << base[i % r][j % c] << (j == m - 1 ? "" : " ");
            }
            cout << "\n";
        }
    }

    return 0;
}


Alice suggested Bob to play a game. Bob didn't like this idea, but he couldn't refuse Alice, so he asked you to write a program that would play instead of him.

The game starts with Alice taking out a grid sheet of size $n \times n$, the cells of which are initially not colored. After that she colors some $2n$ cells with colors $1,2,\ldots, 2n$, respectively, and informs Bob about these cells.

In one move, Bob can point to a cell that has not been colored yet and ask Alice to color that cell. Alice colors that cell with one of the $2n$ colors of her choice, informing Bob of the chosen color. Bob can make no more than $10$ moves, after which he needs to find a good set of four cells.

A set of four cells is considered good if the following conditions are met:

* All the cells in the set are colored;
* No two cells in the set are colored with the same color;
* The centers of the cells form a rectangle with sides parallel to the grid lines.

Input

Each test consists of multiple test cases. The first line contains a single integer $t$ ($1 \le t \le 200$) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($3 \le n \le 1000$) — the size of the grid.

The $i$-th of the following $2n$ lines contains two integers $x_i$ and $y_i$ ($1 \le x_i, y_i \le n$) — the coordinates of the cell colored with the $i$-th color.

It is guaranteed that all coordinates $(x_i, y_i)$ are pairwise distinct for the same test case.

After reading the input data for each test case, continue the interaction as described below.

Interaction

You can make no more than $10$ moves. To make a move, output "? $x$ $y$" ($1 \leq x,y \leq n$). In response to this, the jury's program will output a single integer from $1$ to $2n$ — the color of cell $(x,y)$.

After all moves (it is not necessary to make all $10$ moves and it is not necessary to make at least one move), output a string in the format "! $x_1$ $x_2$ $y_1$ $y_2$" ($1 \leq x_1, x_2, y_1, y_2 \leq n, x_1 \ne x_2, y_1 \ne y_2$). If cells $(x_1, y_1)$, $(x_1, y_2)$, $(x_2, y_1)$, $(x_2, y_2)$ are colored with different colors, the jury's program will output "OK". After that, proceed to the next test case or terminate the program if there are no more test cases left.

Otherwise, if any of the specified cells are colored with the same color or one of the cells is not colored yet, the jury's program will output "ERROR". In this case, your program should immediately terminate its execution to receive the Wrong Answer verdict. Otherwise, you may receive an arbitrary verdict.

After each move or answer, do not forget to output the end of line and flush the output. Otherwise, you will get the Idleness limit exceeded verdict.

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.

Note that the interactor is adaptive, meaning that the color Alice will use to color the cells during Bob's moves is not fixed in advance.

Example

Input

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

1

OK
3
1 1
1 2
1 3
2 1
2 2
2 3

OK
```

Output

```
? 1 1

! 1 2 1 3

! 1 2 1 2
```

Note

In the first test case:

 ![](https://espresso.codeforces.com/2c1d85336cadfac6ae8273d7300d9620f4420679.png)

In the second test case, cells with coordinates $(1, 1), (1, 2), (2, 1), (2, 2)$ are initially colored by Alice in different colors.

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

using namespace std;

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

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

    }
}

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

static bool is_integer(const string& s) {
    if (s.empty()) return false;
    if (s[0] == '-' && s.length() == 1) return false;
    for (size_t i = (s[0] == '-'); i < s.length(); ++i) {
        if (!isdigit(s[i])) return false;
    }
    return true;
}

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

    int t = inf.readInt();

    query_limit = (long long)t * 10;

    cout << t << endl;

    for (int i = 0; i < t; ++i) {

        int n = inf.readInt();
        cout << n << endl;

        vector<vector<int>> grid(n + 1, vector<int>(n + 1, 0));
        vector<vector<bool>> known(n + 1, vector<bool>(n + 1, false));

        for (int j = 0; j < 2 * n; ++j) {
            int r = inf.readInt();
            int c = inf.readInt();
            known[r][c] = true;

            cout << r << " " << c << endl;
        }

        for (int r = 1; r <= n; ++r) {
            for (int c = 1; c <= n; ++c) {
                grid[r][c] = inf.readInt();
            }
        }
        cout.flush();

        int case_queries = 0;
        bool case_solved = false;

        while (true) {

            log_metrics();

            string token;

            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF (waiting for query or answer)");
            }

            if (token == "!") {

                int x1, x2, y1, y2;
                if (!(cin >> x1 >> x2 >> y1 >> y2)) {
                    finish(_wa, "Invalid answer format");
                }

                if (x1 < 1 || x1 > n || x2 < 1 || x2 > n || y1 < 1 || y1 > n || y2 < 1 || y2 > n) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Answer coordinates out of bounds");
                }

                if (x1 == x2 || y1 == y2) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Invalid rectangle (x1==x2 or y1==y2)");
                }

                vector<pair<int, int>> p = {{x1, y1}, {x1, y2}, {x2, y1}, {x2, y2}};

                for (auto& pt : p) {
                    if (!known[pt.first][pt.second]) {
                        cout << "ERROR" << endl;
                        finish(_wa, "Answer uses a cell that has not been colored");
                    }
                }

                set<int> distinct_colors;
                for (auto& pt : p) {
                    distinct_colors.insert(grid[pt.first][pt.second]);
                }

                if (distinct_colors.size() == 4) {
                    cout << "OK" << endl;
                    case_solved = true;
                    break;
                } else {
                    cout << "ERROR" << endl;
                    finish(_wa, "Cells do not have distinct colors");
                }

            } else {

                int x, y;
                if (token == "?") {
                    if (!(cin >> x >> y)) finish(_wa, "Invalid query format after '?'");
                } else {

                    if (!is_integer(token)) finish(_wa, "Invalid token (expected '?', '!', or integer)");
                    try {
                        x = stoi(token);
                    } catch (...) {
                        finish(_wa, "Invalid integer for x");
                    }
                    if (!(cin >> y)) finish(_wa, "Invalid query format (missing y)");
                }

                if (case_queries >= 10) {
                    finish(_wa, "Too many moves (limit 10 per test case)");
                }

                if (x < 1 || x > n || y < 1 || y > n) {
                    finish(_wa, "Query coordinates out of bounds");
                }

                if (known[x][y]) {
                    finish(_wa, "Cell already colored");
                }

                known[x][y] = true;
                queries++;
                case_queries++;

                cout << grid[x][y] << endl;

            }
        }

        if (!case_solved) {

            finish(_wa, "Test case loop exited unexpectedly");
        }
    }

    quitf(_ok, "Passed %d test cases", t);
    return 0;
}

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

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

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

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

int N;

vector<vector<pair<int, int>>> adj;

vector<vector<int>> grid_colors;

int get_color(int r, int c) {
    if (r < 1 || r > N || c < 1 || c > N) return 0;
    return grid_colors[r][c];
}

void add_edge(int r, int c, int color) {
    grid_colors[r][c] = color;
    adj[r].push_back({c + N, color});
    adj[c + N].push_back({r, color});
}

int solve_adaptive_color(int r, int c) {
    int start = r;
    int target = c + N;

    queue<int> q;
    q.push(start);

    int size = 2 * N + 5;
    vector<int> parent(size, 0);
    vector<int> parent_edge_color(size, 0);
    vector<bool> visited(size, false);
    visited[start] = true;

    bool found = false;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        if (u == target) {
            found = true;
            break;
        }
        for (auto& edge : adj[u]) {
            int v = edge.first;
            int col = edge.second;
            if (!visited[v]) {
                visited[v] = true;
                parent[v] = u;
                parent_edge_color[v] = col;
                q.push(v);
            }
        }
    }

    if (found) {
        vector<int> path_colors;
        int curr = target;
        while (curr != start) {
            path_colors.push_back(parent_edge_color[curr]);
            curr = parent[curr];
        }

        if (!path_colors.empty()) {
            return path_colors[0];
        }
    }

    return 1;
}

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

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

    int t = inf.readInt();

    cout << t << endl;

    query_limit = (long long)t * 10;

    log_metrics();

    for (int tc = 0; tc < t; tc++) {

        N = inf.readInt();
        cout << N << endl;

        adj.assign(2 * N + 5, vector<pair<int, int>>());
        grid_colors.assign(N + 1, vector<int>(N + 1, 0));

        for (int i = 0; i < 2 * N; i++) {
            int u = inf.readInt();
            int v = inf.readInt();
            int color = i + 1;
            add_edge(u, v, color);
            cout << u << " " << v << endl;
        }

        bool case_active = true;
        while (case_active) {
            string type;
            if (!(cin >> type)) {
                finish(_pe, "Unexpected EOF (waiting for query or answer)");
            }

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

                if (queries > query_limit + 5000) {
                    finish(_pe, "Too many queries (hard cap hit)");
                }

                int r, c;
                if (!(cin >> r >> c)) finish(_pe, "Invalid query format");

                if (r < 1 || r > N || c < 1 || c > N) {
                    finish(_wa, format("Query out of bounds: %d %d", r, c));
                }

                if (grid_colors[r][c] != 0) {

                    cout << grid_colors[r][c] << endl;
                } else {

                    int color = solve_adaptive_color(r, c);
                    add_edge(r, c, color);
                    cout << color << endl;
                }

            } else if (type == "!") {
                int x1, x2, y1, y2;
                if (!(cin >> x1 >> x2 >> y1 >> y2)) finish(_pe, "Invalid answer format");

                bool ok = true;
                if (x1 < 1 || x1 > N || x2 < 1 || x2 > N) ok = false;
                if (y1 < 1 || y1 > N || y2 < 1 || y2 > N) ok = false;
                if (x1 == x2 || y1 == y2) ok = false;

                if (!ok) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Invalid rectangle coordinates");
                }

                int c1 = get_color(x1, y1);
                int c2 = get_color(x1, y2);
                int c3 = get_color(x2, y1);
                int c4 = get_color(x2, y2);

                if (c1 == 0 || c2 == 0 || c3 == 0 || c4 == 0) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Rectangle contains uncolored cells");
                }

                set<int> distinct;
                distinct.insert(c1);
                distinct.insert(c2);
                distinct.insert(c3);
                distinct.insert(c4);

                if (distinct.size() == 4) {
                    cout << "OK" << endl;
                    case_active = false;
                } else {
                    cout << "ERROR" << endl;
                    finish(_wa, format("Colors not distinct: %d %d %d %d", c1, c2, c3, c4));
                }

            } else {
                finish(_pe, "Expected '?' or '!', got: " + type);
            }
        }

        log_metrics();
    }

    finish(_ok, "All test 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");
    int n_opt = opt<int>("n", -1);

    int n;
    if (n_opt != -1) {
        n = n_opt;
    } else {

        int type = rnd.next(1, 10);
        if (type == 1) n = 3;
        else if (type == 2) n = rnd.next(3, 10);
        else if (type == 3) n = 1000;
        else n = rnd.next(10, 1000);
    }

    n = max(3, min(n, 1000));

    vector<int> rows(n), cols(n);
    iota(rows.begin(), rows.end(), 1);
    iota(cols.begin(), cols.end(), 1);

    shuffle(rows.begin(), rows.end());
    shuffle(cols.begin(), cols.end());

    vector<pair<int, int>> initial_cells;
    initial_cells.reserve(2 * n);

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

        initial_cells.push_back({rows[i], cols[i]});

        initial_cells.push_back({rows[i], cols[(i + 1) % n]});
    }

    shuffle(initial_cells.begin(), initial_cells.end());

    cout << 1 << endl;
    cout << n << endl;
    for (const auto& cell : initial_cells) {
        cout << cell.first << " " << cell.second << endl;
    }

    if (mode == "non") {
        vector<vector<int>> grid(n + 1, vector<int>(n + 1, 0));

        for (int i = 0; i < 2 * n; i++) {
            grid[initial_cells[i].first][initial_cells[i].second] = i + 1;
        }

        for (int r = 1; r <= n; r++) {
            for (int c = 1; c <= n; c++) {
                if (grid[r][c] == 0) {
                    grid[r][c] = rnd.next(1, 2 * n);
                }
            }
        }

        for (int r = 1; r <= n; r++) {
            for (int c = 1; c <= n; c++) {
                cout << grid[r][c] << (c == n ? "" : " ");
            }
            cout << endl;
        }
    }

    return 0;
}