This is an interactive problem.

Alice has a tree $T$ consisting of $n$ nodes, numbered from $1$ to $n$. Alice will show $T$ to Bob. After observing $T$, Bob needs to tell Alice two permutations $p_1$ and $p_2$ of $[1, 2, \ldots, n]$.

Then, Alice will play $q$ rounds of the following game.

* Alice will create an array $a$ that is a permutation of $[0,1,\ldots,n-1]$. The value of node $v$ will be $a_v$.
* Alice will choose two nodes $u$ and $v$ ($1 \leq u, v \leq n$, $u \neq v$) of $T$ and tell them to Bob. Bob will need to find the $\operatorname{MEX}^\dagger$ of the values on the unique simple path between nodes $u$ and $v$.
* To find this value, Bob can ask Alice at most $5$ queries. In each query, Bob should give three integers $t$, $l$ and $r$ to Alice such that $t$ is either $1$ or $2$, and $1 \leq l \leq r \leq n$. Alice will then tell Bob the value equal to\min\_{i=l}^{r} a[p\_{t,i}].

Note that all rounds are independent of each other. In particular, the values of $a$, $u$ and $v$ can be different in different rounds.

Bob is puzzled as he only knows the HLD solution, which requires $O(\log(n))$ queries per round. So he needs your help to win the game.

$^\dagger$ The $\operatorname{MEX}$ (minimum excludant) of a collection of integers $c_1, c_2, \ldots, c_k$ is defined as the smallest non-negative integer $x$ which does not occur in the collection $c$.

Interaction

Each test contains multiple test cases. The first line contains a single integer $t$ ($1 \leq t \leq 10^4$) — the number of test cases. Read it. The description of the test cases follows.

The first line of each test case contains two positive integers $n$ and $q$ ($2 \leq n \leq 10^5$, $1 \leq q \leq 10^4$) — the number of nodes in $T$ and the number of rounds respectively.

The following next $n-1$ lines contains two integers $u$ and $v$ ($1 \leq u, v \leq n$, $u \neq v$) — denoting an edge between nodes $u$ and $v$. It is guaranteed that the given edges form a tree.

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

It is also guaranteed that the sum of $n \cdot q$ does not exceed $3 \cdot 10^6$.

The interaction for each test case begins by outputting two permutations $p_1$ and $p_2$ of $[1, 2, \ldots, n]$.

On a new line, output $n$ space-separated distinct integers denoting $p_1$.

In the next line, output $n$ space-separated distinct integers denoting $p_2$.

Alice will start playing the game.

For each round, you must read two integers, $u$ and $v$ ($1 \leq u, v \leq n$, $u \neq v$). You need to find the $\operatorname{MEX}$ of the values on the unique simple path between nodes $u$ and $v$.

To make a query, output "? $t$ $l$ $r$" without quotes, such that $t$ is either $1$ or $2$, and $1 \leq l \leq r \leq n$. Afterwards, you should read a single integer — the answer to your query $\min_{i=l}^{r} a_{p_{t,i}}$. You can make at most $5$ such queries in each round.

If you want to print the answer, output "! $x$" ($1 \leq x, y \leq n$) without quotes. After doing that, read a single integer, which is normally equal to $1$.

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

After printing a query or the answer, 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 documentation for other languages.

Example

Input

```
1
3 1
1 2
2 3

2 3

1

0

1
```

Output

```
1 2 3
2 1 3

? 1 2 3

? 2 1 3

! 0
```

Note

In the first test, the interaction proceeds as follows.

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | 1 | There are 1 test cases. |
|  | 3 1 | The tree $T$ consists of $3$ nodes, and Alice will play for only one round. |
|  | 1 2 | First edge of $T$ |
|  | 2 3 | Second edge of $T$ |
| 1 2 3 |  | The permutation $p_1$ |
| 2 1 3 |  | The permutation $p_2$ |
|  |  | Alice shuffles $a$ to $a=[0,2,1]$ before giving the nodes for the only round. |
|  | 2 3 | Nodes for the round |
| ? 1 2 3 | 1 | $\min(a_{p_{1,2}},a_{p_{1,3}})=\min(a_2,a_3)=1$ |
| ? 2 1 3 | 0 | $\min(a_{p_{2,1}},a_{p_{2,2}},a_{p_{2,3}})=\min(a_2,a_1,a_3)=0$ |
| ! 0 | 1 | Considering the output of queries, it is clear that $\operatorname{MEX}$ is $0$. Since the output is correct, the jury responds with $1$. |

After each test case, make sure to read $1$ or $-1$.

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

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

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

    }
}

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

struct SegTreeMin {
    int n = 0;
    int base = 1;
    vector<int> seg;

    void init(int n_) {
        n = n_;
        base = 1;
        while (base < n) base <<= 1;
        seg.assign(2 * base, INT_MAX);
    }

    void buildFrom1Indexed(const vector<int>& arr) {
        for (int i = 0; i < base; ++i) seg[base + i] = INT_MAX;
        for (int i = 1; i <= n; ++i) seg[base + (i - 1)] = arr[i];
        for (int i = base - 1; i >= 1; --i) seg[i] = min(seg[i << 1], seg[i << 1 | 1]);
    }

    int query(int l, int r) const {
        int L = base + (l - 1);
        int R = base + (r - 1);
        int res = INT_MAX;
        while (L <= R) {
            if (L & 1) res = min(res, seg[L++]);
            if (!(R & 1)) res = min(res, seg[R--]);
            L >>= 1;
            R >>= 1;
        }
        return res;
    }
};

struct TestCaseData {
    int n = 0, q = 0;
    vector<pair<int,int>> edges;
    struct Round {
        int u = 0, v = 0;
        vector<int> a;
    };
    vector<Round> rounds;
};

struct LCA {
    int n = 0, LOG = 0;
    vector<int> depth;
    vector<vector<int>> up;
    vector<vector<int>> g;

    void init(int n_, const vector<pair<int,int>>& edges) {
        n = n_;
        g.assign(n + 1, {});
        g.reserve(n + 1);
        for (auto [u, v] : edges) {
            g[u].push_back(v);
            g[v].push_back(u);
        }

        LOG = 1;
        while ((1 << LOG) <= n) ++LOG;
        up.assign(LOG, vector<int>(n + 1, 0));
        depth.assign(n + 1, 0);

        vector<int> parent(n + 1, 0);
        queue<int> qq;
        parent[1] = 0;
        depth[1] = 0;
        qq.push(1);

        vector<char> vis(n + 1, 0);
        vis[1] = 1;

        while (!qq.empty()) {
            int v = qq.front();
            qq.pop();
            up[0][v] = parent[v];
            for (int to : g[v]) {
                if (vis[to]) continue;
                vis[to] = 1;
                parent[to] = v;
                depth[to] = depth[v] + 1;
                qq.push(to);
            }
        }

        for (int k = 1; k < LOG; ++k) {
            for (int v = 1; v <= n; ++v) {
                int mid = up[k - 1][v];
                up[k][v] = (mid == 0 ? 0 : up[k - 1][mid]);
            }
        }
    }

    int lca(int a, int b) const {
        if (depth[a] < depth[b]) swap(a, b);
        int diff = depth[a] - depth[b];
        for (int k = 0; k < LOG; ++k) if (diff & (1 << k)) a = up[k][a];
        if (a == b) return a;
        for (int k = LOG - 1; k >= 0; --k) {
            if (up[k][a] != up[k][b]) {
                a = up[k][a];
                b = up[k][b];
            }
        }
        return up[0][a];
    }
};

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

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

static void sendMinusOneAndFinish(TResult verdict, const string& msg) {
    cout << -1 << "\n";
    cout.flush();
    finish(verdict, msg);
}

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

    vector<TestCaseData> tests;
    int T = 0;

    try {
        T = inf.readInt(1, 10000, "t");
        tests.resize(T);
        long long totalRounds = 0;

        for (int tc = 0; tc < T; ++tc) {
            int n = inf.readInt(2, 100000, "n");
            int q = inf.readInt(1, 10000, "q");
            tests[tc].n = n;
            tests[tc].q = q;
            tests[tc].edges.reserve(n - 1);
            for (int i = 0; i < n - 1; ++i) {
                int u = inf.readInt(1, n, "u");
                int v = inf.readInt(1, n, "v");
                tests[tc].edges.push_back({u, v});
            }
            tests[tc].rounds.resize(q);
            for (int i = 0; i < q; ++i) {
                int u = inf.readInt(1, n, "u_round");
                int v = inf.readInt(1, n, "v_round");
                tests[tc].rounds[i].u = u;
                tests[tc].rounds[i].v = v;
                tests[tc].rounds[i].a.assign(n + 1, 0);
                for (int node = 1; node <= n; ++node) {
                    tests[tc].rounds[i].a[node] = inf.readInt(0, n - 1, "a");
                }
            }
            totalRounds += q;
        }

        query_limit = 5LL * totalRounds;
    } catch (...) {
        query_limit = 0;
        log_metrics();
        finish(_pe, "Failed to read hidden input");
    }

    log_metrics();

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

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

    for (int tc = 0; tc < T; ++tc) {
        const int n = tests[tc].n;
        const int q = tests[tc].q;

        cout << n << " " << q << "\n";
        for (auto [u, v] : tests[tc].edges) {
            cout << u << " " << v << "\n";
        }
        cout.flush();

        vector<int> p1(n + 1, 0), p2(n + 1, 0);
        {
            vector<char> used(n + 1, 0);
            for (int i = 1; i <= n; ++i) {
                long long x;
                if (!readIntSafe(x)) sendMinusOneAndFinish(_pe, "EOF while reading p1");
                if (x < 1 || x > n) sendMinusOneAndFinish(_pe, "p1 value out of range");
                if (used[(int)x]) sendMinusOneAndFinish(_pe, "p1 is not a permutation");
                used[(int)x] = 1;
                p1[i] = (int)x;
            }
        }
        {
            vector<char> used(n + 1, 0);
            for (int i = 1; i <= n; ++i) {
                long long x;
                if (!readIntSafe(x)) sendMinusOneAndFinish(_pe, "EOF while reading p2");
                if (x < 1 || x > n) sendMinusOneAndFinish(_pe, "p2 value out of range");
                if (used[(int)x]) sendMinusOneAndFinish(_pe, "p2 is not a permutation");
                used[(int)x] = 1;
                p2[i] = (int)x;
            }
        }

        LCA lca;
        lca.init(n, tests[tc].edges);
        const vector<int>& parent = lca.up[0];

        vector<int> b1(n + 1, 0), b2(n + 1, 0);
        SegTreeMin st1, st2;
        st1.init(n);
        st2.init(n);

        vector<int> seen(n + 1, 0);
        int seenStamp = 0;

        for (int round = 0; round < q; ++round) {
            const int u = tests[tc].rounds[round].u;
            const int v = tests[tc].rounds[round].v;
            const vector<int>& a = tests[tc].rounds[round].a;

            for (int i = 1; i <= n; ++i) {
                b1[i] = a[p1[i]];
                b2[i] = a[p2[i]];
            }
            st1.buildFrom1Indexed(b1);
            st2.buildFrom1Indexed(b2);

            int w = lca.lca(u, v);
            ++seenStamp;
            int x = u;
            while (x != w) {
                int val = a[x];
                if (0 <= val && val <= n) seen[val] = seenStamp;
                x = parent[x];
            }
            {
                int val = a[w];
                if (0 <= val && val <= n) seen[val] = seenStamp;
            }
            x = v;
            while (x != w) {
                int val = a[x];
                if (0 <= val && val <= n) seen[val] = seenStamp;
                x = parent[x];
            }
            int mex = 0;
            while (mex <= n && seen[mex] == seenStamp) ++mex;

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

            while (true) {
                string op;
                if (!readStringSafe(op)) sendMinusOneAndFinish(_pe, "EOF while waiting for command");
                if (op == "?") {
                    long long tt, l, r;
                    if (!readIntSafe(tt) || !readIntSafe(l) || !readIntSafe(r))
                        sendMinusOneAndFinish(_pe, "Malformed query");
                    if (!(tt == 1 || tt == 2) || l < 1 || r < 1 || l > r || r > n)
                        sendMinusOneAndFinish(_pe, "Invalid query parameters");

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

                    int ans = (tt == 1) ? st1.query((int)l, (int)r) : st2.query((int)l, (int)r);
                    cout << ans << "\n";
                    cout.flush();
                } else if (op == "!") {
                    long long xans;
                    if (!readIntSafe(xans)) sendMinusOneAndFinish(_pe, "EOF while reading answer");
                    if (xans < 0 || xans > n) sendMinusOneAndFinish(_pe, "Answer out of range");
                    if ((int)xans != mex) {
                        cout << -1 << "\n";
                        cout.flush();
                        finish(_wa, "Wrong mex");
                    }
                    cout << 1 << "\n";
                    cout.flush();
                    break;
                } else {
                    sendMinusOneAndFinish(_pe, "Unexpected command token");
                }
            }
        }
    }

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

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

static bool readLLFromCin(long long& x) {
    string tok;
    if (!readToken(tok)) return false;
    return parseLL(tok, x);
}

struct LCA {
    int n = 0;
    int LOG = 0;
    vector<vector<int>> g;
    vector<int> depth;
    vector<vector<int>> up;

    void init(int n_, const vector<pair<int,int>>& edges) {
        n = n_;
        g.assign(n + 1, {});
        for (auto [u, v] : edges) {
            if (u < 1 || u > n || v < 1 || v > n) continue;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        LOG = 1;
        while ((1 << LOG) <= n) ++LOG;
        up.assign(LOG, vector<int>(n + 1, 0));
        depth.assign(n + 1, 0);

        vector<int> parent(n + 1, 0);
        queue<int> q;
        q.push(1);
        parent[1] = 0;
        depth[1] = 0;

        vector<char> vis(n + 1, 0);
        vis[1] = 1;

        while (!q.empty()) {
            int v = q.front(); q.pop();
            up[0][v] = parent[v];
            for (int to : g[v]) {
                if (vis[to]) continue;
                vis[to] = 1;
                parent[to] = v;
                depth[to] = depth[v] + 1;
                q.push(to);
            }
        }

        for (int k = 1; k < LOG; ++k) {
            for (int v = 1; v <= n; ++v) {
                int mid = up[k - 1][v];
                up[k][v] = (mid == 0 ? 0 : up[k - 1][mid]);
            }
        }
    }

    int lca(int a, int b) const {
        if (a < 1 || a > n || b < 1 || b > n) return 1;
        if (depth[a] < depth[b]) swap(a, b);
        int diff = depth[a] - depth[b];
        for (int k = 0; k < LOG; ++k) {
            if (diff & (1 << k)) a = up[k][a];
        }
        if (a == b) return a;
        for (int k = LOG - 1; k >= 0; --k) {
            if (up[k][a] != up[k][b]) {
                a = up[k][a];
                b = up[k][b];
            }
        }
        return up[0][a];
    }

    vector<int> getPath(int u, int v) const {
        int w = lca(u, v);
        vector<int> A, B;
        int x = u;
        while (x != w && x != 0) {
            A.push_back(x);
            x = up[0][x];
        }
        A.push_back(w);
        x = v;
        while (x != w && x != 0) {
            B.push_back(x);
            x = up[0][x];
        }
        reverse(B.begin(), B.end());
        A.insert(A.end(), B.begin(), B.end());
        return A;
    }
};

struct TestCaseData {
    int n = 0, q = 0;
    vector<pair<int,int>> edges;
    vector<pair<int,int>> rounds;
    bool hasExplicitA = false;
    vector<vector<int>> aRounds;
};

struct RoundOracle {
    int n = 0;
    bool hasA = false;
    const vector<int>* a = nullptr;
    long long mul = 1;
    long long add = 0;

    int val(int node) const {
        if (hasA) return (*a)[node];
        long long x = node - 1;
        long long res = (mul * x + add) % n;
        return (int)res;
    }
};

static bool isPerm1toN(const vector<int>& p, int n) {
    if ((int)p.size() != n + 1) return false;
    vector<char> seen(n + 1, 0);
    for (int i = 1; i <= n; ++i) {
        int x = p[i];
        if (x < 1 || x > n) return false;
        if (seen[x]) return false;
        seen[x] = 1;
    }
    return true;
}

static bool isPerm0toNminus1(const vector<int>& a, int n) {
    if ((int)a.size() != n + 1) return false;
    vector<char> seen(n, 0);
    for (int i = 1; i <= n; ++i) {
        int x = a[i];
        if (x < 0 || x >= n) return false;
        if (seen[x]) return false;
        seen[x] = 1;
    }
    return true;
}

static long long pickCoprimeMultiplier(int n, long long seed) {
    if (n == 1) return 0;
    long long a = (seed % n + n) % n;
    if (a == 0) a = 1;
    for (int it = 0; it < n + 5; ++it) {
        if (a != 0 && std::gcd((long long)n, a) == 1) return a;
        a++;
        if (a == n) a = 1;
    }
    return 1;
}

static int mexOnPath(const LCA& lca, int u, int v, const RoundOracle& oracle) {
    vector<int> path = lca.getPath(u, v);
    int m = (int)path.size();
    vector<char> seen(m + 1, 0);
    for (int node : path) {
        int x = oracle.val(node);
        if (0 <= x && x <= m) seen[x] = 1;
    }
    for (int x = 0; x <= m; ++x) if (!seen[x]) return x;
    return m;
}

static int minOnSegment(const vector<int>& p, int l, int r, const RoundOracle& oracle) {
    int mn = INT_MAX;
    for (int i = l; i <= r; ++i) {
        int node = p[i];
        mn = min(mn, oracle.val(node));
    }
    return mn;
}

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

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

    vector<TestCaseData> tests;
    tests.reserve(t);

    long long totalQ = 0;

    for (int tc = 0; tc < t; ++tc) {
        TestCaseData data;
        data.n = inf.readInt();
        data.q = inf.readInt();
        if (data.n < 2 || data.n > 100000) finish(_pe, "invalid n in input");
        if (data.q < 1 || data.q > 10000) finish(_pe, "invalid q in input");
        totalQ += data.q;

        data.edges.reserve(data.n - 1);
        for (int i = 0; i < data.n - 1; ++i) {
            int u = inf.readInt();
            int v = inf.readInt();
            data.edges.push_back({u, v});
        }

        if (t == 1) {
            vector<long long> rest;
            while (!inf.seekEof()) {
                rest.push_back(inf.readInt());
            }

            if ((long long)rest.size() == 2LL * data.q) {
                data.rounds.reserve(data.q);
                for (int i = 0; i < data.q; ++i) {
                    int u = (int)rest[2LL * i + 0];
                    int v = (int)rest[2LL * i + 1];
                    data.rounds.push_back({u, v});
                }
                data.hasExplicitA = false;
            } else if ((long long)rest.size() == 1LL * data.q * (2 + data.n)) {
                data.rounds.reserve(data.q);
                data.aRounds.assign(data.q, vector<int>(data.n + 1, 0));
                long long idx = 0;
                for (int i = 0; i < data.q; ++i) {
                    int u = (int)rest[idx++];
                    int v = (int)rest[idx++];
                    data.rounds.push_back({u, v});
                    for (int node = 1; node <= data.n; ++node) {
                        data.aRounds[i][node] = (int)rest[idx++];
                    }
                }
                data.hasExplicitA = true;
            } else if ((long long)rest.size() >= 2LL * data.q) {
                data.rounds.reserve(data.q);
                for (int i = 0; i < data.q; ++i) {
                    int u = (int)rest[2LL * i + 0];
                    int v = (int)rest[2LL * i + 1];
                    data.rounds.push_back({u, v});
                }
                data.hasExplicitA = false;
            } else {
                finish(_pe, "input schema mismatch after edges");
            }
        } else {
            data.rounds.reserve(data.q);
            for (int i = 0; i < data.q; ++i) {
                int u = inf.readInt();
                int v = inf.readInt();
                data.rounds.push_back({u, v});
            }
            data.hasExplicitA = false;
        }

        tests.push_back(std::move(data));
    }

    query_limit = 5LL * totalQ;
    log_metrics();

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

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

    for (int tc = 0; tc < t; ++tc) {
        const auto& data = tests[tc];
        int n = data.n, q = data.q;

        cout << n << " " << q << "\n";
        for (auto [u, v] : data.edges) cout << u << " " << v << "\n";
        cout.flush();

        vector<int> p1(n + 1, 0), p2(n + 1, 0);
        for (int i = 1; i <= n; ++i) {
            long long x;
            if (!readLLFromCin(x)) finish(_pe, "EOF while reading p1");
            if (x < INT_MIN || x > INT_MAX) finish(_pe, "invalid integer in p1");
            p1[i] = (int)x;
        }
        for (int i = 1; i <= n; ++i) {
            long long x;
            if (!readLLFromCin(x)) finish(_pe, "EOF while reading p2");
            if (x < INT_MIN || x > INT_MAX) finish(_pe, "invalid integer in p2");
            p2[i] = (int)x;
        }
        if (!isPerm1toN(p1, n)) finish(_pe, "p1 is not a permutation");
        if (!isPerm1toN(p2, n)) finish(_pe, "p2 is not a permutation");

        if (data.hasExplicitA) {
            for (int i = 0; i < q; ++i) {
                if (!isPerm0toNminus1(data.aRounds[i], n)) finish(_pe, "explicit a is not a permutation");
            }
        }

        LCA lca;
        lca.init(n, data.edges);

        for (int round = 0; round < q; ++round) {
            int u = data.rounds[round].first;
            int v = data.rounds[round].second;
            if (u < 1 || u > n || v < 1 || v > n || u == v) finish(_pe, "invalid (u,v) in hidden rounds");

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

            RoundOracle oracle;
            oracle.n = n;

            if (data.hasExplicitA) {
                oracle.hasA = true;
                oracle.a = &data.aRounds[round];
            } else {
                oracle.hasA = false;
                long long seedMul = ( (long long)(u + v) * 1000003LL + 2LL * round + 1 );
                oracle.mul = pickCoprimeMultiplier(n, seedMul);
                oracle.add = ((long long)u * 239017LL + (long long)v * 1000003LL + (long long)round * 97LL) % n;
            }

            while (true) {
                string tok;
                if (!readToken(tok)) finish(_pe, "EOF during interaction");

                if (tok == "?") {
                    long long tt, l, r;
                    if (!readLLFromCin(tt) || !readLLFromCin(l) || !readLLFromCin(r)) finish(_pe, "malformed query");
                    if (!(tt == 1 || tt == 2)) finish(_pe, "query t must be 1 or 2");
                    if (l < 1 || r < 1 || l > r || r > n) finish(_pe, "query range out of bounds");

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

                    int ans = (tt == 1) ? minOnSegment(p1, (int)l, (int)r, oracle)
                                        : minOnSegment(p2, (int)l, (int)r, oracle);

                    cout << ans << "\n";
                    cout.flush();
                } else if (tok == "!") {
                    long long xll;
                    if (!readLLFromCin(xll)) finish(_pe, "malformed answer");
                    if (xll < 0 || xll > n) finish(_pe, "answer out of bounds");
                    int x = (int)xll;

                    int mex = mexOnPath(lca, u, v, oracle);
                    if (x != mex) finish(_wa, "wrong mex");

                    cout << 1 << "\n";
                    cout.flush();
                    break;
                } else if (tok == "-1") {
                    finish(_pe, "contestant reported -1");
                } else {
                    finish(_pe, "unexpected token");
                }
            }
        }
    }

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

struct LCA {
    int n = 0;
    int LOG = 0;
    vector<int> depth;
    vector<vector<int>> up;
    vector<vector<int>> g;

    LCA() = default;

    LCA(int n_, const vector<pair<int,int>>& edges) {
        init(n_, edges);
    }

    void init(int n_, const vector<pair<int,int>>& edges) {
        n = n_;
        g.assign(n + 1, {});
        for (auto [u, v] : edges) {
            g[u].push_back(v);
            g[v].push_back(u);
        }

        LOG = 1;
        while ((1 << LOG) <= n) ++LOG;
        up.assign(LOG, vector<int>(n + 1, 0));
        depth.assign(n + 1, 0);

        queue<int> q;
        vector<int> parent(n + 1, 0);
        parent[1] = 0;
        depth[1] = 0;
        q.push(1);

        while (!q.empty()) {
            int v = q.front();
            q.pop();
            up[0][v] = parent[v];
            for (int to : g[v]) {
                if (to == parent[v]) continue;
                parent[to] = v;
                depth[to] = depth[v] + 1;
                q.push(to);
            }
        }

        for (int k = 1; k < LOG; ++k) {
            for (int v = 1; v <= n; ++v) {
                int mid = up[k - 1][v];
                up[k][v] = (mid == 0 ? 0 : up[k - 1][mid]);
            }
        }
    }

    int lca(int a, int b) const {
        if (depth[a] < depth[b]) swap(a, b);
        int diff = depth[a] - depth[b];
        for (int k = 0; k < LOG; ++k) {
            if (diff & (1 << k)) a = up[k][a];
        }
        if (a == b) return a;
        for (int k = LOG - 1; k >= 0; --k) {
            if (up[k][a] != up[k][b]) {
                a = up[k][a];
                b = up[k][b];
            }
        }
        return up[0][a];
    }

    vector<int> getPath(int u, int v) const {
        int w = lca(u, v);
        vector<int> A, B;
        int x = u;
        while (x != w) {
            A.push_back(x);
            x = up[0][x];
        }
        A.push_back(w);
        x = v;
        while (x != w) {
            B.push_back(x);
            x = up[0][x];
        }
        reverse(B.begin(), B.end());
        A.insert(A.end(), B.begin(), B.end());
        return A;
    }
};

static pair<vector<pair<int,int>>, vector<pair<int,int>>> buildTreeAndRoundsCorner(long long seed, string mode) {
    vector<pair<int,int>> edges;
    vector<pair<int,int>> rounds;

    if (seed == 1) {
        int n = 2, q = 1;
        edges = {{1,2}};
        rounds = {{1,2}};
        return {edges, rounds};
    }
    if (seed == 2) {
        int n = 7, q = 3;
        for (int i = 2; i <= n; ++i) edges.push_back({1, i});
        rounds = {{2,3}, {4,5}, {6,7}};
        return {edges, rounds};
    }

    {
        int n = 10, q = 5;
        for (int i = 1; i <= 6; ++i) edges.push_back({i, i + 1});
        edges.push_back({4, 8});
        edges.push_back({4, 9});
        edges.push_back({4, 10});
        rounds = {{8,7}, {9,7}, {10,7}, {8,9}, {1,7}};
        return {edges, rounds};
    }
}

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

    string mode = opt<string>("mode", "non");
    if (mode != "non" && mode != "adp") mode = "non";

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

    int nOpt = opt<int>("n", (mode == "adp" ? 60000 : 60000));
    int qOpt = opt<int>("q", (mode == "adp" ? 50 : 50));

    auto clampNQ = [&](int& n, int& q) {
        n = max(2, min(n, 100000));
        q = max(1, min(q, 10000));
        long long prod = 1LL * n * q;
        if (prod > 3000000LL) {
            q = (int)(3000000LL / n);
            q = max(1, q);
        }
    };

    vector<pair<int,int>> edges_old;
    vector<pair<int,int>> rounds_old;
    int n = 0, q = 0;

    if (seedVal >= 1 && seedVal <= 3) {
        auto [edgesC, roundsC] = buildTreeAndRoundsCorner(seedVal, mode);
        edges_old = edgesC;
        rounds_old = roundsC;
        n = 0;
        for (auto [u, v] : edges_old) n = max(n, max(u, v));
        q = (int)rounds_old.size();
    } else {
        n = nOpt;
        q = qOpt;
        clampNQ(n, q);

        int L = n / 2;
        L = max(2, L);
        int hub = max(1, L / 2);

        int S = n / 3;
        S = min(S, n - L);
        S = max(0, S);

        edges_old.reserve(n - 1);
        for (int i = 1; i < L; ++i) edges_old.push_back({i, i + 1});

        for (int i = 1; i <= S; ++i) {
            int node = L + i;
            edges_old.push_back({hub, node});
        }

        for (int node = L + S + 1; node <= n; ++node) {
            int roll = rnd.next(1, 100);
            int parent = 1;
            if (roll <= 50) parent = rnd.next(1, L);
            else if (roll <= 80) parent = hub;
            else parent = rnd.next(1, node - 1);
            if (parent == node) parent = max(1, node - 1);
            edges_old.push_back({parent, node});
        }

        rounds_old.reserve(q);
        auto pickStarLeaf = [&]() -> int {
            if (S == 0) return rnd.next(1, n);
            return L + 1 + rnd.next(0, S - 1);
        };
        auto pickNode = [&]() -> int { return rnd.next(1, n); };

        int endA = 1;
        int endB = L;

        for (int i = 0; i < q; ++i) {
            int u = 1, v = 2;
            int type = i % 10;

            if (type == 0 || type == 1) {
                u = pickStarLeaf();
                v = endB;
            } else if (type == 2) {
                u = endA;
                v = pickStarLeaf();
            } else if (type == 3) {
                u = endA;
                v = endB;
            } else if (type == 4) {
                u = hub;
                v = endB;
            } else if (type == 5) {
                u = pickStarLeaf();
                v = pickStarLeaf();
            } else if (type == 6) {
                u = pickNode();
                v = (rnd.next(0, 1) ? endA : endB);
            } else if (type == 7) {
                u = pickNode();
                v = pickNode();
            } else if (type == 8) {
                u = endB;
                v = pickStarLeaf();
            } else {
                u = pickNode();
                v = pickNode();
            }
            if (u == v) v = (u == 1 ? 2 : 1);
            rounds_old.push_back({u, v});
        }
    }

    if (n == 0) {
        n = 0;
        for (auto [u, v] : edges_old) n = max(n, max(u, v));
        for (auto [u, v] : rounds_old) n = max(n, max(u, v));
        n = max(n, 2);
    }
    q = (int)rounds_old.size();

    vector<int> perm(n + 1), invperm(n + 1);
    for (int i = 1; i <= n; ++i) perm[i] = i;

    if (!(seedVal >= 1 && seedVal <= 3)) {
        vector<int> labels(n);
        for (int i = 0; i < n; ++i) labels[i] = i + 1;
        shuffleVec(labels);
        for (int i = 1; i <= n; ++i) perm[i] = labels[i - 1];
    }
    for (int i = 1; i <= n; ++i) invperm[perm[i]] = i;

    vector<pair<int,int>> edges_new;
    edges_new.reserve(edges_old.size());
    for (auto [u, v] : edges_old) edges_new.push_back({perm[u], perm[v]});

    vector<pair<int,int>> rounds_new;
    rounds_new.reserve(rounds_old.size());
    for (auto [u, v] : rounds_old) rounds_new.push_back({perm[u], perm[v]});

    cout << 1 << "\n";
    cout << n << " " << q << "\n";
    for (auto [u, v] : edges_new) cout << u << " " << v << "\n";

    LCA lcaOld(n, edges_old);

    if (mode == "adp") {
        for (int i = 0; i < q; ++i) {
            cout << rounds_new[i].first << " " << rounds_new[i].second << "\n";
        }
        return 0;
    }

    for (int i = 0; i < q; ++i) {
        int uOld = rounds_old[i].first;
        int vOld = rounds_old[i].second;
        int uNew = rounds_new[i].first;
        int vNew = rounds_new[i].second;

        vector<int> path = lcaOld.getPath(uOld, vOld);
        int m = (int)path.size();

        vector<int> aOld(n + 1, -1);
        vector<char> onPath(n + 1, 0);
        for (int x : path) onPath[x] = 1;

        bool makeLargeMex = true;
        if (m < n) {
            int roll = rnd.next(1, 100);
            makeLargeMex = (roll <= 75);
        }

        int startVal = makeLargeMex ? 0 : 1;
        for (int idx = 0; idx < m; ++idx) {
            int val = startVal + idx;
            if (val >= n) val = n - 1;
            aOld[path[idx]] = val;
        }

        vector<char> usedVal(n, 0);
        for (int v = 1; v <= n; ++v) {
            if (aOld[v] != -1) usedVal[aOld[v]] = 1;
        }

        vector<int> leftover;
        leftover.reserve(n);
        for (int val = 0; val < n; ++val) if (!usedVal[val]) leftover.push_back(val);
        shuffleVec(leftover);

        int ptr = 0;
        for (int node = 1; node <= n; ++node) {
            if (aOld[node] == -1) {
                aOld[node] = leftover[ptr++];
            }
        }

        vector<int> aNew(n + 1, 0);
        for (int oldNode = 1; oldNode <= n; ++oldNode) {
            int newNode = perm[oldNode];
            aNew[newNode] = aOld[oldNode];
        }

        cout << uNew << " " << vNew << "\n";
        for (int node = 1; node <= n; ++node) {
            if (node > 1) cout << " ";
            cout << aNew[node];
        }
        cout << "\n";
    }

    return 0;
}


Hercule Poirot, world-renowned detective, was having a lovely cup of tea in his compartment on the Disorient Express when the train conductor rushed in. “We have lost track of the number of train carriages,” exclaimed the conductor. You see, this was no ordinary train, and had no first or last train carriage. Instead, the train carriages were connected to form a large cycle, causing the conductor’s confusion.

![](images/4f8efbe88056deacf570934998eeaa4624ce60de7e949f9170ba59956585cda8.jpg)
Train. Unsplash License by Robin Ulrich on Unsplash

Hercule thought for a moment. “That is most peculiar,”

he said. “But I may be able to help you.” He reached over and grabbed the lamp from the side table. “You see, each train carriage has a light switch like this one. By moving between the carriages and toggling these switches, we can determine the number of train carriages.”

The conductor was sceptical, but agreed to try it. “We are in a hurry,” he said, “so please determine $n$ , the number of carriages that the train consists of, in at most $3 n + 5 0 0$ steps.” Here a step counts as either moving to an adjacent carriage or toggling a light switch in the current carriage. “The only thing I am certain of is that $n$ is at least 3 and at most 5000.”

# Interaction

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

The interactor first sends an integer $s$ ( $s \in \{ 0 , 1 \}$ ), the state of the light switch in Hercule’s initial carriage.

Your submission may then send at most $3 n + 5 0 0 ~ \mathrm { s t e p s ^ { 1 } }$ for Hercule to carry out, each by printing one line of the form $\stackrel { 6 6 } { \mathop { \ : } } ? \ : \ : a ^ { \ : \prime \prime }$ , where $a$ is one of the following:

• “left”, to move to the adjacent train carriage in the clockwise direction, • “right”, to move to the adjacent train carriage in the counter-clockwise direction, or • “flip”, to toggle the light switch in the current train carriage.

After every step, the interactor replies with an integer $s$ $s \in \{ 0 , 1 \}$ ), the state of the light switch in the train carriage that Hercule is currently in, after he has carried out the requested step.

When you have determined the number of train carriages $n$ , print one line of the form “! $n$ ” ( $3 \leq n \leq 5 0 0 0$ ), after which the interaction will stop. Printing the answer does not count as a query.

The interactor is not adaptive; the initial state of the light switches is determined by the interactor before any interaction takes place. Make sure you flush the buffer after each write. Using more than $3 n + 5 0 0$ queries will result in a wrong answer verdict.

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

![](images/9d0d8564a4937ba26a449c9f93a1a135a524dc218865922274ab69a160028ac3.jpg)

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

static long long queries = 0;
static long long query_limit = 0;
static bool finished = false;

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

    }
}

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

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    int n = inf.readInt(3, 5000, "n");
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        a[i] = inf.readInt(0, 1, format("a[%d]", i));
    }

    query_limit = 3LL * n + 500;

    log_metrics();

    int current_pos = 0;
    cout << a[current_pos] << endl;

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

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF: contestant terminated without providing answer");
        }

        if (token.size() > 0 && token[0] == '!') {
            string ans_str;
            if (token.size() > 1) {
                ans_str = token.substr(1);
            } else {
                if (!(cin >> ans_str)) {
                    finish(_wa, "Unexpected EOF after '!'");
                }
            }

            int ans = 0;
            try {
                ans = stoi(ans_str);
            } catch (...) {
                finish(_pe, "Answer is not a valid integer");
            }

            if (ans == n) {

                finish(_ok, format("Correct! n=%d, queries=%lld", n, queries));
            } else {
                finish(_wa, format("Incorrect answer. Expected %d, got %d", n, ans));
            }
        }

        if (token == "?") {
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF after '?'");
            }
        }

        queries++;

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

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

        int res = -1;
        if (token == "left") {

            current_pos = (current_pos + 1) % n;
            res = a[current_pos];
        } else if (token == "right") {

            current_pos = (current_pos - 1 + n) % n;
            res = a[current_pos];
        } else if (token == "flip") {

            a[current_pos] = 1 - a[current_pos];
            res = a[current_pos];
        } else {
            finish(_pe, format("Invalid query token: '%s'", token.c_str()));
        }

        cout << res << endl;
    }

    return 0;
}

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

using namespace std;

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

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

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

    int n;
    int type = -1;

    if (seed_val == 1) {
        n = 3;
        type = 0;
    } else if (seed_val == 2) {
        n = 5000;
        type = 1;
    } else if (seed_val == 3) {
        n = 5000;
        type = 2;
    } else if (seed_val == 4) {
        n = 5000;
        type = 3;
    } else if (seed_val == 5) {
        n = 5000;
        type = 4;
    } else if (seed_val == 6) {
        n = 5000;
        type = 5;
    } else if (seed_val == 7) {
        n = 4999;
        type = 0;
    } else {

        n = rnd.next(3, 5000);

        int r = rnd.next(1, 100);
        if (r <= 20) type = 0;
        else if (r <= 30) type = 1;
        else if (r <= 40) type = 2;
        else if (r <= 50) type = 3;
        else if (r <= 70) type = 4;
        else if (r <= 90) type = 5;
        else type = 6;
    }

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

    cout << n << endl;
    vector<int> a(n);

    if (type == 0) {
        for (int i = 0; i < n; i++) a[i] = rnd.next(0, 1);
    } else if (type == 1) {
        fill(a.begin(), a.end(), 0);
    } else if (type == 2) {
        fill(a.begin(), a.end(), 1);
    } else if (type == 3) {
        for (int i = 0; i < n; i++) a[i] = i % 2;
    } else if (type == 4) {

        int max_p = max(2, min(n - 1, 50));
        int p = rnd.next(2, max_p);
        vector<int> pat(p);
        for (int i = 0; i < p; i++) pat[i] = rnd.next(0, 1);
        for (int i = 0; i < n; i++) a[i] = pat[i % p];

        int idx = rnd.next(0, n - 1);
        a[idx] = 1 - a[idx];
    } else if (type == 5) {

        int min_p = max(2, n / 3);
        int max_p = max(min_p, n / 2 + 5);
        if (max_p >= n) max_p = n - 1;
        int p = rnd.next(min_p, max_p);
        vector<int> pat(p);
        for (int i = 0; i < p; i++) pat[i] = rnd.next(0, 1);
        for (int i = 0; i < n; i++) a[i] = pat[i % p];

        int idx = rnd.next(0, n - 1);
        a[idx] = 1 - a[idx];
    } else if (type == 6) {
        fill(a.begin(), a.end(), 0);
        int k = rnd.next(1, max(1, n / 40));
        for (int i = 0; i < k; i++) a[rnd.next(0, n - 1)] = 1;
    }

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

    return 0;
}


The two siblings Alberto and Beatrice have to eat a spinach pizza together. However, none of them likes spinach, so they both want to eat as little as possible.

The pizza has the shape of a strictly convex polygon with $n$ vertices located at integer coordinates $(x_1, y_1), \, (x_2, y_2), \, \dots, \, (x_n, y_n)$ of the plane.

The siblings have decided to eat the pizza in the following way: taking turns, starting with Alberto, each sibling chooses a vertex of the remaining part of the pizza and eats out the triangle determined by its two neighboring edges. In this way, after each of the first $n - 3$ turns the pizza will have one less vertex. The game ends after the $(n - 2)$-th turn, when all the pizza has been eaten.

Assuming that Alberto and Beatrice choose the slices to eat optimally, which of the siblings manages to eat at most half of the pizza? You should identify a sibling that has a strategy to do so and help them choose the slices appropriately. Note that it is possible that both Alberto and Beatrice end up eating exactly half of the area if they choose their slices optimally.

Input

The first line contains a single integer $n$ ($4 \le n \le 100$) — the number of vertices.

The next $n$ lines contain two integers $x_i$ and $y_i$ each ($-10^6 \le x_i, y_i \le 10^6$) — the coordinates of the $i$-th vertex of the polygon representing the initial shape of the pizza.

It is guaranteed that the polygon is strictly convex and that its vertices are given in counterclockwise order.

Interaction

First, you should print a line containing either the string $\texttt{Alberto}$ or the string $\texttt{Beatrice}$ — the sibling that you will help to win.

Then, for the next $n - 2$ turns, you will alternate with the judge in choosing a slice of the pizza and removing it, starting with you if you chose to help Alberto, or starting with the judge if you chose to help Beatrice.

* When it is your turn, print a single line containing an integer $p$ ($1 \leq p \leq n$) that has not been chosen before, indicating that you want to eat the slice determined by the vertex located at $(x_p, y_p)$.
* When it is the judge's turn, read an integer $q$ ($1 \leq q \leq n$), indicating that the other player eats the slice determined by the vertex located at $(x_q, y_q)$. It is guaranteed that $q$ has not been chosen before.

If one of your interactions is malformed, the interactor terminates immediately and your program receives the verdict $\texttt{WRONG-ANSWER}$. Otherwise, you will receive $\texttt{CORRECT}$ if at the end your player has eaten at most half of the pizza, and $\texttt{WRONG-ANSWER}$ otherwise.

After printing a line do not forget to end the line and flush the output. Otherwise, you will get the verdict $\texttt{TIMELIMIT}$. To flush the output, use:

* $\texttt{fflush(stdout)}$ in C;
* $\texttt{fflush(stdout)}$, $\texttt{cout <}\texttt{< flush}$ or $\texttt{cout.flush()}$ in C++;
* $\texttt{System.out.flush()}$ in Java and Kotlin;
* $\texttt{sys.stdout.flush()}$ in Python.

Examples

Input

```
4
0 0
6 1
5 3
1 4
```

Output

```
-
```

Input

```
6
0 0
2 0
3 2
2 4
0 4
-1 2
```

Output

```
-
```

Input

```
7
0 0
2 0
5 2
4 5
1 5
-1 4
-1 2
```

Output

```
-
```

Note

In the first sample, the pizza has area $15$. Alberto can eat less than half of the pizza by eating the slice around vertex $2$ (which has area $6.5$) or around vertex $3$ (which has area $3.5$).

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

In the second sample, it can be proved that both players will eat exactly half of the pizza if they eat optimally. Therefore it is possible to choose to help either Alberto or Beatrice.

In the third sample, it is possible to show that only Beatrice has a strategy to eat at most half of the pizza. The following is an example of a valid interaction (after reading the input):

 \begin{array}{|c|c|c|} \hline \textbf{Contestant} & \textbf{Judge} & \textbf{Explanation} \\ \hline \texttt{Beatrice} & & \text{The contestant will help Beatrice} \\ \hline & \texttt{7} & \text{Alberto eats the triangle with vertices $6$, $7$, $1$ and area $1$} \\ \hline \texttt{2} & & \text{Beatrice eats the triangle with vertices $1$, $2$, $3$ and area $2$} \\ \hline & \texttt{5} & \text{Alberto eats the triangle with vertices $4$, $5$, $6$ and area $1.5$} \\ \hline \texttt{4} & & \text{Beatrice eats the triangle with vertices $3$, $4$, $6$ and area $8$} \\ \hline & \texttt{6} & \text{Alberto eats the triangle with vertices $3$, $6$, $1$ and area $11$} \\ \hline \end{array}  The total area eaten by Alberto is $13.5$ and the total area eaten by Beatrice is $10$, which is less than half the area of the whole pizza. The actions performed by the contestant and the judge in this example of interaction may be non-optimal. The process is illustrated below: ![](https://espresso.codeforces.com/46ad7ab3420cde43230c826a0a54a5d8c78de0f9.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 {
        if (query_limit != 0) {
            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());
}

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

struct Point {
    long long x, y;
};

long long cross_product(Point a, Point b, Point c) {
    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

int n;
vector<Point> poly;
vector<int> L, R;
vector<bool> used;

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

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

    n = inf.readInt();
    query_limit = n - 2;

    poly.resize(n);
    for (int i = 0; i < n; i++) {
        poly[i].x = inf.readInt();
        poly[i].y = inf.readInt();
    }

    cout << n << endl;
    for (int i = 0; i < n; i++) {
        cout << poly[i].x << " " << poly[i].y << endl;
    }
    cout.flush();

    L.resize(n);
    R.resize(n);
    used.assign(n, false);
    for (int i = 0; i < n; i++) {
        L[i] = (i - 1 + n) % n;
        R[i] = (i + 1) % n;
    }

    long long total_area_2x = 0;
    for (int i = 0; i < n; i++) {
        total_area_2x += cross_product({0,0}, poly[i], poly[(i+1)%n]);
    }
    total_area_2x = std::abs(total_area_2x);

    log_metrics();

    string choice;
    if (!(cin >> choice)) finish(_wa, "No choice provided (expected Alberto/Beatrice)");

    bool user_is_alberto;
    if (choice == "Alberto") user_is_alberto = true;
    else if (choice == "Beatrice") user_is_alberto = false;
    else finish(_wa, "Invalid choice '%s', expected 'Alberto' or 'Beatrice'", choice.c_str());

    long long user_area_2x = 0;

    for (int turn = 1; turn <= n - 2; turn++) {
        queries = turn;

        bool judge_turn = false;
        if (user_is_alberto) {

            if (turn % 2 == 0) judge_turn = true;
        } else {

            if (turn % 2 != 0) judge_turn = true;
        }

        int p_idx = -1;

        if (judge_turn) {

            long long best_val = -1;
            int best_idx = -1;

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

                    long long current_area = std::abs(cross_product(poly[L[i]], poly[i], poly[R[i]]));
                    if (best_idx == -1 || current_area < best_val) {
                        best_val = current_area;
                        best_idx = i;
                    }
                }
            }
            p_idx = best_idx;

            cout << (p_idx + 1) << endl;
        } else {

            string token;
            if (!(cin >> token)) finish(_wa, "Unexpected end of input waiting for move");

            if (token == "?") {
                if (!(cin >> token)) finish(_wa, "Unexpected end of input after '?'");
            }
            if (!token.empty() && token[0] == '!') finish(_wa, "Unexpected '!' token during game");

            int p_user = 0;
            try {
                size_t pos;
                p_user = stoi(token, &pos);
                if (pos != token.size()) finish(_wa, "Trailing garbage in integer token '%s'", token.c_str());
            } catch (...) {
                finish(_wa, "Invalid integer format '%s'", token.c_str());
            }

            if (p_user < 1 || p_user > n) finish(_wa, "Index %d out of bounds [1, %d]", p_user, n);
            p_idx = p_user - 1;

            if (used[p_idx]) finish(_wa, "Vertex %d already removed", p_user);

            long long area = std::abs(cross_product(poly[L[p_idx]], poly[p_idx], poly[R[p_idx]]));
            user_area_2x += area;
        }

        int left = L[p_idx];
        int right = R[p_idx];
        R[left] = right;
        L[right] = left;
        used[p_idx] = true;

        if (turn % 10 == 0) log_metrics();
    }

    log_metrics();

    if (2 * user_area_2x <= total_area_2x) {
        finish(_ok, "Correct: ate <= half (User=%.1f, Total=%.1f)", user_area_2x / 2.0, total_area_2x / 2.0);
    } else {
        finish(_wa, "Wrong Answer: ate > half (User=%.1f, Total=%.1f)", user_area_2x / 2.0, total_area_2x / 2.0);
    }

    return 0;
}

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

using namespace std;

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

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

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

struct Point {
    long long x, y;
    int id;
};

long long cross_product(Point a, Point b, Point c) {
    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

long long get_area2(const vector<Point>& poly, int i) {
    int n = poly.size();
    Point prev = poly[(i - 1 + n) % n];
    Point curr = poly[i];
    Point next = poly[(i + 1) % n];
    return abs(cross_product(prev, curr, next));
}

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

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

    int n = inf.readInt();
    query_limit = n - 2;

    log_metrics();

    vector<Point> initial_poly(n);
    for (int i = 0; i < n; i++) {
        initial_poly[i].x = inf.readInt();
        initial_poly[i].y = inf.readInt();
        initial_poly[i].id = i + 1;
    }

    long long total_area2 = 0;
    for (int i = 0; i < n; i++) {
        total_area2 += cross_product({0,0,0}, initial_poly[i], initial_poly[(i + 1) % n]);
    }
    total_area2 = abs(total_area2);

    cout << n << endl;
    for (int i = 0; i < n; i++) {
        cout << initial_poly[i].x << " " << initial_poly[i].y << endl;
    }
    cout.flush();

    string choice = ouf.readToken("Alberto|Beatrice");
    bool contestant_is_alberto = (choice == "Alberto");

    vector<Point> current_poly = initial_poly;
    set<int> removed_ids;
    long long contestant_area2 = 0;
    long long judge_area2 = 0;

    for (int turn = 1; turn <= n - 2; turn++) {
        queries++;

        bool is_alberto_turn = (turn % 2 != 0);
        bool is_contestant_turn = (is_alberto_turn == contestant_is_alberto);

        if (is_contestant_turn) {

            int p_id = ouf.readInt(1, n);

            if (removed_ids.count(p_id)) {
                finish(_wa, format("Vertex %d has already been removed.", p_id));
            }

            int idx = -1;
            for (int i = 0; i < (int)current_poly.size(); i++) {
                if (current_poly[i].id == p_id) {
                    idx = i;
                    break;
                }
            }

            if (idx == -1) {

                finish(_wa, format("Vertex %d is not in the current polygon.", p_id));
            }

            long long area = get_area2(current_poly, idx);
            contestant_area2 += area;

            removed_ids.insert(p_id);
            current_poly.erase(current_poly.begin() + idx);

        } else {

            long long best_metric = -5000000000000000000LL;
            int best_idx = -1;
            int sz = current_poly.size();

            for (int i = 0; i < sz; i++) {
                long long my_area = get_area2(current_poly, i);
                long long opp_min_area = 0;

                if (sz - 1 > 2) {

                    vector<Point> next_poly = current_poly;
                    next_poly.erase(next_poly.begin() + i);

                    long long min_a = 5000000000000000000LL;
                    for (int j = 0; j < (int)next_poly.size(); j++) {
                        long long a = get_area2(next_poly, j);
                        if (a < min_a) min_a = a;
                    }
                    opp_min_area = min_a;
                }

                long long metric = opp_min_area - my_area;

                if (metric > best_metric) {
                    best_metric = metric;
                    best_idx = i;
                } else if (metric == best_metric) {

                    if (my_area < get_area2(current_poly, best_idx)) {
                        best_idx = i;
                    }
                }
            }

            int p_id = current_poly[best_idx].id;
            long long area = get_area2(current_poly, best_idx);
            judge_area2 += area;

            removed_ids.insert(p_id);
            current_poly.erase(current_poly.begin() + best_idx);

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

        if (turn % 10 == 0) log_metrics();
    }

    if (contestant_area2 * 2 <= total_area2) {
        finish(_ok, format("Contestant area %lld <= %lld (Total/2).", contestant_area2, total_area2 / 2));
    } else {
        finish(_wa, format("Contestant area %lld > %lld (Total/2).", contestant_area2, total_area2 / 2));
    }

    return 0;
}

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

struct Point {
    long long x, y;
};

int quad(Point p) {
    if (p.x > 0 && p.y >= 0) return 1;
    if (p.x <= 0 && p.y > 0) return 2;
    if (p.x < 0 && p.y <= 0) return 3;
    if (p.x >= 0 && p.y < 0) return 4;
    return 0;
}

long long cross_product(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
}

bool angle_cmp(Point a, Point b) {
    int qa = quad(a), qb = quad(b);
    if (qa != qb) return qa < qb;
    return cross_product(a, b) > 0;
}

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

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

    if (seed == 1) {
        cout << "4\n0 0\n6 1\n5 3\n1 4\n";
        return 0;
    }
    if (seed == 2) {
        cout << "6\n0 0\n2 0\n3 2\n2 4\n0 4\n-1 2\n";
        return 0;
    }
    if (seed == 3) {
        cout << "7\n0 0\n2 0\n5 2\n4 5\n1 5\n-1 4\n-1 2\n";
        return 0;
    }

    int n;
    if (mode == "adp") {

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

        n = rnd.next(4, 100);
    }

    while (true) {

        int k = n + rnd.next(5, 20);
        int vec_range = 20000;

        vector<long long> vx(k), vy(k);
        long long sum_x = 0, sum_y = 0;

        for (int i = 0; i < k; i++) {
            vx[i] = rnd.next(1, vec_range);
            if (rnd.next(2)) vx[i] = -vx[i];
            sum_x += vx[i];

            vy[i] = rnd.next(1, vec_range);
            if (rnd.next(2)) vy[i] = -vy[i];
            sum_y += vy[i];
        }

        while (sum_x != 0) {
            int i = rnd.next(k);
            if (sum_x > 0) { vx[i]--; sum_x--; }
            else { vx[i]++; sum_x++; }
        }
        while (sum_y != 0) {
            int i = rnd.next(k);
            if (sum_y > 0) { vy[i]--; sum_y--; }
            else { vy[i]++; sum_y++; }
        }

        vector<Point> vecs;
        for (int i = 0; i < k; i++) {
            if (vx[i] == 0 && vy[i] == 0) continue;
            vecs.push_back({vx[i], vy[i]});
        }

        if ((int)vecs.size() < n) continue;

        sort(vecs.begin(), vecs.end(), angle_cmp);

        vector<Point> merged;
        merged.push_back(vecs[0]);
        for (size_t i = 1; i < vecs.size(); i++) {
            Point& last = merged.back();
            Point curr = vecs[i];
            if (quad(last) == quad(curr) && cross_product(last, curr) == 0) {
                last.x += curr.x;
                last.y += curr.y;
            } else {
                merged.push_back(curr);
            }
        }

        if (merged.size() > 1) {
            Point& first = merged.front();
            Point& last = merged.back();
            if (quad(first) == quad(last) && cross_product(last, first) == 0) {
                first.x += last.x;
                first.y += last.y;
                merged.pop_back();
            }
        }

        if ((int)merged.size() < n) continue;

        while ((int)merged.size() > n) {
            int idx = rnd.next((int)merged.size());
            int next_idx = (idx + 1) % merged.size();

            merged[idx].x += merged[next_idx].x;
            merged[idx].y += merged[next_idx].y;

            merged.erase(merged.begin() + next_idx);
        }

        bool ok = true;
        for (int i = 0; i < n; i++) {
            Point p1 = merged[i];
            Point p2 = merged[(i + 1) % n];

            if ((p1.x == 0 && p1.y == 0) || (p2.x == 0 && p2.y == 0)) { ok = false; break; }

            if (quad(p1) == quad(p2) && cross_product(p1, p2) == 0) { ok = false; break; }
        }
        if (!ok) continue;

        vector<Point> poly(n);
        Point curr = {0, 0};
        long long min_x = 0, max_x = 0, min_y = 0, max_y = 0;

        for (int i = 0; i < n; i++) {
            poly[i] = curr;
            min_x = min(min_x, curr.x);
            max_x = max(max_x, curr.x);
            min_y = min(min_y, curr.y);
            max_y = max(max_y, curr.y);
            curr.x += merged[i].x;
            curr.y += merged[i].y;
        }

        long long shift_x = -(min_x + max_x) / 2;
        long long shift_y = -(min_y + max_y) / 2;
        bool coords_ok = true;

        for (int i = 0; i < n; i++) {
            poly[i].x += shift_x;
            poly[i].y += shift_y;
            if (abs(poly[i].x) > 1000000 || abs(poly[i].y) > 1000000) coords_ok = false;
        }

        if (!coords_ok) continue;

        cout << n << "\n";
        for (int i = 0; i < n; i++) {
            cout << poly[i].x << " " << poly[i].y << "\n";
        }
        break;
    }

    return 0;
}


This is an interactive problem.

An infinite square grid is hidden from you. Every cell is identified by a pair of integers $( x , y )$ and is randomly colored either black or white with $5 0 \%$ probability for each color, independently of other cells.

Two cells are considered adjacent if they share an edge or a corner. Thus, every cell $( x , y )$ has 8 adjacent cells: $( x - 1 , y - 1 )$ , $( x - 1 , y )$ , $( x - 1 , y + 1 )$ , $( x , y - 1 )$ , $( x , y + 1 )$ , $( x + 1 , y - 1 )$ , $( x + 1 , y )$ , and $( x + 1 , y + 1 )$

A set of cells $S$ is called $\delta$ -connected if for any two cells in $S$ , there exists a path between them using only cells from $S$ , where consecutive cells in the path are adjacent.

In one query, you can learn the color of any cell on the grid. Your task is to find an 8-connected set of $n$ cells such that all cells in the set have the same color.

You need to solve $t$ test cases. In each test case, the grid is colored randomly and independently of the other test cases.

You are allowed to make at most 30 000 queries in total over all test cases.

# Input

The first line contains two integers $t$ and $n$ , denoting the number of test cases and the required size of the 8-connected set ( $1 \leq t \leq 5 0$ ; $2 \leq n \leq 3 0 0$ ).

# Interaction Protocol

In each test case, you can make zero or more queries to learn the colors of grid cells.

To make a query, print a line:

• ? x y

where $( x , y )$ are the coordinates of the requested cell $( - 1 0 ^ { 9 } \leq x , y \leq 1 0 ^ { 9 } ,$ ). After that, read a line containing one letter: $\cdot _ { \tt B } \cdot$ if the cell $( x , y )$ is black, or $" \mathbb { W } ^ { \gamma }$ if the cell $( x , y )$ is white.

Once you are ready to present an 8-connected set of $n$ cells of the same color, print a line:

$\bullet ~ ! ~ c ~ x _ { 1 } ~ y _ { 1 } ~ x _ { 2 } ~ y _ { 2 } ~ . ~ . ~ x _ { n } ~ y _ { n }$

where $c$ is a letter denoting the color of the cells in the set ( $\scriptstyle \mathbf { \tilde { B } } ^ { \prime }$ for black and $" \mathbb { W } ^ { \dag }$ for white), and $( x _ { 1 } , y _ { 1 } ) , ( x _ { 2 } , y _ { 2 } ) , \ldots , ( x _ { n } , y _ { n } )$ are the $n$ distinct cells in the set $( - 1 0 ^ { 9 } \leq x _ { i } , y _ { i } \leq 1 0 ^ { 9 } )$ ). The interactor does not print anything in response to this line.

After printing the set, proceed to the next test case, or terminate the program if this was the last one.

You are allowed to make at most 30 000 queries in total over all test cases (not including the lines that print the sets). If you exceed this limit, the interactor will print 0 instead of its usual response, and your program should terminate immediately to guarantee the “Wrong Answer” verdict.

The interactor is not adaptive: all random grids used in the tests have been pre-generated and remain the same across all submissions.

# Example

standard input	standard output

25	？11

W

W	？12

B	？13

B	？21

B	？22

W	？23

B	？31

B	？32

B	？33 !B2213332132

B	？11

W	？12

W	？13

B	？21

B	？22 ？23

W	？31

W	？32

W	？33

B

	!W1232132331

# Note

In the example, the queries and the responses are separated by empty lines for clarity. In the actual interaction between your program and the interactor, there will be no empty lines.

Your solution will be evaluated on at most 60 test files.

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

static long long queries = 0;
static long long query_limit = 30000;
static const long long HARD_CAP = 300000;

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 uint64_t splitmix64(uint64_t z) {
    z += 0x9e3779b97f4a7c15;
    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
    z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
    return z ^ (z >> 31);
}

static char getColor(long long seed, long long x, long long y) {
    uint64_t h = splitmix64((uint64_t)seed);
    h = splitmix64(h ^ (uint64_t)x);
    h = splitmix64(h ^ (uint64_t)y);
    return (h & 1) ? 'W' : 'B';
}

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

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

    int t = inf.readInt();
    int n = inf.readInt();
    inf.readLine();

    cout << t << " " << n << endl;

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

        long long case_seed = inf.readLong();
        inf.readLine();

        bool solved_case = false;
        while (!solved_case) {

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

            string token;
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF while waiting for command");
            }

            if (token == "!") {

                string cStr;
                if (!(cin >> cStr)) finish(_wa, "Unexpected EOF reading answer color");

                if (cStr.size() != 1 || (cStr[0] != 'B' && cStr[0] != 'W')) {
                    finish(_wa, "Invalid color format in answer: " + cStr);
                }
                char ansC = cStr[0];

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

                for (int k = 0; k < n; k++) {
                    string sx, sy;
                    if (!(cin >> sx >> sy)) finish(_wa, "Unexpected EOF reading answer coordinates");

                    long long x, y;
                    try {
                        x = stoll(sx);
                        y = stoll(sy);
                    } catch (...) {
                        finish(_wa, "Invalid coordinate format in answer");
                    }

                    if (getColor(case_seed, x, y) != ansC) {
                        finish(_wa, format("Cell (%lld, %lld) is not colored %c", x, y, ansC));
                    }
                    cells.push_back({x, y});
                }

                vector<pair<long long, long long>> sorted_cells = cells;
                sort(sorted_cells.begin(), sorted_cells.end());
                if (unique(sorted_cells.begin(), sorted_cells.end()) != sorted_cells.end()) {
                    finish(_wa, "Cells in the answer set must be distinct");
                }

                int visited_count = 0;
                if (n > 0) {
                    vector<bool> vis(n, false);
                    queue<int> q;

                    q.push(0);
                    vis[0] = true;
                    visited_count = 1;

                    while (!q.empty()) {
                        int u = q.front(); q.pop();
                        for (int v = 0; v < n; v++) {
                            if (!vis[v]) {
                                long long dx = abs(cells[u].first - cells[v].first);
                                long long dy = abs(cells[u].second - cells[v].second);

                                if (dx <= 1 && dy <= 1) {
                                    vis[v] = true;
                                    visited_count++;
                                    q.push(v);
                                }
                            }
                        }
                    }
                }

                if (visited_count != n) {
                    finish(_wa, "The set of cells is not 8-connected");
                }

                solved_case = true;

            } else {

                long long x, y;

                if (token == "?") {
                    if (!(cin >> x >> y)) finish(_wa, "Unexpected EOF reading query coordinates");
                } else {

                    try {
                        x = stoll(token);
                    } catch (...) {
                        finish(_wa, "Invalid token (expected integer, '?' or '!'): " + token);
                    }
                    if (!(cin >> y)) finish(_wa, "Unexpected EOF reading query coordinate y");
                }

                queries++;

                if (queries > query_limit) {
                    cout << 0 << endl;
                    finish(_wa, "Query limit exceeded (max 30000)");
                }

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

                char res = getColor(case_seed, x, y);
                cout << res << endl;
            }
        }
    }

    finish(_ok, "All test cases solved successfully");
    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 t_opt = opt<int>("t", -1);
    int n_opt = opt<int>("n", -1);

    int t = t_opt;
    int n = n_opt;

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

    if (t == -1) {

        if (n_opt == -1) {
            if (seed_val == 1) t = 50;
            else if (seed_val == 2) t = 1;
            else if (seed_val == 3) t = 50;
            else if (seed_val == 4) t = 1;
        }

        if (t == -1) {
            int p = rnd.next(100);
            if (p < 10) t = 1;
            else if (p < 25) t = 50;
            else t = rnd.next(1, 50);
        }
    }

    if (n == -1) {

        if (n_opt == -1) {
            if (seed_val == 1) n = 300;
            else if (seed_val == 2) n = 2;
            else if (seed_val == 3) n = 2;
            else if (seed_val == 4) n = 300;
        }

        if (n == -1) {
            int p = rnd.next(100);
            if (p < 10) n = 2;
            else if (p < 25) n = 300;
            else n = rnd.next(2, 300);
        }
    }

    cout << t << " " << n << endl;

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

        long long case_seed = rnd.next(1LL, 4000000000000000000LL);

        cout << case_seed;

        if (mode == "adp") {

            int difficulty = rnd.next(0, 100);

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

            cout << " " << difficulty << " " << strategy;
        }

        cout << endl;
    }

    return 0;
}


This is an interactive problem.

You are given an integer $n$.

The jury has hidden from you a directed graph with $n$ vertices (numbered from $1$ to $n$) and some number of edges. You additionally know that:

* The graph only contains edges of the form $i \leftarrow j$, where $1 \le i < j \le n$.
* For any three vertices $1 \le i < j < k \le n$, at least one of the following holds$^\dagger$:
  + Vertex $i$ is reachable from vertex $j$, or
  + Vertex $i$ is reachable from vertex $k$, or
  + Vertex $j$ is reachable from vertex $k$.

You want to color each vertex in either black or white such that for any two vertices $i$ and $j$ ($1 \le i < j \le n$) of the same color, vertex $i$ is reachable from vertex $j$.

To do that, you can ask queries of the following type:

*? i j — is vertex $i$ reachable from vertex $j$ ($1 \le i < j \le n$)?

Find any valid vertex coloring of the hidden graph in at most $2 \cdot n$ queries. It can be proven that such a coloring always exists.

Note that the grader is not adaptive: the graph is fixed before any queries are made.

$^\dagger$ Vertex $a$ is reachable from vertex $b$ if there exists a path from vertex $b$ to vertex $a$ in the graph.

Input

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

The only line of each test case contains a single integer $n$ ($3 \le n \le 100$) — the number of vertices in the hidden graph.

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

Interaction

The interaction for each test case begins by reading the integer $n$.

To make a query, output "? i j" without quotes ($1 \le i < j \le n$). If vertex $i$ is reachable from vertex $j$, you will get YES as an answer. Otherwise, you will get NO as an answer.

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

When you are ready to give the final answer, output "! $c_1 \ c_2 \ \ldots \ c_n$" without quotes — the colors of the vertices, where $c_i = 0$ if the vertex is black, and $c_i = 1$ if the vertex is white. After solving all test cases, your program should be terminated immediately.

After printing a query, do not forget to output an 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
4

YES

YES

YES

NO

NO

NO

5
```

Output

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

Note

The hidden graph in the first test case:![](https://espresso.codeforces.com/2c76b6097ab80b5e09fcef2a83a9df40cd211c80.png)

The hidden graph in the second test case:![](https://espresso.codeforces.com/c20c9e6f58a290ede775f40980c1691398ae8cb2.png)

The interaction happens as follows:

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | 2 | There are $2$ test cases. |
|  | 4 | In the first test case, the graph has $4$ vertices. |
|? 1 2 | YES | The solution asks if vertex $1$ is reachable from vertex $2$, and the jury answers YES. |
|? 2 3 | YES | The solution asks if vertex $2$ is reachable from vertex $3$, and the jury answers YES. |
|? 1 3 | YES | The solution asks if vertex $1$ is reachable from vertex $3$, and the jury answers YES. |
|? 1 4 | NO | The solution asks if vertex $1$ is reachable from vertex $4$, and the jury answers NO. |
|? 2 4 | NO | The solution asks if vertex $2$ is reachable from vertex $4$, and the jury answers NO. |
|? 3 4 | NO | The solution asks if vertex $3$ is reachable from vertex $4$, and the jury answers NO. |
|! 0 0 0 1 |  | The solution has somehow determined a valid coloring and outputs it. Since the output is correct, the jury continues to the next test case. |
|  | 5 | In the second test case, the graph has $5$ vertices. |
|! 1 1 0 1 0 |  | The solution has somehow determined a valid coloring, and outputs it. Since the output is correct and there are no more test cases, the jury and the solution exit. |

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

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

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

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

    }
}

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

struct TestCase {
    int n = 0;
    vector<vector<unsigned char>> reach;
};

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

static bool parseNonNegInt(const string& s, int& out) {
    if (s.empty()) return false;
    long long v = 0;
    for (char c : s) {
        if (c < '0' || c > '9') return false;
        v = v * 10 + (c - '0');
        if (v > INT_MAX) return false;
    }
    out = (int)v;
    return true;
}

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

    int t = 0;
    try {
        t = inf.readInt(1, 1000, "t");
    } catch (...) {
        query_limit = 0;
        log_metrics();
        finish(_pe, "failed to read t from inf");
    }

    vector<TestCase> tests;
    tests.reserve(t);

    long long sum_n = 0;
    for (int tc = 0; tc < t; tc++) {
        TestCase cs;
        try {
            cs.n = inf.readInt(3, 100, "n");
        } catch (...) {
            query_limit = 0;
            log_metrics();
            finish(_pe, "failed to read n from inf");
        }
        sum_n += cs.n;
        cs.reach.assign(cs.n + 1, vector<unsigned char>(cs.n + 1, 0));

        for (int j = 2; j <= cs.n; j++) {
            string s;
            try {
                s = inf.readToken();
            } catch (...) {
                query_limit = 0;
                log_metrics();
                finish(_pe, "failed to read reachability row from inf");
            }
            if ((int)s.size() != j - 1) {
                query_limit = 0;
                log_metrics();
                finish(_pe, "invalid reachability row length in inf");
            }
            for (int i = 1; i < j; i++) {
                char c = s[i - 1];
                if (c != '0' && c != '1') {
                    query_limit = 0;
                    log_metrics();
                    finish(_pe, "invalid reachability character in inf");
                }
                cs.reach[i][j] = (unsigned char)(c == '1');
            }
        }

        tests.push_back(std::move(cs));
    }

    if (sum_n > 1000) {
        query_limit = 0;
        log_metrics();
        finish(_pe, "sum of n exceeds constraints");
    }

    query_limit = 2LL * sum_n;

    log_metrics();

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

    cout << t << "\n" << flush;

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

        cout << n << "\n" << flush;

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

            if (cmd == "?") {
                string si, sj;
                if (!readTokenFromContestant(si) || !readTokenFromContestant(sj)) {
                    finish(_pe, "malformed query: missing i or j");
                }
                int i = 0, j = 0;
                if (!parseNonNegInt(si, i) || !parseNonNegInt(sj, j)) {
                    finish(_pe, "malformed query: i/j not integers");
                }
                if (!(1 <= i && i < j && j <= n)) {
                    finish(_pe, "invalid query indices");
                }

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

                cout << (cs.reach[i][j] ? "YES" : "NO") << "\n" << flush;
            } else if (cmd == "!") {
                vector<int> color(n + 1, -1);
                for (int v = 1; v <= n; v++) {
                    string sc;
                    if (!readTokenFromContestant(sc)) {
                        finish(_pe, "malformed answer: missing colors");
                    }
                    int c = 0;
                    if (!parseNonNegInt(sc, c) || !(c == 0 || c == 1)) {
                        finish(_pe, "malformed answer: colors must be 0/1");
                    }
                    color[v] = c;
                }

                for (int i = 1; i <= n; i++) {
                    for (int j = i + 1; j <= n; j++) {
                        if (color[i] == color[j] && cs.reach[i][j] == 0) {
                            finish(_wa, "invalid coloring");
                        }
                    }
                }

                break;
            } else {
                finish(_pe, "unexpected token from contestant");
            }
        }
    }

    finish(_ok, "ok");
}

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

static vector<int> make_two_chain_labels(int n, int a0) {
    a0 = max(1, min(n - 1, a0));
    int a1 = n - a0;
    int rem0 = a0, rem1 = a1;
    int cur = rnd.next(0, 1);
    vector<int> lab;
    lab.reserve(n);
    while ((int)lab.size() < n) {
        if (cur == 0 && rem0 == 0) cur = 1;
        if (cur == 1 && rem1 == 0) cur = 0;
        int &rem = (cur == 0 ? rem0 : rem1);
        int maxRun = min(4, rem);
        int runLen = rnd.next(1, maxRun);
        for (int k = 0; k < runLen; k++) lab.push_back(cur);
        rem -= runLen;
        cur ^= 1;
    }
    return lab;
}

static vector<int> make_perm_from_two_chains(int n, const vector<int>& labels, bool layeredValues) {
    int a0 = 0;
    for (int x : labels) a0 += (x == 0);
    int a1 = n - a0;

    vector<int> values0, values1;
    values0.reserve(a0);
    values1.reserve(a1);

    if (layeredValues) {
        for (int v = n - a0 + 1; v <= n; v++) values0.push_back(v);
        for (int v = 1; v <= n - a0; v++) values1.push_back(v);
    } else {
        vector<int> all(n);
        iota(all.begin(), all.end(), 1);
        for (int i = n - 1; i >= 1; i--) {
            int j = rnd.next(0, i);
            swap(all[i], all[j]);
        }
        for (int i = 0; i < a0; i++) values0.push_back(all[i]);
        for (int i = a0; i < n; i++) values1.push_back(all[i]);
        sort(values0.begin(), values0.end());
        sort(values1.begin(), values1.end());
    }

    int p0 = 0, p1 = 0;
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        if (labels[i] == 0) p[i] = values0[p0++];
        else p[i] = values1[p1++];
    }
    return p;
}

static bool is_321_avoiding(const vector<int>& p) {
    int n = (int)p.size();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) if (p[i] > p[j]) {
            for (int k = j + 1; k < n; k++) {
                if (p[j] > p[k]) return false;
            }
        }
    }
    return true;
}

static vector<int> pair_swap_perm(int n) {
    vector<int> p;
    p.reserve(n);
    for (int i = 1; i <= n; i += 2) {
        if (i + 1 <= n) {
            p.push_back(i + 1);
            p.push_back(i);
        } else {
            p.push_back(i);
        }
    }
    return p;
}

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

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

    int n = opt<int>("n", -1);
    if (n == -1) {
        if (seed == 1) n = 3;
        else n = 100;
    }
    n = max(3, min(100, n));

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

    if (mode != "non" && mode != "adp") return 0;

    vector<int> p;
    if (seed == 1) {
        if (n == 3) p = {2, 1, 3};
        else p = pair_swap_perm(n);
    } else if (seed == 2) {
        p.resize(n);
        iota(p.begin(), p.end(), 1);
    } else if (seed == 3) {
        int k = n / 2;
        p.clear();
        for (int v = k + 1; v <= n; v++) p.push_back(v);
        for (int v = 1; v <= k; v++) p.push_back(v);
    } else {
        int a0 = n / 2 + rnd.next(-max(0, n / 10), max(0, n / 10));
        auto labels = make_two_chain_labels(n, a0);

        int variant = rnd.next(0, 2);
        if (variant == 0) {
            p = pair_swap_perm(n);
        } else if (variant == 1) {
            bool layered = true;
            p = make_perm_from_two_chains(n, labels, layered);
        } else {
            bool layered = (rnd.next(0, 1) == 1);
            p = make_perm_from_two_chains(n, labels, layered);
        }

        if (!is_321_avoiding(p)) {
            p = pair_swap_perm(n);
        }
    }

    for (int j = 2; j <= n; j++) {
        string s;
        s.reserve(j - 1);
        for (int i = 1; i < j; i++) {
            s.push_back((p[i - 1] < p[j - 1]) ? '1' : '0');
        }
        cout << s << "\n";
    }

    return 0;
}


Innovative Computable Quality Control (ICQC) has developed a ground-breaking new machine for performing, well, quality control. Thanks to its novel Deep Intelligence technology, an ICQC quality control (QC) machine can automatically, with $1 0 0 \%$ accuracy, detect manufacturing errors in any machine in existence, whether it is a coffee machine, an intergalactic space ship, or a quantum computer.

ICQC is now setting up its factory for producing these QC machines. Like any other manufacturing process, some fraction of the produced machines will suffer from malfunctions and these need to be found and discarded. Fortunately, ICQC has just the product for detecting malfunctioning machines!

Obviously, ICQC should not simply use a QC machine on itself, since a malfunctioning machine might incorrectly classify itself as working correctly. Instead, ICQC will take each batch of $n$ machines produced during a day and have them test each other overnight. In particular, during every hour of the night, each of the $n$ QC machines can run a check on one of the other QC machines, and simultaneously be checked by one other QC machine.

If the machine running the check is correct, it will correctly report whether the tested machine is correct or malfunctioning, but if the machine running the check is malfunctioning, it may report either result. If a machine A is used to test a machine B multiple times it will return the same result every time, even if machine A is malfunctioning. The exact testing schedule does not have to be fixed in advance, so the choice of which machines should check which other machines during the second hour of the night may be based on the result of the tests from the first hour, and so on.

ICQC are $1 0 0 \%$ confident that strictly more than a half of the $n$ QC machines in each batch are working correctly, but the night is only 12 hours long, so there is only time to do a small number of test rounds. Can you help ICQC determine which QC machines are malfunctioning?

For example, consider Sample Interaction 1 below. After the fourth hour, every machine has tested every other machine. For machine 1, only one other machine claimed that it was malfunctioning, and if it was truly malfunctioning then at least 3 of the other machines would claim this. For machine 4, only one other machine claims that it is working, which implies that machine 2 must be malfunctioning since more than half of the machines are supposed to be working. Note that even though machine 4 is malfunctioning, it still happened to produce the correct responses in these specific test rounds.

# Interaction

The first line of input contains a single integer $b$ $( 1 \leq b \leq 5 0 0 )$ , the number of batches to follow. Each batch is independent. You should process each batch interactively, which means the input you receive will depend on the previous output of your program.

The first line of input for each batch contains a single integer $n$ $1 \leq n \leq 1 0 0 )$ , the number of QC machines in the batch. The interaction then proceeds in rounds. In each round, your program can schedule tests for the next hour, by writing a line of the form “test $x _ { 1 } x _ { 2 } \dots x _ { n } { } ^ { \prime }$ indicating that each machine $i$ should run a test on machine $x _ { i }$ . If $x _ { i } = 0$ , then machine $i$ is idle in that round and performs no test. All positive numbers in the sequence must be distinct.

After writing this line, there will be a result to read from the input. The result is one line containing a string of length $n$ , having a $\cdot _ { 1 } ,$ in position $i$ if machine $i$ says that machine $x _ { i }$ is working correctly, ‘0’ if machine $i$ says that machine $x _ { i }$ is malfunctioning, and $^ \ast - \ast$ (dash) if machine $i$ was idle in the round.

When your program has determined which machines are malfunctioning, but no later than after 12 rounds of tests, it must write a line of the form “answer $S ^ { \ast }$ where $S$ is a binary string of length $n$ , having a $\cdot _ { 1 } ,$ in position $i$ if machine $i$ is working correctly, and a $\bullet _ { 0 } ,$ if it is malfunctioning.

After writing the answer line, your program should start processing the next batch by reading its number $n$ . When all $b$ batches have been processed, the interaction ends and your program should exit.

Notes on interactive judging:

• The evaluation is non-adversarial, meaning that the result of each machine testing each other machine is chosen in advance rather than in response to your queries. • Do not forget to flush output buffers after writing. See the Addendum to Judging Notes for details. • You are provided with a command-line tool for local testing, together with input files corresponding to the sample interactions. The tool has comments at the top to explain its use.

![](images/57f6d7d3d691f15efa5bc0a1480e19c20f2589bf9755c898970f76905de255d2.jpg)

![](images/ae2797b206e33e589c778b6cf982c78ef0146b5e18eb2f643dc25602c91b0dc9.jpg)

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

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

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

    }
}

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

static void check_hard_cap() {
    if (queries > 200000) {
        finish(_pe, "Hard query limit exceeded (potential infinite loop)");
    }
}

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

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

    int b = inf.readInt();

    query_limit = (long long)b * 12;
    log_metrics();

    cout << b << endl;

    for (int batch = 1; batch <= b; batch++) {

        int n = inf.readInt();
        string S_truth = inf.readToken();

        vector<string> matrix(n);
        for (int i = 0; i < n; i++) {
            matrix[i] = inf.readToken();
        }

        cout << n << endl;

        int rounds_used = 0;
        bool batch_finished = false;

        while (!batch_finished) {
            check_hard_cap();

            string cmd;

            if (!(cin >> cmd)) {
                finish(_wa, "Unexpected EOF while reading command");
            }

            if (cmd == "test") {

                rounds_used++;
                queries++;
                log_metrics();

                vector<int> x(n);
                vector<int> target_counts(n + 1, 0);

                for (int i = 0; i < n; i++) {
                    if (!(cin >> x[i])) {
                        finish(_wa, "Unexpected EOF or invalid format reading test arguments");
                    }
                }

                for (int i = 0; i < n; i++) {
                    int tester = i + 1;
                    int target = x[i];

                    if (target < 0 || target > n) {
                        finish(_wa, format("Batch %d: Machine %d targeting invalid index %d", batch, tester, target));
                    }

                    if (target != 0) {

                        if (target == tester) {
                            finish(_wa, format("Batch %d: Machine %d cannot test itself", batch, tester));
                        }

                        target_counts[target]++;
                        if (target_counts[target] > 1) {
                            finish(_wa, format("Batch %d: Machine %d is targeted by multiple machines", batch, target));
                        }
                    }
                }

                string response = "";
                for (int i = 0; i < n; i++) {
                    int target = x[i];
                    if (target == 0) {
                        response += "-";
                    } else {

                        response += matrix[i][target - 1];
                    }
                }

                cout << response << endl;

            } else if (cmd == "answer") {
                string ans;
                if (!(cin >> ans)) {
                    finish(_wa, "Unexpected EOF reading answer string");
                }

                if (ans.length() != (size_t)n) {
                    finish(_wa, format("Batch %d: Answer length %d does not match n=%d", batch, (int)ans.length(), n));
                }
                for (char c : ans) {
                    if (c != '0' && c != '1') {
                        finish(_wa, "Answer must contain only '0' and '1'");
                    }
                }

                if (ans != S_truth) {
                    finish(_wa, format("Batch %d: Wrong answer", batch));
                }

                if (rounds_used > 12) {
                    finish(_wa, format("Batch %d: Round limit exceeded (used %d, max 12)", batch, rounds_used));
                }

                batch_finished = true;

            } else {
                finish(_wa, "Unknown command: " + cmd);
            }
        }
    }

    finish(_ok, "All batches 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 b_arg = opt<int>("b", -1);

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

    int b;
    if (b_arg != -1) {
        b = b_arg;
    } else {

        if (seed_val == 1) b = 10;
        else if (seed_val == 2) b = 5;
        else if (seed_val == 3) b = 5;
        else b = rnd.next(5, 20);
    }

    if (b < 1) b = 1;
    if (b > 500) b = 500;

    cout << b << endl;

    for (int k = 0; k < b; k++) {
        int n;
        if (seed_val == 1) {

            n = (k % 10) + 1;
        } else if (seed_val == 2 || seed_val == 3) {

            n = 100;
        } else {

            if (rnd.next(3) == 0) n = rnd.next(1, 20);
            else n = rnd.next(20, 100);
        }

        int min_honest = n / 2 + 1;
        int honest_count;

        if (seed_val == 2) {

            honest_count = min_honest;
        } else {

            if (rnd.next(2) == 0)
                honest_count = min_honest + rnd.next(0, max(0, (n - min_honest) / 4));
            else
                honest_count = rnd.next(min_honest, n);
        }

        string S(n, '0');
        vector<int> p(n);
        iota(p.begin(), p.end(), 0);
        shuffle(p.begin(), p.end());

        for (int i = 0; i < honest_count; i++) S[p[i]] = '1';

        cout << n << endl;
        cout << S << endl;

        if (mode == "non") {

            int strategy = rnd.next(5);
            if (seed_val == 2) strategy = 1;

            for (int i = 0; i < n; i++) {
                string row = "";
                if (S[i] == '1') {

                    for (int j = 0; j < n; j++) row += S[j];
                } else {

                    int s = (strategy == 4) ? rnd.next(4) : strategy;
                    for (int j = 0; j < n; j++) {
                        char c;
                        if (s == 0) {
                            c = rnd.next(2) ? '1' : '0';
                        } else if (s == 1) {
                            c = (S[j] == '1' ? '0' : '1');
                        } else if (s == 2) {
                            c = '1';
                        } else {
                            c = '0';
                        }
                        row += c;
                    }
                }
                cout << row << endl;
            }
        }
    }

    return 0;
}