Problem: cf2129_f2
Difficulty: medium
Categories: data structures
Time limit: 3000 ms, memory limit: 256 MB

This is an interactive problem.

This is the hard version of the problem. The only difference is that $n \le 890$ in this version.

There is a hidden permutation $p$, which is a permutation of $\{1,2,\ldots,n\}$. Let $pos_i$ denote the position of the value $i$ in $p$, i.e., $pos_{p_i} = i$.

To find this permutation, you can ask four types of queries:

* "$1\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ \ldots,\ i_m$ must be distinct). Let $k = \min(60, m)$. The jury will return the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, \ldots, p_{i_m}]$ in increasing order.
* "$2\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ \ldots,\ i_m$ must be distinct). Let $k = \min(60, m)$. The jury will return the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.
* "$3\ m\ i_1\ i_2\ ...\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ ...,\ i_m$ must be distinct). Let $k = \min(300, m)$. The jury will return the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, ..., p_{i_m}]$ in increasing order.
* "$4\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ \ldots,\ i_m$ must be distinct). Let $k = \min(300, m)$. The jury will return the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.

Let $c_i$ be the usage count of queries of type $i$ $(1 \le i \le 4)$. Your query count must satisfy the following constraints:

* $c_1+c_2+c_3+c_4 \le 30.$
* $c_3+c_4 \le 1.$

Input

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

Interaction

The first line of each test case contains one integer $n$ ($2 \le n \le 890$). At this moment, the permutation $p$ is chosen. The interactor in this task is not adaptive. In other words, the permutation $p$ is fixed in every test case and does not change during the interaction.

To ask a query of type $1$, you need to print the line of the following form (without quotes):

* "$1\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(60,m)$ integer(s) — the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, \ldots, p_{i_m}]$ in increasing order.

To ask a query of type $2$, you need to print the line of the following form (without quotes):

* "$2\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(60,m)$ integer(s) — the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.

To ask a query of type $3$, you need to print the line of the following form (without quotes):

* "$3\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(300,m)$ integer(s) — the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, \ldots, p_{i_m}]$ in increasing order.

To ask a query of type $4$, you need to print the line of the following form (without quotes):

* "$4\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(300,m)$ integer(s) — the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.

Next, if your program has found the permutation $p$, print the line of the following form (without quotes):

* "$!\ p_1\ p_2\ \ldots\ p_n$"

Note that this line is not considered a query and is not taken into account when counting the number of queries asked.

After this, proceed to the next test case.

After printing a query or the answer for a test case, do not forget to output the end of the line and flush the output. Otherwise, you will get the verdict 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

```
2
3

2 3

3

2

2
```

Output

```
3 2 3 1

2 1 2

! 3 1 2

4 1 1

! 2 1
```

Note

In the first test case, the hidden permutation is $p = [3, 1, 2]$. Thus, $pos = [2, 3, 1]$.

For the query "3 2 3 1", the jury returns $2$ and $3$ because $2$ and $3$ are the top $k$ largest number(s) in $[p_3, p_1]$, where $k = \min(300, m) = \min(300, 2) = 2$.

For the query "2 1 2", the jury returns $3$ because $3$ is the top $k$ largest number in $[pos_2]$, where $k = \min(60, m) = \min(60, 1) = 1$.

Note that the example is only for understanding the statement and does not guarantee finding the unique permutation $p$.

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;

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

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

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

static bool parseLongLongStrict(const string& s, long long& out) {
    if (s.empty()) return false;
    size_t i = 0;
    bool neg = false;
    if (s[0] == '-') {
        neg = true;
        i = 1;
    }
    if (i == s.size()) return false;
    for (; i < s.size(); i++) {
        if (s[i] < '0' || s[i] > '9') return false;
    }
    try {
        size_t pos = 0;
        long long v = stoll(s, &pos, 10);
        if (pos != s.size()) return false;
        out = v;
        return true;
    } catch (...) {
        return false;
    }
}

static long long readIntFromContestantOrDie(const string& what) {
    string tok;
    if (!readToken(tok)) finish(_wa, "unexpected EOF while reading " + what);
    long long v;
    if (!parseLongLongStrict(tok, v)) finish(_pe, "invalid integer token while reading " + what);
    return v;
}

static void printList(const vector<int>& a) {
    for (int i = 0; i < (int)a.size(); i++) {
        if (i) cout << ' ';
        cout << a[i];
    }
    cout << '\n';
    cout.flush();
}

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

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

    query_limit = 30LL * t;
    log_metrics(); 

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

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

    for (int tc = 1; tc <= t; tc++) {
        int n;
        try {
            n = inf.readInt(2, 890, "n");
        } catch (...) {
            finish(_pe, "failed to read hidden n");
        }

        vector<int> p(n + 1, 0);
        vector<int> pos(n + 1, 0);
        vector<int> seen(n + 1, 0);

        for (int i = 1; i <= n; i++) {
            int v;
            try {
                v = inf.readInt(1, n, "p_i");
            } catch (...) {
                finish(_pe, "failed to read hidden permutation");
            }
            if (seen[v]++) finish(_pe, "hidden permutation has duplicates");
            p[i] = v;
            pos[v] = i;
        }

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

        while (true) {
            string first;
            if (!readToken(first)) finish(_wa, "unexpected EOF (no answer for a test case)");

            if (first == "!") {
                vector<int> ans(n + 1, 0);
                vector<int> used(n + 1, 0);
                for (int i = 1; i <= n; i++) {
                    long long x = readIntFromContestantOrDie("answer permutation");
                    if (x < 1 || x > n) finish(_pe, "answer value out of range");
                    if (used[(int)x]++) finish(_pe, "answer is not a permutation (duplicate)");
                    ans[i] = (int)x;
                }
                for (int i = 1; i <= n; i++) {
                    if (ans[i] != p[i]) finish(_wa, "wrong permutation");
                }
                break; 
            }

            long long typLL;
            if (!parseLongLongStrict(first, typLL)) finish(_pe, "invalid query type token");
            if (typLL < 1 || typLL > 4) finish(_pe, "query type out of range");
            int typ = (int)typLL;

            long long mLL = readIntFromContestantOrDie("m");
            if (mLL < 1 || mLL > n) finish(_pe, "m out of range");
            int m = (int)mLL;

            vector<int> idx(m);
            vector<char> used(n + 1, 0);
            for (int i = 0; i < m; i++) {
                long long xLL = readIntFromContestantOrDie("index/value");
                if (xLL < 1 || xLL > n) finish(_pe, "index/value out of range");
                int x = (int)xLL;
                if (used[x]) finish(_pe, "duplicate index/value in a query");
                used[x] = 1;
                idx[i] = x;
            }

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

            int k = 0;
            if (typ == 1 || typ == 2) k = min(60, m);
            else k = min(300, m);

            vector<int> vals;
            vals.reserve(m);
            if (typ == 1 || typ == 3) {
                for (int x : idx) vals.push_back(p[x]);
            } else {
                for (int x : idx) vals.push_back(pos[x]);
            }

            sort(vals.begin(), vals.end());
            vector<int> out;
            out.reserve(k);
            for (int i = m - k; i < m; i++) out.push_back(vals[i]);

            printList(out);
        }
    }

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


Adaptive interactor (C++):

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

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

static int pickCoprimeStep(int n) {
    if (n <= 2) return 1;
    for (int attempts = 0; attempts < 20000; attempts++) {
        int step = rnd.next(1, n - 1);
        if (std::gcd(step, n) == 1) return step;
    }
    for (int step = 1; step < n; step++) {
        if (std::gcd(step, n) == 1) return step;
    }
    return 1;
}

static vector<int> bitReversalOrder0(int n) {
    int N = 1;
    while (N < n) N <<= 1;
    int lg = 0;
    while ((1 << lg) < N) lg++;

    vector<int> order;
    order.reserve(n);
    for (int x = 0; x < N; x++) {
        int r = 0;
        for (int b = 0; b < lg; b++) {
            if (x & (1 << b)) r |= 1 << (lg - 1 - b);
        }
        if (r < n) order.push_back(r);
    }
    
    if ((int)order.size() != n) {
        
        order.clear();
        order.reserve(n);
        for (int i = 0; i < n; i++) order.push_back(i);
    }
    return order;
}

static vector<int> buildCornerMin(int n) {
    vector<int> p(n + 1, 0);
    if (n == 2) {
        p[1] = 2;
        p[2] = 1;
    } else {
        for (int i = 1; i <= n; i++) p[i] = i;
    }
    return p;
}

static vector<int> buildCornerK60(int n) {
    vector<int> p(n + 1, 0);
    int lo = 1, hi = n;
    for (int i = 1; i <= n; i++) {
        if (i & 1) p[i] = hi--;
        else p[i] = lo++;
    }
    return p;
}

static vector<int> buildBitRevAlternating(int n) {
    vector<int> p(n + 1, 0);
    vector<int> ord0 = bitReversalOrder0(n);
    int lo = 1, hi = n;
    for (int i = 0; i < n; i++) {
        int pos = ord0[i] + 1;
        int v = (i % 2 == 0) ? hi-- : lo++;
        p[pos] = v;
    }
    return p;
}

static vector<int> buildSpreadTopStructured(int n, int topCount) {
    topCount = max(1, min(topCount, n));
    vector<int> p(n + 1, 0);

    int step = pickCoprimeStep(n);
    int offset0 = rnd.next(0, n - 1);

    vector<int> seqPos;
    seqPos.reserve(n);
    for (int i = 0; i < n; i++) {
        int pos = (offset0 + (int)((1LL * i * step) % n)) % n;
        seqPos.push_back(pos + 1);
    }

    
    for (int i = 0; i < topCount; i++) {
        p[seqPos[i]] = n - i;
    }

    int remaining = n - topCount;
    vector<int> vals;
    vals.reserve(remaining);

    
    int lo = 1, hi = remaining;
    while (lo <= hi) {
        vals.push_back(hi--);
        if (lo <= hi) vals.push_back(lo++);
    }

    
    int swaps = min(5000, max(0, remaining * 4));
    for (int s = 0; s < swaps; s++) {
        int i = rnd.next(0, remaining - 1);
        int j = rnd.next(0, remaining - 1);
        swap(vals[i], vals[j]);
    }
    int B = rnd.next(5, 13);
    for (int l = 0; l < remaining; l += B) {
        int r = min(remaining, l + B);
        if (rnd.next(0, 1) == 1) reverse(vals.begin() + l, vals.begin() + r);
    }

    
    for (int i = topCount; i < n; i++) {
        p[seqPos[i]] = vals[i - topCount];
    }

    return p;
}

static void validatePermutationOrDie(const vector<int>& p) {
    int n = (int)p.size() - 1;
    vector<int> seen(n + 1, 0);
    for (int i = 1; i <= n; i++) {
        if (p[i] < 1 || p[i] > n) quitf(_fail, "invalid value");
        if (seen[p[i]]++) quitf(_fail, "duplicate value");
    }
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", -1);
    int topOpt = opt<int>("top", 300);
    string pattern = opt<string>("pattern", "auto");

    if (mode != "non" && mode != "adp") quitf(_fail, "unknown --mode");

    int n;
    int seed = 1;
    if (argc >= 2) {
        
        
        bool ok = true;
        for (char c : string(argv[1])) if (!(c == '-' || (c >= '0' && c <= '9'))) ok = false;
        if (ok) {
            try {
                seed = stoi(string(argv[1]));
            } catch (...) {
                seed = 1000000007;
            }
        } else {
            seed = 1000000007;
        }
    }

    if (nOpt != -1) {
        n = nOpt;
    } else if (seed == 1) {
        n = 2;
    } else if (seed == 2) {
        n = 61; 
    } else if (seed == 3) {
        n = 890; 
    } else {
        
        int wiggle = rnd.next(0, 40); 
        n = 890 - wiggle;
    }

    if (n < 2 || n > 890) quitf(_fail, "n out of bounds");

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

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

    vector<int> p;
    if (seed == 1) {
        p = buildCornerMin(n);
    } else if (seed == 2) {
        p = buildCornerK60(n);
    } else if (seed == 3) {
        p = buildBitRevAlternating(n);
    } else {
        if (pattern == "auto") {
            int v = rnd.next(0, 2);
            if (v == 0) pattern = "spread";
            else if (v == 1) pattern = "bitrev";
            else pattern = "rev";
        }

        if (pattern == "spread") {
            int topCount = min(n, max(1, topOpt));
            p = buildSpreadTopStructured(n, topCount);
        } else if (pattern == "bitrev") {
            p = buildBitRevAlternating(n);
        } else if (pattern == "rev") {
            p.assign(n + 1, 0);
            for (int i = 1; i <= n; i++) p[i] = n - i + 1;
            
            int swaps = min(2000, n * 2);
            for (int s = 0; s < swaps; s++) {
                int i = rnd.next(1, n);
                int j = rnd.next(1, n);
                swap(p[i], p[j]);
            }
        } else {
            
            int topCount = min(n, max(1, topOpt));
            p = buildSpreadTopStructured(n, topCount);
        }
    }

    validatePermutationOrDie(p);

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