Problem: cf2164_g
Difficulty: hard
Categories: graph, bit, math
Time limit: 4000 ms, memory limit: 256 MB

This is an interactive problem.

Madeline is playing with a pointless machine. The pointless machine has a hidden tree of size $n$, and Madeline has to find the edges of the tree by asking the machine.

In a query, Madeline will give the machine a permutation $p$ of $[1,2,\ldots,n]$, and the machine will return a sequence $q_1, q_2, \ldots, q_n$, where $q_i$ is the number of edges of the induced subgraph formed by the vertices $\{p_1,p_2,\ldots,p_i\}$.

Here, an induced subgraph of a graph $G(V,E)$ formed by a subset of vertices $V' \subseteq V$, is a graph consisting of vertices from this subset and all edges between vertices from subset that are present in original graph $G$.

However, the machine works slowly, so Madeline can only get the results at once after all queries are completed. The memory of this machine is not very large either, so Madeline can only ask $31$ times. She doesn't know how to solve it, so she invited you to help her.

Note that the interactor is non-adaptive. That is, tree is fixed in advance and doesn't change with your queries.

Input

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

The only line of each test case contains a single integer $n$ ($3\le n\le 5\cdot 10^4$) — the size of the tree.

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

Interaction

The interaction begins by reading the integer $n$.

Then, output a single integer $k$ ($1 \leq k \leq 31$) — the number of queries.

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

* $p_{i,1}\,p_{i,2}\,\ldots\,p_{i,n}$ ($1 \leq p_{i,j} \leq n$, the $p_{i,j}$ are distinct for each $i$) — a query described above.

Once you've asked all $k$ queries, read $k$ lines of $n$ integers $q_{i,j}$ — the responses to the queries as described above.

When you know the hidden tree, output $n-1$ lines in the following format:

* $u,v$ ($1\leq u,v\leq n$) — an edge $(u,v)$ in the hidden tree.

Then, move on to the next test case, or terminate the program if there are no more test cases.

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

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

Example

Input

```
3
3

0 1 2
0 0 2

4

0 1 1 3
0 1 1 3
0 1 2 3

5

0 0 1 3 4
```

Output

```
2
1 2 3
1 3 2

1 2
2 3

3
3 2 4 1
1 4 3 2
1 2 3 4

2 3
1 2
4 1

1
1 2 3 4 5

1 4
4 3
3 2
5 3
```

Note

Visualizer link

For the first test case:

* The first query has answer 0 1 2, since only edge $(1, 2)$ is in the induced subgraph formed by $\{1,2\}$.
* The second query has answer 0 0 2, since no edges are in the induced subgraph formed by $\{1,3\}$.

For the third test case:

* Edges $(2,3)$, $(3,4)$, and $(4,1)$ are in the induced subgraph formed by $\{1,2,3,4\}$, so $q_{1,4}=3$.

Non-adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;


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


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


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



void fail_query(const string& msg) {
    cout << "-1" << endl;
    finish(_wa, msg);
}

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

    
    
    int t = inf.readInt();
    
    
    query_limit = 31LL * t;
    
    
    
    
    cout << t << endl;

    
    for (int cas = 0; cas < t; ++cas) {
        
        int n = inf.readInt();
        vector<vector<int>> adj(n + 1);
        set<pair<int, int>> hidden_set;

        for (int i = 0; i < n - 1; ++i) {
            int u = inf.readInt();
            int v = inf.readInt();
            if (u > v) swap(u, v);
            adj[u].push_back(v);
            adj[v].push_back(u);
            hidden_set.insert({u, v});
        }

        
        cout << n << endl;

        
        int k;
        if (!(cin >> k)) {
            finish(_wa, "Unexpected EOF reading k");
        }
        
        
        queries += k;
        log_metrics(); 

        if (k < 1 || k > 31) {
            fail_query(format("k must be in [1, 31], read %d", k));
        }

        
        vector<vector<int>> perms(k, vector<int>(n));
        for (int i = 0; i < k; ++i) {
            vector<bool> used(n + 1, false);
            for (int j = 0; j < n; ++j) {
                if (!(cin >> perms[i][j])) {
                    fail_query("Unexpected EOF reading permutation");
                }
                int val = perms[i][j];
                if (val < 1 || val > n) {
                    fail_query(format("Permutation value out of range: %d", val));
                }
                if (used[val]) {
                    fail_query(format("Duplicate value in permutation: %d", val));
                }
                used[val] = true;
            }
        }

        
        for (int i = 0; i < k; ++i) {
            
            
            
            vector<int> q(n);
            vector<bool> active(n + 1, false);
            int current_edges = 0;
            
            for (int j = 0; j < n; ++j) {
                int u = perms[i][j];
                active[u] = true;
                for (int v : adj[u]) {
                    if (active[v]) current_edges++;
                }
                q[j] = current_edges;
            }
            
            
            for (int j = 0; j < n; ++j) {
                cout << q[j] << (j == n - 1 ? "" : " ");
            }
            cout << "\n";
        }
        cout.flush();

        
        set<pair<int, int>> user_edges;
        for (int i = 0; i < n - 1; ++i) {
            int u, v;
            if (!(cin >> u >> v)) {
                finish(_wa, "Unexpected EOF reading answer edges");
            }
            if (u < 1 || u > n || v < 1 || v > n) {
                finish(_wa, format("Edge vertex out of range: %d %d", u, v));
            }
            if (u == v) finish(_wa, "Self loop in answer");
            if (u > v) swap(u, v);
            
            if (user_edges.count({u, v})) {
                finish(_wa, format("Duplicate edge in answer: %d %d", u, v));
            }
            user_edges.insert({u, v});
        }

        
        if (user_edges.size() != hidden_set.size()) {
            finish(_wa, "Wrong number of unique edges");
        }
        for (auto& e : user_edges) {
            if (!hidden_set.count(e)) {
                finish(_wa, format("Edge (%d, %d) is not in the hidden tree", e.first, e.second));
            }
        }
    }

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


Adaptive interactor (C++):

Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;


vector<pair<int, int>> gen_uniform(int n) {
    if (n < 2) return {};
    if (n == 2) return {{1, 2}};
    vector<int> prufer(n - 2);
    vector<int> degree(n + 1, 1);
    for (int i = 0; i < n - 2; ++i) {
        prufer[i] = rnd.next(1, n);
        degree[prufer[i]]++;
    }

    set<int> leaves;
    for (int i = 1; i <= n; ++i) {
        if (degree[i] == 1) leaves.insert(i);
    }

    vector<pair<int, int>> edges;
    for (int v : prufer) {
        int leaf = *leaves.begin();
        leaves.erase(leaves.begin());
        edges.push_back({leaf, v});
        if (--degree[v] == 1) leaves.insert(v);
    }
    edges.push_back({*leaves.begin(), *leaves.rbegin()});
    return edges;
}



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

    for (int i = 1; i < n; ++i) {
        int u = p[i];
        int v = p[rnd.next(0, i - 1)];
        edges.push_back({u, v});
    }
    return edges;
}


vector<pair<int, int>> gen_path(int n) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());
    vector<pair<int, int>> edges;
    for (int i = 0; i < n - 1; ++i) {
        edges.push_back({p[i], p[i+1]});
    }
    return edges;
}


vector<pair<int, int>> gen_star(int n) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());
    vector<pair<int, int>> edges;
    for (int i = 1; i < n; ++i) {
        edges.push_back({p[0], p[i]});
    }
    return edges;
}


vector<pair<int, int>> gen_caterpillar(int n, int len) {
    if (len > n) len = n;
    if (len < 1) len = 1;
    
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());
    
    vector<pair<int, int>> edges;
    
    for (int i = 0; i < len - 1; ++i) {
        edges.push_back({p[i], p[i+1]});
    }
    
    for (int i = len; i < n; ++i) {
        int parent = p[rnd.next(0, len - 1)];
        edges.push_back({parent, p[i]});
    }
    return edges;
}


vector<pair<int, int>> gen_kary(int n, int k) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());
    
    vector<pair<int, int>> edges;
    for (int i = 1; i < n; ++i) {
        int parent = (i - 1) / k;
        edges.push_back({p[parent], p[i]});
    }
    return edges;
}

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

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

    
    long long seed_val = atoll(argv[1]);
    if (n == -1) {
        if (seed_val == 1) n = 3;
        else if (seed_val == 2) n = 10;
        else if (seed_val <= 5) n = 100;
        else {
             
             if (rnd.next(0, 1)) n = 50000;
             else n = rnd.next(40000, 50000);
        }
    }
    
    
    cout << 1 << "\n";
    
    cout << n << "\n";

    if (mode == "adp") {
        
        return 0;
    }

    
    int type = 0;
    
    if (seed_val == 1) type = 2; 
    else if (seed_val == 2) type = 0; 
    else if (seed_val == 3) type = 3; 
    else if (seed_val == 4) type = 2; 
    else if (seed_val == 5) type = 6; 
    else {
        
        type = rnd.next(0, 8);
    }

    vector<pair<int, int>> edges;
    switch(type) {
        case 0: edges = gen_uniform(n); break;
        case 1: edges = gen_random_attach(n); break;
        case 2: edges = gen_path(n); break;
        case 3: edges = gen_star(n); break;
        case 4: edges = gen_caterpillar(n, (int)(n * 0.8)); break;
        case 5: edges = gen_caterpillar(n, (int)(sqrt(n) + 1)); break;
        case 6: edges = gen_kary(n, 2); break;
        case 7: edges = gen_kary(n, 3); break;
        case 8: edges = gen_caterpillar(n, 10); break; 
        default: edges = gen_uniform(n); break;
    }

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

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

    return 0;
}