There is a hidden tree with $n$ vertices. The $n-1$ edges of the tree are numbered from $1$ to $n-1$. You can ask the following queries of two types:

1. Give the grader an array $a$ with $n - 1$ positive integers. For each edge from $1$ to $n - 1$, the weight of edge $i$ is set to $a_i$. Then, the grader will return the length of the diameter$^\dagger$.
2. Give the grader two indices $1 \le a, b \le n - 1$. The grader will return the number of edges between edges $a$ and $b$. In other words, if edge $a$ connects $u_a$ and $v_a$ while edge $b$ connects $u_b$ and $v_b$, the grader will return $\min(\text{dist}(u_a, u_b), \text{dist}(v_a, u_b), \text{dist}(u_a, v_b), \text{dist}(v_a, v_b))$, where $\text{dist}(u, v)$ represents the number of edges on the path between vertices $u$ and $v$.

Find any tree isomorphic$^\ddagger$ to the hidden tree after at most $n$ queries of type 1 and $n$ queries of type 2 in any order.

$^\dagger$ The distance between two vertices is the sum of the weights on the unique simple path that connects them. The diameter is the largest of all those distances.

$^\ddagger$ Two trees, consisting of $n$ vertices each, are called isomorphic if there exists a permutation $p$ containing integers from $1$ to $n$ such that edge ($u$, $v$) is present in the first tree if and only if the edge ($p_u$, $p_v$) is present in the second tree.

Input

The first and only line of input contains a single integer $n$ ($3 \le n \le 1000$) — the number of vertices in the tree.

Interaction

Begin the interaction by reading $n$.

You are allowed to make queries in the following way:

1. "$\mathtt{?}\,1\,a_1\,a_2 \ldots a_{n-1}$" ($1 \le a_i \le 10^9$). Then, you should read an integer $k$ which represents the length of the diameter. You are only allowed to ask this query at most $n$ times.
2. "$\mathtt{?}\,2\,a\,b$" ($1 \le a, b \le n - 1$). Then, you should read an integer $k$ which represents the number of edges between edges $a$ and $b$. You are only allowed to ask this query at most $n$ times.

In case your query is invalid. the program will terminate immediately and you will receive Wrong answer verdict.

To give the final answer, print "!" on a single line, followed by $n - 1$ lines where line $i$ contains "$u_i\,v_i$" ($1 \le u_i, v_i \le n$) which represents that for each $i$ from $1$ to $n-1$, there is an edge between $u_i$ and $v_i$.

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

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

Example

Input

```
5

3

1

9

0
```

Output

```
? 1 1 1 1 1

? 2 1 3

? 1 4 3 2 1

? 2 4 2

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

Note

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

The hidden tree in the example is shown above. The number on the vertices represents the vertex number while the number on the edges represents the edge number.

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

In the first query, all the edges are set to weight $1$, so the diameter has length $3$ as shown in the diagram.

In the second query, there is $1$ edge between edges $1$ and $3$.

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

In the third query, the diameter is $9$ by taking edges $1$, $2$ and $3$.

In the fourth query, there are no edges between edges $4$ and $2$.

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

The answer given in the example is shown in the above diagram. Since it is isomorphic to the hidden tree, it is accepted as a correct answer. Note that the edges can be printed in any order.

#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 DSU {
    vector<int> p, r;
    DSU(int n = 0) { init(n); }
    void init(int n) {
        p.resize(n + 1);
        r.assign(n + 1, 0);
        iota(p.begin(), p.end(), 0);
    }
    int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }
    bool unite(int a, int b) {
        a = find(a); b = find(b);
        if (a == b) return false;
        if (r[a] < r[b]) swap(a, b);
        p[b] = a;
        if (r[a] == r[b]) r[a]++;
        return true;
    }
};

static vector<int> find_centers(const vector<vector<int>>& adj) {
    int n = (int)adj.size() - 1;
    vector<int> deg(n + 1, 0);
    queue<int> q;
    for (int i = 1; i <= n; i++) {
        deg[i] = (int)adj[i].size();
        if (deg[i] <= 1) q.push(i);
    }
    int remaining = n;
    while (remaining > 2) {
        int sz = (int)q.size();
        if (sz == 0) break;
        remaining -= sz;
        for (int it = 0; it < sz; it++) {
            int u = q.front(); q.pop();
            deg[u] = 0;
            for (int v : adj[u]) {
                if (deg[v] == 0) continue;
                deg[v]--;
                if (deg[v] == 1) q.push(v);
            }
        }
    }
    vector<int> centers;
    while (!q.empty()) { centers.push_back(q.front()); q.pop(); }
    if (centers.empty()) centers.push_back(1);
    sort(centers.begin(), centers.end());
    centers.erase(unique(centers.begin(), centers.end()), centers.end());
    if ((int)centers.size() > 2) centers.resize(2);
    return centers;
}

static string encode_rooted(int u, int p, const vector<vector<int>>& adj) {
    vector<string> subs;
    subs.reserve(adj[u].size());
    for (int v : adj[u]) if (v != p) subs.push_back(encode_rooted(v, u, adj));
    sort(subs.begin(), subs.end());
    string res;
    res.reserve(2 + 2 * subs.size());
    res.push_back('(');
    for (auto& s : subs) res += s;
    res.push_back(')');
    return res;
}

static string canonical_form(const vector<vector<int>>& adj) {
    auto centers = find_centers(adj);
    if ((int)centers.size() == 1) return encode_rooted(centers[0], 0, adj);
    string a = encode_rooted(centers[0], centers[1], adj);
    string b = encode_rooted(centers[1], centers[0], adj);

    if (a > b) swap(a, b);
    return string("(") + a + b + ")";
}

static void build_lca(const vector<vector<pair<int,int>>>& adj,
                      vector<vector<int>>& up,
                      vector<int>& depth) {
    int n = (int)adj.size() - 1;
    int LOG = (int)up.size();
    depth.assign(n + 1, 0);
    vector<int> parent(n + 1, 0);

    stack<pair<int,int>> st;
    st.push({1, 1});
    parent[1] = 1;
    depth[1] = 0;

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

    while (!st.empty()) {
        auto [u, p] = st.top();
        st.pop();
        parent[u] = p;
        for (auto [v, idx] : adj[u]) {
            (void)idx;
            if (v == p) continue;
            if (vis[v]) continue;
            vis[v] = 1;
            depth[v] = depth[u] + 1;
            st.push({v, u});
        }
    }

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

static int lca(int a, int b, const vector<vector<int>>& up, const vector<int>& depth) {
    if (depth[a] < depth[b]) swap(a, b);
    int LOG = (int)up.size();
    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 int dist_edges(int a, int b, const vector<vector<int>>& up, const vector<int>& depth) {
    int c = lca(a, b, up, depth);
    return depth[a] + depth[b] - 2 * depth[c];
}

static pair<int,long long> farthest_from(int start,
                                        const vector<vector<pair<int,int>>>& adj,
                                        const vector<long long>& w) {
    int n = (int)adj.size() - 1;
    vector<long long> dist(n + 1, LLONG_MIN);
    dist[start] = 0;
    stack<int> st;
    st.push(start);

    while (!st.empty()) {
        int u = st.top();
        st.pop();
        for (auto [v, idx] : adj[u]) {
            if (dist[v] != LLONG_MIN) continue;
            dist[v] = dist[u] + w[idx];
            st.push(v);
        }
    }

    int bestV = start;
    long long bestD = 0;
    for (int i = 1; i <= n; i++) {
        if (dist[i] > bestD) {
            bestD = dist[i];
            bestV = i;
        }
    }
    return {bestV, bestD};
}

static long long weighted_diameter(const vector<vector<pair<int,int>>>& adj,
                                  const vector<long long>& w) {
    auto p1 = farthest_from(1, adj, w);
    auto p2 = farthest_from(p1.first, adj, w);
    return p2.second;
}

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

    int n = inf.readInt();
    if (n < 3 || n > 1000) finish(_pe, "Hidden n out of range");

    vector<int> eu(n), ev(n);
    vector<vector<pair<int,int>>> adjHidden(n + 1);
    vector<vector<int>> adjHiddenUnw(n + 1);

    for (int i = 1; i <= n - 1; i++) {
        int u = inf.readInt();
        int v = inf.readInt();
        if (u < 1 || u > n || v < 1 || v > n || u == v) finish(_pe, "Bad hidden edge");
        eu[i] = u;
        ev[i] = v;
        adjHidden[u].push_back({v, i});
        adjHidden[v].push_back({u, i});
        adjHiddenUnw[u].push_back(v);
        adjHiddenUnw[v].push_back(u);
    }

    query_limit = 2LL * n;
    log_metrics();

    int LOG = 1;
    while ((1 << LOG) <= n) LOG++;
    vector<vector<int>> up(LOG, vector<int>(n + 1, 1));
    vector<int> depth;
    build_lca(adjHidden, up, depth);

    string hiddenCanon = canonical_form(adjHiddenUnw);

    cout << n << endl;

    long long hard_cap = max(200000LL, 10LL * query_limit);
    vector<long long> w(n, 1);

    while (true) {
        string cmd;
        if (!(cin >> cmd)) finish(_pe, "EOF before final answer");

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

            int type;
            if (!(cin >> type)) finish(_pe, "Missing query type");

            if (type == 1) {
                for (int i = 1; i <= n - 1; i++) {
                    long long ai;
                    if (!(cin >> ai)) finish(_pe, "Missing weight");
                    if (ai < 1 || ai > 1000000000LL) finish(_pe, "Weight out of range");
                    w[i] = ai;
                }
                long long ans = weighted_diameter(adjHidden, w);
                cout << ans << endl;
            } else if (type == 2) {
                int a, b;
                if (!(cin >> a >> b)) finish(_pe, "Missing edge indices");
                if (a < 1 || a > n - 1 || b < 1 || b > n - 1) finish(_pe, "Edge index out of range");

                int ua = eu[a], va = ev[a];
                int ub = eu[b], vb = ev[b];

                int d1 = dist_edges(ua, ub, up, depth);
                int d2 = dist_edges(ua, vb, up, depth);
                int d3 = dist_edges(va, ub, up, depth);
                int d4 = dist_edges(va, vb, up, depth);
                int ans = min(min(d1, d2), min(d3, d4));
                cout << ans << endl;
            } else {
                finish(_pe, "Unknown query type");
            }

        } else if (cmd == "!") {
            vector<vector<int>> adjOut(n + 1);
            DSU dsu(n);
            for (int i = 1; i <= n - 1; i++) {
                int u, v;
                if (!(cin >> u >> v)) finish(_pe, "Missing final edges");
                if (u < 1 || u > n || v < 1 || v > n) finish(_pe, "Final vertex out of range");
                if (u == v) finish(_wa, "Self-loop in final answer");
                adjOut[u].push_back(v);
                adjOut[v].push_back(u);
                if (!dsu.unite(u, v)) finish(_wa, "Cycle in final answer");
            }

            int root = dsu.find(1);
            for (int i = 2; i <= n; i++) {
                if (dsu.find(i) != root) finish(_wa, "Disconnected final answer");
            }

            string outCanon = canonical_form(adjOut);
            if (outCanon != hiddenCanon) finish(_wa, "Final tree is not isomorphic");

            finish(_ok, "OK");
        } else {
            finish(_pe, "Unknown command token");
        }
    }
}

#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 DetRng {
    uint64_t x;
    explicit DetRng(uint64_t seed = 88172645463325252ull) : x(seed ? seed : 88172645463325252ull) {}
    uint64_t nextU64() {
        x ^= x >> 12;
        x ^= x << 25;
        x ^= x >> 27;
        return x * 2685821657736338717ull;
    }
    int nextInt(int l, int r) {
        uint64_t span = (uint64_t)(r - l + 1);
        return l + (int)(nextU64() % span);
    }
};

static uint64_t mix64(uint64_t a) {
    a += 0x9e3779b97f4a7c15ull;
    a = (a ^ (a >> 30)) * 0xbf58476d1ce4e5b9ull;
    a = (a ^ (a >> 27)) * 0x94d049bb133111ebull;
    a = a ^ (a >> 31);
    return a;
}

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

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

static bool readIntStrict(int& x) {
    long long t;
    if (!(cin >> t)) return false;
    if (t < INT_MIN || t > INT_MAX) return false;
    x = (int)t;
    return true;
}

static string rooted_encode(int u, int p, const vector<vector<int>>& g) {
    vector<string> child;
    child.reserve(g[u].size());
    for (int v : g[u]) if (v != p) child.push_back(rooted_encode(v, u, g));
    sort(child.begin(), child.end());
    string res;
    res.reserve(2 + 2 * (int)child.size());
    res.push_back('(');
    for (auto& s : child) res += s;
    res.push_back(')');
    return res;
}

static string tree_canonical_form(int n, const vector<pair<int,int>>& edges) {
    vector<vector<int>> g(n + 1);
    g.reserve(n + 1);
    vector<int> deg(n + 1, 0);
    for (auto [u, v] : edges) {
        g[u].push_back(v);
        g[v].push_back(u);
        deg[u]++; deg[v]++;
    }
    if (n == 1) return "()";
    deque<int> q;
    for (int i = 1; i <= n; i++) if (deg[i] <= 1) q.push_back(i);
    int remaining = n;
    while (remaining > 2) {
        int sz = (int)q.size();
        remaining -= sz;
        for (int i = 0; i < sz; i++) {
            int u = q.front(); q.pop_front();
            deg[u] = 0;
            for (int v : g[u]) {
                if (deg[v] > 0) {
                    deg[v]--;
                    if (deg[v] == 1) q.push_back(v);
                }
            }
        }
    }
    vector<int> centers;
    while (!q.empty()) {
        centers.push_back(q.front());
        q.pop_front();
    }
    if (centers.empty()) centers.push_back(1);
    if ((int)centers.size() == 1) {
        return rooted_encode(centers[0], 0, g);
    } else {
        string a = rooted_encode(centers[0], 0, g);
        string b = rooted_encode(centers[1], 0, g);
        return min(a, b);
    }
}

struct Candidate {
    int n = 0;
    int m = 0;
    vector<pair<int,int>> edges;
    vector<int> eu, ev;
    vector<vector<pair<int,int>>> adj;
    int LOG = 0;
    vector<int> depth;
    vector<vector<int>> up;
    string canon;

    void build(int n_, const vector<pair<int,int>>& edges0) {
        n = n_;
        edges = edges0;
        m = (int)edges.size();
        eu.assign(m + 1, 0);
        ev.assign(m + 1, 0);
        adj.assign(n + 1, {});
        for (int i = 1; i <= m; i++) {
            int u = edges[i - 1].first;
            int v = edges[i - 1].second;
            eu[i] = u; ev[i] = v;
            adj[u].push_back({v, i});
            adj[v].push_back({u, i});
        }
        LOG = 1;
        while ((1 << LOG) <= n) LOG++;
        depth.assign(n + 1, 0);
        up.assign(LOG, vector<int>(n + 1, 0));

        vector<int> parent(n + 1, 0);
        vector<int> st;
        st.reserve(n);
        st.push_back(1);
        parent[1] = 1;
        depth[1] = 0;
        while (!st.empty()) {
            int u = st.back();
            st.pop_back();
            up[0][u] = parent[u];
            for (auto [v, eid] : adj[u]) {
                if (v == parent[u]) continue;
                parent[v] = u;
                depth[v] = depth[u] + 1;
                st.push_back(v);
            }
        }
        for (int k = 1; k < LOG; k++) {
            for (int v = 1; v <= n; v++) {
                up[k][v] = up[k - 1][ up[k - 1][v] ];
            }
        }
        canon = tree_canonical_form(n, edges);
    }

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

    int distV(int a, int b) const {
        int c = lca(a, b);
        return depth[a] + depth[b] - 2 * depth[c];
    }

    int edgeEdgeDist(int ea, int eb) const {
        int a1 = eu[ea], a2 = ev[ea];
        int b1 = eu[eb], b2 = ev[eb];
        int d = distV(a1, b1);
        d = min(d, distV(a1, b2));
        d = min(d, distV(a2, b1));
        d = min(d, distV(a2, b2));
        return d;
    }

    pair<int, long long> farthestFrom(int src, const vector<long long>& w) const {
        vector<long long> dist(n + 1, LLONG_MIN / 4);
        vector<int> parent(n + 1, 0);
        vector<int> st;
        st.reserve(n);
        dist[src] = 0;
        parent[src] = src;
        st.push_back(src);
        while (!st.empty()) {
            int u = st.back();
            st.pop_back();
            for (auto [v, eid] : adj[u]) {
                if (v == parent[u]) continue;
                parent[v] = u;
                dist[v] = dist[u] + w[eid];
                st.push_back(v);
            }
        }
        int bestV = src;
        long long bestD = dist[src];
        for (int i = 1; i <= n; i++) {
            if (dist[i] > bestD) {
                bestD = dist[i];
                bestV = i;
            }
        }
        return {bestV, bestD};
    }

    long long diameter(const vector<long long>& w) const {
        auto p1 = farthestFrom(1, w);
        auto p2 = farthestFrom(p1.first, w);
        return p2.second;
    }
};

static vector<pair<int,int>> makePath(int n) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 1; i + 1 <= n; i++) e.push_back({i, i + 1});
    return e;
}

static vector<pair<int,int>> makeStar(int n) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 2; i <= n; i++) e.push_back({1, i});
    return e;
}

static vector<pair<int,int>> makeCompleteBinary(int n) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 2; i <= n; i++) e.push_back({i / 2, i});
    return e;
}

static void buildFixedBinarySubtree(vector<pair<int,int>>& e, int start, int sz) {
    for (int i = 1; i < sz; i++) {
        int v = start + i;
        int parent = start + (i - 1) / 2;
        e.push_back({parent, v});
    }
}

static vector<pair<int,int>> makeSymmetricTwoSubtrees(int n) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    int root = 1;
    int m = (n - 1) / 2;
    int s1 = 2;
    int s2 = 2 + m;

    e.push_back({root, s1});
    e.push_back({root, s2});
    buildFixedBinarySubtree(e, s1, m);
    buildFixedBinarySubtree(e, s2, m);

    if (n % 2 == 0) {
        int leftover = 2 + 2 * m;
        if (leftover <= n) e.push_back({root, leftover});
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeDoubleStarWithBridge(int n, int bridgeLenEdges) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    if (n == 3) return makePath(n);
    bridgeLenEdges = max(1, min(bridgeLenEdges, n - 2));

    int centerA = 1;
    int nextNode = 2;
    int last = centerA;

    for (int i = 0; i < bridgeLenEdges - 1; i++) {
        int cur = nextNode++;
        e.push_back({last, cur});
        last = cur;
    }
    int centerB = nextNode++;
    e.push_back({last, centerB});

    int used = nextNode - 1;
    int remaining = n - used;
    int leavesA = remaining / 2;
    int leavesB = remaining - leavesA;

    for (int i = 0; i < leavesA; i++) e.push_back({centerA, nextNode++});
    for (int i = 0; i < leavesB; i++) e.push_back({centerB, nextNode++});

    while ((int)e.size() < n - 1 && nextNode <= n) {
        e.push_back({(int)e.size() % 2 ? centerA : centerB, nextNode++});
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeSpiderEqualArms(int n, int arms) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    int center = 1;
    int k = max(1, min(arms, n - 1));
    int total = n - 1;
    int base = total / k;
    int rem = total % k;

    int nextNode = 2;
    for (int a = 0; a < k; a++) {
        int len = base + (a < rem ? 1 : 0);
        int last = center;
        for (int i = 0; i < len; i++) {
            int cur = nextNode++;
            e.push_back({last, cur});
            last = cur;
        }
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeCaterpillar(int n, int spineLen) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    spineLen = max(2, min(spineLen, n));
    for (int i = 1; i < spineLen; i++) e.push_back({i, i + 1});
    int nextNode = spineLen + 1;
    int attach = 1;
    while (nextNode <= n) {
        e.push_back({attach, nextNode});
        nextNode++;
        attach++;
        if (attach > spineLen) attach = 1;
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeRandomTreePruferDet(int n, uint64_t seed) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    if (n <= 1) return e;
    if (n == 2) return vector<pair<int,int>>{{1, 2}};
    DetRng rng(mix64(seed));
    vector<int> prufer(n - 2);
    for (int i = 0; i < n - 2; i++) prufer[i] = rng.nextInt(1, n);

    vector<int> deg(n + 1, 1);
    for (int x : prufer) deg[x]++;

    priority_queue<int, vector<int>, greater<int>> pq;
    for (int i = 1; i <= n; i++) if (deg[i] == 1) pq.push(i);

    for (int x : prufer) {
        int leaf = pq.top(); pq.pop();
        e.push_back({leaf, x});
        deg[leaf]--;
        deg[x]--;
        if (deg[x] == 1) pq.push(x);
    }
    int a = pq.top(); pq.pop();
    int b = pq.top(); pq.pop();
    e.push_back({a, b});
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static void shuffleEdgesDet(vector<pair<int,int>>& e, uint64_t seed) {
    DetRng rng(mix64(seed));
    for (int i = 0; i < (int)e.size(); i++) {
        int j = rng.nextInt(i, (int)e.size() - 1);
        swap(e[i], e[j]);
    }
}

static vector<Candidate> buildCandidates(int n, const vector<pair<int,int>>* fixedEdges) {
    vector<Candidate> cand;
    if (fixedEdges) {
        Candidate c;
        c.build(n, *fixedEdges);
        cand.push_back(std::move(c));
        return cand;
    }

    struct Shape { vector<pair<int,int>> edges; int variants; uint64_t salt; };
    vector<Shape> shapes;

    shapes.push_back({makePath(n), 3, 0x1111});
    shapes.push_back({makeStar(n), 3, 0x2222});
    shapes.push_back({makeCompleteBinary(n), 3, 0x3333});
    shapes.push_back({makeSymmetricTwoSubtrees(n), 3, 0x4444});
    shapes.push_back({makeCaterpillar(n, max(2, n / 3)), 3, 0x5555});
    shapes.push_back({makeCaterpillar(n, max(2, n / 2)), 3, 0x6666});
    shapes.push_back({makeCaterpillar(n, max(2, (2 * n) / 3)), 3, 0x7777});
    shapes.push_back({makeSpiderEqualArms(n, 3), 3, 0x8888});
    shapes.push_back({makeSpiderEqualArms(n, 5), 3, 0x9999});
    shapes.push_back({makeSpiderEqualArms(n, min(12, max(2, n - 1))), 3, 0xaaaa});
    for (int bl : {1, 2, 3, 5, 10, 20, 37}) {
        if (bl <= n - 2) shapes.push_back({makeDoubleStarWithBridge(n, bl), 3, (uint64_t)0xbbbb + (uint64_t)bl});
    }
    for (int s = 1; s <= 10; s++) {
        shapes.push_back({makeRandomTreePruferDet(n, 0xdeadbeefULL ^ (uint64_t)s), 1, 0xcccc + (uint64_t)s});
    }

    cand.reserve(80);
    for (int si = 0; si < (int)shapes.size(); si++) {
        auto base = shapes[si].edges;
        if ((int)base.size() != n - 1) base = makePath(n);
        for (int v = 0; v < shapes[si].variants; v++) {
            auto e = base;
            uint64_t seed = mix64((uint64_t)n * 1315423911ULL ^ (uint64_t)si * 97531ULL ^ (uint64_t)v * 1234567ULL ^ shapes[si].salt);
            shuffleEdgesDet(e, seed);
            Candidate c;
            c.build(n, e);
            cand.push_back(std::move(c));
        }
    }

    if ((int)cand.size() > 120) cand.resize(120);
    return cand;
}

static bool validateTreeEdges(int n, const vector<pair<int,int>>& edges, string& why) {
    if ((int)edges.size() != n - 1) {
        why = "wrong number of edges";
        return false;
    }
    vector<int> p(n + 1), r(n + 1, 0);
    iota(p.begin(), p.end(), 0);
    function<int(int)> findp = [&](int x) { return p[x] == x ? x : p[x] = findp(p[x]); };
    auto unite = [&](int a, int b) -> bool {
        a = findp(a); b = findp(b);
        if (a == b) return false;
        if (r[a] < r[b]) swap(a, b);
        p[b] = a;
        if (r[a] == r[b]) r[a]++;
        return true;
    };
    for (auto [u, v] : edges) {
        if (u < 1 || u > n || v < 1 || v > n) {
            why = "vertex out of range";
            return false;
        }
        if (u == v) {
            why = "self-loop";
            return false;
        }
        if (!unite(u, v)) {
            why = "cycle detected";
            return false;
        }
    }
    int root = findp(1);
    for (int i = 2; i <= n; i++) {
        if (findp(i) != root) {
            why = "disconnected";
            return false;
        }
    }
    return true;
}

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

    int n = inf.readInt(3, 1000, "n");

    bool hasFixed = !inf.seekEof();
    vector<pair<int,int>> fixedEdges;
    if (hasFixed) {
        fixedEdges.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");
            fixedEdges.push_back({u, v});
        }

    }

    query_limit = 2LL * n;
    log_metrics();

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

    vector<Candidate> candidates = buildCandidates(n, hasFixed ? &fixedEdges : nullptr);
    if (candidates.empty()) finish(_pe, "internal: no candidates");

    vector<int> active;
    active.reserve(candidates.size());
    for (int i = 0; i < (int)candidates.size(); i++) active.push_back(i);

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

    int m = n - 1;
    vector<long long> w(m + 1, 1);

    while (true) {
        string tok;
        if (!readToken(tok)) finish(_wa, "unexpected EOF from contestant");

        if (tok == "?") {
            int type;
            if (!readIntStrict(type)) {
                if (cin.eof()) finish(_wa, "unexpected EOF after '?'");
                finish(_pe, "bad query type token");
            }
            queries++;
            if (queries > hard_cap) finish(_pe, "too many queries (hard cap)");

            if (type == 1) {
                for (int i = 1; i <= m; i++) {
                    long long ai;
                    if (!readLongLong(ai)) {
                        if (cin.eof()) finish(_wa, "unexpected EOF in type1 weights");
                        finish(_pe, "bad weight token");
                    }
                    if (ai <= 0 || ai > 1000000000LL) finish(_pe, "weight out of range");
                    w[i] = ai;
                }

                map<long long, vector<int>> buckets;
                for (int id : active) {
                    long long ans = candidates[id].diameter(w);
                    buckets[ans].push_back(id);
                }
                if (buckets.empty()) finish(_pe, "internal: empty buckets");

                long long bestAns = buckets.begin()->first;
                size_t bestSz = buckets.begin()->second.size();
                for (auto& kv : buckets) {
                    if (kv.second.size() > bestSz) {
                        bestSz = kv.second.size();
                        bestAns = kv.first;
                    } else if (kv.second.size() == bestSz && kv.first < bestAns) {
                        bestAns = kv.first;
                    }
                }
                active = std::move(buckets[bestAns]);

                cout << bestAns << "\n";
                cout.flush();
            } else if (type == 2) {
                int a, b;
                if (!readIntStrict(a) || !readIntStrict(b)) {
                    if (cin.eof()) finish(_wa, "unexpected EOF in type2");
                    finish(_pe, "bad indices in type2");
                }
                if (a < 1 || a > m || b < 1 || b > m) finish(_pe, "edge index out of range");

                map<long long, vector<int>> buckets;
                for (int id : active) {
                    long long ans = candidates[id].edgeEdgeDist(a, b);
                    buckets[ans].push_back(id);
                }
                if (buckets.empty()) finish(_pe, "internal: empty buckets");

                long long bestAns = buckets.begin()->first;
                size_t bestSz = buckets.begin()->second.size();
                for (auto& kv : buckets) {
                    if (kv.second.size() > bestSz) {
                        bestSz = kv.second.size();
                        bestAns = kv.first;
                    } else if (kv.second.size() == bestSz && kv.first < bestAns) {
                        bestAns = kv.first;
                    }
                }
                active = std::move(buckets[bestAns]);

                cout << bestAns << "\n";
                cout.flush();
            } else {
                finish(_pe, "unknown query type");
            }
        } else if (tok == "!") {
            vector<pair<int,int>> outEdges;
            outEdges.reserve(n - 1);
            for (int i = 0; i < n - 1; i++) {
                int u, v;
                if (!readIntStrict(u) || !readIntStrict(v)) {
                    if (cin.eof()) finish(_wa, "unexpected EOF in final answer");
                    finish(_pe, "bad final edge token");
                }
                outEdges.push_back({u, v});
            }

            string why;
            if (!validateTreeEdges(n, outEdges, why)) finish(_wa, string("final answer is not a tree: ") + why);

            string canonOut = tree_canonical_form(n, outEdges);
            for (int id : active) {
                if (candidates[id].canon != canonOut) {
                    finish(_wa, "final tree not isomorphic to all feasible hidden instances");
                }
            }
            finish(_ok, "ok");
        } else {
            finish(_pe, "unexpected token (expected '?' or '!')");
        }
    }
}

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

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

static void shuffleVertices(vector<pair<int,int>>& e, int n) {
    vector<int> p(n + 1);
    for (int i = 1; i <= n; i++) p[i] = i;
    for (int i = 1; i <= n; i++) {
        int j = rnd.next(i, n);
        swap(p[i], p[j]);
    }
    for (auto& ed : e) {
        ed.first = p[ed.first];
        ed.second = p[ed.second];
        if (ed.first == ed.second) {
            ed.second = p[1];
            if (ed.first == ed.second) ed.second = (ed.first % n) + 1;
        }
    }
}

static vector<pair<int,int>> makePath(int n) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 1; i + 1 <= n; i++) e.push_back({i, i + 1});
    return e;
}

static void buildFixedBinarySubtree(vector<pair<int,int>>& e, int start, int sz) {

    for (int i = 1; i < sz; i++) {
        int v = start + i;
        int parent = start + (i - 1) / 2;
        e.push_back({parent, v});
    }
}

static vector<pair<int,int>> makeSymmetricTwoSubtrees(int n) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    int root = 1;
    int m = (n - 1) / 2;
    int s1 = 2;
    int s2 = 2 + m;

    e.push_back({root, s1});
    e.push_back({root, s2});
    buildFixedBinarySubtree(e, s1, m);
    buildFixedBinarySubtree(e, s2, m);

    if (n % 2 == 0) {
        int leftover = 2 + 2 * m;
        if (leftover <= n) e.push_back({root, leftover});
    }
    if ((int)e.size() != n - 1) {

        return makePath(n);
    }
    return e;
}

static vector<pair<int,int>> makeDoubleStarWithBridge(int n, int bridgeLenEdges) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);

    if (n == 3) return makePath(n);
    bridgeLenEdges = max(1, min(bridgeLenEdges, n - 2));

    int centerA = 1;
    int nextNode = 2;
    int last = centerA;

    for (int i = 0; i < bridgeLenEdges - 1; i++) {
        int cur = nextNode++;
        e.push_back({last, cur});
        last = cur;
    }
    int centerB = nextNode++;
    e.push_back({last, centerB});

    int used = nextNode - 1;
    int remaining = n - used;
    int leavesA = remaining / 2;
    int leavesB = remaining - leavesA;

    for (int i = 0; i < leavesA; i++) {
        e.push_back({centerA, nextNode++});
    }
    for (int i = 0; i < leavesB; i++) {
        e.push_back({centerB, nextNode++});
    }

    if ((int)e.size() != n - 1) {

        while ((int)e.size() < n - 1 && nextNode <= n) {
            int to = nextNode++;
            e.push_back({(rnd.next(0, 1) ? centerA : centerB), to});
        }
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeSpiderEqualArms(int n, int arms) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    int center = 1;
    int maxArms = max(1, min(arms, n - 1));
    int total = n - 1;
    int base = total / maxArms;
    int rem = total % maxArms;

    int nextNode = 2;
    for (int a = 0; a < maxArms; a++) {
        int len = base + (a < rem ? 1 : 0);
        int last = center;
        for (int i = 0; i < len; i++) {
            int cur = nextNode++;
            e.push_back({last, cur});
            last = cur;
        }
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeCaterpillar(int n, int spineLen) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    spineLen = max(2, min(spineLen, n));
    for (int i = 1; i < spineLen; i++) e.push_back({i, i + 1});
    int nextNode = spineLen + 1;
    while (nextNode <= n) {
        int attach = rnd.next(1, spineLen);
        e.push_back({attach, nextNode});
        nextNode++;
    }
    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

static vector<pair<int,int>> makeRandomTreePrufer(int n) {
    vector<pair<int,int>> e;
    e.reserve(n - 1);
    if (n <= 1) return e;
    if (n == 2) { e.push_back({1, 2}); return e; }

    vector<int> prufer(n - 2);
    for (int i = 0; i < n - 2; i++) prufer[i] = rnd.next(1, n);

    vector<int> deg(n + 1, 1);
    for (int x : prufer) deg[x]++;

    priority_queue<int, vector<int>, greater<int>> pq;
    for (int i = 1; i <= n; i++) if (deg[i] == 1) pq.push(i);

    for (int x : prufer) {
        int leaf = pq.top(); pq.pop();
        e.push_back({leaf, x});
        deg[leaf]--;
        deg[x]--;
        if (deg[x] == 1) pq.push(x);
    }

    int a = pq.top(); pq.pop();
    int b = pq.top(); pq.pop();
    e.push_back({a, b});

    if ((int)e.size() != n - 1) return makePath(n);
    return e;
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 1000);
    string pattern = opt<string>("pattern", "auto");
    int arms = opt<int>("arms", 9);

    long long seed = 1;
    if (argc > 1) {
        seed = atoll(argv[1]);
        if (seed <= 0) seed = 1;
    }

    int n = nOpt;
    if (seed == 1) n = 3;
    else if (seed == 2) n = max(3, nOpt);
    else if (seed == 3) n = max(3, nOpt);
    else {
        n = max(3, nOpt);
        if (n >= 50) {
            int lo = max(3, n - 50);
            int hi = n;
            n = rnd.next(lo, hi);
        }
    }

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

    vector<pair<int,int>> edges;
    if (seed == 1) {
        edges = makePath(n);
    } else if (seed == 2) {
        int bridge = min(n - 2, 37);
        edges = makeDoubleStarWithBridge(n, bridge);
    } else if (seed == 3) {
        edges = makeSpiderEqualArms(n, min(arms, 12));
    } else {
        if (pattern == "auto") {
            int t = rnd.next(0, 4);
            if (t == 0) {
                int bridge = rnd.next(10, min(80, n - 2));
                edges = makeDoubleStarWithBridge(n, bridge);
            } else if (t == 1) {
                edges = makeSymmetricTwoSubtrees(n);
            } else if (t == 2) {
                int spineLen = rnd.next(max(2, n / 3), max(2, (2 * n) / 3));
                edges = makeCaterpillar(n, spineLen);
            } else if (t == 3) {
                edges = makeSpiderEqualArms(n, min(arms, max(2, n - 1)));
            } else {
                edges = makeRandomTreePrufer(n);
            }
        } else if (pattern == "double") {
            int bridge = rnd.next(10, min(80, n - 2));
            edges = makeDoubleStarWithBridge(n, bridge);
        } else if (pattern == "sym") {
            edges = makeSymmetricTwoSubtrees(n);
        } else if (pattern == "cater") {
            int spineLen = rnd.next(max(2, n / 3), max(2, (2 * n) / 3));
            edges = makeCaterpillar(n, spineLen);
        } else if (pattern == "spider") {
            edges = makeSpiderEqualArms(n, min(arms, max(2, n - 1)));
        } else if (pattern == "rand") {
            edges = makeRandomTreePrufer(n);
        } else {
            edges = makeRandomTreePrufer(n);
        }
    }

    if ((int)edges.size() != n - 1) {
        edges = makePath(n);
    }

    shuffleEdges(edges);
    if (rnd.next(0, 1)) shuffleVertices(edges, n);
    shuffleEdges(edges);

    cout << n << "\n";
    for (auto [u, v] : edges) {
        cout << u << " " << v << "\n";
    }
    return 0;
}


The only difference between the easy and the hard version is the limit to the number of queries.

This is an interactive problem.

There is an array $a$ of $n$ different numbers. In one query you can ask the position of the second maximum element in a subsegment $a[l..r]$. Find the position of the maximum element in the array in no more than 40 queries.

A subsegment $a[l..r]$ is all the elements $a_l, a_{l + 1}, ..., a_r$. After asking this subsegment you will be given the position of the second maximum from this subsegment in the whole array.

Input

The first line contains a single integer $n$ $(2 \leq n \leq 10^5)$ — the number of elements in the array.

Interaction

You can ask queries by printing "? $l$ $r$" $(1 \leq l < r \leq n)$. The answer is the index of the second maximum of all elements $a_l, a_{l + 1}, \ldots, a_r$. Array $a$ is fixed beforehand and can't be changed in time of interaction.

You can output the answer by printing "! $p$", where $p$ is the index of the maximum element in the array.

You can ask no more than 40 queries. Printing the answer doesn't count as a query.

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

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

Example

Input

```
5

3

4
```

Output

```
? 1 5

? 4 5

! 1
```

Note

In the sample suppose $a$ is $[5, 1, 4, 2, 3]$. So after asking the $[1..5]$ subsegment $4$ is second to max value, and it's position is $3$. After asking the $[4..5]$ subsegment $2$ is second to max value and it's position in the whole array is $4$.

Note that there are other arrays $a$ that would produce the same interaction, and the answer for them might be different. Example output is given in purpose of understanding the 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 Node {
    long long v1; int i1;
    long long v2; int i2;
};

static const long long NEG_INF = (long long)-4e18;

static Node emptyNode() {
    return Node{NEG_INF, -1, NEG_INF, -1};
}

static Node combineNode(const Node& A, const Node& B) {
    array<pair<long long,int>, 4> cands = {{
        {A.v1, A.i1}, {A.v2, A.i2}, {B.v1, B.i1}, {B.v2, B.i2}
    }};
    vector<pair<long long,int>> v;
    v.reserve(4);
    for (auto &p : cands) if (p.second != -1) v.push_back(p);
    if (v.empty()) return emptyNode();
    sort(v.begin(), v.end(), [](const auto& x, const auto& y){
        if (x.first != y.first) return x.first > y.first;
        return x.second < y.second;
    });
    Node res = emptyNode();
    res.v1 = v[0].first; res.i1 = v[0].second;
    if ((int)v.size() >= 2) {
        res.v2 = v[1].first; res.i2 = v[1].second;
    }
    return res;
}

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

    int n = inf.readInt(2, 100000, "n");

    vector<long long> a(n + 1, 0);
    unordered_set<long long> seen;
    seen.reserve((size_t)n * 2);

    int posMax = 1;
    for (int i = 1; i <= n; ++i) {
        long long x = inf.readLong((long long)-1000000000000000000LL, (long long)1000000000000000000LL, "a[i]");
        if (seen.find(x) != seen.end()) {
            finish(_fail, "invalid hidden input: duplicate array values");
        }
        seen.insert(x);
        a[i] = x;
        if (a[i] > a[posMax]) posMax = i;
    }

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

    log_metrics();

    cout << n << endl;

    int sz = 1;
    while (sz < n) sz <<= 1;
    vector<Node> seg(2 * sz, emptyNode());
    for (int i = 1; i <= n; ++i) {
        seg[sz + (i - 1)] = Node{a[i], i, NEG_INF, -1};
    }
    for (int i = sz - 1; i >= 1; --i) {
        seg[i] = combineNode(seg[2 * i], seg[2 * i + 1]);
    }

    auto rangeQuery = [&](int l, int r) -> Node {
        Node left = emptyNode(), right = emptyNode();
        int L = sz + (l - 1);
        int R = sz + (r - 1);
        while (L <= R) {
            if (L & 1) left = combineNode(left, seg[L++]);
            if (!(R & 1)) right = combineNode(seg[R--], right);
            L >>= 1; R >>= 1;
        }
        return combineNode(left, right);
    };

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

        if (!cmd.empty() && cmd[0] == '?') {
            long long lll, rrr;
            if (!(cin >> lll >> rrr)) {
                finish(_pe, "malformed query: expected two integers after '?'");
            }
            if (lll < 1 || rrr < 1 || lll > n || rrr > n) {
                finish(_pe, "query indices out of range");
            }
            int l = (int)lll, r = (int)rrr;
            if (l >= r) {
                finish(_pe, "malformed query: require l < r");
            }

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

            Node ans = rangeQuery(l, r);
            if (ans.i2 == -1) {
                finish(_fail, "internal error: second maximum missing for a valid range");
            }
            cout << ans.i2 << endl;
        } else if (!cmd.empty() && cmd[0] == '!') {
            long long pLL;
            if (!(cin >> pLL)) {
                finish(_pe, "malformed answer: expected index after '!'");
            }
            if (pLL < 1 || pLL > n) {
                finish(_pe, "answer index out of range");
            }
            int p = (int)pLL;
            if (p == posMax) finish(_ok, "correct");
            finish(_wa, "wrong maximum position");
        } else {
            finish(_pe, "unexpected token (expected '?' or '!')");
        }
    }
}

#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 void maybe_log_progress() {
    if (queries <= 1000 || (queries % 1000 == 0)) log_metrics();
}

struct SegTree {
    struct Node {
        int v1 = INT_MIN, i1 = -1;
        int v2 = INT_MIN, i2 = -1;
    };
    int n = 0;
    vector<Node> st;

    static void upd(Node& cur, int v, int idx) {
        if (idx == -1) return;
        if (cur.i1 == idx) {
            cur.v1 = max(cur.v1, v);
            return;
        }
        if (cur.i2 == idx) {
            cur.v2 = max(cur.v2, v);
            return;
        }
        if (v > cur.v1) {
            cur.v2 = cur.v1; cur.i2 = cur.i1;
            cur.v1 = v; cur.i1 = idx;
        } else if (v > cur.v2) {
            cur.v2 = v; cur.i2 = idx;
        }
    }

    static Node mergeNodes(const Node& a, const Node& b) {
        Node res;
        upd(res, a.v1, a.i1);
        upd(res, a.v2, a.i2);
        upd(res, b.v1, b.i1);
        upd(res, b.v2, b.i2);
        return res;
    }

    void init(const vector<int>& arr1indexed) {
        n = (int)arr1indexed.size() - 1;
        st.assign(4 * n + 4, Node());
        build(1, 1, n, arr1indexed);
    }

    void build(int p, int l, int r, const vector<int>& a) {
        if (l == r) {
            st[p].v1 = a[l];
            st[p].i1 = l;
            st[p].v2 = INT_MIN;
            st[p].i2 = -1;
            return;
        }
        int m = (l + r) >> 1;
        build(p << 1, l, m, a);
        build(p << 1 | 1, m + 1, r, a);
        st[p] = mergeNodes(st[p << 1], st[p << 1 | 1]);
    }

    Node query(int p, int l, int r, int ql, int qr) const {
        if (ql <= l && r <= qr) return st[p];
        int m = (l + r) >> 1;
        if (qr <= m) return query(p << 1, l, m, ql, qr);
        if (ql > m) return query(p << 1 | 1, m + 1, r, ql, qr);
        Node left = query(p << 1, l, m, ql, qr);
        Node right = query(p << 1 | 1, m + 1, r, ql, qr);
        return mergeNodes(left, right);
    }

    int secondMaxIndex(int l, int r) const {
        Node nd = query(1, 1, n, l, r);
        return nd.i2;
    }
};

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

    int n = inf.readInt(2, 100000, "n");

    vector<int> rest;
    while (!inf.seekEof()) {
        rest.push_back(inf.readInt());
    }

    bool non_adaptive = false;
    vector<int> a;
    int pMax = -1;
    int pFixed = -1;

    if ((int)rest.size() == n) {
        non_adaptive = true;
        a.assign(n + 1, 0);
        for (int i = 1; i <= n; i++) a[i] = rest[i - 1];
        int bestVal = INT_MIN;
        for (int i = 1; i <= n; i++) {
            if (a[i] > bestVal) {
                bestVal = a[i];
                pMax = i;
            }
        }
        if (pMax == -1) finish(_fail, "failed to determine maximum position from array");
    } else if ((int)rest.size() == 1) {
        non_adaptive = false;
        pFixed = rest[0];
        if (pFixed < 1 || pFixed > n) finish(_fail, "invalid p in adaptive input");
        pMax = pFixed;
    } else {
        finish(_fail, "unexpected input schema: expected n ints (non-adaptive) or 1 int (adaptive) after n");
    }

    query_limit = 40;
    log_metrics();

    cout << n << endl;

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

    SegTree st;
    if (non_adaptive) st.init(a);

    int dir = 0;

    while (true) {
        string tok;
        if (!(cin >> tok)) {
            finish(_pe, "unexpected EOF from participant");
        }

        if (tok == "?") {
            long long lll, rll;
            if (!(cin >> lll >> rll)) finish(_pe, "malformed query: expected '? l r'");
            if (lll < 1 || rll > n || lll >= rll) finish(_pe, "query out of bounds or invalid (need 1<=l<r<=n)");

            int l = (int)lll, r = (int)rll;

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

            int ans = -1;
            if (non_adaptive) {
                ans = st.secondMaxIndex(l, r);
                if (ans < l || ans > r) finish(_fail, "internal error: computed answer out of range");
            } else {
                if (dir == 0) {

                    dir = (l <= pMax && pMax <= r) ? -1 : +1;
                }

                bool hasP = (l <= pMax && pMax <= r);
                if (dir == +1) {
                    if (hasP) {
                        ans = r;
                        if (ans == pMax) ans--;
                    } else {
                        ans = r - 1;
                    }
                } else {
                    if (hasP) {
                        ans = l;
                        if (ans == pMax) ans++;
                    } else {
                        ans = l + 1;
                    }
                }

                if (!(l <= ans && ans <= r) || ans == -1) finish(_fail, "internal error: adaptive answer invalid");
            }

            cout << ans << endl;
        } else if (tok == "!") {
            long long xll;
            if (!(cin >> xll)) finish(_pe, "malformed answer: expected '! p'");
            if (xll < 1 || xll > n) finish(_pe, "final answer out of range");

            int x = (int)xll;
            if (x == pMax) finish(_ok, "correct");
            finish(_wa, "wrong maximum position");
        } else {
            finish(_pe, "unknown token (expected '?' or '!')");
        }
    }
}

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

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

static vector<int> buildWithFixedTop2(int n, int posMax, int posSecond, int fillMode) {

    vector<int> a(n + 1, -1);
    if (n == 2) {
        a[posMax] = 2;
        a[posSecond] = 1;
        return a;
    }

    vector<int> rem;
    rem.reserve(max(0, n - 2));
    for (int x = 1; x <= n - 2; ++x) rem.push_back(x);

    if (fillMode == 0) {
        shuffleVec(rem);
    } else if (fillMode == 1) {

    } else if (fillMode == 2) {
        reverse(rem.begin(), rem.end());
    } else if (fillMode == 3) {
        vector<int> alt;
        alt.reserve(rem.size());
        int l = 0, r = (int)rem.size() - 1;
        while (l <= r) {
            alt.push_back(rem[l++]);
            if (l <= r) alt.push_back(rem[r--]);
        }
        rem.swap(alt);
    }

    int ptr = 0;
    for (int i = 1; i <= n; ++i) {
        if (i == posMax || i == posSecond) continue;
        a[i] = rem[ptr++];
    }
    a[posSecond] = n - 1;
    a[posMax] = n;

    return a;
}

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

static Instance makeInstance(int seed, int nOpt, int maxN) {
    Instance inst;

    auto clampN = [&](int x) -> int {
        if (x < 2) x = 2;
        if (x > maxN) x = maxN;
        return x;
    };

    int n;
    if (nOpt != -1) {
        n = clampN(nOpt);
    } else {
        if (seed == 1) n = 2;
        else if (seed == 2) n = maxN;
        else if (seed == 3) n = maxN;
        else {

            int roll = rnd.next(1, 10);
            if (roll <= 8) n = maxN;
            else n = rnd.next(2, maxN);
        }
    }
    inst.n = n;

    if (seed == 1) {

        inst.p = 1;
        inst.a = buildWithFixedTop2(n, 1, 2, 1);
        return inst;
    }
    if (seed == 2) {

        inst.p = n;
        inst.a.assign(n + 1, 0);
        for (int i = 1; i <= n; ++i) inst.a[i] = i;
        return inst;
    }
    if (seed == 3) {

        inst.p = n;
        inst.a = buildWithFixedTop2(n, n, 1, 3);
        return inst;
    }

    int type = rnd.next(1, 6);
    if (type == 1) {

        int posMax = 1;
        int posSecond = n;
        inst.p = posMax;
        inst.a = buildWithFixedTop2(n, posMax, posSecond, 0);
    } else if (type == 2) {

        int posMax = n;
        int posSecond = 1;
        inst.p = posMax;
        inst.a = buildWithFixedTop2(n, posMax, posSecond, 3);
    } else if (type == 3) {

        int posMax = (n + 1) / 2;
        int posSecond = posMax + 1;
        if (posSecond > n) posSecond = posMax - 1;
        if (posSecond < 1) posSecond = (posMax == 1 ? 2 : 1);
        inst.p = posMax;
        inst.a = buildWithFixedTop2(n, posMax, posSecond, 2);
    } else if (type == 4) {

        vector<int> v(n);
        for (int i = 0; i < n; ++i) v[i] = i + 1;
        shuffleVec(v);
        inst.a.assign(n + 1, 0);
        for (int i = 1; i <= n; ++i) inst.a[i] = v[i - 1];
        for (int i = 1; i <= n; ++i) if (inst.a[i] == n) inst.p = i;
    } else if (type == 5) {

        int posMax = rnd.next(1, n);
        int posSecond = rnd.next(1, n - 1);
        if (posSecond >= posMax) posSecond++;
        inst.p = posMax;
        inst.a = buildWithFixedTop2(n, posMax, posSecond, 1);

        int L = rnd.next(1, n);
        int R = rnd.next(1, n);
        if (L > R) swap(L, R);
        if (!(L <= posMax && posMax <= R) && !(L <= posSecond && posSecond <= R) && R - L + 1 >= 2) {
            reverse(inst.a.begin() + L, inst.a.begin() + R + 1);
        }
    } else {

        int posMax = rnd.next(1, n);
        int posSecond;
        if (posMax == 1) posSecond = n;
        else if (posMax == n) posSecond = 1;
        else posSecond = (rnd.next(0, 1) ? 1 : n);
        inst.p = posMax;
        inst.a = buildWithFixedTop2(n, posMax, posSecond, 3);
    }

    if (inst.p < 1 || inst.p > n) {

        inst.p = n;
        inst.a.assign(n + 1, 0);
        for (int i = 1; i <= n; ++i) inst.a[i] = i;
    }
    return inst;
}

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

    string mode = opt<string>("mode", "non");
    int maxN = opt<int>("maxn", 100000);
    if (maxN < 2) maxN = 2;
    if (maxN > 100000) maxN = 100000;

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

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

    Instance inst = makeInstance(seed, nOpt, maxN);

    if (mode == "non") {
        cout << inst.n << "\n";
        for (int i = 1; i <= inst.n; ++i) {
            if (i > 1) cout << ' ';
            cout << inst.a[i];
        }
        cout << "\n";
    } else if (mode == "adp") {

        cout << inst.n << "\n" << inst.p << "\n";
    } else {
        quitf(_fail, "unknown mode: %s", mode.c_str());
    }

    return 0;
}


Michael and Brian are stuck in a hotel with $n$ rooms, numbered from $1$ to $n$, and need to find each other. But this hotel's doors are all locked and the only way of getting around is by using the teleporters in each room. Room $i$ has a teleporter that will take you to room $a_i$ (it might be that $a_i = i$). But they don't know the values of $a_1,a_2, \dots, a_n$.

Instead, they can call up the front desk to ask queries. In one query, they give a room $u$, a positive integer $k$, and a set of rooms $S$. The hotel concierge answers whether a person starting in room $u$, and using the teleporters $k$ times, ends up in a room in $S$.

Brian is in room $1$. Michael wants to know the set $A$ of rooms so that if he starts in one of those rooms they can use the teleporters to meet up. He can ask at most $2000$ queries.

The values $a_1, a_2, \dots, a_n$ are fixed before the start of the interaction and do not depend on your queries. In other words, the interactor is not adaptive.

Input

The input contains a single integer $n$ ($2 \leq n \leq 500$).

Interaction

To ask a query, print a line in the format "? u k |S| S\_1 S\_2 ... S\_|S|" with $1 \leq u, S_1, \ldots, S_{|S|} \leq n$, all the $S_i$ distinct, and $1 \leq k \leq 10^9$.

As a response to the query you will get "1" if the answer is yes, and "0" if the answer is no.

To output an answer, you should print "! |A| A\_1 A\_2 ... A\_|A|" with $1 \leq A_1, \ldots, A_{|A|} \leq n$ all distinct. Printing the answer doesn't count as a query.

See the interaction example for more clarity.

If you ask too many queries or you ask a malformed query, you will get Wrong answer.

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

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

Example

Input

```
5

0

1
```

Output

```
? 3 5 2 2 3

? 2 5 2 2 3

! 3 1 3 4
```

Note

In the sample test, there are $n=5$ rooms and the (hidden) array describing the behavior of the teleporters is $[1, 2, 1, 3, 2]$.

* The first query asks whether starting from room number $a=3$, and using the teleporters $5$ times, one ends up in one of the two rooms $S=\{2, 3\}$. This action results in ending up in the room $1$, so the answer is $0$.
* The second query asks whether starting from room number $a=2$, and using the teleporters $5$ times, one ends up in one of the two rooms $S=\{2, 3\}$. This action results in ending up in the room $2$, so the answer is $1$.

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

static int queries = 0;
static int query_limit = 2000;
static const int HARD_CAP = 20005;

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

    }
}

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

int n;
vector<int> a;
int up[505][32];
set<int> true_answer;

int get_dest(int u, long long k) {
    for (int j = 0; j < 30; j++) {
        if ((k >> j) & 1) {
            u = up[u][j];
        }
    }
    return u;
}

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

    n = inf.readInt();
    a.resize(n + 1);
    for (int i = 1; i <= n; i++) {
        a[i] = inf.readInt();
    }

    query_limit = 2000;

    log_metrics();

    for (int i = 1; i <= n; i++) {
        up[i][0] = a[i];
    }
    for (int j = 1; j < 30; j++) {
        for (int i = 1; i <= n; i++) {
            up[i][j] = up[up[i][j-1]][j-1];
        }
    }

    vector<int> vis(n + 1, 0);
    int curr = 1;
    while (!vis[curr]) {
        vis[curr] = 1;
        curr = a[curr];
    }

    set<int> cycle_nodes;
    int start_cycle = curr;
    while (true) {
        cycle_nodes.insert(curr);
        curr = a[curr];
        if (curr == start_cycle) break;
    }

    vector<vector<int>> rev_adj(n + 1);
    for (int i = 1; i <= n; i++) {
        rev_adj[a[i]].push_back(i);
    }

    queue<int> q;
    vector<bool> in_component(n + 1, false);
    for (int x : cycle_nodes) {
        in_component[x] = true;
        true_answer.insert(x);
        q.push(x);
    }

    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : rev_adj[u]) {
            if (!in_component[v]) {
                in_component[v] = true;
                true_answer.insert(v);
                q.push(v);
            }
        }
    }

    cout << n << endl;

    while (true) {

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

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

        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF: failed to read query/answer token");
        }

        if (token == "!") {

            int sz;
            if (!(cin >> sz)) finish(_wa, "Failed to read answer size");

            vector<int> user_ans;
            for (int i = 0; i < sz; i++) {
                int val;
                if (!(cin >> val)) finish(_wa, "Failed to read answer element");
                user_ans.push_back(val);
            }

            sort(user_ans.begin(), user_ans.end());
            if (unique(user_ans.begin(), user_ans.end()) != user_ans.end()) {
                finish(_wa, "Duplicate elements in answer set");
            }

            if ((int)user_ans.size() != (int)true_answer.size()) {
                finish(_wa, "Answer set size mismatch");
            }

            int idx = 0;
            for (int x : true_answer) {
                if (idx >= (int)user_ans.size() || user_ans[idx] != x) {
                    finish(_wa, "Answer set content mismatch");
                }
                idx++;
            }

            finish(_ok, "Correct answer");
        } else {

            int u;
            if (token == "?") {
                if (!(cin >> u)) finish(_wa, "Failed to read u after '?'");
            } else {
                try {
                    u = stoi(token);
                } catch (...) {
                    finish(_wa, "Invalid format for u: " + token);
                }
            }

            long long k;
            if (!(cin >> k)) finish(_wa, "Failed to read k");

            int s_len;
            if (!(cin >> s_len)) finish(_wa, "Failed to read |S|");

            if (u < 1 || u > n) finish(_wa, "u out of range [1, n]");
            if (k < 1 || k > 1000000000LL) finish(_wa, "k out of range [1, 10^9]");
            if (s_len < 1 || s_len > n) finish(_wa, "|S| out of range [1, n]");

            set<int> S;
            for (int i = 0; i < s_len; i++) {
                int val;
                if (!(cin >> val)) finish(_wa, "Failed to read element of S");
                if (val < 1 || val > n) finish(_wa, "Element of S out of range");
                if (S.count(val)) finish(_wa, "Duplicate element in S");
                S.insert(val);
            }

            queries++;

            int dest = get_dest(u, k);
            int response = (S.count(dest) ? 1 : 0);

            cout << response << endl;
        }
    }

    return 0;
}

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

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

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

    int n_opt = opt<int>("n", -1);

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

    int n = n_opt;
    vector<int> a;

    if (seed_val == 1) {
        n = 2;
        a.resize(n + 1);
        a[1] = 2; a[2] = 1;
    }
    else if (seed_val == 2) {

        if (n == -1) n = 500;
        a.resize(n + 1);
        vector<int> p = rnd.perm(n, 1);
        for (int i = 0; i < n; ++i) {
            a[p[i]] = p[(i + 1) % n];
        }
    }
    else if (seed_val == 3) {

        if (n == -1) n = 500;
        a.resize(n + 1);
        for (int i = 1; i <= n; ++i) a[i] = i;
    }
    else {

        if (n == -1) {

            if (rnd.next(3) == 0) n = rnd.next(2, 500);
            else n = 500;
        }
        a.resize(n + 1);

        int type = rnd.next(5);

        if (type == 0) {

            for (int i = 1; i <= n; ++i) a[i] = rnd.next(1, n);
        }
        else if (type == 1) {

            vector<int> p = rnd.perm(n, 1);

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

            vector<int> p = rnd.perm(n, 1);
            int cycle_len = rnd.next(1, n);

            for (int i = 0; i < cycle_len; ++i) {
                a[p[i]] = p[(i + 1) % cycle_len];
            }

            for (int i = cycle_len; i < n; ++i) {

                int target_idx = rnd.next(0, i - 1);

                if (rnd.next(3) == 0) target_idx = rnd.next(max(0, i - 20), i - 1);
                a[p[i]] = p[target_idx];
            }
        }
        else if (type == 3) {

            int comp_size = rnd.next(1, min(n, 50));
            vector<int> p = rnd.perm(n, 1);

            for (int i = 0; i < n; ++i) {
                if (p[i] == 1) {
                    swap(p[0], p[i]);
                    break;
                }
            }

            for (int i = 0; i < comp_size; ++i) {
                a[p[i]] = p[rnd.next(0, comp_size - 1)];
            }

            for (int i = comp_size; i < n; ++i) {
                if (comp_size < n)
                    a[p[i]] = p[rnd.next(comp_size, n - 1)];
                else
                    a[p[i]] = p[rnd.next(0, n - 1)];
            }
        }
        else {

            int cycle_len = rnd.next(1, max(1, n / 10));
            int tail_len = n - cycle_len;

            vector<int> p = rnd.perm(n, 1);

            for(int i=0; i<tail_len; ++i) {
                a[p[i]] = p[i+1];
            }

            if (tail_len > 0)
                a[p[tail_len-1]] = p[tail_len + rnd.next(0, cycle_len-1)];

            for(int i=tail_len; i<n; ++i) {
                int nxt = i + 1;
                if (nxt == n) nxt = tail_len;
                a[p[i]] = p[nxt];
            }
        }
    }

    if (mode == "non") {

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

        cout << n << endl;
    }

    return 0;
}


This is an interactive problem.

Baby Ehab loves crawling around his apartment. It has $n$ rooms numbered from $0$ to $n-1$. For every pair of rooms, $a$ and $b$, there's either a direct passage from room $a$ to room $b$, or from room $b$ to room $a$, but never both.

Baby Ehab wants to go play with Baby Badawy. He wants to know if he could get to him. However, he doesn't know anything about his apartment except the number of rooms. He can ask the baby sitter two types of questions:

* is the passage between room $a$ and room $b$ directed from $a$ to $b$ or the other way around?
* does room $x$ have a passage towards any of the rooms $s_1$, $s_2$, ..., $s_k$?

He can ask at most $9n$ queries of the first type and at most $2n$ queries of the second type.

After asking some questions, he wants to know for every pair of rooms $a$ and $b$ whether there's a path from $a$ to $b$ or not. A path from $a$ to $b$ is a sequence of passages that starts from room $a$ and ends at room $b$.

Input

The first line contains an integer $t$ ($1 \le t \le 30$) — the number of test cases you need to solve.

Then each test case starts with an integer $n$ ($4 \le n \le 100$) — the number of rooms.

The sum of $n$ across the test cases doesn't exceed $500$.

Output

To print the answer for a test case, print a line containing "3", followed by $n$ lines, each containing a binary string of length $n$. The $j$-th character of the $i$-th string should be $1$ if there's a path from room $i$ to room $j$, and $0$ if there isn't. The $i$-th character of the $i$-th string should be $1$ for each valid $i$.

After printing the answer, we will respond with a single integer. If it's $1$, you printed a correct answer and should keep solving the test cases (or exit if it is the last one). If it's $-1$, you printed a wrong answer and should terminate to get Wrong answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

Interaction

To ask a question of the first type, use the format:

* $1$ $a$ $b$ ($0 \le a,b \le n-1$, $a \neq b$).
* we will answer with $1$ if the passage is from $a$ to $b$, and $0$ if it is from $b$ to $a$.
* you can ask at most $9n$ questions of this type in each test case.

To ask a question of the second type, use the format:

* $2$ $x$ $k$ $s_1$ $s_2$ ... $s_k$ ($0 \le x,s_i \le n-1$, $0 \le k < n$, $x \neq s_i$, elements of $s$ are pairwise distinct).
* we will answer with $1$ if there's a passage from $x$ to any of the rooms in $s$, and $0$ otherwise.
* you can ask at most $2n$ questions of this type in each test case.

If we answer with $-1$ instead of a valid answer, that means you exceeded the number of queries or made an invalid query. Exit immediately after receiving $-1$ and you will see 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, do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

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

Example

Input

```
1
4

0

0

1

1

1
```

Output

```
2 3 3 0 1 2

1 0 1

1 0 2

2 2 1 1

3
1111
1111
1111
0001
```

Note

In the given example:

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

The first query asks whether there's a passage from room $3$ to any of the other rooms.

The second query asks about the direction of the passage between rooms $0$ and $1$.

After a couple other queries, we concluded that you can go from any room to any other room except if you start at room $3$, and you can't get out of this room, so we printed the matrix:

```
1111
1111
1111
0001
```

The interactor answered with $1$, telling us the answer is correct.

#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 readLL(long long& x) {
    return (cin >> x) ? true : false;
}

static void sendToContestant(long long x) {
    cout << x << "\n";
    cout.flush();
}

static void sendMinusOneAndPE(const string& msg) {
    sendToContestant(-1);
    finish(_pe, msg);
}

static void sendMinusOneAndWA(const string& msg) {
    sendToContestant(-1);
    finish(_wa, msg);
}

static uint64_t fnv1a64(const string& s) {
    uint64_t h = 14695981039346656037ULL;
    for (unsigned char c : s) {
        h ^= (uint64_t)c;
        h *= 1099511628211ULL;
    }
    return h;
}

static uint64_t splitmix64(uint64_t x) {
    x += 0x9e3779b97f4a7c15ULL;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;
    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;
    return x ^ (x >> 31);
}

static vector<string> generateTournament(int n, uint64_t seed) {
    vector<string> g(n, string(n, '0'));

    for (int i = 0; i < n; i++) {
        g[i][i] = '0';
        for (int j = i + 1; j < n; j++) {
            uint64_t h = splitmix64(seed ^ (uint64_t)(i + 1) * 0x9e3779b97f4a7c15ULL ^ (uint64_t)(j + 1));
            bool dir = (h & 1ULL);
            g[i][j] = dir ? '1' : '0';
            g[j][i] = dir ? '0' : '1';
        }
    }

    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    for (int i = n - 1; i >= 1; --i) {
        seed = splitmix64(seed);
        int j = (int)(seed % (uint64_t)(i + 1));
        swap(p[i], p[j]);
    }
    for (int i = 0; i < n; i++) {
        int u = p[i];
        int v = p[(i + 1) % n];
        g[u][v] = '1';
        g[v][u] = '0';
    }

    return g;
}

static const int MAXN = 105;

struct CaseData {
    int n;
    vector<string> g;
    vector<bitset<MAXN>> reach;
};

static vector<bitset<MAXN>> computeReach(int n, const vector<string>& g) {
    vector<bitset<MAXN>> reach(n);
    for (int i = 0; i < n; i++) {
        reach[i].reset();
        reach[i].set(i);
        for (int j = 0; j < n; j++) {
            if (i != j && g[i][j] == '1') reach[i].set(j);
        }
    }
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            if (reach[i].test(k)) reach[i] |= reach[k];
        }
    }
    return reach;
}

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

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

    long long sumN = 0;
    uint64_t seed = fnv1a64((argc >= 2) ? string(argv[1]) : string("cf1514E"));

    for (int tc = 0; tc < t; tc++) {
        int n = inf.readInt(4, 100, "n");
        sumN += n;
        if (sumN > 500) finish(_fail, "Hidden input: sum of n exceeds 500");

        vector<string> g;
        if (inf.seekEof()) {

            seed = splitmix64(seed ^ (uint64_t)n);
            g = generateTournament(n, seed);
        } else {

            g.assign(n, "");
            for (int i = 0; i < n; i++) {
                string s = inf.readToken();
                if ((int)s.size() != n) finish(_fail, "Hidden input: row length != n");
                for (int j = 0; j < n; j++) {
                    if (s[j] != '0' && s[j] != '1') finish(_fail, "Hidden input: non-binary char");
                }
                g[i] = std::move(s);
            }
        }

        for (int i = 0; i < n; i++) {
            if (g[i][i] != '0') g[i][i] = '0';
            for (int j = i + 1; j < n; j++) {
                char a = g[i][j], b = g[j][i];
                if (!((a == '0' && b == '1') || (a == '1' && b == '0'))) {
                    finish(_fail, "Hidden input: not a tournament (pair not complementary)");
                }
            }
        }

        CaseData cd;
        cd.n = n;
        cd.g = std::move(g);
        cd.reach = computeReach(n, cd.g);
        cases.push_back(std::move(cd));

        query_limit += 11LL * n;
    }

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

    log_metrics();

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

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

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

        long long q1 = 0, q2 = 0;
        while (true) {
            long long cmd;
            if (!readLL(cmd)) finish(_pe, "Unexpected EOF while waiting for command");

            if (cmd == 1) {
                long long a_ll, b_ll;
                if (!readLL(a_ll) || !readLL(b_ll)) finish(_pe, "EOF while reading query type 1");
                if (a_ll < 0 || a_ll >= n || b_ll < 0 || b_ll >= n) sendMinusOneAndPE("Type 1: index out of range");
                if (a_ll == b_ll) sendMinusOneAndPE("Type 1: a == b");
                int a = (int)a_ll, b = (int)b_ll;

                q1++;
                queries++;
                if (queries > hard_cap) sendMinusOneAndPE("Hard cap exceeded");
                if (q1 > 9LL * n) sendMinusOneAndPE("Type 1: query limit exceeded");

                int ans = (g[a][b] == '1') ? 1 : 0;
                sendToContestant(ans);
            } else if (cmd == 2) {
                long long x_ll, k_ll;
                if (!readLL(x_ll) || !readLL(k_ll)) finish(_pe, "EOF while reading query type 2 header");
                if (x_ll < 0 || x_ll >= n) sendMinusOneAndPE("Type 2: x out of range");
                if (k_ll < 0 || k_ll >= n) sendMinusOneAndPE("Type 2: k out of range");
                int x = (int)x_ll;
                int k = (int)k_ll;

                vector<int> s;
                s.reserve(k);
                vector<char> seen(n, 0);
                for (int i = 0; i < k; i++) {
                    long long si_ll;
                    if (!readLL(si_ll)) finish(_pe, "EOF while reading query type 2 set");
                    if (si_ll < 0 || si_ll >= n) sendMinusOneAndPE("Type 2: s_i out of range");
                    int si = (int)si_ll;
                    if (si == x) sendMinusOneAndPE("Type 2: s_i == x");
                    if (seen[si]) sendMinusOneAndPE("Type 2: duplicate s_i");
                    seen[si] = 1;
                    s.push_back(si);
                }

                q2++;
                queries++;
                if (queries > hard_cap) sendMinusOneAndPE("Hard cap exceeded");
                if (q2 > 2LL * n) sendMinusOneAndPE("Type 2: query limit exceeded");

                int ans = 0;
                for (int si : s) {
                    if (g[x][si] == '1') {
                        ans = 1;
                        break;
                    }
                }
                sendToContestant(ans);
            } else if (cmd == 3) {
                vector<string> out(n);
                for (int i = 0; i < n; i++) {
                    string row;
                    if (!(cin >> row)) finish(_pe, "EOF while reading final answer matrix");
                    if ((int)row.size() != n) sendMinusOneAndPE("Final answer: row length != n");
                    for (int j = 0; j < n; j++) {
                        if (row[j] != '0' && row[j] != '1') sendMinusOneAndPE("Final answer: non-binary character");
                    }
                    out[i] = std::move(row);
                }

                for (int i = 0; i < n; i++) {
                    if (out[i][i] != '1') sendMinusOneAndWA("Final answer: diagonal must be 1");
                    for (int j = 0; j < n; j++) {
                        bool got = (out[i][j] == '1');
                        bool exp = reach[i].test(j);
                        if (got != exp) sendMinusOneAndWA("Final answer: reachability mismatch");
                    }
                }

                sendToContestant(1);
                break;
            } else {
                sendMinusOneAndPE("Unknown command (expected 1/2/3)");
            }
        }
    }

    finish(_ok, "OK");
}

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

static void setEdge(vector<string>& g, int a, int b, int dirAB) {
    if (a == b) return;
    if (dirAB) {
        g[a][b] = '1';
        g[b][a] = '0';
    } else {
        g[a][b] = '0';
        g[b][a] = '1';
    }
}

static vector<int> rndPerm(int n) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 0);
    for (int i = 0; i < n; i++) {
        int j = rnd.next(i, n - 1);
        swap(p[i], p[j]);
    }
    return p;
}

static vector<string> buildTransitive(int n) {
    vector<string> g(n, string(n, '0'));
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            setEdge(g, i, j, 1);
    return g;
}

static vector<string> buildCirculant(int n) {
    vector<string> g(n, string(n, '0'));
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int d = j - i;
            int rev = n - d;
            if (d < rev) setEdge(g, i, j, 1);
            else if (d > rev) setEdge(g, i, j, 0);
            else setEdge(g, i, j, (i % 2 == 0) ? 1 : 0);
        }
    }
    return g;
}

static vector<string> buildRandomStrong(int n) {
    vector<string> g(n, string(n, '0'));
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int dir = rnd.next(0, 1);
            setEdge(g, i, j, dir);
        }
    }

    vector<int> p = rndPerm(n);
    for (int i = 0; i < n; i++) {
        int u = p[i];
        int v = p[(i + 1) % n];
        setEdge(g, u, v, 1);
    }
    return g;
}

static vector<string> buildBlocksChain(int n, int minSz, int maxSz, bool allowSmallBlocks) {
    vector<string> g(n, string(n, '0'));
    vector<int> order = rndPerm(n);

    vector<pair<int,int>> blocks;
    int pos = 0;
    while (pos < n) {
        int rem = n - pos;
        int sz;
        if (rem <= 2) {
            sz = rem;
        } else {
            int lo = minSz, hi = maxSz;
            if (allowSmallBlocks) lo = 1;
            lo = max(lo, 1);
            hi = max(hi, lo);
            sz = rnd.next(lo, min(hi, rem));
            if (!allowSmallBlocks && sz < 3) sz = 3;
            if (sz > rem) sz = rem;
            if (!allowSmallBlocks && rem < 3) sz = rem;
            if (!allowSmallBlocks && sz == 2) sz = 3 <= rem ? 3 : rem;
        }
        blocks.push_back({pos, pos + sz});
        pos += sz;
    }

    for (int bi = 0; bi < (int)blocks.size(); bi++) {
        for (int bj = bi + 1; bj < (int)blocks.size(); bj++) {
            for (int ii = blocks[bi].first; ii < blocks[bi].second; ii++) {
                int u = order[ii];
                for (int jj = blocks[bj].first; jj < blocks[bj].second; jj++) {
                    int v = order[jj];
                    setEdge(g, u, v, 1);
                }
            }
        }
    }

    for (auto [l, r] : blocks) {
        int sz = r - l;
        vector<int> verts;
        verts.reserve(sz);
        for (int i = l; i < r; i++) verts.push_back(order[i]);

        for (int i = 0; i < sz; i++) {
            int j = rnd.next(i, sz - 1);
            swap(verts[i], verts[j]);
        }

        for (int i = 0; i < sz; i++) {
            for (int j = i + 1; j < sz; j++) {
                int dir = rnd.next(0, 1);
                setEdge(g, verts[i], verts[j], dir);
            }
        }

        if (sz >= 3) {
            for (int i = 0; i < sz; i++) {
                int u = verts[i];
                int v = verts[(i + 1) % sz];
                setEdge(g, u, v, 1);
            }
        }
    }

    return g;
}

static vector<string> buildWindowMostlyTransitive(int n, int w) {
    vector<string> g(n, string(n, '0'));
    vector<int> ord = rndPerm(n);

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int u = ord[i], v = ord[j];
            int dir;
            if (j - i <= w) dir = rnd.next(0, 1);
            else dir = 1;
            setEdge(g, u, v, dir);
        }
    }

    int flips = max(1, n / 3);
    for (int it = 0; it < flips; it++) {
        int i = rnd.next(0, n - 1);
        int j = rnd.next(0, n - 1);
        if (i == j) { it--; continue; }
        if (abs(i - j) <= w) { it--; continue; }
        int u = ord[min(i, j)];
        int v = ord[max(i, j)];

        setEdge(g, u, v, 0);
    }

    vector<int> p = rndPerm(n);
    for (int i = 0; i < n; i++) {
        int u = p[i], v = p[(i + 1) % n];
        setEdge(g, u, v, 1);
    }
    return g;
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", -1);
    string style = opt<string>("style", "auto");

    long long seedVal = 0;
    if (argc >= 2) {

        seedVal = atoll(argv[1]);
    }

    int n;
    if (nOpt != -1) n = nOpt;
    else if (seedVal == 1) n = 4;
    else if (seedVal == 2) n = 100;
    else if (seedVal == 3) n = 100;
    else n = rnd.next(80, 100);

    ensuref(4 <= n && n <= 100, "n out of range: %d", n);

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

    vector<string> g;

    if (style != "auto") {
        if (style == "transitive") g = buildTransitive(n);
        else if (style == "circulant") g = buildCirculant(n);
        else if (style == "random") g = buildRandomStrong(n);
        else if (style == "blocks") {
            int minSz = opt<int>("minBlock", 3);
            int maxSz = opt<int>("maxBlock", 7);
            bool allowSmall = opt<int>("allowSmall", 0) != 0;
            g = buildBlocksChain(n, minSz, maxSz, allowSmall);
        } else if (style == "window") {
            int w = opt<int>("w", max(2, n / 10));
            g = buildWindowMostlyTransitive(n, w);
        } else {
            quitf(_fail, "unknown --style: %s", style.c_str());
        }
    } else {
        if (seedVal == 1) {
            g = buildTransitive(n);
        } else if (seedVal == 2) {
            g = buildCirculant(n);
        } else if (seedVal == 3) {

            g = buildBlocksChain(n, 3, 6, false);
        } else {
            int pick = rnd.next(1, 100);
            if (pick <= 45) {
                g = buildBlocksChain(n, 3, 8, true);
            } else if (pick <= 80) {
                g = buildRandomStrong(n);
            } else {
                int w = rnd.next(2, max(2, n / 8));
                g = buildWindowMostlyTransitive(n, w);
            }
        }
    }

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