Did you know? During the selection of ISIJ contestants, ISTJs and ISFJs don’t get extra points.

This is an interactive problem.

Kevin is dissatisfied with his MBTI, so he asked Doraemon for a magical machine: the MBTI converter.

The MBTI converter can convert the MBTI attributes of 8 people at a time. It will generate a “random” new MBTI for all individuals based on their initial MBTIs and a 32-bit key $k$ .

Kevin carefully studied this machine and found that the “random” MBTI it generates actually follows a certain pattern. The machine mainly includes three basic structures that shuffle the MBTI: “ xor”, “perm”, and “mix”. Each of these structures takes the MBTIs of 8 individuals as input and outputs 8 MBTIs as a result. In each structure, the input 8 MBTIs are denoted as $i n _ { 0 } , i n _ { 1 } , i n _ { 2 } , \cdots , i n _ { 7 }$ and the output 8 MBTIs are denoted as $o u t _ { 0 } , o u t _ { 1 } , o u t _ { 2 } , \cdot \cdot \cdot , o u t _ { 7 }$ . For convenience, Kevin replaces each MBTI with a hexadecimal number according to the following table.

INFP	INFJ	INTP	INTJ	ISFP	ISFJ	ISTP	ISTJ

0	1	2	3	4	5	6	7

ENFP	ENFJ	ENTP	ENTJ	ESFP	ESFJ	ESTP	ESTJ

8	9	a	b	C	d	e	f

# “xor” Structure:

The xor structure flips certain attributes of the MBTI based on the key $k$ .

Let $k _ { j }$ be the $j$ -th binary bit of the key $k$ ( $0 \leq j < 3 2$ ). The functionality of the xor structure can be expressed as:

$$
o u t _ { i } = i n _ { i } \oplus ( \overline { { k _ { 4 i + 3 } k _ { 4 i + 2 } k _ { 4 i + 1 } k _ { 4 i } } } ) _ { 2 }
$$

where $\bigoplus$ denotes the bitwise XOR1.

# “perm” Structure:

The perm structure replaces the MBTI, where each MBTI is replaced by another fixed MBTI.

The functionality of the perm structure can be expressed as:

$$
o u t _ { i } = p _ { i n _ { i } }
$$

where $p$ is a fixed array of length 16 with the following values:

P0	p1	P2	p3	P4	P5	p6	P7	p8	p9	P10	P11	P12	P13	P14	P15

7	0	5	6	b	f	4	3	1	d	C	e	8	9	a	2

# “mix” Structure:

The mix structure is used to mix the MBTIs of different people, with each output determined by two inputs.

The mix structure requires an intermediate array $t$ of length 8, defined as:

$$
t _ { i } = \left\{ { \begin{array} { l l } { i n _ { i } \ll 1 } & { 0 \leq i n _ { i } < 8 } \\ { ( ( i n _ { i } \oplus 8 ) \ll 1 ) \oplus 3 } & { 8 \leq i n _ { i } < 1 6 } \end{array} } \right.
$$

where $\bigoplus$ denotes the bitwise XOR $\cdot ^ { 1 }$ and $\ll$ denotes logical left shift of four binary digits2.

The functionality of the mix structure can be expressed as:

$$
o u t _ { i } = i n _ { i \gg 1 } \oplus \left( t _ { ( i \gg 1 ) \oplus 1 } \right)
$$

where $\bigoplus$ denotes the bitwise XOR $\cdot ^ { 1 }$ , and $\ggg$ denotes circular right shift of three binary digits3.

The initial 8 MBTIs will sequentially go through 19 structures to produce the final output of 8 MBTIs. These structures are: xor, perm, mix, xor, perm, mix, xor, perm, mix, xor, perm, mix, xor, perm, mix, xor, perm, mix, xor, which is six consecutive rounds of “xor, perm, mix” followed by an “xor”.

Users of this machine typically hope to obtain a specific MBTI. Unfortunately, when Doraemon built this machine, he encapsulated the key $k$ inside the machine and refused to tell Kevin the value of the key. Thus, Kevin turned to you, the clever one. Kevin hopes you can construct some inputs (not exceeding 4096, or the machine may be damaged), test run to obtain the corresponding outputs, and then analyze the value of the key. This way, he can write a program to predict the output for each input, allowing everyone to get their desired MBTI.

Can you accomplish this task?

1 Bitwise XOR refers to performing the modulo 2 addition operation on each corresponding bit of two binary numbers. For example: $( 0 0 1 1 ) _ { 2 } \oplus ( 0 1 0 1 ) _ { 2 } = ( 0 1 1 0 ) _ { 2 }$ .

2 $x \ll y$ means to logically left shift the binary number $x$ by $y$ bits, discarding the overflow and filling the vacated parts with 0. For example: $( 1 1 0 0 ) _ { 2 } \ll 1 = ( 1 0 0 0 ) _ { 2 }$ , $( 1 0 0 1 ) _ { 2 } \ll 1 = ( 0 0 1 0 ) _ { 2 }$ .

3 $x \gg y$ means to circularly right shift the binary number $x$ by $y$ bits. For example: $( 1 0 1 ) _ { 2 } \gg 1 =$ $( 1 1 0 ) _ { 2 }$ , $( 1 1 0 ) _ { 2 } \gg 1 = ( 0 1 1 ) _ { 2 }$ .

# Interaction Protocol

To run the MBTI converter, please output “? in7in6in5in4in3in2in1in0” ( $i n _ { i } \in \{ 0 - 9 , a - f \} )$ , where $i n _ { i }$ is the hexadecimal value corresponding to the $i$ -th input MBTI. You may perform this operation at most 4096 times. After flushing your output, please read the output of the MBTI converter in the format “out7out6out5out4out3out2out1out0” $( o u t _ { i } \in \{ 0 - 9 , a - f \} )$ .

To answer for the value of $k$ , please output “! $k ^ { \prime \prime }$ ( $0 \leq k < 2 ^ { 3 2 }$ ), where $k$ is the decimal representation of the value you believe the key $k$ to be. You may perform this operation at most once. After performing the operation, you should exit your program immediately.

If you run the MBTI converter more than 4096 times, or if your output contains invalid characters, the interactor will output “-1”. Upon receiving such a response, you should immediately exit your program, and you will receive a “Wrong Answer” result. Otherwise, the result is uncertain, as you will attempt to read data from a closed output stream.

To flush your output, you can use:

• fflush(stdout) (if you use printf) or cout.flush() (if you use cout) in C and C++.
• System.out.flush() in Java and Kotlin.
• stdout.flush() in Python.

# Example

standard input	standard output

acf7e10b 105092e0	？ 04f37255 ？ 9090cfca

# Note

The following information might be helpful when solving the problem:

1. There are no spaces between the $i n _ { i }$ s, $o u t _ { i }$ s, so please do not output extra spaces. The output is not a hexadecimal number, so do not ignore leading 0s that may exist.
2. The range of $k$ is $[ 0 , 2 ^ { 3 2 } - 1 ]$ , so please be careful to avoid outputting negative numbers when outputting the answer.
3. The attachment for this problem includes “interact.hpp”, which you may need for local debugging. For its usage, you can refer to the file “local_test_example.cpp” provided in the attachment.
4. The interactor is not adaptive. That is, the value of $k$ in the interactor is fixed before the interaction begins and will not change according to your interactions.
5. There are 64 tests for this problem in total.

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

using namespace std;

static const int P[16] = {7, 0, 5, 6, 0xb, 0xf, 4, 3, 1, 0xd, 0xc, 0xe, 8, 9, 0xa, 2};

static long long HIDDEN_K = 0;
static int queries = 0;
static const int QUERY_LIMIT = 4096;

void log_metrics() {

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

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

int hex2int(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    return -1;
}

char int2hex(int v) {
    if (v >= 0 && v <= 9) return '0' + v;
    if (v >= 10 && v <= 15) return 'a' + (v - 10);
    return '?';
}

void run_machine(vector<int>& state, long long k) {

    for (int round = 0; round < 6; ++round) {

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

            int sub = (k >> (4 * i)) & 0xF;
            state[i] ^= sub;
        }

        for (int i = 0; i < 8; ++i) {
            state[i] = P[state[i]];
        }

        vector<int> t(8);
        for (int i = 0; i < 8; ++i) {
            if (state[i] < 8) {
                t[i] = (state[i] << 1) & 0xF;
            } else {

                int val = state[i];
                val ^= 8;
                val <<= 1;
                val &= 0xF;
                val ^= 3;
                t[i] = val;
            }
        }

        vector<int> next_state(8);
        for (int i = 0; i < 8; ++i) {

            int idx_shifted = ((i >> 1) | ((i & 1) << 2)) & 0x7;

            int term1 = state[idx_shifted];

            int term2 = t[idx_shifted ^ 1];

            next_state[i] = term1 ^ term2;
        }
        state = next_state;
    }

    for (int i = 0; i < 8; ++i) {
        int sub = (k >> (4 * i)) & 0xF;
        state[i] ^= sub;
    }
}

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

    HIDDEN_K = inf.readLong();

    log_metrics();

    string token;
    while (cin >> token) {

        if (token == "!") {
            long long user_k;
            if (!(cin >> user_k)) {
                finish(_pe, "Expected key after '!'");
            }

            if (user_k == HIDDEN_K) {
                finish(_ok, "Correct key");
            } else {
                finish(_wa, "Incorrect key");
            }
        }

        string query_str;
        if (token == "?") {

            if (!(cin >> query_str)) {
                finish(_pe, "Expected query string after '?'");
            }
        } else {

            query_str = token;
        }

        if (queries >= QUERY_LIMIT) {
            cout << "-1" << endl;
            finish(_wa, "Query limit exceeded");
        }

        queries++;
        log_metrics();

        if (query_str.length() != 8) {
            cout << "-1" << endl;
            finish(_wa, "Invalid query string length (must be 8 hex chars)");
        }

        vector<int> state(8);
        bool valid = true;
        for (int i = 0; i < 8; ++i) {

            int val = hex2int(query_str[i]);
            if (val == -1) {
                valid = false;
                break;
            }
            state[7 - i] = val;
        }

        if (!valid) {
            cout << "-1" << endl;
            finish(_wa, "Invalid hex character in query");
        }

        run_machine(state, HIDDEN_K);

        for (int i = 0; i < 8; ++i) {
            cout << int2hex(state[7 - i]);
        }
        cout << endl;
    }

    finish(_wa, "Unexpected EOF: solution exited without providing answer");
}

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

using namespace std;

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

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

    int seed_val = 0;
    if (argc > 1) {
        seed_val = atoi(argv[1]);
    }

    long long k;

    if (mode == "non") {

        if (seed_val == 1) k = 0;
        else if (seed_val == 2) k = 4294967295LL;
        else if (seed_val == 3) k = 0xAAAAAAAA;
        else if (seed_val == 4) k = 0x55555555;
        else if (seed_val == 5) k = 0xFF00FF00;
        else if (seed_val == 6) k = 0x00FF00FF;
        else if (seed_val == 7) k = 0x0F0F0F0F;
        else if (seed_val == 8) k = 0xF0F0F0F0;
        else if (seed_val == 9) k = 0x12345678;
        else if (seed_val == 10) k = (1LL << 31);
        else {

            k = rnd.next(0LL, 4294967295LL);
        }
    } else {

        k = rnd.next(0LL, 4294967295LL);
    }

    cout << k << endl;

    return 0;
}


H. New Year and Snowy Grid

Pay attention to the output section below, where you will see the information about flushing the output.

Bearland is a grid with *h* rows and *w* columns. Rows are numbered 1 through *h* from top to bottom. Columns are numbered 1 through *w* from left to right. Every cell is either allowed (denoted by '.' in the input) or permanently blocked (denoted by '#').

Bearland is a cold land, where heavy snow often makes travelling harder. Every day a few allowed cells are temporarily blocked by snow. Note, that this block works only on this particular day and next day any of these cells might be allowed again (unless there is another temporarily block).

It's possible to move directly between two cells only if they share a side and none of them is permanently or temporarily blocked.

Limak is a little polar bear who lives in Bearland. His house is at the top left cell, while his school is at the bottom right cell. Every day Limak should first go from his house to the school and then return back to his house. Since he gets bored easily, he doesn't want to visit the same cell twice on one day, except for the cell with his house, where he starts and ends. If Limak can reach a school and return home avoiding revisiting cells, he calls a day interesting.

There are *q* days you must process, one after another. For each of these days you should check if it's interesting and print "YES" or "NO" on a separate line. In order to be able to read the description of the next day you should print the answer for the previous one and flush the output.

It's guaranteed that a day with no cells temporarily blocked by snow would be interesting. It's also guaranteed that cells with Limak's house and school are never blocked (neither permanently or temporarily).

Input

The first line of the input contains three integers *h*, *w* and *q* (2 ≤ *h*, *w* ≤ 1000, 1 ≤ *q* ≤ 10 000) — the height and the width of the grid, and the number of days, respectively.

Next *h* lines describe which cells are allowed and which permanently blocked. The *i*-th line contains a string of length *w*, describing the *i*-th row. Every character is either '.' (denoting an allowed cell) or '#' (denoting a permanently blocked cell). It's guaranteed that a day with no cells temporarily blocked by snow would be interesting.

Then, the description of *q* days is given. The description of the *i*-th day starts with a line containing a single integer *k**i* (1 ≤ *k**i* ≤ 10) — the number of cells that are temporarily blocked by snow on that day. Each of next *k**i* lines contains two integers *r**i*, *j* and *c**i*, *j* (1 ≤ *r**i*, *j* ≤ *h*, 1 ≤ *c**i*, *j* ≤ *w*), representing a cell at the intersection of the row *r**i*, *j* and the column *c**i*, *j*. The given *k**i* cells are distinct and none of them is permanently blocked. Also, none of them contains Limak's house or school.

Output

For each of *q* days print "YES" if that day is interesting, and otherwise print "NO", both without the quotes. After printing an answer, you have to both print the end-of-line character and flush the output. Then you can proceed to the next day. You can get Idleness Limit Exceeded if you don't print anything or if you forget to flush the output.

To flush you can use (just after printing a YES/NO 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.

Examples

Input

```
3 5 4
.....
.....
.#...
1
1 4
1
1 5
2
2 4
3 1
2
1 5
3 3
```

Output

```
NO
YES
YES
NO
```

Input

```
9 31 5
...............................
...............................
.###.###.#.###...###.###.#.###.
...#.#.#.#.#.......#.#.#.#...#.
.###.#.#.#.###...###.#.#.#...#.
.#...#.#.#.#.#...#...#.#.#...#.
.###.###.#.###...###.###.#...#.
...............................
...............................
5
6 5
2 11
1 14
8 15
2 14
5
2 14
1 14
8 16
6 5
2 11
3
2 2
1 4
8 30
10
3 1
3 11
5 16
7 21
4 16
3 5
7 31
3 9
7 25
3 27
10
3 1
3 9
7 25
3 27
7 21
4 17
3 5
7 31
4 16
3 11
```

Output

```
NO
YES
YES
YES
NO
```

Note

In the first sample, there are 4 days. Drawings below show how Limak could go to school and return to his home in the second and the third day (on the left and on the right respectively). A permanently blocked cell is painted red, while cells temporarily blocked by snow are painted orange. Black and green arrows should Limak's way to the school and back to the house respectively.

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

For the second sample, below you can see how the grid looks like on each day, where '#' denotes a cell that is blocked, either temporarily or permanently.

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

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

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

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

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

static string to_upper(string s) {
    for (char& ch : s) ch = (char)toupper((unsigned char)ch);
    return s;
}

static bool parse_yes_no(const string& token, bool& value_out) {
    string s = to_upper(token);
    if (s == "YES") {
        value_out = true;
        return true;
    }
    if (s == "NO") {
        value_out = false;
        return true;
    }
    return false;
}

struct DualityChecker {
    int H = 0;
    int W = 0;
    int H2 = 0;
    int W2 = 0;

    vector<int> cc;
    int base_cc_cnt = 0;
    int side1 = 0;
    int side2 = 0;

    unordered_set<uint64_t> edges;

    vector<int> parent;
    vector<int> sz;
    vector<int> touched;

    explicit DualityChecker(int h, int w, const vector<string>& grid) : H(h), W(w) {
        H2 = H + 2;
        W2 = W + 2;

        auto idx = [&](int r, int c) -> int { return r * W2 + c; };
        auto in_range = [&](int r, int c) -> bool { return 0 <= r && r <= H + 1 && 0 <= c && c <= W + 1; };

        vector<unsigned char> allow(H2 * W2, 0);
        cc.assign(H2 * W2, 0);

        for (int r = 1; r <= H; r++) {
            for (int c = 1; c <= W; c++) {
                allow[idx(r, c)] = (grid[r - 1][c - 1] == '#') ? 1 : 0;
            }
        }

        for (int r = 3; r <= H + 1; r++) allow[idx(r, 0)] = 1;
        for (int c = 1; c <= W - 2; c++) allow[idx(H + 1, c)] = 1;
        for (int c = 3; c <= W + 1; c++) allow[idx(0, c)] = 1;
        for (int r = 1; r <= H - 2; r++) allow[idx(r, W + 1)] = 1;

        vector<int> st;
        st.reserve((H + 2) * (W + 2));

        for (int r = 0; r <= H + 1; r++) {
            for (int c = 0; c <= W + 1; c++) {
                int pos = idx(r, c);
                if (!allow[pos] || cc[pos] != 0) continue;
                ++base_cc_cnt;
                cc[pos] = base_cc_cnt;
                st.push_back(pos);
                while (!st.empty()) {
                    int cur = st.back();
                    st.pop_back();
                    int cr = cur / W2;
                    int cc0 = cur % W2;
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = cr + dr;
                            int nc = cc0 + dc;
                            if (!in_range(nr, nc)) continue;
                            int np = idx(nr, nc);
                            if (!allow[np] || cc[np] != 0) continue;
                            cc[np] = base_cc_cnt;
                            st.push_back(np);
                        }
                    }
                }
            }
        }

        side1 = cc[idx(3, 0)];
        side2 = cc[idx(0, 3)];
        if (side1 == 0 || side2 == 0) {
            finish(_fail, "Invalid case: missing SIDE1/SIDE2 components");
        }

        parent.assign(base_cc_cnt + 11, 0);
        sz.assign(base_cc_cnt + 11, 0);

        long long allow_cells = 0;
        for (int v : cc) allow_cells += (v != 0);
        edges.reserve((size_t)min(1LL << 22, max(1LL, allow_cells * 2)));

        for (int r = 0; r <= H + 1; r++) {
            for (int c = 0; c <= W + 1; c++) {
                int a = cc[idx(r, c)];
                if (a == 0) continue;
                for (int dr = 0; dr <= 2; dr++) {
                    for (int dc = -2; dc <= 2; dc++) {
                        if (dr == 0 && dc <= 0) continue;
                        int nr = r + dr;
                        int nc = c + dc;
                        if (!in_range(nr, nc)) continue;
                        int b = cc[idx(nr, nc)];
                        if (b == 0 || b == a) continue;
                        int x = min(a, b);
                        int y = max(a, b);
                        edges.insert((uint64_t)((uint32_t)x) << 32 | (uint32_t)y);
                    }
                }
            }
        }
    }

    void dsu_clear() {
        for (int x : touched) {
            parent[x] = 0;
            sz[x] = 0;
        }
        touched.clear();
    }

    void dsu_init(int x) {
        if (x <= 0 || x >= (int)parent.size()) {
            finish(_fail, "DSU index out of range");
        }
        if (parent[x] != 0) return;
        parent[x] = x;
        sz[x] = 1;
        touched.push_back(x);
    }

    int dsu_find(int x) {
        dsu_init(x);
        while (parent[x] != x) {
            parent[x] = parent[parent[x]];
            x = parent[x];
        }
        return x;
    }

    void dsu_union(int a, int b) {
        a = dsu_find(a);
        b = dsu_find(b);
        if (a == b) return;
        if (sz[a] < sz[b]) swap(a, b);
        parent[b] = a;
        sz[a] += sz[b];
    }

    bool duality(const vector<pair<int, int>>& snow) {
        auto idx = [&](int r, int c) -> int { return r * W2 + c; };
        auto in_range = [&](int r, int c) -> bool { return 0 <= r && r <= H + 1 && 0 <= c && c <= W + 1; };

        dsu_clear();
        dsu_init(side1);
        dsu_init(side2);

        const int next_id = base_cc_cnt + 1;
        vector<int> snow_pos;
        snow_pos.reserve(snow.size());

        for (int i = 0; i < (int)snow.size(); i++) {
            int r = snow[i].first;
            int c = snow[i].second;
            if (r < 1 || r > H || c < 1 || c > W) {
                finish(_fail, "Snow cell out of bounds");
            }
            if ((r == 1 && c == 1) || (r == H && c == W)) {
                finish(_fail, "Snow cell hits start/end");
            }
            int pos = idx(r, c);
            if (cc[pos] != 0) {
                finish(_fail, "Snow cell is permanently blocked or duplicated");
            }
            int id = next_id + i;
            cc[pos] = id;
            snow_pos.push_back(pos);
        }

        for (int i = 0; i < (int)snow.size(); i++) {
            int r = snow[i].first;
            int c = snow[i].second;
            int id = next_id + i;
            dsu_init(id);
            for (int dr = -1; dr <= 1; dr++) {
                for (int dc = -1; dc <= 1; dc++) {
                    int nr = r + dr;
                    int nc = c + dc;
                    if (!in_range(nr, nc)) continue;
                    int b = cc[idx(nr, nc)];
                    if (b != 0) dsu_union(id, b);
                }
            }
        }

        int root1 = dsu_find(side1);
        int root2 = dsu_find(side2);
        bool ok = false;

        if (root1 == root2) {
            ok = true;
        } else {
            vector<int> g1;
            vector<int> g2;
            g1.reserve(touched.size());
            g2.reserve(touched.size());
            for (int x : touched) {
                int rx = dsu_find(x);
                if (rx == root1) g1.push_back(x);
                else if (rx == root2) g2.push_back(x);
            }
            for (int x : g1) {
                if (x > base_cc_cnt) continue;
                for (int y : g2) {
                    if (y > base_cc_cnt) continue;
                    int a = min(x, y);
                    int b = max(x, y);
                    uint64_t key = (uint64_t)((uint32_t)a) << 32 | (uint32_t)b;
                    if (edges.find(key) != edges.end()) {
                        ok = true;
                        break;
                    }
                }
                if (ok) break;
            }
        }

        if (!ok) {
            for (int i = 0; i < (int)snow.size(); i++) {
                int r = snow[i].first;
                int c = snow[i].second;
                int id = next_id + i;
                int rid = dsu_find(id);
                for (int dr = -2; dr <= 2; dr++) {
                    for (int dc = -2; dc <= 2; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (!in_range(nr, nc)) continue;
                        int b = cc[idx(nr, nc)];
                        if (b == 0) continue;
                        int rb = dsu_find(b);
                        if ((rid == root1 && rb == root2) || (rid == root2 && rb == root1)) {
                            ok = true;
                            break;
                        }
                    }
                    if (ok) break;
                }
                if (ok) break;
            }
        }

        for (int pos : snow_pos) cc[pos] = 0;
        return ok;
    }

    bool expected_yes(const vector<pair<int, int>>& snow) {
        return !duality(snow);
    }
};

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

    int H = inf.readInt(2, 1000, "h");
    int W = inf.readInt(2, 1000, "w");
    int Q = inf.readInt(1, 10000, "q");

    vector<string> grid(H);
    for (int r = 0; r < H; r++) {
        grid[r] = inf.readToken();
        if ((int)grid[r].size() != W) finish(_fail, "Grid width mismatch");
        for (char ch : grid[r]) {
            if (ch != '.' && ch != '#') finish(_fail, "Invalid grid character");
        }
    }

    DualityChecker checker(H, W, grid);

    query_limit = Q;
    log_metrics();

    cout << H << " " << W << " " << Q << endl;
    for (int r = 0; r < H; r++) cout << grid[r] << endl;
    cout.flush();

    for (int qi = 0; qi < Q; qi++) {
        int k = inf.readInt(1, 10, "k");
        vector<pair<int, int>> snow(k);
        set<pair<int, int>> seen;
        for (int j = 0; j < k; j++) {
            int r = inf.readInt(1, H, "r");
            int c = inf.readInt(1, W, "c");
            if (!seen.insert({r, c}).second) finish(_fail, "Duplicate cell in query");
            if (grid[r - 1][c - 1] != '.') finish(_fail, "Snow cell on permanently blocked cell");
            if ((r == 1 && c == 1) || (r == H && c == W)) finish(_fail, "Snow cell hits start/end");
            snow[j] = {r, c};
        }

        cout << k << endl;
        for (auto [r, c] : snow) cout << r << " " << c << endl;
        cout.flush();

        string token;
        if (!(cin >> token)) finish(_pe, "Unexpected EOF from contestant");
        bool got_yes = false;
        if (!parse_yes_no(token, got_yes)) finish(_pe, "Expected YES/NO");

        bool exp_yes = checker.expected_yes(snow);
        if (got_yes != exp_yes) finish(_wa, exp_yes ? "Expected YES" : "Expected NO");

        queries++;
        if ((queries & 127) == 0) log_metrics();
    }

    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 << 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 string to_upper(string s) {
    for (char& ch : s) ch = (char)toupper((unsigned char)ch);
    return s;
}

static bool parse_yes_no(const string& token, bool& value_out) {
    string s = to_upper(token);
    if (s == "YES") {
        value_out = true;
        return true;
    }
    if (s == "NO") {
        value_out = false;
        return true;
    }
    return false;
}

struct DualityChecker {
    int H = 0;
    int W = 0;
    int H2 = 0;
    int W2 = 0;

    vector<int> cc;
    int base_cc_cnt = 0;
    int side1 = 0;
    int side2 = 0;

    unordered_set<uint64_t> edges;

    vector<int> parent;
    vector<int> sz;
    vector<int> touched;

    explicit DualityChecker(int h, int w, const vector<string>& grid) : H(h), W(w) {
        H2 = H + 2;
        W2 = W + 2;

        auto idx = [&](int r, int c) -> int { return r * W2 + c; };
        auto in_range = [&](int r, int c) -> bool { return 0 <= r && r <= H + 1 && 0 <= c && c <= W + 1; };

        vector<unsigned char> allow(H2 * W2, 0);
        cc.assign(H2 * W2, 0);

        for (int r = 1; r <= H; r++) {
            for (int c = 1; c <= W; c++) {
                allow[idx(r, c)] = (grid[r - 1][c - 1] == '#') ? 1 : 0;
            }
        }

        for (int r = 3; r <= H + 1; r++) allow[idx(r, 0)] = 1;
        for (int c = 1; c <= W - 2; c++) allow[idx(H + 1, c)] = 1;
        for (int c = 3; c <= W + 1; c++) allow[idx(0, c)] = 1;
        for (int r = 1; r <= H - 2; r++) allow[idx(r, W + 1)] = 1;

        vector<int> st;
        st.reserve((H + 2) * (W + 2));

        for (int r = 0; r <= H + 1; r++) {
            for (int c = 0; c <= W + 1; c++) {
                int pos = idx(r, c);
                if (!allow[pos] || cc[pos] != 0) continue;
                ++base_cc_cnt;
                cc[pos] = base_cc_cnt;
                st.push_back(pos);
                while (!st.empty()) {
                    int cur = st.back();
                    st.pop_back();
                    int cr = cur / W2;
                    int cc0 = cur % W2;
                    for (int dr = -1; dr <= 1; dr++) {
                        for (int dc = -1; dc <= 1; dc++) {
                            int nr = cr + dr;
                            int nc = cc0 + dc;
                            if (!in_range(nr, nc)) continue;
                            int np = idx(nr, nc);
                            if (!allow[np] || cc[np] != 0) continue;
                            cc[np] = base_cc_cnt;
                            st.push_back(np);
                        }
                    }
                }
            }
        }

        side1 = cc[idx(3, 0)];
        side2 = cc[idx(0, 3)];
        if (side1 == 0 || side2 == 0) {
            finish(_fail, "Invalid case: missing SIDE1/SIDE2 components");
        }

        parent.assign(base_cc_cnt + 11, 0);
        sz.assign(base_cc_cnt + 11, 0);

        long long allow_cells = 0;
        for (int v : cc) allow_cells += (v != 0);
        edges.reserve((size_t)min(1LL << 22, max(1LL, allow_cells * 2)));

        for (int r = 0; r <= H + 1; r++) {
            for (int c = 0; c <= W + 1; c++) {
                int a = cc[idx(r, c)];
                if (a == 0) continue;
                for (int dr = 0; dr <= 2; dr++) {
                    for (int dc = -2; dc <= 2; dc++) {
                        if (dr == 0 && dc <= 0) continue;
                        int nr = r + dr;
                        int nc = c + dc;
                        if (!in_range(nr, nc)) continue;
                        int b = cc[idx(nr, nc)];
                        if (b == 0 || b == a) continue;
                        int x = min(a, b);
                        int y = max(a, b);
                        edges.insert((uint64_t)((uint32_t)x) << 32 | (uint32_t)y);
                    }
                }
            }
        }
    }

    void dsu_clear() {
        for (int x : touched) {
            parent[x] = 0;
            sz[x] = 0;
        }
        touched.clear();
    }

    void dsu_init(int x) {
        if (x <= 0 || x >= (int)parent.size()) {
            finish(_fail, "DSU index out of range");
        }
        if (parent[x] != 0) return;
        parent[x] = x;
        sz[x] = 1;
        touched.push_back(x);
    }

    int dsu_find(int x) {
        dsu_init(x);
        while (parent[x] != x) {
            parent[x] = parent[parent[x]];
            x = parent[x];
        }
        return x;
    }

    void dsu_union(int a, int b) {
        a = dsu_find(a);
        b = dsu_find(b);
        if (a == b) return;
        if (sz[a] < sz[b]) swap(a, b);
        parent[b] = a;
        sz[a] += sz[b];
    }

    bool duality(const vector<pair<int, int>>& snow) {
        auto idx = [&](int r, int c) -> int { return r * W2 + c; };
        auto in_range = [&](int r, int c) -> bool { return 0 <= r && r <= H + 1 && 0 <= c && c <= W + 1; };

        dsu_clear();
        dsu_init(side1);
        dsu_init(side2);

        const int next_id = base_cc_cnt + 1;
        vector<int> snow_pos;
        snow_pos.reserve(snow.size());

        for (int i = 0; i < (int)snow.size(); i++) {
            int r = snow[i].first;
            int c = snow[i].second;
            if (r < 1 || r > H || c < 1 || c > W) {
                finish(_fail, "Snow cell out of bounds");
            }
            if ((r == 1 && c == 1) || (r == H && c == W)) {
                finish(_fail, "Snow cell hits start/end");
            }
            int pos = idx(r, c);
            if (cc[pos] != 0) {
                finish(_fail, "Snow cell is permanently blocked or duplicated");
            }
            int id = next_id + i;
            cc[pos] = id;
            snow_pos.push_back(pos);
        }

        for (int i = 0; i < (int)snow.size(); i++) {
            int r = snow[i].first;
            int c = snow[i].second;
            int id = next_id + i;
            dsu_init(id);
            for (int dr = -1; dr <= 1; dr++) {
                for (int dc = -1; dc <= 1; dc++) {
                    int nr = r + dr;
                    int nc = c + dc;
                    if (!in_range(nr, nc)) continue;
                    int b = cc[idx(nr, nc)];
                    if (b != 0) dsu_union(id, b);
                }
            }
        }

        int root1 = dsu_find(side1);
        int root2 = dsu_find(side2);
        bool ok = false;

        if (root1 == root2) {
            ok = true;
        } else {
            vector<int> g1;
            vector<int> g2;
            g1.reserve(touched.size());
            g2.reserve(touched.size());
            for (int x : touched) {
                int rx = dsu_find(x);
                if (rx == root1) g1.push_back(x);
                else if (rx == root2) g2.push_back(x);
            }
            for (int x : g1) {
                if (x > base_cc_cnt) continue;
                for (int y : g2) {
                    if (y > base_cc_cnt) continue;
                    int a = min(x, y);
                    int b = max(x, y);
                    uint64_t key = (uint64_t)((uint32_t)a) << 32 | (uint32_t)b;
                    if (edges.find(key) != edges.end()) {
                        ok = true;
                        break;
                    }
                }
                if (ok) break;
            }
        }

        if (!ok) {
            for (int i = 0; i < (int)snow.size(); i++) {
                int r = snow[i].first;
                int c = snow[i].second;
                int id = next_id + i;
                int rid = dsu_find(id);
                for (int dr = -2; dr <= 2; dr++) {
                    for (int dc = -2; dc <= 2; dc++) {
                        int nr = r + dr;
                        int nc = c + dc;
                        if (!in_range(nr, nc)) continue;
                        int b = cc[idx(nr, nc)];
                        if (b == 0) continue;
                        int rb = dsu_find(b);
                        if ((rid == root1 && rb == root2) || (rid == root2 && rb == root1)) {
                            ok = true;
                            break;
                        }
                    }
                    if (ok) break;
                }
                if (ok) break;
            }
        }

        for (int pos : snow_pos) cc[pos] = 0;
        return ok;
    }

    bool expected_yes(const vector<pair<int, int>>& snow) {
        return !duality(snow);
    }
};

static uint64_t fnv1a_64(uint64_t seed, const string& s) {
    uint64_t h = seed;
    for (unsigned char ch : s) {
        h ^= (uint64_t)ch;
        h *= 1099511628211ULL;
    }
    return h;
}

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

    int H = inf.readInt(2, 1000, "h");
    int W = inf.readInt(2, 1000, "w");
    int Q = inf.readInt(1, 10000, "q");

    vector<string> grid(H);
    for (int r = 0; r < H; r++) {
        grid[r] = inf.readToken();
        if ((int)grid[r].size() != W) finish(_fail, "Grid width mismatch");
        for (char ch : grid[r]) {
            if (ch != '.' && ch != '#') finish(_fail, "Invalid grid character");
        }
    }

    vector<pair<int, int>> allowed;
    allowed.reserve((size_t)H * (size_t)W);
    for (int r = 1; r <= H; r++) {
        for (int c = 1; c <= W; c++) {
            if ((r == 1 && c == 1) || (r == H && c == W)) continue;
            if (grid[r - 1][c - 1] == '.') allowed.push_back({r, c});
        }
    }
    if (allowed.empty()) finish(_fail, "No allowed cells for queries");

    DualityChecker checker(H, W, grid);

    uint64_t seed = 1469598103934665603ULL;
    seed ^= (uint64_t)H;
    seed *= 1099511628211ULL;
    seed ^= (uint64_t)W;
    seed *= 1099511628211ULL;
    seed ^= (uint64_t)Q;
    seed *= 1099511628211ULL;
    for (const string& row : grid) seed = fnv1a_64(seed, row);
    mt19937_64 rng(seed);

    query_limit = Q;
    log_metrics();

    cout << H << " " << W << " " << Q << endl;
    for (int r = 0; r < H; r++) cout << grid[r] << endl;
    cout.flush();

    for (int qi = 0; qi < Q; qi++) {
        int k_max = min(10, (int)allowed.size());
        uniform_int_distribution<int> kdist(1, k_max);
        int k = kdist(rng);

        vector<int> picked;
        picked.reserve(k);
        while ((int)picked.size() < k) {
            int idx = (int)(rng() % (uint64_t)allowed.size());
            bool ok = true;
            for (int x : picked) {
                if (x == idx) {
                    ok = false;
                    break;
                }
            }
            if (ok) picked.push_back(idx);
        }
        sort(picked.begin(), picked.end());

        vector<pair<int, int>> snow;
        snow.reserve(k);
        for (int idx : picked) snow.push_back(allowed[idx]);

        cout << k << endl;
        for (auto [r, c] : snow) cout << r << " " << c << endl;
        cout.flush();

        string token;
        if (!(cin >> token)) finish(_pe, "Unexpected EOF from contestant");
        bool got_yes = false;
        if (!parse_yes_no(token, got_yes)) finish(_pe, "Expected YES/NO");

        bool exp_yes = checker.expected_yes(snow);
        if (got_yes != exp_yes) finish(_wa, exp_yes ? "Expected YES" : "Expected NO");

        queries++;
        if ((queries & 127) == 0) log_metrics();
    }

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

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

void ensure_valid(int H, int W, vector<string>& grid) {

    for(int c = 0; c < W; c++) grid[0][c] = '.';
    for(int r = 0; r < H; r++) grid[r][W-1] = '.';

    for(int r = 0; r < H; r++) grid[r][0] = '.';
    for(int c = 0; c < W; c++) grid[H-1][c] = '.';

    grid[0][0] = '.';
    grid[H-1][W-1] = '.';
}

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

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

    int H = opt<int>("h", rnd.next(2, 1000));
    int W = opt<int>("w", rnd.next(2, 1000));
    int Q = opt<int>("q", rnd.next(1, 10000));

    long long seed = atoll(argv[1]);
    bool manual = has_opt("h") || has_opt("w") || has_opt("q");
    if (!manual) {
        if (seed == 1) { H = 2; W = 2; Q = 5; }
        else if (seed == 2) { H = 1000; W = 1000; Q = 5; }
        else if (seed == 3) { H = 50; W = 50; Q = 10000; }
    }

    vector<string> grid(H, string(W, '.'));

    int type = rnd.next(0, 2);

    if (type == 0) {
        int density = rnd.next(10, 60);
        for(int r=0; r<H; r++)
            for(int c=0; c<W; c++)
                if (rnd.next(100) < density) grid[r][c] = '#';
    } else if (type == 1) {

        for(int r=0; r<H; r++) fill(grid[r].begin(), grid[r].end(), '.');
        int barriers = rnd.next(1, 3);
        for(int b=0; b<barriers; b++) {
            int diag = rnd.next(2, H+W-3);
            for(int r=0; r<H; r++) {
                int c = diag - r;
                if (c >= 0 && c < W) grid[r][c] = '#';
            }
        }
    } else {

        int density = rnd.next(50, 80);
        for(int r=0; r<H; r++)
            for(int c=0; c<W; c++)
                if (rnd.next(100) < density) grid[r][c] = '#';
    }

    ensure_valid(H, W, grid);

    cout << H << " " << W << " " << Q << "\n";
    for(int r=0; r<H; r++) {
        cout << grid[r] << "\n";
    }

    if (mode == "adp") {
        return 0;
    }

    vector<pair<int,int>> allowed;
    for(int r=0; r<H; r++) {
        for(int c=0; c<W; c++) {
            if ((r==0 && c==0) || (r==H-1 && c==W-1)) continue;
            if (grid[r][c] == '#') continue;
            allowed.push_back({r + 1, c + 1});
        }
    }

    for(int i=0; i<Q; i++) {
        int k = rnd.next(1, 10);
        if (k > (int)allowed.size()) k = (int)allowed.size();

        cout << k << "\n";

        set<int> picked;
        while((int)picked.size() < k) {
            picked.insert(rnd.next(0, (int)allowed.size() - 1));
        }

        for(int idx : picked) {
            cout << allowed[idx].first << " " << allowed[idx].second << "\n";
        }
    }

    return 0;
}


This is an interactive problem.

As is well known, the city "E" has never had its roads repaired in its a thousand and a half years old history. And only recently the city administration repaired some of them.

It is known that in total in the city "E" there are $n$ intersections and $m$ roads, which can be used in both directions, numbered with integers from $1$ to $m$. The $i$-th road connects intersections with numbers $a_i$ and $b_i$.

Among all $m$ roads, some subset of the roads has been repaired, but you do not know which one. The only information you could get from the city's road services is that you can get from any intersection to any other intersection by driving only on the roads that have been repaired.

You are a young entrepreneur, and decided to organize a delivery service of fresh raw meat in the city "E" (in this city such meat is called "steaks", it is very popular among the locals). You have already recruited a staff of couriers, but the couriers are willing to travel only on repaired roads. Now you have to find out which roads have already been repaired.

The city administration has given you the city for a period of time, so you can make different queries of one of three types:

1. Block the road with the number $x$. In this case, movement on the road for couriers will be forbidden. Initially all roads are unblocked.
2. Unblock the road with the number $x$. In this case, couriers will be able to move on the road $x$ if it is repaired.
3. Try to deliver the order to the intersection with the number $y$. In this case, one of your couriers will start moving from intersection with number $s$ you don't know and deliver the order to intersection with number $y$ if there is a path on unblocked repaired roads from intersection $s$ to intersection $y$. It is guaranteed that intersection $s$ will be chosen beforehand.

Unfortunately, the city is placed at your complete disposal for a short period of time, so you can make no more than $100 \cdot m$ requests.

Input

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

The first line contains two integers $n$ and $m$ ($2 \le n \le 2\,000$, $n - 1 \le m \le 2\,000$) —the number of intersections and roads in the city "E".

Each of the following $m$ lines describes one road. The $i$-th of these lines contains two integers $a_i$ and $b_i$ ($1 \le a_i, b_i \le n$) — the ends of the $i$-th road. It is guaranteed that no road connects the city to itself, while it is possible that there are several roads between a pair of different intersections.

It is guaranteed that the sum of $n$ and the sum of $m$ over all test cases does not exceed $2\,000$.

Interaction

Once you have read the description of the test case, you can make queries. Queries can be of three types:

1. "- $x$" ($1 \le x \le m$). In this case the road with the number $x$ is blocked if it has not already been blocked.
2. "+ $x$" ($1 \le x \le m$). In this case the road with the number $x$ is unblocked. Note that road $x$ must be blocked beforehand. All roads are initially unblocked.
3. "? $y$" ($1 \le y \le n$). In this case the jury program chooses some city $s$. If you can get from town $s$ to town $y$ by unblocked repaired roads, the jury program will output $1$, otherwise the jury program will output $0$. Note that city $s$ will be selected before getting information about city $y$, but your previous requests may be taken into account when selecting city $s$.

In total, you can make no more than $100 \cdot m$ queries for each set of input data.

After you have found all repaired roads, output "! $c_1,\ c_2,\ c_3,\ \ldots,\ c_m$", where $c_i$ is $1$ if road $i$ is repaired, and $0$ if road is not repaired. This output will not count in the total number of queries. The jury program will output $1$ if your answer is correct, and $0$ if the answer is not correct. If you received $0$, your program must terminate immediately to receive a Wrong Answer verdict. Otherwise you can get any verdict, because the program will continue reading from the closed stream. If you read $1$, move on to the next test case, or terminate the program if there is none.

Note that you do not have to unblock all roads before outputting the answer. It is guaranteed that all repaired roads are fixed initially and will not be changed by the jury program depending on queries.

After outputting 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 the documentation for other languages.

Example

Input

```
2
2 2
1 2
2 1

1

0

1

1
3 3
1 2
2 3
3 1

1

1

1

0

1

1

1

1
```

Output

```
- 1
? 1

? 2

- 2
+ 1
? 1

! 1 0

- 1
? 2

? 1

- 2
? 3

? 3

+ 1
? 3

? 2

? 1

! 1 1 1
```

Note

In the first test case, road $1$ was repaired, while road $2$ was not. For the first delivery request, intersection $1$ was selected as $s$, and the path from intersection $1$ to $1$ exists. For the second delivery request, intersection $1$ was selected as $s$. Since the only repaired road was blocked, there was no path between intersections $1$ and $2$. For the third delivery request, intersection $2$ was selected as $s$, the path between intersections $2$ and $1$ exists along road $1$, which is repaired and unblocked.

In the second test case, intersections $1$, $3$, $1$, $2$, $2$, $3$, $1$ were selected as starting intersections for delivery requests.

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

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

void log_metrics() {

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

    }
}

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

struct Edge {
    int u, v;
};

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    mt19937 rng(5489u);

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

    const long long HARD_CAP = 500000;

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

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

        query_limit += 100LL * m;

        log_metrics();

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

        vector<int> repaired(m);
        for(int i = 0; i < m; ++i) {
            repaired[i] = inf.readInt();
        }

        cout << n << " " << m << endl;
        for(const auto& e : edges) {
            cout << e.u << " " << e.v << endl;
        }
        cout.flush();

        vector<vector<pair<int, int>>> adj(n + 1);
        for(int i = 0; i < m; ++i) {
            adj[edges[i].u].push_back({edges[i].v, i});
            adj[edges[i].v].push_back({edges[i].u, i});
        }

        vector<bool> blocked(m, false);

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

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

                finish(_wa, "Unexpected EOF (solution exited early?)");
            }

            if (token == "+") {
                int x;
                if (!(cin >> x)) finish(_pe, "Expected integer after +");
                queries++;

                if (x < 1 || x > m) finish(_pe, "Road index out of range");
                blocked[x-1] = false;

            } else if (token == "-") {
                int x;
                if (!(cin >> x)) finish(_pe, "Expected integer after -");
                queries++;

                if (x < 1 || x > m) finish(_pe, "Road index out of range");
                blocked[x-1] = true;

            } else if (token == "?") {
                int y;
                if (!(cin >> y)) finish(_pe, "Expected integer after ?");
                queries++;

                if (y < 1 || y > n) finish(_pe, "Intersection index out of range");

                int s = uniform_int_distribution<int>(1, n)(rng);

                bool reachable = false;
                if (s == y) {
                    reachable = true;
                } else {
                    queue<int> q;
                    q.push(s);
                    vector<bool> vis(n + 1, false);
                    vis[s] = true;

                    while(!q.empty()) {
                        int u = q.front(); q.pop();
                        if (u == y) {
                            reachable = true;
                            break;
                        }
                        for(auto& edge : adj[u]) {
                            int v = edge.first;
                            int id = edge.second;

                            if (!vis[v] && repaired[id] == 1 && !blocked[id]) {
                                vis[v] = true;
                                q.push(v);
                            }
                        }
                    }
                }

                cout << (reachable ? 1 : 0) << endl;

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

                vector<int> ans(m);
                bool correct = true;
                for(int i = 0; i < m; ++i) {
                    if (!(cin >> ans[i])) finish(_pe, "Expected m integers in answer");
                    if (ans[i] != repaired[i]) {
                        correct = false;
                    }
                }

                if (correct) {
                    cout << 1 << endl;
                    break;
                } else {
                    cout << 0 << endl;
                    finish(_wa, "Incorrect answer mask");
                }

            } else {
                finish(_pe, "Invalid query token: " + token);
            }

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

    finish(_ok, "All cases passed");
    return 0;
}

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

long long global_queries = 0;
long long global_limit = 0;

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

    }
}

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

mt19937 rng(1819);

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

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

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

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

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

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

        struct Edge { int u, v; };
        vector<Edge> edges;
        vector<vector<int>> adj(n + 1);
        edges.reserve(m);

        for(int j = 0; j < m; ++j) {
            int u = inf.readInt();
            int v = inf.readInt();
            edges.push_back({u, v});
            adj[u].push_back(j);
            adj[v].push_back(j);

            cout << u << " " << v << endl;
        }

        vector<int> repaired(m);
        for(int j = 0; j < m; ++j) {
            repaired[j] = inf.readInt();
        }

        vector<int> blocked(m, 0);

        long long local_limit = 100LL * m;
        global_limit += local_limit;
        long long local_queries = 0;

        log_metrics();

        bool case_active = true;
        while(case_active) {
            string type;
            if (!(cin >> type)) {
                finish(_pe, "Unexpected end of file reading query type");
            }

            if (type == "+" || type == "-") {
                int x;
                if (!(cin >> x)) finish(_pe, "Expected road index");
                if (x < 1 || x > m) finish(_pe, "Invalid road index");

                blocked[x-1] = (type == "-");

                local_queries++;
                global_queries++;
            }
            else if (type == "?") {
                int y;
                if (!(cin >> y)) finish(_pe, "Expected intersection index");
                if (y < 1 || y > n) finish(_pe, "Invalid intersection index");

                int s = std::uniform_int_distribution<int>(1, n)(rng);

                bool found = false;
                if (s == y) {
                    found = true;
                } else {
                    queue<int> q;
                    q.push(s);
                    vector<bool> vis(n + 1, false);
                    vis[s] = true;

                    while(!q.empty()) {
                        int curr = q.front(); q.pop();
                        if (curr == y) { found = true; break; }

                        for(int e_idx : adj[curr]) {
                            if (repaired[e_idx] && !blocked[e_idx]) {
                                int nxt = (edges[e_idx].u == curr ? edges[e_idx].v : edges[e_idx].u);
                                if (!vis[nxt]) {
                                    vis[nxt] = true;
                                    q.push(nxt);
                                }
                            }
                        }
                    }
                }

                cout << (found ? 1 : 0) << endl;
                local_queries++;
                global_queries++;
            }
            else if (type == "!") {
                vector<int> ans(m);
                bool ok = true;
                for(int j = 0; j < m; ++j) {
                    if (!(cin >> ans[j])) finish(_pe, "Failed to read answer mask");
                    if (ans[j] != repaired[j]) ok = false;
                }

                if (ok) {
                    cout << 1 << endl;
                    case_active = false;
                } else {
                    cout << 0 << endl;
                    finish(_wa, "Incorrect repaired roads mask");
                }
            }
            else {
                finish(_pe, "Unknown query type");
            }

            if (local_queries > local_limit) {
                finish(_wa, "Query limit exceeded for this test case");
            }

            if (global_queries > 500000) {
                finish(_pe, "Hard query limit exceeded (infinite loop?)");
            }

            if (global_queries % 100 == 0) log_metrics();
        }
    }

    finish(_ok, "All cases passed");
    return 0;
}

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

using namespace std;

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

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

    const int TOTAL_BUDGET = 2000;
    int used_budget = 0;

    struct TestCase {
        int n, m;
        vector<pair<int, int>> edges;
        vector<int> repaired;
    };
    vector<TestCase> cases;

    while (used_budget <= TOTAL_BUDGET - 3) {
        int rem = TOTAL_BUDGET - used_budget;

        int n;

        if (cases.empty() && rnd.next(3) == 0) {

            int max_n = (rem + 1) / 2;
            max_n = min(max_n, 2000);
            if (max_n < 2) max_n = 2;
            n = rnd.next(2, max_n);
        } else {

            int max_n = (rem + 1) / 2;

            int cap = (mode == "adp" ? 60 : 40);
            n = rnd.next(2, min(max_n, cap));
        }

        int min_m = n - 1;
        int max_m = rem - n;

        if (max_m < min_m) break;

        int m = rnd.next(min_m, max_m);

        used_budget += (n + m);

        int type = 0;

        if (mode == "adp") {

            int r = rnd.next(100);
            if (r < 60) type = 1;
            else if (r < 80) type = 2;
            else type = 0;
        } else {

            int r = rnd.next(100);
            if (r < 70) type = 0;
            else if (r < 85) type = 1;
            else type = 2;
        }

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

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

        if (type == 1) {
            for(int i = 0; i < n - 1; ++i) {
                edges.push_back({p[i], p[i+1]});
                repaired.push_back(1);
            }
        } else if (type == 2) {
            for(int i = 1; i < n; ++i) {
                edges.push_back({p[0], p[i]});
                repaired.push_back(1);
            }
        } else {
            for(int i = 1; i < n; ++i) {

                int parent = rnd.next(0, i - 1);
                edges.push_back({p[i], p[parent]});
                repaired.push_back(1);
            }
        }

        int extra = m - (n - 1);
        for(int i = 0; i < extra; ++i) {
            int u = rnd.next(1, n);
            int v = rnd.next(1, n);
            while (u == v) {
                v = rnd.next(1, n);
            }
            edges.push_back({u, v});

            if (mode == "adp") {

                repaired.push_back(rnd.next(10) == 0 ? 1 : 0);
            } else {

                repaired.push_back(rnd.next(2));
            }
        }

        vector<int> perm(m);
        iota(perm.begin(), perm.end(), 0);
        shuffle(perm.begin(), perm.end());

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

        for(int idx : perm) {
            final_edges.push_back(edges[idx]);
            final_repaired.push_back(repaired[idx]);
        }

        cases.push_back({n, m, final_edges, final_repaired});
    }

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

        for(int i = 0; i < c.m; ++i) {
            cout << c.repaired[i] << (i == c.m - 1 ? "" : " ");
        }
        cout << endl;
    }

    return 0;
}


Let us call a point of the plane admissible if its coordinates are positive integers less than or equal to $200$.

There is an invisible rectangle such that:

* its vertices are all admissible;
* its sides are parallel to the coordinate axes;
* its area is strictly positive.

Your task is to guess the perimeter of this rectangle.

In order to guess it, you may ask at most $4$ queries.

In each query, you choose a nonempty subset of the admissible points and you are told how many of the chosen points are inside or on the boundary of the invisible rectangle.

Interaction

To ask a query (of the kind described in the statement), you shall print two lines:

* In the first line print "? $k$" (without the quotes) where $k$ ($k\ge 1$) is the number of chosen points.
* In the second line print $2k$ integers $x_1,\, y_1,\, x_2,\, y_2,\, \dots,\, x_k,\, y_k$ ($1\le x_i,y_i\le 200$ for $i=1,2,\dots,k$) where $(x_1, y_1),\,(x_2, y_2),\,(x_3, y_3),\, \dots,\,(x_k, y_k)$ are the $k$ distinct admissible chosen points (the order of the points is not important).

After this, you should read an integer — the number of chosen points that are inside or on the boundary of the invisible rectangle.

When you have identified the perimeter $p$ of the invisible rectangle, you must print "! $p$" (without quotes) and terminate your program.

If you ask more than $4$ queries or if one of the queries is malformed, the interactor terminates immediately and your program receives verdict Wrong Answer.

The interactor may be adaptive (i.e., the hidden rectangle may not be chosen before the beginning of the interaction).

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.

Examples

Input

```
13 5 123 80
```

Output

Input

```
2 2 4 4
```

Output

Input

```
1 1 200 200
```

Output

Note

The following is an example of interaction for the first sample intended to show the format of the queries.

 \begin{array}{l|l|l} \text{Query (contestant program)} & \text{Answer (interactor)} & \text{Explanation} \\ \hline \mathtt{?\ 4} & & \text{We choose the $4$ vertices of} \\ \mathtt{13\ 5\ 13\ 80\ 123\ 5\ 123\ 80} & \mathtt{4} &\text{the hidden rectangle.}\\ \hline \mathtt{?\ 5} & & \text{We choose $4$ points just outside the hidden}\\ \mathtt{100\ 4\ 100\ 81\ 12\ 40\ 124\ 40\ 50\ 50} & \mathtt{1}& \text{rectangle and also the point $(50,50)$.}\\ \hline \mathtt{?\ 2} & & \text{We choose the points $(1, 1)$} \\ \mathtt{200\ 200\ 1\ 1} & \mathtt{0} & \text{and $(200,200)$.}\\ \hline \mathtt{!\ 370} & & \text{This is the correct perimeter.} \end{array}

For the second sample, a possible interaction is the following.

 \begin{array}{l|l|l} \text{Query (contestant program)} & \text{Answer (interactor)} & \text{Explanation} \\ \hline \mathtt{?\ 4} & & \text{We choose the points $(3, 2)$, $(4, 1)$,} \\ \mathtt{3\ 2\ 4\ 1\ 5\ 2\ 4\ 3} & 2 & \text{$(5, 2)$ and $(4, 3)$.} \\ \hline \mathtt{?\ 7} & & \text{We choose the points $(1, 4)$, $(2, 4)$,} \\ \mathtt{1\ 4\ 2\ 4\ 1\ 5\ 2\ 5\ 5\ 5\ 5\ 6\ 6\ 5} & 1 & \text{$(1, 5)$, $(2, 5)$, $(5, 5)$, $(5, 6)$ and $(6, 5)$.} \\ \hline \mathtt{!\ 8} & & \text{This is the correct perimeter.} \end{array}  The situation is shown in the following picture: ![](https://espresso.codeforces.com/48058721d325b8816be56f22859d6ad002db127f.png)

The green points are the ones belonging to the first query, while the orange points are the ones belonging to the second query. One can see that there are exactly two rectangles consistent with the interactor's answers:

* the rectangle of vertices $(2, 2)$ and $(4, 4)$, shown in red;
* the rectangle of vertices $(4, 2)$ and $(5, 5)$, shown in blue.

Since both of these rectangles have perimeter $8$, this is the final answer.

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

using namespace std;

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

static int hx1, hy1, hx2, hy2;

static const int HARD_CAP = 50;

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

    hx1 = inf.readInt(1, 200, "hx1");
    hy1 = inf.readInt(1, 200, "hy1");
    hx2 = inf.readInt(1, 200, "hx2");
    hy2 = inf.readInt(1, 200, "hy2");

    if (hx1 > hx2) swap(hx1, hx2);
    if (hy1 > hy2) swap(hy1, hy2);

    while (true) {

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

            finish(_wa, "Unexpected EOF: contestant terminated without providing an answer");
        }

        if (token == "!") {

            long long p;
            if (!(cin >> p)) {
                finish(_wa, "Expected integer perimeter after '!'");
            }

            long long width = hx2 - hx1;
            long long height = hy2 - hy1;
            long long true_p = 2 * (width + height);

            if (p == true_p) {
                finish(_ok, "Correct perimeter " + to_string(p));
            } else {
                finish(_wa, "Wrong perimeter. Expected " + to_string(true_p) + ", got " + to_string(p));
            }
        } else {

            queries++;

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

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

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

                if (!(cin >> k)) {
                    finish(_wa, "Expected integer k after '?'");
                }
            } else {

                try {
                    k = stoi(token);
                } catch (...) {
                    finish(_wa, "Invalid query start token: '" + token + "' (expected '?' or integer k)");
                }
            }

            if (k < 1) {
                finish(_wa, "Invalid number of points k=" + to_string(k) + " (must be >= 1)");
            }

            int count = 0;
            for (int i = 0; i < k; ++i) {
                int x, y;
                if (!(cin >> x >> y)) {
                    finish(_wa, "Expected " + to_string(k) + " points, but input ended early");
                }

                if (x < 1 || x > 200 || y < 1 || y > 200) {
                    finish(_wa, "Point (" + to_string(x) + "," + to_string(y) + ") is out of admissible range [1, 200]");
                }

                if (x >= hx1 && x <= hx2 && y >= hy1 && y <= hy2) {
                    count++;
                }
            }

            cout << count << endl;
        }
    }

    return 0;
}

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

using namespace std;

const int MAX_COORD = 200;
const int QUERY_LIMIT = 4;

static long long queries = 0;
static long long query_limit = QUERY_LIMIT;
static bool adaptive = false;

struct Rect {
    int x1, y1, x2, y2;

    int perimeter() const {
        return 2 * ((x2 - x1) + (y2 - y1));
    }

    int query_count(const vector<vector<int>>& pref) const {
        return pref[x2][y2] - pref[x1 - 1][y2] - pref[x2][y1 - 1] + pref[x1 - 1][y1 - 1];
    }
};

vector<Rect> pool;

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

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

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

    int hx1 = inf.readInt();
    int hy1 = inf.readInt();
    int hx2 = inf.readInt();
    int hy2 = inf.readInt();

    if (hx1 == 0 && hy1 == 0 && hx2 == 0 && hy2 == 0) {
        adaptive = true;
    } else {
        adaptive = false;

        if (hx1 > hx2) swap(hx1, hx2);
        if (hy1 > hy2) swap(hy1, hy2);
        pool.push_back({hx1, hy1, hx2, hy2});
    }

    if (adaptive) {

        int target_size = 300000;
        pool.reserve(target_size + 10);

        for(int i = 0; i < target_size; ++i) {
            int rx1 = rnd.next(1, MAX_COORD);
            int rx2 = rnd.next(1, MAX_COORD);

            if(rx1 == rx2) {
                if(rx2 < MAX_COORD) rx2++; else rx1--;
            }
            if(rx1 > rx2) swap(rx1, rx2);

            int ry1 = rnd.next(1, MAX_COORD);
            int ry2 = rnd.next(1, MAX_COORD);

            if(ry1 == ry2) {
                if(ry2 < MAX_COORD) ry2++; else ry1--;
            }
            if(ry1 > ry2) swap(ry1, ry2);

            pool.push_back({rx1, ry1, rx2, ry2});
        }

        pool.push_back({1, 1, 200, 200});

        pool.push_back({1, 1, 2, 2});

        pool.push_back({1, 1, 2, 200});
        pool.push_back({1, 1, 200, 2});
    }

    while (true) {
        string type;

        if (!(cin >> type)) {

            finish(_wa, "Unexpected EOF");
        }

        if (type == "!") {
            long long ans;
            if (!(cin >> ans)) finish(_wa, "Expected perimeter after '!'");

            if (pool.empty()) {
                finish(_wa, "No consistent rectangles left (contestant forced invalid state)");
            }

            for (const auto& r : pool) {
                if (r.perimeter() != ans) {
                    string s = "Wrong answer. Found consistent rectangle with perimeter " + to_string(r.perimeter())
                             + ", but contestant guessed " + to_string(ans);
                    finish(_wa, s);
                }
            }
            finish(_ok, "Correct perimeter " + to_string(ans));

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

            int k;
            if (!(cin >> k)) finish(_wa, "Expected k after '?'");
            if (k < 1) finish(_wa, "k must be >= 1");

            static int grid[MAX_COORD + 2][MAX_COORD + 2];

            for(int i=0; i<=MAX_COORD; ++i)
                memset(grid[i], 0, sizeof(grid[i]));

            for(int i=0; i<k; ++i) {
                int x, y;
                if (!(cin >> x >> y)) finish(_wa, "Expected coordinates");
                if (x < 1 || x > MAX_COORD || y < 1 || y > MAX_COORD) {
                    finish(_wa, "Coordinate out of range");
                }
                grid[x][y] = 1;
            }

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

            vector<vector<int>> pref(MAX_COORD + 2, vector<int>(MAX_COORD + 2, 0));
            for(int i=1; i<=MAX_COORD; ++i) {
                for(int j=1; j<=MAX_COORD; ++j) {
                    pref[i][j] = grid[i][j] + pref[i-1][j] + pref[i][j-1] - pref[i-1][j-1];
                }
            }

            int chosen_ans = -1;

            if (!adaptive) {
                chosen_ans = pool[0].query_count(pref);
            } else {

                map<int, int> counts;
                for(const auto& r : pool) {
                    counts[r.query_count(pref)]++;
                }

                int max_rem = -1;
                for(auto const& [ans, cnt] : counts) {
                    if (cnt > max_rem) {
                        max_rem = cnt;
                        chosen_ans = ans;
                    } else if (cnt == max_rem) {

                        if (chosen_ans == -1 || ans < chosen_ans) {
                            chosen_ans = ans;
                        }
                    }
                }

                int new_size = 0;
                for(int i=0; i<(int)pool.size(); ++i) {
                    if (pool[i].query_count(pref) == chosen_ans) {
                        pool[new_size++] = pool[i];
                    }
                }
                pool.resize(new_size);
            }

            cout << chosen_ans << endl;
            log_metrics();

        } else {
            finish(_wa, "Invalid query type");
        }
    }

    return 0;
}

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

using namespace std;

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

    registerGen(argc, argv, 1);

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

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

    const int N = 200;

    auto print_rect = [&](int x1, int y1, int x2, int y2) {
        if (x1 > x2) swap(x1, x2);
        if (y1 > y2) swap(y1, y2);
        cout << x1 << " " << y1 << " " << x2 << " " << y2 << endl;
    };

    long long seedVal = -1;
    try {
        seedVal = stoll(string(argv[1]));
    } catch (...) {
        seedVal = -1;
    }

    if (seedVal >= 1 && seedVal <= 10) {

        if (seedVal == 1) {

            print_rect(1, 1, N, N);
        } else if (seedVal == 2) {

            print_rect(100, 100, 101, 101);
        } else if (seedVal == 3) {

            print_rect(1, 1, N, 2);
        } else if (seedVal == 4) {

            print_rect(1, 1, 2, N);
        } else if (seedVal == 5) {

            print_rect(10, 10, 138, 12);
        } else if (seedVal == 6) {

            print_rect(10, 10, 137, 12);
        } else if (seedVal == 7) {

            print_rect(1, 1, 129, 129);
        } else if (seedVal == 8) {

            print_rect(1, 1, 200, 200);
        } else if (seedVal == 9) {

            print_rect(N-2, N-2, N, N);
        } else {

            if (rnd.next(2) == 0) {
                int y = rnd.next(1, N - 1);
                vector<int> x = rnd.distinct(2, 1, N);
                print_rect(x[0], y, x[1], y + 1);
            } else {
                int x = rnd.next(1, N - 1);
                vector<int> y = rnd.distinct(2, 1, N);
                print_rect(x, y[0], x + 1, y[1]);
            }
        }
    } else {

        int type = rnd.next(1, 100);
        if (type <= 60) {

            vector<int> x = rnd.distinct(2, 1, N);
            vector<int> y = rnd.distinct(2, 1, N);
            print_rect(x[0], y[0], x[1], y[1]);
        } else if (type <= 80) {

            int w = rnd.next(N / 2, N - 1);
            int h = rnd.next(N / 2, N - 1);
            int x1 = rnd.next(1, N - w);
            int y1 = rnd.next(1, N - h);
            print_rect(x1, y1, x1 + w, y1 + h);
        } else {

            int w = rnd.next(1, 20);
            int h = rnd.next(1, 20);
            int x1 = rnd.next(1, N - w);
            int y1 = rnd.next(1, N - h);
            print_rect(x1, y1, x1 + w, y1 + h);
        }
    }

    return 0;
}


This is an interactive problem.

Initially, there is an array $a = [1, 2, \ldots, n]$, where $n$ is an odd positive integer. The jury has selected $\frac{n-1}{2}$ disjoint pairs of elements, and then the elements in those pairs are swapped. For example, if $a=[1,2,3,4,5]$, and the pairs $1 \leftrightarrow 4$ and $3 \leftrightarrow 5$ are swapped, then the resulting array is $[4, 2, 5, 1, 3]$.

As a result of these swaps, exactly one element will not change position. You need to find this element.

To do this, you can ask several queries. In each query, you can pick two integers $l$ and $r$ ($1 \leq l \leq r \leq n$). In return, you will be given the elements of the subarray $[a_l, a_{l + 1}, \dots, a_r]$ sorted in increasing order.

Find the element which did not change position. You can make at most $\mathbf{15}$ queries.

The array $a$ is fixed before the interaction and does not change after your queries.

Recall that an array $b$ is a subarray of the array $a$ if $b$ can be obtained from $a$ by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.

Input

Each test contains multiple test cases. The first line contains an integer $t$ ($1 \leq t \leq 500$) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer $n$ ($3 \leq n < 10^4$; $n$ is odd) — the length of the array $a$.

After reading the first line of each test case, you should begin the interaction.

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

Interaction

For each test case, begin the interaction by reading the integer $n$.

To make a query, output "$\texttt{?}\;l\;r$" ($1 \leq l \leq r \leq n$) without quotes. Afterwards, you should read in $r-l+1$ integers — the integers $a_l, a_{l + 1}, \dots, a_r$, in increasing order. You can make at most $15$ such queries in a single test case.

If you receive the integer $-1$ instead of an answer or the integer $n$, it means your program has made an invalid query, has exceed the limit of queries, or has given incorrect answer on the previous test case. Your program must terminate immediately to receive a Wrong Answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you are ready to give the final answer, output "$\texttt{!}\;x$" ($1 \leq x \leq n$) without quotes — the element that did not change position. Giving this answer does not count towards the limit of $15$ queries. Afterwards, your program must continue to solve the remaining test cases, or exit if all test cases have been solved.

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

```
2
5

1 2 4 5

1 3 5

3

1
```

Output

```
? 1 4

? 3 5

! 2

? 1 1

! 1
```

Note

In the first test, the interaction proceeds as follows.

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | $\texttt{2}$ | There are 2 test cases. |
|  | $\texttt{5}$ | In the first test case, the hidden array is $[4,2,5,1,3]$, with length $5$. |
| $\texttt{? 1 4}$ | $\texttt{1 2 4 5}$ | The solution requests the subarray $[4,2,5,1]$ in increasing order, and the jury responds with $[1,2,4,5]$. |
| $\texttt{? 3 5}$ | $\texttt{1 3 5}$ | The solution requests the subarray $[5,1,3]$ in increasing order, and the jury responds with $[1,3,5]$. |
| $\texttt{! 2}$ |  | The solution has somehow determined that $a_2=2$, and outputs it. Since the output is correct, the jury continues to the next test case. |
|  | $\texttt{3}$ | In the second test case, the hidden array is $[1,3,2]$, with length $3$. |
| $\texttt{? 1 1}$ | $\texttt{1}$ | The solution requests the number $[1]$ only, and the jury responds with $[1]$. |
| $\texttt{! 1}$ |  | The solution has determined that $a_1=1$, and outputs it. Since the output is correct and there are no more test cases, the jury and the solution exit. |

Note that the line breaks in the example input and output are for the sake of clarity, and do not occur in the real interaction.

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

static long long queries = 0;
static long long query_limit = 15;
static const long long HARD_CAP = 200000;

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 t = inf.readInt();
    cout << t << endl;

    long long total_ops = 0;

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

        int n = inf.readInt();
        vector<int> a(n + 1);
        int ans = -1;

        for (int j = 1; j <= n; ++j) {
            a[j] = inf.readInt();
            if (a[j] == j) {
                ans = j;
            }
        }

        if (ans == -1) {
            finish(_fail, "Invalid hidden input: no fixed point found in permutation");
        }

        cout << n << endl;

        int current_case_queries = 0;

        log_metrics();

        while (true) {
            if (++total_ops > HARD_CAP) {
                finish(_pe, "Hard interaction limit exceeded (solution spamming or infinite loop)");
            }

            string token;
            if (!(cin >> token)) {
                finish(_pe, "Unexpected EOF from solution");
            }

            bool is_ans = false;
            bool is_query = false;
            int l = -1, r = -1, x = -1;

            if (token[0] == '!') {
                is_ans = true;
                if (token.size() > 1) {

                    try { x = stoi(token.substr(1)); }
                    catch (...) { finish(_pe, "Invalid integer format after '!'"); }
                } else {

                    if (!(cin >> x)) finish(_pe, "Expected integer after '!'");
                }
            } else if (token[0] == '?') {
                is_query = true;
                if (token.size() > 1) {

                    try { l = stoi(token.substr(1)); }
                    catch (...) { finish(_pe, "Invalid integer format after '?'"); }
                    if (!(cin >> r)) finish(_pe, "Expected r after ?l");
                } else {

                    if (!(cin >> l >> r)) finish(_pe, "Expected l r after '?'");
                }
            } else {

                is_query = true;
                try { l = stoi(token); }
                catch (...) { finish(_pe, "Expected '?', '!', or integer start of query"); }
                if (!(cin >> r)) finish(_pe, "Expected r after l");
            }

            if (is_ans) {
                if (x == ans) {

                    break;
                } else {

                    cout << -1 << endl;
                    finish(_wa, format("Wrong answer. Expected %d, got %d", ans, x));
                }
            } else if (is_query) {
                current_case_queries++;
                if (current_case_queries > queries) {
                    queries = current_case_queries;
                }

                if (current_case_queries % 5 == 0) log_metrics();

                if (current_case_queries > 15) {
                    cout << -1 << endl;
                    finish(_wa, "Query limit exceeded (15 per test case)");
                }

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

                vector<int> res;
                res.reserve(r - l + 1);
                for (int k = l; k <= r; ++k) {
                    res.push_back(a[k]);
                }
                sort(res.begin(), res.end());

                for (size_t k = 0; k < res.size(); ++k) {
                    cout << res[k] << (k == res.size() - 1 ? "" : " ");
                }
                cout << endl;
            }
        }
    }

    finish(_ok, "All test cases passed");
    return 0;
}

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

static long long total_queries = 0;
static long long total_limit = 0;

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

    }
}

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

void solve_test_case() {

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

    cout << n << endl;

    vector<int> p(n + 1);
    p[target] = target;

    vector<int> others;
    others.reserve(n);
    for (int i = 1; i <= n; ++i) {
        if (i != target) others.push_back(i);
    }

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

    for (size_t i = 0; i < others.size(); i += 2) {
        int u = others[i];
        int v = others[i+1];
        p[u] = v;
        p[v] = u;
    }

    int queries_case = 0;
    const int LIMIT_PER_CASE = 15;

    while (true) {
        string type;

        if (!(cin >> type)) {
            finish(_pe, "Unexpected EOF or error reading query type");
        }

        if (type == "!") {

            int ans;
            if (!(cin >> ans)) {
                finish(_pe, "Unexpected EOF reading answer");
            }

            if (ans == target) {

                return;
            } else {

                cout << -1 << endl;
                finish(_wa, format("Wrong answer: expected %d, got %d", target, ans));
            }
        } else if (type == "?") {

            int l, r;
            if (!(cin >> l >> r)) {
                finish(_pe, "Unexpected EOF reading query range");
            }

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

            queries_case++;
            total_queries++;

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

            if (queries_case > LIMIT_PER_CASE) {
                cout << -1 << endl;

                finish(_wa, format("Query limit exceeded for test case (used %d > %d)", queries_case, LIMIT_PER_CASE));
            }

            vector<int> res;
            res.reserve(r - l + 1);
            for (int i = l; i <= r; ++i) {
                res.push_back(p[i]);
            }
            sort(res.begin(), res.end());

            for (size_t i = 0; i < res.size(); ++i) {
                cout << res[i] << (i == res.size() - 1 ? "" : " ");
            }
            cout << endl;
        } else {

            cout << -1 << endl;
            finish(_pe, format("Unknown query type '%s'", type.c_str()));
        }
    }
}

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

    atexit(log_metrics);

    int t = inf.readInt();

    total_limit = t * 15LL;
    log_metrics();

    cout << t << endl;

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

    finish(_ok, "All test cases passed");
}

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

using namespace std;

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

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

    int seed_val = atoi(argv[1]);

    const int MAX_SUM_N = 10000;

    struct TestCase {
        int n;
        int fixed_idx;
    };
    vector<TestCase> tests;

    if (seed_val == 1) {

        for (int i = 1; i <= 3; ++i) {
            tests.push_back({3, i});
        }

        tests.push_back({5, rnd.next(1, 5)});
    } else if (seed_val == 2) {

        int n = 9999;
        tests.push_back({n, rnd.next(1, n)});
    } else if (seed_val == 3) {

        int n1 = 4999;
        tests.push_back({n1, rnd.next(1, n1)});
        int n2 = 4999;
        tests.push_back({n2, rnd.next(1, n2)});
    } else {

        int current_sum = 0;
        while (current_sum < MAX_SUM_N) {
            int rem = MAX_SUM_N - current_sum;

            if (rem < 3) break;

            int n;

            if (rnd.next(5) == 0) {
                int upper = min(rem, 21);
                if (upper < 3) upper = 3;
                n = rnd.next(3, upper);
            } else {
                n = rnd.next(3, rem);
            }

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

            if (n < 3) n = 3;

            if (current_sum + n > MAX_SUM_N) {
                n = rem;
                if (n % 2 == 0) n--;
                if (n < 3) break;
            }

            tests.push_back({n, rnd.next(1, n)});
            current_sum += n;
        }
    }

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

    for (const auto& t : tests) {
        if (mode == "non") {

            vector<int> p(t.n + 1);
            vector<int> others;
            others.reserve(t.n - 1);

            p[t.fixed_idx] = t.fixed_idx;

            for (int i = 1; i <= t.n; ++i) {
                if (i != t.fixed_idx) {
                    others.push_back(i);
                }
            }

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

            for (size_t k = 0; k < others.size(); k += 2) {
                int u = others[k];
                int v = others[k+1];
                p[u] = v;
                p[v] = u;
            }

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

        } else {

            cout << t.n << " " << t.fixed_idx << endl;
        }
    }

    return 0;
}