Problem: cf2133_c
Difficulty: easy
Categories: graph, search
Time limit: 3000 ms, memory limit: 256 MB

This is an interactive problem.

Having recently discovered The Nether, Steve has built a network of $n$ nether portals, each at a different location in his world.

Each portal is connected in one direction to some number (possibly zero) of other portals. To avoid getting lost, Steve has carefully built the network of portals so that there is no sequence of jumps through portals that will bring you from a location back to itself; formally, the network forms a directed acyclic graph.

Steve refuses to tell you which portals are connected to which, but he will allow you to ask queries. In each query, you give Steve a set of locations $S = \{s_1, s_2, \ldots, s_k\}$ and a starting location $x \in S$. Steve will figure out the longest path starting at $x$ that only passes through locations in $S$ and tell you the number of locations in it. (If it is impossible to reach any other location in $S$ from $x$, Steve will reply with $1$.)

As you are looking to obtain the achievement "Hot Tourist Destinations", you want to find any path that visits as many locations as possible. Steve is feeling particularly generous and will give you $2 \cdot n$ queries to find it.

Input

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

The only line of each test case contains a single integer $n$ ($2 \le n \le 500$) — the number of locations.

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

Interaction

The interaction for each test case begins with reading the integer $n$. Then you can make up to $2 \cdot n$ queries.

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

* $\texttt{?}\,\,x\,\,k\,\,s_1\,s_2\,\ldots\,s_k$

The jury will return the answer to the query.

When you find a path with maximum length, output a single line in the following format:

* $\texttt{!}\,\,k\,\,v_1\,v_2\,\ldots\,v_k$

This denotes starting at portal $v_1$, then jumping to $v_2$, then to $v_3$ and so on, ending at $v_k$.

Note that outputting the answer does not count towards the limit of $2 \cdot n$ queries.

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.

The interactor is not adaptive. The connections between portals do not change during the interaction.

Example

Input

```
2
5

3

3

2

1

2

1

1
```

Output

```
? 1 4 1 2 3 4

? 3 3 4 3 2

? 5 2 1 5

? 2 2 2 4

! 4 5 1 4 2

? 1 2 1 2

? 2 2 1 2

! 1 1
```

Note

In the first test case, the network of portals is as follows:

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

* The longest path starting at location $1$ passing only through $\{1, 2, 3, 4\}$ is the path $1 \rightarrow 4 \rightarrow 2$, which has $3$ distinct locations.
* The longest path starting at location $3$ passing only through $\{2, 3, 4\}$ is the path $3 \rightarrow 4 \rightarrow 2$, which has $3$ distinct locations.
* The longest path starting at location $5$ passing only through $\{1, 5\}$ is the path $5 \rightarrow 1$, which has $2$ distinct locations.
* It is impossible to get to any other location in $\{2, 4\}$ starting from $2$, so Steve answers $1$ for that query.

Using the information from these queries, it is possible to determine that a longest path is $5 \rightarrow 1 \rightarrow 4 \rightarrow 2$.

In the second test case, the network of portals is as follows:

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

Neither of the portals is connected to the other, so the longest path is a single location. Note that ! 1 2 would also be a valid answer.

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








int get_global_longest(int u, const vector<vector<int>>& adj, vector<int>& memo) {
    if (memo[u] != -1) return memo[u];
    int res = 1;
    for (int v : adj[u]) {
        res = max(res, 1 + get_global_longest(v, adj, memo));
    }
    return memo[u] = res;
}




int solve_query(int start_node, const vector<int>& S, const vector<vector<int>>& adj) {
    
    
    static vector<bool> in_S;
    if (in_S.size() <= adj.size()) in_S.resize(adj.size() + 1, false);
    
    for (int u : S) in_S[u] = true;

    
    static vector<int> memo;
    if (memo.size() <= adj.size()) memo.resize(adj.size() + 1);
    
    
    
    fill(memo.begin(), memo.end(), -1);

    
    auto dfs = [&](auto&& self, int u) -> int {
        if (memo[u] != -1) return memo[u];
        int res = 1;
        
        for (int v : adj[u]) {
            if (in_S[v]) {
                res = max(res, 1 + self(self, v));
            }
        }
        return memo[u] = res;
    };

    int ans = dfs(dfs, start_node);

    
    for (int u : S) in_S[u] = false;

    return ans;
}

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

    
    int t = inf.readInt();
    
    cout << t << endl; 

    
    for (int cas = 1; cas <= t; cas++) {
        
        int n = inf.readInt();
        int m = inf.readInt();

        
        long long current_limit = 2LL * n;
        query_limit += current_limit;
        
        
        log_metrics();

        
        vector<vector<int>> adj(n + 1);
        for (int i = 0; i < m; i++) {
            int u = inf.readInt();
            int v = inf.readInt();
            adj[u].push_back(v);
        }

        
        int global_max = 0;
        {
            vector<int> memo(n + 1, -1);
            for (int i = 1; i <= n; i++) {
                global_max = max(global_max, get_global_longest(i, adj, memo));
            }
        }

        
        cout << n << endl;

        
        bool active = true;
        int queries_in_case = 0;
        
        int hard_cap = max(200000, 10 * (int)current_limit);

        while (active) {
            string token;
            
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF (expected query '?' or answer '!')");
            }

            if (token == "!") {
                
                int k;
                if (!(cin >> k)) finish(_wa, "Expected path length k after '!'");
                
                vector<int> path(k);
                for (int i = 0; i < k; i++) {
                    if (!(cin >> path[i])) finish(_wa, "Expected path vertex");
                }

                
                if (k != global_max) {
                    finish(_wa, format("Incorrect path length: got %d, expected %d", k, global_max));
                }

                
                if (k > 0) {
                    
                    if (path[0] < 1 || path[0] > n) finish(_wa, format("Vertex %d out of bounds", path[0]));

                    for (int i = 0; i < k - 1; i++) {
                        int u = path[i];
                        int v = path[i+1];

                        
                        if (v < 1 || v > n) finish(_wa, format("Vertex %d out of bounds", v));

                        
                        bool edge_exists = false;
                        for (int neighbor : adj[u]) {
                            if (neighbor == v) {
                                edge_exists = true;
                                break;
                            }
                        }
                        if (!edge_exists) {
                            finish(_wa, format("No edge exists from %d to %d", u, v));
                        }
                    }
                } else if (global_max > 0) {
                    
                    finish(_wa, "Path length cannot be 0");
                }

                
                
                active = false;

            } else {
                
                
                int x;
                if (token == "?") {
                    if (!(cin >> x)) finish(_wa, "Expected x after '?'");
                } else {
                    
                    try {
                        x = stoi(token);
                    } catch (...) {
                        finish(_wa, "Invalid token (expected '!', '?' or integer)");
                    }
                }

                int k_sz;
                if (!(cin >> k_sz)) finish(_wa, "Expected set size k");

                vector<int> S(k_sz);
                bool x_in_S = false;
                for (int i = 0; i < k_sz; i++) {
                    if (!(cin >> S[i])) finish(_wa, "Expected set element");
                    if (S[i] < 1 || S[i] > n) finish(_wa, "Set element out of bounds");
                    if (S[i] == x) x_in_S = true;
                }

                if (!x_in_S) {
                    finish(_wa, "Starting location x must be in set S");
                }

                
                queries++;
                queries_in_case++;
                if (queries % 10 == 0) log_metrics(); 

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

                
                int ans = solve_query(x, S, adj);
                cout << ans << endl;
            }
        }
    }

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


Adaptive interactor (C++):

Test generator (C++):
#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 seed_val = atoi(argv[1]);

    int t = 0;
    vector<int> ns;

    
    if (seed_val == 1) {
        
        t = 3;
        ns = {2, 5, 5};
    } else if (seed_val == 2) {
        
        t = 1;
        ns = {500};
    } else if (seed_val == 3) {
        
        t = 1;
        ns = {500};
    } else {
        
        long long limit = 124000000; 
        long long current = 0;
        
        while (t < 1000) {
            int n;
            int r = rnd.next(100);
            
            if (r < 50) n = rnd.next(2, 20);
            else if (r < 90) n = rnd.next(20, 100);
            else n = rnd.next(100, 500);

            long long cost = (long long)n * n * n;
            if (current + cost > limit) break;
            
            ns.push_back(n);
            current += cost;
            t++;
        }
        
        if (t == 0) {
            t = 1;
            ns.push_back(500);
        }
    }

    cout << t << endl;

    for (int i = 0; i < t; i++) {
        int n = ns[i];
        if (mode == "adp") {
            
            cout << n << endl;
        } else {
            
            
            vector<int> p(n);
            iota(p.begin(), p.end(), 1);
            shuffle(p.begin(), p.end());

            vector<pair<int, int>> edges;

            if (seed_val == 1) {
                if (i == 0) {
                    
                    edges.push_back({1, 2});
                } else if (i == 1) {
                    
                    for (int k = 1; k < 5; k++) edges.push_back({k, k + 1});
                }
                
            } else {
                int type = rnd.next(3);
                if (seed_val == 2) type = 0; 
                if (seed_val == 3) type = 1; 

                if (type == 0) { 
                    double prob = rnd.next(0.1, 0.8);
                    for (int u = 0; u < n; u++) {
                        for (int v = u + 1; v < n; v++) {
                            if (rnd.next(0.0, 1.0) < prob) {
                                edges.push_back({p[u], p[v]});
                            }
                        }
                    }
                } else if (type == 1) { 
                    
                    int len = rnd.next(n / 2, n);
                    for (int k = 0; k < len - 1; k++) {
                        edges.push_back({p[k], p[k + 1]});
                    }
                    
                    int m_noise = rnd.next(0, n * 5);
                    for (int k = 0; k < m_noise; k++) {
                        int u = rnd.next(0, n - 2);
                        int v = rnd.next(u + 1, n - 1);
                        edges.push_back({p[u], p[v]});
                    }
                } else { 
                    int m = rnd.next(0, min(n * (n - 1) / 2, n * 10));
                    set<pair<int, int>> distinct_indices;
                    int attempts = 0;
                    while ((int)distinct_indices.size() < m && attempts < m * 3) {
                        int u = rnd.next(0, n - 2);
                        int v = rnd.next(u + 1, n - 1);
                        if (distinct_indices.find({u, v}) == distinct_indices.end()) {
                            distinct_indices.insert({u, v});
                            edges.push_back({p[u], p[v]});
                        }
                        attempts++;
                    }
                }
            }

            
            sort(edges.begin(), edges.end());
            edges.erase(unique(edges.begin(), edges.end()), edges.end());
            shuffle(edges.begin(), edges.end());

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

    return 0;
}