This is an interactive problem.

Having recently discovered The Nether, Steve has built a network of $n$ nether portals, each at a different location in his world.

Each portal is connected in one direction to some number (possibly zero) of other portals. To avoid getting lost, Steve has carefully built the network of portals so that there is no sequence of jumps through portals that will bring you from a location back to itself; formally, the network forms a directed acyclic graph.

Steve refuses to tell you which portals are connected to which, but he will allow you to ask queries. In each query, you give Steve a set of locations $S = \{s_1, s_2, \ldots, s_k\}$ and a starting location $x \in S$. Steve will figure out the longest path starting at $x$ that only passes through locations in $S$ and tell you the number of locations in it. (If it is impossible to reach any other location in $S$ from $x$, Steve will reply with $1$.)

As you are looking to obtain the achievement "Hot Tourist Destinations", you want to find any path that visits as many locations as possible. Steve is feeling particularly generous and will give you $2 \cdot n$ queries to find it.

Input

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

The only line of each test case contains a single integer $n$ ($2 \le n \le 500$) — the number of locations.

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

Interaction

The interaction for each test case begins with reading the integer $n$. Then you can make up to $2 \cdot n$ queries.

To make a query, output a line in the following format:

* $\texttt{?}\,\,x\,\,k\,\,s_1\,s_2\,\ldots\,s_k$

The jury will return the answer to the query.

When you find a path with maximum length, output a single line in the following format:

* $\texttt{!}\,\,k\,\,v_1\,v_2\,\ldots\,v_k$

This denotes starting at portal $v_1$, then jumping to $v_2$, then to $v_3$ and so on, ending at $v_k$.

Note that outputting the answer does not count towards the limit of $2 \cdot n$ queries.

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

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

The interactor is not adaptive. The connections between portals do not change during the interaction.

Example

Input

```
2
5

3

3

2

1

2

1

1
```

Output

```
? 1 4 1 2 3 4

? 3 3 4 3 2

? 5 2 1 5

? 2 2 2 4

! 4 5 1 4 2

? 1 2 1 2

? 2 2 1 2

! 1 1
```

Note

In the first test case, the network of portals is as follows:

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

* The longest path starting at location $1$ passing only through $\{1, 2, 3, 4\}$ is the path $1 \rightarrow 4 \rightarrow 2$, which has $3$ distinct locations.
* The longest path starting at location $3$ passing only through $\{2, 3, 4\}$ is the path $3 \rightarrow 4 \rightarrow 2$, which has $3$ distinct locations.
* The longest path starting at location $5$ passing only through $\{1, 5\}$ is the path $5 \rightarrow 1$, which has $2$ distinct locations.
* It is impossible to get to any other location in $\{2, 4\}$ starting from $2$, so Steve answers $1$ for that query.

Using the information from these queries, it is possible to determine that a longest path is $5 \rightarrow 1 \rightarrow 4 \rightarrow 2$.

In the second test case, the network of portals is as follows:

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

Neither of the portals is connected to the other, so the longest path is a single location. Note that ! 1 2 would also be a valid answer.

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

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

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

    }
}

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

int get_global_longest(int u, const vector<vector<int>>& adj, vector<int>& memo) {
    if (memo[u] != -1) return memo[u];
    int res = 1;
    for (int v : adj[u]) {
        res = max(res, 1 + get_global_longest(v, adj, memo));
    }
    return memo[u] = res;
}

int solve_query(int start_node, const vector<int>& S, const vector<vector<int>>& adj) {

    static vector<bool> in_S;
    if (in_S.size() <= adj.size()) in_S.resize(adj.size() + 1, false);

    for (int u : S) in_S[u] = true;

    static vector<int> memo;
    if (memo.size() <= adj.size()) memo.resize(adj.size() + 1);

    fill(memo.begin(), memo.end(), -1);

    auto dfs = [&](auto&& self, int u) -> int {
        if (memo[u] != -1) return memo[u];
        int res = 1;

        for (int v : adj[u]) {
            if (in_S[v]) {
                res = max(res, 1 + self(self, v));
            }
        }
        return memo[u] = res;
    };

    int ans = dfs(dfs, start_node);

    for (int u : S) in_S[u] = false;

    return ans;
}

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

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

    int t = inf.readInt();

    cout << t << endl;

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

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

        long long current_limit = 2LL * n;
        query_limit += current_limit;

        log_metrics();

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

        int global_max = 0;
        {
            vector<int> memo(n + 1, -1);
            for (int i = 1; i <= n; i++) {
                global_max = max(global_max, get_global_longest(i, adj, memo));
            }
        }

        cout << n << endl;

        bool active = true;
        int queries_in_case = 0;

        int hard_cap = max(200000, 10 * (int)current_limit);

        while (active) {
            string token;

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

            if (token == "!") {

                int k;
                if (!(cin >> k)) finish(_wa, "Expected path length k after '!'");

                vector<int> path(k);
                for (int i = 0; i < k; i++) {
                    if (!(cin >> path[i])) finish(_wa, "Expected path vertex");
                }

                if (k != global_max) {
                    finish(_wa, format("Incorrect path length: got %d, expected %d", k, global_max));
                }

                if (k > 0) {

                    if (path[0] < 1 || path[0] > n) finish(_wa, format("Vertex %d out of bounds", path[0]));

                    for (int i = 0; i < k - 1; i++) {
                        int u = path[i];
                        int v = path[i+1];

                        if (v < 1 || v > n) finish(_wa, format("Vertex %d out of bounds", v));

                        bool edge_exists = false;
                        for (int neighbor : adj[u]) {
                            if (neighbor == v) {
                                edge_exists = true;
                                break;
                            }
                        }
                        if (!edge_exists) {
                            finish(_wa, format("No edge exists from %d to %d", u, v));
                        }
                    }
                } else if (global_max > 0) {

                    finish(_wa, "Path length cannot be 0");
                }

                active = false;

            } else {

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

                    try {
                        x = stoi(token);
                    } catch (...) {
                        finish(_wa, "Invalid token (expected '!', '?' or integer)");
                    }
                }

                int k_sz;
                if (!(cin >> k_sz)) finish(_wa, "Expected set size k");

                vector<int> S(k_sz);
                bool x_in_S = false;
                for (int i = 0; i < k_sz; i++) {
                    if (!(cin >> S[i])) finish(_wa, "Expected set element");
                    if (S[i] < 1 || S[i] > n) finish(_wa, "Set element out of bounds");
                    if (S[i] == x) x_in_S = true;
                }

                if (!x_in_S) {
                    finish(_wa, "Starting location x must be in set S");
                }

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

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

                int ans = solve_query(x, S, adj);
                cout << ans << endl;
            }
        }
    }

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

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

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

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

    int t = 0;
    vector<int> ns;

    if (seed_val == 1) {

        t = 3;
        ns = {2, 5, 5};
    } else if (seed_val == 2) {

        t = 1;
        ns = {500};
    } else if (seed_val == 3) {

        t = 1;
        ns = {500};
    } else {

        long long limit = 124000000;
        long long current = 0;

        while (t < 1000) {
            int n;
            int r = rnd.next(100);

            if (r < 50) n = rnd.next(2, 20);
            else if (r < 90) n = rnd.next(20, 100);
            else n = rnd.next(100, 500);

            long long cost = (long long)n * n * n;
            if (current + cost > limit) break;

            ns.push_back(n);
            current += cost;
            t++;
        }

        if (t == 0) {
            t = 1;
            ns.push_back(500);
        }
    }

    cout << t << endl;

    for (int i = 0; i < t; i++) {
        int n = ns[i];
        if (mode == "adp") {

            cout << n << endl;
        } else {

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

            vector<pair<int, int>> edges;

            if (seed_val == 1) {
                if (i == 0) {

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

                    for (int k = 1; k < 5; k++) edges.push_back({k, k + 1});
                }

            } else {
                int type = rnd.next(3);
                if (seed_val == 2) type = 0;
                if (seed_val == 3) type = 1;

                if (type == 0) {
                    double prob = rnd.next(0.1, 0.8);
                    for (int u = 0; u < n; u++) {
                        for (int v = u + 1; v < n; v++) {
                            if (rnd.next(0.0, 1.0) < prob) {
                                edges.push_back({p[u], p[v]});
                            }
                        }
                    }
                } else if (type == 1) {

                    int len = rnd.next(n / 2, n);
                    for (int k = 0; k < len - 1; k++) {
                        edges.push_back({p[k], p[k + 1]});
                    }

                    int m_noise = rnd.next(0, n * 5);
                    for (int k = 0; k < m_noise; k++) {
                        int u = rnd.next(0, n - 2);
                        int v = rnd.next(u + 1, n - 1);
                        edges.push_back({p[u], p[v]});
                    }
                } else {
                    int m = rnd.next(0, min(n * (n - 1) / 2, n * 10));
                    set<pair<int, int>> distinct_indices;
                    int attempts = 0;
                    while ((int)distinct_indices.size() < m && attempts < m * 3) {
                        int u = rnd.next(0, n - 2);
                        int v = rnd.next(u + 1, n - 1);
                        if (distinct_indices.find({u, v}) == distinct_indices.end()) {
                            distinct_indices.insert({u, v});
                            edges.push_back({p[u], p[v]});
                        }
                        attempts++;
                    }
                }
            }

            sort(edges.begin(), edges.end());
            edges.erase(unique(edges.begin(), edges.end()), edges.end());
            shuffle(edges.begin(), edges.end());

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

    return 0;
}


### Problem Statement

**This is an interactive task** (where your program interacts with the judge's program via input and output).

We have an $N$-by-$N$ chessboard and $N$ rooks. Below, the square at the $i$-th row from the top and $j$-th column from the left is denoted by $(i, j)$.
Consider placing the rooks on squares of the chessboard. Here, you have to place the rooks so that all of the following conditions are satisfied.

* No row contains two or more rooks.
* No column contains two or more rooks.

Now, $N-1$ rooks are placed on the chessboard so that all of the above conditions are satisfied. You will choose a square that is not occupied by a rook and place a rook on that square. (It can be proved that there is at least one square on which a rook can be placed under the conditions.)

However, you cannot directly see which squares of the chessboard are occupied by a rook.
Instead, you may ask at most $20$ questions to the judge in the following manner.

* You choose integers $A$, $B$, $C$, and $D$ such that $1 \leq A \leq B \leq N, 1 \leq C \leq D \leq N$, and ask the number of rooks in the rectangular region formed by the squares $(i, j)$ such that $A \leq i \leq B, C \leq j \leq D$.

Find a square to place a rook.

### Constraints

* $2 \leq N \leq 10^3$
* $N$ is an integer.

### Input and Output

This is an interactive task (where your program interacts with the judge's program via input and output).

First, receive the size of the chessboard, $N$, from Standard Input.

```
$N$
```

Next, repeat asking a question until you find a square to place a rook.
A question should be printed to Standard Output in the following format:

```
$?$ $A$ $B$ $C$ $D$
```

The response will be given from Standard Input in the following format:

```
$T$
```

Here, $T$ is the response to the question, or `-1` if the question is invalid or more than $20$ questions have been asked.

When the judge returns `-1`, the submission is already regarded as incorrect. In this case, terminate the program immediately.

When you find a square to place a rook, let $(X, Y)$ be that square and print an answer in the following format. Then, terminate the program immediately.

```
$!$ $X$ $Y$
```

If there are multiple appropriate answers, any of them will be accepted.

### Notes

* **Each time you print something, end it with a newline and then flush Standard Output. Otherwise, you may get a TLE verdict.**
* **If an invalid output is printed during the interaction, the verdict will be indeterminate.**
* Terminate the program immediately after printing an answer. Otherwise, the verdict will be indeterminate.

### Sample Interaction

Below is an interaction where $N=3$ and the rooks are placed on $(1, 2)$ and $(2, 1)$.

| Input | Output | Description |
| --- | --- | --- |
| `3` |  | Judge first gives the integer $N$. |
|  | `? 1 2 1 3` | Participant asks a question with $(A,B,C,D)=(1,2,1,3)$. |
| `2` |  | Judge returns the answer to the question, which is $2$. |
|  | `? 2 3 1 1` | Participant asks a question with $(A,B,C,D)=(2,3,1,1)$. |
| `1` |  | Judge returns the answer to the question, which is $1$. |
|  | `? 1 3 3 3` | Participant asks a question with $(A,B,C,D)=(1,3,3,3)$. |
| `0` |  | Judge returns the answer to the question, which is $0$. |
|  | `! 3 3` | Participant finds the answer to be $(3, 3)$ and prints it. |

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

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

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

    vector<pair<int, int>> rooks;
    vector<bool> r_occ(N + 1, false);
    vector<bool> c_occ(N + 1, false);

    for (int i = 0; i < N - 1; ++i) {
        int r = inf.readInt();
        int c = inf.readInt();
        rooks.push_back({r, c});
        r_occ[r] = true;
        c_occ[c] = true;
    }

    int ans_r = -1, ans_c = -1;
    for (int i = 1; i <= N; ++i) {
        if (!r_occ[i]) ans_r = i;
        if (!c_occ[i]) ans_c = i;
    }

    if (ans_r == -1 || ans_c == -1) {
        quitf(_fail, "Generator error: No empty row/column found");
    }

    cout << N << endl;

    string token;
    while (cin >> token) {
        bool is_query = false;
        bool is_answer = false;
        vector<int> args;

        if (!token.empty() && token[0] == '!') {
            is_answer = true;

            if (token.size() > 1) {
                try {
                    args.push_back(stoi(token.substr(1)));
                } catch (...) {
                    finish(_pe, "Invalid format: '!' followed by non-integer: " + token);
                }
            }
        } else if (!token.empty() && token[0] == '?') {
            is_query = true;

            if (token.size() > 1) {
                try {
                    args.push_back(stoi(token.substr(1)));
                } catch (...) {
                    finish(_pe, "Invalid format: '?' followed by non-integer: " + token);
                }
            }
        } else {

            try {
                size_t idx;
                int val = stoi(token, &idx);
                if (idx != token.size()) {
                    finish(_pe, "Invalid token (expected integer, '?', or '!'): " + token);
                }
                args.push_back(val);
                is_query = true;
            } catch (...) {
                finish(_pe, "Invalid token (not integer/!/?): " + token);
            }
        }

        if (is_answer) {

            while (args.size() < 2) {
                string t;
                if (!(cin >> t)) finish(_pe, "Unexpected EOF reading answer coordinates");
                try {
                    args.push_back(stoi(t));
                } catch (...) {
                    finish(_pe, "Invalid integer in answer coordinate: " + t);
                }
            }

            int r = args[0];
            int c = args[1];

            if (r == ans_r && c == ans_c) {
                finish(_ok, "Correct");
            } else {
                finish(_wa, "Wrong answer: expected " + to_string(ans_r) + " " + to_string(ans_c)
                            + ", got " + to_string(r) + " " + to_string(c));
            }

        } else {

            while (args.size() < 4) {
                string t;
                if (!(cin >> t)) finish(_pe, "Unexpected EOF reading query parameters");
                try {
                    args.push_back(stoi(t));
                } catch (...) {
                    finish(_pe, "Invalid integer in query parameters: " + t);
                }
            }

            queries++;

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

            int A = args[0];
            int B = args[1];
            int C = args[2];
            int D = args[3];

            bool invalid = false;
            if (A < 1 || A > N || B < 1 || B > N || A > B) invalid = true;
            if (C < 1 || C > N || D < 1 || D > N || C > D) invalid = true;

            if (invalid) {
                cout << -1 << endl;
                finish(_wa, "Invalid query range: " + to_string(A) + " " + to_string(B) + " "
                            + to_string(C) + " " + to_string(D));
            }

            int cnt = 0;
            for (auto& p : rooks) {
                if (p.first >= A && p.first <= B && p.second >= C && p.second <= D) {
                    cnt++;
                }
            }
            cout << cnt << endl;

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

    finish(_pe, "Program exited without providing an answer");
    return 0;
}

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

int queries = 0;
const int query_limit = 20;

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 N;
bool adaptive_mode = false;

vector<pair<int, int>> rooks;
int target_X = -1;
int target_Y = -1;

vector<int> candX;
vector<int> candY;
bool collapsed = false;

int count_rooks_fixed(int A, int B, int C, int D, const vector<pair<int, int>>& current_rooks) {
    int cnt = 0;
    for (auto p : current_rooks) {
        if (p.first >= A && p.first <= B && p.second >= C && p.second <= D) {
            cnt++;
        }
    }
    return cnt;
}

int count_rooks_collapsed(int A, int B, int C, int D, int mx, int my) {

    int cnt = 0;
    int c_ptr = 1;
    for (int r = 1; r <= N; r++) {
        if (r == mx) continue;
        while (c_ptr == my) c_ptr++;
        int c = c_ptr;
        c_ptr++;

        if (r >= A && r <= B && c >= C && c <= D) {
            cnt++;
        }
    }
    return cnt;
}

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

    N = inf.readInt();
    inf.skipBlanks();

    if (inf.eof()) {

        adaptive_mode = true;
        for (int i = 1; i <= N; i++) {
            candX.push_back(i);
            candY.push_back(i);
        }
    } else {

        adaptive_mode = false;
        vector<bool> row_has(N + 1, false);
        vector<bool> col_has(N + 1, false);
        for (int i = 0; i < N - 1; i++) {
            int r = inf.readInt();
            int c = inf.readInt();
            rooks.push_back({r, c});
            row_has[r] = true;
            col_has[c] = true;
        }
        for (int i = 1; i <= N; i++) {
            if (!row_has[i]) target_X = i;
            if (!col_has[i]) target_Y = i;
        }
    }

    cout << N << endl;

    while (true) {
        char type;

        if (!(cin >> type)) break;

        if (type == '?') {
            int A, B, C, D;
            if (!(cin >> A >> B >> C >> D)) finish(_pe, "Invalid query format");

            queries++;

            if (queries > 200) finish(_pe, "Too many queries (hard cap)");

            bool valid = (1 <= A && A <= B && B <= N && 1 <= C && C <= D && D <= N);

            if (!valid || queries > query_limit) {
                cout << -1 << endl;
                if (!valid) finish(_wa, "Query coordinates out of bounds");
                else finish(_wa, "Query limit exceeded");
            }

            int ans = 0;

            if (!adaptive_mode) {
                ans = count_rooks_fixed(A, B, C, D, rooks);
            } else {

                if (collapsed) {

                    ans = count_rooks_collapsed(A, B, C, D, candX[0], candY[0]);
                } else {
                    bool is_row_query = (C == 1 && D == N);
                    bool is_col_query = (A == 1 && B == N);

                    if (is_row_query) {

                        int len = B - A + 1;
                        int ans0 = len;
                        int ans1 = len - 1;

                        int count0 = 0;
                        int count1 = 0;
                        for (int x : candX) {
                            if (x < A || x > B) count0++;
                            else count1++;
                        }

                        if (count1 > count0) {
                            ans = ans1;
                            vector<int> nextX;
                            for (int x : candX) if (x >= A && x <= B) nextX.push_back(x);
                            candX = nextX;
                        } else {
                            ans = ans0;
                            vector<int> nextX;
                            for (int x : candX) if (x < A || x > B) nextX.push_back(x);
                            candX = nextX;
                        }
                    }
                    else if (is_col_query) {

                        int len = D - C + 1;
                        int ans0 = len;
                        int ans1 = len - 1;

                        int count0 = 0;
                        int count1 = 0;
                        for (int y : candY) {
                            if (y < C || y > D) count0++;
                            else count1++;
                        }

                        if (count1 > count0) {
                            ans = ans1;
                            vector<int> nextY;
                            for (int y : candY) if (y >= C && y <= D) nextY.push_back(y);
                            candY = nextY;
                        } else {
                            ans = ans0;
                            vector<int> nextY;
                            for (int y : candY) if (y < C || y > D) nextY.push_back(y);
                            candY = nextY;
                        }
                    }
                    else {

                        collapsed = true;
                        int finalX = candX[0];
                        int finalY = candY[0];
                        candX = {finalX};
                        candY = {finalY};
                        ans = count_rooks_collapsed(A, B, C, D, finalX, finalY);
                    }
                }
            }
            cout << ans << endl;

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

            bool ok = false;
            if (!adaptive_mode) {
                ok = (X == target_X && Y == target_Y);
            } else {

                bool x_in = false;
                for (int x : candX) if (x == X) x_in = true;
                bool y_in = false;
                for (int y : candY) if (y == Y) y_in = true;
                ok = (x_in && y_in);
            }

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

        } else {
            finish(_pe, "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");

    long long seed_val = 0;
    if (argc > 1) {
        string s = argv[1];
        bool is_num = !s.empty();
        for (char c : s) {
            if (!isdigit(c)) {
                is_num = false;
                break;
            }
        }
        if (is_num) {
            seed_val = atoll(s.c_str());
        }
    }

    int N;
    if (seed_val == 1) {
        N = 2;
    } else if (seed_val == 2) {
        N = 3;
    } else if (seed_val == 3) {
        N = 1000;
    } else {

        N = rnd.next(2, 1000);
    }

    if (mode == "adp") {

        cout << N << endl;
    } else {

        cout << N << endl;

        int X = rnd.next(1, N);
        int Y = rnd.next(1, N);

        vector<int> rows;
        vector<int> cols;
        for (int i = 1; i <= N; i++) {
            if (i != X) rows.push_back(i);
            if (i != Y) cols.push_back(i);
        }

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

        vector<pair<int, int>> rooks;
        for (int i = 0; i < N - 1; i++) {
            rooks.push_back({rows[i], cols[i]});
        }

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

        for (const auto& p : rooks) {
            cout << p.first << " " << p.second << endl;
        }
    }

    return 0;
}


Integer factorisation is hard. The RSA Factoring Challenge offered $$100\,000$ for factoring RSA-$1024$, a $1024$-bit long product of two prime numbers. To this date, nobody was able to claim the prize. We want you to factorise a $1024$-bit number.

Since your programming language of choice might not offer facilities for handling large integers, we will provide you with a very simple calculator.

To use this calculator, you can print queries on the standard output and retrieve the results from the standard input. The operations are as follows:

* + x y where $x$ and $y$ are integers between $0$ and $n-1$. Returns $(x+y) \bmod n$.
* - x y where $x$ and $y$ are integers between $0$ and $n-1$. Returns $(x-y) \bmod n$.
* \* x y where $x$ and $y$ are integers between $0$ and $n-1$. Returns $(x \cdot y) \bmod n$.
* / x y where $x$ and $y$ are integers between $0$ and $n-1$ and $y$ is coprime with $n$. Returns $(x \cdot y^{-1}) \bmod n$ where $y^{-1}$ is multiplicative inverse of $y$ modulo $n$. If $y$ is not coprime with $n$, then $-1$ is returned instead.
* sqrt x where $x$ is integer between $0$ and $n-1$ coprime with $n$. Returns $y$ such that $y^2 \bmod n = x$. If there are multiple such integers, only one of them is returned. If there are none, $-1$ is returned instead.
* ^ x y where $x$ and $y$ are integers between $0$ and $n-1$. Returns ${x^y \bmod n}$.

Find the factorisation of $n$ that is a product of between $2$ and $10$ distinct prime numbers, all of form $4x + 3$ for some integer $x$.

Because of technical issues, we restrict number of requests to $100$.

Input

The only line contains a single integer $n$ ($21 \leq n \leq 2^{1024}$). It is guaranteed that $n$ is a product of between $2$ and $10$ distinct prime numbers, all of form $4x + 3$ for some integer $x$.

Output

You can print as many queries as you wish, adhering to the time limit (see the Interaction section for more details).

When you think you know the answer, output a single line of form ! k p\_1 p\_2 ... p\_k, where $k$ is the number of prime factors of $n$, and $p_i$ are the distinct prime factors. You may print the factors in any order.

Example

Input

```
21

7

17

15

17

11

-1

15
```

Output

```
+ 12 16

- 6 10

* 8 15

/ 5 4

sqrt 16

sqrt 5

^ 6 12

! 2 3 7
```

Note

We start by reading the first line containing the integer $n = 21$. Then, we ask for:

1. $(12 + 16) \bmod 21 = 28 \bmod 21 = 7$.
2. $(6 - 10) \bmod 21 = -4 \bmod 21 = 17$.
3. $(8 \cdot 15) \bmod 21 = 120 \bmod 21 = 15$.
4. $(5 \cdot 4^{-1}) \bmod 21 = (5 \cdot 16) \bmod 21 = 80 \bmod 21 = 17$.
5. Square root of $16$. The answer is $11$, as $(11 \cdot 11) \bmod 21 = 121 \bmod 21 = 16$. Note that the answer may as well be $10$.
6. Square root of $5$. There is no $x$ such that $x^2 \bmod 21 = 5$, so the output is $-1$.
7. $(6^{12}) \bmod 21 = 2176782336 \bmod 21 = 15$.

We conclude that our calculator is working, stop fooling around and realise that $21 = 3 \cdot 7$.

#include "testlib.h"

#include <algorithm>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>

using namespace std;

using i128 = __int128_t;

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

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

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

static long long mod_norm(long long x, long long mod) {
    x %= mod;
    if (x < 0) x += mod;
    return x;
}

static long long mod_mul(long long a, long long b, long long mod) {
    return (long long)((i128)a * (i128)b % (i128)mod);
}

static long long mod_pow(long long a, unsigned long long e, long long mod) {
    long long r = 1 % mod;
    a = mod_norm(a, mod);
    while (e) {
        if (e & 1ULL) r = mod_mul(r, a, mod);
        a = mod_mul(a, a, mod);
        e >>= 1ULL;
    }
    return r;
}

static long long ext_gcd(long long a, long long b, long long& x, long long& y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long x1 = 0, y1 = 0;
    long long g = ext_gcd(b, a % b, x1, y1);
    x = y1;
    y = x1 - (a / b) * y1;
    return g;
}

static long long mod_inv(long long a, long long mod) {
    long long x = 0, y = 0;
    long long g = ext_gcd(a, mod, x, y);
    if (g != 1 && g != -1) return 0;
    return mod_norm(x, mod);
}

static long long crt_pair(long long a1, long long m1, long long a2, long long m2) {

    long long inv = mod_inv(mod_norm(m1, m2), m2);
    if (inv == 0) die(_fail, "CRT failed: no inverse");
    long long t = mod_norm(a2 - a1, m2);
    t = mod_mul(t, inv, m2);
    long long res = (long long)((i128)a1 + (i128)m1 * (i128)t);
    long long mod = (long long)((i128)m1 * (i128)m2);
    return mod_norm(res, mod);
}

static long long sqrt_mod_blum(long long a, long long n, const vector<long long>& primes) {
    if (std::gcd(a, n) != 1) return -1;
    if (primes.empty()) return -1;

    vector<long long> rs;
    rs.reserve(primes.size());
    for (long long p : primes) {
        long long ai = mod_norm(a, p);
        long long e = (p + 1) / 4;
        long long r = mod_pow(ai, (unsigned long long)e, p);
        if (mod_mul(r, r, p) != ai) return -1;
        rs.push_back(r);
    }

    long long cur = rs[0];
    long long mod = primes[0];
    for (size_t i = 1; i < primes.size(); i++) {
        cur = crt_pair(cur, mod, rs[i], primes[i]);
        mod = (long long)((i128)mod * (i128)primes[i]);
    }
    return mod_norm(cur, n);
}

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

    int k = inf.readInt();
    if (k < 2 || k > 10) die(_fail, "Invalid hidden input: k out of range");

    vector<long long> primes;
    primes.reserve(k);
    for (int i = 0; i < k; i++) {
        long long p = inf.readLong();
        if (p <= 1) die(_fail, "Invalid hidden input: p <= 1");
        if (p % 4 != 3) die(_fail, "Invalid hidden input: p % 4 != 3");
        primes.push_back(p);
    }
    sort(primes.begin(), primes.end());
    if (adjacent_find(primes.begin(), primes.end()) != primes.end()) die(_fail, "Duplicated primes");

    const long long N_MAX = 9000000000000000000LL;
    long long n = 1;
    for (long long p : primes) {
        if ((i128)n * (i128)p > (i128)N_MAX) die(_fail, "Hidden n exceeds 64-bit limit");
        n = (long long)((i128)n * (i128)p);
    }
    if (n < 21) die(_fail, "Invalid hidden input: n < 21");

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

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

    while (true) {
        string cmd;
        if (!(cin >> cmd)) {
            die(_wa, "Unexpected EOF from solution");
        }

        if (cmd == "!") {
            int out_k = 0;
            if (!(cin >> out_k)) die(_wa, "Invalid answer format");
            if (out_k < 2 || out_k > 10) die(_wa, "Invalid answer k");

            vector<long long> out_ps;
            out_ps.reserve(out_k);
            for (int i = 0; i < out_k; i++) {
                long long p;
                if (!(cin >> p)) die(_wa, "Invalid answer factor");
                out_ps.push_back(p);
            }
            sort(out_ps.begin(), out_ps.end());
            out_ps.erase(unique(out_ps.begin(), out_ps.end()), out_ps.end());
            if (out_ps != primes) die(_wa, "Wrong factorization");
            die(_ok, "OK");
        }

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

        if (cmd == "+") {
            long long x, y;
            if (!(cin >> x >> y)) die(_wa, "Invalid '+' query");
            if (x < 0 || x >= n || y < 0 || y >= n) die(_wa, "Out of range '+' args");
            cout << mod_norm(x + y, n) << endl;
            cout.flush();
            continue;
        }
        if (cmd == "-") {
            long long x, y;
            if (!(cin >> x >> y)) die(_wa, "Invalid '-' query");
            if (x < 0 || x >= n || y < 0 || y >= n) die(_wa, "Out of range '-' args");
            cout << mod_norm(x - y, n) << endl;
            cout.flush();
            continue;
        }
        if (cmd == "*") {
            long long x, y;
            if (!(cin >> x >> y)) die(_wa, "Invalid '*' query");
            if (x < 0 || x >= n || y < 0 || y >= n) die(_wa, "Out of range '*' args");
            cout << mod_mul(x, y, n) << endl;
            cout.flush();
            continue;
        }
        if (cmd == "/") {
            long long x, y;
            if (!(cin >> x >> y)) die(_wa, "Invalid '/' query");
            if (x < 0 || x >= n || y < 0 || y >= n) die(_wa, "Out of range '/' args");
            if (std::gcd(y, n) != 1) {
                cout << -1 << endl;
                cout.flush();
                continue;
            }
            long long inv = mod_inv(y, n);
            if (inv == 0) {
                cout << -1 << endl;
                cout.flush();
                continue;
            }
            cout << mod_mul(x, inv, n) << endl;
            cout.flush();
            continue;
        }
        if (cmd == "sqrt") {
            long long x;
            if (!(cin >> x)) die(_wa, "Invalid 'sqrt' query");
            if (x < 0 || x >= n) die(_wa, "Out of range 'sqrt' arg");
            cout << sqrt_mod_blum(x, n, primes) << endl;
            cout.flush();
            continue;
        }
        if (cmd == "^") {
            long long x, y;
            if (!(cin >> x >> y)) die(_wa, "Invalid '^' query");
            if (x < 0 || x >= n || y < 0 || y >= n) die(_wa, "Out of range '^' args");
            cout << mod_pow(x, (unsigned long long)y, n) << endl;
            cout.flush();
            continue;
        }

        die(_pe, "Unknown command: " + cmd);
    }
}

#include "testlib.h"

#include <bits/stdc++.h>

using namespace std;

using u64 = unsigned long long;
using u128 = __uint128_t;

static u64 mod_mul(u64 a, u64 b, u64 mod) {
    return (u128)a * b % mod;
}

static u64 mod_pow(u64 a, u64 e, u64 mod) {
    u64 r = 1 % mod;
    while (e) {
        if (e & 1) {
            r = mod_mul(r, a, mod);
        }
        a = mod_mul(a, a, mod);
        e >>= 1;
    }
    return r;
}

static bool is_prime_u64(u64 n) {
    if (n < 2) return false;
    for (u64 p: {2ULL, 3ULL, 5ULL, 7ULL, 11ULL, 13ULL, 17ULL, 19ULL, 23ULL, 29ULL, 31ULL, 37ULL}) {
        if (n % p == 0) return n == p;
    }
    u64 d = n - 1;
    int s = 0;
    while ((d & 1) == 0) {
        d >>= 1;
        s++;
    }

    static const u64 bases[] = {2ULL, 325ULL, 9375ULL, 28178ULL, 450775ULL, 9780504ULL, 1795265022ULL};
    for (u64 a: bases) {
        if (a % n == 0) continue;
        u64 x = mod_pow(a % n, d, n);
        if (x == 1 || x == n - 1) continue;
        bool ok = false;
        for (int r = 1; r < s; r++) {
            x = mod_mul(x, x, n);
            if (x == n - 1) {
                ok = true;
                break;
            }
        }
        if (!ok) return false;
    }
    return true;
}

static u64 sample_blum_prime(int bits) {

    bits = max(10, min(bits, 62));
    const long long lo = (1LL << (bits - 1));
    const long long hi = (1LL << bits) - 1;
    for (;;) {
        long long x = rnd.next(lo, hi);
        x |= 1LL;
        x = (x & ~3LL) | 3LL;
        if (x > hi) x -= 4;
        if (x < lo) x += 4;
        if (x < 7) x = 7;
        const u64 p = (u64)x;
        if (is_prime_u64(p)) return p;
    }
}

int main(int argc, char** argv) {
    registerGen(argc, argv, 1);
    (void)opt<string>("mode", "non");

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

    vector<u64> primes;
    if (seed_val == 1) {
        primes = {3ULL, 7ULL};
    } else if (seed_val == 2) {
        primes = {3ULL, 7ULL, 11ULL};
    } else if (seed_val == 3) {
        primes = {3ULL, 7ULL, 11ULL, 19ULL, 23ULL};
    } else {

        const u64 N_MAX = 9000000000000000000ULL;
        __uint128_t prod = 1;
        int target = rnd.next(2, 10);
        unordered_set<u64> used;
        primes.reserve(target);
        for (int tries = 0; tries < 200000 && (int)primes.size() < target; tries++) {
            int bits = rnd.next(10, 20);
            u64 p = sample_blum_prime(bits);
            if (!used.insert(p).second) continue;
            if (prod * (__uint128_t)p > (__uint128_t)N_MAX) continue;
            primes.push_back(p);
            prod *= (__uint128_t)p;
        }
        if ((int)primes.size() < 2) primes = {3ULL, 7ULL};
    }

    cout << primes.size() << "\n";
    for (u64 p: primes) {
        cout << p << "\n";
    }
    return 0;
}


The king of Belle Aire People’s Country has come up with a new plan: he has heard about the popular phenomenon called “King of the Hill”, and he would like to become one as well. To do so, he has ordered you to raise a flag on the highest hill in his square kingdom, which has dimensions $n \times n$ . You are given a very expensive (it is gold- and jewel-embedded) satellite-based height-measuring system. This equipment is highly accurate: the heights on every location in the kingdom are represented with distinct integers. However, to cut costs, you are only allowed to take $1 0 n + 1 0 0$ measurements before reporting back to the king.

![](images/e56c7d9411a009439bd288d2d989442952202d61019c8f0b716b35b9fba291c2.jpg)
Raising the flag, Linglie Hill, Selkirk. CC BY-SA 2.0 by Jim Barton on Wikimedia Commons

Furthermore, you know for certain that there is only a single point that is the absolute highest: this is the only point for which its height is larger than the (up to) four orthogonally adjacent points that lie inside the kingdom. In other words, there are no local maxima besides the global maximum.

# Interaction

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

The interactor first sends one line with an integer $n$ ( $1 \leq n \leq 1 0 0 0 0$ ), the width and height of the kingdom.

Then, your program should make at most $1 0 n + 1 0 0$ queries to find the highest point in the kingdom. Each query is made by printing one line of the form $\textit { \textbf { * } ? } \textit { x } \textit { y } ^ { \flat }$ ( $1 \leq x , y \leq n$ ). The interactor will respond with an integer $\boldsymbol { v }$ ( $1 \le v \le 1 0 ^ { 9 }$ ), indicating the height at coordinate $( x , y )$ .

When you have determined the height of the highest point in the kingdom $v$ , print one line of the form “! $v$ ”, after which the interaction will stop. Printing the answer does not count as a query.

The interactor is not adaptive: the heights in the kingdom are fixed up front, and do not depend on your queries.

Make sure you flush the buffer after each write.

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

Using more than $1 0 n + 1 0 0$ queries will result in a wrong answer.

![](images/1996fe64e572c5dbfd79d13eedec283d76eda4fc28b8613861c2c5c938ea4604.jpg)

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

using namespace std;

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

static void log_metrics() {
    try {

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

    }
}

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

int N;
int px, py;
long long wx, wy;
int type;
long long noise_seed;

long long get_height(int x, int y) {
    if (x < 1 || x > N || y < 1 || y > N) return -1;

    long long dist_cost = 0;
    long long dx = abs(x - px);
    long long dy = abs(y - py);

    if (type == 0) {

        dist_cost = wx * dx + wy * dy;
    } else {

        dist_cost = wx * dx * dx + wy * dy * dy;
    }

    long long max_h = 1000000000LL;
    long long h = max_h - dist_cost;

    if (h < 1) h = 1;

    return h;
}

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    N = inf.readInt(1, 10000, "n");
    px = inf.readInt(1, N, "px");
    py = inf.readInt(1, N, "py");

    wx = inf.readLong(1LL, 10000LL, "wx");
    wy = inf.readLong(1LL, 10000LL, "wy");
    type = inf.readInt(0, 1, "type");
    noise_seed = inf.readLong(0LL, 2000000000LL, "noise_seed");

    query_limit = 10LL * N + 100;

    cout << N << endl;

    long long hard_cap = 2 * query_limit + 2000;

    while (true) {

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

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

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

            long long correct_h = get_height(px, py);
            if (ans == correct_h) {
                finish(_ok, "Correct peak height found");
            } else {
                string msg = "Wrong answer: expected " + to_string(correct_h) + ", got " + to_string(ans);
                finish(_wa, msg);
            }
        }

        else {
            int x, y;

            if (token == "?") {
                if (!(cin >> x >> y)) {
                    finish(_pe, "Expected coordinates after '?'");
                }
            } else {

                try {
                    x = stoi(token);
                } catch (...) {
                    finish(_pe, "Invalid token (expected '!', '?', or integer): " + token);
                }
                if (!(cin >> y)) {
                    finish(_pe, "Expected y coordinate");
                }
            }

            queries++;

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

            long long h = get_height(x, y);
            if (h == -1) {
                finish(_wa, "Query coordinates out of bounds: " + to_string(x) + " " + to_string(y));
            }

            cout << h << 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");
    int seed_val = atoi(argv[1]);

    int n;

    if (seed_val == 1) n = 1;
    else if (seed_val == 2) n = 2;
    else if (seed_val == 3) n = 10000;
    else if (seed_val == 4) n = 10000;
    else if (seed_val == 5) n = 10000;
    else {

        int p = rnd.next(100);
        if (p < 5) n = rnd.next(1, 10);
        else if (p < 15) n = rnd.next(11, 100);
        else if (p < 40) n = rnd.next(101, 1000);
        else n = rnd.next(1001, 10000);
    }

    if (mode == "adp") {

        cout << n << "\n";
        cout << rnd.next(1, 2000000000) << "\n";
    } else {

        int px = rnd.next(1, n);
        int py = rnd.next(1, n);

        if (seed_val == 4) { px = 1; py = 1; }
        else if (seed_val == 5) { px = n; py = n; }
        else if (seed_val == 6) { px = 1; py = n; }
        else if (seed_val == 7) { px = n/2 + 1; py = n/2 + 1; }

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

        long long wx, wy;
        if (type == 1) {

            wx = rnd.next(1, 8);
            wy = rnd.next(1, 8);
        } else {

            wx = rnd.next(1, 10000);
            wy = rnd.next(1, 10000);
        }

        long long noise_seed = rnd.next(1, 2000000000);

        cout << n << "\n";
        cout << px << " " << py << "\n";
        cout << wx << " " << wy << " " << type << " " << noise_seed << "\n";
    }

    return 0;
}


Unfortunately, a mistake was found in the proof of the author's solution to this problem. Currently, we don't know the absolutely correct solution. However, you can solve this task, but if your solution passes all the tests, it is not guaranteed to be correct. If your solution has passed all the tests and you are sure that it is correct, you can write to one of the contest authors about it.

Surely you all read the book "Alice in Wonderland". In this task, Nastya got to the country of Three strange Bees. The bees are strange because their honeycombs are pentagonal. Nastya got there illegally, so she wants bees not to catch her. Help the bees punish the intruder!

This is an interactive problem.

A beehive is a connected undirected graph where bees and Nastya can move along the edges. A graph satisfies two properties:

* The degree of any of its vertex is no more than $3$.
* For each edge, there exists a cycle of length not greater than $5$ passing through this edge.

There are three bees and Nastya. You play for bees. Firstly, you choose the vertices where you put the bees. Then Nastya chooses another vertex in which she will initially appear. One move is first moving the bees, then Nastya, in turn:

1. For each of your bees, you can either move each one along some edge from the vertex they are currently staying or leave it in place.
2. Then Nastya will necessarily move along some edge of the graph from the vertex she is currently staying/.

You win if at least one of the bees and Nastya are in the same vertex at any time of the game.

If this situation does not occur after $n$ moves, then you lose.

Several bees can be in the same vertex.

Input

The first line contains two integers $n$ $(4 \leq n \leq 5000)$ and $m$ $(n \leq m \leq 3n)$  — the number of vertices and edges in the graph.

Each of the next $m$ lines contains two integers $v$ and $u$ $(1 \leq v, u \leq n)$, which mean that there is an edge between the vertices $v$ and $u$. It is guaranteed that the graph is connected, does not contain loops that the degree of any vertex does not exceed $3$ and a cycle of length no more than $5$ passes through each edge. Note that the graph may contain multiple edges.

Interaction

At each turn, you must output exactly three vertices $a, b, c$ $(1 \leq a, b, c \leq n)$. For the first time, $3$ vertices displayed will indicate which vertices you originally placed bees on. In response, you will receive the vertex where the jury placed Nastya. Each next $3$ vertices will indicate where the $3$ bees move at your turn. Each of the bees can, regardless of other bees, both remain at the current vertex and move along the edge. After the next output of $3$ vertices, in response, you get the number of the new vertex to which Nastya went.

As soon as one of the bees is at the same vertex with Nastya or you have reached the limit on the number of moves, your program should stop working. That is if you made a move, and one of the bees ended up at the same vertex with Nastya, your program must stop working, or if Nastya made a move and ended up at the same vertex with one of the bees, you should not make your move and the program should stop working.

If the number of moves exceeds limit ($n$, where $n$ is the number of vertices), you will get the Wrong Answer verdict.

Your solution may receive the verdict Idleness Limit Exceeded if you don't output anything or forget to flush the output buffer.

To flush the output buffer, you need to do the following immediately after printing the query and the line end:

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

In this problem interactor is adaptive. This means that depending on all your previous moves, Nastya's behavior may change.

Examples

Input

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

Output

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

Input

```
8 9
1 2
2 3
3 4
4 5
5 1
5 6
6 7
7 8
8 4
1
5
```

Output

```
7 3 3
6 2 2
5 3 1
```

Note

Let Nastya be a green chip, and three numbered red ones are three bees.

In the first test, the movement of the heroes looks like this.

 ![](https://espresso.codeforces.com/681226301bceb8882bbd73c62195ea5e0cd934f4.png) After selecting the starting vertices.  ![](https://espresso.codeforces.com/e74b5dfad9cb0b1679c38e835016a5d04762021a.png) The first move after the bees move.  ![](https://espresso.codeforces.com/fc9f6c44b3c02e114d39af25d4f8f22e208d5fad.png) The first move after the Nastya's move. The first bee caught Nastya.

In the second test, the movement of the heroes looks like this.

 ![](https://espresso.codeforces.com/0945063f5bde2c495484066cb15e6ffc4b59af1f.png) After selecting the starting vertices.  ![](https://espresso.codeforces.com/ee8ff1f13c25ad4d025d01d85ea7ce55a941de51.png) The first move after the bees move.  ![](https://espresso.codeforces.com/d543d752047d335962f95d72004206da230cfe16.png) The first move after the Nastya's move.  ![](https://espresso.codeforces.com/82ba746a8735c7d033253a8808217df3430971cf.png) The second move after the bees move. The first bee caught Nastya.

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

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

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

    }
}

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

static bool parseLL(const string& s, long long& out) {
    if (s.empty()) return false;
    int i = 0;
    int sign = 1;
    if (s[i] == '+' || s[i] == '-') {
        if (s[i] == '-') sign = -1;
        i++;
    }
    if (i >= (int)s.size()) return false;
    long long val = 0;
    for (; i < (int)s.size(); i++) {
        unsigned char c = (unsigned char)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 = sign * val;
    return true;
}

static bool readThreeVertices(int& a, int& b, int& c) {
    string sa, sb, sc;
    if (!(cin >> sa)) return false;
    if (!(cin >> sb)) return false;
    if (!(cin >> sc)) return false;
    long long la, lb, lc;
    if (!parseLL(sa, la) || !parseLL(sb, lb) || !parseLL(sc, lc)) return false;
    if (la < INT_MIN || la > INT_MAX || lb < INT_MIN || lb > INT_MAX || lc < INT_MIN || lc > INT_MAX) return false;
    a = (int)la;
    b = (int)lb;
    c = (int)lc;
    return true;
}

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

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

    int n = inf.readInt(4, 5000, "n");
    int m = inf.readInt(n, 3 * n, "m");

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

    vector<int> script;
    script.reserve(n + 2);
    while (true) {
        inf.skipBlanks();
        if (inf.eof()) break;
        int x = inf.readInt(1, n, "script_pos");
        script.push_back(x);
    }

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

    log_metrics();

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

    auto isAdjOrSame = [&](int from, int to) -> bool {
        if (from == to) return true;
        for (int nei : g[from]) if (nei == to) return true;
        return false;
    };
    auto isAdjStrict = [&](int from, int to) -> bool {
        if (from == to) return false;
        for (int nei : g[from]) if (nei == to) return true;
        return false;
    };
    auto deterministicNext = [&](int cur) -> int {
        int best = -1;
        for (int nei : g[cur]) {
            if (best == -1 || nei < best) best = nei;
        }
        if (best == -1) finish(_pe, "graph has isolated vertex (unexpected)");
        if (best == cur) finish(_pe, "deterministicNext produced non-move (unexpected)");
        return best;
    };
    auto scriptedOrDet = [&](int idx, int cur) -> int {
        if (idx >= 0 && idx < (int)script.size()) {
            int nxt = script[idx];
            if (1 <= nxt && nxt <= n && isAdjStrict(cur, nxt)) return nxt;
        }
        return deterministicNext(cur);
    };

    int b1, b2, b3;
    if (!readThreeVertices(b1, b2, b3)) finish(_pe, "failed to read initial bee positions (expected 3 integers)");
    if (b1 < 1 || b1 > n || b2 < 1 || b2 > n || b3 < 1 || b3 > n) finish(_wa, "initial bee position out of range");

    array<int,3> bees = {b1, b2, b3};

    int nastya = (script.empty() ? 1 : script[0]);
    if (nastya < 1 || nastya > n) nastya = 1;

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

    if (bees[0] == nastya || bees[1] == nastya || bees[2] == nastya) {
        finish(_ok, "caught at initial placement");
    }

    for (int move = 1; move <= n; move++) {
        int n1, n2, n3;
        if (!readThreeVertices(n1, n2, n3)) finish(_pe, "failed to read bee move (expected 3 integers)");

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

        if (n1 < 1 || n1 > n || n2 < 1 || n2 > n || n3 < 1 || n3 > n) finish(_wa, "bee move out of range");
        if (!isAdjOrSame(bees[0], n1) || !isAdjOrSame(bees[1], n2) || !isAdjOrSame(bees[2], n3)) {
            finish(_wa, "illegal bee move (must stay or move along an edge)");
        }

        bees = {n1, n2, n3};

        if (bees[0] == nastya || bees[1] == nastya || bees[2] == nastya) {
            finish(_ok, "caught after bees move");
        }

        int nextNastya = scriptedOrDet((int)queries, nastya);
        nastya = nextNastya;

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

        if (bees[0] == nastya || bees[1] == nastya || bees[2] == nastya) {
            finish(_ok, "caught after Nastya move");
        }

        if (move == n) {
            finish(_wa, "Nastya escaped after n moves");
        }
    }

    finish(_wa, "unexpected termination");
}

#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 readToken(string& tok) {
    return (cin >> tok) ? true : false;
}

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

static int readIntFromCin(int lo, int hi, const string& ctx) {
    string tok;
    if (!readToken(tok)) finish(_pe, "unexpected eof while reading " + ctx);
    bool ok = false;
    long long x = parseLLStrict(tok, ok);
    if (!ok) finish(_pe, "non-integer token while reading " + ctx);
    if (x < lo || x > hi) finish(_pe, "out of range while reading " + ctx);
    return (int)x;
}

static vector<int> bfsMultiSource(int n, const vector<vector<int>>& adj, const vector<int>& sources) {
    const int INF = 1e9;
    vector<int> dist(n + 1, INF);
    deque<int> q;
    for (int s : sources) {
        if (s < 1 || s > n) continue;
        if (dist[s] == 0) continue;
        dist[s] = 0;
        q.push_back(s);
    }
    while (!q.empty()) {
        int v = q.front();
        q.pop_front();
        int nd = dist[v] + 1;
        for (int to : adj[v]) {
            if (dist[to] > nd) {
                dist[to] = nd;
                q.push_back(to);
            }
        }
    }
    return dist;
}

static bool isNeighbor(const vector<vector<int>>& adj, int u, int v) {
    for (int to : adj[u]) if (to == v) return true;
    return false;
}

static vector<int> expandedSources(int n, const vector<vector<int>>& adj, const array<int, 3>& bees) {
    vector<char> used(n + 1, 0);
    vector<int> src;
    src.reserve(16);
    for (int i = 0; i < 3; i++) {
        int b = bees[i];
        if (b >= 1 && b <= n && !used[b]) {
            used[b] = 1;
            src.push_back(b);
        }
        if (b >= 1 && b <= n) {
            for (int to : adj[b]) {
                if (!used[to]) {
                    used[to] = 1;
                    src.push_back(to);
                }
            }
        }
    }
    return src;
}

static int pickNastyaStart(int n,
                           const vector<vector<int>>& adj,
                           const array<int, 3>& bees) {
    vector<char> occupied(n + 1, 0);
    for (int b : bees) if (b >= 1 && b <= n) occupied[b] = 1;

    vector<int> src0;
    src0.reserve(3);
    for (int b : bees) src0.push_back(b);
    vector<int> dist0 = bfsMultiSource(n, adj, src0);

    vector<int> src1 = expandedSources(n, adj, bees);
    vector<int> dist1 = bfsMultiSource(n, adj, src1);

    int bestV = -1;
    int bestD1 = -1, bestD0 = -1, bestDeg = -1;

    for (int v = 1; v <= n; v++) {
        if (occupied[v]) continue;
        int d1 = dist1[v];
        int d0 = dist0[v];
        int dg = (int)adj[v].size();
        if (bestV == -1 ||
            d1 > bestD1 ||
            (d1 == bestD1 && d0 > bestD0) ||
            (d1 == bestD1 && d0 == bestD0 && dg > bestDeg) ||
            (d1 == bestD1 && d0 == bestD0 && dg == bestDeg && v < bestV)) {
            bestV = v;
            bestD1 = d1;
            bestD0 = d0;
            bestDeg = dg;
        }
    }
    if (bestV == -1) finish(_fail, "internal: no valid start for Nastya");
    return bestV;
}

static int pickNastyaMove(int n,
                          const vector<vector<int>>& adj,
                          int curNastya,
                          const array<int, 3>& bees) {
    if (curNastya < 1 || curNastya > n) finish(_fail, "internal: Nastya out of range");
    const auto& nbrs = adj[curNastya];
    if (nbrs.empty()) finish(_fail, "internal: Nastya has no legal move");

    vector<int> src0;
    src0.reserve(3);
    for (int b : bees) src0.push_back(b);
    vector<int> dist0 = bfsMultiSource(n, adj, src0);

    vector<int> src1 = expandedSources(n, adj, bees);
    vector<int> dist1 = bfsMultiSource(n, adj, src1);

    int bestV = -1;
    int bestD1 = -1, bestD0 = -1, bestDeg = -1;

    for (int v : nbrs) {
        int d1 = dist1[v];
        int d0 = dist0[v];
        int dg = (int)adj[v].size();
        if (bestV == -1 ||
            d1 > bestD1 ||
            (d1 == bestD1 && d0 > bestD0) ||
            (d1 == bestD1 && d0 == bestD0 && dg > bestDeg) ||
            (d1 == bestD1 && d0 == bestD0 && dg == bestDeg && v < bestV)) {
            bestV = v;
            bestD1 = d1;
            bestD0 = d0;
            bestDeg = dg;
        }
    }
    if (bestV == -1) finish(_fail, "internal: no move picked for Nastya");
    return bestV;
}

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

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

    int n = inf.readInt(4, 5000, "n");
    int m = inf.readInt(n, 3 * n, "m");

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

    auto addAdjUnique = [&](int u, int v) {
        for (int to : adj[u]) if (to == v) return;
        adj[u].push_back(v);
    };

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

    query_limit = n;
    log_metrics();

    cout << n << ' ' << m << '\n';
    for (auto& e : edges) {
        cout << e.first << ' ' << e.second << '\n';
    }
    cout.flush();

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

    array<int, 3> bees;
    bees[0] = readIntFromCin(1, n, "initial bee 1");
    bees[1] = readIntFromCin(1, n, "initial bee 2");
    bees[2] = readIntFromCin(1, n, "initial bee 3");

    int nastya = pickNastyaStart(n, adj, bees);
    if (nastya == bees[0] || nastya == bees[1] || nastya == bees[2]) {
        finish(_fail, "internal: Nastya started on a bee vertex");
    }

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

    for (int move = 1; move <= n; move++) {
        array<int, 3> nextBees;
        nextBees[0] = readIntFromCin(1, n, "bee move vertex 1");
        nextBees[1] = readIntFromCin(1, n, "bee move vertex 2");
        nextBees[2] = readIntFromCin(1, n, "bee move vertex 3");

        for (int i = 0; i < 3; i++) {
            int from = bees[i];
            int to = nextBees[i];
            if (to == from) continue;
            if (!isNeighbor(adj, from, to)) {
                finish(_pe, "illegal bee move (not adjacent)");
            }
        }
        bees = nextBees;

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

        if (bees[0] == nastya || bees[1] == nastya || bees[2] == nastya) {
            finish(_ok, "caught Nastya after bees move");
        }

        int nextNastya = pickNastyaMove(n, adj, nastya, bees);
        if (!isNeighbor(adj, nastya, nextNastya)) {
            finish(_fail, "internal: picked non-adjacent Nastya move");
        }
        nastya = nextNastya;

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

        if (bees[0] == nastya || bees[1] == nastya || bees[2] == nastya) {
            finish(_ok, "caught Nastya after Nastya move");
        }
    }

    finish(_wa, "not caught within n moves");
}

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

struct Builder {
    int targetN;
    int curN;
    vector<int> deg;
    vector<pair<int,int>> edges;
    vector<int> frontier;
    vector<char> sealed;
    unordered_set<long long> exist;

    explicit Builder(int targetN_) : targetN(targetN_), curN(0) {
        deg.assign(targetN + 1, 0);
        edges.reserve(3 * targetN + 5);
        sealed.reserve(3 * targetN + 5);
        frontier.reserve(3 * targetN + 5);
        exist.reserve((size_t)(6 * targetN + 100));
        exist.max_load_factor(0.7f);
    }

    static long long keyOf(int u, int v) {
        if (u > v) swap(u, v);
        return 1LL * u * 100000LL + v;
    }

    int newVertex() {
        if (curN >= targetN) quitf(_fail, "internal: exceeded targetN");
        return ++curN;
    }

    int addEdge(int u, int v) {
        if (u == v) quitf(_fail, "loop edge attempted");
        if (u < 1 || v < 1 || u > targetN || v > targetN) quitf(_fail, "vertex out of range");
        long long k = keyOf(u, v);
        if (exist.find(k) != exist.end()) {
            quitf(_fail, "duplicate edge attempted: %d %d", u, v);
        }
        exist.insert(k);
        edges.push_back({u, v});
        sealed.push_back(0);
        deg[u]++, deg[v]++;
        if (deg[u] > 3 || deg[v] > 3) quitf(_fail, "degree exceeded 3");
        return (int)edges.size() - 1;
    }

    bool isAttachableEdge(int eid) const {
        if (eid < 0 || eid >= (int)edges.size()) return false;
        if (sealed[eid]) return false;
        int u = edges[eid].first;
        int v = edges[eid].second;
        return deg[u] == 2 && deg[v] == 2;
    }

    bool isAttachableEdgeExcluding(int eid, int ex1, int ex2) const {
        if (!isAttachableEdge(eid)) return false;
        int u = edges[eid].first;
        int v = edges[eid].second;
        if (u == ex1 || u == ex2 || v == ex1 || v == ex2) return false;
        return true;
    }

    int takeAnyAttachableEdge(int ex1 = -1, int ex2 = -1) {
        for (int it = 0; it < 2000 && !frontier.empty(); it++) {
            int idx = rnd.next(0, (int)frontier.size() - 1);
            int eid = frontier[idx];
            frontier[idx] = frontier.back();
            frontier.pop_back();
            if (isAttachableEdgeExcluding(eid, ex1, ex2)) {
                sealed[eid] = 1;
                return eid;
            }
        }
        for (int eid = 0; eid < (int)edges.size(); eid++) {
            if (isAttachableEdgeExcluding(eid, ex1, ex2)) {
                sealed[eid] = 1;
                return eid;
            }
        }
        quitf(_fail, "no attachable edge found");
        return -1;
    }

    void addBaseCycle(int len) {
        vector<int> v(len);
        for (int i = 0; i < len; i++) v[i] = newVertex();
        for (int i = 0; i < len; i++) {
            int a = v[i];
            int b = v[(i + 1) % len];
            int eid = addEdge(a, b);
            frontier.push_back(eid);
        }
    }

    vector<int> attachPentagonOnSealedEdge(int eidSealed) {
        int u = edges[eidSealed].first;
        int v = edges[eidSealed].second;
        if (deg[u] != 2 || deg[v] != 2) quitf(_fail, "attachPentagon: endpoints not degree 2");
        int a = newVertex();
        int b = newVertex();
        int c = newVertex();
        int e1 = addEdge(v, a);
        int e2 = addEdge(a, b);
        int e3 = addEdge(b, c);
        int e4 = addEdge(c, u);
        (void)e1; (void)e4;
        frontier.push_back(e2);
        frontier.push_back(e3);
        return {e2, e3};
    }

    vector<int> attachSquareOnSealedEdge(int eidSealed) {
        int u = edges[eidSealed].first;
        int v = edges[eidSealed].second;
        if (deg[u] != 2 || deg[v] != 2) quitf(_fail, "attachSquare: endpoints not degree 2");
        int x = newVertex();
        int y = newVertex();
        int e1 = addEdge(v, x);
        int e2 = addEdge(x, y);
        int e3 = addEdge(y, u);
        (void)e1; (void)e3;
        frontier.push_back(e2);
        return {e2};
    }

    vector<int> attachTriangleOnSealedEdge(int eidSealed) {
        int u = edges[eidSealed].first;
        int v = edges[eidSealed].second;
        if (deg[u] != 2 || deg[v] != 2) quitf(_fail, "attachTriangle: endpoints not degree 2");
        int w = newVertex();
        addEdge(u, w);
        addEdge(v, w);
        return {};
    }

    void buildRandom(int squarePct, int branchPct, bool preferPentagons) {
        if (targetN == 4) {
            addBaseCycle(4);
            return;
        }
        if (targetN < 4) quitf(_fail, "n must be >= 4");

        if (targetN >= 5) addBaseCycle(5);
        else addBaseCycle(4);

        int tail = takeAnyAttachableEdge();
        while (curN < targetN) {
            if (!isAttachableEdge(tail)) {
                tail = takeAnyAttachableEdge();
            } else {
                sealed[tail] = 1;
            }

            int remaining = targetN - curN;
            vector<int> candidates;

            if (remaining == 1) {
                candidates = attachTriangleOnSealedEdge(tail);
            } else if (remaining == 2) {
                candidates = attachSquareOnSealedEdge(tail);
            } else {
                bool makeSquare = false;
                if (!preferPentagons && remaining >= 2) {
                    int roll = rnd.next(0, 99);
                    if (roll < squarePct) makeSquare = true;
                }
                if (makeSquare && remaining == 3) makeSquare = false;
                if (makeSquare) candidates = attachSquareOnSealedEdge(tail);
                else candidates = attachPentagonOnSealedEdge(tail);
            }

            if (!candidates.empty()) {
                tail = candidates[rnd.next(0, (int)candidates.size() - 1)];
            }

            if (branchPct > 0 && curN < targetN && !candidates.empty()) {
                int roll = rnd.next(0, 99);
                if (roll < branchPct) {
                    int tu = edges[tail].first;
                    int tv = edges[tail].second;
                    int rem2 = targetN - curN;
                    if (rem2 >= 3) {
                        int beid = takeAnyAttachableEdge(tu, tv);
                        attachPentagonOnSealedEdge(beid);
                    }
                }
            }
        }

        for (int i = 1; i <= curN; i++) {
            if (deg[i] < 1 || deg[i] > 3) quitf(_fail, "invalid degree on vertex %d: %d", i, deg[i]);
        }
    }
};

static void outputGraph(int n, const vector<pair<int,int>>& edges) {
    cout << n << " " << (int)edges.size() << "\n";
    for (auto &e : edges) cout << e.first << " " << e.second << "\n";
}

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

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

    int forcedN = opt<int>("n", 0);
    int targetN;
    if (forcedN > 0) targetN = forcedN;
    else {
        if (seed == 1) targetN = 4;
        else if (seed == 2) targetN = 5;
        else if (seed == 3) targetN = 8;
        else targetN = (mode == "adp" ? 5000 : 5000);
    }

    targetN = max(4, min(5000, targetN));

    if (forcedN == 0 && seed == 1) {
        vector<pair<int,int>> edges;
        edges.push_back({1, 2});
        edges.push_back({2, 3});
        edges.push_back({3, 4});
        edges.push_back({4, 1});
        outputGraph(4, edges);
        return 0;
    }
    if (forcedN == 0 && seed == 2) {
        vector<pair<int,int>> edges;
        edges.push_back({1, 2});
        edges.push_back({2, 3});
        edges.push_back({3, 4});
        edges.push_back({4, 5});
        edges.push_back({5, 1});
        outputGraph(5, edges);
        return 0;
    }
    if (forcedN == 0 && seed == 3) {
        vector<pair<int,int>> edges;

        edges.push_back({1, 2});
        edges.push_back({2, 3});
        edges.push_back({3, 4});
        edges.push_back({4, 5});
        edges.push_back({5, 1});
        edges.push_back({2, 6});
        edges.push_back({6, 7});
        edges.push_back({7, 8});
        edges.push_back({8, 1});
        outputGraph(8, edges);
        return 0;
    }

    int squarePct = opt<int>("square", mode == "adp" ? 2 : 12);
    int branchPct = opt<int>("branch", mode == "adp" ? 0 : 10);

    squarePct = max(0, min(60, squarePct));
    branchPct = max(0, min(60, branchPct));

    Builder b(targetN);

    if (mode == "adp") {

        b.buildRandom(squarePct, branchPct, true);
    } else if (mode == "non") {

        b.buildRandom(squarePct, branchPct, false);
    } else {
        quitf(_fail, "unknown mode: %s", mode.c_str());
    }

    outputGraph(b.curN, b.edges);
    return 0;
}


D. Finding lines

After some programming contest Roma decided to try himself in tourism. His home country Uzhlyandia is a Cartesian plane. He wants to walk along each of the Main Straight Lines in Uzhlyandia. It is known that each of these lines is a straight line parallel to one of the axes (i.e. it is described with the equation *x* = *a* or *y* = *a*, where *a* is integer called the coordinate of this line).

Roma lost his own map, so he should find out the coordinates of all lines at first. Uncle Anton agreed to help him, using the following rules:

* Initially Roma doesn't know the number of vertical and horizontal lines and their coordinates;
* Roma can announce integer coordinates of some point in Uzhlandia, and Anton then will tell him the minimum among the distances from the chosen point to each of the lines. However, since the coordinates of the lines don't exceed 108 by absolute value, Roma can't choose a point with coordinates exceeding 108 by absolute value.

Uncle Anton is in a hurry to the UOI (Uzhlandian Olympiad in Informatics), so he can only answer no more than 3·105 questions.

The problem is that Roma doesn't know how to find out the coordinates of the lines. Write a program that plays Roma's role and finds the coordinates.

Input

There is no input initially. Your program should make queries to get information.

It is guaranteed that the number of horizontal and vertical lines is at least 1 and less than or equal to 104 for each type.

Interaction

To make a query, print a line "0 x y" (-108 ≤ *x*, *y* ≤ 108), where *x* and *y* are the coordinates of the point. After each query you need to print end-of-line, make "flush" operation, and then read the answer to the query — the minimum among the distances prom this point to the Main Straight Lines of Uzhlyandia.

You can do no more than 3·105 queries.

When you are ready to print the answer, print three lines:

1. In the first line print "1 n m", where *n* is the number of vertical lines (parallel to *OY*), and *m* is the number of horizontal lines (parallel to *OX*).
2. In the second line print *n* integers *x*1, *x*2, ..., *x**n* — the coordinates of the vertical lines.
3. In the third line in the same format print *m* integers *y*1, *y*2, ..., *y**m* — the coordinates of the horizontal lines.

You can print coordinates in arbitrary order.

To make "flush", you can use (just after printing a query/answer 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.

You will get Wrong Answer if you make more queries than allowed or make an invalid query.

You can get Idleness Limit Exceeded if you don't print anything or if you forget to flush the output.

If at any moment your program reads -1 as an answer, it should immediately exit normally (for example, by calling exit(0)). You will get Wrong Answer in this case, it means that you made more queries than allowed, or made an invalid query. If you ignore this, you can get other verdicts since your program will continue to read from a closed stream.

Example

Input

```
1
1
3
2
```

Output

```
0 1 2
0 -2 -2
0 5 6
0 -2 2
1 1 2
2
0 -3
```

Note

The example test is

```
1 2
2
0 -3
```

The minimum distances are:

* from (1, 2) to *x* = 2;
* from ( - 2,  - 2) to *y* =  - 3;
* from (5, 6) to *x* = 2;
* from ( - 2, 2) to *y* = 0.

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

using namespace std;

static long long queries = 0;
static const long long query_limit = 300000;
static bool finished_logging = false;

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

    }
}

static void finish_verdict(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();
    int m = inf.readInt();

    vector<int> true_x;
    true_x.reserve(n);
    for (int i = 0; i < n; ++i) {
        true_x.push_back(inf.readInt());
    }

    vector<int> true_y;
    true_y.reserve(m);
    for (int i = 0; i < m; ++i) {
        true_y.push_back(inf.readInt());
    }

    sort(true_x.begin(), true_x.end());
    sort(true_y.begin(), true_y.end());

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish_verdict(_wa, "Unexpected EOF (solution exited without answer)");
        }

        bool is_query = (token == "0" || token == "?" || (token.size() > 0 && token[0] == '?'));
        bool is_answer = (token == "1" || token == "!" || (token.size() > 0 && token[0] == '!'));

        if (is_query) {
            queries++;

            if (queries > query_limit) {
                cout << -1 << endl;
                finish_verdict(_wa, "Query limit exceeded");
            }

            int qx, qy;
            if (!(cin >> qx >> qy)) {
                finish_verdict(_wa, "Invalid query format (expected 2 integers)");
            }

            if (abs(qx) > 100000000 || abs(qy) > 100000000) {
                finish_verdict(_wa, "Query coordinates out of range [-10^8, 10^8]");
            }

            long long ans = 2000000000LL;

            auto itx = lower_bound(true_x.begin(), true_x.end(), qx);
            if (itx != true_x.end()) {
                ans = min(ans, (long long)abs((long long)*itx - qx));
            }
            if (itx != true_x.begin()) {
                ans = min(ans, (long long)abs((long long)*prev(itx) - qx));
            }

            auto ity = lower_bound(true_y.begin(), true_y.end(), qy);
            if (ity != true_y.end()) {
                ans = min(ans, (long long)abs((long long)*ity - qy));
            }
            if (ity != true_y.begin()) {
                ans = min(ans, (long long)abs((long long)*prev(ity) - qy));
            }

            cout << ans << endl;
        }
        else if (is_answer) {

            int an, am;
            if (!(cin >> an >> am)) {
                finish_verdict(_wa, "Invalid answer format (expected n m)");
            }

            if (an < 0 || an > 20000 || am < 0 || am > 20000) {
                finish_verdict(_wa, "Answer counts out of reasonable range");
            }

            vector<int> ax(an), ay(am);

            for (int i = 0; i < an; ++i) {
                if (!(cin >> ax[i])) finish_verdict(_wa, "Invalid answer format (reading x)");
            }

            for (int i = 0; i < am; ++i) {
                if (!(cin >> ay[i])) finish_verdict(_wa, "Invalid answer format (reading y)");
            }

            sort(ax.begin(), ax.end());
            sort(ay.begin(), ay.end());

            if (ax == true_x && ay == true_y) {
                finish_verdict(_ok, "Correct lines found");
            } else {
                finish_verdict(_wa, "Incorrect lines found");
            }
        }
        else {

            finish_verdict(_wa, "Invalid token '" + token + "' (expected 0 or 1)");
        }
    }

    return 0;
}

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

using namespace std;

const int MIN_COORD = -100000000;
const int MAX_COORD = 100000000;
const long long HARD_CAP = 3000000;

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

vector<int> hidden_x;
vector<int> hidden_y;

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

vector<int> generate_coords(int k, int seed_salt) {
    vector<int> res;
    set<int> taken;

    long long state = 5489LL * k + 7919LL * seed_salt + 12345;

    int attempts = 0;
    while(res.size() < (size_t)k) {
        attempts++;
        state = (state * 48271LL) % 2147483647LL;

        long long val = state % 200000001;
        val -= 100000000;

        if (taken.find((int)val) == taken.end()) {
            taken.insert((int)val);
            res.push_back((int)val);
        }

        if (attempts > k * 10 && res.size() < (size_t)k) {
            int needed = k - res.size();
            int start = MIN_COORD;
            while (needed > 0) {
                if (taken.find(start) == taken.end()) {
                    res.push_back(start);
                    needed--;
                }
                start++;
            }
            break;
        }
    }
    sort(res.begin(), res.end());
    return res;
}

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

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

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

    if (inf.seekEof()) {

        hidden_x = generate_coords(n, 1);
        hidden_y = generate_coords(m, 2);
    } else {

        for (int i = 0; i < n; i++) {
            hidden_x.push_back(inf.readInt(MIN_COORD, MAX_COORD, "x_i"));
        }
        for (int i = 0; i < m; i++) {
            hidden_y.push_back(inf.readInt(MIN_COORD, MAX_COORD, "y_i"));
        }
        sort(hidden_x.begin(), hidden_x.end());
        sort(hidden_y.begin(), hidden_y.end());
    }

    log_metrics();

    while (true) {

        string type_str;

        if (!(cin >> type_str)) {

            finish(_wa, "Unexpected end of stream (output closed?)");
        }

        if (type_str == "0") {

            long long x, y;
            if (!(cin >> x >> y)) {
                finish(_wa, "Invalid format for query type 0");
            }

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

            queries++;

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

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

            long long min_dist = 2000000000LL;

            auto it_x = lower_bound(hidden_x.begin(), hidden_x.end(), (int)x);
            if (it_x != hidden_x.end()) {
                min_dist = min(min_dist, abs((long long)*it_x - x));
            }
            if (it_x != hidden_x.begin()) {
                min_dist = min(min_dist, abs((long long)*prev(it_x) - x));
            }

            auto it_y = lower_bound(hidden_y.begin(), hidden_y.end(), (int)y);
            if (it_y != hidden_y.end()) {
                min_dist = min(min_dist, abs((long long)*it_y - y));
            }
            if (it_y != hidden_y.begin()) {
                min_dist = min(min_dist, abs((long long)*prev(it_y) - y));
            }

            cout << min_dist << endl;

        } else if (type_str == "1") {

            int ans_n, ans_m;
            if (!(cin >> ans_n >> ans_m)) {
                finish(_wa, "Invalid format for answer type 1");
            }

            if (ans_n != (int)hidden_x.size() || ans_m != (int)hidden_y.size()) {
                finish(_wa, format("Incorrect counts: expected %d %d, got %d %d",
                                   (int)hidden_x.size(), (int)hidden_y.size(), ans_n, ans_m));
            }

            vector<int> ans_x(ans_n), ans_y(ans_m);
            for (int i = 0; i < ans_n; i++) {
                if (!(cin >> ans_x[i])) finish(_wa, "Failed reading vertical lines answer");
            }
            for (int i = 0; i < ans_m; i++) {
                if (!(cin >> ans_y[i])) finish(_wa, "Failed reading horizontal lines answer");
            }

            sort(ans_x.begin(), ans_x.end());
            sort(ans_y.begin(), ans_y.end());

            if (ans_x != hidden_x) {
                finish(_wa, "Vertical lines incorrect");
            }
            if (ans_y != hidden_y) {
                finish(_wa, "Horizontal lines incorrect");
            }

            finish(_ok, "Correct");

        } else {
            finish(_wa, "Unknown command type (expected 0 or 1)");
        }
    }

    return 0;
}

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

using namespace std;

const int MIN_COORD = -100000000;
const int MAX_COORD = 100000000;
const int MIN_NM = 1;
const int MAX_NM = 10000;

vector<int> generate_coords(int k, int min_v, int max_v, int type) {
    vector<int> res;

    long long range_len = (long long)max_v - min_v + 1;
    if (range_len < k) {
        for (int i = 0; i < k; i++) res.push_back(min_v + i);
        return res;
    }

    if (type == 1) {
        set<int> taken;
        int center = rnd.next(min_v, max_v);

        int radius = rnd.next(k, 200000);
        int l = max(min_v, center - radius);
        int r = min(max_v, center + radius);

        if ((long long)r - l + 1 < k) {
            l = min_v; r = max_v;
        }

        if ((long long)r - l + 1 < 2LL * k) {
             vector<int> p(r - l + 1);
             iota(p.begin(), p.end(), l);
             shuffle(p.begin(), p.end());

             res.clear();

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

                 int j = rnd.next(i, (int)p.size() - 1);
                 swap(p[i], p[j]);
                 res.push_back(p[i]);
             }
        } else {

             while ((int)taken.size() < k) {
                int x = rnd.next(l, r);
                if (taken.insert(x).second) res.push_back(x);
             }
        }
    } else if (type == 2) {
        int start = rnd.next(min_v, max_v - k + 1);
        for (int i = 0; i < k; ++i) {
            res.push_back(start + i);
        }
    } else if (type == 3) {

        long long total_gap = (long long)max_v - min_v + 1 - k;
        vector<long long> gaps = rnd.partition(k + 1, total_gap);
        long long current = min_v;
        for (int i = 0; i < k; i++) {
            current += gaps[i];
            res.push_back((int)current);
            current++;
        }
    } else {
        set<int> taken;
        while ((int)taken.size() < k) {
            int x = rnd.next(min_v, max_v);
            if (taken.insert(x).second) res.push_back(x);
        }
    }

    sort(res.begin(), res.end());
    return res;
}

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

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

    int seed_val = 0;
    try {
        if (argc > 1) seed_val = stoi(argv[1]);
    } catch (...) {
        seed_val = 100;
    }

    int n, m;
    if (seed_val == 1) {
        n = 1; m = 1;
    } else if (seed_val == 2) {
        n = 1; m = MAX_NM;
    } else if (seed_val == 3) {
        n = MAX_NM; m = 1;
    } else if (seed_val == 4) {
        n = 100; m = 100;
    } else if (seed_val == 5) {
        n = MAX_NM; m = MAX_NM;
    } else {

        int dice = rnd.next(100);
        if (dice < 10) {
            n = rnd.next(1, 10);
            m = rnd.next(1, 10);
        } else if (dice < 30) {
            n = rnd.next(10, 100);
            m = rnd.next(10, 100);
        } else if (dice < 60) {
             n = rnd.next(100, 5000);
             m = rnd.next(100, 5000);
        } else {
             n = rnd.next(5000, MAX_NM);
             m = rnd.next(5000, MAX_NM);
        }
    }

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

    vector<int> xs, ys;

    if (seed_val == 1) {
        xs = {0};
        ys = {0};
    } else if (seed_val == 2) {
        xs = {-100000000};
        ys = generate_coords(m, MIN_COORD, MAX_COORD, 0);
    } else if (seed_val == 3) {
        xs = generate_coords(n, MIN_COORD, MAX_COORD, 0);
        ys = {100000000};
    } else {

        int typeX = (seed_val == 4) ? 1 : (rnd.next(10) < 3 ? 2 : (rnd.next(10) < 3 ? 3 : 0));
        int typeY = (seed_val == 4) ? 1 : (rnd.next(10) < 3 ? 2 : (rnd.next(10) < 3 ? 3 : 0));

        if (seed_val > 5 && typeX == 2 && typeY == 2) typeY = 0;

        xs = generate_coords(n, MIN_COORD, MAX_COORD, typeX);
        ys = generate_coords(m, MIN_COORD, MAX_COORD, typeY);
    }

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

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

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

    return 0;
}