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

This is the Hard Version of the problem. The only difference between the two versions is that in the Hard Version the tree may be of any shape.

This problem is interactive.

Baudelaire is very rich, so he bought a tree of size $n$, rooted at some arbitrary node. Additionally, every node has a value of $1$ or $-1$.

Cow the Nerd saw the tree and fell in love with it. However, computer science doesn't pay him enough, so he can't afford to buy it. Baudelaire decided to play a game with Cow the Nerd, and if he won, he would gift him the tree.

Cow the Nerd does not know which node is the root, and he doesn't know the values of the nodes either. However, he can ask Baudelaire queries of two types:

* $1$ $k$ $u_1$ $u_2$ $...$ $u_k$: Let $f(u)$ be the sum of the values of all nodes in the path from the root of the tree to node $u$. Cow the Nerd may choose an integer $k$ $(1 \le k \le n)$ and $k$ nodes $u_1, u_2, ..., u_k$, and he will receive the value $f(u_1) + f(u_2) + ... + f(u_k)$.
* $2$ $u$: Baudelaire will toggle the value of node $u$. Specifically, if the value of $u$ is $1$, it will become $-1$, and vice versa.

Cow the Nerd wins if he guesses the value of every node correctly (the values of the final tree, after performing the queries) within $n + 200$ total queries. Can you help him win?

Input

The first line of the input contains a single integer $t$ $(1 \le t \le 100)$, the number of test cases.

The first line of each test case contains a single integer $n$ $(2 \le n \le 10^3)$, the size of the tree.

Each of the next $n-1$ lines contains two integers $u$ and $v$ $(1 \le u, v \le n, u \neq v)$, denoting an edge between nodes $u$ and $v$ in the tree.

It is guaranteed that the sum of $n$ over all test cases does not exceed $10^3$ and that each graph provided is a valid tree.

Interaction

To ask a query of type $1$, output a line in the following format (without the quotes):

* "? 1 k $u_1$ $u_2$ $...$ $u_k$", ($1 \le k, u_i \le n$)

The jury will return a single integer, $f(u_1) + f(u_2) + ... + f(u_k)$.

To ask a query of type $2$, output a line in the following format:

* "? 2 $u$" ($1 \le u \le n$)

The jury will toggle the value of node $u$: if its value is $1$, it will become $-1$ and vice versa.

When you have found the answer, output a single line in the following format:

* "! $v_1, v_2, ..., v_n$" ($v_i = 1$ or $v_i = -1$, and $v_i$ is the value of node $i$ after performing the queries)

After that, proceed to process the next test case or terminate the program if it was the last test case. Printing the answer does not count as a query.

The interactor is not adaptive, meaning that the values of the tree are known before the participant asks the queries.

If your program makes more than $n + 200$ queries, your program should immediately terminate to receive the verdict Wrong Answer. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

After printing a query do not forget to output the end of line and flush the output. Otherwise, you may get the Idleness Limit Exceeded verdict. 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

```
3
4
1 4
4 2
2 3

1

-1

-5

-5

2
1 2

2

7
1 2
2 7
7 3
7 4
7 5
7 6

-1
```

Output

```
? 1 3 1 2 4

? 1 2 3 1

? 2 4
? 1 3 1 2 4

? 1 2 3 1

! -1 -1 -1 -1

? 1 1 1

! 1 1

? 1 1 1

! -1 1 1 1 1 1 -1
```

Note

In the first example, the root of the tree is node $4$ and the values are: $[-1, -1, -1, 1]$ (the $i$-th value is the value of node $i$).

Initially, $f(1) = 0, f(2) = 0, f(3) = -1, f(4) = 1$. Therefore, the answer to our first query is $f(1) + f(2) + f(4) = 1$, and of the second query is $f(3) + f(1) = -1$.

After toggling the value of node $4$, the values are $[-1, -1, -1, -1]$. In addition, $f(1) = -2, f(2) = -2, f(3) = -3, f(4) = -1$. Therefore, $f(1) + f(2) + f(4) = -5$ and $f(3) + f(1) = -5$.

We answer that the final values of the nodes are $[-1, -1, -1, -1]$, which is correct. Notice that we report the values of the nodes after the changes, and not before.

In the second example, the root of the tree is $2$ and the initial values are $[1, 1]$.

In the last example, the root of the tree is $1$ and the initial values are $[-1, 1, 1, 1, 1, 1, -1]$.

Note that this is just an explanation of how the queries work, and it is not supposed to use any specific strategy to solve the problem.

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









struct BIT {
    int n;
    vector<long long> tree;

    void init(int _n) {
        n = _n;
        tree.assign(n + 1, 0);
    }

    
    
    
    
    
    void add(int i, long long val) {
        for (; i <= n; i += i & -i) tree[i] += val;
    }

    void range_add(int l, int r, long long val) {
        if (l > r) return;
        add(l, val);
        add(r + 1, -val);
    }

    long long query(int i) {
        long long res = 0;
        for (; i > 0; i -= i & -i) res += tree[i];
        return res;
    }
};


static const int HARD_CAP = 500000;





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

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

    
    for (int tc = 1; tc <= t; ++tc) {
        
        int n = inf.readInt();
        vector<pair<int, int>> edges;
        vector<vector<int>> adj(n + 1);
        for (int i = 0; i < n - 1; ++i) {
            int u = inf.readInt();
            int v = inf.readInt();
            edges.push_back({u, v});
            adj[u].push_back(v);
            adj[v].push_back(u);
        }

        int root = inf.readInt();
        vector<int> current_vals(n + 1);
        for (int i = 1; i <= n; ++i) {
            current_vals[i] = inf.readInt();
        }

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

        
        
        
        query_limit += (n + 200);
        log_metrics();

        
        
        
        
        
        
        
        vector<int> tin(n + 1), sz(n + 1);
        int timer = 0;
        
        function<void(int, int)> dfs = [&](int u, int p) {
            tin[u] = ++timer;
            sz[u] = 1;
            for (int v : adj[u]) {
                if (v != p) {
                    dfs(v, u);
                    sz[u] += sz[v];
                }
            }
        };
        dfs(root, 0);

        
        BIT bit;
        bit.init(n);
        
        for (int i = 1; i <= n; ++i) {
            if (current_vals[i] != 0) {
                
                bit.range_add(tin[i], tin[i] + sz[i] - 1, current_vals[i]);
            }
        }

        
        bool solved = false;
        while (true) {
            
            if (queries > HARD_CAP) {
                finish(_pe, "Hard query limit exceeded (potential infinite loop).");
            }

            
            string token;
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF reading query token.");
            }

            
            if (token == "!") {
                
                vector<int> guess(n);
                for (int i = 0; i < n; ++i) {
                    if (!(cin >> guess[i])) finish(_wa, "EOF reading answer.");
                }

                
                for (int i = 0; i < n; ++i) {
                    if (guess[i] != current_vals[i + 1]) {
                        finish(_wa, format("Incorrect value for node %d in test case %d. Expected %d, got %d.", 
                                           i + 1, tc, current_vals[i + 1], guess[i]));
                    }
                }
                
                solved = true;
                break; 
            }
            
            
            int type = -1;
            if (token == "?") {
                if (!(cin >> type)) finish(_wa, "EOF reading query type.");
            } else {
                
                try {
                    type = stoi(token);
                } catch(...) {
                    finish(_wa, "Invalid query format (expected '?' or '!' or integer type).");
                }
            }

            
            queries++;
            
            if (queries % 50 == 0) log_metrics();

            if (type == 1) {
                
                int k;
                if (!(cin >> k)) finish(_wa, "EOF reading k.");
                if (k < 1 || k > n) finish(_wa, "k out of bounds.");

                long long total_sum = 0;
                for (int i = 0; i < k; ++i) {
                    int u;
                    if (!(cin >> u)) finish(_wa, "EOF reading node index.");
                    if (u < 1 || u > n) finish(_wa, "Node index out of bounds.");
                    
                    
                    total_sum += bit.query(tin[u]);
                }
                cout << total_sum << endl;
                cout.flush();

            } else if (type == 2) {
                
                int u;
                if (!(cin >> u)) finish(_wa, "EOF reading u.");
                if (u < 1 || u > n) finish(_wa, "Node index out of bounds.");

                int old_val = current_vals[u];
                int new_val = -old_val;
                current_vals[u] = new_val;

                long long diff = new_val - old_val;
                
                bit.range_add(tin[u], tin[u] + sz[u] - 1, diff);

                
            } else {
                finish(_wa, "Unknown query type " + to_string(type));
            }
        }

        if (!solved) {
            finish(_wa, "Loop terminated without solution (should not happen).");
        }
    }

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


Adaptive interactor (C++):

Test generator (C++):


















#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

struct TestCase {
    int n;
    vector<pair<int, int>> edges;
    int root;
    vector<int> values;
};


void relabel_and_shuffle(int n, vector<pair<int, int>>& edges) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());
    
    for (auto& e : edges) {
        e.first = p[e.first - 1];
        e.second = p[e.second - 1];
        if (rnd.next(2)) swap(e.first, e.second);
    }
    shuffle(edges.begin(), edges.end());
}







void genTree(int n, int type, vector<pair<int, int>>& edges) {
    edges.clear();
    edges.reserve(n - 1);
    if (n == 2) {
        edges.push_back({1, 2});
        return;
    }
    
    if (type == 0) { 
        for (int i = 2; i <= n; i++)
            edges.push_back({rnd.next(1, i - 1), i});
    } else if (type == 1) { 
        for (int i = 1; i < n; i++)
            edges.push_back({i, i + 1});
    } else if (type == 2) { 
        for (int i = 2; i <= n; i++)
            edges.push_back({1, i});
    } else if (type == 3) { 
        int len = rnd.next(2, max(2, n - 1));
        if (n <= 5) len = 2; 
        for (int i = 1; i < len; i++)
            edges.push_back({i, i + 1});
        for (int i = len + 1; i <= n; i++)
            edges.push_back({len, i});
    } else if (type == 4) { 
        for (int i = 2; i <= n; i++)
            edges.push_back({i / 2, i});
    }
    
    relabel_and_shuffle(n, edges);
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    string mode = opt<string>("mode", "non");
    long long seedVal = atoll(argv[1]);
    
    vector<TestCase> cases;
    int MAX_N = 1000;
    
    if (seedVal == 1) {
        
        vector<int> ns = {2, 3, 4, 5, 10, 20};
        for (int n : ns) {
            TestCase tc;
            tc.n = n;
            
            if (n == 2) genTree(n, 1, tc.edges);
            else if (n == 3) genTree(n, 2, tc.edges);
            else if (n == 5) genTree(n, 3, tc.edges);
            else genTree(n, 0, tc.edges);
            
            tc.root = rnd.next(1, n);
            for (int i = 0; i < n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
            cases.push_back(tc);
        }
    } else if (seedVal == 2) {
        
        TestCase tc;
        tc.n = MAX_N;
        genTree(tc.n, 1, tc.edges);
        tc.root = rnd.next(1, tc.n); 
        for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
        cases.push_back(tc);
    } else if (seedVal == 3) {
        
        TestCase tc;
        tc.n = MAX_N;
        genTree(tc.n, 2, tc.edges);
        tc.root = rnd.next(1, tc.n);
        for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
        cases.push_back(tc);
    } else {
        
        int rem = MAX_N;
        
        
        if (rnd.next(100) < 40) {
            TestCase tc;
            tc.n = rem;
            genTree(tc.n, rnd.next(0, 4), tc.edges);
            tc.root = rnd.next(1, tc.n);
            for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
            cases.push_back(tc);
        } else {
            
            while (rem >= 2) {
                
                if (cases.size() == 99) {
                    TestCase tc;
                    tc.n = rem;
                    genTree(tc.n, rnd.next(0, 4), tc.edges);
                    tc.root = rnd.next(1, tc.n);
                    for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
                    cases.push_back(tc);
                    break;
                }

                int n;
                
                if (rem <= 10) n = rem;
                else {
                    
                    int ub = min(rem, 200);
                    if (rnd.next(2)) ub = min(rem, 50);
                    n = rnd.next(2, ub);
                }

                TestCase tc;
                tc.n = n;
                genTree(tc.n, rnd.next(0, 4), tc.edges);
                tc.root = rnd.next(1, tc.n);
                for (int i = 0; i < tc.n; ++i) tc.values.push_back(rnd.next(0, 1) ? 1 : -1);
                cases.push_back(tc);
                
                rem -= n;
            }
        }
    }
    
    
    println(cases.size());
    for (const auto& tc : cases) {
        println(tc.n);
        for (const auto& e : tc.edges) {
            println(e.first, e.second);
        }
        if (mode == "non") {
            println(tc.root);
            println(tc.values); 
        }
    }
    
    return 0;
}