The only difference between this problem and the other two versions is the maximum number of queries. In this version, you are allowed to ask at most $\mathbf{30}$ queries.

This is an interactive problem.

"Everybody! Doremy's Perfect Data Structure Class is about to start! Come and do your best if you want to have as much IQ as me!" In today's Data Structure class, Doremy is teaching everyone a powerful data structure — Doremy tree! Now she gives you a quiz to prove that you are paying attention in class.

Given an array $a$ of length $m$, Doremy tree supports the query $Q(l,r,k)$, where $1 \leq l \leq r \leq m$ and $1 \leq k \leq m$, which returns the number of distinct integers in the array $\left[\lfloor\frac{a_l}{k} \rfloor, \lfloor\frac{a_{l+1}}{k} \rfloor, \ldots, \lfloor\frac{a_r}{k} \rfloor\right]$.

Doremy has a secret permutation $p$ of integers from $1$ to $n$. You can make queries, in one query, you give $3$ integers $l,r,k$ ($1 \leq l \leq r \leq n$, $1 \leq k \leq n$) and receive the value of $Q(l,r,k)$ for the array $p$. Can you find the index $y$ ($1 \leq y \leq n$) such that $p_y=1$ in at most $\mathbf{30}$ queries?

Note that the permutation $p$ is fixed before any queries are made.

Interaction

You begin the interaction by reading an integer $n$ ($3 \le n \le 1024$) in the first line — the length of the permutation.

To make a query, you should output

* "? $l\ r\ k$" ($1 \leq l \leq r \leq n$, $1 \leq k \leq n$)

in a separate line. After each query, you should read an integer $x$ — the value of $Q(l,r,k)$ for $p$. In this version of the problem, you can make at most $30$ such queries.

To give the answer, you should output

* "! $y$" ($1 \leq y \leq n$)

in a separate line, where $p_y=1$.

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

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

Example

Input

```
5

2

2

1

3
```

Output

```
? 1 3 4

? 3 5 3

? 3 4 5

? 3 5 2

! 4
```

Note

The permutation in the example is $[3,5,2,1,4]$.

The input and output for example illustrate possible interaction on that test (empty lines are inserted only for clarity).

In this interaction process:

* For the first query, $\lfloor\frac{3}{4}\rfloor=0,\lfloor\frac{5}{4}\rfloor=1,\lfloor\frac{2}{4}\rfloor=0$, so the answer is $2$.
* For the second query, $\lfloor\frac{2}{3}\rfloor=0,\lfloor\frac{1}{3}\rfloor=0,\lfloor\frac{4}{3}\rfloor=1$, so the answer is still $2$.
* For the third query, $\lfloor\frac{2}{5}\rfloor=0,\lfloor\frac{1}{5}\rfloor=0$, so the answer is $1$.
* For the fourth query, $\lfloor\frac{2}{2}\rfloor=1,\lfloor\frac{1}{2}\rfloor=0,\lfloor\frac{4}{2}\rfloor=2$, so the answer is $3$.

The correct answer is got after $4$ queries, so this process will be judged correct.

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

using namespace std;

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

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(3, 1024, "n");
    vector<int> p(n);
    int one_pos = -1;
    for (int i = 0; i < n; ++i) {
        p[i] = inf.readInt(1, n, "p_i");
        if (p[i] == 1) {
            one_pos = i + 1;
        }
    }

    log_metrics();

    cout << n << endl;

    vector<bool> seen(n + 1, false);
    vector<int> reset_list;
    reset_list.reserve(n + 1);

    int hard_cap = 300;

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Contestant output ended without providing an answer");
        }

        if (token == "!") {

            int y;
            if (!(cin >> y)) {
                finish(_pe, "Unexpected EOF after '!'");
            }

            if (y < 1 || y > n) {
                finish(_wa, format("Answer index %d is out of bounds [1, %d]", y, n));
            }

            if (y == one_pos) {
                finish(_ok, format("Correct! Found index %d.", y));
            } else {
                finish(_wa, format("Wrong Answer. Expected %d, found %d.", one_pos, y));
            }

        }
        else {

            int l, r, k;

            if (token == "?") {
                if (!(cin >> l >> r >> k)) {
                    finish(_pe, "Unexpected EOF reading query parameters");
                }
            } else {

                try {
                    l = stoi(token);
                } catch (...) {
                    finish(_pe, format("Expected integer or '?', found '%s'", token.c_str()));
                }
                if (!(cin >> r >> k)) {
                    finish(_pe, "Unexpected EOF reading r, k");
                }
            }

            if (l < 1 || l > n || r < 1 || r > n || l > r) {
                finish(_wa, format("Invalid query range [%d, %d] with n=%d", l, r, n));
            }
            if (k < 1 || k > n) {
                finish(_wa, format("Invalid k=%d (1 <= k <= %d)", k, n));
            }

            queries++;

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

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

            for (int val : reset_list) {
                seen[val] = false;
            }
            reset_list.clear();

            int distinct_count = 0;
            for (int i = l - 1; i < r; ++i) {
                int val = p[i] / k;
                if (!seen[val]) {
                    seen[val] = true;
                    reset_list.push_back(val);
                    distinct_count++;
                }
            }

            cout << distinct_count << endl;
        }
    }

    return 0;
}

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

using namespace std;

static int queries = 0;
static int query_limit = 30;

void log_metrics() {
    try {

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

    }
}

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

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

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

    int n = inf.readInt(3, 1024, "n");

    vector<int> data;
    while (!inf.seekEof()) {
        data.push_back(inf.readInt());
    }

    vector<int> p(n);
    int target = -1;

    if (data.size() == 1) {

        target = data[0];
        ensuref(target >= 1 && target <= n, "Target index %d out of bounds [1, %d]", target, n);

        p[target - 1] = 1;

        vector<int> others;
        others.reserve(n - 1);
        for (int i = 2; i <= n; i++) {
            others.push_back(i);
        }

        mt19937 rng(1337);
        shuffle(others.begin(), others.end(), rng);

        int ptr = 0;
        for (int i = 0; i < n; i++) {
            if (i == target - 1) continue;
            p[i] = others[ptr++];
        }

    } else {

        if (data.size() != (size_t)n) {
            finish(_fail, "Input format error: expected %d integers for permutation, found %d", n, (int)data.size());
        }

        vector<int> count(n + 1, 0);
        for (int i = 0; i < n; i++) {
            p[i] = data[i];
            ensuref(p[i] >= 1 && p[i] <= n, "Permutation value %d out of bounds", p[i]);
            count[p[i]]++;
        }

        for (int i = 1; i <= n; i++) {
            ensuref(count[i] == 1, "Invalid permutation: value %d appears %d times", i, count[i]);
        }

        for (int i = 0; i < n; i++) {
            if (p[i] == 1) {
                target = i + 1;
                break;
            }
        }
    }

    cout << n << endl;

    log_metrics();

    int hard_cap = 200;

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

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

            finish(_pe, "Unexpected end of output from solution");
        }

        if (type == "?") {
            queries++;
            int l, r, k;
            if (!(cin >> l >> r >> k)) {
                finish(_pe, "Invalid query format");
            }

            if (l < 1 || l > n || r < 1 || r > n || k < 1 || k > n) {
                finish(_pe, "Query parameters out of bounds: %d %d %d", l, r, k);
            }
            if (l > r) {
                finish(_pe, "Invalid query range: l (%d) > r (%d)", l, r);
            }

            set<int> distinct;
            for (int i = l - 1; i < r; i++) {
                distinct.insert(p[i] / k);
            }

            cout << distinct.size() << endl;

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

            if (y == target) {
                finish(_ok, "Correct! Found index %d in %d queries", target, queries);
            } else {
                finish(_wa, "Wrong Answer. Expected index %d, found %d", target, y);
            }

        } else {
            finish(_pe, "Invalid query type '%s', expected '?' or '!'", type.c_str());
        }
    }

    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");

    long long seed_val = -1;
    if (argc > 1) {
        string s = argv[1];

        if (!s.empty() && s.find_first_not_of("0123456789") == string::npos) {
            try {
                seed_val = stoll(s);
            } catch (...) {
                seed_val = -1;
            }
        }
    }

    int n;
    vector<int> p;

    if (seed_val == 1) {

        n = 1024;
        p.resize(n);
        iota(p.begin(), p.end(), 1);
    }
    else if (seed_val == 2) {

        n = 1024;
        p.resize(n);
        iota(p.begin(), p.end(), 1);
        reverse(p.begin(), p.end());
    }
    else if (seed_val == 3) {

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

        n = 1024;
        p.assign(n, 0);

        vector<int> smalls = {1, 2, 3, 4, 5};
        int start_pos = n / 2 - 2;

        for (int i = 0; i < (int)smalls.size(); ++i) {
            if (start_pos + i < n) p[start_pos + i] = smalls[i];
        }

        vector<int> others;
        for (int i = 6; i <= n; ++i) others.push_back(i);
        shuffle(others.begin(), others.end());

        int ptr = 0;
        for (int i = 0; i < n; ++i) {
            if (p[i] == 0) p[i] = others[ptr++];
        }
    }
    else if (seed_val == 5) {

        n = 512;
        p.resize(n);
        iota(p.begin(), p.end(), 1);
        shuffle(p.begin(), p.end());
    }
    else {

        if (rnd.next(0, 1)) {
            n = 1024;
        } else {
            n = rnd.next(3, 1024);
        }

        p.resize(n);
        iota(p.begin(), p.end(), 1);
        shuffle(p.begin(), p.end());
    }

    if (mode == "non") {

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

        int target = -1;
        for (int i = 0; i < n; ++i) {
            if (p[i] == 1) {
                target = i + 1;
                break;
            }
        }
        cout << n << endl;
        cout << target << endl;
    }

    return 0;
}


Aboard the spaceship Skeld are you — the ship’s commander — along with $N$ crewmates. The voyage from Earth to Polus was meant to be peaceful... until it wasn’t. A series of strange incidents occurs: oxygen runs low, the reactor nearly melts down, the lights flicker, and the doors jam shut. Suspicion spreads — there might be impostors among us.

Moments of crisis were handled with the crewmates’ unity, but the tension lingered. Each crewmate now secretly suspects exactly one crewmate of being the impostor. Remarkably, no crewmate is suspected by more than one person. Formally, there exists a permutation $P$ of length $N$ , where $P [ i ]$ is the crewmate whom the $i$ -th crewmate suspects.

Overseeing this chaos from the commander’s room, you, however, are not actually concerned with finding the impostors. Rather, your only goal is to determine the hidden permutation $P$ .

Naturally, to achieve this, you may call emergency meetings. In each meeting, you can choose the order in which the crewmates speak.

Given a crewmate speaking, they will accuse the crewmate they suspect. If the speaker has not yet been marked as sus, their accusation is valid, and the accused crewmate becomes sus. However, if the speaker is already $\mathbf { \Delta } _ { \mathbf { \Delta } } \mathbf { \Delta } _ { \mathbf { \Delta } } \mathbf { \Delta } _ { \mathbf { \Delta } } \mathbf { \Sigma } _ { \mathbf { \Delta } } \mathbf { \Sigma } _ { \mathbf { \Delta } } \mathbf { \Sigma } _ { \mathbf { \Delta } } \mathbf { \Sigma } _ { \mathbf { \Delta } } \mathbf { \Sigma } _ { \mathbf { \Delta } }$ , their accusation is ignored.

Unfortunately, as the commander, you cannot attend the meetings yourself. Instead, after each meeting, the ship’s log reports the sus status of all crewmates as a binary array, where 1 indicates sus and 0 indicates not $\mathbf { { \mathit { s u s s } } }$ .

Since time is limited, you may hold at most 400 emergency meetings. Your task is to determine the hidden permutation $P$ within this limit.

# Interaction Protocol

Your program first reads a single integer $N$ ( $2 \leq N \leq 1 0 0$ ) — the number of crewmates.

Then, you may repeatedly perform queries (call emergency meetings). To make a query, print a line in the following format:

• ? q1 q2 . . . qN

Here, $( q _ { 1 } , q _ { 2 } , \ldots , q _ { N } )$ is the order in which the crewmates will speak during the meeting. The sequence must be a permutation of length $N$ .

After printing a query, flush the output and read a line containing $N$ integers:

• $s _ { 1 } ~ s _ { 2 } ~ . . . ~ s _ { N }$

Here, $s _ { i }$ indicates the status of the $i$ -th crewmate after the meeting ends:

• $s _ { i } = 0 - \mathrm { t h e } ~ i$ -th crewmate is not sus.
• $s _ { i } = 1$ — the $i$ -th crewmate is sus.

# Each emergency meeting is independent; all crewmates start as not sus.

When you have determined the hidden permutation $P$ , print it in the following format:

• ! p1 p2 . . . pN

Printing the answer does not count as a query. After printing the final answer, your program should immediately terminate. Failure to do so may result in an undefined verdict.

You may perform at most 400 queries. If your program performs more than 400 queries or outputs an invalid format, you may receive a Wrong Answer verdict.

The interactor is not adaptive, which means that the hidden permutation does not depend on the queries you make.

After printing a query or an answer, do not forget to output the end of line and flush the output. Otherwise, you may get an Idleness Limit Exceeded verdict. To do this, use:

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

# Example

standard input

？123456

101110 001111

?243156

？654321 ？354216

# Note

For the first emergency meeting, the permutation $P$ is $[ 4 , 5 , 3 , 6 , 2 , 1 ]$ and the accusations go as follows:

• Crewmate 1 accuses crewmate 4. Crewmate 4 becomes sus.
• Crewmate 2 accuses crewmate 5. Crewmate 5 becomes sus.
• Crewmate 3 accuses crewmate 3. Crewmate 3 becomes sus.
• Crewmate 4 accuses crewmate 6, but they are already sus, so it is ignored.
• Crewmate 5 accuses crewmate 2, but they are already sus, so it is ignored.
• Crewmate 6 accuses crewmate 1. Crewmate 1 becomes sus.
• The ship reports the status of the crewmates as 1 0 1 1 1 0.

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

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

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;
    size_t i = 0;
    if (s[0] == '-') i = 1;
    if (i == s.size()) return false;
    for (; i < s.size(); ++i) {
        if (!isdigit(s[i])) return false;
    }
    return true;
}

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    int N = inf.readInt(2, 100, "N");
    vector<int> P(N + 1);
    vector<bool> p_seen(N + 1, false);
    for (int i = 1; i <= N; ++i) {
        P[i] = inf.readInt(1, N, format("P[%d]", i));
        if (p_seen[P[i]]) quitf(_fail, "Hidden input P is not a permutation");
        p_seen[P[i]] = true;
    }

    log_metrics();

    cout << N << endl;

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF (expected query '?' or answer '!')");
        }

        if (token == "!") {

            vector<int> guess(N + 1);
            for (int i = 1; i <= N; ++i) {
                string t;
                if (!(cin >> t)) finish(_wa, "EOF reading answer permutation");
                if (!is_integer(t)) finish(_wa, "Answer token '" + t + "' is not an integer");
                try {
                    guess[i] = stoi(t);
                } catch (...) {
                    finish(_wa, "Answer integer out of range");
                }
            }

            bool ok = true;
            for (int i = 1; i <= N; ++i) {
                if (guess[i] != P[i]) {
                    ok = false;
                    break;
                }
            }

            if (ok) finish(_ok, "Correct permutation found");
            else finish(_wa, "Incorrect permutation");

        } else {

            queries++;

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

            if (queries > 200000) {
                finish(_pe, "Hard query limit exceeded (infinite loop protection)");
            }

            vector<int> Q;
            Q.reserve(N);

            if (token != "?") {
                if (!is_integer(token)) {
                    finish(_wa, "Invalid token '" + token + "' (expected '?' or integer)");
                }
                try {
                    Q.push_back(stoi(token));
                } catch (...) {
                    finish(_wa, "Query integer out of range");
                }
            }

            int needed = (token == "?") ? N : N - 1;
            for (int i = 0; i < needed; ++i) {
                string t;
                if (!(cin >> t)) finish(_wa, "EOF reading query");
                if (!is_integer(t)) finish(_wa, "Query token '" + t + "' is not an integer");
                try {
                    Q.push_back(stoi(t));
                } catch (...) {
                    finish(_wa, "Query integer out of range");
                }
            }

            if ((int)Q.size() != N) finish(_wa, "Query size mismatch");
            vector<bool> q_seen(N + 1, false);
            bool valid = true;
            for (int x : Q) {
                if (x < 1 || x > N || q_seen[x]) {
                    valid = false;
                    break;
                }
                q_seen[x] = true;
            }
            if (!valid) finish(_wa, "Query is not a valid permutation of 1..N");

            vector<int> sus(N + 1, 0);
            for (int u : Q) {
                if (sus[u]) continue;
                int target = P[u];
                sus[target] = 1;
            }

            for (int i = 1; i <= N; ++i) {
                cout << sus[i] << (i == N ? "" : " ");
            }
            cout << endl;
        }
    }

    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");

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

    int n;
    vector<int> p;

    if (seed == 1) {

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

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

        n = 100;
        p.resize(n);
        for (int i = 0; i < n; ++i) {
            p[i] = (i + 1) % n + 1;
        }
    } else if (seed == 4) {

        n = 100;
        p.resize(n);
        iota(p.begin(), p.end(), 1);
        for (int i = 0; i + 1 < n; i += 2) {
            swap(p[i], p[i+1]);
        }
    } else {

        if (rnd.next(4) > 0) n = 100;
        else n = rnd.next(2, 100);

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

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

            p = rnd.perm(n, 1);

            for (int iter = 0; iter < 50; ++iter) {
                bool has_fixed = false;
                for (int i = 0; i < n; ++i) if (p[i] == i + 1) has_fixed = true;
                if (!has_fixed) break;
                shuffle(p.begin(), p.end());
            }

            for (int i = 0; i < n; ++i) {
                if (p[i] == i + 1) {

                    int j = (i + 1) % n;
                    swap(p[i], p[j]);

                    if (p[j] == j + 1) {
                        int k = (j + 1) % n;
                        swap(p[j], p[k]);
                    }
                }
            }
        } else {

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

            int idx = 0;
            while(idx < n) {
                int rem = n - idx;

                int len = rnd.next(1, min(rem, 15));

                if (rem - len == 1) len++;

                for(int k = 0; k < len; ++k) {
                    p[nodes[idx + k] - 1] = nodes[idx + (k + 1) % len];
                }
                idx += len;
            }
        }
    }

    if (mode == "non") {

        cout << n << endl;
        println(p);
    } else {

        cout << n << endl;
    }

    return 0;
}


This is an interactive problem

You are given a grid $n\times n$, where $n$ is odd. Rows are enumerated from $1$ to $n$ from up to down, columns are enumerated from $1$ to $n$ from left to right. Cell, standing on the intersection of row $x$ and column $y$, is denoted by $(x, y)$.

Every cell contains $0$ or $1$. It is known that the top-left cell contains $1$, and the bottom-right cell contains $0$.

We want to know numbers in all cells of the grid. To do so we can ask the following questions:

"$?$ $x_1$ $y_1$ $x_2$ $y_2$", where $1 \le x_1 \le x_2 \le n$, $1 \le y_1 \le y_2 \le n$, and $x_1 + y_1 + 2 \le x_2 + y_2$. In other words, we output two different cells $(x_1, y_1)$, $(x_2, y_2)$ of the grid such that we can get from the first to the second by moving only to the right and down, and they aren't adjacent.

As a response to such question you will be told if there exists a path between $(x_1, y_1)$ and $(x_2, y_2)$, going only to the right or down, numbers in cells of which form a palindrome.

For example, paths, shown in green, are palindromic, so answer for "$?$ $1$ $1$ $2$ $3$" and "$?$ $1$ $2$ $3$ $3$" would be that there exists such path. However, there is no palindromic path between $(1, 1)$ and $(3, 1)$.

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

Determine all cells of the grid by asking not more than $n^2$ questions. It can be shown that the answer always exists.

Input

The first line contains odd integer ($3 \le n < 50$) — the side of the grid.

Interaction

You begin the interaction by reading $n$.

To ask a question about cells $(x_1, y_1), (x_2, y_2)$, in a separate line output "$?$ $x_1$ $y_1$ $x_2$ $y_2$".

Numbers in the query have to satisfy $1 \le x_1 \le x_2 \le n$, $1 \le y_1 \le y_2 \le n$, and $x_1 + y_1 + 2 \le x_2 + y_2$. Don't forget to 'flush', to get the answer.

In response, you will receive $1$, if there exists a path going from $(x_1, y_1)$ to $(x_2, y_2)$ only to the right or down, numbers in cells of which form a palindrome, and $0$ otherwise.

In case your query is invalid or you asked more than $n^2$ queries, program will print $-1$ and will finish interaction. You will receive Wrong answer verdict. Make sure to exit immediately to avoid getting other verdicts.

When you determine numbers in all cells, output "!".

Then output $n$ lines, the $i$-th of which is a string of length $n$, corresponding to numbers in the $i$-th row of the grid.

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

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

Example

Input

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

Output

```
? 1 1 1 3
? 1 1 2 3
? 2 1 2 3
? 3 1 3 3
? 2 2 3 3
? 1 2 3 2
? 1 2 3 3
!
100
001
000
```

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

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

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

    }
}

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

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

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

static bool readIntInRange(long long& x, long long lo, long long hi) {
    string tok;
    if (!readToken(tok)) return false;
    if (!parseLongLongToken(tok, x)) return false;
    return (lo <= x && x <= hi);
}

static inline int idx4(int n, int x1, int y1, int x2, int y2) {
    return (((x1 * n + y1) * n + x2) * n + y2);
}

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

    int n = 0;
    try {
        n = inf.readInt();
    } catch (...) {
        query_limit = 0;
        log_metrics();
        quitf(_fail, "failed to read n from hidden input");
    }
    if (n < 1 || n > 200) {
        query_limit = 0;
        log_metrics();
        quitf(_fail, "invalid n in hidden input");
    }

    vector<string> g(n);
    for (int i = 0; i < n; i++) {
        string row;
        try {
            row = inf.readToken();
        } catch (...) {
            query_limit = 0;
            log_metrics();
            quitf(_fail, "failed to read grid row from hidden input");
        }
        if ((int)row.size() != n) {
            query_limit = 0;
            log_metrics();
            quitf(_fail, "grid row has invalid length in hidden input");
        }
        for (char c : row) {
            if (c != '0' && c != '1') {
                query_limit = 0;
                log_metrics();
                quitf(_fail, "grid row has invalid character in hidden input");
            }
        }
        g[i] = row;
    }

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

    vector<uint8_t> dp((size_t)n * n * n * n, 0);

    int maxd = 2 * (n - 1);
    for (int d = 0; d <= maxd; d++) {
        for (int x1 = 0; x1 < n; x1++) {
            for (int y1 = 0; y1 < n; y1++) {
                int maxDx = min(n - 1 - x1, d);
                for (int dx = 0; dx <= maxDx; dx++) {
                    int dy = d - dx;
                    if (dy < 0) continue;
                    if (y1 + dy >= n) continue;
                    int x2 = x1 + dx;
                    int y2 = y1 + dy;

                    int id = idx4(n, x1, y1, x2, y2);
                    if (d == 0) {
                        dp[id] = 1;
                        continue;
                    }
                    if (g[x1][y1] != g[x2][y2]) {
                        dp[id] = 0;
                        continue;
                    }
                    if (d == 1) {
                        dp[id] = 1;
                        continue;
                    }

                    bool ok = false;

                    for (int sm = 0; sm < 2 && !ok; sm++) {
                        int nx1 = x1 + (sm == 0 ? 1 : 0);
                        int ny1 = y1 + (sm == 1 ? 1 : 0);
                        if (nx1 > x2 || ny1 > y2) continue;

                        for (int em = 0; em < 2 && !ok; em++) {
                            int nx2 = x2 - (em == 0 ? 1 : 0);
                            int ny2 = y2 - (em == 1 ? 1 : 0);
                            if (nx2 < x1 || ny2 < y1) continue;
                            if (nx1 > nx2 || ny1 > ny2) continue;

                            int sub = idx4(n, nx1, ny1, nx2, ny2);
                            if (dp[sub]) ok = true;
                        }
                    }
                    dp[id] = ok ? 1 : 0;
                }
            }
        }
    }

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

    log_metrics();

    while (true) {
        string cmd;
        if (!readToken(cmd)) {

            finish(_pe, "unexpected EOF from contestant");
        }

        if (cmd == "?") {
            long long x1ll, y1ll, x2ll, y2ll;
            if (!readIntInRange(x1ll, 1, n) || !readIntInRange(y1ll, 1, n) ||
                !readIntInRange(x2ll, 1, n) || !readIntInRange(y2ll, 1, n)) {
                cout << -1 << '\n';
                cout.flush();
                finish(_pe, "malformed query coordinates");
            }
            int x1 = (int)x1ll - 1, y1 = (int)y1ll - 1, x2 = (int)x2ll - 1, y2 = (int)y2ll - 1;

            if (!(0 <= x1 && x1 <= x2 && x2 < n && 0 <= y1 && y1 <= y2 && y2 < n)) {
                cout << -1 << '\n';
                cout.flush();
                finish(_pe, "query violates ordering/range constraints");
            }
            int dist = (x2 - x1) + (y2 - y1);
            if (dist < 2) {
                cout << -1 << '\n';
                cout.flush();
                finish(_pe, "query endpoints are adjacent or same (distance < 2)");
            }

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

            int ans = dp[idx4(n, x1, y1, x2, y2)] ? 1 : 0;
            cout << ans << '\n';
            cout.flush();
        } else if (cmd == "!") {
            vector<string> outg(n);
            for (int i = 0; i < n; i++) {
                string row;
                if (!readToken(row)) {
                    finish(_pe, "unexpected EOF while reading final grid");
                }
                if ((int)row.size() != n) {
                    finish(_pe, "final grid row has invalid length");
                }
                for (char c : row) {
                    if (c != '0' && c != '1') finish(_pe, "final grid row has invalid character");
                }
                outg[i] = row;
            }

            for (int i = 0; i < n; i++) {
                if (outg[i] != g[i]) {
                    finish(_wa, "final grid is incorrect");
                }
            }
            finish(_ok, "ok");
        } else {
            cout << -1 << '\n';
            cout.flush();
            finish(_pe, "unknown command token");
        }
    }
}

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

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

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

    }
}

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

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

struct GridRep {
    int n = 0;
    vector<uint8_t> val;
    vector<string> rows;
};

static int gN = 0;
static int gCells = 0;
static vector<int> gX, gY;
static vector<int> gDown, gRight, gUp, gLeft;

static inline int idx0(int x0, int y0) {
    return x0 * gN + y0;
}
static inline int idx1(int x1, int y1) {
    return (x1 - 1) * gN + (y1 - 1);
}

static GridRep buildRepFromRows(const vector<string>& rows) {
    GridRep rep;
    rep.n = (int)rows.size();
    rep.rows = rows;
    rep.val.assign(rep.n * rep.n, 0);
    for (int i = 0; i < rep.n; i++) {
        for (int j = 0; j < rep.n; j++) {
            rep.val[i * rep.n + j] = (uint8_t)(rows[i][j] == '1');
        }
    }
    return rep;
}

static vector<string> genCandidateRows(int n, int which) {
    vector<string> rows(n, string(n, '0'));
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            int b = 0;
            if (which == 0) {
                int t = (i * 17 + j * 31 + (i * j) % 7);
                b = (t & 1);
                if ((i + j) % 3 == 0) b ^= 1;
                if (i == j || i + j == n + 1) b ^= 1;
            } else if (which == 1) {
                b = ((i + j) % 2 == 0) ? 1 : 0;
                if (i % 7 == 0) b ^= 1;
                if (j % 5 == 0) b ^= 1;
            } else {
                b = (j % 2 == 1) ? 1 : 0;
                if (i % 4 == 1) b ^= 1;
                if ((i + 2 * j) % 11 == 0) b ^= 1;
            }
            rows[i - 1][j - 1] = char('0' + (b & 1));
        }
    }
    rows[0][0] = '1';
    rows[n - 1][n - 1] = '0';
    return rows;
}

static bool palExists(const GridRep& rep, int x1, int y1, int x2, int y2,
                      vector<int>& seen, int& stamp) {

    if (x1 > x2 || y1 > y2) return false;
    int L = (x2 - x1) + (y2 - y1) + 1;
    int a0 = idx1(x1, y1);
    int b0 = idx1(x2, y2);
    if (rep.val[a0] != rep.val[b0]) return false;
    if (L <= 2) return true;

    stamp++;
    if (stamp == INT_MAX) {
        fill(seen.begin(), seen.end(), 0);
        stamp = 1;
    }

    const int cells = gCells;
    auto keyOf = [&](int a, int b) -> int { return a * cells + b; };

    vector<int> cur, nxt;
    cur.reserve(3000);
    nxt.reserve(3000);

    int k0 = keyOf(a0, b0);
    seen[k0] = stamp;
    cur.push_back(k0);

    int steps = (L - 1) / 2;
    for (int step = 0; step < steps; step++) {
        nxt.clear();
        for (int key : cur) {
            int a = key / cells;
            int b = key - a * cells;

            int ax = gX[a], ay = gY[a];
            int bx = gX[b], by = gY[b];

            int aMoves[2], aCnt = 0;
            int bMoves[2], bCnt = 0;

            if (ax + 1 <= x2 - 1) aMoves[aCnt++] = gDown[a];
            if (ay + 1 <= y2 - 1) aMoves[aCnt++] = gRight[a];

            if (bx + 1 >= x1 - 1) bMoves[bCnt++] = gUp[b];
            if (by + 1 >= y1 - 1) bMoves[bCnt++] = gLeft[b];

            for (int i = 0; i < aCnt; i++) {
                int a2 = aMoves[i];
                int ax2 = gX[a2], ay2 = gY[a2];
                if (ax2 < x1 - 1 || ax2 > x2 - 1 || ay2 < y1 - 1 || ay2 > y2 - 1) continue;

                for (int j = 0; j < bCnt; j++) {
                    int b2 = bMoves[j];
                    int bx2 = gX[b2], by2 = gY[b2];
                    if (bx2 < x1 - 1 || bx2 > x2 - 1 || by2 < y1 - 1 || by2 > y2 - 1) continue;

                    if (ax2 > bx2 || ay2 > by2) continue;
                    if (rep.val[a2] != rep.val[b2]) continue;

                    int nk = keyOf(a2, b2);
                    if (seen[nk] == stamp) continue;
                    seen[nk] = stamp;
                    nxt.push_back(nk);
                }
            }
        }
        cur.swap(nxt);
        if (cur.empty()) return false;
    }

    if (L % 2 == 1) {
        for (int key : cur) {
            int a = key / cells;
            int b = key - a * cells;
            if (a == b) return true;
        }
        return false;
    } else {
        for (int key : cur) {
            int a = key / cells;
            int b = key - a * cells;
            int ax = gX[a], ay = gY[a];
            int bx = gX[b], by = gY[b];
            int md = abs(ax - bx) + abs(ay - by);
            if (md == 1 && ax <= bx && ay <= by) return true;
        }
        return false;
    }
}

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

    int n = inf.readInt(3, 49, "n");
    if (n % 2 == 0) finish(_pe, "n must be odd");
    gN = n;
    gCells = n * n;

    query_limit = 1LL * n * n;

    gX.assign(gCells, 0);
    gY.assign(gCells, 0);
    gDown.assign(gCells, -1);
    gRight.assign(gCells, -1);
    gUp.assign(gCells, -1);
    gLeft.assign(gCells, -1);
    for (int x = 0; x < n; x++) {
        for (int y = 0; y < n; y++) {
            int id = idx0(x, y);
            gX[id] = x;
            gY[id] = y;
            if (x + 1 < n) gDown[id] = idx0(x + 1, y);
            if (y + 1 < n) gRight[id] = idx0(x, y + 1);
            if (x - 1 >= 0) gUp[id] = idx0(x - 1, y);
            if (y - 1 >= 0) gLeft[id] = idx0(x, y - 1);
        }
    }

    bool hasFixedGrid = false;
    GridRep hidden;

    if (!inf.seekEof()) {
        vector<string> rows(n);
        for (int i = 0; i < n; i++) {
            rows[i] = inf.readToken();
            if ((int)rows[i].size() != n) finish(_pe, "invalid grid row length in inf");
            for (char c : rows[i]) if (c != '0' && c != '1') finish(_pe, "invalid grid char in inf");
        }
        if (rows[0][0] != '1') finish(_pe, "inf grid: top-left must be 1");
        if (rows[n - 1][n - 1] != '0') finish(_pe, "inf grid: bottom-right must be 0");
        hidden = buildRepFromRows(rows);
        hasFixedGrid = true;
    }

    vector<GridRep> candidates;
    if (!hasFixedGrid) {
        candidates.reserve(3);
        for (int which = 0; which < 3; which++) {
            auto rows = genCandidateRows(n, which);
            candidates.push_back(buildRepFromRows(rows));
        }
    }

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

    log_metrics();

    vector<int> seen((size_t)gCells * (size_t)gCells, 0);
    int stamp = 0;

    bool chosen = hasFixedGrid;
    int chosenCand = -1;

    auto sendInvalidAndDie = [&](const string& why) -> void {
        cout << -1 << "\n";
        cout.flush();
        finish(_pe, why);
    };

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

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

        if (cmd == "?") {
            string sx1, sy1, sx2, sy2;
            if (!(cin >> sx1 >> sy1 >> sx2 >> sy2)) finish(_pe, "unexpected EOF in query arguments");
            long long X1, Y1, X2, Y2;
            if (!parseLLStrict(sx1, X1) || !parseLLStrict(sy1, Y1) || !parseLLStrict(sx2, X2) || !parseLLStrict(sy2, Y2))
                sendInvalidAndDie("non-integer query arguments");

            if (X1 < 1 || X1 > n || X2 < 1 || X2 > n || Y1 < 1 || Y1 > n || Y2 < 1 || Y2 > n)
                sendInvalidAndDie("query coordinates out of range");
            if (X1 > X2 || Y1 > Y2) sendInvalidAndDie("query order invalid");
            if (X1 + Y1 + 2 > X2 + Y2) sendInvalidAndDie("query cells adjacent or unreachable");

            queries++;
            if (queries > hard_cap) sendInvalidAndDie("too many queries (hard cap exceeded)");

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

            if (!chosen) {

                int cnt0 = 0, cnt1 = 0;
                int a0 = -1, a1 = -1;
                for (int i = 0; i < (int)candidates.size(); i++) {
                    bool r = palExists(candidates[i], x1, y1, x2, y2, seen, stamp);
                    if (!r) {
                        cnt0++;
                        if (a0 == -1) a0 = i;
                    } else {
                        cnt1++;
                        if (a1 == -1) a1 = i;
                    }
                }
                int pickAns;
                int pickIdx;
                if (cnt0 > cnt1) {
                    pickAns = 0; pickIdx = a0;
                } else if (cnt1 > cnt0) {
                    pickAns = 1; pickIdx = a1;
                } else {

                    if (cnt0 > 0) { pickAns = 0; pickIdx = a0; }
                    else { pickAns = 1; pickIdx = a1; }
                }
                if (pickIdx < 0) finish(_pe, "internal: no candidate to pick");
                chosen = true;
                chosenCand = pickIdx;
                hidden = candidates[pickIdx];
                ans = pickAns;
            } else {
                ans = palExists(hidden, x1, y1, x2, y2, seen, stamp) ? 1 : 0;
            }

            cout << ans << "\n";
            cout.flush();
        } else if (cmd == "!") {
            vector<string> outRows(n);
            for (int i = 0; i < n; i++) {
                if (!(cin >> outRows[i])) finish(_pe, "unexpected EOF reading final grid");
                if ((int)outRows[i].size() != n) finish(_pe, "final grid row has wrong length");
                for (char c : outRows[i]) if (c != '0' && c != '1') finish(_pe, "final grid row has non-binary char");
            }

            if (!chosen) {

                if (hasFixedGrid) {

                } else {
                    chosen = true;
                    chosenCand = 0;
                    hidden = candidates[0];
                }
            }

            if (outRows[0][0] != '1' || outRows[n - 1][n - 1] != '0') {
                finish(_wa, "final grid violates fixed corners");
            }

            if (outRows == hidden.rows) {
                finish(_ok, "correct");
            } else {
                finish(_wa, "wrong grid");
            }
        } else {
            sendInvalidAndDie("unknown command token");
        }
    }
}

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

static int clampInt(int x, int lo, int hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

static int makeOdd(int n) {
    if (n % 2 == 0) n++;
    return n;
}

static vector<string> genGridNon(int n, long long seedVal) {
    vector<string> g(n, string(n, '0'));

    if (seedVal == 1) {

        g = {"101", "010", "000"};
        g[0][0] = '1';
        g[n - 1][n - 1] = '0';
        return g;
    }

    if (seedVal == 2) {

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int b = ((i + j) & 1);
                if (i % 7 == 0) b ^= 1;
                if (j % 11 == 0) b ^= 1;
                if (((i - j + n) % 9) == 0) b ^= 1;
                if (i == j) b ^= 1;
                if (i + j == n - 1) b ^= 1;
                if (i == n / 2 || j == n / 2) b ^= ((i + 2 * j) % 3 == 0);

                int r = rnd.next(0, 99);
                if (r < 18) b ^= 1;

                g[i][j] = char('0' + b);
            }
        }
        g[0][0] = '1';
        g[n - 1][n - 1] = '0';
        return g;
    }

    if (seedVal == 3) {

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                int parity = ((i + j) & 1);
                int b;
                if (parity == 0) b = (rnd.next(0, 99) < 92 ? 1 : 0);
                else b = (rnd.next(0, 99) < 8 ? 1 : 0);

                if ((i % 5 == 0 && j % 5 == 0) || (i % 8 == 1 && j % 8 == 6)) b ^= 1;
                if (i == j || i + j == n - 1) b ^= 1;
                if (i == n / 2 || j == n / 2) b ^= ((i + j) % 3 == 1);

                int r = rnd.next(0, 99);
                if (r < 10) b ^= 1;

                g[i][j] = char('0' + b);
            }
        }
        g[0][0] = '1';
        g[n - 1][n - 1] = '0';
        return g;
    }

    int biasEven = opt<int>("biasEven", 86);
    int biasOdd = opt<int>("biasOdd", 14);
    int noise = opt<int>("noise", 16);
    biasEven = clampInt(biasEven, 0, 100);
    biasOdd = clampInt(biasOdd, 0, 100);
    noise = clampInt(noise, 0, 60);

    int cx = n / 2, cy = n / 2;
    int rad = max(1, n / 6);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int parity = ((i + j) & 1);
            int b = 0;

            int pr = rnd.next(0, 99);
            if (parity == 0) b = (pr < biasEven ? 1 : 0);
            else b = (pr < biasOdd ? 1 : 0);

            if (i == j) b ^= 1;
            if (i + j == n - 1) b ^= 1;
            if (i == cx || j == cy) b ^= ((i + 2 * j) % 3 == 0);
            if ((i % 9 == 0) || (j % 10 == 0)) b ^= 1;
            if (((i * 7 + j * 13) % 17) == 0) b ^= 1;

            if (abs(i - cx) + abs(j - cy) <= rad) b ^= (((i + j) % 4) == 1);

            int rr = rnd.next(0, 99);
            if (rr < noise) b ^= 1;

            g[i][j] = char('0' + b);
        }
    }

    g[0][0] = '1';
    g[n - 1][n - 1] = '0';

    int oddOnes = 0, oddCnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (((i + j) & 1) == 1) {
                oddCnt++;
                oddOnes += (g[i][j] == '1');
            }
        }
    }
    if (oddOnes == 0 || oddOnes == oddCnt) {

        for (int t = 0; t < min(7, oddCnt); t++) {
            int i = (t * 7 + 3) % n;
            int j = (t * 11 + 5) % n;
            if (((i + j) & 1) == 0) j = (j + 1) % n;
            if (i == 0 && j == 0) j = 1;
            if (i == n - 1 && j == n - 1) j = n - 2;
            g[i][j] = (g[i][j] == '1' ? '0' : '1');
        }
        g[0][0] = '1';
        g[n - 1][n - 1] = '0';
    }

    return g;
}

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

    string mode = opt<string>("mode", "non");
    long long seedVal = 0;
    if (argc >= 2) {

        seedVal = atoll(argv[1]);
    }

    int nOpt = opt<int>("n", 0);
    int n = 0;

    if (nOpt != 0) {
        n = clampInt(nOpt, 3, 49);
        n = makeOdd(n);
        if (n >= 50) n = 49;
    } else {
        if (seedVal == 1) n = 3;
        else if (seedVal == 2) n = 49;
        else if (seedVal == 3) n = 49;
        else {

            int lo = opt<int>("nlo", 41);
            int hi = opt<int>("nhi", 49);
            lo = clampInt(lo, 3, 49);
            hi = clampInt(hi, 3, 49);
            if (lo > hi) swap(lo, hi);
            n = rnd.next(lo, hi);
            if (n % 2 == 0) n = (n == hi ? n - 1 : n + 1);
            if (n < 3) n = 3;
            if (n >= 50) n = 49;
            if (n % 2 == 0) n = 49;
        }
    }

    if (mode == "non") {
        vector<string> g = genGridNon(n, seedVal);
        cout << n << "\n";
        for (int i = 0; i < n; i++) cout << g[i] << "\n";
        return 0;
    }

    if (mode == "adp") {

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

    vector<string> g = genGridNon(n, seedVal);
    cout << n << "\n";
    for (int i = 0; i < n; i++) cout << g[i] << "\n";
    return 0;
}


AdhesiveWombat - Overdrive

The two versions have different constraints on $t$, $n$, and the maximum number of queries, and solving one of the two versions does not necessarily solve the other. You may want to read both versions.

This is an interactive problem.

There is a hidden array $a_1, a_2, \ldots, a_{2n-1}$ containing all the numbers from $1$ to $n$, and all of them appear twice except one (which only appears once).

You can ask queries in the following format, where $S$ is a subset of $\{1, 2, \ldots, 2n-1\}$ and $x$ is an integer in $[1, n]$:

* $\texttt{ask(S, x)}$: does there exist $i \in S$ such that $a_i = x$?

Find the number appearing exactly once, using at most $4n + 2 \lceil \log_2 n \rceil$ queries. You don't need to find its position.

Note that the interactor is not adaptive, which means that the hidden array does not depend on the queries you make.

Input

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

The first line of each test case contains a single integer $n$ ($1 \le n \le 300$) — the maximum value in the hidden array $a_1, a_2, \ldots, a_{2n-1}$.

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

There are exactly $80$ tests in this problem (including the example).

Interaction

For each test case, first read a single integer $n$. If the integer you read is $-1$, it means that the answer to the previous test case was wrong, and you should exit immediately.

You may ask up to $4n + 2 \lceil \log_2 n \rceil$ queries in each test case.

To ask a query, print a line in the format $\texttt{? x |S| S_1 S_2... S_|S|}$ with $1 \leq x \leq n$, $1 \leq S_1, S_2, \ldots, S_{|S|} \leq 2n-1$, and all the $S_i$ distinct.

As a response to the query, you will get $1$ if the answer is yes, $0$ if the answer is no, and $-1$ if you made an invalid query. You should exit immediately if you receive a $-1$.

To output an answer, you should print $\texttt{! y}$, where $y$ is the number that appears exactly once. Printing the answer doesn't count as a query.

See the interaction example for more clarity.

If you ask too many queries, you ask a malformed query, or your answer is wrong, you will get $\texttt{Wrong answer}$.

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

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

Note that the interactor is not adaptive, which means that the hidden arrays do not depend on the queries you make.

Example

Input

```
2
2

0

3

1

1

1

1
```

Output

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

Note

In the first test case, $n = 2$, so the hidden array has length $2n-1 = 3$. One possible hidden array consistent with the interaction is $[2, 2, 1]$, where $1$ appears once and $2$ appears twice.

|  |  |  |  |
| --- | --- | --- | --- |
| # | Contestant prints | Interactor replies | Explanation |
| 1 |? 1 2 1 2 | 0 | Query: does $a_1=1$ or $a_2=1$? No (they are both $2$). Therefore $1$ can appear at most once (only in position $3$), so the number appearing exactly once must be $1$. |
| 2 |! 1 |  | Output the answer. |

We have asked $1$ query (printing the answer does not count as a query), which is less than the maximum allowed number of queries ($4n + 2 \lceil \log_2 n \rceil = 10$).

$\color{white}{2}$

In the second testcase, $n = 3$, so the hidden array has length $5$. One possible hidden array consistent with the interaction is $[1, 2, 3, 2, 1]$, where $3$ appears once, and $1$ and $2$ appear twice.

|  |  |  |  |
| --- | --- | --- | --- |
| # | Contestant prints | Interactor replies | Explanation |
| 1 |? 1 2 1 4 | 1 | Check if $a_1$ or $a_4$ equals $1$. Yes ($a_1=1$). |
| 2 |? 2 2 1 4 | 1 | Check if $a_1$ or $a_4$ equals $2$. Yes ($a_4=2$). |
| 3 |? 2 1 2 | 1 | Check if $a_2=2$. Yes. |
| 4 |? 1 1 5 | 1 | Check if $a_5=1$. Yes. |
| 5 |! 3 |  | We know that $3$ cannot appear neither in positions $1$ and $4$ (which contain $1$ and $2$ in some order), nor in positions $2$ and $5$ (which contain $2$ and $1$, respectively). So the answer must be $3$. |

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

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

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

    }
}

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

struct TestCase {
    int n = 0;
    vector<int> a;
    int single = -1;
};

static int ceil_log2_int(int n) {
    int k = 0;
    int p = 1;
    while (p < n) {
        p <<= 1;
        ++k;
    }
    return k;
}

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

    int t = 0;
    vector<TestCase> tests;
    try {
        t = inf.readInt(1, 4000, "t");
        tests.resize(t);

        long long total_limit = 0;
        for (int tc = 0; tc < t; ++tc) {
            int n = inf.readInt(1, 300, "n");
            int m = 2 * n - 1;

            vector<int> a(m + 1, 0);
            vector<int> freq(n + 1, 0);
            for (int i = 1; i <= m; ++i) {
                int v = inf.readInt(1, n, "a_i");
                a[i] = v;
                freq[v]++;
            }

            int single = -1;
            for (int v = 1; v <= n; ++v) {
                if (freq[v] == 1) {
                    if (single != -1) {

                        query_limit = total_limit;
                        log_metrics();
                        quitf(_fail, "Invalid hidden input: multiple singletons");
                    }
                    single = v;
                } else if (freq[v] == 0 || freq[v] == 2) {

                } else {
                    query_limit = total_limit;
                    log_metrics();
                    quitf(_fail, "Invalid hidden input: value %d has freq %d", v, freq[v]);
                }
            }
            if (single == -1) {
                query_limit = total_limit;
                log_metrics();
                quitf(_fail, "Invalid hidden input: no singleton");
            }

            tests[tc].n = n;
            tests[tc].a = std::move(a);
            tests[tc].single = single;

            long long lim = 4LL * n + 2LL * ceil_log2_int(n);
            total_limit += lim;
        }

        query_limit = total_limit;
    } catch (...) {

        log_metrics();
        throw;
    }

    log_metrics();

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

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

    for (int tc = 0; tc < t; ++tc) {
        const int n = tests[tc].n;
        const int m = 2 * n - 1;
        const vector<int>& a = tests[tc].a;
        const int correct = tests[tc].single;

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

        bool answered = false;
        while (!answered) {
            string tok;
            if (!(cin >> tok)) finish(_pe, "Unexpected EOF from participant");

            if (tok == "?") {
                long long x_ll = 0, k_ll = 0;
                if (!(cin >> x_ll >> k_ll)) {
                    cout << -1 << "\n";
                    cout.flush();
                    finish(_pe, "Malformed query header");
                }
                if (x_ll < 1 || x_ll > n || k_ll < 1 || k_ll > m) {
                    cout << -1 << "\n";
                    cout.flush();
                    finish(_pe, "Invalid query parameters");
                }
                int x = (int)x_ll;
                int k = (int)k_ll;

                vector<char> seen(m + 1, 0);
                bool ok = true;
                bool exists = false;
                for (int i = 0; i < k; ++i) {
                    long long s_ll = 0;
                    if (!(cin >> s_ll)) {
                        cout << -1 << "\n";
                        cout.flush();
                        finish(_pe, "Malformed query set");
                    }
                    if (s_ll < 1 || s_ll > m) ok = false;
                    else {
                        int s = (int)s_ll;
                        if (seen[s]) ok = false;
                        seen[s] = 1;
                        if (a[s] == x) exists = true;
                    }
                }

                if (!ok) {
                    cout << -1 << "\n";
                    cout.flush();
                    finish(_pe, "Invalid query indices");
                }

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

                cout << (exists ? 1 : 0) << "\n";
                cout.flush();
            } else if (tok == "!") {
                long long y_ll = 0;
                if (!(cin >> y_ll)) finish(_pe, "Malformed answer");
                if (y_ll < 1 || y_ll > n) finish(_wa, "Answer out of range");
                int y = (int)y_ll;
                if (y != correct) finish(_wa, "Wrong answer");
                answered = true;
            } else {
                finish(_pe, "Unexpected token");
            }
        }
    }

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

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

template <class T>
static void shuffleVec(vector<T>& v) {
    for (int i = (int)v.size() - 1; i > 0; --i) {
        int j = rnd.next(0, i);
        swap(v[i], v[j]);
    }
}

static bool isPow2(int x) {
    return x > 0 && (x & (x - 1)) == 0;
}

static vector<int> makeSymmetric(int n, int singleVal) {
    int m = 2 * n - 1;
    vector<int> a(m + 1, 0);
    vector<int> rest;
    rest.reserve(n - 1);
    for (int v = 1; v <= n; ++v) if (v != singleVal) rest.push_back(v);
    shuffleVec(rest);

    for (int i = 1; i <= n - 1; ++i) a[i] = rest[i - 1];
    a[n] = singleVal;
    for (int i = 1; i <= n - 1; ++i) a[n + i] = rest[n - 1 - i];
    return a;
}

static vector<int> makeORCollision(int n, int singleVal) {
    int m = 2 * n - 1;
    vector<int> a(m + 1, 0);
    a[m] = singleVal;

    vector<int> vals;
    vals.reserve(n - 1);
    for (int v = 1; v <= n; ++v) if (v != singleVal) vals.push_back(v);
    shuffleVec(vals);

    vector<pair<int,int>> pairs;
    pairs.reserve(n - 1);
    for (int p = 1; p <= m - 1; ++p) {
        int q = (m ^ p);
        if (p < q) pairs.push_back({p, q});
    }

    shuffleVec(pairs);

    int need = n - 1;
    if ((int)pairs.size() != need) {

        return makeSymmetric(n, singleVal);
    }
    for (int i = 0; i < need; ++i) {
        int p = pairs[i].first;
        int q = pairs[i].second;
        a[p] = vals[i];
        a[q] = vals[i];
    }
    return a;
}

static vector<int> makeRandomShuffle(int n, int singleVal) {
    int m = 2 * n - 1;
    vector<int> bag;
    bag.reserve(m);
    for (int v = 1; v <= n; ++v) {
        bag.push_back(v);
        if (v != singleVal) bag.push_back(v);
    }
    shuffleVec(bag);
    vector<int> a(m + 1, 0);
    for (int i = 1; i <= m; ++i) a[i] = bag[i - 1];
    return a;
}

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

    string mode = opt<string>("mode", "non");
    int nArg = opt<int>("n", -1);
    int yArg = opt<int>("y", -1);
    int maxN = opt<int>("maxn", 300);
    int minN = opt<int>("minn", 250);

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

    auto pickN = [&]() -> int {
        if (nArg != -1) return nArg;
        if (seedVal == 1) return 1;
        if (seedVal == 2) return 300;
        if (seedVal == 3) return 256;

        int roll = rnd.next(0, 99);
        if (roll < 60) return 256;
        int lo = minN, hi = maxN;
        if (lo < 1) lo = 1;
        if (hi > 300) hi = 300;
        if (lo > hi) swap(lo, hi);
        if (lo == hi) return lo;
        return rnd.next(lo, hi);
    };

    auto pickY = [&](int n) -> int {
        if (yArg != -1) return yArg;
        if (seedVal == 1) return 1;
        if (seedVal == 2) return n;
        if (seedVal == 3) return 1;
        return rnd.next(1, n);
    };

    int n = pickN();
    ensuref(1 <= n && n <= 300, "n out of bounds: %d", n);
    int y = pickY(n);
    ensuref(1 <= y && y <= n, "y out of bounds: %d (n=%d)", y, n);

    cout << 1 << "\n";
    if (mode == "non") {
        cout << n << "\n";
        vector<int> a;

        if (seedVal == 1) {
            a.assign(2 * n, 0);
            a[1] = 1;
        } else if (seedVal == 2) {

            a.assign(2 * n, 0);
            for (int i = 1; i <= n - 1; ++i) a[i] = i;
            a[n] = n;
            for (int i = 1; i <= n - 1; ++i) a[n + i] = (n - i);
        } else if (seedVal == 3) {
            if (isPow2(n) && n >= 2) a = makeORCollision(n, y);
            else a = makeSymmetric(n, y);
        } else {
            int roll = rnd.next(0, 99);
            if (isPow2(n) && n >= 2 && roll < 70) {
                a = makeORCollision(n, y);
            } else if (roll < 90) {
                a = makeSymmetric(n, y);
            } else {
                a = makeRandomShuffle(n, y);
            }
        }

        int m = 2 * n - 1;
        for (int i = 1; i <= m; ++i) {
            if (i > 1) cout << ' ';
            cout << a[i];
        }
        cout << "\n";
    } else if (mode == "adp") {

        cout << n << " " << y << "\n";
    } else {
        quitf(_fail, "Unknown --mode: %s", mode.c_str());
    }

    return 0;
}


We call a function good if its domain of definition is some set of integers and if in case it's defined in $x$ and $x-1$, $f(x) = f(x-1) + 1$ or $f(x) = f(x-1)$.

Tanya has found $n$ good functions $f_{1}, \ldots, f_{n}$, which are defined on all integers from $0$ to $10^{18}$ and $f_i(0) = 0$ and $f_i(10^{18}) = L$ for all $i$ from $1$ to $n$. It's an notorious coincidence that $n$ is a divisor of $L$.

She suggests Alesya a game. Using one question Alesya can ask Tanya a value of any single function in any single point. To win Alesya must choose integers $l_{i}$ and $r_{i}$ ($0 \leq l_{i} \leq r_{i} \leq 10^{18}$), such that $f_{i}(r_{i}) - f_{i}(l_{i}) \geq \frac{L}{n}$ (here $f_i(x)$ means the value of $i$-th function at point $x$) for all $i$ such that $1 \leq i \leq n$ so that for any pair of two functions their segments $[l_i, r_i]$ don't intersect (but may have one common point).

Unfortunately, Tanya doesn't allow to make more than $2 \cdot 10^{5}$ questions. Help Alesya to win!

It can be proved that it's always possible to choose $[l_i, r_i]$ which satisfy the conditions described above.

It's guaranteed, that Tanya doesn't change functions during the game, i.e. interactor is not adaptive

Input

The first line contains two integers $n$ and $L$ ($1 \leq n \leq 1000$, $1 \leq L \leq 10^{18}$, $n$ is a divisor of $L$)  — number of functions and their value in $10^{18}$.

Output

When you've found needed $l_i, r_i$, print $"!"$ without quotes on a separate line and then $n$ lines, $i$-th from them should contain two integers $l_i$, $r_i$ divided by space.

Interaction

To ask $f_i(x)$, print symbol "?" without quotes and then two integers $i$ and $x$ ($1 \leq i \leq n$, $0 \leq x \leq 10^{18}$). Note, you must flush your output to get a response.

After that, you should read an integer which is a value of $i$-th function in point $x$.

You're allowed not more than $2 \cdot 10^5$ questions.

To flush you can use (just after printing an integer and end-of-line):

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

Example

Input

```
5 5
? 1 0
? 1 1
? 2 1
? 2 2
? 3 2
? 3 3
? 4 3
? 4 4
? 5 4
? 5 5
!
0 1
1 2
2 3
3 4
4 5
```

Output

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

Note

In the example Tanya has $5$ same functions where $f(0) = 0$, $f(1) = 1$, $f(2) = 2$, $f(3) = 3$, $f(4) = 4$ and all remaining points have value $5$.

Alesya must choose two integers for all functions so that difference of values of a function in its points is not less than $\frac{L}{n}$ (what is $1$ here) and length of intersection of segments is zero.

One possible way is to choose pairs $[0$, $1]$, $[1$, $2]$, $[2$, $3]$, $[3$, $4]$ and $[4$, $5]$ for functions $1$, $2$, $3$, $4$ and $5$ respectively.

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

using namespace std;

static const long long MAX_COORD = 1000000000000000000LL;
static const long long LIMIT_QUERIES = 200000;
static const long long HARD_CAP = 400000;

static int n;
static long long L;
static vector<pair<long long, long long>> funcs[1005];

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

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

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

long long get_func_val(int i, long long x) {
    long long val = 0;
    for (const auto& p : funcs[i]) {
        long long l = p.first;
        long long r = p.second;

        if (x <= l) continue;
        if (x >= r) val += (r - l);
        else val += (x - l);
    }
    return val;
}

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

    registerInteraction(argc, argv);

    n = inf.readInt();
    L = inf.readLong();

    for (int i = 1; i <= n; i++) {
        int k = inf.readInt();
        for (int j = 0; j < k; j++) {
            long long l = inf.readLong();
            long long r = inf.readLong();
            funcs[i].push_back({l, r});
        }
    }

    cout << n << " " << L << endl;

    log_metrics();

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

        int i_idx = -1;
        long long x_val = -1;
        bool parse_ok = true;

        if (token == "?") {
            if (!(cin >> i_idx >> x_val)) parse_ok = false;
        } else {

            try {
                i_idx = stoi(token);
            } catch (...) {
                parse_ok = false;
            }
            if (parse_ok && !(cin >> x_val)) parse_ok = false;
        }

        if (!parse_ok) {
            finish(_wa, "Invalid query format or unexpected EOF");
        }

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

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

        if (i_idx < 1 || i_idx > n) {
            finish(_wa, format("Function index %d out of bounds [1, %d]", i_idx, n));
        }
        if (x_val < 0 || x_val > MAX_COORD) {
            finish(_wa, format("Coordinate %lld out of bounds [0, 10^18]", x_val));
        }

        long long ans = get_func_val(i_idx, x_val);
        cout << ans << endl;
    }

    vector<pair<long long, long long>> ans_intervals;
    ans_intervals.reserve(n);

    for (int i = 1; i <= n; i++) {
        long long l, r;
        if (!(cin >> l >> r)) {
            finish(_wa, "Failed to read answer intervals");
        }

        if (l < 0 || r > MAX_COORD || l > r) {
            finish(_wa, format("Invalid interval %d: [%lld, %lld]", i, l, r));
        }

        long long val_l = get_func_val(i, l);
        long long val_r = get_func_val(i, r);
        if (val_r - val_l < L / n) {
            finish(_wa, format("Insufficient value for function %d: %lld < %lld", i, val_r - val_l, L / n));
        }

        ans_intervals.push_back({l, r});
    }

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

    for (size_t k = 0; k < ans_intervals.size() - 1; k++) {

        if (ans_intervals[k].second > ans_intervals[k+1].first) {
            finish(_wa, format("Intervals intersect: [%lld, %lld] and [%lld, %lld]",
                ans_intervals[k].first, ans_intervals[k].second,
                ans_intervals[k+1].first, ans_intervals[k+1].second));
        }
    }

    finish(_ok, "Solution found");
    return 0;
}

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

using namespace std;

using ll = long long;
const ll MAX_COORD = 1000000000000000000LL;

vector<ll> partition_ll(int k, ll total_sum) {
    if (k <= 0) return {};
    if (k == 1) return {total_sum};
    vector<ll> seps;
    seps.reserve(k - 1);
    for (int i = 0; i < k - 1; ++i) {
        seps.push_back(rnd.next(0LL, total_sum));
    }
    seps.push_back(0);
    seps.push_back(total_sum);
    sort(seps.begin(), seps.end());

    vector<ll> res;
    res.reserve(k);
    for (int i = 0; i < k; ++i) {
        res.push_back(seps[i+1] - seps[i]);
    }
    return res;
}

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

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

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

        int r = rnd.next(100);
        if (r < 10) n = rnd.next(1, 10);
        else if (r < 30) n = rnd.next(10, 100);
        else n = rnd.next(100, 1000);
    }

    ll L = opt<ll>("L", -1);
    if (L == -1) {

        ll max_mult = MAX_COORD / n;

        int r = rnd.next(100);
        ll mult;
        if (r < 10) mult = rnd.next(1LL, 100LL);
        else if (r < 30) mult = rnd.next(100LL, min(1000000LL, max_mult));
        else mult = rnd.next(max_mult / 10 + 1, max_mult);

        L = mult * n;
    }

    if (L % n != 0) {
        L = (L / n) * n;
        if (L == 0) L = n;
    }
    if (L > MAX_COORD) L = (MAX_COORD / n) * n;

    cout << n << " " << L;

    if (mode == "adp") {

        cout << " " << rnd.next(1LL, MAX_COORD) << endl;
        return 0;
    }

    cout << endl;

    int fragmentation_type = rnd.next(3);

    for (int i = 0; i < n; ++i) {
        int blocks = 1;
        if (fragmentation_type == 1) blocks = rnd.next(2, 5);
        else if (fragmentation_type == 2) blocks = rnd.next(5, 20);

        if (blocks > L) blocks = (int)L;
        if (blocks < 1) blocks = 1;

        vector<ll> ones = partition_ll(blocks, L);

        vector<ll> zeros = partition_ll(blocks + 1, MAX_COORD - L);

        vector<pair<ll, ll>> intervals;
        ll current_pos = 0;
        for (int j = 0; j < blocks; ++j) {
            current_pos += zeros[j];
            ll len = ones[j];
            if (len > 0) {
                intervals.push_back({current_pos, current_pos + len});
                current_pos += len;
            }
        }

        cout << intervals.size();
        for (auto &p : intervals) {
            cout << " " << p.first << " " << p.second;
        }
        cout << "\n";
    }

    return 0;
}


This is an interactive problem.

$n$ people sitting in a circle are trying to shuffle a deck of cards. The players are numbered from $1$ to $n$, so that players $i$ and $i+1$ are neighbours (as well as players $1$ and $n$). Each of them has exactly $k$ cards, where $k$ is even. The left neighbour of a player $i$ is player $i - 1$, and their right neighbour is player $i + 1$ (except for players $1$ and $n$, who are respective neighbours of each other).

Each turn the following happens: if a player has $x$ cards, they give $\lfloor x / 2 \rfloor$ to their neighbour on the left and $\lceil x / 2 \rceil$ cards to their neighbour on the right. This happens for all players simultaneously.

However, one player $p$ is the impostor and they just give all their cards to their neighbour on the right. You know the number of players $n$ and the number of cards $k$ each player has initially, but $p$ is unknown to you. Your task is to determine the value of $p$, by asking questions like "how many cards does player $q$ have?" for an index $q$ of your choice. After each question all players will make exactly one move and give their cards to their neighbours. You need to find the impostor by asking no more than $1000$ questions.

Input

The first line contains two integers $n$ and $k$ ($4 \le n \le 10^5$, $2 \le k \le 10^9$, $k$ is even) — the number of players and the number of cards.

Interaction

You can ask questions by printing "? $q$". The answer to this question is the number of cards player $q$ has now ($1 \le q \le n$). The shuffling process starts immediately after your first question, so the answer to the first one is always equal to $k$.

Once you have identified the impostor, you can output the answer by printing "! $p$", where $p$ is the player who is the impostor ($1 \le p \le n$). Then you have to terminate your program.

You have to find the impostor by asking no more than $1000$ questions.

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

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

Example

Input

```
4 2

2

1

2

3

2
```

Output

```
? 1

? 1

? 2

? 3

? 4

! 2
```

Note

In the example the cards are transferred in the following way:

* $2$ $2$ $2$ $2$ — player $1$ has $2$ cards.
* $1$ $2$ $3$ $2$ — player $1$ has $1$ card.

After this turn the number of cards remains unchanged for each player.

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

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

static int n;
static long long k;
static int p;

static vector<long long> current_cards;
static vector<long long> next_cards;

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

void simulate() {

    fill(next_cards.begin(), next_cards.end(), 0LL);

    int imp = p - 1;

    for (int i = 0; i < n; i++) {
        long long val = current_cards[i];
        if (val == 0) continue;

        int left = (i - 1 + n) % n;
        int right = (i + 1) % n;

        if (i == imp) {

            next_cards[right] += val;
        } else {

            long long to_left = val / 2;
            long long to_right = (val + 1) / 2;
            next_cards[left] += to_left;
            next_cards[right] += to_right;
        }
    }

    swap(current_cards, next_cards);
}

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

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

    try {
        n = inf.readInt(4, 100000, "n");
        k = inf.readLong(2LL, 1000000000LL, "k");
        p = inf.readInt(1, n, "p");
    } catch (const std::exception& e) {
        finish(_fail, "Failed to read input (n k p): " + string(e.what()));
    }

    current_cards.assign(n, k);
    next_cards.resize(n);

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

    while (true) {

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

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

            finish(_wa, "Unexpected end of interaction (EOF)");
        }

        if (token == "!") {
            int ans_p;
            if (!(cin >> ans_p)) finish(_wa, "Expected number after '!'");
            if (ans_p == p) finish(_ok, "Correct impostor found");
            finish(_wa, format("Incorrect impostor: expected %d, found %d", p, ans_p));
        }
        if (token != "?") {
            finish(_wa, "Invalid token (expected '?' or '!')");
        }

        int q;
        if (!(cin >> q)) finish(_wa, "Expected number after '?'");
        if (q < 1 || q > n) {
            finish(_wa, format("Query index out of bounds: %d", q));
        }

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

            cout << current_cards[q - 1] << endl;

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

            simulate();
    }

    return 0;
}

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

static int queries_count = 0;
static const int query_limit = 1000;
static bool finished = false;

static int n;
static long long k;
static int p;

static vector<long long> ref_sim;
static int sim_t = 0;
static int min_active = 0;
static int max_active = 0;

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

    }
}

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

void advance_simulation() {

    int next_min = min_active - 1;
    int next_max = max_active + 1;

    int range_start = next_min;
    int range_end = next_max;

    if (range_end - range_start >= n - 1) {
        range_start = 0;
        range_end = n - 1;
    }

    vector<pair<int, long long>> updates;
    updates.reserve(range_end - range_start + 5);

    for (int i_unwrapped = range_start; i_unwrapped <= range_end; ++i_unwrapped) {

        int i = (i_unwrapped % n + n) % n;

        int L = (i - 1 + n) % n;
        int R = (i + 1) % n;

        long long from_L = 0;
        long long from_R = 0;

        if (L == 0) {

            if (i == 1) from_L = ref_sim[L];
            else from_L = 0;
        } else {

            long long v = ref_sim[L];
            from_L = (v + 1) / 2;
        }

        if (R == 0) {

            from_R = 0;
        } else {

            long long v = ref_sim[R];
            from_R = v / 2;
        }

        long long new_val = from_L + from_R;

        if (new_val != ref_sim[i]) {
            updates.push_back({i, new_val});
        }
    }

    for (auto& p : updates) {
        ref_sim[p.first] = p.second;
    }

    min_active = next_min;
    max_active = next_max;
    sim_t++;
}

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

    n = inf.readInt(4, 100000, "n");
    k = inf.readLong(2LL, 1000000000LL, "k");
    p = inf.readInt(1, n, "p");

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

    ref_sim.assign(n, k);
    min_active = 0;
    max_active = 0;

    int hard_cap = 20000;

    while (true) {
        string token;
        if (!(cin >> token)) {
            finish(_pe, "Unexpected end of interaction");
        }

        if (token == "!") {
            int ans_p;
            if (!(cin >> ans_p)) finish(_wa, "Expected answer after '!'");
            if (ans_p == p) finish(_ok, "Correct");
            finish(_wa, format("Incorrect impostor: expected %d, found %d", p, ans_p));

        } else if (token == "?") {
            int q;
            if (!(cin >> q)) finish(_wa, "Expected index after '?'");

            if (q < 1 || q > n) finish(_wa, "Query index out of bounds");
            int q_idx = q - 1;
            int p_idx = p - 1;

            queries_count++;
            if (queries_count > hard_cap) {
                finish(_pe, "Too many queries (hard cap)");
            }
            if (queries_count > query_limit) {
                finish(_wa, "Query limit exceeded");
            }

            while (sim_t < queries_count - 1) {
                advance_simulation();
            }

            int rel = (q_idx - p_idx + n) % n;
            cout << ref_sim[rel] << endl;

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

        } else {
            finish(_wa, "Invalid token (expected '?' or '!')");
        }
    }

    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 opt_n = opt<int>("n", -1);
    long long opt_k = opt<long long>("k", -1);

    long long seed_val = -1;
    try {
        string s = argv[1];

        if (s.length() <= 18 && s.find_first_not_of("0123456789") == string::npos) {
            seed_val = stoll(s);
        }
    } catch (...) {}

    int n;
    long long k;
    int p;

    if (opt_n != -1) {
        n = opt_n;
    } else {
        if (seed_val == 1) n = 4;
        else if (seed_val == 2) n = 100000;
        else if (seed_val == 3) n = 100000;
        else {

            int t = rnd.next(1, 10);
            if (t == 1) n = rnd.next(4, 100);
            else if (t <= 4) n = rnd.next(101, 5000);
            else n = rnd.next(5001, 100000);
        }
    }

    if (opt_k != -1) {
        k = opt_k;
    } else {
        if (seed_val == 1) k = 2;
        else if (seed_val == 2) k = 1000000000LL;
        else if (seed_val == 3) k = 2;
        else {

            int t = rnd.next(1, 3);
            if (t == 1) k = rnd.next(2LL, 100LL);
            else if (t == 2) k = rnd.next(101LL, 100000LL);
            else k = rnd.next(100001LL, 1000000000LL);
        }
    }

    if (k < 2) k = 2;
    if (k > 1000000000LL) k = 1000000000LL;
    if (k % 2 != 0) {
        k++;
        if (k > 1000000000LL) k -= 2;
    }

    if (opt_n == -1 && seed_val == 1) p = 1;
    else if (opt_n == -1 && seed_val == 2) p = n;
    else if (opt_n == -1 && seed_val == 3) p = n / 2;
    else {
        p = rnd.next(1, n);
    }

    if (mode == "non") {

        cout << n << " " << k << " " << p << endl;
    } else if (mode == "adp") {

        cout << n << " " << k << " " << p << endl;
    } else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}


If you want to make an array problem harder - solve it on a tree. If you want to make a tree problem harder - solve it on a cactus
Conventional wisdom
NEERC featured a number of problems in previous years about cactuses — connected undirected graphs in which every edge belongs to at most one simple cycle. Intuitively, a cactus is a generalization of a tree where some cycles are allowed. An example of a cactus from NEERC 2007 problem is given on the picture below.
![image](https://cdn-mineru.openxlab.org.cn/result/2026-01-05/48855c1b-a5da-4c0e-b1d5-0e0d7f736bb8/3e5597fdf3edfe843267780e831b3d4e3dea1c15226b146616094d16bb471ecd.jpg)

You are playing a game on a cactus with Chloe. You are given a cactus. Chloe had secretly picked one vertex  $v$  from the cactus and your goal is to find it. You can make at most 10 guesses. If your guess is vertex  $v$  — you win. Otherwise, if your guess is another vertex  $u$  — Chloe helps you and tells you some vertex  $w$  which is adjacent to  $u$  and such that the distance from  $w$  to  $v$  is strictly less than the distance from  $u$  to  $v$  (here the distance is the number of edges in the shortest path between vertices).
# Interaction Protocol
First, the testing system writes a line with two integers  $n$  and  $m$  ( $1 \leq n \leq 500; 0 \leq m \leq 500$ ). Here  $n$  is the number of vertices in the graph. Vertices are numbered from 1 to  $n$ . Edges of the graph are represented by a set of edge-distinct paths, where  $m$  is the number of such paths. Each of the following  $m$  lines contains a path in the graph. A path starts with an integer  $k_i$  ( $2 \leq k_i \leq 500$ ) followed by  $k_i$  integers from 1 to  $n$ . These  $k_i$  integers represent vertices of a path. Adjacent vertices in a path are distinct. The path can go to the same vertex multiple times, but every edge is traversed exactly once in the whole input. The graph in the input is a cactus.
To prove that your program can find a secret vertex in at most 10 queries, you need to do that  $n$  times. Each time testing system picks some vertex before interacting with your program. Your program makes guesses by writing lines with a single number  $u$  ( $1 \leq u \leq n$ ).
Testing system responds by writing lines with one of the two responses:
- "FOUND" — means that your guess is correct. After that, your program should proceed to the next test case or terminate if  $n$  vertices were already guessed.
- "GO  $w$ " — means that your guess is incorrect, but now you know that the distance from vertex  $w$  to the secret vertex is less than the distance from  $u$ . It is guaranteed that vertices  $u$  and  $w$  are connected by an edge.
Do not forget to flush the output after each guess!
Page 1 of 2

Example

standard input	standard output	Illustration

5 2

5 1 2 3 4 5

2 1 3

FOUND	3

GO 4	3

FOUND	4

GO 2	3

FOUND	2

GO 1	3

FOUND	1

GO 4	3

GO 5	4

FOUND	5

# Note
Empty lines are added to the standard input and the standard output examples for clarity only. They are not present during the actual interaction.
Page 2 of 2

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

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

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

    }
}

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

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

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

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

    vector<vector<int>> paths;
    paths.reserve(m);

    vector<vector<int>> adj(n + 1);
    unordered_set<long long> seen;
    seen.reserve(2048);

    auto addEdge = [&](int u, int v) {
        if (u == v) return;
        int a = min(u, v), b = max(u, v);
        long long key = (long long)a * 1000LL + (long long)b;
        if (seen.insert(key).second) {
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
    };

    for (int i = 0; i < m; ++i) {
        int k = inf.readInt(2, 500, ("k_" + to_string(i + 1)).c_str());
        vector<int> p(k);
        for (int j = 0; j < k; ++j) {
            p[j] = inf.readInt(1, n, ("v_" + to_string(i + 1) + "_" + to_string(j + 1)).c_str());
            if (j && p[j] == p[j - 1]) {

                finish(_fail, "Invalid input: adjacent equal vertices in a path");
            }
        }
        for (int j = 0; j + 1 < k; ++j) addEdge(p[j], p[j + 1]);
        paths.push_back(std::move(p));
    }

    for (int u = 1; u <= n; ++u) {
        sort(adj[u].begin(), adj[u].end());
        adj[u].erase(unique(adj[u].begin(), adj[u].end()), adj[u].end());
    }

    vector<int> secrets;
    secrets.reserve(n);
    if (!inf.seekEof()) {
        for (int i = 0; i < n; ++i) {
            if (inf.seekEof()) break;
            secrets.push_back(inf.readInt(1, n, ("secret_" + to_string(i + 1)).c_str()));
        }
    }
    if ((int)secrets.size() != n) {
        secrets.clear();
        for (int i = 1; i <= n; ++i) secrets.push_back(i);
    }

    const int INF = 1e9;
    vector<vector<int>> dist(n + 1, vector<int>(n + 1, INF));
    for (int s = 1; s <= n; ++s) {
        deque<int> q;
        dist[s][s] = 0;
        q.push_back(s);
        while (!q.empty()) {
            int u = q.front();
            q.pop_front();
            int du = dist[s][u];
            for (int v : adj[u]) {
                if (dist[s][v] > du + 1) {
                    dist[s][v] = du + 1;
                    q.push_back(v);
                }
            }
        }
    }

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

    cout << n << " " << m << endl;
    for (int i = 0; i < m; ++i) {
        cout << (int)paths[i].size();
        for (int v : paths[i]) cout << " " << v;
        cout << endl;
    }
    cout.flush();

    log_metrics();

    for (int round = 0; round < n; ++round) {
        int secret = secrets[round];

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

            long long u_ll = 0;
            if (!parsePositiveInt(tok, u_ll)) {
                finish(_pe, "Malformed token (expected integer vertex id)");
            }
            if (u_ll < 1 || u_ll > n) {
                finish(_pe, "Vertex id out of range");
            }
            int u = (int)u_ll;

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

            if (u == secret) {
                cout << "FOUND" << endl;
                cout.flush();
                break;
            }

            if (dist[u][secret] >= INF) {
                finish(_wa, "Graph appears disconnected (no path to secret)");
            }

            int bestW = -1;
            int du = dist[u][secret];
            for (int w : adj[u]) {
                if (dist[w][secret] < du) {
                    if (bestW == -1 || w < bestW) bestW = w;
                }
            }

            if (bestW == -1) {
                finish(_wa, "No valid GO move exists for this query");
            }

            cout << "GO " << bestW << endl;
            cout.flush();
        }
    }

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

    }
}

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

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

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

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

    query_limit = 10LL * n;
    log_metrics();

    vector<vector<int>> paths;
    paths.reserve(m);

    set<pair<int,int>> edges;
    vector<vector<int>> adj(n + 1);

    auto addEdge = [&](int u, int v) {
        if (u == v) finish(_fail, "Invalid test: self-loop");
        int a = min(u, v), b = max(u, v);
        if (edges.insert({a, b}).second) {
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
    };

    for (int i = 0; i < m; ++i) {
        int k = inf.readInt(2, 500, "k");
        vector<int> p(k);
        for (int j = 0; j < k; ++j) p[j] = inf.readInt(1, n, "v");
        for (int j = 0; j + 1 < k; ++j) addEdge(p[j], p[j + 1]);
        paths.push_back(std::move(p));
    }

    for (int i = 1; i <= n; ++i) {
        sort(adj[i].begin(), adj[i].end());
        adj[i].erase(unique(adj[i].begin(), adj[i].end()), adj[i].end());
    }

    cout << n << " " << m << "\n";
    for (const auto& p : paths) {
        cout << (int)p.size();
        for (int v : p) cout << " " << v;
        cout << "\n";
    }
    cout.flush();

    const int INF = 1e9;
    vector<vector<int>> dist(n + 1, vector<int>(n + 1, INF));
    for (int s = 1; s <= n; ++s) {
        deque<int> q;
        dist[s][s] = 0;
        q.push_back(s);
        while (!q.empty()) {
            int u = q.front();
            q.pop_front();
            for (int v : adj[u]) {
                if (dist[s][v] == INF) {
                    dist[s][v] = dist[s][u] + 1;
                    q.push_back(v);
                }
            }
        }
    }

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

    vector<int> candidates;
    vector<char> inSet(n + 1, 0);

    auto resetRound = [&]() {
        candidates.clear();
        candidates.reserve(n);
        fill(inSet.begin(), inSet.end(), 0);
        for (int v = 1; v <= n; ++v) {
            candidates.push_back(v);
            inSet[v] = 1;
        }
    };

    for (int round = 1; round <= n; ++round) {
        resetRound();
        while (true) {
            string tok;
            if (!(cin >> tok)) finish(_pe, "Unexpected EOF from contestant");
            if (!isAllDigits(tok)) finish(_pe, "Malformed query token (expected integer)");

            long long uu = 0;
            for (char c : tok) {
                uu = uu * 10 + (c - '0');
                if (uu > (long long)n + 10LL) break;
            }
            if (uu < 1 || uu > n) finish(_pe, "Guessed vertex out of range");
            int u = (int)uu;

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

            if ((int)candidates.size() == 1 && candidates[0] == u) {
                cout << "FOUND\n";
                cout.flush();
                break;
            }

            if (adj[u].empty()) {

                finish(_fail, "Invalid test: isolated vertex encountered in interaction");
            }

            int bestW = -1;
            int bestCnt = -1;

            for (int w : adj[u]) {
                int cnt = 0;
                for (int v : candidates) {
                    if (dist[w][v] < dist[u][v]) ++cnt;
                }
                if (cnt > bestCnt || (cnt == bestCnt && w < bestW)) {
                    bestCnt = cnt;
                    bestW = w;
                }
            }

            if (bestCnt <= 0 || bestW == -1) {
                finish(_fail, "Internal error: no valid GO reply keeps feasibility");
            }

            vector<int> nextCandidates;
            nextCandidates.reserve(bestCnt);
            fill(inSet.begin(), inSet.end(), 0);
            for (int v : candidates) {
                if (dist[bestW][v] < dist[u][v]) {
                    nextCandidates.push_back(v);
                    inSet[v] = 1;
                }
            }
            candidates.swap(nextCandidates);

            if (candidates.empty()) finish(_fail, "Internal error: feasibility became empty");

            cout << "GO " << bestW << "\n";
            cout.flush();
        }
    }

    finish(_ok, "OK");
}

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

static void addEdge(vector<pair<int,int>>& edges, int u, int v) {
    ensuref(u != v, "Self-loop is not allowed");
    if (u > v) swap(u, v);
    edges.push_back({u, v});
}

static vector<int> makePermutation(int n) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    for (int i = n - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(p[i], p[j]);
    }
    return p;
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 500);

    int seed = 1;
    if (argc >= 2) {

        seed = atoi(argv[1]);
        if (seed <= 0) seed = 1;
    }

    int n = max(1, min(500, nOpt));
    vector<pair<int,int>> edges;

    if (seed == 1) {

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

        n = 500;
        for (int i = 1; i < n; ++i) addEdge(edges, i, i + 1);
        addEdge(edges, n, 1);
    } else if (seed == 3) {

        n = 500;
        for (int i = 1; i < n; ++i) addEdge(edges, i, i + 1);
    } else {

        if (n == 1) {

        } else if (n == 2) {
            addEdge(edges, 1, 2);
        } else {
            int maxSpare = min(200, n - 3);
            int spare = rnd.next(0, maxSpare);
            int baseLen = n - spare;
            if (baseLen < 3) baseLen = 3;
            if (baseLen > n) baseLen = n;

            for (int i = 1; i < baseLen; ++i) addEdge(edges, i, i + 1);
            addEdge(edges, baseLen, 1);

            int cur = baseLen + 1;
            int extra = n - baseLen;

            while (extra > 0) {
                int attach = rnd.next(1, baseLen);

                int maxLen = min(60, extra);
                int minLen = 1;
                if (rnd.next(0, 99) < 55) {

                    minLen = max(1, min(maxLen, extra / 4));
                }
                int len = (minLen == maxLen) ? minLen : rnd.next(minLen, maxLen);

                int prev = attach;
                for (int i = 0; i < len; ++i) {
                    int v = cur++;
                    addEdge(edges, prev, v);
                    prev = v;
                }
                extra -= len;
            }
        }
    }

    ensuref(n >= 1 && n <= 500, "n out of range");
    ensuref((int)edges.size() <= 500, "Too many edges for m<=500");

    int m = (int)edges.size();
    cout << n << " " << m << "\n";
    for (auto [u, v] : edges) {
        cout << 2 << " " << u << " " << v << "\n";
    }

    if (mode == "non") {

        vector<int> perm = makePermutation(n);
        for (int i = 0; i < n; ++i) {
            if (i) cout << ' ';
            cout << perm[i];
        }
        cout << "\n";
    } else if (mode == "adp") {

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

    return 0;
}