The only difference between the easy and hard versions is the constraints on the number of queries.

This is an interactive problem.

Ridbit has a hidden array $a$ of $n$ integers which he wants Ashish to guess. Note that $n$ is a power of two. Ashish is allowed to ask three different types of queries. They are of the form

* AND $i$ $j$: ask for the bitwise AND of elements $a_i$ and $a_j$ $(1 \leq i, j \le n$, $i \neq j)$
* OR $i$ $j$: ask for the bitwise OR of elements $a_i$ and $a_j$ $(1 \leq i, j \le n$, $i \neq j)$
* XOR $i$ $j$: ask for the bitwise XOR of elements $a_i$ and $a_j$ $(1 \leq i, j \le n$, $i \neq j)$

Can you help Ashish guess the elements of the array?

In this version, each element takes a value in the range $[0, n-1]$ (inclusive) and Ashish can ask no more than $n+1$ queries.

Input

The first line of input contains one integer $n$ $(4 \le n \le 2^{16})$ — the length of the array. It is guaranteed that $n$ is a power of two.

Interaction

To ask a query print a single line containing one of the following (without quotes)

* "AND i j"
* "OR i j"
* "XOR i j"

where $i$ and $j$ $(1 \leq i, j \le n$, $i \neq j)$ denote the indices being queried.

For each query, you will receive an integer $x$ whose value depends on the type of query. If the indices queried are invalid or you exceed the number of queries however, you will get $x = -1$. In this case, you should terminate the program immediately.

When you have guessed the elements of the array, print a single line "! " (without quotes), followed by $n$ space-separated integers  — the elements of the array.

Guessing the array does not count towards the number of queries asked.

The interactor is not adaptive. The array $a$ does not change with queries.

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

```
4

0

2

3
```

Output

```
OR 1 2

OR 2 3

XOR 2 4! 0 0 2 3
```

Note

The array $a$ in the example is $[0, 0, 2, 3]$.

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

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

static void log_metrics() {
    try {
        tout << "queries=" << queries << 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 isPow2(int x) { return x >= 1 && (x & (x - 1)) == 0; }

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

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

    int n = inf.readInt(4, 1 << 16, "n");
    if (!isPow2(n)) finish(_pe, "n is not a power of two in hidden input");

    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        a[i] = inf.readInt(0, n - 1, ("a[" + to_string(i) + "]").c_str());
    }

    query_limit = (long long)n + 1;
    log_metrics();

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

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

    while (true) {
        string cmd;
        if (!(cin >> cmd)) {
            finish(_pe, "Unexpected EOF from contestant (no final answer)");
        }
        cmd = toUpperStr(cmd);

        if (cmd == "!") {
            vector<int> ans(n + 1);
            for (int i = 1; i <= n; i++) {
                long long x;
                if (!(cin >> x)) finish(_pe, "Could not read full answer array after '!'");
                if (x < 0 || x > n - 1) finish(_wa, "Answer element out of allowed range");
                ans[i] = (int)x;
            }
            for (int i = 1; i <= n; i++) {
                if (ans[i] != a[i]) finish(_wa, "Wrong array");
            }
            finish(_ok, "Correct");
        }

        if (cmd != "AND" && cmd != "OR" && cmd != "XOR") {
            cout << -1 << endl;
            cout.flush();
            finish(_pe, "Invalid command token");
        }

        long long i, j;
        if (!(cin >> i >> j)) {
            finish(_pe, "Could not read query indices");
        }

        if (i < 1 || i > n || j < 1 || j > n || i == j) {
            cout << -1 << endl;
            cout.flush();
            finish(_pe, "Invalid query indices");
        }

        int ai = a[(int)i], aj = a[(int)j];
        int res = 0;
        if (cmd == "AND") res = (ai & aj);
        else if (cmd == "OR") res = (ai | aj);
        else res = (ai ^ aj);

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

        cout << res << endl;
        cout.flush();
    }
}

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

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

static int clampPow2InRange(int n) {
    n = max(n, 4);
    n = min(n, 1 << 16);
    if (isPow2(n)) return n;
    int p = 1;
    while (p < n) p <<= 1;
    int lower = p >> 1;
    if (lower >= 4 && (n - lower) <= (p - n)) n = lower;
    else n = p;
    n = min(n, 1 << 16);
    if (n < 4) n = 4;
    return n;
}

static vector<int> permAffine(int n, bool forceNonZeroFirst) {
    int mask = n - 1;
    int mul = rnd.next(1, n - 1) | 1;
    int add;
    if (forceNonZeroFirst && n > 1) add = rnd.next(1, n - 1);
    else add = rnd.next(0, n - 1);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        long long v = 1LL * mul * i + add;
        a[i] = int(v & mask);
    }
    return a;
}

static vector<int> permGrayXor(int n, bool forceNonZeroFirst) {
    int c;
    if (forceNonZeroFirst && n > 1) c = rnd.next(1, n - 1);
    else c = rnd.next(0, n - 1);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        int g = i ^ (i >> 1);
        a[i] = g ^ c;
    }
    return a;
}

static vector<int> permShuffled(int n, bool forceNonZeroFirst) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    for (int i = n - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(p[i], p[j]);
    }
    if (forceNonZeroFirst && n > 1) {
        int want = rnd.next(1, n - 1);
        int pos = 0;
        for (int i = 0; i < n; i++) if (p[i] == want) { pos = i; break; }
        swap(p[0], p[pos]);
    }
    return p;
}

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

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

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

    int n = 0;
    vector<int> a;

    auto outputNon = [&](int nn, const vector<int>& aa) {
        cout << nn << "\n";
        for (int i = 0; i < nn; i++) {
            if (i) cout << ' ';
            cout << aa[i];
        }
        cout << "\n";
    };

    if (seed == 1) {
        n = 4;
        a = {0, 0, 0, 0};
    } else if (seed == 2) {
        n = 4;
        a = {2, 3, 1, 0};
    } else if (seed == 3) {
        n = 8;
        a = {3, 0, 5, 5, 1, 2, 4, 6};
    } else {
        int exp = opt<int>("exp", -1);
        int nOpt = opt<int>("n", 1 << 16);
        if (exp != -1) {
            exp = max(exp, 2);
            exp = min(exp, 16);
            n = 1 << exp;
        } else {
            n = clampPow2InRange(nOpt);
        }

        string kind = opt<string>("kind", "auto");
        string permType = opt<string>("perm", "auto");
        bool forceNonZeroFirst = opt<int>("nonzero_first", 1) != 0;

        if (kind == "auto") {

            if (seed % 17 == 0) kind = "const";
            else if (seed % 11 == 0) kind = "dups";
            else if (seed % 7 == 0) kind = "dups";
            else kind = "perm";
        }

        auto genPerm = [&]() -> vector<int> {
            string t = permType;
            if (t == "auto") {
                if (seed % 6 == 0) t = "gray";
                else if (seed % 2 == 0) t = "affine";
                else t = "shuf";
            }
            if (t == "affine") return permAffine(n, forceNonZeroFirst);
            if (t == "gray") return permGrayXor(n, forceNonZeroFirst);
            return permShuffled(n, forceNonZeroFirst);
        };

        if (kind == "perm") {
            a = genPerm();
        } else if (kind == "const") {
            int v = rnd.next(0, n - 1);
            a.assign(n, v);
        } else {
            a = genPerm();

            int i = rnd.next(1, n - 1);
            int j = rnd.next(1, n - 1);
            while (j == i) j = rnd.next(1, n - 1);
            a[j] = a[i];

            bool addX0 = (seed % 11 == 0);
            if (addX0 && n >= 4) {
                int k = rnd.next(1, n - 1);
                while (k == i || k == j) k = rnd.next(1, n - 1);
                a[k] = a[0];
            }
        }
    }

    if (mode == "adp") {

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

    outputNon(n, a);
    return 0;
}


E. Verifying Kingdom

This is an interactive problem.

The judge has a hidden rooted full binary tree with *n* leaves. A full binary tree is one where every node has either 0 or 2 children. The nodes with 0 children are called the leaves of the tree. Since this is a full binary tree, there are exactly 2*n* - 1 nodes in the tree. The leaves of the judge's tree has labels from 1 to *n*. You would like to reconstruct a tree that is isomorphic to the judge's tree. To do this, you can ask some questions.

A question consists of printing the label of three distinct leaves *a*1, *a*2, *a*3. Let the depth of a node be the shortest distance from the node to the root of the tree. Let *LCA*(*a*, *b*) denote the node with maximum depth that is a common ancestor of the nodes *a* and *b*.

Consider *X* = *LCA*(*a*1, *a*2), *Y* = *LCA*(*a*2, *a*3), *Z* = *LCA*(*a*3, *a*1). The judge will tell you which one of *X*, *Y*, *Z* has the maximum depth. Note, this pair is uniquely determined since the tree is a binary tree; there can't be any ties.

More specifically, if *X* (or *Y*, *Z* respectively) maximizes the depth, the judge will respond with the string "X" (or "Y", "Z" respectively).

You may only ask at most 10·*n* questions.

Input

The first line of input will contain a single integer *n* (3 ≤ *n* ≤ 1 000) — the number of leaves in the tree.

Output

To print the final answer, print out the string "-1" on its own line. Then, the next line should contain 2*n* - 1 integers. The *i*-th integer should be the parent of the *i*-th node, or -1, if it is the root.

Your answer will be judged correct if your output is isomorphic to the judge's tree. In particular, the labels of the leaves do not need to be labeled from 1 to *n*. Here, isomorphic means that there exists a permutation π such that node *i* is the parent of node *j* in the judge tree if and only node π(*i*) is the parent of node π(*j*) in your tree.

Interaction

To ask a question, print out three distinct integers *a*1, *a*2, *a*3. These integers should be between 1 and *n*, inclusive.

The judge will respond with a single character, either "X", "Y", "Z".

If the string is "X" (or "Y", "Z" respectively), that means the pair (*a*1, *a*2) (or (*a*2, *a*3), (*a*3, *a*1) respectively) has the deepest *LCA* among the three pairs.

You may only ask a question at most 10·*n* times, otherwise, you will get Wrong Answer.

When you are ready to answer, print out a single integer "-1" on its own line. The next line should contain 2*n* - 1 integers. The *i*-th integer should be the parent of the *i*-th node, or -1, if it is the root. Do not forget to flush the final answer as well. Printing the answer does not count as asking a question.

You will get Wrong Answer verdict if

* Your question or answers are not in the format described in this statement.
* You ask strictly more than 10·*n* questions.
* Your question contains duplicate indices.
* Your final answer is not isomorphic to the judge tree.

You will get Idleness Limit Exceeded if you don't print anything or if you forget to flush the output, including for the final answer (more info about flushing output below).

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

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

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

```
5
X
Z
Y
Y
X
```

Output

```
1 4 2
1 2 4
2 4 1
2 3 5
2 4 3
-1
-1 1 1 2 2 3 3 6 6
```

Note

For the first sample, the judge has the hidden tree:

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

Here is a more readable format of the interaction:

![](https://espresso.codeforces.com/1cfb86747dfd0278bc848ef24aa3a158e4ce0220.png) The last line can also be 8 6 9 8 9 7 -1 6 7.

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

static int n;
static vector<int> judge_parent;
static vector<vector<int>> judge_adj;
static vector<int> judge_depth;
static int judge_root = -1;

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

void build_judge() {
    judge_adj.assign(2 * n, vector<int>());
    judge_depth.assign(2 * n, 0);

    for (int i = 1; i < 2 * n; i++) {
        int p = judge_parent[i];
        if (p == -1) {
            judge_root = i;
        } else {

            if (p < 1 || p >= 2 * n) {

                quitf(_fail, "Judge tree parent out of range");
            }
            judge_adj[p].push_back(i);
        }
    }

    if (judge_root == -1) {
        quitf(_fail, "No root found in judge tree");
    }

    vector<int> q;
    q.push_back(judge_root);
    judge_depth[judge_root] = 0;

    int head = 0;
    while(head < (int)q.size()) {
        int u = q[head++];
        for(int v : judge_adj[u]) {
            judge_depth[v] = judge_depth[u] + 1;
            q.push_back(v);
        }
    }
}

int get_lca(int u, int v) {
    int du = judge_depth[u];
    int dv = judge_depth[v];

    while (du > dv) {
        u = judge_parent[u];
        du--;
    }
    while (dv > du) {
        v = judge_parent[v];
        dv--;
    }
    while (u != v) {
        u = judge_parent[u];
        v = judge_parent[v];
    }
    return u;
}

string get_canonical(int u, const vector<vector<int>>& adj) {
    if (adj[u].empty()) return "1";

    vector<string> subs;
    for (int v : adj[u]) {
        subs.push_back(get_canonical(v, adj));
    }
    sort(subs.begin(), subs.end());

    string res = "0";
    for (const auto& s : subs) res += s;
    return res;
}

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

    n = inf.readInt();
    query_limit = 10LL * n;

    judge_parent.assign(2 * n, 0);
    for (int i = 1; i < 2 * n; i++) {
        judge_parent[i] = inf.readInt();
    }

    build_judge();

    cout << n << endl;

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

            finish(_wa, "Unexpected EOF waiting for query/answer");
        }

        if (token == "!") {
            continue;
        }

        if (token == "-1") {

            break;
        }

        int a1, a2, a3;

        if (token == "?") {
            if (!(cin >> a1 >> a2 >> a3)) {
                finish(_wa, "Incomplete query format");
            }
        } else {

            try {
                a1 = stoi(token);
            } catch (...) {
                finish(_wa, "Invalid token in query");
            }
            if (a1 == -1) break;

            if (!(cin >> a2 >> a3)) {
                finish(_wa, "Incomplete query format");
            }
        }

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

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

        if (a1 < 1 || a1 > n || a2 < 1 || a2 > n || a3 < 1 || a3 > n) {
            finish(_wa, "Query indices must be leaves 1..n");
        }
        if (a1 == a2 || a1 == a3 || a2 == a3) {
            finish(_wa, "Query indices must be distinct");
        }

        int X = get_lca(a1, a2);
        int Y = get_lca(a2, a3);
        int Z = get_lca(a3, a1);

        int dX = judge_depth[X];
        int dY = judge_depth[Y];
        int dZ = judge_depth[Z];

        if (dX >= dY && dX >= dZ) cout << "X" << endl;
        else if (dY >= dX && dY >= dZ) cout << "Y" << endl;
        else cout << "Z" << endl;
    }

    vector<int> user_p(2 * n);
    for (int i = 1; i < 2 * n; i++) {
        if (!(cin >> user_p[i])) {
            finish(_wa, "Incomplete answer (expected 2n-1 integers)");
        }
    }

    vector<vector<int>> user_adj(2 * n);
    int user_root = -1;
    int root_count = 0;

    for (int i = 1; i < 2 * n; i++) {
        int p = user_p[i];
        if (p == -1) {
            user_root = i;
            root_count++;
        } else {
            if (p < 1 || p >= 2 * n) finish(_wa, "Parent index out of range");
            if (p == i) finish(_wa, "Self loop in tree");
            user_adj[p].push_back(i);
        }
    }

    if (root_count != 1) finish(_wa, "Tree must have exactly one root");
    if (user_root == -1) finish(_wa, "No root found");

    int seen = 0;
    vector<bool> vis(2 * n, false);
    vector<int> q;
    q.push_back(user_root);
    vis[user_root] = true;
    seen++;

    int head = 0;
    while(head < (int)q.size()){
        int u = q[head++];
        for(int v : user_adj[u]){
            if(vis[v]) finish(_wa, "Cycle detected");
            vis[v] = true;
            seen++;
            q.push_back(v);
        }
    }

    if (seen != 2 * n - 1) finish(_wa, "Graph is not connected or contains cycles");

    int leaves = 0;
    for (int i = 1; i < 2 * n; i++) {
        int deg = user_adj[i].size();
        if (deg == 0) leaves++;
        else if (deg != 2) finish(_wa, "Not a full binary tree (node degree is not 0 or 2)");
    }

    if (leaves != n) finish(_wa, "Wrong number of leaves in reconstructed tree");

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

    string code_judge = get_canonical(judge_root, judge_adj);
    string code_user = get_canonical(user_root, user_adj);

    if (code_judge == code_user) {
        finish(_ok, "Correct");
    } else {
        finish(_wa, "Tree is not isomorphic to the hidden tree");
    }

    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() {
    if (query_limit == 0) return;
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {

    }
}

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

int n;
vector<vector<int>> hidden_adj;
vector<int> hidden_parent;
vector<int> hidden_depth;
int hidden_root = -1;

void build_hidden_tree_from_parents(int N, const vector<int>& p) {
    n = N;
    int nodes = 2 * n - 1;
    hidden_adj.assign(nodes + 1, vector<int>());
    hidden_parent = p;
    hidden_depth.assign(nodes + 1, 0);

    hidden_root = -1;
    for (int i = 1; i <= nodes; i++) {
        if (p[i] == -1) {
            hidden_root = i;
        } else {
            hidden_adj[p[i]].push_back(i);
        }
    }

    function<void(int, int)> dfs = [&](int u, int d) {
        hidden_depth[u] = d;
        for (int v : hidden_adj[u]) dfs(v, d + 1);
    };
    if (hidden_root != -1) dfs(hidden_root, 0);
}

void generate_hidden_tree(int N) {
    n = N;

    struct Info { int id; int h; };
    vector<Info> roots;
    for(int i = 1; i <= n; ++i) roots.push_back({i, 0});

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

    int next_id = n + 1;
    vector<int> p(2 * n, 0);

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

        int idx1 = rnd.next(0, (int)roots.size() - 1);
        int idx2 = rnd.next(0, (int)roots.size() - 1);
        while(idx1 == idx2) idx2 = rnd.next(0, (int)roots.size() - 1);

        if (idx1 > idx2) swap(idx1, idx2);

        Info r1 = roots[idx1];
        Info r2 = roots[idx2];

        roots.erase(roots.begin() + idx2);
        roots.erase(roots.begin() + idx1);

        p[r1.id] = next_id;
        p[r2.id] = next_id;

        roots.push_back({next_id, max(r1.h, r2.h) + 1});
        next_id++;
    }
    p[2 * n - 1] = -1;

    build_hidden_tree_from_parents(n, p);
}

int get_lca_depth(int u, int v) {
    if (u == v) return hidden_depth[u];

    if (hidden_depth[u] < hidden_depth[v]) swap(u, v);
    while (hidden_depth[u] > hidden_depth[v]) {
        u = hidden_parent[u];
    }

    while (u != v) {
        u = hidden_parent[u];
        v = hidden_parent[v];
    }
    return hidden_depth[u];
}

map<pair<int,int>, int> canon_map;

int get_canon_id(pair<int,int> p) {
    if (canon_map.find(p) == canon_map.end()) {
        canon_map[p] = (int)canon_map.size();
    }
    return canon_map[p];
}

int get_tree_hash(int u, const vector<vector<int>>& adj) {
    if (adj[u].empty()) return 0;

    vector<int> children_hashes;
    for (int v : adj[u]) {
        children_hashes.push_back(get_tree_hash(v, adj));
    }
    sort(children_hashes.begin(), children_hashes.end());

    if (children_hashes.size() != 2) return -1;

    return get_canon_id({children_hashes[0], children_hashes[1]});
}

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

    n = inf.readInt();

    if (inf.seekEof()) {
        generate_hidden_tree(n);
    } else {
        vector<int> p(2 * n);
        for (int i = 1; i < 2 * n; i++) {
            p[i] = inf.readInt();
        }
        build_hidden_tree_from_parents(n, p);
    }

    query_limit = 10LL * n;

    cout << n << endl;

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

    while (true) {
        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected end of input (expected query or -1)");
        }

        if (token == "-1") {
            break;
        }

        int a1, a2, a3;
        try {
            a1 = stoi(token);
        } catch (...) {
            finish(_wa, "Invalid query format (expected integer)");
        }

        if (!(cin >> a2 >> a3)) {
            finish(_wa, "Unexpected end of input reading query arguments");
        }

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

        if (a1 < 1 || a1 > n || a2 < 1 || a2 > n || a3 < 1 || a3 > n) {
            finish(_wa, "Query index out of range [1, n]");
        }
        if (a1 == a2 || a1 == a3 || a2 == a3) {
            finish(_wa, "Query indices must be distinct");
        }

        int dX = get_lca_depth(a1, a2);
        int dY = get_lca_depth(a2, a3);
        int dZ = get_lca_depth(a1, a3);

        char ans;

        if (dX >= dY && dX >= dZ) ans = 'X';
        else if (dY >= dX && dY >= dZ) ans = 'Y';
        else ans = 'Z';

        cout << ans << endl;

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

    vector<int> user_p(2 * n);
    for (int i = 1; i < 2 * n; i++) {
        if (!(cin >> user_p[i])) {
            finish(_wa, "Failed to read final answer parent array");
        }
    }

    int user_nodes = 2 * n - 1;
    vector<vector<int>> user_adj(user_nodes + 1);
    int user_root = -1;
    vector<int> user_degree(user_nodes + 1, 0);

    for (int i = 1; i <= user_nodes; i++) {
        int p = user_p[i];
        if (p == -1) {
            if (user_root != -1) finish(_wa, "Output contains multiple roots");
            user_root = i;
        } else {
            if (p < 1 || p > user_nodes) finish(_wa, "Parent index out of range in final answer");
            user_adj[p].push_back(i);
            user_degree[p]++;
        }
    }

    if (user_root == -1) finish(_wa, "Output tree has no root");

    int edges = 0;
    for (int i = 1; i <= user_nodes; i++) {
        if (user_degree[i] != 0 && user_degree[i] != 2) {
            finish(_wa, "Output is not a full binary tree (nodes must have 0 or 2 children)");
        }
        if (user_degree[i] > 0) edges += user_degree[i];
    }

    vector<int> q;
    vector<bool> visited(user_nodes + 1, false);
    q.push_back(user_root);
    visited[user_root] = true;
    size_t head = 0;
    while(head < q.size()){
        int u = q[head++];
        for(int v : user_adj[u]){
            if(visited[v]) finish(_wa, "Output tree contains a cycle");
            visited[v] = true;
            q.push_back(v);
        }
    }

    if (q.size() != user_nodes) finish(_wa, "Output tree is disconnected or not a single component");

    canon_map.clear();

    int h1 = get_tree_hash(hidden_root, hidden_adj);
    int h2 = get_tree_hash(user_root, user_adj);

    if (h1 == -1) finish(_wa, "Internal Error: Hidden tree invalid");
    if (h2 == -1) finish(_wa, "Output tree structure mismatch (hash failed)");

    if (h1 == h2) {
        finish(_ok, "Correct (Isomorphic)");
    } else {
        finish(_wa, "Output tree is not isomorphic to the hidden tree");
    }

    return 0;
}

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

using namespace std;

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

    string mode = opt<string>("mode", "non");
    int n_opt = opt<int>("n", 0);

    int seed = atoi(argv[1]);

    int n;
    string type;

    if (n_opt > 0) {
        n = n_opt;
        type = "random";
    } else {
        if (seed == 1) {
            n = 3;
            type = "random";
        } else if (seed == 2) {
            n = 1000;
            type = "caterpillar";
        } else if (seed == 3) {
            n = 1000;
            type = "balanced";
        } else {

            n = rnd.next(500, 1000);
            int t = rnd.next(0, 2);
            if (t == 0) type = "random";
            else if (t == 1) type = "caterpillar";
            else type = "balanced";
        }
    }

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

    struct NodeInfo {
        int id;
        int height;
    };

    vector<NodeInfo> roots;
    for (int i = 1; i <= n; i++) {
        roots.push_back({i, 0});
    }

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

    vector<int> p(2 * n);
    int next_internal = n + 1;

    for (int step = 0; step < n - 1; step++) {
        int i1 = -1, i2 = -1;

        if (type == "random") {

            i1 = rnd.next(0, (int)roots.size() - 1);
            i2 = rnd.next(0, (int)roots.size() - 1);
            while (i1 == i2) {
                i2 = rnd.next(0, (int)roots.size() - 1);
            }
        } else if (type == "caterpillar") {

            vector<int> leaf_indices;
            for(int i=0; i<(int)roots.size(); ++i) {
                if(roots[i].height == 0) leaf_indices.push_back(i);
            }

            if (!leaf_indices.empty()) {
                i1 = leaf_indices[rnd.next(0, (int)leaf_indices.size() - 1)];
            } else {
                i1 = rnd.next(0, (int)roots.size() - 1);
            }

            int max_h = -1;
            int bi = -1;
            for(int i=0; i<(int)roots.size(); ++i) {
                if (i == i1) continue;
                if (roots[i].height > max_h) {
                    max_h = roots[i].height;
                    bi = i;
                }
            }

            if (bi == -1) {
                bi = rnd.next(0, (int)roots.size() - 1);
                while (bi == i1) bi = rnd.next(0, (int)roots.size() - 1);
            }
            i2 = bi;

        } else {

            i1 = 0;
            for(int i=1; i<(int)roots.size(); ++i) {
                if (roots[i].height < roots[i1].height) i1 = i;
            }

            i2 = -1;
            for(int i=0; i<(int)roots.size(); ++i) {
                if (i == i1) continue;
                if (i2 == -1 || roots[i].height < roots[i2].height) i2 = i;
            }
        }

        if (i1 > i2) swap(i1, i2);

        int id1 = roots[i1].id;
        int id2 = roots[i2].id;
        int h = max(roots[i1].height, roots[i2].height) + 1;

        roots.erase(roots.begin() + i2);
        roots.erase(roots.begin() + i1);

        p[id1] = next_internal;
        p[id2] = next_internal;

        roots.push_back({next_internal, h});

        next_internal++;
    }

    p[2 * n - 1] = -1;

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

    return 0;
}


AdhesiveWombat - Overdrive

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

This is an interactive problem.

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

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

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

Find the number appearing exactly once, using at most $925$ queries. You don't need to find its position.

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

Input

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

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

There are exactly $50$ tests in this problem (including the example). The example has $t = 1$, and all the other tests have $t = 20$.

Interaction

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

You may ask up to $925$ queries in each test case.

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

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

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

See the interaction example for more clarity.

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

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

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

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

Example

Input

```
1
300

0
```

Output

```? 187 1 1! 187
```

Note

In the first test case, $n = 300$, so the hidden array has length $2n-1 = 599$.

|  |  |  |  |
| --- | --- | --- | --- |
| # | Contestant prints | Interactor replies | Explanation |
| 1 |? 187 1 1 | 0 | Query: does $a_1=187$? No. |
| 2 |! 187 |  | We feel lucky, and claim that the answer is $187$. Fortunately, the answer is correct. |

We have asked $1$ query (printing the answer does not count as a query), which is less than the maximum allowed number of queries ($925$).

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

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

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

    }
}

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

static bool readLL(long long& out) {
    if (!(cin >> out)) return false;
    return true;
}

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

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

    int t = 0;
    if (inf.seekEof()) finish(_pe, "Empty input");
    t = inf.readInt(1, 1000000, "t");

    const long long per_case_budget = 925;
    query_limit = per_case_budget * 1LL * t;

    log_metrics();

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

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

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

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

        int singleton = -1;
        for (int x = 1; x <= n; ++x) {
            if (cnt[x] == 1) {
                if (singleton != -1) finish(_pe, "Invalid hidden input: multiple singletons");
                singleton = x;
            } else if (cnt[x] != 2) {
                finish(_pe, "Invalid hidden input: value count not 1 or 2");
            }
        }
        if (singleton == -1) finish(_pe, "Invalid hidden input: no singleton");

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

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

            string cmd;
            if (!readToken(cmd)) finish(_pe, "Unexpected EOF from contestant");

            if (cmd == "?") {
                long long x_ll = 0, k_ll = 0;
                if (!readLL(x_ll) || !readLL(k_ll)) {
                    cout << -1 << endl;
                    cout.flush();
                    finish(_pe, "Malformed query header");
                }

                if (x_ll < 1 || x_ll > n || k_ll < 1 || k_ll > m) {
                    cout << -1 << endl;
                    cout.flush();
                    finish(_pe, "Query parameter out of range");
                }

                int x = (int)x_ll;
                int k = (int)k_ll;

                vector<char> seen(m + 1, 0);
                bool ok = true;
                bool exists = false;

                for (int i = 0; i < k; ++i) {
                    long long idx_ll = 0;
                    if (!readLL(idx_ll)) {
                        cout << -1 << endl;
                        cout.flush();
                        finish(_pe, "Malformed query indices");
                    }
                    if (idx_ll < 1 || idx_ll > m) ok = false;
                    else {
                        int idx = (int)idx_ll;
                        if (seen[idx]) ok = false;
                        seen[idx] = 1;
                        if (a[idx] == x) exists = true;
                    }
                }

                if (!ok) {
                    cout << -1 << endl;
                    cout.flush();
                    finish(_pe, "Invalid query indices (range/distinctness)");
                }

                ++queries;
                cout << (exists ? 1 : 0) << endl;
                cout.flush();
            } else if (cmd == "!") {
                long long y_ll = 0;
                if (!readLL(y_ll)) finish(_pe, "Malformed answer");
                if (y_ll < 1 || y_ll > n) finish(_wa, "Answer out of range");
                int y = (int)y_ll;
                if (y != singleton) {

                    cout << -1 << endl;
                    cout.flush();
                    finish(_wa, "Wrong answer");
                }
                break;
            } else {
                finish(_pe, "Unknown command token");
            }
        }
    }

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

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

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

static vector<int> buildNonInstance(int n, int seed, int forcedY) {
    int y;
    if (forcedY != 0) {
        y = forcedY;
    } else if (seed == 1) {
        y = 1;
    } else if (seed == 2) {
        y = n;
    } else if (seed == 3) {
        y = (n + 1) / 2;
    } else {
        y = rnd.next(1, n);
    }

    vector<int> a;
    a.reserve(2 * n - 1);

    if (seed == 1) {

        for (int x = 2; x <= n; ++x) {
            a.push_back(x);
            a.push_back(x);
        }
        a.push_back(1);
        return a;
    }

    if (seed == 2) {

        for (int x = 1; x <= n; ++x) a.push_back(x);
        for (int x = n - 1; x >= 1; --x) a.push_back(x);
        return a;
    }

    if (seed == 3) {

        vector<int> vals;
        vals.reserve(n - 1);
        for (int x = 1; x <= n; ++x) if (x != y) vals.push_back(x);

        for (int x : vals) a.push_back(x);
        for (int i = (int)vals.size() - 1; i >= 0; --i) a.push_back(vals[i]);
        a.push_back(y);
        return a;
    }

    int m = 2 * n - 1;
    vector<int> positions(m);
    iota(positions.begin(), positions.end(), 0);
    fisherYatesShuffle(positions);

    vector<int> lowPos(positions.begin(), positions.begin() + (n - 1));
    vector<int> highPos(positions.begin() + (n - 1), positions.end());
    fisherYatesShuffle(lowPos);
    fisherYatesShuffle(highPos);

    vector<int> vals;
    vals.reserve(n - 1);
    for (int x = 1; x <= n; ++x) if (x != y) vals.push_back(x);
    fisherYatesShuffle(vals);

    vector<int> out(m, 0);
    for (int i = 0; i < n - 1; ++i) {
        out[lowPos[i]] = vals[i];
        out[highPos[i]] = vals[i];
    }
    out[highPos[n - 1]] = y;

    return out;
}

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

    string mode = opt<string>("mode", "non");
    int n = opt<int>("n", 300);
    int forcedY = opt<int>("y", 0);

    if (n < 1) n = 1;
    if (forcedY != 0) {
        if (forcedY < 1) forcedY = 1;
        if (forcedY > n) forcedY = n;
    }

    int seed = 0;
    if (argc >= 2) seed = atoi(argv[1]);

    if (mode == "adp") {
        int y;
        if (forcedY != 0) {
            y = forcedY;
        } else if (seed == 1) {
            y = 1;
        } else if (seed == 2) {
            y = n;
        } else if (seed == 3) {
            y = (n + 1) / 2;
        } else {
            y = rnd.next(1, n);
        }

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

    vector<int> a = buildNonInstance(n, seed, forcedY);

    cout << 1 << "\n";
    cout << n << "\n";
    for (int i = 0; i < (int)a.size(); ++i) {
        if (i) cout << ' ';
        cout << a[i];
    }
    cout << "\n";
    return 0;
}


You are given a bipartite graph consisting of $n_1$ vertices in the first part, $n_2$ vertices in the second part, and $m$ edges, numbered from $1$ to $m$. You have to color each edge into one of two colors, red and blue. You have to minimize the following value: $\sum \limits_{v \in V} |r(v) - b(v)|$, where $V$ is the set of vertices of the graph, $r(v)$ is the number of red edges incident to $v$, and $b(v)$ is the number of blue edges incident to $v$.

Sounds classical and easy, right? Well, you have to process $q$ queries of the following format:

* $1$ $v_1$ $v_2$ — add a new edge connecting the vertex $v_1$ of the first part with the vertex $v_2$ of the second part. This edge gets a new index as follows: the first added edge gets the index $m + 1$, the second — $m + 2$, and so on. After adding the edge, you have to print the hash of the current optimal coloring (if there are multiple optimal colorings, print the hash of any of them). Actually, this hash won't be verified, you may print any number as the answer to this query, but you may be asked to produce the coloring having this hash;
* $2$ — print the optimal coloring of the graph with the same hash you printed while processing the previous query. The query of this type will only be asked after a query of type $1$, and there will be at most $10$ queries of this type. If there are multiple optimal colorings corresponding to this hash, print any of them.

Note that if an edge was red or blue in some coloring, it may change its color in next colorings.

The hash of the coloring is calculated as follows: let $R$ be the set of indices of red edges, then the hash is $(\sum \limits_{i \in R} 2^i) \bmod 998244353$.

Note that you should solve the problem in online mode. It means that you can't read the whole input at once. You can read each query only after writing the answer for the last query. Use functions fflush in C++ and BufferedWriter.flush in Java languages after each writing in your program.

Input

The first line contains three integers $n_1$, $n_2$ and $m$ ($1 \le n_1, n_2, m \le 2 \cdot 10^5$).

Then $m$ lines follow, the $i$-th of them contains two integers $x_i$ and $y_i$ ($1 \le x_i \le n_1$; $1 \le y_i \le n_2$) meaning that the $i$-th edge connects the vertex $x_i$ from the first part and the vertex $y_i$ from the second part.

The next line contains one integer $q$ ($1 \le q \le 2 \cdot 10^5$) — the number of queries you have to process.

The next $q$ lines contain the queries in the format introduced in the statement.

Additional constraints on the input:

* at any moment, the graph won't contain any multiple edges;
* the queries of type $2$ are only asked if the previous query had type $1$;
* there are at most $10$ queries of type $2$.

Output

To answer a query of type $1$, print one integer — the hash of the optimal coloring.

To answer a query of type $2$, print one line. It should begin with the integer $k$ — the number of red edges. Then, $k$ distinct integer should follow — the indices of red edges in your coloring, in any order. Each index should correspond to an existing edge, and the hash of the coloring you produce should be equal to the hash you printed as the answer to the previous query.

If there are multiple answers to a query, you may print any of them.

Example

Input

```
3 4 2
1 2
3 4
10
1 1 3
1 2 3
2
1 3 3
2
1 2 4
2
1 2 1
1 1 1
2
```

Output

```
8
8
1 3
40
2 3 5
104
3 5 6 3
104
360
4 5 6 3 8
```

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

static long long queries_processed = 0;
static long long query_limit = 0;

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

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

const int MOD = 998244353;
vector<int> pow2;

void init_pow2(int max_n) {
    pow2.resize(max_n + 1);
    pow2[0] = 1;
    for (int i = 1; i <= max_n; i++) {
        pow2[i] = (1LL * pow2[i-1] * 2) % MOD;
    }
}

struct Edge {
    int u, v;
};

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

    int n1 = inf.readInt(1, 200000, "n1");
    int n2 = inf.readInt(1, 200000, "n2");
    int m = inf.readInt(1, 200000, "m");

    cout << n1 << " " << n2 << " " << m << endl;

    vector<Edge> edges;
    edges.reserve(400005);
    edges.push_back({-1, -1});

    for (int i = 1; i <= m; i++) {
        int u = inf.readInt(1, n1, "u_i");
        int v = inf.readInt(1, n2, "v_i");
        edges.push_back({u, v});
        cout << u << " " << v << endl;
    }

    int q = inf.readInt(1, 200000, "q");
    query_limit = q;
    cout << q << endl;

    log_metrics();

    init_pow2(m + q + 5);

    long long last_contestant_hash = -1;
    bool has_last_hash = false;

    for (int k = 0; k < q; k++) {
        int type = inf.readInt(1, 2, "type");
        if (type == 1) {
            int u = inf.readInt(1, n1, "u");
            int v = inf.readInt(1, n2, "v");

            cout << "1 " << u << " " << v << endl;

            edges.push_back({u, v});

            string token;
            if (!(cin >> token)) {
                finish(_pe, "Unexpected end of output from contestant (expected hash)");
            }

            long long h_val;
            try {
                h_val = stoll(token);
            } catch (...) {
                finish(_pe, "Expected integer hash, got: " + token);
            }

            last_contestant_hash = h_val;
            has_last_hash = true;
            queries_processed++;

        } else {

            cout << "2" << endl;

            if (!has_last_hash) {

                finish(_fail, "Type 2 query requested but no Type 1 query processed yet");
            }

            string token;
            if (!(cin >> token)) {
                finish(_pe, "Unexpected end of output from contestant (expected k)");
            }

            int num_red;
            try {
                num_red = stoi(token);
            } catch (...) {
                finish(_pe, "Expected integer k, got: " + token);
            }

            int current_total_edges = (int)edges.size() - 1;
            if (num_red < 0 || num_red > current_total_edges) {
                finish(_wa, "Number of red edges " + to_string(num_red) + " out of range [0, " + to_string(current_total_edges) + "]");
            }

            vector<bool> is_red(current_total_edges + 1, false);
            long long computed_hash = 0;

            for (int i = 0; i < num_red; i++) {
                if (!(cin >> token)) {
                    finish(_pe, "Unexpected end of output (expected red edge index)");
                }
                int idx;
                try {
                    idx = stoi(token);
                } catch (...) {
                    finish(_pe, "Expected integer edge index, got: " + token);
                }

                if (idx < 1 || idx > current_total_edges) {
                    finish(_wa, "Edge index " + to_string(idx) + " out of range [1, " + to_string(current_total_edges) + "]");
                }
                if (is_red[idx]) {
                    finish(_wa, "Duplicate edge index " + to_string(idx) + " in coloring");
                }
                is_red[idx] = true;
                computed_hash = (computed_hash + pow2[idx]) % MOD;
            }

            if (computed_hash != last_contestant_hash) {
                finish(_wa, "Coloring hash " + to_string(computed_hash) + " does not match previously declared hash " + to_string(last_contestant_hash));
            }

            vector<int> balance(n1 + n2 + 1, 0);
            for (int i = 1; i <= current_total_edges; i++) {
                int u = edges[i].u;
                int v = edges[i].v + n1;

                if (is_red[i]) {
                    balance[u]++;
                    balance[v]++;
                } else {
                    balance[u]--;
                    balance[v]--;
                }
            }

            for (int i = 1; i <= n1 + n2; i++) {
                if (abs(balance[i]) > 1) {
                    finish(_wa, "Vertex " + to_string(i > n1 ? i - n1 : i) +
                           (i > n1 ? " (part 2)" : " (part 1)") +
                           " has imbalance " + to_string(balance[i]) +
                           " (red - blue). Allowed range [-1, 1].");
                }
            }

            queries_processed++;
        }
    }

    finish(_ok, "Passed " + to_string(q) + " queries");
    return 0;
}

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

static long long queries_count = 0;
static long long query_limit = 0;

const int MOD = 998244353;

struct Edge {
    int u, v;
    int id;
};

vector<Edge> edges;
int n1, n2;
int last_contestant_hash = -1;

vector<int> pow2;

void ensure_pow2(int max_idx) {
    if (pow2.empty()) {
        pow2.push_back(1);
    }
    while ((int)pow2.size() <= max_idx) {
        pow2.push_back((1LL * pow2.back() * 2) % MOD);
    }
}

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

    }
}

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

long long readContestantHash() {
    return ouf.readLong(0LL, 2000000000LL, "hash");
}

void verifyColoring() {
    int current_m = edges.size();

    int k = ouf.readInt(0, current_m, "k (number of red edges)");

    ensure_pow2(current_m);

    vector<bool> is_red(current_m + 1, false);
    long long computed_hash = 0;

    for (int i = 0; i < k; i++) {
        int idx = ouf.readInt(1, current_m, "edge index");
        if (is_red[idx]) {
            finish(_wa, "Duplicate edge index in coloring: " + to_string(idx));
        }
        is_red[idx] = true;
        computed_hash = (computed_hash + pow2[idx]) % MOD;
    }

    if (computed_hash != last_contestant_hash) {
        finish(_wa, "Hash mismatch. Expected: " + to_string(last_contestant_hash) + ", Found: " + to_string(computed_hash));
    }

    vector<int> r(n1 + n2 + 1, 0);
    vector<int> b(n1 + n2 + 1, 0);

    for (int i = 0; i < current_m; i++) {
        int idx = edges[i].id;
        int u = edges[i].u;
        int v_shifted = edges[i].v + n1;

        if (is_red[idx]) {
            r[u]++;
            r[v_shifted]++;
        } else {
            b[u]++;
            b[v_shifted]++;
        }
    }

    for (int i = 1; i <= n1 + n2; i++) {
        if (abs(r[i] - b[i]) > 1) {
            string v_str = (i > n1) ? ("(part 2 vertex " + to_string(i - n1) + ")")
                                    : ("(part 1 vertex " + to_string(i) + ")");
            finish(_wa, "Coloring not optimal at " + v_str +
                        ". r=" + to_string(r[i]) + ", b=" + to_string(b[i]));
        }
    }
}

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

    n1 = inf.readInt();
    n2 = inf.readInt();
    int m_initial = inf.readInt();

    cout << n1 << " " << n2 << " " << m_initial << endl;

    for (int i = 1; i <= m_initial; i++) {
        int u = inf.readInt();
        int v = inf.readInt();
        edges.push_back({u, v, i});
        cout << u << " " << v << endl;
    }

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

    query_limit = q;
    ensure_pow2(1);

    for (int k = 0; k < q; k++) {
        int type = inf.readInt();

        if (type == 1) {
            int u = inf.readInt();
            int v = inf.readInt();

            cout << "1 " << u << " " << v << endl;

            int new_idx = (int)edges.size() + 1;
            edges.push_back({u, v, new_idx});

            long long h = readContestantHash();
            last_contestant_hash = (int)h;
        } else {

            cout << "2" << endl;

            verifyColoring();
        }

        queries_count++;

        if (queries_count % 1000 == 0) log_metrics();
    }

    finish(_ok, "All queries processed successfully");
}

#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 = atoi(argv[1]);

    int n1, n2, m, q;

    if (seed == 1) {
        n1 = 3; n2 = 4; m = 2; q = 10;
    } else if (seed == 2) {

        n1 = 2; n2 = 2; m = 1; q = 5;
    } else if (seed == 3) {

        n1 = 10; n2 = 10; m = 20; q = 50;
    } else {

        int n1_min = 100000, n1_max = 200000;
        int n2_min = 100000, n2_max = 200000;
        int m_min = 100000, m_max = 200000;
        int q_min = 100000, q_max = 200000;

        n1 = opt<int>("n1", rnd.next(n1_min, n1_max));
        n2 = opt<int>("n2", rnd.next(n2_min, n2_max));
        m = opt<int>("m", rnd.next(m_min, m_max));
        q = opt<int>("q", rnd.next(q_min, q_max));
    }

    n1 = max(1, n1);
    n2 = max(1, n2);
    m = max(1, m);
    q = max(1, q);

    long long max_edges = (long long)n1 * n2;

    if (m > max_edges) m = (int)max_edges;
    if (m == max_edges && max_edges > 1) m--;

    vector<pair<int, int>> initial_edges;
    vector<string> queries;

    if (max_edges <= 2000000) {
        vector<pair<int, int>> pool;
        pool.reserve(max_edges);
        for (int i = 1; i <= n1; i++) {
            for (int j = 1; j <= n2; j++) {
                pool.push_back({i, j});
            }
        }
        shuffle(pool.begin(), pool.end());

        int ptr = 0;

        for (int i = 0; i < m && ptr < (int)pool.size(); i++) {
            initial_edges.push_back(pool[ptr++]);
        }
        m = (int)initial_edges.size();

        int t2_count = 0;
        bool last_type1 = false;

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

            bool type2 = false;

            if (last_type1 && t2_count < 10) {

                if (rnd.next(20) == 0 || ptr >= (int)pool.size()) {
                    type2 = true;
                }
            }

            if (!type2 && ptr >= (int)pool.size()) {
                 break;
            }

            if (type2) {
                queries.push_back("2");
                t2_count++;
                last_type1 = false;
            } else {
                pair<int, int> e = pool[ptr++];
                queries.push_back("1 " + to_string(e.first) + " " + to_string(e.second));
                last_type1 = true;
            }
        }
    } else {

        set<long long> used;
        auto get_hash = [&](int u, int v) {
            return ((long long)u << 32) | v;
        };

        while ((int)initial_edges.size() < m) {
            int u = rnd.next(1, n1);
            int v = rnd.next(1, n2);
            if (used.insert(get_hash(u, v)).second) {
                initial_edges.push_back({u, v});
            }
        }

        vector<int> hot_n1, hot_n2;
        if (mode == "adp") {
            int cnt1 = max(1, n1 / 40);
            int cnt2 = max(1, n2 / 40);
            for(int i=0; i<cnt1; ++i) hot_n1.push_back(rnd.next(1, n1));
            for(int i=0; i<cnt2; ++i) hot_n2.push_back(rnd.next(1, n2));
        }

        int t2_count = 0;
        bool last_type1 = false;

        for (int k = 0; k < q; k++) {
            bool type2 = false;
            if (last_type1 && t2_count < 10 && rnd.next(20) == 0) {
                type2 = true;
            }

            if (type2) {
                queries.push_back("2");
                t2_count++;
                last_type1 = false;
            } else {

                while (true) {
                    int u, v;

                    if (mode == "adp" && !hot_n1.empty() && rnd.next(3) == 0)
                        u = hot_n1[rnd.next((int)hot_n1.size())];
                    else
                        u = rnd.next(1, n1);

                    if (mode == "adp" && !hot_n2.empty() && rnd.next(3) == 0)
                        v = hot_n2[rnd.next((int)hot_n2.size())];
                    else
                        v = rnd.next(1, n2);

                    if (used.insert(get_hash(u, v)).second) {
                        queries.push_back("1 " + to_string(u) + " " + to_string(v));
                        break;
                    }

                }
                last_type1 = true;
            }
        }
    }

    cout << n1 << " " << n2 << " " << m << "\n";
    for (auto &p : initial_edges) {
        cout << p.first << " " << p.second << "\n";
    }
    cout << queries.size() << "\n";
    for (auto &s : queries) {
        cout << s << "\n";
    }

    return 0;
}


This is the easy version of the problem. You can find the hard version in the Div. 1 contest. Both versions only differ in the number of times you can ask your friend to taste coffee.

This is an interactive problem.

You're considering moving to another city, where one of your friends already lives. There are $n$ cafés in this city, where $n$ is a power of two. The $i$-th café produces a single variety of coffee $a_i$.

As you're a coffee-lover, before deciding to move or not, you want to know the number $d$ of distinct varieties of coffees produced in this city.

You don't know the values $a_1, \ldots, a_n$. Fortunately, your friend has a memory of size $k$, where $k$ is a power of two.

Once per day, you can ask him to taste a cup of coffee produced by the café $c$, and he will tell you if he tasted a similar coffee during the last $k$ days.

You can also ask him to take a medication that will reset his memory. He will forget all previous cups of coffee tasted. You can reset his memory at most $30\ 000$ times.

More formally, the memory of your friend is a queue $S$. Doing a query on café $c$ will:

* Tell you if $a_c$ is in $S$;
* Add $a_c$ at the back of $S$;
* If $|S| > k$, pop the front element of $S$.

Doing a reset request will pop all elements out of $S$.

Your friend can taste at most $\dfrac{2n^2}{k}$ cups of coffee in total. Find the diversity $d$ (number of distinct values in the array $a$).

Note that asking your friend to reset his memory does not count towards the number of times you ask your friend to taste a cup of coffee.

In some test cases the behavior of the interactor is adaptive. It means that the array $a$ may be not fixed before the start of the interaction and may depend on your queries. It is guaranteed that at any moment of the interaction, there is at least one array $a$ consistent with all the answers given so far.

Input

The first line contains two integers $n$ and $k$ ($1 \le k \le n \le 1024$, $k$ and $n$ are powers of two).

It is guaranteed that $\dfrac{2n^2}{k} \le 20\ 000$.

Interaction

You begin the interaction by reading $n$ and $k$.

* To ask your friend to taste a cup of coffee produced by the café $c$, in a separate line output

  ? $c$

  Where $c$ must satisfy $1 \le c \le n$. Don't forget to flush, to get the answer.

  In response, you will receive a single letter Y (yes) or N (no), telling you if variety $a_c$ is one of the last $k$ varieties of coffee in his memory.
* To reset the memory of your friend, in a separate line output the single letter R in upper case. You can do this operation at most $30\ 000$ times.
* When you determine the number $d$ of different coffee varieties, output

  ! $d$

In case your query is invalid, you asked more than $\frac{2n^2}{k}$ queries of type ? or you asked more than $30\ 000$ queries of type R, the program will print the letter E and will finish interaction. You will receive a Wrong Answer verdict. Make sure to exit immediately to avoid getting other verdicts.

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

```
4 2
N
N
Y
N
N
N
N
```

Output

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

Input

```
8 8
N
N
N
N
Y
Y
```

Output

```
? 2
? 6
? 4
? 5
? 2
? 5
! 6
```

Note

In the first example, the array is $a = [1, 4, 1, 3]$. The city produces $3$ different varieties of coffee ($1$, $3$ and $4$).

The successive varieties of coffee tasted by your friend are $1, 4, \textbf{1}, 3, 3, 1, 4$ (bold answers correspond to Y answers). Note that between the two ? 4 asks, there is a reset memory request R, so the answer to the second ? 4 ask is N. Had there been no reset memory request, the answer to the second ? 4 ask is Y.

In the second example, the array is $a = [1, 2, 3, 4, 5, 6, 6, 6]$. The city produces $6$ different varieties of coffee.

The successive varieties of coffee tasted by your friend are $2, 6, 4, 5, \textbf{2}, \textbf{5}$.

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

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

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

    }
}

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

static inline string trim_copy(const string& s) {
    size_t l = 0, r = s.size();
    while (l < r && isspace((unsigned char)s[l])) ++l;
    while (r > l && isspace((unsigned char)s[r - 1])) --r;
    return s.substr(l, r - l);
}

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

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

    int n = 0, k = 0;
    vector<int> a;
    try {
        n = inf.readInt(1, 1024, "n");
        k = inf.readInt(1, n, "k");
        a.resize(n);
        for (int i = 0; i < n; i++) {
            a[i] = inf.readInt(-2000000000, 2000000000, ("a[" + to_string(i) + "]").c_str());
        }
    } catch (...) {
        query_limit = 0;
        log_metrics();
        quitf(_fail, "Invalid hidden input");
    }

    query_limit = (2LL * n * n) / k;
    if (query_limit < 0) query_limit = 0;

    log_metrics();

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

    unordered_set<int> distinct;
    distinct.reserve((size_t)n * 2);
    for (int x : a) distinct.insert(x);
    const long long correct_d = (long long)distinct.size();

    deque<int> mem;
    unordered_map<int, int> freq;
    freq.reserve((size_t)k * 2 + 16);

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

    auto send_E_and_WA = [&](const string& reason) -> void {
        cout << "E\n";
        cout.flush();
        finish(_wa, reason);
    };

    string line;
    while (true) {
        if (!std::getline(cin, line)) {
            finish(_pe, "Unexpected EOF from contestant");
        }
        line = trim_copy(line);
        if (line.empty()) {
            finish(_pe, "Empty command line");
        }

        stringstream ss(line);
        string cmd;
        ss >> cmd;
        if (!ss) finish(_pe, "Malformed command");

        auto has_extra_tokens = [&]() -> bool {
            string extra;
            if (ss >> extra) return true;
            return false;
        };

        if (cmd == "R") {
            if (has_extra_tokens()) finish(_pe, "Extra tokens after R");
            ++resets;
            if (resets > 30000) {
                send_E_and_WA("Too many resets");
            }
            mem.clear();
            freq.clear();
            continue;
        }

        if (cmd == "?" || (!cmd.empty() && cmd[0] == '?' && cmd.size() > 1)) {
            string ctok;
            if (cmd == "?") {
                if (!(ss >> ctok)) finish(_pe, "Missing cafe index after ?");
            } else {
                ctok = cmd.substr(1);
            }
            if (has_extra_tokens()) finish(_pe, "Extra tokens after query");

            long long c = 0;
            if (!parse_int64_strict(ctok, c)) finish(_pe, "Non-integer cafe index");
            if (c < 1 || c > n) {
                send_E_and_WA("Cafe index out of range");
            }

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

            int val = a[(int)c - 1];
            bool seen = false;
            auto it = freq.find(val);
            if (it != freq.end() && it->second > 0) seen = true;

            cout << (seen ? 'Y' : 'N') << '\n';
            cout.flush();

            mem.push_back(val);
            freq[val] += 1;
            if ((int)mem.size() > k) {
                int front = mem.front();
                mem.pop_front();
                auto it2 = freq.find(front);
                if (it2 != freq.end()) {
                    it2->second -= 1;
                    if (it2->second <= 0) freq.erase(it2);
                }
            }
            continue;
        }

        if (cmd == "!" || (!cmd.empty() && cmd[0] == '!' && cmd.size() > 1)) {
            string dtok;
            if (cmd == "!") {
                if (!(ss >> dtok)) finish(_pe, "Missing answer after !");
            } else {
                dtok = cmd.substr(1);
            }
            if (has_extra_tokens()) finish(_pe, "Extra tokens after answer");

            long long ans = 0;
            if (!parse_int64_strict(dtok, ans)) finish(_pe, "Non-integer answer");
            if (ans == correct_d) {
                finish(_ok, "OK");
            } else {
                finish(_wa, "Wrong answer");
            }
        }

        finish(_pe, "Unknown command");
    }
}

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

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

static long long resets = 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 void protocol_error(const string& msg) {
    cout << "E" << endl;
    cout.flush();
    finish(_pe, msg);
}

static void wrong_answer(const string& msg) {
    finish(_wa, msg);
}

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

    int n = 0, k = 0;
    try {
        n = inf.readInt(1, 1024, "n");
        k = inf.readInt(1, 1024, "k");
    } catch (...) {
        finish(_pe, "failed to read n,k from hidden input");
    }

    if ((n & (n - 1)) != 0 || (k & (k - 1)) != 0 || k > n) {
        finish(_pe, "hidden input violates power-of-two constraints");
    }

    query_limit = (2LL * n * n) / k;

    log_metrics();

    vector<long long> rest;
    try {
        while (!inf.seekEof()) rest.push_back(inf.readLong());
    } catch (...) {
        finish(_pe, "failed while reading hidden tail");
    }

    vector<long long> a(n + 1, 0);
    long long true_d = 0;

    if ((int)rest.size() == n) {

        unordered_set<long long> uniq;
        uniq.reserve((size_t)n * 2);
        for (int i = 1; i <= n; i++) {
            a[i] = rest[i - 1];
            uniq.insert(a[i]);
        }
        true_d = (long long)uniq.size();
    } else if ((int)rest.size() == 1) {

        true_d = rest[0];
        if (true_d < 1 || true_d > n) finish(_pe, "hidden d out of range");
        for (int i = 1; i <= n; i++) a[i] = (long long)(((i - 1) % (int)true_d) + 1);
    } else {
        finish(_pe, "hidden input tail must be either n integers (array) or 1 integer (d)");
    }

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

    deque<long long> mem;
    unordered_map<long long, int> freq;
    freq.reserve((size_t)k * 2 + 16);

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

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

        if (cmd == "?") {
            long long c;
            if (!(cin >> c)) protocol_error("missing index after '?'");
            if (c < 1 || c > n) protocol_error("index out of range");

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

            long long val = a[(int)c];
            bool inMem = false;
            auto it = freq.find(val);
            if (it != freq.end() && it->second > 0) inMem = true;

            cout << (inMem ? 'Y' : 'N') << endl;
            cout.flush();

            mem.push_back(val);
            freq[val]++;

            if ((int)mem.size() > k) {
                long long front = mem.front();
                mem.pop_front();
                auto it2 = freq.find(front);
                if (it2 != freq.end()) {
                    it2->second--;
                    if (it2->second <= 0) freq.erase(it2);
                }
            }
        } else if (cmd == "R") {
            resets++;
            if (resets > 30000) protocol_error("too many resets");
            mem.clear();
            freq.clear();
        } else if (cmd == "!") {
            long long ans;
            if (!(cin >> ans)) protocol_error("missing answer after '!'");
            if (ans == true_d) finish(_ok, "OK");
            wrong_answer("wrong diversity");
        } else {
            protocol_error("unknown command");
        }
    }
}

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

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

static int floorPow2(int x) {
    int p = 1;
    while ((p << 1) > 0 && (p << 1) <= x) p <<= 1;
    return p;
}

static int ceilPow2(int x) {
    if (x <= 1) return 1;
    int p = 1;
    while (p < x) p <<= 1;
    return p;
}

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

static void pickNK(int seed, int &n, int &k) {

    vector<int> ns = {128, 256, 512, 1024};
    int nPick;
    {
        int roll = rnd.next(0, 99);
        if (roll < 70) nPick = 1024;
        else if (roll < 90) nPick = 512;
        else if (roll < 97) nPick = 256;
        else nPick = 128;
    }
    n = nPick;

    long long need = (2LL * n * n + 20000LL - 1) / 20000LL;
    if (need < 1) need = 1;
    int minK = ceilPow2((int)need);
    if (minK > n) {

        for (int i = (int)ns.size() - 1; i >= 0; --i) {
            int candN = ns[i];
            long long need2 = (2LL * candN * candN + 20000LL - 1) / 20000LL;
            int minK2 = ceilPow2((int)max(1LL, need2));
            if (minK2 <= candN) {
                n = candN;
                minK = minK2;
                break;
            }
        }
        if (minK > n) {
            n = 1024;
            minK = 128;
        }
    }

    vector<int> ks;
    for (int kk = 1; kk <= n; kk <<= 1) {
        if (kk >= minK && 2LL * n * n <= 20000LL * kk) ks.push_back(kk);
    }
    if (ks.empty()) {

        k = n;
        return;
    }

    int roll = rnd.next(0, 99);
    if (roll < 75) k = ks.front();
    else if (roll < 90) k = ks.back();
    else k = ks[rnd.next(0, (int)ks.size() - 1)];
}

static int pickD(int n, int k, int seed) {

    int mod = seed % 7;
    if (mod == 0) return min(n, k + 1);
    if (mod == 1) return n;
    if (mod == 2) return 1;
    if (mod == 3) return max(2, min(n, k));
    int roll = rnd.next(0, 99);
    if (roll < 40) return min(n, k + 1);
    if (roll < 60) return min(n, 2 * k + 1);
    if (roll < 70) return 1;
    if (roll < 85) return n;
    return rnd.next(2, n);
}

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

    string mode = opt<string>("mode", "non");
    int nArg = opt<int>("n", -1);
    int kArg = opt<int>("k", -1);

    int seed = 1;
    if (argc >= 2) seed = atoi(argv[1]);

    int n = -1, k = -1, d = -1;
    vector<int> a;

    auto finalizeNK = [&]() {
        if (n < 1) n = 1;
        if (n > 1024) n = 1024;
        if (!isPow2(n)) n = floorPow2(n);

        if (k < 1) k = 1;
        if (k > n) k = n;
        if (!isPow2(k)) k = floorPow2(k);

        if (2LL * n * n > 20000LL * k) {
            long long need = (2LL * n * n + 20000LL - 1) / 20000LL;
            int minK = ceilPow2((int)max(1LL, need));
            if (minK <= n) k = max(k, minK);
            else {

                int nn = n;
                while (nn > 1 && 2LL * nn * nn > 20000LL * k) nn >>= 1;
                n = nn;
                if (k > n) k = n;
            }
        }

        if (k > n) k = n;
        if (!isPow2(n)) n = floorPow2(n);
        if (!isPow2(k)) k = floorPow2(k);
        if (n < 1) n = 1;
        if (k < 1) k = 1;
        if (k > n) k = n;

        if (2LL * n * n > 20000LL * k) {

            n = 1024;
            k = 128;
            if (2LL * n * n > 20000LL * k) {
                n = 512;
                k = 64;
            }
        }
    };

    if (seed == 1) {
        n = 1; k = 1; d = 1;
        a = {123456789};
    } else if (seed == 2) {
        n = 1024; k = 1024; d = 1024;
        a.resize(n);
        for (int i = 0; i < n; i++) a[i] = 1000000000 - i;
    } else if (seed == 3) {
        n = 1024; k = 128; d = 129;
        a.resize(n);
        for (int i = 0; i < n; i++) a[i] = 100000 + (i % d);
    } else {
        if (nArg != -1) n = nArg;
        if (kArg != -1) k = kArg;

        if (n == -1 || k == -1) {
            pickNK(seed, n, k);
        }
        finalizeNK();
        d = pickD(n, k, seed);

        if (mode == "non") {
            a.resize(n);
            if (d <= 1) {
                int val = 42424242;
                for (int i = 0; i < n; i++) a[i] = val;
            } else if (d >= n) {
                for (int i = 0; i < n; i++) a[i] = 1000000000 - i;

                for (int i = n - 1; i >= 1; --i) {
                    int j = rnd.next(0, i);
                    swap(a[i], a[j]);
                }
            } else {
                vector<int> base(d);
                for (int i = 0; i < d; i++) base[i] = 700000000 - i;
                shuffleVec(base);

                int shift = rnd.next(0, d - 1);

                for (int i = 0; i < n; i++) {
                    a[i] = base[(i + shift) % d];
                }

                if (n >= 4 && rnd.next(0, 99) < 35) {
                    int cut = rnd.next(n / 4, 3 * n / 4);
                    rotate(a.begin(), a.begin() + cut, a.end());
                }
            }
        }
    }

    if (mode != "non" && mode != "adp") {
        mode = "non";
    }

    if (mode == "non") {
        if (n == -1 || k == -1) { n = 1024; k = 128; }
        finalizeNK();
        if ((int)a.size() != n) {
            a.assign(n, 1);
            d = 1;
        }
        cout << n << " " << k << "\n";
        for (int i = 0; i < n; i++) {
            if (i) cout << ' ';
            cout << a[i];
        }
        cout << "\n";
    } else {
        if (n == -1 || k == -1) { n = 1024; k = 128; }
        finalizeNK();
        if (d == -1) d = pickD(n, k, seed);
        d = max(1, min(d, n));
        cout << n << " " << k << "\n";
        cout << d << "\n";
    }
    return 0;
}


This is the easy version of the problem. The only difference between the two versions is that in this version, it is guaranteed that every node is adjacent to node $1$.

This problem is interactive.

Baudelaire is very rich, so he bought a tree of size $n$ that is rooted at some arbitrary node. Additionally, every node has a value of $1$ or $-1$. In this version, every node is adjacent to node $1$. However, please note that node $1$ is not necessarily the root.

Cow the Nerd saw the tree and fell in love with it. However, computer science doesn't pay him enough, so he can't afford to buy it. Baudelaire decided to play a game with Cow the Nerd, and if he won, he would gift him the tree.

Cow the Nerd does not know which node is the root, and he doesn't know the values of the nodes either. However, he can ask Baudelaire queries of two types:

* $1$ $k$ $u_1$ $u_2$ $...$ $u_k$: Let $f(u)$ be the sum of the values of all nodes in the path from the root of the tree to node $u$. Cow the Nerd may choose an integer $k$ $(1 \le k \le n)$ and $k$ nodes $u_1, u_2, ..., u_k$, and he will receive the value $f(u_1) + f(u_2) + ... + f(u_k)$.
* $2$ $u$: Baudelaire will toggle the value of node $u$. Specifically, if the value of $u$ is $1$ it will become $-1$, and vice versa.

Cow the Nerd wins if he guesses the value of every node correctly (the values of the final tree, after performing the queries) within $n + 200$ total queries. Can you help him win?

Input

The first line of the input contains a single integer $t$ $(1 \le t \le 100)$, the number of test cases.

The first line of each test case contains a single integer $n$ $(2 \le n \le 10^3)$, the size of the tree.

Each of the next $n-1$ lines contains two integers $u$ and $v$ $(1 \le u, v \le n, u \neq v)$, denoting an edge between nodes $u$ and $v$ in the tree. In this version, it is guaranteed that either $u = 1$ or $v = 1$.

It is guaranteed that the sum of $n$ over all test cases does not exceed $10^3$ and that each graph provided is a valid tree.

Interaction

To ask a query of type $1$, output a line in the following format (without the quotes):

* "? 1 k $u_1$ $u_2$ $...$ $u_k$", ($1 \le k, u_i \le n$)

The jury will return a single integer, $f(u_1) + f(u_2) + ... + f(u_k)$.

To ask a query of type $2$, output a line in the following format:

* "? 2 $u$" ($1 \le u \le n$)

The jury will toggle the value of node $u$: if its value is $1$ it will become $-1$ and vice versa.

When you have found the answer, output a single line in the following format:

* "! $v_1, v_2, ..., v_n$" ($v_i = 1$ or $v_i = -1$, and $v_i$ is the value of node $i$ after performing the queries)

After that, proceed to process the next test case or terminate the program if it was the last test case. Printing the answer does not count as a query.

The interactor is not adaptive, meaning that the values of the tree are known before the participant asks the queries.

If your program makes more than $n + 200$ queries, your program should immediately terminate to receive the verdict Wrong Answer. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

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

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

Example

Input

```
1
4
1 2
3 1
1 4

0

-6
```

Output

```
? 1 3 1 2 3

? 2 2
? 1 3 1 2 3

! -1 -1 -1 1
```

Note

In the example, the root of the tree is node $2$, and the values of the nodes are $[-1, 1, -1, 1]$. Therefore, $f(1) = 0, f(2) = 1, f(3) = -1, f(4) = 1$.

First, we query about the sum $f(1) + f(2) + f(3)$, so we receive the value $0$. Then, we toggle the value of node $2$, and the values are: $[-1, -1, -1, 1]$. Therefore, $f(1) = -2, f(2) = -1, f(3) = -3, f(4) = -1$, and $f(1) + f(2) + f(3) = -6$.

Finally, we figure out that the values of the nodes are $[-1, -1, -1, 1]$, so we answer that.

Note that this is just an explanation of how the queries work, and it is not supposed to use any specific strategy to solve the problem.

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

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

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

    }
}

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

int n;
vector<vector<int>> adj;
int root_node;
vector<int> vals;
vector<int> parent;

void build_tree(int r) {
    parent.assign(n + 1, 0);
    queue<int> q;
    q.push(r);
    vector<bool> vis(n + 1, false);
    vis[r] = true;
    parent[r] = 0;

    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : adj[u]) {
            if (!vis[v]) {
                vis[v] = true;
                parent[v] = u;
                q.push(v);
            }
        }
    }
}

long long get_path_sum(int u) {
    long long s = 0;
    int cur = u;

    while (cur != 0) {
        s += vals[cur];
        cur = parent[cur];
    }
    return s;
}

void run_test_case() {

    n = inf.readInt(2, 1000, "n");

    long long local_limit = n + 200;
    query_limit += local_limit;

    log_metrics();

    adj.assign(n + 1, vector<int>());
    vector<pair<int, int>> edges_out;
    for (int i = 0; i < n - 1; ++i) {
        int u = inf.readInt(1, n, "u");
        int v = inf.readInt(1, n, "v");
        adj[u].push_back(v);
        adj[v].push_back(u);
        edges_out.push_back({u, v});
    }

    root_node = inf.readInt(1, n, "root");
    vals.assign(n + 1, 0);
    for (int i = 1; i <= n; ++i) {
        vals[i] = inf.readInt(-1, 1, "val");

        if (vals[i] == 0) vals[i] = 1;
    }

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

    build_tree(root_node);

    int local_q = 0;
    while (true) {
        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF (expected '?' or '!')");
        }

        if (token == "!") {

            vector<int> user_vals(n + 1);
            for (int i = 1; i <= n; ++i) {
                string vs;
                if (!(cin >> vs)) finish(_wa, "Unexpected EOF reading answer");
                try {
                    user_vals[i] = stoi(vs);
                } catch (...) {
                    finish(_wa, "Answer values must be integers");
                }
            }

            for (int i = 1; i <= n; ++i) {
                if (user_vals[i] != vals[i]) {
                    finish(_wa, format("Incorrect value for node %d. Expected %d, got %d", i, vals[i], user_vals[i]));
                }
            }

            return;
        } else {

            int type = -1;

            if (token == "?") {
                if (!(cin >> type)) finish(_wa, "Expected query type after '?'");
            } else {
                try {
                    type = stoi(token);
                } catch (...) {
                    finish(_wa, "Invalid query token (expected '?' or query type)");
                }
            }

            local_q++;
            queries++;

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

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

            if (local_q > local_limit) {
                finish(_wa, format("Query limit exceeded for this test case (%d > %lld)", local_q, local_limit));
            }

            if (type == 1) {

                int k;
                if (!(cin >> k)) finish(_wa, "Expected k for query type 1");
                if (k < 1 || k > n) finish(_wa, format("Invalid k=%d", k));

                long long total_sum = 0;
                for (int i = 0; i < k; ++i) {
                    int u;
                    if (!(cin >> u)) finish(_wa, "Expected node index");
                    if (u < 1 || u > n) finish(_wa, format("Invalid node index %d", u));
                    total_sum += get_path_sum(u);
                }

                cout << total_sum << endl;
                cout.flush();
            } else if (type == 2) {

                int u;
                if (!(cin >> u)) finish(_wa, "Expected node index for query type 2");
                if (u < 1 || u > n) finish(_wa, format("Invalid node index %d", u));

                vals[u] = -vals[u];

            } else {
                finish(_wa, format("Unknown query type %d", type));
            }
        }
    }
}

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

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

    int t = inf.readInt(1, 100, "t");
    cout << t << endl;
    cout.flush();

    for (int i = 0; i < t; ++i) {
        run_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");

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

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

        n = 2 + rnd.wnext(999, 10);
    }

    cout << 1 << "\n";

    cout << n << "\n";

    vector<pair<int, int>> edges;
    edges.reserve(n - 1);
    for (int i = 2; i <= n; i++) {

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

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

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

    if (mode == "non") {

        int root = rnd.next(1, n);
        cout << root << "\n";

        vector<int> vals(n);
        int strategy = rnd.next(4);

        if (strategy == 0) {

            for (int& x : vals) x = rnd.next(2) ? 1 : -1;
        } else if (strategy == 1) {

            for (int& x : vals) x = (rnd.next(10) == 0) ? -1 : 1;
        } else if (strategy == 2) {

            for (int& x : vals) x = (rnd.next(10) == 0) ? 1 : -1;
        } else {

            vector<int> temp(n);
            for (int i = 0; i < n; i++) temp[i] = (i < n / 2) ? 1 : -1;
            shuffle(temp.begin(), temp.end());
            vals = temp;
        }

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

    return 0;
}