Problem: cf1990_e1
Difficulty: easy
Categories: graph, search
Time limit: 4000 ms, memory limit: 256 MB

This is the easy version of the problem. The only difference is the limit on the number of queries.

This is an interactive problem.

You are given a tree of $n$ nodes with node $1$ as its root node.

There is a hidden mole in one of the nodes. To find its position, you can pick an integer $x$ ($1 \le x \le n$) to make an inquiry to the jury. Next, the jury will return $1$ when the mole is in subtree $x$. Otherwise, the judge will return $0$. If the judge returns $0$ and the mole is not in root node $1$, the mole will move to the parent node of the node it is currently on.

Use at most $300$ operations to find the current node where the mole is located.

Input

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

Interaction

The first line of each test case contains one integer $n$ ($2 \le n \le 5000$).

The following $n-1$ lines describe the edges of the tree. Each line contains two space-separated integers $u_i$ and $v_i$ ($1 \le u_i, v_i \le n$), indicating an edge between nodes $u_i$ and $v_i$.

It is guaranteed that the input data represents a tree.

The interactor in this task is not adaptive. In other words, the node where the mole is located at first is fixed in every test case and does not change during the interaction.

To ask a query, you need to pick a vertex $x$ ($1 \le x \le n$) and print the line of the following form:

* "? x"

After that, you receive:

* $0$ if the mole is not in subtree $x$;
* $1$ if the mole is in subtree $x$.

You can make at most $300$ queries of this form for each test case.

Next, if your program has found the current node where the mole is located, print the line of the following form:

* "! x"

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.

If you make more than $300$ queries during an interaction, your program must terminate immediately, and you will receive the 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 or the answer for a test case, do not forget to output the end of 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
2
1 2

1

6
1 2
1 3
1 4
4 5
5 6

0

0

1
```

Output

```
? 2

! 2

? 2

? 6

? 4

! 4
```

Note

In the first test case, the mole is in node $2$ initially.

For the query "? 2", the jury returns $1$ because the mole is in subtree $2$. After this query, the mole does not move.

The answer $2$ is the current node where the mole is located, so the answer is considered correct.

In the second test case, the mole is in node $6$ initially.

For the query "? 2", the jury returns $0$ because the mole is not in subtree $2$. After this query, the mole moves from node $6$ to node $5$.

For the query "? 6", the jury returns $0$ because the mole is not in subtree $6$. After this query, the mole moves from node $5$ to node $4$.

For the query "? 4", the jury returns $1$ because the mole is in subtree $4$. After this query, the mole does not move.

The answer $4$ is the current node where the mole is located, so the answer is considered correct.

Please note that the example is only for understanding the statement, and the queries in the example do not guarantee to determine the unique position of the mole.

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


static long long global_max_queries = 0;
static const long long QUERY_LIMIT_PER_CASE = 300;





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


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


int n;
vector<vector<int>> adj;
vector<int> tin_time, tout_time, parent;
int timer_dfs;
int mole;


void dfs(int u, int p) {
    tin_time[u] = ++timer_dfs;
    parent[u] = p;
    for (int v : adj[u]) {
        if (v != p) dfs(v, u);
    }
    tout_time[u] = timer_dfs;
}

void solve_test_case() {
    
    n = inf.readInt(2, 5000, "n");
    
    
    adj.assign(n + 1, vector<int>());
    vector<pair<int,int>> edges_list;
    
    for (int i = 0; i < n - 1; ++i) {
        int u = inf.readInt(1, n, "u");
        int v = inf.readInt(1, n, "v");
        adj[u].push_back(v);
        adj[v].push_back(u);
        edges_list.push_back({u, v});
    }
    
    mole = inf.readInt(1, n, "mole");

    
    cout << n << endl;
    for (auto& p : edges_list) {
        cout << p.first << " " << p.second << endl;
    }
    cout.flush();

    
    tin_time.assign(n + 1, 0);
    tout_time.assign(n + 1, 0);
    parent.assign(n + 1, 0);
    timer_dfs = 0;
    dfs(1, 0);

    int queries_this_case = 0;
    
    
    while (true) {
        
        if (queries_this_case > 0 && queries_this_case % 10 == 0) {
            log_metrics();
        }

        
        while (true) {
            int c = cin.peek();
            if (c == EOF) break;
            if (isspace(c)) {
                cin.get();
            } else {
                break;
            }
        }
        
        if (cin.peek() == EOF) {
            finish(_wa, "Unexpected EOF (expected query or answer)");
        }
        
        string token;
        cin >> token;

        if (token == "!") {
            
            int ans;
            if (!(cin >> ans)) {
                finish(_wa, "Failed to read answer index after '!'");
            }
            if (ans != mole) {
                finish(_wa, format("Incorrect answer. Expected %d, got %d", mole, ans));
            }
            
            return;
        } else {
            
            int x;
            if (token == "?") {
                if (!(cin >> x)) {
                     finish(_wa, "Failed to read query index after '?'");
                }
            } else {
                
                try {
                    size_t processed = 0;
                    x = stoi(token, &processed);
                    if (processed != token.size()) {
                        finish(_pe, "Invalid token format (expected integer or '?'/'!'): " + token);
                    }
                } catch (...) {
                    finish(_pe, "Invalid token format (expected integer or '?'/'!'): " + token);
                }
            }

            if (x < 1 || x > n) {
                finish(_pe, format("Query index out of range: %d", x));
            }

            
            queries_this_case++;
            if (queries_this_case > global_max_queries) {
                global_max_queries = queries_this_case;
            }
            
            
            if (queries_this_case > QUERY_LIMIT_PER_CASE) {
                finish(_wa, "Too many queries used in a single test case");
            }

            
            bool in_subtree = (tin_time[x] <= tin_time[mole] && tout_time[mole] <= tout_time[x]);
            
            cout << (in_subtree ? 1 : 0) << endl;
            

            
            if (!in_subtree) {
                if (mole != 1) {
                    mole = parent[mole];
                }
            }
        }
    }
}

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

    int t = inf.readInt(1, 100, "t");
    cout << t << endl;

    for (int i = 0; i < t; ++i) {
        solve_test_case();
    }

    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_tree(int n, string type) {
    vector<pair<int,int>> edges;
    if (type == "line") {
        for (int i = 2; i <= n; ++i) edges.push_back({i - 1, i});
    } else if (type == "star") {
        for (int i = 2; i <= n; ++i) edges.push_back({1, i});
    } else if (type == "random") {
        for (int i = 2; i <= n; ++i) edges.push_back({rnd.next(1, i - 1), i});
    } else if (type == "binary") {
        for (int i = 2; i <= n; ++i) edges.push_back({i / 2, i});
    } else if (type == "caterpillar") {
        int len = rnd.next(max(2, n / 2), n);
        
        for (int i = 2; i <= len; ++i) edges.push_back({i - 1, i});
        
        for (int i = len + 1; i <= n; ++i) edges.push_back({rnd.next(1, len), i});
    } else if (type == "broom") {
        int len = rnd.next(max(1, n / 3), 2 * n / 3);
        if (len < 1) len = 1;
        for (int i = 2; i <= len; ++i) edges.push_back({i - 1, i});
        
        for (int i = len + 1; i <= n; ++i) edges.push_back({len, i});
    }

    
    
    vector<int> p(n + 1);
    p[1] = 1;
    vector<int> others;
    for (int i = 2; i <= n; ++i) others.push_back(i);
    shuffle(others.begin(), others.end());
    for (int i = 0; i < (int)others.size(); ++i) p[others[i]] = i + 2;

    vector<pair<int,int>> final_edges;
    for (auto e : edges) {
        final_edges.push_back({p[e.first], p[e.second]});
    }
    return final_edges;
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    string mode = opt<string>("mode", "non");
    
    int seed_val = 0;
    if (argc > 1) seed_val = atoi(argv[1]);

    
    if (seed_val == 1) {
        int t = 4;
        println(t);

        
        println(2);
        println(1, 2);
        if (mode == "non") println(2);

        
        println(3);
        println(1, 2);
        println(1, 3);
        if (mode == "non") println(3);

        
        println(4);
        println(1, 2); println(2, 3); println(3, 4);
        if (mode == "non") println(4);

        
        println(5);
        println(1, 2); println(1, 3); println(1, 4); println(4, 5);
        if (mode == "non") println(5);

        return 0;
    }

    
    string forced_type = "";
    if (seed_val == 2) forced_type = "line";
    else if (seed_val == 3) forced_type = "star";
    else if (seed_val == 4) forced_type = "binary";

    int t = rnd.next(5, 15);
    int total_n = 5000;
    
    
    auto ns_ll = rnd.partition(t, (long long)total_n, 2LL);
    vector<int> ns;
    for(auto val : ns_ll) ns.push_back((int)val);

    println(t);
    for (int n : ns) {
        string type = forced_type;
        if (type.empty()) {
            int r = rnd.next(1, 100);
            if (r <= 30) type = "random";
            else if (r <= 50) type = "line";
            else if (r <= 60) type = "star";
            else if (r <= 75) type = "binary";
            else if (r <= 90) type = "caterpillar";
            else type = "broom";
        }

        vector<pair<int,int>> edges = gen_tree(n, type);
        println(n);
        for (auto e : edges) println(e.first, e.second);

        if (mode == "non") {
            
            vector<vector<int>> adj(n + 1);
            for (auto e : edges) {
                adj[e.first].push_back(e.second);
                adj[e.second].push_back(e.first);
            }
            vector<int> depth(n + 1, 0);
            vector<int> q;
            q.reserve(n);
            q.push_back(1);
            vector<bool> vis(n + 1, false);
            vis[1] = true;
            
            int head = 0;
            while(head < (int)q.size()){
                int u = q[head++];
                for(int v : adj[u]){
                    if(!vis[v]){
                        vis[v] = true;
                        depth[v] = depth[u] + 1;
                        q.push_back(v);
                    }
                }
            }

            int max_d = 0;
            for(int i=1; i<=n; ++i) max_d = max(max_d, depth[i]);
            
            
            vector<int> candidates;
            for(int i=1; i<=n; ++i) {
                if(depth[i] >= max(1, max_d / 2)) candidates.push_back(i);
            }
            if(candidates.empty()) candidates.push_back(n); 

            int mole = candidates[rnd.next(0, (int)candidates.size() - 1)];
            println(mole);
        }
    }

    return 0;
}