Problem: cf2152_e
Difficulty: hard
Categories: greedy, math
Time limit: 2000 ms, memory limit: 1024 MB

This is an interactive problem.

Faker is being naughty again. You asked him to create a nice query problem, but he created an interactive problem where he is answering a query instead! Faker hid a permutation from you, and you have to infer some interesting information by interacting with him.

You are given an integer $n$. Faker hid a hidden permutation$^{\text{∗}}$ $p_1, p_2, \ldots, p_{n^2+1}$ of length $n^2+1$. Your goal is to find a monotone subsequence (either increasing or decreasing) of the hidden permutation, with length exactly $n+1$. It can be proved that every permutation of length $n^2 + 1$ contains a monotone subsequence of length $n+1$. For more information about the proof, you can check out this Wikipedia page.

To find it, you can make at most $n$ skyscraper queries to the interactor, which is defined as follows:

* You provide a set of $k$ indices as a strictly increasing sequence: $i_1, i_2, \ldots, i_k$.
* The interactor considers the values of the hidden permutation at these indices: $p_{i_1}, p_{i_2}, \ldots, p_{i_k}$.
* The interactor then returns the indices corresponding to the visible skyscrapers from this set. An index $i_j$ is visible if its value $p_{i_j}$ is greater than the values of all preceding elements in your query, i.e., $p_{i_j} > p_{i_m}$ for all $1 \le m < j$. This is equivalent to finding the indices of the left-to-right maxima of the sequence $(p_{i_1}, \ldots, p_{i_k})$.

After making at most $n$ queries, you must report a valid monotone subsequence of length exactly $n+1$.

Note that the permutation $p$ is fixed before any queries are made and does not depend on the queries.

$^{\text{∗}}$A permutation of length $m$ is an array consisting of $m$ distinct integers from $1$ to $m$ in arbitrary order. For example, $[2,3,1,5,4]$ is a permutation, but $[1,2,2]$ is not a permutation ($2$ appears twice in the array), and $[1,3,4]$ is also not a permutation ($m=3$ but there is $4$ in the array).

Input

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

The first and only line of each test case contains a single integer $n$ ($1 \le n \le 100$).

It is guaranteed that the sum of $n^2+1$ over all test cases does not exceed $10\,001$.

Interaction

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

To make a query, print a line in the following format:

*? $k \; i_1 \; i_2 \; \ldots \; i_k$

where $k$ is the number of indices in your query ($1 \le k \le n^2+1$), and $i_1, \ldots, i_k$ are the indices themselves, satisfying $1 \le i_1 < i_2 < \ldots < i_k \le n^2+1$. The indices should be presented in sorted order.

In response, the interactor will print a line in the following format:

* $c \; j_1 \; j_2 \; \ldots \; j_c$

where $c$ is the number of visible skyscrapers from your query ($1 \le c \le k$), and $j_1, \ldots, j_c$ are their indices, satisfying $1 \le j_1 < j_2 < \ldots < j_c \le n^2+1$. The indices will be presented in sorted order.

To report your final answer, print a line in the following format:

*! $s_1 \; s_2 \; \ldots \; s_{n+1}$

where $s_1, \ldots, s_{n+1}$ are the indices of the elements that form your found monotone subsequence of length $n+1$, satisfying $1 \le s_1 < s_2 < \ldots < s_{n+1} \le n^2 + 1$. The indices should be presented in sorted order.

Note that answering does not count toward your limit of commands.

After printing the answer, your program should proceed to the next test case or terminate if there are no more.

After printing each query 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

```
2
1

2 1 2

2

1 1

2 2 3
```

Output

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

Note

For the first test case, $n=1$. The hidden permutation is $p=[1, 2]$.

* For the query? 2 1 2, the visible skyscrapers are at indices $1$ and $2$. The interactor returns 2 1 2.
* An increasing subsequence of length $2$ at indices $1, 2$ is reported.

For the second test case, $n=2$. The hidden permutation is $p=[5, 3, 4, 1, 2]$.

* For the query? 3 1 2 3, the visible skyscraper is at index $1$. The interactor returns 1 1.
* For the query? 3 2 3 5, the visible skyscrapers are at indices $2$ and $3$. The interactor returns 2 2 3.
* A decreasing subsequence of length $3$ at indices $1, 3, 4$ is reported.

Although Faker will play the role of interactor, the interactor will never lie to you.

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 << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {
        
    }
}

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

static bool isIntegerToken(const string& s) {
    if (s.empty()) return false;
    int i = 0;
    if (s[0] == '-') {
        if ((int)s.size() == 1) return false;
        i = 1;
    }
    for (; i < (int)s.size(); ++i) if (!isdigit((unsigned char)s[i])) return false;
    return true;
}

static long long readLLFromCinOrFail(const string& what) {
    string tok;
    if (!(cin >> tok)) finish(_pe, "Unexpected EOF while reading " + what);
    if (!isIntegerToken(tok)) finish(_pe, "Non-integer token for " + what);
    long long x = 0;
    try {
        x = stoll(tok);
    } catch (...) {
        finish(_pe, "Integer out of range for " + what);
    }
    return x;
}

static void sendMinusOneAndFail(TResult verdict, const string& msg) {
    cout << -1 << endl;
    cout.flush();
    finish(verdict, msg);
}

static bool isStrictlyIncreasingIndices(const vector<int>& idx, int m) {
    if (idx.empty()) return false;
    if (idx[0] < 1 || idx[0] > m) return false;
    for (int i = 1; i < (int)idx.size(); ++i) {
        if (idx[i] <= idx[i - 1]) return false;
        if (idx[i] < 1 || idx[i] > m) return false;
    }
    return true;
}

static bool isMonotoneByValues(const vector<int>& p, const vector<int>& pos) {
    if ((int)pos.size() <= 2) return true;
    bool inc = true, dec = true;
    for (int i = 1; i < (int)pos.size(); ++i) {
        int a = p[pos[i - 1]];
        int b = p[pos[i]];
        if (!(a < b)) inc = false;
        if (!(a > b)) dec = false;
    }
    return inc || dec;
}

struct CaseData {
    int n;
    int m;
    vector<int> p; 
};

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

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

    long long sumBudget = 0;
    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt(1, 100, "n");
        int m = n * n + 1;
        vector<int> p(m + 1, 0);
        for (int i = 1; i <= m; ++i) p[i] = inf.readInt(1, m, "p[i]");
        cases.push_back(CaseData{n, m, std::move(p)});
        sumBudget += n;
    }

    query_limit = sumBudget;
    log_metrics(); 

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

    cout << t << endl;
    cout.flush();

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

        cout << n << endl;
        cout.flush();

        while (true) {
            string cmd;
            if (!(cin >> cmd)) finish(_pe, "Unexpected EOF while waiting for command");
            if (cmd == "?") {
                long long kll = readLLFromCinOrFail("k");
                if (kll < 1 || kll > m) sendMinusOneAndFail(_pe, "Invalid k in query");
                int k = (int)kll;

                vector<int> idx(k);
                for (int i = 0; i < k; ++i) {
                    long long v = readLLFromCinOrFail("query index");
                    if (v < INT_MIN || v > INT_MAX) sendMinusOneAndFail(_pe, "Query index out of int range");
                    idx[i] = (int)v;
                }
                if (!isStrictlyIncreasingIndices(idx, m)) sendMinusOneAndFail(_pe, "Query indices not strictly increasing or out of range");

                ++queries;
                if (queries > hard_cap) sendMinusOneAndFail(_pe, "Hard cap exceeded (too many queries)");

                vector<int> visible;
                visible.reserve(k);
                int best = -1;
                for (int id : idx) {
                    int val = p[id];
                    if (val > best) {
                        best = val;
                        visible.push_back(id);
                    }
                }

                cout << (int)visible.size();
                for (int id : visible) cout << " " << id;
                cout << endl;
                cout.flush();
            } else if (cmd == "!") {
                vector<int> ans(n + 1);
                for (int i = 0; i < n + 1; ++i) {
                    long long v = readLLFromCinOrFail("answer index");
                    if (v < INT_MIN || v > INT_MAX) finish(_pe, "Answer index out of int range");
                    ans[i] = (int)v;
                }
                if (!isStrictlyIncreasingIndices(ans, m)) finish(_wa, "Answer indices not strictly increasing or out of range");
                if (!isMonotoneByValues(p, ans)) finish(_wa, "Answer is not a monotone subsequence by values");
                break; 
            } else {
                sendMinusOneAndFail(_pe, "Unknown command token");
            }
        }
    }

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


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 long long hard_cap = 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 reachable(int start, int target, const vector<vector<int>>& g, vector<int>& vis, int& vid) {
    if (start == target) return false;
    ++vid;
    const int mark = vid;
    deque<int> dq;
    vis[start] = mark;
    dq.push_back(start);
    while (!dq.empty()) {
        int u = dq.front();
        dq.pop_front();
        for (int v : g[u]) {
            if (v == target) return true;
            if (vis[v] == mark) continue;
            vis[v] = mark;
            dq.push_back(v);
        }
    }
    return false;
}

static bool forced_chain(const vector<vector<int>>& g, const vector<int>& s, bool increasing) {
    
    
    int m = (int)g.size() - 1;
    vector<int> vis(m + 1, 0);
    int vid = 0;
    for (int i = 0; i + 1 < (int)s.size(); ++i) {
        int a = increasing ? s[i] : s[i + 1];
        int b = increasing ? s[i + 1] : s[i];
        if (!reachable(a, b, g, vis, vid)) return false;
    }
    return true;
}

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

    int t = inf.readInt(1, 5000, "t");
    vector<int> ns(t);
    long long sumN = 0;
    for (int i = 0; i < t; ++i) {
        ns[i] = inf.readInt(1, 100, "n");
        sumN += ns[i];
    }

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

    
    log_metrics();

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

    for (int tc = 0; tc < t; ++tc) {
        int n = ns[tc];
        int m = n * n + 1;

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

        vector<vector<int>> g(m + 1);

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

            if (cmd == "?") {
                long long kll;
                if (!(cin >> kll)) finish(_pe, "failed to read k");
                if (kll < 1 || kll > m) finish(_pe, "k out of range");

                int k = (int)kll;
                vector<int> idx(k);
                for (int i = 0; i < k; ++i) {
                    long long xll;
                    if (!(cin >> xll)) finish(_pe, "failed to read query index");
                    if (xll < 1 || xll > m) finish(_pe, "query index out of range");
                    idx[i] = (int)xll;
                }
                for (int i = 1; i < k; ++i) {
                    if (idx[i - 1] >= idx[i]) finish(_pe, "query indices not strictly increasing");
                }

                int first = idx[0];
                for (int i = 1; i < k; ++i) {
                    
                    
                    g[idx[i]].push_back(first);
                }

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

                cout << 1 << " " << first << "\n";
                cout.flush();
            } else if (cmd == "!") {
                vector<int> s(n + 1);
                for (int i = 0; i < n + 1; ++i) {
                    long long xll;
                    if (!(cin >> xll)) finish(_pe, "failed to read final answer index");
                    if (xll < 1 || xll > m) finish(_pe, "final answer index out of range");
                    s[i] = (int)xll;
                }
                for (int i = 1; i < n + 1; ++i) {
                    if (s[i - 1] >= s[i]) finish(_pe, "final answer indices not strictly increasing");
                }

                bool ok = false;
                if (n + 1 <= 2) {
                    ok = true; 
                } else {
                    if (forced_chain(g, s, true)) ok = true;   
                    if (forced_chain(g, s, false)) ok = true;  
                }

                if (!ok) finish(_wa, "answer is not guaranteed monotone for all feasible permutations");
                break;
            } else {
                finish(_pe, "unknown command (expected ? or !)");
            }
        }
    }

    finish(_ok, "ok");
}


Test generator (C++):
#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 bool isMonotoneByPositions(const vector<int>& p, const vector<int>& pos) {
    if ((int)pos.size() <= 2) return true;
    bool inc = true, dec = true;
    for (int i = 1; i < (int)pos.size(); ++i) {
        int a = p[pos[i - 1]];
        int b = p[pos[i]];
        if (!(a < b)) inc = false;
        if (!(a > b)) dec = false;
    }
    return inc || dec;
}

static bool isMonotoneSegment(const vector<int>& p, int startPos, int len) {
    if (len <= 2) return true;
    bool inc = true, dec = true;
    for (int i = 1; i < len; ++i) {
        int a = p[startPos + i - 1];
        int b = p[startPos + i];
        if (!(a < b)) inc = false;
        if (!(a > b)) dec = false;
    }
    return inc || dec;
}

static vector<int> genHardPerm(int n, bool forceEarlyMaxInFirstGroup) {
    int m = n * n + 1;
    vector<int> p(m + 1, 0);
    p[1] = m;

    int writePos = 2;
    for (int j = n; j >= 1; --j) {
        vector<int> group;
        group.reserve(n);
        for (int b = 0; b < n; ++b) group.push_back(b * n + j); 
        shuffleVec(group);

        if (forceEarlyMaxInFirstGroup && j == n) {
            int target = n * n;
            for (int idx = 0; idx < n; ++idx) {
                if (group[idx] == target) {
                    swap(group[0], group[idx]);
                    break;
                }
            }
        }

        for (int x : group) p[writePos++] = x;
    }
    return p;
}

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

    string mode = opt<string>("mode", "non");
    long long seedVal = 0;
    if (argc >= 2) seedVal = atoll(argv[1]);

    int n = opt<int>("n", 100);
    n = max(1, min(100, n));

    if (seedVal == 1) n = 1;
    else if (seedVal == 2) n = 2;
    else if (seedVal == 3) n = 100;
    else {
        int bias = opt<int>("bias", 0); 
        if (bias != 0) {
            int lo = max(1, min(100, n - abs(bias)));
            int hi = max(1, min(100, n));
            if (lo > hi) swap(lo, hi);
            n = rnd.next(lo, hi);
        }
    }

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

    if (mode == "adp") {
        return 0;
    }
    if (mode != "non") {
        quitf(_fail, "unknown mode=%s", mode.c_str());
    }

    int m = n * n + 1;
    vector<int> p;

    if (seedVal == 1) {
        
        p.assign(m + 1, 0);
        p[1] = 2;
        p[2] = 1;
    } else if (seedVal == 2) {
        
        
        p.assign(m + 1, 0);
        p[1] = 5;
        p[2] = 2;
        p[3] = 4;
        p[4] = 1;
        p[5] = 3;
    } else {
        bool forceEarlyMax = opt<int>("forceEarlyMax", 1) != 0;

        
        
        const int maxAttempts = 2000;
        for (int attempt = 0; attempt < maxAttempts; ++attempt) {
            p = genHardPerm(n, forceEarlyMax);

            bool bad = false;

            
            if (isMonotoneSegment(p, 1, n + 1)) bad = true;
            if (isMonotoneSegment(p, m - n, n + 1)) bad = true;

            
            vector<int> groupFirst;
            groupFirst.reserve(n + 1);
            groupFirst.push_back(1);
            for (int t = 0; t < n; ++t) groupFirst.push_back(2 + t * n);
            if (isMonotoneByPositions(p, groupFirst)) bad = true;

            
            vector<int> groupLast;
            groupLast.reserve(n + 1);
            groupLast.push_back(1);
            for (int t = 0; t < n; ++t) groupLast.push_back(1 + (t + 1) * n + 1);
            if (isMonotoneByPositions(p, groupLast)) bad = true;

            
            if (m >= (n + 1) * (n + 1)) {
                vector<int> ap;
                ap.reserve(n + 1);
                int step = n + 1;
                int start = 1 + rnd.next(0, min(step - 1, 10));
                for (int k = 0; k <= n; ++k) {
                    int pos = start + k * step;
                    if (pos > m) break;
                    ap.push_back(pos);
                }
                if ((int)ap.size() == n + 1 && isMonotoneByPositions(p, ap)) bad = true;
            }

            if (!bad) break;
        }

        if ((int)p.size() != m + 1) quitf(_fail, "internal generation failed");
    }

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