This is an interactive problem!

In the new round, there were $n$ tasks with difficulties from $1$ to $n$. The coordinator, who decided to have the first round with tasks in unsorted order of difficulty, rearranged the tasks, resulting in a permutation of difficulties from $1$ to $n$. After that, the coordinator challenged ace5 to guess the permutation in the following way.

Initially, the coordinator chooses a number $x$ from $1$ to $n$.

ace5 can make queries of the form: $?\ i$. The answer will be:

* $>$, if $a_i > x$, after which $x$ increases by $1$.
* $<$, if $a_i < x$, after which $x$ decreases by $1$.
* $=$, if $a_i = x$, after which $x$ remains unchanged.

The task for ace5 is to guess the permutation in no more than $40n$ queries. Since ace5 is too busy writing the announcement, he has entrusted this task to you.

Input

The first line contains a single integer $t$ ($1 \leq t \leq 1000$) — the number of test cases.

Interaction

The interaction between your program and the jury's program begins with reading a positive integer $n$ ($1 \leq n \leq 2000$) — the length of the hidden permutation.

To make a query, output a line in the format "? i", where $1 \leq i \leq n$.

As an answer, you will receive:

* ">", if $a_i$ > $x$, after which $x$ will increase by $1$.
* "<", if $a_i$ < $x$, after which $x$ will decrease by $1$.
* "=", if $a_i$ = $x$, after which $x$ will remain unchanged.

You can make no more than $40n$ queries. To output the answer, you need to print "! a\_1 a\_2 ... a\_n", where $1 \leq a_i \leq n$, and all of them are distinct. Outputting the answer does not count as a query.

If your program makes more than $40n$ queries for one test case, or makes an invalid query, then the response to the query will be -1. After receiving such a response, your program should immediately terminate to receive the verdict Wrong Answer. Otherwise, it may receive any other verdict.

After outputting a query, do not forget to print a newline and flush the output buffer. Otherwise, you will receive the verdict Presentation Error. To flush the buffer, 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.

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

The interactor in this problem is not adaptive.

Example

Input

```
2
5

>

=

<

=

<

<

2

>
```

Output

```
? 4

? 2

? 1

? 5

? 1

? 3

! 2 4 1 5 3

? 1

! 2 1
```

Note

In the first test, the hidden permutation is $a$ = [$2,4,1,5,3$], and the initial value of $x$ is $3$.

In the second test, the hidden permutation is $a$ = [$2,1$], and the initial value of $x$ is $1$.

#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& tok) {
    tok.clear();
    if (!(cin >> tok)) return false;
    return true;
}

static bool parseLL(const string& s, long long& out) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[0] == '+' || s[0] == '-') {
        neg = (s[0] == '-');
        i = 1;
        if (i == (int)s.size()) return false;
    }
    long long val = 0;
    for (; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = neg ? -val : val;
    return true;
}

static long long mustReadIntInRange(long long lo, long long hi, const string& what) {
    string tok;
    if (!readToken(tok)) finish(_pe, "unexpected EOF while reading " + what);
    long long v;
    if (!parseLL(tok, v)) finish(_pe, "invalid integer token for " + what);
    if (v < lo || v > hi) finish(_pe, "integer out of range for " + what);
    return v;
}

struct TestCase {
    int n = 0;
    vector<int> a;
    int x0 = 0;
};

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

    vector<TestCase> cases;
    int t = 0;

    try {
        t = inf.readInt(1, 1000, "t");
        cases.resize(t);
        long long totalBudget = 0;

        for (int tc = 0; tc < t; tc++) {
            int n = inf.readInt(1, 2000, "n");
            vector<int> a(n);
            vector<int> seen(n + 1, 0);
            for (int i = 0; i < n; i++) {
                a[i] = inf.readInt(1, n, "a[i]");
                if (seen[a[i]]++) finish(_fail, "invalid hidden input: not a permutation");
            }
            int x = inf.readInt(1, n, "x");
            cases[tc] = TestCase{n, std::move(a), x};
            totalBudget += 40LL * n;
        }

        query_limit = totalBudget;
        log_metrics();

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

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

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

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

            while (true) {
                if (queries > hard_cap) finish(_pe, "hard cap exceeded");

                string cmd;
                if (!readToken(cmd)) finish(_pe, "unexpected EOF: contestant did not output final answer");

                if (cmd == "?") {
                    long long idx = mustReadIntInRange(1, n, "query index");
                    int ai = a[(int)idx - 1];

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

                    if (ai > x) {
                        cout << ">\n";
                        cout.flush();
                        x++;
                    } else if (ai < x) {
                        cout << "<\n";
                        cout.flush();
                        x--;
                    } else {
                        cout << "=\n";
                        cout.flush();
                    }
                } else if (cmd == "!") {
                    vector<int> ans(n);
                    vector<int> used(n + 1, 0);
                    for (int i = 0; i < n; i++) {
                        long long v = mustReadIntInRange(1, n, "answer value");
                        ans[i] = (int)v;
                        if (used[ans[i]]++) finish(_wa, "answer is not a permutation");
                    }
                    if (ans != a) finish(_wa, "wrong permutation");
                    break;
                } else {
                    finish(_pe, "invalid command token");
                }
            }
        }

        string extra;
        if (cin >> extra) finish(_pe, "extra output after finishing all test cases");

        finish(_ok, "ok");
    } catch (const std::exception& e) {
        finish(_pe, string("exception: ") + e.what());
    } catch (...) {
        finish(_pe, "unknown exception");
    }
}

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

static int clampInt(int v, int lo, int hi) {
    if (v < lo) return lo;
    if (v > hi) return hi;
    return v;
}

static vector<int> permZigzag(int n) {
    vector<int> p;
    p.reserve(n);
    int lo = 1, hi = n;
    while ((int)p.size() < n) {
        if ((int)p.size() < n) p.push_back(lo++);
        if ((int)p.size() < n) p.push_back(hi--);
    }
    return p;
}

static vector<int> permBlocks(int n, int blockSize, bool alternateReverse) {
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    for (int start = 0, blk = 0; start < n; start += blockSize, blk++) {
        int end = min(n, start + blockSize);
        if (!alternateReverse || (blk % 2 == 1)) {
            reverse(p.begin() + start, p.begin() + end);
        }
    }
    return p;
}

static void fisherYates(vector<int>& p) {
    for (int i = (int)p.size() - 1; i >= 1; --i) {
        int j = rnd.next(0, i);
        swap(p[i], p[j]);
    }
}

static void applySwaps(vector<int>& p, int swaps) {
    int n = (int)p.size();
    for (int k = 0; k < swaps; k++) {
        int i = rnd.next(0, n - 1);
        int j = rnd.next(0, n - 1);
        if (i != j) swap(p[i], p[j]);
    }
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 2000);
    int xOpt = opt<int>("x", -1);
    string pattern = opt<string>("pattern", "mix");

    long long seedVal = 1;
    if (argc >= 2) {

        seedVal = atoll(argv[1]);
        if (seedVal <= 0) seedVal = 1;
    }

    int n = clampInt(nOpt, 1, 2000);
    int x = (xOpt == -1 ? -1 : clampInt(xOpt, 1, n));

    cout << 1 << "\n";

    if (seedVal == 1) {
        n = 1;
        if (x == -1) x = 1;
        if (mode == "adp") {
            cout << n << "\n" << x << "\n";
        } else {
            cout << n << "\n";
            cout << 1 << "\n";
            cout << x << "\n";
        }
        return 0;
    }
    if (seedVal == 2) {
        n = 2;
        if (x == -1) x = 1;
        if (mode == "adp") {
            cout << n << "\n" << x << "\n";
        } else {
            cout << n << "\n";
            cout << 2 << " " << 1 << "\n";
            cout << x << "\n";
        }
        return 0;
    }
    if (seedVal == 3) {
        n = 2000;
        if (x == -1) x = 1000;
        if (mode == "adp") {
            cout << n << "\n" << x << "\n";
        } else {
            vector<int> p = permZigzag(n);
            cout << n << "\n";
            for (int i = 0; i < n; i++) {
                if (i) cout << ' ';
                cout << p[i];
            }
            cout << "\n" << x << "\n";
        }
        return 0;
    }

    n = 2000;
    if (x == -1) {
        int center = n / 2;
        int delta = rnd.next(-n / 6, n / 6);
        x = clampInt(center + delta, 1, n);
        if (rnd.next(1, 20) == 1) x = 1;
        if (rnd.next(1, 20) == 1) x = n;
    }

    if (mode == "adp") {

        cout << n << "\n" << x << "\n";
        return 0;
    }

    vector<int> p;
    if (pattern == "zigzag") {
        p = permZigzag(n);
        int rot = rnd.next(0, n - 1);
        rotate(p.begin(), p.begin() + rot, p.end());
        applySwaps(p, rnd.next(n / 2, n));
    } else if (pattern == "blocks") {
        int b = rnd.next(25, 80);
        p = permBlocks(n, b, true);
        int rot = rnd.next(0, n - 1);
        rotate(p.begin(), p.begin() + rot, p.end());
        applySwaps(p, rnd.next(n / 2, 2 * n));
    } else if (pattern == "random") {
        p.resize(n);
        iota(p.begin(), p.end(), 1);
        fisherYates(p);
    } else {
        int type = rnd.next(0, 2);
        if (type == 0) {
            p = permZigzag(n);
            int rot = rnd.next(0, n - 1);
            rotate(p.begin(), p.begin() + rot, p.end());
            applySwaps(p, rnd.next(n, 2 * n));
        } else if (type == 1) {
            int b = rnd.next(20, 100);
            p = permBlocks(n, b, true);
            int rot = rnd.next(0, n - 1);
            rotate(p.begin(), p.begin() + rot, p.end());
            applySwaps(p, rnd.next(n, 3 * n / 2));
        } else {
            p.resize(n);
            iota(p.begin(), p.end(), 1);
            fisherYates(p);

            applySwaps(p, rnd.next(n / 2, 2 * n));
        }
    }

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


This is an interactive problem

Ginny is taking an exam on game theory. The professor is tired of hearing the same answers over and over again, so he offered Ginny to play a game instead of a standard exam.

As known from the course, a combinatorial game on a graph with multiple starting positions is a game with a directed graph and multiple starting vertices holding a token each. Two players take turns moving one of the tokens along the graph edges on each turn. The player who can't make a move loses the game. If both players can play an infinitely long game without losing, a draw is called.

For the exam, the professor drew an acyclic directed graph and chose one of its vertices. Ginny needs to guess the vertex the professor chose. To do so, Ginny can choose a multiset of vertices $S$ several times and ask the professor: "If I put one token in each vertex of the given graph for each occurrence of the vertex in the multiset $S$, and then one more in the selected vertex, what would be the result of the combinatorial game?".

Having given the task, the professor left the room to give Ginny some time to prepare for the game. Ginny thinks that she's being tricked because the problem is impossible to solve. Therefore, while the professor is away, she wants to add or remove several edges from the graph. Even though the original graph was acyclic, edges could be added to the graph to make cycles appear.

Interaction

In this task, interaction consists of several phases.

In the first phase, the interactor gives as an input to your program three integers $N$ ($1 \le N \le 1000$), $M$ ($0 \le M \le 100\,000$), $T$ ($1 \le T \le 2000$): the number of vertices and edges in the initial graph, and the number of times Ginny has to guess the chosen vertex. The next $M$ lines contain pairs of vertices $a_i$ $b_i$ ($1 \le a_i, b_i \le N$): beginning and end of corresponding graph edges. The graph is guaranteed to be acyclic and all of its edges to be distinct.

The solution should print an integer $K$ ($0 \le K \le 4242$): the number of edges to change in the graph. The next $K$ lines should contain either "+ $a_i$ $b_i$" or "- $a_i$ $b_i$": the beginning and the end of an edge that Ginny has to add or remove accordingly. You are allowed to add preexisting edges to the graph. Operations are performed in the order of appearance, so Ginny is allowed to remove an edge added by the solution. You can only remove an existing edge. The operations can create cycles in the graph.

The next $T$ phases are dedicated to guessing the chosen vertices. In each phase, the solution can make at most 20 queries and then print the answer. To query a multiset $S$, the solution should print "? $|S|~S_1~S_2~\dots~S_{|S|}$". The total size of all multisets in a single phase should not exceed 20. The interactor will reply with one of the following words:

* "Win", if the winner of a combinatorial game with tokens in multiset $S$ and the selected vertex is the first player.
* "Lose", if the winner of a combinatorial game with tokens in multiset $S$ and the selected vertex is the second player.
* "Draw", if a combinatorial game with tokens in multiset $S$ and selected vertex ends in a draw.
* "Slow", if the solution made a 21-st request, or the total size of all multisets in a single phase exceeded 20. In this case, the solution should terminate and receive Wrong Answer verdict.

As soon as the selected vertex is guessed, that solution should print "! v". If the chosen vertex is guessed correctly, the interactor will print Correct and the solution should either move on to the next phase of guessing or finish its execution if it's the last phase. Otherwise, the interactor will print Wrong, which means that the solution should terminate and will receive the Wrong Answer verdict.

The interactor can change the chosen vertex based on graph changes and solution actions, but at every given moment of time, at least one vertex that corresponds to all given interactor answers will exist.

Example

Input

```
3 2 3
1 2
2 3

Lose

Correct

Win

Correct

Draw

Correct
```

Output

```
6
+ 2 2
- 1 2
+ 2 3
- 2 2
+ 3 1
+ 2 2
? 0

! 1

? 1 2

! 3

? 5 1 3 1 3 1

! 2
```

Note

In the sample test, the empty lines represent waiting for the input by the other side of the interaction. The real interactor will not print empty lines, and the solution should not print them either.

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

The image above illustrates the sample test. Added edges are coloured in red, and the removed edges are drawn with a dotted line. Three guessing phases denote different ways of getting the answer.

* If the solution will query just the chosen vertex, the interactor will return the result of the game in that vertex. The first player loses only if the chosen vertex has the number $1$.
* If we add a single vertex $2$ to the chosen vertex, then if the chosen vertex is either $1$ or $2$, the game should end in a draw. If vertex number $3$ is chosen, then the first player wins.
* If we place three tokens in vertex $1$ and two tokens in vertex $3$, then the game will end in a draw only if vertex $2$ is chosen. If the professor chose vertex $3$, the first player will win, if the professor chose vertex $1$, then the second player will win.

In the first test, the interactor will behave as if the chosen vertices are the same as those in the example above. However, if you will try to guess the answer before it limits the options to one single vertex, the solution will get "Wrong Answer", even if you print the same answers. That's because the interactor is allowed to change the chosen vertex if it's consistent with the previous query answers.

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static const int MAX_N = 1005;
static bool adj[MAX_N][MAX_N];
static vector<int> adj_list[MAX_N];
static int N, M, T;
static vector<int> targets;
static int in_degree[MAX_N];
static int grundy[MAX_N];
static bool is_dag = false;

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_verdict(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

void check_graph() {
    for(int i = 1; i <= N; ++i) {
        adj_list[i].clear();
        in_degree[i] = 0;
    }
    for(int i = 1; i <= N; ++i) {
        for(int j = 1; j <= N; ++j) {
            if(adj[i][j]) {
                adj_list[i].push_back(j);
                in_degree[j]++;
            }
        }
    }

    queue<int> q;
    vector<int> topo;
    vector<int> deg(N + 1);
    for(int i = 1; i <= N; ++i) {
        deg[i] = in_degree[i];
        if(deg[i] == 0) q.push(i);
    }

    while(!q.empty()) {
        int u = q.front(); q.pop();
        topo.push_back(u);
        for(int v : adj_list[u]) {
            deg[v]--;
            if(deg[v] == 0) q.push(v);
        }
    }

    if((int)topo.size() == N) {
        is_dag = true;

        for(int i = N - 1; i >= 0; --i) {
            int u = topo[i];
            set<int> seen;
            for(int v : adj_list[u]) seen.insert(grundy[v]);
            int g = 0;
            while(seen.count(g)) g++;
            grundy[u] = g;
        }
    } else {
        is_dag = false;
    }
}

static map<vector<int>, int> memo;

int solve_cyclic(vector<int> state) {
    sort(state.begin(), state.end());
    if(memo.count(state)) {
        int val = memo[state];
        if(val == -1) return 2;
        return val;
    }

    memo[state] = -1;

    bool can_reach_lose = false;
    bool can_reach_draw = false;

    vector<int> unique_pos;
    if(!state.empty()) {
        unique_pos.push_back(state[0]);
        for(size_t i = 1; i < state.size(); ++i) {
            if(state[i] != state[i-1]) unique_pos.push_back(state[i]);
        }
    }

    for(int u : unique_pos) {
        for(int v : adj_list[u]) {
            vector<int> next_state = state;

            auto it = lower_bound(next_state.begin(), next_state.end(), u);
            *it = v;

            int res = solve_cyclic(next_state);

            if(res == 0) {
                can_reach_lose = true;
                break;
            }
            if(res == 2) {
                can_reach_draw = true;
            }
        }
        if(can_reach_lose) break;
    }

    int res;
    if(can_reach_lose) res = 1;
    else if(can_reach_draw) res = 2;
    else res = 0;

    memo[state] = res;
    return res;
}

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

    N = inf.readInt(1, 1000, "N");
    M = inf.readInt(0, 100000, "M");
    T = inf.readInt(1, 2000, "T");
    query_limit = 20LL * T;

    vector<pair<int,int>> input_edges;
    for(int i = 0; i < M; ++i) {
        int u = inf.readInt(1, N, "u");
        int v = inf.readInt(1, N, "v");
        input_edges.push_back({u, v});
        adj[u][v] = true;
    }

    for(int i = 0; i < T; ++i) {
        targets.push_back(inf.readInt(1, N, "target"));
    }

    cout << N << " " << M << " " << T << endl;
    for(auto &e : input_edges) {
        cout << e.first << " " << e.second << endl;
    }
    cout.flush();

    int K;
    if(!(cin >> K)) finish_verdict(_wa, "Failed to read K");
    if(K < 0 || K > 4242) finish_verdict(_wa, "K out of range");

    for(int k = 0; k < K; ++k) {
        string type;
        int u, v;
        if(!(cin >> type >> u >> v)) finish_verdict(_wa, "Failed to read operation");
        if(u < 1 || u > N || v < 1 || v > N) finish_verdict(_wa, "Vertex index out of range");

        if(type == "+") {
            adj[u][v] = true;
        } else if(type == "-") {
            if(!adj[u][v]) finish_verdict(_wa, "Attempt to remove non-existing edge");
            adj[u][v] = false;
        } else {
            finish_verdict(_wa, "Invalid operation type");
        }
    }

    check_graph();

    for(int phase = 0; phase < T; ++phase) {
        int target = targets[phase];
        int phase_queries = 0;
        int sum_sizes = 0;

        while(true) {
            string token;
            if(!(cin >> token)) finish_verdict(_wa, "Unexpected EOF during interaction");

            if(token == "!") {
                int guess;
                if(!(cin >> guess)) finish_verdict(_wa, "Failed to read guess");
                if(guess == target) {
                    cout << "Correct" << endl;
                    break;
                } else {
                    cout << "Wrong" << endl;
                    finish_verdict(_wa, "Wrong guess");
                }
            } else if(token == "?") {
                phase_queries++;
                queries++;

                int k;
                if(!(cin >> k)) finish_verdict(_wa, "Failed to read multiset size");
                sum_sizes += k;

                vector<int> s;
                for(int i = 0; i < k; ++i) {
                    int val;
                    if(!(cin >> val)) finish_verdict(_wa, "Failed to read multiset element");
                    s.push_back(val);
                }

                if(phase_queries > 20 || sum_sizes > 20) {
                    cout << "Slow" << endl;
                    finish_verdict(_wa, "Too many queries or multiset size limit exceeded");
                }

                int res = 0;
                if(is_dag) {

                    int x = grundy[target];
                    for(int val : s) x ^= grundy[val];
                    res = (x > 0 ? 1 : 0);
                } else {

                    s.push_back(target);
                    res = solve_cyclic(s);
                }

                if(res == 1) cout << "Win" << endl;
                else if(res == 0) cout << "Lose" << endl;
                else cout << "Draw" << endl;

                cout.flush();
            } else {
                finish_verdict(_wa, "Invalid protocol token (expected '?' or '!')");
            }
        }
    }

    finish_verdict(_ok, "Passed all phases");
    return 0;
}

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

static long long total_queries = 0;
static long long query_limit = 0;

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

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

int N, M, T;
vector<pair<int,int>> initial_edges;
vector<vector<int>> adj;
vector<int> sg;
vector<vector<int>> reach_vals;

vector<int> candidates;
vector<bool> is_candidate;

void compute_sg() {

    vector<int> out_degree(N + 1, 0);
    vector<vector<int>> rev_adj(N + 1);

    for(int u = 1; u <= N; ++u) {
        out_degree[u] = adj[u].size();
        for(int v : adj[u]) {
            rev_adj[v].push_back(u);
        }
    }

    sg.assign(N + 1, -1);

    vector<int> rem_out = out_degree;
    queue<int> q;

    for(int i = 1; i <= N; ++i) {
        if(out_degree[i] == 0) {
            sg[i] = 0;
            q.push(i);
        }
    }

    while(!q.empty()) {
        int v = q.front(); q.pop();

        for(int u : rev_adj[v]) {
            rem_out[u]--;
            if(rem_out[u] == 0) {

                vector<int> seen;
                seen.reserve(adj[u].size());
                for(int w : adj[u]) {
                    if(sg[w] != -1) seen.push_back(sg[w]);
                }
                sort(seen.begin(), seen.end());
                seen.erase(unique(seen.begin(), seen.end()), seen.end());

                int mex = 0;
                for(int x : seen) {
                    if(x == mex) mex++;
                    else if(x > mex) break;
                }
                sg[u] = mex;
                q.push(u);
            }
        }
    }

    reach_vals.assign(N + 1, vector<int>());
    for(int u = 1; u <= N; ++u) {
        if(sg[u] == -1) {
            for(int v : adj[u]) {
                if(sg[v] != -1) {
                    reach_vals[u].push_back(sg[v]);
                }
            }
            sort(reach_vals[u].begin(), reach_vals[u].end());
            reach_vals[u].erase(unique(reach_vals[u].begin(), reach_vals[u].end()), reach_vals[u].end());
        }
    }
}

int solve_game(const vector<int>& S, int hidden) {
    int undef_cnt = 0;
    int xor_sum = 0;
    int bad_node = -1;

    auto process = [&](int u) {
        if(sg[u] == -1) {
            undef_cnt++;
            bad_node = u;
        } else {
            xor_sum ^= sg[u];
        }
    };

    for(int u : S) process(u);
    process(hidden);

    if(undef_cnt == 0) {
        return (xor_sum != 0) ? 0 : 1;
    } else if(undef_cnt > 1) {
        return 2;
    } else {

        const auto& rv = reach_vals[bad_node];
        bool can_win = binary_search(rv.begin(), rv.end(), xor_sum);
        return can_win ? 0 : 2;
    }
}

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

    N = inf.readInt();
    M = inf.readInt();
    T = inf.readInt();
    for(int i = 0; i < M; ++i) {
        int u = inf.readInt();
        int v = inf.readInt();
        initial_edges.push_back({u, v});
    }

    query_limit = (long long)T * 20;

    cout << N << " " << M << " " << T << endl;
    for(auto& e : initial_edges) {
        cout << e.first << " " << e.second << endl;
    }
    cout.flush();

    int K;
    if(!(cin >> K)) finish(_wa, "Cannot read K");
    if(K < 0 || K > 4242) finish(_wa, "K out of range");

    set<pair<int,int>> current_edges(initial_edges.begin(), initial_edges.end());

    for(int i = 0; i < K; ++i) {
        string type_str;
        int u, v;
        if(!(cin >> type_str >> u >> v)) finish(_wa, "Cannot read op");
        if(u < 1 || u > N || v < 1 || v > N) finish(_wa, "Vertex out of range in op");

        if(type_str == "+") {
            current_edges.insert({u, v});
        } else if(type_str == "-") {
            current_edges.erase({u, v});
        } else {
            finish(_wa, "Invalid op type");
        }
    }

    adj.assign(N + 1, vector<int>());
    for(auto& e : current_edges) {
        adj[e.first].push_back(e.second);
    }

    compute_sg();

    is_candidate.assign(N + 1, true);

    for(int t = 0; t < T; ++t) {

        candidates.clear();
        for(int i = 1; i <= N; ++i) candidates.push_back(i);
        is_candidate.assign(N + 1, true);

        int phase_queries = 0;
        int phase_size_sum = 0;
        bool solved = false;

        while(true) {
            string token;
            if(!(cin >> token)) finish(_wa, "Unexpected EOF during interaction");

            if(token == "!") {
                int guess;
                if(!(cin >> guess)) finish(_wa, "No guess provided");

                if(guess >= 1 && guess <= N && is_candidate[guess]) {
                    if(candidates.size() == 1) {
                        cout << "Correct" << endl;
                        solved = true;
                        break;
                    } else {
                        cout << "Wrong" << endl;
                        finish(_wa, "Ambiguous guess (adaptive)");
                    }
                } else {
                    cout << "Wrong" << endl;
                    finish(_wa, "Guess inconsistent with history");
                }
            } else if(token == "?") {
                total_queries++;
                phase_queries++;

                int k;
                if(!(cin >> k)) finish(_wa, "Cannot read set size");

                phase_size_sum += k;

                vector<int> S(k);
                for(int i = 0; i < k; ++i) {
                    cin >> S[i];
                    if(S[i] < 1 || S[i] > N) finish(_wa, "Vertex in query out of range");
                }

                if(phase_queries > 20 || phase_size_sum > 20) {
                    cout << "Slow" << endl;
                    finish(_wa, "Phase budget exceeded");
                }

                int counts[3] = {0, 0, 0};
                for(int h : candidates) {
                    counts[solve_game(S, h)]++;
                }

                int best_resp = -1;
                int max_c = -1;
                for(int r = 0; r < 3; ++r) {
                    if(counts[r] > max_c) {
                        max_c = counts[r];
                        best_resp = r;
                    }
                }

                if(max_c <= 0) {
                    finish(_wa, "No consistent hidden vertex exists (internal error or empty candidate set)");
                }

                if(best_resp == 0) cout << "Win" << endl;
                else if(best_resp == 1) cout << "Lose" << endl;
                else cout << "Draw" << endl;

                vector<int> next_cand;
                next_cand.reserve(max_c);
                for(int h : candidates) {
                    if(solve_game(S, h) == best_resp) {
                        next_cand.push_back(h);
                    } else {
                        is_candidate[h] = false;
                    }
                }
                candidates = next_cand;
            } else {
                finish(_wa, "Invalid token " + token);
            }
        }
        if(!solved) finish(_wa, "Phase ended without correct guess");
    }

    finish(_ok, "All phases passed");
}

#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");

    long long seed_val = 0;
    if (argc > 1) {
        seed_val = atoll(argv[1]);
    }

    int N = -1, M = -1, T = -1;

    int n_arg = opt<int>("n", -1);
    int m_arg = opt<int>("m", -1);
    int t_arg = opt<int>("t", -1);

    if (n_arg != -1) {
        N = n_arg;
        long long max_edges = 1LL * N * (N - 1) / 2;
        if (m_arg != -1) M = m_arg;
        else M = rnd.next(0LL, min((long long)100000, max_edges));

        if (t_arg != -1) T = t_arg;
        else T = rnd.next(1, 2000);
    } else {

        if (seed_val == 1) {
            N = 3; M = 2; T = 3;
        } else if (seed_val == 2) {
            N = 1000; M = 0; T = 1;
        } else if (seed_val == 3) {
            N = 1000; M = 100000; T = 2000;
        } else {
            N = rnd.next(2, 1000);

            long long max_E = 1LL * N * (N - 1) / 2;
            long long cap_M = min((long long)100000, max_E);

            int type = rnd.next(1, 10);
            if (type == 1) M = 0;
            else if (type <= 4) M = rnd.next(1LL, min(cap_M, (long long)N * 2));
            else if (type <= 8) M = rnd.next(min(cap_M, (long long)N * 2), cap_M);
            else M = cap_M;

            T = rnd.next(1, 2000);
        }
    }

    N = max(1, min(1000, N));
    long long max_edges = 1LL * N * (N - 1) / 2;
    M = max(0, min((int)min((long long)100000, max_edges), M));
    T = max(1, min(2000, T));

    vector<int> p(N);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());

    vector<pair<int,int>> final_edges;

    if (max_edges <= 200000 && M > max_edges / 2) {
        vector<pair<int,int>> all_edges;
        all_edges.reserve(max_edges);
        for (int i = 0; i < N; ++i) {
            for (int j = i + 1; j < N; ++j) {

                all_edges.push_back({p[i], p[j]});
            }
        }
        shuffle(all_edges.begin(), all_edges.end());
        for (int i = 0; i < M; ++i) final_edges.push_back(all_edges[i]);
    } else {
        set<pair<int,int>> distinct_edges;
        while ((int)distinct_edges.size() < M) {
            int u = rnd.next(0, N - 1);
            int v = rnd.next(0, N - 1);
            if (u == v) continue;

            if (u > v) swap(u, v);
            distinct_edges.insert({p[u], p[v]});
        }
        for (auto &e : distinct_edges) final_edges.push_back(e);
    }

    shuffle(final_edges.begin(), final_edges.end());

    println(N, M, T);
    for (auto &e : final_edges) {
        println(e.first, e.second);
    }

    if (mode == "non") {
        vector<int> targets(T);
        for (int i = 0; i < T; ++i) {
            targets[i] = rnd.next(1, N);
        }
        println(targets);
    } else if (mode == "adp") {
        println(-1);
    }

    return 0;
}


This is an interactive problem.

This is the game version of the problem. Note that the solution of this problem may or may not share ideas with the solution of the solo version. You can solve and get points for both versions independently.

Alice and Bob are playing a game. The game starts with a positive integer $n$, with players taking turns. On each turn of the game, the following sequence of events takes place:

* The player having the integer $p$ breaks it into two integers $p_{1}$ and $p_{2}$, where $0 \lt p_{1} \lt p$, $0 \lt p_{2} \lt p$ and $p_{1} \oplus p_{2} = p$.
* If no such $p_{1}$, $p_{2}$ exist, the player loses.
* Otherwise, the opponent does either select the integer $p_{1}$ or $p_{2}$.
* The game continues with the selected integer. The opponent will try to break it.

As Alice, your goal is to win. You can execute a maximum of $63$ break operations. You have the choice to play first or second. The system will act for Bob.

Here $\oplus$ denotes the bitwise XOR operation.

Input

Each test contains multiple test cases. The first line of input contains a single integer $t$ ($1 \leq t \leq 1000$) — the number of test cases.

The only line of each test case contains a single integer $n$ ($1 \leq n \leq 10^{18}$) — the number the game starts with.

Interaction

For each test case, the interaction begins by reading the integer $n$.

After reading $n$, print a single line containing either "first" or "second", denoting what you want to play as (as first or second correspondingly).

On Alice's turn, you are required to print two positive integers, $p_{1}$ and $p_{2}$ such that $0 \lt p_{1} \lt p$, $0 \lt p_{2} \lt p$ and $p_{1} \oplus p_{2} = p$. Here, $p$ equals one of the two integers printed by Bob in the previous turn. If no turn has occurred previously, $p$ is equal to $n$. If Alice cannot perform a break operation, print "0 0" to receive a Wrong answer verdict.

On Bob's turn, you should read two integers, $p_{1}$ and $p_{2}$ such that $0 \lt p_{1} \lt p$, $0 \lt p_{2} \lt p$ and $p_{1} \oplus p_{2} = p$. Here, $p$ equals one of the two integers printed by Alice in the previous turn. If no turn has occurred previously, $p$ is equal to $n$. If Bob cannot perform a break operation $p_{1} = 0$ and $p_2 = 0$ in which case you should proceed to the next test case.

If any break operation performed by Alice is invalid, the interactor prints "-1 -1" and your code should promptly exit to receive a wrong answer verdict.

If Alice performs $63$ turns and Bob can still execute a break operation on the current integers, the interactor prints "-1 -1", and your code should promptly exit to receive a wrong answer verdict.

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

```
4
1

0 0
3

0 0
13

3 4

0 0
777777770001

0 0
```

Output

```
second

first
2 1

first
10 7

1 2

first
777777770000 1
```

Note

Explanation for the interaction.

|  |  |  |
| --- | --- | --- |
| Interactor / Bob | Alice | Explanation |
| 4 |  | $t$ |
| 1 |  | $n$ for the first test case |
|  | second | Alice chooses to go second |
| 0 0 |  | Bob says he cannot break $p = 1$ |
| 3 |  | $n$ for the second test case |
|  | first | Alice chooses to go first |
|  | 1 2 | Alice breaks $p = 3$ into $p_1 = 1$ and $p_2 = 2$ |
| 0 0 |  | Bob says he cannot break $p = 1$ or $p = 2$ |
| 13 |  | $n$ for the third test case |
|  | first | Alice chooses to go first |
|  | 10 7 | Alice breaks $p = 13$ into $p_1 = 10$ and $p_2 = 7$ |
| 3 4 |  | Bob breaks $p = 7$ into $p_1 = 3$ and $p_2 = 4$ |
|  | 1 2 | Alice breaks $p = 3$ into $p_1 = 1$ and $p_2 = 2$ |
| 0 0 |  | Bob says he cannot break $p = 1$ or $p = 2$ |
| 777777770001 |  | $n$ for the fourth test case |
|  | first | Alice chooses to go first |
|  | 777777770000 1 | Alice breaks $p = 777\,777\,770\,001$ into $p_1 = 777\,777\,770\,000$ and $p_2 = 1$ |
| 0 0 |  | Bob says he cannot perform break operation. |

This table is for explanation only and does not reflect the actual behavior of the interactor.

Note that in the last test case Bob could choose $p_1$ and perform a break operation but he gave up.

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

using i64 = long long;
using u64 = unsigned long long;

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 isPowerOfTwo(u64 x) {
    return x && ((x & (x - 1ULL)) == 0ULL);
}

static bool canBreak(u64 p) {
    return !isPowerOfTwo(p);
}

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

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

static pair<u64, u64> splitLowbit(u64 p) {
    u64 a = p & (~p + 1ULL);
    u64 b = p ^ a;
    return {a, b};
}

static u64 chooseForBob(u64 x, u64 y) {
    bool ex = (__builtin_popcountll(x) % 2 == 0);
    bool ey = (__builtin_popcountll(y) % 2 == 0);
    if (ex != ey) return ex ? x : y;
    if (ex) return max(x, y);

    bool px = isPowerOfTwo(x);
    bool py = isPowerOfTwo(y);
    if (px != py) return px ? y : x;
    return max(x, y);
}

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

    int t = inf.readInt(1, 1000, "t");
    query_limit = 63LL * t;
    log_metrics();

    cout << t << endl;

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

    for (int tc = 1; tc <= t; ++tc) {
        i64 n_in = inf.readLong(1LL, 1000000000000000000LL, "n");
        u64 n = (u64)n_in;

        cout << n_in << endl;

        string role;
        if (!readToken(role)) finish(_pe, "Unexpected EOF while reading role");
        if (role != "first" && role != "second") finish(_pe, "Role must be 'first' or 'second'");

        bool aliceToBreak = (role == "first");

        u64 fixedP = n;
        bool hasPending = false;
        u64 pendA = 0, pendB = 0;

        long long aliceMovesThisCase = 0;

        while (true) {
            if (aliceToBreak) {
                string sx, sy;
                if (!readToken(sx) || !readToken(sy)) finish(_pe, "Unexpected EOF while reading Alice move");

                i64 ix, iy;
                if (!parseI64(sx, ix) || !parseI64(sy, iy)) finish(_pe, "Alice move must be integers");

                if (ix == 0 && iy == 0) {
                    finish(_wa, "Alice printed 0 0");
                }

                if (ix <= 0 || iy <= 0) {
                    cout << "-1 -1" << endl;
                    finish(_wa, "Alice printed non-positive numbers");
                }

                u64 x = (u64)ix;
                u64 y = (u64)iy;

                u64 p = 0;
                if (hasPending) {
                    p = x ^ y;
                    if (!(p == pendA || p == pendB)) {
                        cout << "-1 -1" << endl;
                        finish(_wa, "Alice broke a number different from the offered choice");
                    }
                } else {
                    p = fixedP;
                    if ((x ^ y) != p) {
                        cout << "-1 -1" << endl;
                        finish(_wa, "XOR does not match current p");
                    }
                }

                if (!(x < p && y < p)) {
                    cout << "-1 -1" << endl;
                    finish(_wa, "Alice printed parts not strictly less than p");
                }

                hasPending = false;

                ++aliceMovesThisCase;
                ++queries;

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

                if (aliceMovesThisCase > 63) {
                    cout << "-1 -1" << endl;
                    finish(_wa, "Alice exceeded 63 moves");
                }

                if (aliceMovesThisCase == 63) {
                    if (canBreak(x) || canBreak(y)) {
                        cout << "-1 -1" << endl;
                        finish(_wa, "Alice reached 63 moves but Bob can still break");
                    } else {

                        cout << "0 0" << endl;
                        break;
                    }
                }

                fixedP = chooseForBob(x, y);
                aliceToBreak = false;
            } else {

                if (!canBreak(fixedP)) {
                    cout << "0 0" << endl;
                    break;
                }

                auto [a, b] = splitLowbit(fixedP);
                if (a == 0 || b == 0 || a >= fixedP || b >= fixedP || (a ^ b) != fixedP) {
                    finish(_fail, "Internal error: invalid Bob split");
                }

                cout << (i64)a << " " << (i64)b << endl;

                pendA = a;
                pendB = b;
                hasPending = true;
                aliceToBreak = true;
            }
        }
    }

    finish(_ok, "OK");
}

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

using u64 = unsigned long long;

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 isPowerOfTwo(u64 x) {
    return x && ((x & (x - 1)) == 0);
}

static int poppar(u64 x) {
    return __builtin_popcountll(x) & 1;
}

static u64 lowbit(u64 x) {
    return x & (~x + 1);
}

static u64 msbPow2(u64 x) {

    int b = 63 - __builtin_clzll(x);
    return 1ULL << b;
}

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

static bool readU64(u64& x) {
    string s;
    if (!(cin >> s)) return false;
    if (s.empty()) return false;
    if (s.size() > 1 && s[0] == '+') s.erase(s.begin());
    if (s.empty()) return false;
    for (char c : s) if (c < '0' || c > '9') return false;
    if (s.size() > 20) return false;
    __int128 v = 0;
    for (char c : s) {
        v = v * 10 + (c - '0');
        if (v > (__int128)numeric_limits<u64>::max()) return false;
    }
    x = (u64)v;
    return true;
}

struct BestRes {
    int pc = -1;
    u64 val = 0;
    bool ok = false;
};

static u64 chooseNInRangeMaxPopcount(u64 L, u64 R) {

    static BestRes memo[64][2][2];
    static bool vis[64][2][2];

    auto better = [](const BestRes& a, const BestRes& b) -> bool {
        if (!a.ok) return false;
        if (!b.ok) return true;
        if (a.pc != b.pc) return a.pc > b.pc;
        return a.val > b.val;
    };

    function<BestRes(int, int, int)> dfs = [&](int bit, int tightL, int tightR) -> BestRes {
        if (bit < 0) {
            BestRes base;
            base.pc = 0;
            base.val = 0;
            base.ok = true;
            return base;
        }
        if (vis[bit][tightL][tightR]) return memo[bit][tightL][tightR];
        vis[bit][tightL][tightR] = true;

        int lb = tightL ? int((L >> bit) & 1ULL) : 0;
        int ub = tightR ? int((R >> bit) & 1ULL) : 1;

        BestRes best;
        best.ok = false;

        if (lb > ub) {
            memo[bit][tightL][tightR] = best;
            return best;
        }

        for (int v = ub; v >= lb; --v) {
            int ntL = tightL && (v == lb);
            int ntR = tightR && (v == ub);
            BestRes sub = dfs(bit - 1, ntL, ntR);
            if (!sub.ok) continue;
            BestRes cur;
            cur.ok = true;
            cur.pc = sub.pc + v;
            cur.val = sub.val | (u64(v) << bit);
            if (!best.ok || better(cur, best)) best = cur;
        }

        memo[bit][tightL][tightR] = best;
        return best;
    };

    memset(vis, 0, sizeof(vis));
    int topBit = 0;
    for (int b = 63; b >= 0; --b) {
        if (((R >> b) & 1ULL) || ((L >> b) & 1ULL)) {
            topBit = b;
            break;
        }
    }
    BestRes ans = dfs(topBit, 1, 1);
    if (!ans.ok) return L;
    if (ans.val < L) return L;
    if (ans.val > R) return R;
    return ans.val;
}

static bool validSplit(u64 p, u64 a, u64 b) {
    if (a == 0 || b == 0) return false;
    if (!(a < p && b < p)) return false;
    if ( (a ^ b) != p ) return false;
    return true;
}

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

    int t = 0;
    try {
        t = inf.readInt(1, 1000, "t");
    } catch (...) {
        finish(_pe, "failed to read t from inf");
    }

    query_limit = 63LL * t;
    log_metrics();

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

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

    for (int tc = 1; tc <= t; ++tc) {
        string line;

        while (true) {
            if (inf.eof()) finish(_pe, "unexpected eof in inf");
            line = inf.readLine();
            bool any = false;
            for (char c : line) if (!isspace((unsigned char)c)) { any = true; break; }
            if (any) break;
        }

        stringstream ss(line);
        unsigned long long a = 0, b = 0;
        if (!(ss >> a)) finish(_pe, "bad line in inf");
        if (ss >> b) {
            u64 L = a, R = b;
            if (L < 1) L = 1;
            if (R < 1) R = 1;
            if (L > R) swap(L, R);
            u64 n = chooseNInRangeMaxPopcount(L, R);
            cout << n << endl;
        } else {
            u64 n = a;
            if (n < 1) n = 1;
            cout << n << endl;
        }
        cout.flush();

        ss.clear();
        ss.str(line);
        u64 first = 0, second = 0;
        ss >> first;
        bool hasSecond = bool(ss >> second);
        u64 n = 0;
        if (!hasSecond) {
            n = first < 1 ? 1ULL : first;
        } else {
            u64 L = first, R = second;
            if (L < 1) L = 1;
            if (R < 1) R = 1;
            if (L > R) swap(L, R);
            n = chooseNInRangeMaxPopcount(L, R);
        }

        string who;
        if (!readToken(who)) finish(_pe, "EOF while reading first/second");
        for (char& c : who) c = (char)tolower((unsigned char)c);

        bool aliceBreaks = false;
        if (who == "first") aliceBreaks = true;
        else if (who == "second") aliceBreaks = false;
        else finish(_pe, "expected first/second");

        long long aliceMovesThisCase = 0;

        bool aliceHasChoice = false;
        u64 offer1 = 0, offer2 = 0;

        u64 bobCurrent = n;

        while (true) {
            if (aliceBreaks) {
                u64 p1 = 0, p2 = 0;
                if (!readU64(p1) || !readU64(p2)) finish(_pe, "bad/missing Alice move");
                if (p1 == 0 && p2 == 0) {

                    cout << "-1 -1" << endl;
                    cout.flush();
                    finish(_wa, "Alice output 0 0");
                }

                u64 p = p1 ^ p2;

                if (!aliceHasChoice) {

                    if (p != n) {
                        cout << "-1 -1" << endl;
                        cout.flush();
                        finish(_wa, "Alice broke wrong number");
                    }
                } else {
                    if (!(p == offer1 || p == offer2)) {
                        cout << "-1 -1" << endl;
                        cout.flush();
                        finish(_wa, "Alice did not choose a valid offered number");
                    }
                }

                if (isPowerOfTwo(p)) {
                    cout << "-1 -1" << endl;
                    cout.flush();
                    finish(_wa, "Alice attempted to break a power of two");
                }
                if (!validSplit(p, p1, p2)) {
                    cout << "-1 -1" << endl;
                    cout.flush();
                    finish(_wa, "invalid split by Alice");
                }

                ++queries;
                ++aliceMovesThisCase;
                if (queries > hard_cap) finish(_pe, "too many queries (hard cap exceeded)");
                if (aliceMovesThisCase > 63) {
                    cout << "-1 -1" << endl;
                    cout.flush();
                    finish(_wa, "Alice exceeded 63 turns");
                }

                auto chooseForBob = [&](u64 x, u64 y) -> u64 {

                    if (isPowerOfTwo(x) && !isPowerOfTwo(y)) return y;
                    if (isPowerOfTwo(y) && !isPowerOfTwo(x)) return x;

                    int px = poppar(x);
                    int py = poppar(y);

                    if (px != py) {
                        if (px == 0) return x;
                        return y;
                    }

                    bool xP2 = isPowerOfTwo(x), yP2 = isPowerOfTwo(y);
                    if (xP2 != yP2) return xP2 ? y : x;
                    if (x != y) return max(x, y);
                    return x;
                };

                bobCurrent = chooseForBob(p1, p2);
                aliceHasChoice = false;
                aliceBreaks = false;
            } else {

                if (isPowerOfTwo(bobCurrent)) {
                    cout << "0 0" << endl;
                    cout.flush();
                    break;
                }

                if (aliceMovesThisCase >= 63) {

                    cout << "-1 -1" << endl;
                    cout.flush();
                    finish(_wa, "Alice did not win within 63 turns");
                }

                u64 x = 0, y = 0;
                if (poppar(bobCurrent) == 0) {

                    u64 h = msbPow2(bobCurrent);
                    if (h == bobCurrent) {

                        cout << "0 0" << endl;
                        cout.flush();
                        break;
                    }
                    x = h;
                    y = bobCurrent ^ x;
                } else {

                    x = lowbit(bobCurrent);
                    if (x == bobCurrent) {

                        cout << "0 0" << endl;
                        cout.flush();
                        break;
                    }
                    y = bobCurrent ^ x;
                }

                if (!validSplit(bobCurrent, x, y)) {
                    finish(_pe, "internal error: produced invalid Bob split");
                }

                cout << x << " " << y << endl;
                cout.flush();

                offer1 = x;
                offer2 = y;
                aliceHasChoice = true;
                aliceBreaks = true;
            }
        }
    }

    finish(_ok, "ok");
}

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

using u64 = unsigned long long;
using i64 = long long;

static bool isPowerOfTwo(u64 x) {
    return x && ((x & (x - 1)) == 0);
}

static int msbPos(u64 x) {
    int p = -1;
    while (x) {
        ++p;
        x >>= 1;
    }
    return p;
}

static u64 clampU64(u64 x, u64 lo, u64 hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

static u64 genHardFixedN(u64 maxn, long long seedVal) {
    if (maxn < 1) return 1;

    int high = msbPos(maxn);
    if (high < 0) return 1;

    auto safePow2 = [&](int b) -> u64 {
        if (b < 0) return 0;
        if (b >= 63) return (u64(1) << 62);
        return (u64(1) << b);
    };

    if (seedVal == 1) return 1;
    if (seedVal == 2) {
        u64 p = safePow2(high);
        while (p > maxn) p >>= 1;
        if (p < 1) p = 1;
        return p;
    }
    if (seedVal == 3) {
        u64 p = safePow2(high);
        while (p > maxn) p >>= 1;
        u64 m = (p > 1 ? (p - 1) : 1);
        if (m < 1) m = 1;
        return m;
    }

    vector<u64> candidates;

    u64 top = safePow2(high);
    while (top > maxn) top >>= 1;

    if (top >= 4) candidates.push_back(top - 1);

    if (high >= 1) {
        u64 x = safePow2(high) + safePow2(high - 1);
        if (x > 0) x -= 1;
        if (x >= 1 && x <= maxn) candidates.push_back(x);
    }

    if (maxn >= 2) candidates.push_back(maxn - 1);

    {
        u64 x = safePow2(high);
        int parity = rnd.next(0, 1);
        for (int b = high - 1; b >= 0; --b) {
            if ((b & 1) == parity) x |= safePow2(b);
        }
        if (x >= 1 && x <= maxn) candidates.push_back(x);
    }

    if (high >= 10) {
        int low = rnd.next(8, min(20, high - 1));
        u64 x = safePow2(high);
        u64 block = safePow2(low) - 1;
        if (x + block <= maxn) candidates.push_back(x + block);
    }

    if (!candidates.empty() && rnd.next(0, 99) < 55) {
        u64 x = candidates[rnd.next(0, (int)candidates.size() - 1)];
        if (x < 1) x = 1;
        if (x > maxn) x = maxn;
        if (isPowerOfTwo(x) && x > 1) x ^= 1ULL;
        if (x < 1) x = 1;
        if (x > maxn) x = maxn;
        if (isPowerOfTwo(x) && x + 1 <= maxn) x += 1;
        return x;
    }

    for (int it = 0; it < 200; ++it) {
        int hbLo = max(0, high - 6);
        int hb = rnd.next(hbLo, high);
        u64 x = safePow2(hb);

        int pnum = rnd.next(65, 90);
        for (int b = hb - 1; b >= 0; --b) {
            if (rnd.next(0, 99) < pnum) x |= safePow2(b);
        }

        if (isPowerOfTwo(x)) {
            int addb = (hb == 0 ? 0 : rnd.next(0, hb - 1));
            x |= safePow2(addb);
        }

        if (x >= 1 && x <= maxn) return x;
    }

    u64 fallback = (top >= 4 ? top - 1 : maxn);
    fallback = clampU64(fallback, 1, maxn);
    if (isPowerOfTwo(fallback) && fallback + 1 <= maxn) fallback += 1;
    if (fallback < 1) fallback = 1;
    return fallback;
}

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

    string mode = opt<string>("mode", "non");
    long long seedVal = 0;
    if (argc >= 2) {
        try {
            seedVal = stoll(string(argv[1]));
        } catch (...) {
            seedVal = 0;
        }
    }

    u64 maxn = (u64)opt<long long>("maxn", 1000000000000000000LL);
    if (maxn < 1) maxn = 1;

    if (mode != "non" && mode != "adp") mode = "non";

    if (mode == "non") {
        u64 n = genHardFixedN(maxn, seedVal);
        cout << 1 << "\n" << n << "\n";
        return 0;
    }

    u64 center = genHardFixedN(maxn, seedVal);

    if (seedVal >= 1 && seedVal <= 3) {
        cout << 1 << "\n" << center << " " << center << "\n";
        return 0;
    }

    int high = msbPos(maxn);
    int wexpLo = 18;
    int wexpHi = min(26, max(18, high - 20));
    int wexp = rnd.next(wexpLo, wexpHi);
    u64 width = (wexp >= 63 ? (u64)-1 : ((u64)1 << wexp));
    if (width > 0) width -= 1;

    u64 L = (center > width ? center - width : 1ULL);
    u64 R = center + width;
    if (R > maxn || R < center) R = maxn;

    if (rnd.next(0, 99) < 60) {
        u64 capR = maxn;
        u64 capL = (maxn > width ? maxn - width : 1ULL);
        if (capL <= capR) {
            L = max(L, capL);
            R = capR;
        }
    }

    L = clampU64(L, 1, maxn);
    R = clampU64(R, 1, maxn);
    if (L > R) swap(L, R);

    cout << 1 << "\n" << L << " " << R << "\n";
    return 0;
}


All problems in this contest share the same statement, the only difference is the test your solution runs on. For further information on scoring please refer to "Scoring" section of the statement.

This is an interactive problem.

Imagine you are a treasure hunter, a very skillful one. One day you came across an ancient map which could help you to become rich. The map shows multiple forestry roads, and at each junction there is a treasure. So, you start your journey hoping to retrieve all the hidden treasures, but you don't know yet that there is a wicked wizard standing against you and craving to tangle up these roads and impede your achievements.

The treasure map is represented as an undirected graph in which vertices correspond to junctions and edges correspond to roads. Your path begins at a certain fixed vertex with a label known to you. Every time you come to a vertex that you have not been to before, you dig up a treasure chest and put a flag in this vertex. At the initial vertex you'll find a treasure chest immediately and, consequently, you'll put a flag there immediately as well.

When you are standing at the junction you can see for each of the adjacent vertices its degree and if there is a flag there. There are no other things you can see from there. Besides, the power of the wicked wizard is so great that he is able to change the location of the roads and junctions on the map without changing the graph structure. Therefore, the sequence of the roads coming from the junction $v$ might be different each time you come in the junction $v$. However, keep in mind that the set of adjacent crossroads does not change, and you are well aware of previously dug treasures at each adjacent to $v$ vertex.

Your goal is to collect treasures from all vertices of the graph as fast as you can. Good luck in hunting!

Interaction

On the first line the interactor prints an integer $t$ ($1 \leq t \leq 5$) — the number of maps for which you need to solve the problem.

Then for each of the $t$ maps interactor firstly prints the graph description and after that interaction on this map starts. The map description is given in the following format.

The first line contains four integers $n, m, start, base\_move\_count$ ($2 \leq n \leq 300$, $1 \leq m \leq min(\frac{n(n-1)}{2}, 25n)$, $1 \leq start \leq n$, $1000 \leq base\_move\_count \leq 30000$) — the number of vertices and edges in the graph, the label of the vertex where you start the journey and some base move count, on which the score for the map depends. It's guaranteed that the jury has a solution traversing the map using not more than $base\_move\_count$ moves with high probability.

The next $m$ lines contain descriptions of the edges of the graph $u, v$ ($1 \leq u, v \leq n$, $u \neq v$). It is guaranteed that the graph is connected, does not contain multiple edges and the degrees of all vertices do not exceed 50.

You can find map descriptions for all tests in the archive 'map\_descriptions.zip' which you can find in any of the archives 'problem-X-materials.zip' in the section "Contest materials" — they are all the same.

After that the interaction begins. The interactor prints vertex descriptions in the following format:

R~d~deg\_1~flag\_1~deg\_2~flag\_2 \ldots deg\_d~flag\_d, where $d$ is the degree of the current vertex, $deg_i$ is the degree of the $i$-th vertex adjacent to the current one, and $flag_i$ (0 or 1) is an indicator if the $i$-th adjacent vertex contains a flag. The order of neighbors in the vertex description is chosen by the interactor uniformly at random independently each time. Please keep in mind that you are not given the actual labels of adajacent vertices.

In response to the description of the vertex you should print a single integer $i$ ($1 \leq i \leq d$), which means that you have chosen the vertex with description $deg_i~flag_i$. Remember to use the flush operation after each output. If your output is invalid, you will get a "Wrong Answer" verdict.

When you have visited all the vertices of the graph at least once, the interactor prints the string "AC" instead of the vertex description. If you use more than $2 \cdot base\_move\_count$ moves, the interactor prints the string "F". In both cases, you have to either start reading the description of the next map, or terminate the program, if it has been the last map in the test.

Below the example of interaction is presented. Note that the test from the example is not the same that your solution will be tested on.

```
|  |  |
| --- | --- |
| Interactor | Solution |
| 1 |  |
| 3 3 1 1000 |  |
| 1 2 |  |
| 2 3 |  |
| 3 1 |  |
| R 2 2 0 2 0 |  |
|  | 1 |
| R 2 2 0 2 1 |  |
|  | 2 |
| R 2 2 0 2 1 |  |
|  | 1 |
| AC |  |
```

Scoring

All problems of this contest share the same statement and differ only in the test. Each problem contains one test. Map descriptions for the test are available to look at in the archive.

Each test consists of several maps.

The solution score for the problem will be $0$ in case your solution for some map failed to get an answer "AC" or "F". If the solution correctly interacted with the interactor on all $t$ maps, the score for the task will be equal to the sum of the scores for each of the maps.

If you have successfully passed all vertices of a graph with $n$ vertices using $moves$ moves, the score for the map is calculated as follows. Denote

base\\_fraction=\frac{base\\_move\\_count + 1}{n},sol\\_fraction=\frac{moves+1}{n},c=\frac{90}{\sqrt{base\\_fraction - 1}}.

Then:

* if $moves \leq base\_move\_count$, you get $100-c \sqrt{sol\_fraction - 1}$ points.
* if $base\_move\_count < moves \leq 2 \cdot base\_move\_count$, you get $20 - \frac{10\cdot(moves + 1)}{base\_move\_count + 1}$ points.

If you use more than $2 \cdot base\_move\_count$ moves, you get 0 points for the map.

For each problem the solution with the highest score is chosen. Please note that the maximum is chosen for the entire test as a whole, not for each separate map.

The final result of the participant is the sum of points for each of the problems.

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 0;

const long long HARD_CAP = 1000000;

struct LCG {
    unsigned long long state;
    LCG(unsigned long long seed = 1) : state(seed) {}
    unsigned int next() {
        state = state * 6364136223846793005ULL + 1;
        return state >> 33;
    }
    int next(int r) {
        if (r <= 0) return 0;
        return next() % r;
    }
};

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 NeighborInfo {
    int v;
    int degree;
    int flag;
};

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

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

    LCG rng(163916391639ULL);

    for (int map_idx = 0; map_idx < t; ++map_idx) {

        int n = inf.readInt(2, 300, "n");

        int max_possible_edges = n * (n - 1) / 2;
        int max_constraint = 25 * n;
        int max_m = min(max_possible_edges, max_constraint);

        int m_edges = inf.readInt(1, max_m, "m");
        int start = inf.readInt(1, n, "start");
        int base_move_count = inf.readInt(1000, 30000, "base_move_count");

        query_limit += 2LL * base_move_count;
        log_metrics();

        vector<vector<int>> adj(n + 1);
        vector<pair<int,int>> edges_list;
        edges_list.reserve(m_edges);

        for (int i = 0; i < m_edges; ++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});
        }

        cout << n << " " << m_edges << " " << start << " " << base_move_count << endl;

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

        int current_u = start;
        vector<bool> visited(n + 1, false);
        visited[start] = true;
        int visited_cnt = 1;
        int moves_this_map = 0;
        int limit_this_map = 2 * base_move_count;

        while (true) {

            if (queries > HARD_CAP) {
                finish(_pe, "Hard query limit exceeded (infinite loop?)");
            }

            if (moves_this_map > limit_this_map) {
                cout << "F" << endl;
                break;
            }

            if (visited_cnt == n) {
                cout << "AC" << endl;
                break;
            }

            const auto& neighbors = adj[current_u];
            int d = neighbors.size();
            vector<NeighborInfo> n_infos;
            n_infos.reserve(d);
            for (int v : neighbors) {
                n_infos.push_back({v, (int)adj[v].size(), visited[v] ? 1 : 0});
            }

            for (int i = d - 1; i > 0; --i) {
                int j = rng.next(i + 1);
                swap(n_infos[i], n_infos[j]);
            }

            cout << "R " << d;
            for (const auto& info : n_infos) {
                cout << " " << info.degree << " " << info.flag;
            }
            cout << endl;

            string token;
            if (!(cin >> token)) {
                finish(_pe, "Unexpected EOF or read error waiting for move");
            }

            int choice = -1;
            try {
                size_t pos;
                choice = stoi(token, &pos);
                if (pos != token.size()) {
                    finish(_pe, "Invalid token (trailing characters): " + token);
                }
            } catch (...) {
                finish(_pe, "Invalid token (not an integer): " + token);
            }

            if (choice < 1 || choice > d) {
                finish(_wa, format("Invalid choice %d, expected [1, %d]", choice, d));
            }

            int next_v = n_infos[choice - 1].v;
            current_u = next_v;
            moves_this_map++;
            queries++;

            if (!visited[current_u]) {
                visited[current_u] = true;
                visited_cnt++;
            }

            if (queries % 200 == 0) log_metrics();
        }
    }

    finish(_ok, "All maps processed");
    return 0;
}

#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 Neighbor {
    int id;
    int degree;
    bool has_flag;
};

void run_map() {

    int n = inf.readInt(2, 300, "n");

    int m = inf.readInt(1, n * (n - 1) / 2, "m");
    int start = inf.readInt(1, n, "start");
    int base_move_count = inf.readInt(1000, 30000, "base_move_count");

    query_limit += 2LL * base_move_count;

    vector<vector<int>> adj(n + 1);
    vector<pair<int, int>> edges;
    edges.reserve(m);
    for (int i = 0; i < m; ++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.push_back({u, v});
    }

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

    vector<bool> has_flag(n + 1, false);
    int visited_count = 0;

    has_flag[start] = true;
    visited_count = 1;

    int curr = start;
    int moves = 0;
    int max_moves = 2 * base_move_count;

        while (true) {

            if (visited_count == n) {
                cout << "AC" << endl;
                return;
            }

            if (moves > max_moves) {
                cout << "F" << endl;
                return;
            }

        vector<int>& neighbors = adj[curr];
        vector<Neighbor> desc;
        desc.reserve(neighbors.size());
        for (int v : neighbors) {
            desc.push_back({v, (int)adj[v].size(), has_flag[v]});
        }

        shuffle(desc.begin(), desc.end());

        cout << "R " << desc.size();
        for (const auto& nb : desc) {
            cout << " " << nb.degree << " " << (nb.has_flag ? 1 : 0);
        }
        cout << endl;

        int choice = 0;
        cin >> choice;
        if (cin.fail()) {
            finish(_wa, "Failed to read integer choice");
        }
        if (choice < 1 || choice > (int)desc.size()) {
            finish(_wa, format("Invalid choice %d, expected [1, %d]", choice, (int)desc.size()));
        }

        curr = desc[choice - 1].id;
        moves++;
        queries++;

        if (!has_flag[curr]) {
            has_flag[curr] = true;
            visited_count++;
        }

        if (queries > 3000000) {
            finish(_pe, "Hard query limit exceeded (3,000,000)");
        }
    }
}

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

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

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

    finish(_ok, "All maps processed successfully");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 300;
const int MAX_DEG = 50;

struct Edge {
    int u, v;
    bool operator<(const Edge& other) const {
        if (u != other.u) return u < other.u;
        return v < other.v;
    }
};

bool is_connected(int n, const vector<Edge>& edges) {
    if (n <= 1) return true;
    if (edges.empty()) return false;
    vector<vector<int>> adj(n + 1);
    for (const auto& e : edges) {
        adj[e.u].push_back(e.v);
        adj[e.v].push_back(e.u);
    }
    vector<bool> vis(n + 1, false);
    vector<int> q;
    q.reserve(n);
    q.push_back(1);
    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;
                q.push_back(v);
            }
        }
    }
    for (int i = 1; i <= n; ++i) if (!vis[i]) return false;
    return true;
}

bool check_degrees(int n, const vector<Edge>& edges) {
    vector<int> deg(n + 1, 0);
    for (const auto& e : edges) {
        deg[e.u]++;
        deg[e.v]++;
    }
    for (int i = 1; i <= n; ++i) if (deg[i] > MAX_DEG) return false;
    return true;
}

vector<Edge> gen_random_graph(int n, int m_target) {
    vector<Edge> edges;
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);
    shuffle(p.begin(), p.end());

    set<Edge> edge_set;
    vector<int> deg(n + 1, 0);

    for (int i = 1; i < n; ++i) {
        int u = p[i];
        int v = p[rnd.next(0, i - 1)];
        if (u > v) swap(u, v);

        if (deg[u] < MAX_DEG && deg[v] < MAX_DEG) {
            edge_set.insert({u, v});
            deg[u]++; deg[v]++;
        } else {

             for(int j=0; j<i; ++j){
                 int candidate = p[j];
                 int uu = u, vv = candidate;
                 if (uu > vv) swap(uu, vv);
                 if(deg[uu] < MAX_DEG && deg[vv] < MAX_DEG){
                     edge_set.insert({uu, vv});
                     deg[uu]++; deg[vv]++;
                     break;
                 }
             }
        }
    }

    int attempts = 0;
    while ((int)edge_set.size() < m_target && attempts < 20000) {
        attempts++;
        int u = rnd.next(1, n);
        int v = rnd.next(1, n);
        if (u == v) continue;
        if (u > v) swap(u, v);
        if (edge_set.count({u, v})) continue;

        if (deg[u] < MAX_DEG && deg[v] < MAX_DEG) {
            edge_set.insert({u, v});
            deg[u]++; deg[v]++;
        }
    }

    for (auto e : edge_set) edges.push_back(e);
    return edges;
}

vector<Edge> gen_grid(int n) {
    int rows = sqrt(n);
    if (rows < 1) rows = 1;
    while (n % rows != 0) rows--;
    int cols = n / rows;

    vector<Edge> edges;
    auto idx = [&](int r, int c) { return (r - 1) * cols + c; };

    for (int r = 1; r <= rows; ++r) {
        for (int c = 1; c <= cols; ++c) {
            int u = idx(r, c);
            if (c < cols) edges.push_back({u, idx(r, c + 1)});
            if (r < rows) edges.push_back({u, idx(r + 1, c)});
        }
    }
    return edges;
}

vector<Edge> gen_regular(int n, int k) {
    if ((n * k) % 2 != 0) k--;
    if (k < 2) k = 2;

    set<Edge> edge_set;
    vector<int> p(n);
    iota(p.begin(), p.end(), 1);

    int half_k = k / 2;
    for(int i = 0; i < half_k; ++i) {
        shuffle(p.begin(), p.end());
        for(int j = 0; j < n; ++j) {
            int u = p[j];
            int v = p[(j + 1) % n];
            if (u > v) swap(u, v);
            edge_set.insert({u, v});
        }
    }

    if (k % 2 != 0) {
        shuffle(p.begin(), p.end());
        for(int i = 0; i < n / 2; ++i) {
            int u = p[2 * i];
            int v = p[2 * i + 1];
            if (u > v) swap(u, v);
            edge_set.insert({u, v});
        }
    }

    vector<Edge> res;
    for(auto e : edge_set) res.push_back(e);
    return res;
}

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

    string mode = opt<string>("mode", "non");

    int t = rnd.next(1, 5);
    cout << t << "\n";

    for (int i = 0; i < t; ++i) {
        int n = 0;
        vector<Edge> edges;
        bool generated = false;

        while (!generated) {
            n = rnd.next(2, MAXN);
            string type = "random";

            if (mode == "adp") {

                int r = rnd.next(0, 3);
                if (r == 0) type = "regular";
                else if (r == 1) type = "grid";
                else if (r == 2) type = "regular_dense";
                else type = "random_dense";
            } else {

                int r = rnd.next(0, 4);
                if (r == 0) type = "tree";
                else if (r == 1) type = "random_sparse";
                else type = "random_dense";
            }

            if (type == "tree") {
                edges = gen_random_graph(n, n - 1);
            } else if (type == "grid") {

                if (n > 10 && rnd.next(2)) {
                    int r = rnd.next(2, (int)sqrt(n));
                    n = r * (n / r);
                }
                edges = gen_grid(n);
            } else if (type == "regular" || type == "regular_dense") {
                int k;
                if (type == "regular") {
                    int lo = 3, hi = min(6, n - 1);
                    if (lo > hi) { type = "random_sparse"; goto retry_type; }
                    k = rnd.next(lo, hi);
                } else {
                    int lo = 6, hi = min(20, n - 1);
                    if (lo > hi) { type = "random_sparse"; goto retry_type; }
                    k = rnd.next(lo, hi);
                }

                if (k > MAX_DEG) k = MAX_DEG;
                edges = gen_regular(n, k);
            } else if (type == "random_sparse") {
                retry_type:
                int m = rnd.next(n - 1, min((int)(n * 1.5), n * (n - 1) / 2));
                edges = gen_random_graph(n, m);
            } else {
                int max_m = min(n * (n - 1) / 2, 25 * n);
                int min_m = min(n, max_m);
                int m = rnd.next(min_m, max_m);
                edges = gen_random_graph(n, m);
            }

            if (edges.size() >= 1 && is_connected(n, edges) && check_degrees(n, edges)) {
                generated = true;
            }
        }

        vector<int> p(n + 1);
        iota(p.begin(), p.end(), 0);
        shuffle(p.begin() + 1, p.end());

        vector<Edge> final_edges;
        for (auto& e : edges) {
            int u = p[e.u];
            int v = p[e.v];
            if (rnd.next(2)) swap(u, v);
            final_edges.push_back({u, v});
        }
        shuffle(final_edges.begin(), final_edges.end());

        int m = final_edges.size();
        int start = rnd.next(1, n);

        long long calc_base = (long long)m * 25 / 10;
        if (calc_base < 1000) calc_base = 1000;
        if (calc_base > 30000) calc_base = 30000;

        cout << n << " " << m << " " << start << " " << calc_base << "\n";
        for (const auto& e : final_edges) {
            cout << e.u << " " << e.v << "\n";
        }
    }

    return 0;
}


#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static mt19937 rng(42);

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 int read_choice_index() {
    string token;
    if (!(cin >> token)) {
        finish(_wa, "Unexpected EOF while reading move");
    }
    if (token.empty()) {
        finish(_wa, "Invalid move token");
    }
    for (char ch : token) {
        if (ch < '0' || ch > '9') {
            finish(_wa, "Invalid move token");
        }
    }
    try {
        size_t pos = 0;
        long long v = stoll(token, &pos);
        if (pos != token.size() || v > numeric_limits<int>::max()) {
            finish(_wa, "Invalid move token");
        }
        return (int)v;
    } catch (...) {
        finish(_wa, "Invalid move token");
    }
    return -1;
}

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

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt(2, 300, "n");
        int max_m = (int)min(1LL * n * (n - 1) / 2, 25LL * n);
        int m = inf.readInt(1, max_m, "m");
        int start = inf.readInt(1, n, "start");
        int base_move_count = inf.readInt(1000, 30000, "base_move_count");

        long long map_limit = 2LL * base_move_count;
        query_limit += map_limit;
        if (tc == 0) log_metrics();

        vector<vector<int>> adj(n + 1);
        vector<int> deg(n + 1, 0);
        vector<pair<int, int>> edges;
        edges.reserve(m);

        for (int i = 0; i < m; ++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);
            deg[u]++;
            deg[v]++;
            edges.push_back({u, v});
        }

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

        vector<char> visited(n + 1, 0);
        visited[start] = 1;
        int visited_count = 1;
        int cur = start;
        long long moves = 0;

        while (true) {
            if (visited_count == n) {
                cout << "AC" << endl;
                cout.flush();
                break;
            }
            if (moves > map_limit) {
                cout << "F" << endl;
                cout.flush();
                break;
            }

            vector<int> neighbors = adj[cur];
            shuffle(neighbors.begin(), neighbors.end(), rng);

            cout << "R " << neighbors.size();
            for (int v : neighbors) {
                cout << " " << deg[v] << " " << (visited[v] ? 1 : 0);
            }
            cout << endl;
            cout.flush();

            int choice = read_choice_index();
            if (choice < 1 || choice > (int)neighbors.size()) {
                finish(_wa, format("Invalid choice %d (expected 1..%d)", choice, (int)neighbors.size()));
            }

            cur = neighbors[choice - 1];
            moves++;
            queries++;
            if (queries % 200 == 0) log_metrics();

            if (!visited[cur]) {
                visited[cur] = 1;
                visited_count++;
            }
        }
    }

    finish(_ok, "All maps processed");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static mt19937 rng(239);

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 int read_choice_index() {
    string token;
    if (!(cin >> token)) {
        finish(_wa, "Unexpected EOF while reading move");
    }
    if (token.empty()) {
        finish(_wa, "Invalid move token");
    }
    for (char ch : token) {
        if (ch < '0' || ch > '9') {
            finish(_wa, "Invalid move token");
        }
    }
    try {
        size_t pos = 0;
        long long v = stoll(token, &pos);
        if (pos != token.size() || v > numeric_limits<int>::max()) {
            finish(_wa, "Invalid move token");
        }
        return (int)v;
    } catch (...) {
        finish(_wa, "Invalid move token");
    }
    return -1;
}

struct DisplayEntry {
    int v;
    int degree;
    int flag;
};

static void run_map(int n, int m, int start, int base_move_count, const vector<pair<int, int>>& edges) {
    vector<vector<int>> adj(n + 1);
    vector<int> deg(n + 1, 0);
    for (const auto& e : edges) {
        adj[e.first].push_back(e.second);
        adj[e.second].push_back(e.first);
        deg[e.first]++;
        deg[e.second]++;
    }

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

    long long map_limit = 2LL * base_move_count;
    vector<char> visited(n + 1, 0);
    visited[start] = 1;
    int visited_count = 1;
    int cur = start;
    long long moves = 0;

    while (true) {
        if (visited_count == n) {
            cout << "AC" << endl;
            cout.flush();
            return;
        }
        if (moves > map_limit) {
            cout << "F" << endl;
            cout.flush();
            return;
        }

        const vector<int>& neighbors = adj[cur];
        int d = (int)neighbors.size();

        vector<DisplayEntry> display;
        display.reserve(d);
        for (int v : neighbors) {
            display.push_back({v, deg[v], visited[v] ? 1 : 0});
        }
        shuffle(display.begin(), display.end(), rng);

        cout << "R " << d;
        for (const auto& e : display) {
            cout << " " << e.degree << " " << e.flag;
        }
        cout << endl;
        cout.flush();

        int choice = read_choice_index();
        if (choice < 1 || choice > d) {
            finish(_wa, format("Invalid choice %d (expected 1..%d)", choice, d));
        }

        cur = display[choice - 1].v;
        if (!visited[cur]) {
            visited[cur] = 1;
            visited_count++;
        }

        moves++;
        queries++;
        if (queries % 200 == 0) log_metrics();
        if (queries > 2000000) finish(_pe, "Hard query cap exceeded");
    }
}

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

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

    for (int tc = 0; tc < t; ++tc) {
        int n = inf.readInt(2, 300, "n");
        int max_m = (int)min(1LL * n * (n - 1) / 2, 25LL * n);
        int m = inf.readInt(1, max_m, "m");
        int start = inf.readInt(1, n, "start");
        int base_move_count = inf.readInt(1000, 30000, "base_move_count");

        query_limit += 2LL * base_move_count;
        if (tc == 0) log_metrics();

        vector<pair<int, int>> edges;
        edges.reserve(m);
        for (int i = 0; i < m; ++i) {
            int u = inf.readInt(1, n, "u");
            int v = inf.readInt(1, n, "v");
            edges.push_back({u, v});
        }

        run_map(n, m, start, base_move_count, edges);
    }

    finish(_ok, "All maps processed");
    return 0;
}

#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

struct DSU {
    vector<int> par;
    void init(int n) {
        par.resize(n + 1);
        iota(par.begin(), par.end(), 0);
    }
    int find(int x) {
        return par[x] == x ? x : par[x] = find(par[x]);
    }
    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x != y) par[x] = y;
    }
};

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

    string mode = opt<string>("mode", "non");

    int t = 1;
    cout << t << endl;

    for (int ti = 0; ti < t; ++ti) {
        int n;

        int type_val = rnd.next(1, 100);
        if (type_val <= 5) n = rnd.next(2, 10);
        else if (type_val <= 20) n = rnd.next(11, 50);
        else n = rnd.next(200, 300);

        int topology = 0;
        if (mode == "adp") {

            int r = rnd.next(1, 100);
            if (r <= 40) topology = 2;
            else if (r <= 70) topology = 1;
            else if (r <= 90) topology = 0;
            else topology = 3;
        } else {

            int r = rnd.next(1, 100);
            if (r <= 50) topology = 0;
            else if (r <= 80) topology = 3;
            else if (r <= 90) topology = 1;
            else topology = 2;
        }

        if (n < 5) topology = 0;

        set<pair<int,int>> edgeSet;
        vector<pair<int,int>> raw_edges;

        auto addEdge = [&](int u, int v) {
            if (u > v) swap(u, v);
            if (u != v && edgeSet.find({u, v}) == edgeSet.end()) {
                edgeSet.insert({u, v});
                raw_edges.push_back({u, v});
                return true;
            }
            return false;
        };

        if (topology == 0) {

            for (int i = 2; i <= n; ++i) {
                addEdge(rnd.next(1, i - 1), i);
            }

            long long max_edges = min((long long)n * (n - 1) / 2, (long long)25 * n);
            int target_m = rnd.next(n - 1, (int)min((long long)n * 5, max_edges));
            int fails = 0;
            while ((int)raw_edges.size() < target_m && fails < 500) {
                if (!addEdge(rnd.next(1, n), rnd.next(1, n))) fails++;
            }
        }
        else if (topology == 1) {
            int h = (int)sqrt(n);
            if (h < 1) h = 1;
            while (n % h != 0) h--;
            int w = n / h;
            for (int r = 0; r < h; ++r) {
                for (int c = 0; c < w; ++c) {
                    int u = r * w + c + 1;
                    if (c + 1 < w) addEdge(u, u + 1);
                    if (r + 1 < h) addEdge(u, u + w);
                }
            }

            if (mode == "non") {
                int noise = rnd.next(0, n / 2);
                for (int i = 0; i < noise; ++i) addEdge(rnd.next(1, n), rnd.next(1, n));
            }
        }
        else if (topology == 2) {

            vector<int> p(n);
            iota(p.begin(), p.end(), 1);
            shuffle(p.begin(), p.end());
            for (int i = 0; i < n; ++i) addEdge(p[i], p[(i + 1) % n]);

            int k = rnd.next(3, 5);
            vector<int> deg(n + 1, 2);
            int attempts = 0;
            while (attempts < 3000) {
                attempts++;
                int u = rnd.next(1, n);
                int v = rnd.next(1, n);
                if (u != v && deg[u] < k && deg[v] < k) {
                    if (addEdge(u, v)) {
                        deg[u]++;
                        deg[v]++;
                    }
                }
            }
        }
        else {

            for (int i = 2; i <= n; ++i) {
                addEdge(rnd.next(1, i - 1), i);
            }
        }

        shuffle(raw_edges.begin(), raw_edges.end());

        vector<pair<int,int>> final_edges;
        vector<int> deg(n + 1, 0);
        DSU dsu;
        dsu.init(n);

        for (auto& e : raw_edges) {
            int u = e.first, v = e.second;
            if (deg[u] < 50 && deg[v] < 50) {
                deg[u]++; deg[v]++;
                final_edges.push_back(e);
                dsu.unite(u, v);
            }
        }

        int comps = 0;
        vector<int> roots;
        for (int i = 1; i <= n; ++i) {
            if (dsu.find(i) == i) {
                comps++;
                roots.push_back(i);
            }
        }

        if (comps > 1) {
            for (size_t i = 1; i < roots.size(); ++i) {
                int r1 = roots[i-1], r2 = roots[i];
                int u = -1, v = -1;

                for (int x = 1; x <= n; ++x) if (dsu.find(x) == r1 && deg[x] < 50) { u = x; break; }
                for (int x = 1; x <= n; ++x) if (dsu.find(x) == r2 && deg[x] < 50) { v = x; break; }

                if (u != -1 && v != -1) {
                    final_edges.push_back({u, v});
                    deg[u]++; deg[v]++;
                    dsu.unite(u, v);
                }
            }
        }

        int start_node = rnd.next(1, n);

        int base_move_count = max(1000, n * 15);
        if (base_move_count > 30000) base_move_count = 30000;

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

    return 0;
}