This is an interactive problem.

Upon clearing the Waterside Area, Gretel has found a monster named Genokraken, and she's keeping it contained for her scientific studies.

The monster's nerve system can be structured as a tree$^{\dagger}$ of $n$ nodes (really, everything should stop resembling trees all the time$\ldots$), numbered from $0$ to $n-1$, with node $0$ as the root.

Gretel's objective is to learn the exact structure of the monster's nerve system — more specifically, she wants to know the values $p_1, p_2, \ldots, p_{n-1}$ of the tree, where $p_i$ ($0 \le p_i < i$) is the direct parent node of node $i$ ($1 \le i \le n - 1$).

She doesn't know exactly how the nodes are placed, but she knows a few convenient facts:

* If we remove root node $0$ and all adjacent edges, this tree will turn into a forest consisting of only paths$^{\ddagger}$. Each node that was initially adjacent to the node $0$ will be the end of some path.
* The nodes are indexed in a way that if $1 \le x \le y \le n - 1$, then $p_x \le p_y$.
* Node $1$ has exactly two adjacent nodes (including the node $0$).

|  |  |  |
| --- | --- | --- |
|  |  |  |
| The tree in this picture does not satisfy the condition, because if we remove node $0$, then node $2$ (which was initially adjacent to the node $0$) will not be the end of the path $4-2-5$. | The tree in this picture does not satisfy the condition, because $p_3 \le p_4$ must hold. | The tree in this picture does not satisfy the condition, because node $1$ has only one adjacent node. |

Gretel can make queries to the containment cell:

* "? a b" ($1 \le a, b < n$, $a \ne b$) — the cell will check if the simple path between nodes $a$ and $b$ contains the node $0$.

However, to avoid unexpected consequences by overstimulating the creature, Gretel wants to query at most $2n - 6$ times. Though Gretel is gifted, she can't do everything all at once, so can you give her a helping hand?

$^{\dagger}$A tree is a connected graph where every pair of distinct nodes has exactly one simple path connecting them.

$^{\ddagger}$A path is a tree whose vertices can be listed in the order $v_1, v_2, \ldots, v_k$ such that the edges are $(v_i, v_{i+1})$ ($1 \le i < k$).

Input

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

The first line of each test case contains a single integer $n$ ($4 \le n \le 10^4$) — the number of nodes in Genokraken's nerve system.

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

Interaction

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

Then you can make queries of the following type:

* "? a b" (without quotes) ($1 \le a, b < n$, $a \ne b$).

After the query, read an integer $r$ — the answer to your query. You are allowed to use at most $2n - 6$ queries of this type.

* If the simple path between nodes $a$ and $b$ does not contain node $0$, you will get $r = 0$.
* If the simple path between nodes $a$ and $b$ contains node $0$, you will get $r = 1$.
* In case you make more than $2n-6$ queries or make an invalid query, you will get $r = -1$. You will need to terminate after this to get the "Wrong answer" verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you find out the structure, output a line in the format "! $p_1 \space p_2 \ldots p_{n-1}$" (without quotes), where $p_i$ ($0 \le p_i < i$) denotes the index of the direct parent of node $i$. This query is not counted towards the $2n - 6$ queries limit.

After solving one test case, the program should immediately move on to the next one. After solving all test cases, the program should be terminated immediately.

After printing any query do not forget to output an end of line and flush the output buffer. 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.

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

Example

Input

```
3
4

1

5

1

0

9
```

Output

```
? 2 3

! 0 0 1

? 2 3

? 2 4

! 0 0 1 2

! 0 0 0 1 3 5 6 7
```

Note

In the first test case, Genokraken's nerve system forms the following tree:

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

* The answer to "? 2 3" is $1$. This means that the simple path between nodes $2$ and $3$ contains node $0$.

In the second test case, Genokraken's nerve system forms the following tree:

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

* The answer to "? 2 3" is $1$. This means that the simple path between nodes $2$ and $3$ contains node $0$.
* The answer to "? 2 4" is $0$. This means that the simple path between nodes $2$ and $4$ doesn't contain node $0$.

In the third test case, Genokraken's nerve system forms the following tree:

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

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

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

static void log_metrics() {
    try {
        tout << "queries=" << queries << "\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& s) {
    if (!(cin >> s)) return false;
    return true;
}

static bool parseLL(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;
    }
    __int128 val = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        val = val * 10 + (c - '0');
        if (!neg && val > (__int128)LLONG_MAX) return false;
        if (neg && -val < (__int128)LLONG_MIN) return false;
    }
    out = neg ? (long long)(-val) : (long long)val;
    return true;
}

static bool readLL(long long& v) {
    string s;
    if (!readToken(s)) return false;
    return parseLL(s, v);
}

struct TestCase {
    int n = 0;
    vector<int> parent;
    vector<int> rootChild;
};

static TestCase loadCaseFromInf() {
    TestCase tc;
    tc.n = inf.readInt(4, 10000, "n");
    tc.parent.assign(tc.n, -1);
    tc.parent[0] = -1;
    for (int i = 1; i < tc.n; i++) {
        int p = inf.readInt(0, i - 1, ("p_" + to_string(i)).c_str());
        tc.parent[i] = p;
    }

    vector<vector<int>> children(tc.n);
    children[0].reserve(tc.n);
    for (int i = 1; i < tc.n; i++) children[tc.parent[i]].push_back(i);

    tc.rootChild.assign(tc.n, -1);
    tc.rootChild[0] = 0;

    queue<int> q;
    for (int c : children[0]) {
        tc.rootChild[c] = c;
        q.push(c);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int u : children[v]) {
                tc.rootChild[u] = c;
                q.push(u);
            }
        }
    }

    for (int i = 1; i < tc.n; i++) {
        if (tc.rootChild[i] == -1) quitf(_fail, "Internal error: node %d not reachable from root 0", i);
    }
    return tc;
}

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

    int t = inf.readInt(1, 500, "t");
    vector<TestCase> cases;
    cases.reserve(t);

    long long totalBudget = 0;
    for (int tc = 0; tc < t; tc++) {
        TestCase one = loadCaseFromInf();
        totalBudget += (long long)2 * one.n - 6;
        cases.push_back(std::move(one));
    }

    query_limit = totalBudget;
    log_metrics();

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

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

    for (int tc = 0; tc < t; tc++) {
        const int n = cases[tc].n;
        const vector<int>& parent = cases[tc].parent;
        const vector<int>& rootChild = cases[tc].rootChild;

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

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

            if (cmd == "?") {
                long long a_ll, b_ll;
                if (!readLL(a_ll) || !readLL(b_ll)) finish(_pe, "Malformed query: expected two integers");
                if (a_ll < 1 || a_ll >= n || b_ll < 1 || b_ll >= n) finish(_pe, "Invalid query indices");
                if (a_ll == b_ll) finish(_pe, "Invalid query: a == b");

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

                int a = (int)a_ll, b = (int)b_ll;
                int ans = (rootChild[a] != rootChild[b]) ? 1 : 0;

                cout << ans << "\n";
                cout.flush();
            } else if (cmd == "!") {
                for (int i = 1; i < n; i++) {
                    long long x;
                    if (!readLL(x)) finish(_pe, "Malformed answer: not enough integers after '!'");
                    if (x < 0 || x >= i) finish(_wa, "Answer has invalid parent value");
                    if ((int)x != parent[i]) finish(_wa, "Wrong parent array");
                }
                break;
            } else {
                finish(_pe, "Unknown command token");
            }
        }
    }

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

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

static vector<int> buildParentsFromChainLengths(int n, const vector<int>& len) {
    int m = (int)len.size();
    vector<int> parent(n, -1);
    vector<int> last(m, 0);
    int cur = 0;

    int maxLen = 0;
    for (int x : len) maxLen = max(maxLen, x);

    for (int depth = 1; depth <= maxLen; depth++) {
        for (int i = 0; i < m; i++) {
            if (depth > len[i]) continue;
            cur++;
            if (depth == 1) parent[cur] = 0;
            else parent[cur] = last[i];
            last[i] = cur;
        }
    }

    ensuref(cur == n - 1, "Internal error: constructed %d nodes, expected %d", cur, n - 1);

    for (int i = 1; i < n; i++) {
        ensuref(0 <= parent[i] && parent[i] < i, "Invalid parent[%d]=%d", i, parent[i]);
    }

    int deg1 = 0;
    for (int i = 0; i < n; i++) {
        if (i == 1) {
            if (parent[i] != -1) deg1++;
        } else if (i > 1) {
            if (parent[i] == 1) deg1++;
            if (parent[1] == i) deg1++;
        }
    }
    ensuref(deg1 == 2, "Node 1 degree must be 2, got %d", deg1);

    for (int i = 2; i < n; i++) ensuref(parent[i - 1] <= parent[i], "Parent array not nondecreasing at %d", i);

    return parent;
}

static vector<int> makeLengthsCorner(int seed, int& nOut) {
    if (seed == 1) {
        nOut = 4;

        return {2, 1};
    }
    if (seed == 2) {
        nOut = 6;

        return {2, 1, 1, 1};
    }

    nOut = 10000;

    int m = 5000;
    vector<int> len(m, 2);
    len[m - 1] = 1;
    return len;
}

static vector<int> makeLengthsPattern0(int n) {

    int mLo = max(2, n / 3);
    int mHi = max(2, n / 2);
    int m = rnd.next(mLo, mHi);
    m = min(m, n - 2);

    vector<int> len(m, 1);

    int wantTwo = rnd.next(max(1, m / 3), m);
    vector<int> idx(m);
    iota(idx.begin(), idx.end(), 0);

    for (int i = m - 1; i > 0; i--) {
        int j = rnd.next(0, i);
        swap(idx[i], idx[j]);
    }
    for (int k = 0; k < wantTwo; k++) len[idx[k]] = 2;

    len[0] = max(len[0], 2);

    long long sum = 0;
    for (int x : len) sum += x;
    long long need = (long long)(n - 1) - sum;

    if (need > 0) {
        int tails = rnd.next(1, min(12, m));
        vector<int> tailIdx;
        tailIdx.reserve(tails);
        for (int i = 0; i < tails; i++) tailIdx.push_back(rnd.next(0, m - 1));
        for (int i = 0; i < (int)tailIdx.size() && need > 0; i++) {
            int ci = tailIdx[i];
            int add = (int)min<long long>(need, rnd.next(100, 800));
            len[ci] += add;
            need -= add;
        }
        if (need > 0) {
            len[0] += (int)need;
            need = 0;
        }
    } else if (need < 0) {
        long long over = -need;

        for (int i = m - 1; i >= 0 && over > 0; i--) {
            int minLen = (i == 0 ? 2 : 1);
            while (len[i] > minLen && over > 0) {
                len[i]--;
                over--;
            }
        }
        ensuref(over == 0, "Pattern0 adjustment failed: could not reduce enough");
    }

    long long finalSum = 0;
    for (int x : len) finalSum += x;
    ensuref(finalSum == n - 1, "Pattern0 sum mismatch %lld vs %d", finalSum, n - 1);
    ensuref(len[0] >= 2, "Pattern0 len[0] must be >=2");
    return len;
}

static vector<int> makeLengthsPattern1(int n) {

    int m = rnd.next(5, 30);
    m = min(m, n - 2);
    vector<int> len(m, 1);

    long long remaining = (long long)(n - 1) - m;
    for (int i = 1; i < m && remaining > 0; i++) {
        int add = (int)min<long long>(remaining, rnd.next(1, 300));
        len[i] += add;
        remaining -= add;
    }

    len[0] = 2;
    remaining -= 1;
    if (remaining < 0) remaining = 0;
    len[0] += (int)remaining;

    long long finalSum = 0;
    for (int x : len) finalSum += x;
    ensuref(finalSum == n - 1, "Pattern1 sum mismatch %lld vs %d", finalSum, n - 1);
    ensuref(len[0] >= 2, "Pattern1 len[0] must be >=2");
    return len;
}

static vector<int> makeLengthsPattern2(int n) {

    int m = rnd.next(80, 220);
    m = min(m, n - 2);
    vector<int> len(m, 1);

    int period = rnd.next(7, 19);
    int peak = rnd.next(30, 160);

    for (int i = 0; i < m; i++) {
        int pos = i % period;
        int target = max(1, peak - pos * (peak / period));
        len[i] += rnd.next(0, max(0, target - 1));
    }

    len[0] = max(len[0], 2);

    long long sum = 0;
    for (int x : len) sum += x;
    long long need = (long long)(n - 1) - sum;

    if (need > 0) {

        int i = 0;
        while (need > 0) {
            int add = (int)min<long long>(need, (i < m / 3 ? rnd.next(5, 200) : rnd.next(1, 20)));
            len[i] += add;
            need -= add;
            i++;
            if (i == m) i = 0;
        }
    } else if (need < 0) {
        long long over = -need;
        for (int i = m - 1; i >= 0 && over > 0; i--) {
            int minLen = (i == 0 ? 2 : 1);
            while (len[i] > minLen && over > 0) {
                len[i]--;
                over--;
            }
        }
        ensuref(over == 0, "Pattern2 adjustment failed: could not reduce enough");
    }

    long long finalSum = 0;
    for (int x : len) finalSum += x;
    ensuref(finalSum == n - 1, "Pattern2 sum mismatch %lld vs %d", finalSum, n - 1);
    ensuref(len[0] >= 2, "Pattern2 len[0] must be >=2");
    return len;
}

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

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

    int nOpt = opt<int>("n", -1);
    int patternOpt = opt<int>("pattern", -1);

    int n = -1;
    vector<int> len;

    if (seed >= 1 && seed <= 3) {
        len = makeLengthsCorner((int)seed, n);
    } else {
        if (nOpt != -1) n = nOpt;
        else n = rnd.next(9500, 10000);
        n = max(n, 4);
        n = min(n, 10000);

        int pattern = patternOpt;
        if (pattern == -1) pattern = (int)(seed % 3);

        if (pattern == 0) len = makeLengthsPattern0(n);
        else if (pattern == 1) len = makeLengthsPattern1(n);
        else len = makeLengthsPattern2(n);
    }

    cout << 1 << "\n";
    cout << n << "\n";

    if (mode == "non") {
        vector<int> parent = buildParentsFromChainLengths(n, len);
        for (int i = 1; i < n; i++) {
            if (i > 1) cout << ' ';
            cout << parent[i];
        }
        cout << "\n";
    } else if (mode == "adp") {

    } else {
        quitf(_fail, "Unknown --mode=%s (expected non or adp)", mode.c_str());
    }

    return 0;
}


This is the Hard Version of the problem. The only difference between the two versions is that in the Hard Version the tree may be of any shape.

This problem is interactive.

Baudelaire is very rich, so he bought a tree of size $n$, rooted at some arbitrary node. Additionally, every node has a value of $1$ or $-1$.

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.

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

```
3
4
1 4
4 2
2 3

1

-1

-5

-5

2
1 2

2

7
1 2
2 7
7 3
7 4
7 5
7 6

-1
```

Output

```
? 1 3 1 2 4

? 1 2 3 1

? 2 4
? 1 3 1 2 4

? 1 2 3 1

! -1 -1 -1 -1

? 1 1 1

! 1 1

? 1 1 1

! -1 1 1 1 1 1 -1
```

Note

In the first example, the root of the tree is node $4$ and the values are: $[-1, -1, -1, 1]$ (the $i$-th value is the value of node $i$).

Initially, $f(1) = 0, f(2) = 0, f(3) = -1, f(4) = 1$. Therefore, the answer to our first query is $f(1) + f(2) + f(4) = 1$, and of the second query is $f(3) + f(1) = -1$.

After toggling the value of node $4$, the values are $[-1, -1, -1, -1]$. In addition, $f(1) = -2, f(2) = -2, f(3) = -3, f(4) = -1$. Therefore, $f(1) + f(2) + f(4) = -5$ and $f(3) + f(1) = -5$.

We answer that the final values of the nodes are $[-1, -1, -1, -1]$, which is correct. Notice that we report the values of the nodes after the changes, and not before.

In the second example, the root of the tree is $2$ and the initial values are $[1, 1]$.

In the last example, the root of the tree is $1$ and the initial values are $[-1, 1, 1, 1, 1, 1, -1]$.

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

struct BIT {
    int n;
    vector<long long> tree;

    void init(int _n) {
        n = _n;
        tree.assign(n + 1, 0);
    }

    void add(int i, long long val) {
        for (; i <= n; i += i & -i) tree[i] += val;
    }

    void range_add(int l, int r, long long val) {
        if (l > r) return;
        add(l, val);
        add(r + 1, -val);
    }

    long long query(int i) {
        long long res = 0;
        for (; i > 0; i -= i & -i) res += tree[i];
        return res;
    }
};

static const int HARD_CAP = 500000;

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

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

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

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

        int root = inf.readInt();
        vector<int> current_vals(n + 1);
        for (int i = 1; i <= n; ++i) {
            current_vals[i] = inf.readInt();
        }

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

        query_limit += (n + 200);
        log_metrics();

        vector<int> tin(n + 1), sz(n + 1);
        int timer = 0;

        function<void(int, int)> dfs = [&](int u, int p) {
            tin[u] = ++timer;
            sz[u] = 1;
            for (int v : adj[u]) {
                if (v != p) {
                    dfs(v, u);
                    sz[u] += sz[v];
                }
            }
        };
        dfs(root, 0);

        BIT bit;
        bit.init(n);

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

                bit.range_add(tin[i], tin[i] + sz[i] - 1, current_vals[i]);
            }
        }

        bool solved = false;
        while (true) {

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

            string token;
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF reading query token.");
            }

            if (token == "!") {

                vector<int> guess(n);
                for (int i = 0; i < n; ++i) {
                    if (!(cin >> guess[i])) finish(_wa, "EOF reading answer.");
                }

                for (int i = 0; i < n; ++i) {
                    if (guess[i] != current_vals[i + 1]) {
                        finish(_wa, format("Incorrect value for node %d in test case %d. Expected %d, got %d.",
                                           i + 1, tc, current_vals[i + 1], guess[i]));
                    }
                }

                solved = true;
                break;
            }

            int type = -1;
            if (token == "?") {
                if (!(cin >> type)) finish(_wa, "EOF reading query type.");
            } else {

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

            queries++;

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

            if (type == 1) {

                int k;
                if (!(cin >> k)) finish(_wa, "EOF reading k.");
                if (k < 1 || k > n) finish(_wa, "k out of bounds.");

                long long total_sum = 0;
                for (int i = 0; i < k; ++i) {
                    int u;
                    if (!(cin >> u)) finish(_wa, "EOF reading node index.");
                    if (u < 1 || u > n) finish(_wa, "Node index out of bounds.");

                    total_sum += bit.query(tin[u]);
                }
                cout << total_sum << endl;
                cout.flush();

            } else if (type == 2) {

                int u;
                if (!(cin >> u)) finish(_wa, "EOF reading u.");
                if (u < 1 || u > n) finish(_wa, "Node index out of bounds.");

                int old_val = current_vals[u];
                int new_val = -old_val;
                current_vals[u] = new_val;

                long long diff = new_val - old_val;

                bit.range_add(tin[u], tin[u] + sz[u] - 1, diff);

            } else {
                finish(_wa, "Unknown query type " + to_string(type));
            }
        }

        if (!solved) {
            finish(_wa, "Loop terminated without solution (should not happen).");
        }
    }

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

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

struct TestCase {
    int n;
    vector<pair<int, int>> edges;
    int root;
    vector<int> values;
};

void relabel_and_shuffle(int n, vector<pair<int, int>>& edges) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());

    for (auto& e : edges) {
        e.first = p[e.first - 1];
        e.second = p[e.second - 1];
        if (rnd.next(2)) swap(e.first, e.second);
    }
    shuffle(edges.begin(), edges.end());
}

void genTree(int n, int type, vector<pair<int, int>>& edges) {
    edges.clear();
    edges.reserve(n - 1);
    if (n == 2) {
        edges.push_back({1, 2});
        return;
    }

    if (type == 0) {
        for (int i = 2; i <= n; i++)
            edges.push_back({rnd.next(1, i - 1), i});
    } else if (type == 1) {
        for (int i = 1; i < n; i++)
            edges.push_back({i, i + 1});
    } else if (type == 2) {
        for (int i = 2; i <= n; i++)
            edges.push_back({1, i});
    } else if (type == 3) {
        int len = rnd.next(2, max(2, n - 1));
        if (n <= 5) len = 2;
        for (int i = 1; i < len; i++)
            edges.push_back({i, i + 1});
        for (int i = len + 1; i <= n; i++)
            edges.push_back({len, i});
    } else if (type == 4) {
        for (int i = 2; i <= n; i++)
            edges.push_back({i / 2, i});
    }

    relabel_and_shuffle(n, edges);
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    string mode = opt<string>("mode", "non");
    long long seedVal = atoll(argv[1]);

    vector<TestCase> cases;
    int MAX_N = 1000;

    if (seedVal == 1) {

        vector<int> ns = {2, 3, 4, 5, 10, 20};
        for (int n : ns) {
            TestCase tc;
            tc.n = n;

            if (n == 2) genTree(n, 1, tc.edges);
            else if (n == 3) genTree(n, 2, tc.edges);
            else if (n == 5) genTree(n, 3, tc.edges);
            else genTree(n, 0, tc.edges);

            tc.root = rnd.next(1, n);
            for (int i = 0; i < n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
            cases.push_back(tc);
        }
    } else if (seedVal == 2) {

        TestCase tc;
        tc.n = MAX_N;
        genTree(tc.n, 1, tc.edges);
        tc.root = rnd.next(1, tc.n);
        for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
        cases.push_back(tc);
    } else if (seedVal == 3) {

        TestCase tc;
        tc.n = MAX_N;
        genTree(tc.n, 2, tc.edges);
        tc.root = rnd.next(1, tc.n);
        for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
        cases.push_back(tc);
    } else {

        int rem = MAX_N;

        if (rnd.next(100) < 40) {
            TestCase tc;
            tc.n = rem;
            genTree(tc.n, rnd.next(0, 4), tc.edges);
            tc.root = rnd.next(1, tc.n);
            for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
            cases.push_back(tc);
        } else {

            while (rem >= 2) {

                if (cases.size() == 99) {
                    TestCase tc;
                    tc.n = rem;
                    genTree(tc.n, rnd.next(0, 4), tc.edges);
                    tc.root = rnd.next(1, tc.n);
                    for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
                    cases.push_back(tc);
                    break;
                }

                int n;

                if (rem <= 10) n = rem;
                else {

                    int ub = min(rem, 200);
                    if (rnd.next(2)) ub = min(rem, 50);
                    n = rnd.next(2, ub);
                }

                TestCase tc;
                tc.n = n;
                genTree(tc.n, rnd.next(0, 4), tc.edges);
                tc.root = rnd.next(1, tc.n);
                for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
                cases.push_back(tc);

                rem -= n;
            }
        }
    }

    println(cases.size());
    for (const auto& tc : cases) {
        println(tc.n);
        for (const auto& e : tc.edges) {
            println(e.first, e.second);
        }
        if (mode == "non") {
            println(tc.root);
            println(tc.values);
        }
    }

    return 0;
}


wavetearz - contemporary chemical bonds

You have reached the final level of the popular roguelike game "Isaac's Keybindings". Instead of a boss, you encounter a shopkeeper who holds an hidden array of integers $a_1, a_2, \ldots, a_n$, where $0 \leq a_i < 2^{30}$ for each $i$ in $[1, n]$.

It is guaranteed that the array is generated randomly, i.e., each $a_i$ ($1 \leq i \leq n$) is an integer independently generated uniformly at random in $[0, 2^{30})$, in all the tests excluding the example.

Let $f(u, v) = a_u \oplus a_{u+1} \oplus \ldots \oplus a_v$, where $\oplus$ is the bitwise $\texttt{XOR}$.

You can ask queries of the following form: $\texttt{? u v}$, with $1 \leq u \leq v \leq n$.

The answer to the query is:

* $-1$, if $f(u, v) = 0$;
* $\lfloor \log_2(f(u, v)) \rfloor$ otherwise.

Each query has a cost of $\frac{1}{v-u+1}$ robocoins. On each test, you are given $300$ robocoins in total to pass at most $30$ test cases (that is, you can spend $10$ robocoins on average for a single test case). If your balance ever becomes negative you lose. Note that your robocoin balance does not need to be an integer at any moment.

Find the answer to all possible $\frac{n(n+1)}{2}$ queries without losing.

Input

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

The first line of each test case contains one integer $n$ ($n = 3$ or $n = 100$) — the length of the array $a_1, a_2, \ldots, a_n$. It is guaranteed that the array is generated randomly in all the tests excluding the example.

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

Interaction

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

To ask a query, print a line in the format $\texttt{? u v}$ with $1 \leq u \leq v \leq n$.

As a response to the query, you will receive $-2$ if you made an invalid query (i.e., the format is invalid, or you would reach a negative amount of robocoins). In that case, you should exit immediately. Otherwise, you will receive the answer to the query.

When you determine the answers to all the $\frac{n(n+1)}{2}$ queries, print them in the following format.

Print $n+1$ lines. The first line must contain a single character $\texttt{!}$. The $i$-th of the next $n$ lines must contain $n-i+1$ integers: the answers to queries $\texttt{? i i}, \, \texttt{? i i+1}, \,\ldots, \, \texttt{? i n}$, respectively.

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{stdout.flush()}$ in Python;
* see the documentation for other languages.

Example

Input

```
1
3

2

-1

1
```

Output

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

Note

In the example, the hidden array is $[a_1, a_2, a_3] = [2, 4, 6]$.

* First, you ask $\texttt{? 1 2}$. Since $f(1, 2) = a_1 \oplus a_2 = 6$, the answer is $\lfloor \log_2(6) \rfloor = 2$.
* Then, you ask $\texttt{? 1 3}$. Since $f(1, 3) = a_1 \oplus a_2 \oplus a_3 = 0$, the answer is $-1$.
* Then, you ask $\texttt{? 2 3}$. Since $f(2, 3) = a_2 \oplus a_3 = 2$, the answer is $\lfloor \log_2(2) \rfloor = 1$.

Now, even without knowing the hidden array, you claim the answer to all the possible $6$ queries. For example, you claim that the answer to $\texttt{? 1 1}$ is $1$.

You have spent $1/2 + 1/3 + 1/2 = 4/3$ robocoins, which is less than the allowed $300$ robocoins.

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

static long long queries = 0;
static long long query_limit = 50000;
static double remaining_budget = 300.0;
static const double EPS = 1e-9;

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

long long get_val(int u, int v, const vector<int>& pref) {

    long long x = pref[v] ^ pref[u-1];
    if (x == 0) return -1;

    return 31 - __builtin_clz((unsigned int)x);
}

void solve_case(int test_idx) {

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

    vector<int> pref(n + 1, 0);
    for (int i = 0; i < n; i++) {
        pref[i+1] = pref[i] ^ a[i];
    }

    cout << n << endl;

    while (true) {

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

        string token;

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

        if (token == "!") {

            for (int i = 1; i <= n; i++) {
                for (int j = i; j <= n; j++) {
                    long long user_ans;
                    if (!(cin >> user_ans)) {
                        finish(_wa, "Unexpected EOF while reading answer matrix");
                    }
                    long long correct = get_val(i, j, pref);
                    if (user_ans != correct) {

                        cout << -2 << endl;
                        finish(_wa, format("Wrong answer for range [%d, %d]: expected %lld, got %lld", i, j, correct, user_ans));
                    }
                }
            }

            return;
        } else {

            int u, v;
            if (token == "?") {
                if (!(cin >> u >> v)) finish(_wa, "Invalid query format");
            } else {

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

            if (u < 1 || u > n || v < 1 || v > n || u > v) {
                cout << -2 << endl;
                finish(_wa, format("Query range out of bounds: %d %d", u, v));
            }

            double cost = 1.0 / (v - u + 1);
            remaining_budget -= cost;
            queries++;

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

            if (remaining_budget < -EPS) {
                cout << -2 << endl;
                finish(_wa, "Budget limit exceeded (300 robocoins)");
            }

            cout << get_val(u, v, pref) << endl;
        }
    }
}

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

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

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

    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 def_t = 30;
    int def_n = 100;
    if (string(argv[1]) == "1") {
        def_t = 1;
        def_n = 3;
    }

    int t = opt<int>("t", def_t);
    int n = opt<int>("n", def_n);

    if (mode == "non" || mode == "adp") {
        cout << t << endl;
        for (int i = 0; i < t; i++) {
            cout << n << endl;
            vector<int> a(n);

            if (string(argv[1]) == "1" && i == 0 && n == 3) {
                a = {2, 4, 6};
            } else {

                for (int j = 0; j < n; j++) {
                    a[j] = rnd.next(0, (1 << 30) - 1);
                }
            }

            for (int j = 0; j < n; j++) {
                cout << a[j] << (j == n - 1 ? "" : " ");
            }
            cout << endl;
        }
    } else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}


This is an interactive problem.

Your task is to write a program that guesses a secret number through repetitive queries and responses. The secret number is a non-negative integer less than $1 0 ^ { 1 8 }$ .

Let $x$ be the secret number. In a query, you specify a non-negative integer $a$ . In response to this, the digit sum of $( x + a )$ will be returned. Here, the digit sum of a number means the sum of all the digits in its decimal notation. For example, the digit sum of 4096 is $4 + 0 + 9 + 6 = 1 9$ .

# Interaction

You should start with sending a query to the standard output and receiving the response from the standard input. This interaction can be repeated a number of times. When you have become confident of your guess through these interactions, you can send your answer.

A query should be in the following format, followed by a newline.

query $a$

Here, $a$ is an integer between 0 and $1 0 ^ { 1 8 } - 1$ , inclusive. In response to this query, the digit sum of $( x + a )$ , where $x$ is the secret number, is sent back to the standard input, followed by a newline.

You should send your answer to the standard output in the following format, followed by a newline.

answer $y$

Here, $y$ is the secret number you have identified, an integer between 0 and $1 0 ^ { 1 8 } - 1$ , inclusive.

You can send the answer only once, so you have to become sure of your guess through repeated interactions before sending the answer. However, you can send no more than 75 queries, and thus you have to choose your queries cleverly. After sending the answer, your program should terminate without any extra output.

# Notes on interactive judging

When your output violates any of the conditions above (invalid format, $a$ or $y$ being out of the range, too many queries, an extra output after sending your answer, and so on), your submission will be judged as a wrong answer. As some environments require flushing the output buffers, make sure that your outputs are actually sent. Otherwise, your outputs will never reach the judge.

![](images/4307c5b11e8043fa11d70eefc855cd43d417bbb10f3e9c091d7931656602dcb7.jpg)

In this example, the secret number $x$ is 75. In response to the first query, 15 is returned because $x + a = 7 5 + 3 = 7 8$ and its digit sum is $7 + 8 = 1 5$ . After the second response, you can conclude that the only possible secret number is 75.

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

using namespace std;

static long long queries = 0;
static long long query_limit = 75;
static const long long HARD_CAP = 20000;

long long get_digit_sum(long long n) {
    string s = to_string(n);
    long long sum = 0;
    for (char c : s) {
        sum += (c - '0');
    }
    return sum;
}

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

    }
}

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

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    long long x = inf.readLong();

    log_metrics();

    string token;
    while (cin >> token) {
        string lower_token = token;
        transform(lower_token.begin(), lower_token.end(), lower_token.begin(), ::tolower);

        bool is_query = false;
        bool is_answer = false;
        long long val = 0;

        if (lower_token == "query" || token == "?") {
            is_query = true;
            if (!(cin >> val)) {
                finish(_wa, "Unexpected EOF after query token");
            }
        } else if (lower_token == "answer" || token == "!") {
            is_answer = true;
            if (!(cin >> val)) {
                finish(_wa, "Unexpected EOF after answer token");
            }
        } else {

            if (isdigit(token[0]) || (token.size() > 1 && token[0] == '-' && isdigit(token[1]))) {
                try {
                    size_t pos;
                    val = stoll(token, &pos);
                    if (pos != token.size()) {
                        finish(_wa, "Invalid token format (trailing characters): " + token);
                    }
                    is_query = true;
                } catch (...) {
                    finish(_wa, "Invalid number format (parse error/overflow): " + token);
                }
            } else {
                finish(_wa, "Unknown token or invalid format: " + token);
            }
        }

        if (is_answer) {

            if (val < 0 || val >= 1000000000000000000LL) {
                finish(_wa, "Answer is out of range [0, 10^18 - 1]");
            }

            if (val == x) {
                finish(_ok, "Correct answer");
            } else {
                finish(_wa, "Wrong answer");
            }
        } else if (is_query) {

            if (val < 0 || val >= 1000000000000000000LL) {
                finish(_wa, "Query parameter is out of range [0, 10^18 - 1]");
            }

            queries++;

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

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

            long long resp = get_digit_sum(x + val);
            cout << resp << endl;
        }
    }

    finish(_wa, "Submission terminated without providing an answer");

    return 0;
}

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

using namespace std;

long long queries = 0;
const long long QUERY_LIMIT = 75;
const long long HARD_CAP = 2000;

bool adaptive = false;
long long fixed_secret = 0;
vector<long long> pool;

inline int get_digit_sum(long long n) {
    int sum = 0;
    while (n > 0) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}

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

    }
}

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

void generate_pool() {

    pool.reserve(150000);
    mt19937_64 rng(1337);

    auto add = [&](long long x) {
        if (x >= 0 && x < 1000000000000000000LL) {
            pool.push_back(x);
        }
    };

    for(int i = 0; i < 40000; ++i) {
        add(rng() % 1000000000000000000LL);
    }

    long long p10 = 1;
    for(int k = 0; k <= 18; ++k) {
        long long suffix = p10 - 1;

        long long max_prefix = (1000000000000000000LL - 1 - suffix) / p10;

        if (max_prefix >= 0) {

            if (max_prefix < 2500) {
                for(long long pre = 0; pre <= max_prefix; ++pre) {
                    add(pre * p10 + suffix);
                }
            } else {
                for(int i = 0; i < 2500; ++i) {
                    long long prefix = rng() % (max_prefix + 1);
                    add(prefix * p10 + suffix);
                }
            }
        }
        if (k < 18) p10 *= 10;
    }

    for(int i = 0; i < 20000; ++i) {
        long long x = 0;
        for(int d = 0; d < 18; ++d) {
            int dig = rng() % 10;
            if (rng() % 3 == 0) dig = 9;
            x = x * 10 + dig;
        }
        add(x);
    }

    for(int i = 0; i < 10000; ++i) {
        long long x = 0;
        long long p = 1;
        for(int d = 0; d < 18; ++d) {
            if (rng() % 10 == 0) x += (rng() % 9 + 1) * p;
            p *= 10;
        }
        add(x);
    }

    add(0);
    add(1);
    add(1000000000000000000LL - 1);

    sort(pool.begin(), pool.end());
    pool.erase(unique(pool.begin(), pool.end()), pool.end());
}

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

    long long input_val = inf.readLong();

    if (input_val == 1000000000000000000LL) {
        adaptive = true;
        generate_pool();
    } else {
        adaptive = false;
        fixed_secret = input_val;
    }

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF (no answer provided)");
        }

        if (token == "query" || token == "?") {
            long long a;
            if (!(cin >> a)) finish(_wa, "Invalid query parameter");

            if (a < 0 || a >= 1000000000000000000LL) {
                finish(_wa, "Query parameter out of range");
            }

            queries++;

            if (queries > QUERY_LIMIT) {
                finish(_wa, "Too many queries");
            }

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

            int response = 0;
            if (!adaptive) {
                response = get_digit_sum(fixed_secret + a);
            } else {

                static int freq[300];
                memset(freq, 0, sizeof(freq));

                for (long long cand : pool) {
                    freq[get_digit_sum(cand + a)]++;
                }

                int best_resp = -1;
                int max_count = -1;

                for (int v = 0; v < 300; ++v) {
                    if (freq[v] > max_count) {
                        max_count = freq[v];
                        best_resp = v;
                    }
                }

                if (best_resp == -1) {

                    finish(_wa, "Interactor error: inconsistent state");
                }

                response = best_resp;

                int write_idx = 0;
                for (long long cand : pool) {
                    if (get_digit_sum(cand + a) == response) {
                        pool[write_idx++] = cand;
                    }
                }
                pool.resize(write_idx);
            }

            cout << response << endl;

        } else if (token == "answer" || token == "!" || token == "ans") {
            long long y;
            if (!(cin >> y)) finish(_wa, "Invalid answer parameter");

            if (y < 0 || y >= 1000000000000000000LL) {
                finish(_wa, "Answer parameter out of range");
            }

            bool correct = false;
            if (!adaptive) {
                correct = (y == fixed_secret);
            } else {

                bool possible_alternative = false;
                for (long long cand : pool) {
                    if (cand != y) {
                        possible_alternative = true;
                        break;
                    }
                }

                if (possible_alternative) {
                    correct = false;
                } else {

                    correct = true;
                }
            }

            if (correct) {
                finish(_ok, "Correct");
            } else {
                finish(_wa, "Wrong answer");
            }

        } else {
            finish(_wa, "Invalid protocol: expected 'query' or 'answer'");
        }
    }

    return 0;
}

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

using namespace std;

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

    registerGen(argc, argv, 1);

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

    long long seed_val = 0;
    if (argc > 1) {
        try {
            seed_val = stoll(argv[1]);
        } catch (...) {
            seed_val = 0;
        }
    }

    if (mode == "adp") {

        println(1000000000000000000LL);
    } else {

        long long MAX_VAL = 1000000000000000000LL;
        long long x = 0;

        if (seed_val == 1) {
            x = 0;
        } else if (seed_val == 2) {
            x = MAX_VAL - 1;
        } else if (seed_val == 3) {
            x = 99999999999999999LL;
        } else {

            int strategy = rnd.next(4);

            if (strategy == 0) {

                x = rnd.next(0LL, MAX_VAL - 1);
            } else if (strategy == 1) {

                x = 0;
                for (int i = 0; i < 18; ++i) {
                    int d = rnd.next(0, 9);

                    if (rnd.next(4) == 0) d = 9;
                    x = x * 10 + d;
                }
            } else if (strategy == 2) {

                int num_nines = rnd.next(1, 17);
                long long suffix = 0;
                long long p = 1;
                for (int i = 0; i < num_nines; ++i) {
                    suffix += 9 * p;
                    p *= 10;
                }
                long long max_prefix = (MAX_VAL - 1 - suffix) / p;
                long long prefix = rnd.next(0LL, max_prefix);
                x = prefix * p + suffix;
            } else {

                x = 0;
                long long p = 1;
                for (int i = 0; i < 18; ++i) {
                    if (rnd.next(4) == 0) {
                        x += rnd.next(1, 9) * p;
                    }
                    p *= 10;
                }
            }
        }
        println(x);
    }

    return 0;
}


You are given a complete bipartite graph with $$$2n$$$ nodes, with $$$n$$$ nodes on each side of the bipartition. Nodes $$$1$$$ through $$$n$$$ are on one side of the bipartition, and nodes $$$n+1$$$ to $$$2n$$$ are on the other side. You are also given an $$$n \times n$$$ matrix $$$a$$$ describing the edge weights. $$$a\_{ij}$$$ denotes the weight of the edge between nodes $$$i$$$ and $$$j+n$$$. Each edge has a distinct weight.

Alice and Bob are playing a game on this graph. First Alice chooses to play as either "increasing" or "decreasing" for herself, and Bob gets the other choice. Then she places a token on any node of the graph. Bob then moves the token along any edge incident to that node. They now take turns playing the following game, with Alice going first.

The current player must move the token from the current vertex to some adjacent unvisited vertex. Let $$$w$$$ be the last weight of the last edge that was traversed. The edge that is traversed must be strictly greater than $$$w$$$ if the player is playing as "increasing", otherwise, it must be strictly less. The first player unable to make a move loses.

You are given $$$n$$$ and the edge weights of the graph. You can choose to play as either Alice or Bob, and you will play against the judge. You must win all the games for your answer to be judged correct.

Interaction

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

Each test starts with an integer $$$n$$$ ($$$1 \leq n \leq 50$$$) — the number of nodes on each side of the bipartition.

The next $$$n$$$ lines contain $$$n$$$ integers $$$a\_{ij}$$$ ($$$1 \leq a\_{ij} \leq n^2$$$). $$$a\_{ij}$$$ denotes the weight of the edge between node $$$i$$$ and node $$$j+n$$$. All $$$a\_{ij}$$$ will be distinct.

You first print a string "A" or "B", denoting which player you want to play ("A" for Alice and "B" for Bob).

If playing as Alice, first print either "I" or "D" (denoting whether you choose "increasing" or "decreasing"). Then, print the node that you wish to start at.

If playing as Bob, read in a character "I" or "D" (denoting whether the judge chose "increasing" or "decreasing"), then the node that the judge chooses to start at.

To make a move, print the index of the node that you wish to go to. To read what move the judge made, read an integer from standard in.

If the judge responds with $$$-1$$$, then that means the judge has determined it has no legal moves (or it may have just given up) and that you won the case. Stop processing this case immediately and start processing the next case.

If the judge responds with $$$-2$$$, that means that the judge has determined that you made an invalid move, so you should exit immediately to avoid getting other verdicts.

If you are unable to make a move or give up, print $$$-1$$$ and then exit immediately. This will give you a Wrong answer verdict.

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

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

Example

Input

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

Output

```
A
D 3
2
B
2
```

Note

The first example has two test cases. In the first test case, the graph looks like the following.

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

In the sample output, the player decides to play as Alice and chooses "decreasing" and starting at node $$$3$$$. The judge responds by moving to node $$$6$$$. After, the player moves to node $$$2$$$. At this point, the judge has no more moves (since the weight must "increase"), so it gives up and prints $$$-1$$$.

In the next case, we have two nodes connected by an edge of weight $$$1$$$. The player decides to play as Bob. No matter what the judge chooses, the player can move the token to the other node and the judge has no moves so will lose.

#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 string readTokenOrDie(const string& ctx) {
    string s;
    if (!(cin >> s)) finish(_pe, "Unexpected EOF while reading " + ctx);
    return s;
}

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

struct TestCase {
    int n = 0;
    vector<vector<int>> a;

    vector<int> max1, max2, argMax;
    vector<int> min1, min2, argMin;

    bool isLeft(int v) const { return 1 <= v && v <= n; }

    int w(int u, int v) const {
        if (isLeft(u) && !isLeft(v)) return a[u][v - n];
        if (!isLeft(u) && isLeft(v)) return a[v][u - n];
        return -1;
    }

    void precomputeExtremes() {
        int N = 2 * n;
        max1.assign(N + 1, INT_MIN);
        max2.assign(N + 1, INT_MIN);
        argMax.assign(N + 1, -1);

        min1.assign(N + 1, INT_MAX);
        min2.assign(N + 1, INT_MAX);
        argMin.assign(N + 1, -1);

        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                int left = i;
                int right = n + j;
                int wt = a[i][j];

                auto updMax = [&](int node, int other, int val) {
                    if (val > max1[node]) {
                        max2[node] = max1[node];
                        max1[node] = val;
                        argMax[node] = other;
                    } else if (val > max2[node]) {
                        max2[node] = val;
                    }
                };
                auto updMin = [&](int node, int other, int val) {
                    if (val < min1[node]) {
                        min2[node] = min1[node];
                        min1[node] = val;
                        argMin[node] = other;
                    } else if (val < min2[node]) {
                        min2[node] = val;
                    }
                };

                updMax(left, right, wt);
                updMax(right, left, wt);
                updMin(left, right, wt);
                updMin(right, left, wt);
            }
        }
    }

    int exclMax(int node, int excludeNeighbor) const {
        if (argMax[node] == excludeNeighbor) return max2[node];
        return max1[node];
    }

    int exclMin(int node, int excludeNeighbor) const {
        if (argMin[node] == excludeNeighbor) return min2[node];
        return min1[node];
    }

    vector<pair<int,int>> legalMoves(int cur, char type, int lastW, const vector<char>& vis) const {
        vector<pair<int,int>> res;
        if (!(type == 'I' || type == 'D')) return res;
        bool curLeft = isLeft(cur);
        if (curLeft) {
            for (int j = 1; j <= n; ++j) {
                int v = n + j;
                if (vis[v]) continue;
                int wt = a[cur][j];
                if ((type == 'I' && wt > lastW) || (type == 'D' && wt < lastW)) res.push_back({v, wt});
            }
        } else {
            int rightIdx = cur - n;
            for (int i = 1; i <= n; ++i) {
                int v = i;
                if (vis[v]) continue;
                int wt = a[i][rightIdx];
                if ((type == 'I' && wt > lastW) || (type == 'D' && wt < lastW)) res.push_back({v, wt});
            }
        }
        return res;
    }

    pair<char,int> chooseAliceOpeningHeuristic() const {

        int N = 2 * n;
        for (int s = 1; s <= N; ++s) {
            bool ok = true;
            if (isLeft(s)) {
                for (int j = 1; j <= n; ++j) {
                    int u = n + j;
                    int wt = a[s][j];
                    int mx = exclMax(u, s);
                    if (mx <= wt) { ok = false; break; }
                }
            } else {
                int sj = s - n;
                for (int i = 1; i <= n; ++i) {
                    int u = i;
                    int wt = a[i][sj];
                    int mx = exclMax(u, s);
                    if (mx <= wt) { ok = false; break; }
                }
            }
            if (ok) return {'I', s};
        }

        for (int s = 1; s <= N; ++s) {
            bool ok = true;
            if (isLeft(s)) {
                for (int j = 1; j <= n; ++j) {
                    int u = n + j;
                    int wt = a[s][j];
                    int mn = exclMin(u, s);
                    if (mn >= wt) { ok = false; break; }
                }
            } else {
                int sj = s - n;
                for (int i = 1; i <= n; ++i) {
                    int u = i;
                    int wt = a[i][sj];
                    int mn = exclMin(u, s);
                    if (mn >= wt) { ok = false; break; }
                }
            }
            if (ok) return {'D', s};
        }

        return {'I', 1};
    }

    int pickInitialBobMoveFromStart(int start, char aliceType) const {

        bool startLeft = isLeft(start);
        int bestV = -1;
        int bestW = (aliceType == 'I') ? INT_MIN : INT_MAX;

        if (startLeft) {
            for (int j = 1; j <= n; ++j) {
                int v = n + j;
                int wt = a[start][j];
                if (aliceType == 'I') {
                    if (wt > bestW) { bestW = wt; bestV = v; }
                } else {
                    if (wt < bestW) { bestW = wt; bestV = v; }
                }
            }
        } else {
            int sj = start - n;
            for (int i = 1; i <= n; ++i) {
                int v = i;
                int wt = a[i][sj];
                if (aliceType == 'I') {
                    if (wt > bestW) { bestW = wt; bestV = v; }
                } else {
                    if (wt < bestW) { bestW = wt; bestV = v; }
                }
            }
        }
        return bestV;
    }

    int pickGreedyMove(int cur, char myType, char oppType, int lastW, vector<char>& vis) const {
        auto moves = legalMoves(cur, myType, lastW, vis);
        if (moves.empty()) return -1;

        int bestV = -1, bestWt = 0;
        int bestOpp = INT_MAX;

        for (auto [v, wt] : moves) {
            vis[v] = 1;
            int oppCount = (int)legalMoves(v, oppType, wt, vis).size();
            vis[v] = 0;

            bool better = false;
            if (oppCount < bestOpp) {
                better = true;
            } else if (oppCount == bestOpp) {
                if (bestV == -1) {
                    better = true;
                } else {

                    if (oppType == 'I') {
                        if (wt > bestWt) better = true;
                        else if (wt == bestWt && v < bestV) better = true;
                    } else {
                        if (wt < bestWt) better = true;
                        else if (wt == bestWt && v < bestV) better = true;
                    }
                }
            }

            if (better) {
                bestOpp = oppCount;
                bestV = v;
                bestWt = wt;
            }
        }
        return bestV;
    }
};

static void sendInvalidAndDie(const string& msg) {
    cout << -2 << endl;
    finish(_wa, msg);
}

static void ensureQueryCap(long long hard_cap) {
    if (queries > hard_cap) finish(_pe, "Hard cap exceeded");
}

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

    int t = inf.readInt(1, 50);
    vector<TestCase> cases;
    cases.reserve(t);

    long long limitSum = 0;
    for (int tc = 0; tc < t; ++tc) {
        TestCase cs;
        cs.n = inf.readInt(1, 50);
        cs.a.assign(cs.n + 1, vector<int>(cs.n + 1, 0));
        for (int i = 1; i <= cs.n; ++i) {
            for (int j = 1; j <= cs.n; ++j) {
                cs.a[i][j] = inf.readInt(1, cs.n * cs.n);
            }
        }
        cs.precomputeExtremes();
        cases.push_back(std::move(cs));
        limitSum += (2LL * cases.back().n - 1);
    }

    query_limit = limitSum;
    log_metrics();

    cout << t << endl;

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

    for (int tc = 0; tc < t; ++tc) {
        const TestCase& cs = cases[tc];
        int n = cs.n;
        int N = 2 * n;

        cout << n << endl;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (j > 1) cout << ' ';
                cout << cs.a[i][j];
            }
            cout << endl;
        }

        string role = readTokenOrDie("role (A/B)");
        if (role != "A" && role != "B") sendInvalidAndDie("Invalid role token");

        vector<char> vis(N + 1, 0);
        int cur = -1;
        int lastW = 0;

        auto oppositeType = [&](char c) -> char {
            if (c == 'I') return 'D';
            if (c == 'D') return 'I';
            return '?';
        };

        if (role == "A") {
            string typeTok = readTokenOrDie("Alice type (I/D)");
            if (typeTok.size() != 1 || (typeTok[0] != 'I' && typeTok[0] != 'D')) sendInvalidAndDie("Invalid type token");
            char aliceType = typeTok[0];

            long long startLL;
            if (!parseIntStrict(readTokenOrDie("start node"), startLL)) sendInvalidAndDie("Invalid start node token");
            if (startLL < 1 || startLL > N) sendInvalidAndDie("Start node out of range");
            int start = (int)startLL;

            vis[start] = 1;

            char bobType = oppositeType(aliceType);
            int bobMove = cs.pickInitialBobMoveFromStart(start, aliceType);
            if (bobMove < 1 || bobMove > N || vis[bobMove] || (cs.isLeft(start) == cs.isLeft(bobMove)))
                finish(_fail, "Interactor internal error selecting initial Bob move");

            cout << bobMove << endl;
            vis[bobMove] = 1;
            lastW = cs.w(start, bobMove);
            cur = bobMove;

            while (true) {

                string mvTok = readTokenOrDie("contestant move");
                long long mvLL;
                if (!parseIntStrict(mvTok, mvLL)) sendInvalidAndDie("Non-integer move token");
                if (mvLL == -1) finish(_wa, "Contestant gave up / lost a game");
                if (mvLL < 1 || mvLL > N) sendInvalidAndDie("Move out of range");
                int v = (int)mvLL;

                if (vis[v]) sendInvalidAndDie("Move to visited vertex");
                if (cs.isLeft(cur) == cs.isLeft(v)) sendInvalidAndDie("Move not along bipartite edge");

                int wt = cs.w(cur, v);
                if (aliceType == 'I') {
                    if (!(wt > lastW)) sendInvalidAndDie("Increasing constraint violated");
                } else {
                    if (!(wt < lastW)) sendInvalidAndDie("Decreasing constraint violated");
                }

                ++queries;
                ensureQueryCap(hard_cap);

                vis[v] = 1;
                lastW = wt;
                cur = v;

                int reply = cs.pickGreedyMove(cur, bobType, aliceType, lastW, vis);
                if (reply == -1) {
                    cout << -1 << endl;
                    break;
                }

                int wt2 = cs.w(cur, reply);
                if (wt2 == -1 || vis[reply] || (cs.isLeft(cur) == cs.isLeft(reply)))
                    finish(_fail, "Interactor internal error selecting Bob move");
                if (bobType == 'I') {
                    if (!(wt2 > lastW)) finish(_fail, "Interactor violated increasing constraint");
                } else {
                    if (!(wt2 < lastW)) finish(_fail, "Interactor violated decreasing constraint");
                }

                cout << reply << endl;
                vis[reply] = 1;
                lastW = wt2;
                cur = reply;
            }
        } else {

            auto [aliceType, start] = cs.chooseAliceOpeningHeuristic();
            char bobType = oppositeType(aliceType);

            cout << aliceType << " " << start << endl;
            if (start < 1 || start > N) finish(_fail, "Interactor internal error selecting start node");
            vis[start] = 1;
            cur = start;

            {
                string mvTok = readTokenOrDie("contestant initial Bob move");
                long long mvLL;
                if (!parseIntStrict(mvTok, mvLL)) sendInvalidAndDie("Non-integer initial move token");
                if (mvLL == -1) finish(_wa, "Contestant gave up / lost a game");
                if (mvLL < 1 || mvLL > N) sendInvalidAndDie("Initial move out of range");
                int v = (int)mvLL;

                if (vis[v]) sendInvalidAndDie("Initial move to visited vertex");
                if (cs.isLeft(cur) == cs.isLeft(v)) sendInvalidAndDie("Initial move not along bipartite edge");

                ++queries;
                ensureQueryCap(hard_cap);

                lastW = cs.w(cur, v);
                vis[v] = 1;
                cur = v;
            }

            while (true) {

                int reply = cs.pickGreedyMove(cur, aliceType, bobType, lastW, vis);
                if (reply == -1) {
                    cout << -1 << endl;
                    break;
                }

                int wt2 = cs.w(cur, reply);
                if (wt2 == -1 || vis[reply] || (cs.isLeft(cur) == cs.isLeft(reply)))
                    finish(_fail, "Interactor internal error selecting Alice move");
                if (aliceType == 'I') {
                    if (!(wt2 > lastW)) finish(_fail, "Interactor violated increasing constraint");
                } else {
                    if (!(wt2 < lastW)) finish(_fail, "Interactor violated decreasing constraint");
                }

                cout << reply << endl;
                vis[reply] = 1;
                lastW = wt2;
                cur = reply;

                string mvTok = readTokenOrDie("contestant move");
                long long mvLL;
                if (!parseIntStrict(mvTok, mvLL)) sendInvalidAndDie("Non-integer move token");
                if (mvLL == -1) finish(_wa, "Contestant gave up / lost a game");
                if (mvLL < 1 || mvLL > N) sendInvalidAndDie("Move out of range");
                int v = (int)mvLL;

                if (vis[v]) sendInvalidAndDie("Move to visited vertex");
                if (cs.isLeft(cur) == cs.isLeft(v)) sendInvalidAndDie("Move not along bipartite edge");

                int wt = cs.w(cur, v);
                if (bobType == 'I') {
                    if (!(wt > lastW)) sendInvalidAndDie("Increasing constraint violated");
                } else {
                    if (!(wt < lastW)) sendInvalidAndDie("Decreasing constraint violated");
                }

                ++queries;
                ensureQueryCap(hard_cap);

                vis[v] = 1;
                lastW = wt;
                cur = v;
            }
        }
    }

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

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

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

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

    }
}

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

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

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

static long long readIntOrFail(const string& context) {
    string tok;
    if (!readToken(tok)) finish(_pe, "unexpected EOF while reading " + context);
    long long x;
    if (!parseIntStrict(tok, x)) finish(_pe, "non-integer token while reading " + context);
    return x;
}

struct CaseData {
    int n = 0;
    vector<vector<int>> a;
};

static inline bool isLeft(int v, int n) { return 1 <= v && v <= n; }
static inline bool isRight(int v, int n) { return n + 1 <= v && v <= 2 * n; }
static inline int rightIndex(int v, int n) { return v - n; }

static int edgeWeight(int u, int v, int n, const vector<vector<int>>& a) {
    if (isLeft(u, n) && isRight(v, n)) return a[u][rightIndex(v, n)];
    if (isRight(u, n) && isLeft(v, n)) return a[v][rightIndex(u, n)];
    return -1;
}

static bool cmpOk(char mode, int w, int lastW) {
    if (mode == 'I') return w > lastW;
    return w < lastW;
}

struct Vis {
    vector<char> L, R;
    explicit Vis(int n = 0) : L(n + 1, 0), R(n + 1, 0) {}
    bool seen(int v, int n) const {
        if (isLeft(v, n)) return L[v];
        if (isRight(v, n)) return R[rightIndex(v, n)];
        return true;
    }
    void mark(int v, int n, bool val) {
        if (isLeft(v, n)) L[v] = (char)val;
        else if (isRight(v, n)) R[rightIndex(v, n)] = (char)val;
    }
};

static int countLegal(int cur, int lastW, char mode, int n, const vector<vector<int>>& a, const Vis& vis) {
    int cnt = 0;
    if (isLeft(cur, n)) {
        int i = cur;
        for (int j = 1; j <= n; ++j) {
            if (vis.R[j]) continue;
            int w = a[i][j];
            if (cmpOk(mode, w, lastW)) ++cnt;
        }
    } else {
        int j = rightIndex(cur, n);
        for (int i = 1; i <= n; ++i) {
            if (vis.L[i]) continue;
            int w = a[i][j];
            if (cmpOk(mode, w, lastW)) ++cnt;
        }
    }
    return cnt;
}

static vector<int> listLegal(int cur, int lastW, char mode, int n, const vector<vector<int>>& a, const Vis& vis) {
    vector<int> moves;
    if (isLeft(cur, n)) {
        int i = cur;
        for (int j = 1; j <= n; ++j) {
            if (vis.R[j]) continue;
            int w = a[i][j];
            if (cmpOk(mode, w, lastW)) moves.push_back(n + j);
        }
    } else {
        int j = rightIndex(cur, n);
        for (int i = 1; i <= n; ++i) {
            if (vis.L[i]) continue;
            int w = a[i][j];
            if (cmpOk(mode, w, lastW)) moves.push_back(i);
        }
    }
    return moves;
}

static int chooseBestConstrainedMove(int cur, int lastW, char judgeMode, char oppMode,
                                    int n, const vector<vector<int>>& a, Vis& vis) {
    vector<int> legal = listLegal(cur, lastW, judgeMode, n, a, vis);
    if (legal.empty()) return -1;

    int bestV = -1;
    int bestOpp = INT_MAX;

    for (int v : legal) {
        int w = edgeWeight(cur, v, n, a);
        vis.mark(v, n, true);
        int oppCnt = countLegal(v, w, oppMode, n, a, vis);
        vis.mark(v, n, false);

        if (oppCnt < bestOpp || (oppCnt == bestOpp && v < bestV)) {
            bestOpp = oppCnt;
            bestV = v;
        }
    }
    return bestV;
}

static int chooseBestUnconstrainedMove(int cur, char oppMode, int n, const vector<vector<int>>& a, Vis& vis) {
    vector<int> candidates;
    if (isLeft(cur, n)) {
        for (int j = 1; j <= n; ++j) if (!vis.R[j]) candidates.push_back(n + j);
    } else {
        for (int i = 1; i <= n; ++i) if (!vis.L[i]) candidates.push_back(i);
    }
    if (candidates.empty()) return -1;

    int bestV = -1;
    int bestOpp = INT_MAX;

    for (int v : candidates) {
        int w = edgeWeight(cur, v, n, a);
        vis.mark(v, n, true);
        int oppCnt = countLegal(v, w, oppMode, n, a, vis);
        vis.mark(v, n, false);

        if (oppCnt < bestOpp || (oppCnt == bestOpp && v < bestV)) {
            bestOpp = oppCnt;
            bestV = v;
        }
    }
    return bestV;
}

static pair<char,int> chooseAliceModeAndStart(int n, const vector<vector<int>>& a) {
    const long long NEG_INF = -(1LL<<60);

    auto evalAfterBobMove = [&](char aliceMode, int start, int bobMove) -> long long {
        char bobMode = (aliceMode == 'I') ? 'D' : 'I';
        Vis vis(n);
        vis.mark(start, n, true);
        vis.mark(bobMove, n, true);
        int cur = bobMove;
        int lastW = edgeWeight(start, bobMove, n, a);

        int best = chooseBestConstrainedMove(cur, lastW, aliceMode, bobMode, n, a, vis);
        if (best == -1) return NEG_INF;

        int w = edgeWeight(cur, best, n, a);
        vis.mark(best, n, true);
        int oppCnt = countLegal(best, w, bobMode, n, a, vis);
        vis.mark(best, n, false);

        return - (long long)oppCnt;
    };

    long long bestValue = NEG_INF;
    char bestMode = 'D';
    int bestStart = 1;

    for (char aliceMode : {'D', 'I'}) {
        for (int start = 1; start <= 2 * n; ++start) {

            vector<int> bobMoves;
            if (isLeft(start, n)) {
                bobMoves.reserve(n);
                for (int j = 1; j <= n; ++j) bobMoves.push_back(n + j);
            } else {
                bobMoves.reserve(n);
                for (int i = 1; i <= n; ++i) bobMoves.push_back(i);
            }

            long long worstForUs = (1LL<<60);
            for (int bm : bobMoves) {
                long long v = evalAfterBobMove(aliceMode, start, bm);
                worstForUs = min(worstForUs, v);
            }

            if (worstForUs > bestValue ||
                (worstForUs == bestValue && aliceMode < bestMode) ||
                (worstForUs == bestValue && aliceMode == bestMode && start < bestStart)) {
                bestValue = worstForUs;
                bestMode = aliceMode;
                bestStart = start;
            }
        }
    }
    return {bestMode, bestStart};
}

int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

    int t = inf.readInt();
    if (t < 1 || t > 50) finish(_pe, "invalid t in input");

    vector<CaseData> cases;
    cases.reserve(t);

    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt();
        if (n < 1 || n > 50) finish(_pe, "invalid n in input");
        CaseData cd;
        cd.n = n;
        cd.a.assign(n + 1, vector<int>(n + 1, 0));
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                int w = inf.readInt();
                cd.a[i][j] = w;
            }
        }
        cases.push_back(std::move(cd));
    }

    query_limit = 0;
    for (auto& cd : cases) query_limit += cd.n;
    long long hard_cap = max(200000LL, 10LL * max(1LL, query_limit));

    cout << t << "\n";
    for (int tc = 0; tc < t; ++tc) {
        int n = cases[tc].n;
        cout << n << "\n";
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (j > 1) cout << ' ';
                cout << cases[tc].a[i][j];
            }
            cout << "\n";
        }
    }
    cout.flush();

    log_metrics();

    for (int tc = 0; tc < t; ++tc) {
        int n = cases[tc].n;
        const auto& a = cases[tc].a;

        string roleTok;
        if (!readToken(roleTok)) finish(_pe, "unexpected EOF before choosing A/B");
        if (roleTok != "A" && roleTok != "B") finish(_wa, "invalid role token (expected A/B)");

        Vis vis(n);
        int cur = -1;
        int lastW = 0;
        bool lastWDefined = false;

        char aliceMode = '?';
        char bobMode = '?';

        bool contestantIsAlice = (roleTok == "A");
        bool contestantTurn = false;

        auto sendInt = [&](long long x) {
            cout << x << "\n";
            cout.flush();
        };

        auto invalidMove = [&](const string& why) {
            sendInt(-2);
            finish(_wa, why);
        };

        auto readMoveInt = [&](const string& ctx) -> long long {
            long long x = readIntOrFail(ctx);
            if (x == -2) finish(_pe, "participant printed -2 (reserved)");
            return x;
        };

        auto requireVertex = [&](long long x, const string& ctx) -> int {
            if (x < 1 || x > 2LL * n) invalidMove("vertex out of range in " + ctx);
            return (int)x;
        };

        auto checkOppositeSide = [&](int u, int v, const string& ctx) {
            bool ok = (isLeft(u, n) && isRight(v, n)) || (isRight(u, n) && isLeft(v, n));
            if (!ok) invalidMove("non-adjacent (same side) move in " + ctx);
        };

        auto checkUnvisited = [&](int v, const string& ctx) {
            if (vis.seen(v, n)) invalidMove("revisited vertex in " + ctx);
        };

        auto checkConstraint = [&](int u, int v, char mode, const string& ctx) {
            if (!lastWDefined) invalidMove("constraint checked without lastW in " + ctx);
            int w = edgeWeight(u, v, n, a);
            if (w < 0) invalidMove("invalid edge in " + ctx);
            if (!cmpOk(mode, w, lastW)) invalidMove("weight constraint violated in " + ctx);
        };

        auto applyMove = [&](int u, int v) {
            int w = edgeWeight(u, v, n, a);
            vis.mark(v, n, true);
            cur = v;
            lastW = w;
            lastWDefined = true;
        };

        if (contestantIsAlice) {

            string modeTok;
            if (!readToken(modeTok)) finish(_pe, "unexpected EOF while reading Alice mode");
            if (modeTok != "I" && modeTok != "D") finish(_wa, "invalid mode token (expected I/D)");
            aliceMode = modeTok[0];
            bobMode = (aliceMode == 'I') ? 'D' : 'I';

            long long s = readIntOrFail("starting node");
            int start = requireVertex(s, "starting node");
            vis.mark(start, n, true);
            cur = start;

            int judgeFirst = chooseBestUnconstrainedMove(cur, aliceMode, n, a, vis);
            if (judgeFirst == -1) {

                sendInt(-1);
                continue;
            }
            sendInt(judgeFirst);
            applyMove(cur, judgeFirst);

            contestantTurn = true;
        } else {

            auto [jMode, jStart] = chooseAliceModeAndStart(n, a);
            aliceMode = jMode;
            bobMode = (aliceMode == 'I') ? 'D' : 'I';

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

            vis.mark(jStart, n, true);
            cur = jStart;

            long long mv0 = readMoveInt("Bob initial move");
            if (mv0 == -1) finish(_wa, "participant gave up on initial move");
            int v0 = requireVertex(mv0, "Bob initial move");
            checkUnvisited(v0, "Bob initial move");
            checkOppositeSide(cur, v0, "Bob initial move");
            queries++;
            if (queries > hard_cap) finish(_pe, "too many moves (hard cap exceeded)");

            applyMove(cur, v0);

            contestantTurn = false;
        }

        while (true) {
            if (contestantTurn) {
                long long mv = readMoveInt("move");
                if (mv == -1) finish(_wa, "participant gave up");
                int v = requireVertex(mv, "move");
                checkUnvisited(v, "move");
                checkOppositeSide(cur, v, "move");
                char mode = contestantIsAlice ? aliceMode : bobMode;
                checkConstraint(cur, v, mode, "move");

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

                applyMove(cur, v);
                contestantTurn = false;
            } else {

                char judgeMode = contestantIsAlice ? bobMode : aliceMode;
                char oppMode = contestantIsAlice ? aliceMode : bobMode;

                int judgeMove = chooseBestConstrainedMove(cur, lastW, judgeMode, oppMode, n, a, vis);
                if (judgeMove == -1) {
                    sendInt(-1);
                    break;
                }
                sendInt(judgeMove);
                applyMove(cur, judgeMove);
                contestantTurn = true;
            }
        }
    }

    finish(_ok, "ok");
}

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

static void shuffleVec(vector<int>& 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> randomPermutation(int n) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    shuffleVec(p);
    return p;
}

static vector<vector<int>> genSnake(int n) {
    vector<vector<int>> a(n, vector<int>(n, 0));
    int cur = 1;
    for (int i = 0; i < n; ++i) {
        if (i % 2 == 0) {
            for (int j = 0; j < n; ++j) a[i][j] = cur++;
        } else {
            for (int j = n - 1; j >= 0; --j) a[i][j] = cur++;
        }
    }
    return a;
}

static vector<vector<int>> genRandomPermMatrix(int n) {
    int m = n * n;
    vector<int> w(m);
    iota(w.begin(), w.end(), 1);
    shuffleVec(w);

    vector<vector<int>> a(n, vector<int>(n, 0));
    int k = 0;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            a[i][j] = w[k++];
    return a;
}

static vector<vector<int>> genCheckerboardLowHigh(int n) {
    int m = n * n;
    vector<int> pos0, pos1;
    pos0.reserve((m + 1) / 2);
    pos1.reserve(m / 2);

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int idx = i * n + j;
            if (((i + j) & 1) == 0) pos0.push_back(idx);
            else pos1.push_back(idx);
        }
    }

    shuffleVec(pos0);
    shuffleVec(pos1);

    vector<int> flat(m, 0);
    int cur = 1;
    for (int idx : pos0) flat[idx] = cur++;
    for (int idx : pos1) flat[idx] = cur++;

    vector<vector<int>> a(n, vector<int>(n, 0));
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            a[i][j] = flat[i * n + j];
    return a;
}

static vector<vector<int>> genPermutedSnake(int n) {
    vector<vector<int>> base = genSnake(n);
    vector<int> rp = randomPermutation(n);
    vector<int> cp = randomPermutation(n);

    vector<vector<int>> a(n, vector<int>(n, 0));
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            a[i][j] = base[rp[i]][cp[j]];
    return a;
}

static long long gcdll(long long a, long long b) {
    while (b) {
        long long t = a % b;
        a = b;
        b = t;
    }
    return a;
}

static vector<vector<int>> genAffinePermutationMatrix(int n) {
    long long m = 1LL * n * n;
    long long mul = 1;
    long long add = rnd.next(0LL, m - 1);

    for (int attempts = 0; attempts < 100000; ++attempts) {
        long long cand = rnd.next(1LL, m - 1);
        if (gcdll(cand, m) == 1) {
            mul = cand;
            break;
        }
    }

    vector<vector<int>> a(n, vector<int>(n, 0));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            long long idx = 1LL * i * n + j;
            long long w = (idx * mul + add) % m + 1;
            a[i][j] = (int)w;
        }
    }
    return a;
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 50);
    long long seedVal = 0;
    if (argc > 1) {
        try {
            seedVal = stoll(string(argv[1]));
        } catch (...) {
            seedVal = 0;
        }
    }

    int n = nOpt;
    if (n < 1) n = 1;
    if (n > 50) n = 50;

    vector<vector<int>> a;

    if (seedVal == 1) {
        n = 1;
        a.assign(1, vector<int>(1, 1));
    } else if (seedVal == 2) {
        n = 2;
        a = {
            {1, 4},
            {3, 2}
        };
    } else if (seedVal == 3) {
        n = 50;
        a = genSnake(n);
    } else {
        if (n < 45) n = 45;
        int type = rnd.next(0, 3);
        if (type == 0) a = genRandomPermMatrix(n);
        else if (type == 1) a = genCheckerboardLowHigh(n);
        else if (type == 2) a = genPermutedSnake(n);
        else a = genAffinePermutationMatrix(n);
    }

    (void)mode;
    if (mode != "non" && mode != "adp") mode = "non";

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