Alessia and Bernardo are discovering the world of competitive programming through the books of their university library.

The library consists of $m$ sections numbered from $1$ to $m$. Each section contains only books dedicated to a particular subject and different sections correspond to different subjects. In order to prevent the students from wandering in the library, the university has established a system of passes. Each pass has a length $y$ associated to it and allows access to an interval of $y$ consecutive sections in the library. During a visit, the student must choose exactly one book from one of these sections and leave the library. Each pass can be used only once.

At the moment Alessia and Bernardo have $n$ passes of lengths $x_1, \, x_2, \, \dots, \, x_n$. They have different opinions on the best way to improve: Alessia thinks that it is important to study many different topics, while Bernardo believes that it is important to study deeply at least one topic. So, Alessia wants to use the $n$ passes to get $n$ books on distinct topics, while Bernardo would like to get at least two books on the same topic.

They have reached the following agreement: for each of the following $n$ days, Alessia will choose a pass of length $y$ among those which are still available and an interval of $y$ sections in the library, and Bernardo will go into the library and will take exactly one book from one of those sections.

Can Bernardo manage to get at least two books on the same subject, or will Alessia be able to avoid it?

You should decide whether you want to be Alessia or Bernardo, and you have to fulfill the goal of your chosen character. The judge will impersonate the other character. Note that, even if at some moment Bernardo has already taken two books on the same subject, the interaction should go on until the end of the $n$ days.

Input

The first line contains two integers $n$ and $m$ ($1 \le n \le 100$, $n \le m \le 5000$) — the number of passes and the number of sections.

The second line contains $n$ integers $x_1, \, x_2, \, \dots, \, x_n$ ($1 \le x_i \le m$) — the lengths of the passes available.

Interaction

First, you should print a line containing either the string $\texttt{Alessia}$ or the string $\texttt{Bernardo}$ — the character that you want to impersonate.

Then, for each of the $n$ turns:

* If you are taking the role of Alessia, print a single line consisting of two integers $y$ and $a$ ($1 \le a \le m - y + 1$) — you are choosing a pass of length $y$ and the interval of sections $[a, a + y - 1]$. Note that at least one pass of length $y$ must still be available. After this, read a single integer $b$ ($a \le b \le a + y - 1$) — the subject of the book selected by Bernardo.
* If you are taking the role of Bernardo, read two integers $y$ and $a$ ($1 \le a \le m - y + 1$) — the length of the pass chosen by Alessia and the index of the first section of the interval. It is guaranteed that there is at least one pass of length $y$ available. Then, print a line consisting of a single integer $b$ ($a \le b \le a + y - 1$) — the subject from which you choose to take a book.

If one of your interactions is malformed, the interactor terminates immediately and your program receives the verdict $\texttt{WRONG-ANSWER}$. Otherwise, you will receive the verdict according to the game's criteria described above.

After printing a line do not forget to end the line and flush the output. Otherwise, you will get the verdict $\texttt{TIMELIMIT}$. To flush the output, use:

* $\texttt{fflush(stdout)}$ in C;
* $\texttt{fflush(stdout)}$, $\texttt{cout <}\texttt{< flush}$ or $\texttt{cout.flush()}$ in C++;
* $\texttt{System.out.flush()}$ in Java and Kotlin;
* $\texttt{sys.stdout.flush()}$ in Python.

Examples

Input

```
5 14
3 7 2 3 10
```

Output

```
-
```

Input

```
4 10
4 1 6 4
```

Output

```
-
```

Note

In the first sample, it can be shown that Alessia can accomplish her goal. An example of interaction (after reading the input) follows:

 \begin{array}{|c|c|c|} \hline \textbf{Contestant} & \textbf{Judge} & \textbf{Explanation} \\ \hline \texttt{Alessia} & & \text{The program will act as Alessia} \\ \hline 3 \quad 11 & & \text{Choose $y = 3$ and $a = 11$} \\ \hline & 13 & \text{Judge selects $b = 13$} \\ \hline 10 \quad 2 & & \text{Choose $y = 10$ and $a = 2$} \\ \hline & 9 & \text{Judge selects $b = 9$} \\ \hline 7 \quad 1 & & \text{Choose $y = 7$ and $a = 1$} \\ \hline & 4 & \text{Judge selects $b = 4$} \\ \hline 2 \quad 10 & & \text{Choose $y = 2$ and $a = 10$} \\ \hline & 10 & \text{Judge selects $b = 10$} \\ \hline 3 \quad 6 & & \text{Choose $y = 3$ and $a = 6$} \\ \hline & 7 & \text{Judge selects $b = 7$} \\ \hline \end{array}

The program of the contestant wins because all the books chosen by Bernardo pertain to different topics. The actions performed by the contestant and the judge in this example of interaction may be non-optimal.

In the second sample, it can be shown that Bernardo can manage to fulfil his goal. An example of interaction (after reading the input) follows:

 \begin{array}{|c|c|c|} \hline \textbf{Contestant} & \textbf{Judge} & \textbf{Explanation} \\ \hline \texttt{Bernardo} & & \text{The program will act as Bernardo} \\ \hline & 4 \quad 1 & \text{Judge chooses $y = 4$ and $a = 1$} \\ \hline 4 & & \text{Select $b = 4$} \\ \hline & 1 \quad 10 & \text{Judge chooses $y = 1$ and $a = 10$} \\ \hline 10 & & \text{Select $b = 10$} \\ \hline & 6 \quad 3 & \text{Judge chooses $y = 6$ and $a = 3$} \\ \hline 4 & & \text{Select $b = 4$} \\ \hline & 4 \quad 5 & \text{Judge chooses $y = 4$ and $a = 5$} \\ \hline 8 & & \text{Select $b = 8$} \\ \hline \end{array}

The program of the contestant wins because Bernardo has selected two books on topic number $4$. The actions performed by the contestant and the judge in this example of interaction may be non-optimal.

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

using namespace std;

static int queries = 0;
static int query_limit = 0;

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

    }
}

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

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

    registerInteraction(argc, argv);
    atexit(log_metrics);

    int n = inf.readInt(1, 100, "n");
    int m = inf.readInt(n, 5000, "m");

    multiset<int> available_passes;
    vector<int> x(n);
    for (int i = 0; i < n; i++) {
        x[i] = inf.readInt(1, m, "x_i");
        available_passes.insert(x[i]);
    }

    query_limit = n;

    cout << n << " " << m << endl;
    for (int i = 0; i < n; i++) {
        cout << x[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;

    string role_token;
    if (!(cin >> role_token)) {
        finish(_wa, "No role provided");
    }

    bool contestant_is_alessia = false;
    if (role_token == "Alessia") {
        contestant_is_alessia = true;
    } else if (role_token == "Bernardo") {
        contestant_is_alessia = false;
    } else {
        finish(_wa, "Invalid role: " + role_token + " (expected Alessia or Bernardo)");
    }

    vector<bool> book_taken(m + 1, false);
    bool duplicate_found = false;

    for (int turn = 0; turn < n; turn++) {

        log_metrics();

        if (contestant_is_alessia) {

            string s;
            if (!(cin >> s)) finish(_pe, "Unexpected EOF reading 'y'");
            if (s == "?") cin >> s;

            int y = 0, a = 0;
            try { y = stoi(s); } catch(...) { finish(_pe, "Invalid format for 'y'"); }

            if (!(cin >> s)) finish(_pe, "Unexpected EOF reading 'a'");
            try { a = stoi(s); } catch(...) { finish(_pe, "Invalid format for 'a'"); }

            auto it = available_passes.find(y);
            if (it == available_passes.end()) {
                finish(_wa, "Pass length " + to_string(y) + " is not available");
            }
            available_passes.erase(it);

            if (a < 1 || a + y - 1 > m) {
                finish(_wa, "Interval [" + to_string(a) + ", " + to_string(a + y - 1) +
                            "] out of bounds [1, " + to_string(m) + "]");
            }

            int b = -1;
            for (int k = 0; k < y; k++) {
                int current_book = a + k;
                if (book_taken[current_book]) {
                    b = current_book;
                    break;
                }
            }

            if (b == -1) {
                b = a;
            }

            if (book_taken[b]) duplicate_found = true;
            book_taken[b] = true;

            cout << b << endl;

        } else {

            vector<pair<int, int>> gaps;
            int start = -1;
            for (int i = 1; i <= m; i++) {
                if (!book_taken[i]) {
                    if (start == -1) start = i;
                } else {
                    if (start != -1) {
                        gaps.push_back({start, i - 1});
                        start = -1;
                    }
                }
            }
            if (start != -1) {
                gaps.push_back({start, m});
            }

            int choose_y = -1;
            int choose_a = -1;

            for (auto rit = available_passes.rbegin(); rit != available_passes.rend(); ++rit) {
                int p = *rit;
                int best_gap_idx = -1;
                int min_gap_len = 1000000;

                for (int g = 0; g < (int)gaps.size(); g++) {
                    int gap_len = gaps[g].second - gaps[g].first + 1;
                    if (gap_len >= p) {
                        if (gap_len < min_gap_len) {
                            min_gap_len = gap_len;
                            best_gap_idx = g;
                        }
                    }
                }

                if (best_gap_idx != -1) {
                    choose_y = p;
                    choose_a = gaps[best_gap_idx].first;
                    break;
                }
            }

            if (choose_y == -1) {
                choose_y = *available_passes.begin();
                choose_a = 1;

                if (choose_a + choose_y - 1 > m) {
                    choose_a = m - choose_y + 1;
                }
            }

            available_passes.erase(available_passes.find(choose_y));

            cout << choose_y << " " << choose_a << endl;

            string s;
            if (!(cin >> s)) finish(_pe, "Unexpected EOF reading 'b'");
            if (s == "?" || s == "!") cin >> s;

            int b = 0;
            try { b = stoi(s); } catch(...) { finish(_pe, "Invalid format for 'b'"); }

            if (b < choose_a || b > choose_a + choose_y - 1) {
                finish(_wa, "Book " + to_string(b) + " is not in interval [" +
                            to_string(choose_a) + ", " + to_string(choose_a + choose_y - 1) + "]");
            }

            if (book_taken[b]) duplicate_found = true;
            book_taken[b] = true;
        }

        queries++;
    }

    log_metrics();

    if (contestant_is_alessia) {

        if (duplicate_found) {
            finish(_wa, "Bernardo (Judge) managed to take a duplicate book.");
        } else {
            finish(_ok, "Alessia (Contestant) successfully avoided duplicates.");
        }
    } else {

        if (duplicate_found) {
            finish(_ok, "Bernardo (Contestant) successfully took a duplicate book.");
        } else {
            finish(_wa, "Bernardo (Contestant) failed to take a duplicate book.");
        }
    }

    return 0;
}

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

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

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

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

string readToken() {
    string s;
    if (!(cin >> s)) finish(_wa, "Unexpected EOF reading token");
    return s;
}

int readInt() {
    string s;
    if (!(cin >> s)) finish(_wa, "Unexpected EOF reading int");
    try {
        size_t pos;
        int val = stoi(s, &pos);
        if (pos != s.size()) finish(_wa, "Malformed integer");
        return val;
    } catch (...) {
        finish(_wa, "Malformed integer");
    }
    return 0;
}

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

    registerInteraction(argc, argv);
    atexit(log_metrics);

    int n = inf.readInt();
    int m = inf.readInt();
    vector<int> x(n);
    multiset<int> available_passes;
    for (int i = 0; i < n; i++) {
        x[i] = inf.readInt();
        available_passes.insert(x[i]);
    }

    query_limit = n;

    cout << n << " " << m << endl;
    for (int i = 0; i < n; i++) {
        cout << x[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;

    string chosen_role = readToken();
    if (chosen_role != "Alessia" && chosen_role != "Bernardo") {
        finish(_wa, "Invalid role: " + chosen_role);
    }

    set<int> used_points;
    bool collision_occurred = false;

    if (chosen_role == "Alessia") {

        for (int turn = 1; turn <= n; turn++) {
            queries = turn;
            log_metrics();

            int y = readInt();
            int a = readInt();

            auto it = available_passes.find(y);
            if (it == available_passes.end()) {
                finish(_wa, "Used unavailable pass length " + to_string(y));
            }
            available_passes.erase(it);

            if (a < 1 || a + y - 1 > m) {
                finish(_wa, "Interval out of bounds: [" + to_string(a) + ", " + to_string(a + y - 1) + "]");
            }

            int L = a;
            int R = a + y - 1;
            int pick = -1;

            for (int u : used_points) {
                if (u >= L && u <= R) {
                    pick = u;
                    collision_occurred = true;
                    break;
                }
            }

            if (pick == -1) {

                int gap_start = 0;
                int gap_end = m + 1;

                auto it_up = used_points.upper_bound(R);
                if (it_up != used_points.end()) gap_end = *it_up;

                auto it_low = used_points.lower_bound(L);
                if (it_low != used_points.begin()) {
                    gap_start = *prev(it_low);
                }

                double target = (gap_start + gap_end) / 2.0;
                double best_dist = 1e18;
                pick = L;

                for (int candidate = L; candidate <= R; candidate++) {
                    double dist = abs(candidate - target);
                    if (dist < best_dist) {
                        best_dist = dist;
                        pick = candidate;
                    }
                }
            }

            cout << pick << endl;
            used_points.insert(pick);
        }

        if (collision_occurred) {
            finish(_wa, "Bernardo managed to get at least two books on the same subject");
        } else {
            if ((int)used_points.size() == n)
                finish(_ok, "Alessia wins (all distinct)");
            else
                finish(_wa, "Size mismatch logic error");
        }

    } else {

        vector<int> sorted_passes = x;
        sort(sorted_passes.rbegin(), sorted_passes.rend());

        for (int turn = 1; turn <= n; turn++) {
            queries = turn;
            log_metrics();

            int y = sorted_passes[turn - 1];

            vector<pair<int, int>> gaps;
            int last_u = 0;
            for (int u : used_points) {
                if (u > last_u + 1) {
                    gaps.push_back({last_u + 1, u - 1});
                }
                last_u = u;
            }
            if (m > last_u) {
                gaps.push_back({last_u + 1, m});
            }

            int best_gap_idx = -1;
            int max_len = -1;
            for (int i = 0; i < (int)gaps.size(); i++) {
                int len = gaps[i].second - gaps[i].first + 1;
                if (len >= y) {
                    if (len > max_len) {
                        max_len = len;
                        best_gap_idx = i;
                    }
                }
            }

            int a;
            if (best_gap_idx != -1) {

                a = gaps[best_gap_idx].first;
            } else {

                a = 1;

                if (a + y - 1 > m) a = m - y + 1;
            }

            cout << y << " " << a << endl;

            int b = readInt();

            if (b < a || b > a + y - 1) {
                finish(_wa, "Bernardo chose b outside interval");
            }

            if (used_points.count(b)) {
                collision_occurred = true;
            }
            used_points.insert(b);
        }

        if (collision_occurred) {
            finish(_ok, "Bernardo wins (managed collision)");
        } else {
            finish(_wa, "Alessia prevented collision");
        }
    }

    return 0;
}

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

using namespace std;

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

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

    int n, m;
    vector<int> x;

    if (mode == "adp") {

        int type = rnd.next(1, 6);

        if (type == 1) {

            n = rnd.next(50, 100);
            m = rnd.next(n, 3 * n);
            x.resize(n);
            for (int i = 0; i < n; i++)
                x[i] = rnd.next(1, max(1, m / 2));
        } else if (type == 2) {

            n = rnd.next(20, 50);
            m = rnd.next(n * 2, 2000);
            x.resize(n);
            for (int i = 0; i < n; i++)
                x[i] = rnd.next(m / 2, m);
        } else if (type == 3) {

            n = rnd.next(30, 80);
            m = rnd.next(n * 5, 5000);
            x.resize(n);
            for (int i = 0; i < n; i++) {
                if (rnd.next(2)) x[i] = rnd.next(1, 3);
                else x[i] = rnd.next(m / 3, m);
            }
        } else if (type == 4) {

            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
            int val = rnd.next(1, m);
            x.assign(n, val);
        } else if (type == 5) {

             n = rnd.next(20, 100);
             m = rnd.next(n * 2, 5000);
             x.resize(n);
             int limit = max(1, (int)sqrt(m));
             for(int i=0; i < n; i++) x[i] = rnd.next(limit, m);
        } else {

            n = rnd.next(80, 100);
            m = rnd.next(n, 5000);
            x.resize(n);
            for (int i = 0; i < n; i++) x[i] = rnd.next(1, m);
        }
    } else {

        int type = rnd.next(1, 7);

        if (type == 1) {
            n = rnd.next(1, 5);
            m = rnd.next(n, 20);
        } else if (type == 2) {
            n = rnd.next(5, 15);
            m = rnd.next(n, 50);
        } else if (type == 3) {
            n = 100;
            m = 5000;
        } else if (type == 4) {
            n = 100;
            m = 100;
        } else if (type == 5) {
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
            x.assign(n, 1);
        } else if (type == 6) {
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
            x.assign(n, m);
        } else {
            n = rnd.next(10, 100);
            m = rnd.next(n, 5000);
        }

        if (x.empty()) {
            x.resize(n);
            for (int i = 0; i < n; i++) x[i] = rnd.next(1, m);
        }
    }

    if (m < n) m = n;
    for (int i = 0; i < n; i++) {
        if (x[i] < 1) x[i] = 1;
        if (x[i] > m) x[i] = m;
    }

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

    println(n, m);
    println(x);

    return 0;
}


Ivan and Petr like to play with cacti — special graphs where each edge belongs to at most one simple cycle, and the graph is connected. Multiple edges between pairs of vertices and loops are allowed.

They invent the following game:

• Petr secretly builds a cactus with $n$ vertices and $m$ edges. The edges are labeled from 1 to $m$ .

• Petr only tells Ivan the number $m$ .

• Ivan is then allowed to ask questions of the following form:

– He chooses a subset $S$ of edge labels (see below about limitations on the subset), and asks: “If we only keep the edges whose labels are in $S$ (and all $n$ vertices), is the resulting graph connected?”
– Petr must answer either “yes” or “no”.

After asking at most $8 m$ questions, Ivan must determine, for every edge:

1. whether this edge lies on some cycle in the cactus;
2. if it does, what is the length of that simple cycle.

In this problem, each loop is considered a simple cycle of length 1 and two edges between the same pair of vertices form a simple cycle of length 2.

However, Ivan is still very young and only knows numbers up to 14. So:

• if an edge lies on a simple cycle of length at most 14, he must output that exact length; • if an edge lies on a simple cycle of length greater than 14, he must say that this edge lies on a big cycle.

Also, to avoid having to list a lot of edges each time, Ivan always asks about an edge set obtained from the set used in one of the previous queries, or from the set of all edges, by removing exactly one edge.

Can you design a strategy that allows Ivan to complete this task?

# Input

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

The first line of each test case contains $m$ $1 \leq m \leq 1 0 ^ { 4 }$ ) — the number of edges in the cactus.

It is guaranteed that the sum of $m$ over all test cases does not exceed $1 0 ^ { 4 }$ .

# Interaction Protocol

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

• “ ? $\textit { p } e ^ { \gamma }$ ( $0 \leq p \leq q$ ; $1 \leq e \leq m$ ), where $p$ is the number of a previous query or zero (queries are numbered from 1 in the order they are asked), $q$ is the number of queries made before the current one, $e$ is the label an edge.

The query denotes a graph consisting of the edges used in the query number $p$ (or all edges if $p = 0$ ), with edge $e$ removed. The interactor checks whether this graph is connected when considering all original vertices and returns a single integer:

$\bullet$ $^ 1$ if the graph denoted by the query is connected;
$\bullet$ $0$ if the graph denoted by the query is not connected;
• $^ { - 1 }$ if you have exceeded $\mathrm { 8 } m$ allowed queries or edge $e$ was already removed from the set of edges used in query $p$ . In this case you should terminate your program to receive a Wrong Answer verdict.

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

• “ ! $e _ { 1 }$ e2 . . . $e _ { m }$ ” (−1 ≤ ei ≤ 14 for all i),

where:

• if $e _ { i }$ is positive, then edge number $i$ belongs to a simple cycle of length exactly $e _ { i }$ , • if $e _ { i } = 0$ , then edge number $i$ belongs to a big cycle (simple cycle of length greater than 14), • if $e _ { i } = - 1$ , then edge number $i$ does not belong to any cycle.

The interactor returns a single integer:

• 1 if your answer is correct. Proceed to the next test case or terminate your program if this was the last case.
• $- 1$ if your answer is incorrect. In this case you should terminate your program to receive a Wrong Answer verdict.

The interactor is not adaptive, meaning that the graph is fixed before you ask any queries.

# Example

standard input	standard output

1

	？01

0

1	？03

1	？24

1	!-1313232

# Note

In the example interaction, the input and output contain empty lines to align interactor responses with queries. These empty lines do not appear in the actual input and output.

In this example, the graph has 5 vertices and 7 edges; edges 1 through 7, in this order, are $( 1 , 2 )$ , $( 2 , 3 )$ , $( 3 , 3 )$ , $( 3 , 4 )$ , $( 4 , 5 )$ , $( 2 , 4 )$ , $( 4 , 5 )$ .

![](images/380fab149723c0e3b0b1a7c96c515456622fb609e35534e63249d071c7191b1b.jpg)
Page 2 of 2

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

static long long current_queries = 0;
static long long current_limit = 0;

void log_metrics() {
    if (current_limit > 0) {
        try {
            tout << "queries=" << current_queries << endl;
            tout << "query_limit=" << current_limit << endl;
        } catch (...) {}
    }
}

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

const int MAXN = 20005;
const int MAXM = 20005;

int head[MAXN];
struct EdgeNode {
    int to;
    int nxt;
    int id;
} edges_store[MAXM * 2];
int ecnt = 0;

void add_edge(int u, int v, int id) {
    edges_store[ecnt] = {v, head[u], id};
    head[u] = ecnt++;
    edges_store[ecnt] = {u, head[v], id};
    head[v] = ecnt++;
}

int N, M;
vector<int> edge_ans;

vector<vector<bool>> history_sets;

int vis[MAXN];
int p_node[MAXN];
int p_edge[MAXN];
int depth[MAXN];

void find_cycles() {
    edge_ans.assign(M, -1);

    for(int i = 0; i <= N; ++i) {
        vis[i] = 0;
        p_node[i] = 0;
        p_edge[i] = -1;
        depth[i] = 0;
    }

    if (N < 1) return;

    function<void(int, int)> dfs = [&](int u, int pe_idx) {
        vis[u] = 1;
        for (int i = head[u]; i != -1; i = edges_store[i].nxt) {
            int v = edges_store[i].to;
            int idx = edges_store[i].id;

            if (idx == pe_idx) continue;

            if (vis[v] == 1) {

                vector<int> cycle;
                cycle.push_back(idx);

                int curr = u;
                while (curr != v) {
                    cycle.push_back(p_edge[curr]);
                    curr = p_node[curr];
                }

                int len = cycle.size();
                int val = (len <= 14 ? len : 0);

                for (int eid : cycle) {
                    edge_ans[eid] = val;
                }
            } else if (vis[v] == 0) {
                p_node[v] = u;
                p_edge[v] = idx;
                depth[v] = depth[u] + 1;
                dfs(v, idx);
            }
        }
        vis[u] = 2;
    };

    dfs(1, -1);
}

int bfs_vis[MAXN];
int bfs_cookie = 0;
int bfs_q[MAXN];

bool check_conn(const vector<bool>& mask) {
    if (N <= 1) return true;

    bfs_cookie++;
    int q_head = 0, q_tail = 0;

    bfs_q[q_tail++] = 1;
    bfs_vis[1] = bfs_cookie;
    int visited_count = 0;

    while(q_head < q_tail) {
        int u = bfs_q[q_head++];
        visited_count++;

        for (int i = head[u]; i != -1; i = edges_store[i].nxt) {
            int v = edges_store[i].to;
            int idx = edges_store[i].id;

            if (mask[idx] && bfs_vis[v] != bfs_cookie) {
                bfs_vis[v] = bfs_cookie;
                bfs_q[q_tail++] = v;
            }
        }
    }

    return visited_count == N;
}

void solve_case() {

    N = inf.readInt();
    M = inf.readInt();

    ecnt = 0;
    for(int i = 0; i <= N; ++i) head[i] = -1;

    for(int i = 0; i < M; ++i) {
        int u = inf.readInt();
        int v = inf.readInt();
        add_edge(u, v, i);
    }

    find_cycles();

    cout << M << endl;

    current_queries = 0;
    current_limit = 8LL * M;
    log_metrics();

    history_sets.clear();

    history_sets.reserve(80005);

    history_sets.push_back(vector<bool>(M, true));

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF while waiting for query/answer");
        }

        if (token == "!") {

            bool correct = true;
            for (int i = 0; i < M; ++i) {
                int val;
                if (!(cin >> val)) finish(_wa, "Unexpected EOF reading answer values");
                if (val != edge_ans[i]) correct = false;
            }

            if (correct) {
                cout << 1 << endl;
                return;
            } else {
                cout << -1 << endl;
                finish(_wa, "Incorrect answer provided");
            }
        } else {

            int p;
            int e_label;

            if (token == "?") {
                if (!(cin >> p >> e_label)) finish(_wa, "Invalid query format");
            } else {

                try {
                    p = stoi(token);
                    if (!(cin >> e_label)) finish(_wa, "Invalid query format");
                } catch (...) {
                    finish(_wa, "Invalid query token (expected '!', '?', or integer)");
                }
            }

            current_queries++;

            if (current_queries % 100 == 0) log_metrics();

            if (current_queries > current_limit) {
                cout << -1 << endl;
                finish(_wa, "Query limit exceeded");
            }

            if (p < 0 || p >= (int)history_sets.size()) {
                cout << -1 << endl;
                finish(_wa, "Invalid query index p (out of range)");
            }

            if (e_label < 1 || e_label > M) {
                cout << -1 << endl;
                finish(_wa, "Invalid edge label e (out of range)");
            }

            int e_idx = e_label - 1;

            if (!history_sets[p][e_idx]) {
                cout << -1 << endl;
                finish(_wa, "Edge not present in referenced query set");
            }

            history_sets.push_back(history_sets[p]);
            history_sets.back()[e_idx] = false;

            bool connected = check_conn(history_sets.back());
            cout << (connected ? 1 : 0) << endl;
        }
    }
}

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

    registerInteraction(argc, argv);
    atexit(log_metrics);

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

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

    for (int i = 0; i < T; ++i) {
        solve_case();
    }

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

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

struct Graph {
    int n;
    vector<pair<int, int>> edges;
};

vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> tree_edges;
    if (n <= 1) return tree_edges;

    vector<int> p(n + 1);
    for (int i = 2; i <= n; i++) {
        p[i] = rnd.next(1, i - 1);
        tree_edges.push_back({i, p[i]});
    }

    vector<int> perm(n + 1);
    for (int i = 1; i <= n; i++) perm[i] = i;
    shuffle(perm.begin() + 1, perm.end());

    vector<pair<int, int>> ret;
    for (auto e : tree_edges) {
        ret.push_back({perm[e.first], perm[e.second]});
    }
    return ret;
}

Graph genCactus(int n, int target_m, bool force_tricky = false) {
    Graph g;
    g.n = n;

    vector<pair<int, int>> tree_edges = genTree(n);

    vector<vector<pair<int, int>>> adj(n + 1);
    for (int i = 0; i < (int)tree_edges.size(); i++) {
        adj[tree_edges[i].first].push_back({tree_edges[i].second, i});
        adj[tree_edges[i].second].push_back({tree_edges[i].first, i});
    }

    vector<bool> edge_in_cycle(tree_edges.size(), false);
    vector<pair<int, int>> extra_edges;
    int current_m = (int)tree_edges.size();

    auto getPath = [&](int u, int v) -> vector<int> {
        if (u == v) return {};
        queue<pair<int, vector<int>>> q;
        q.push({u, {}});
        vector<bool> vis(n + 1, false);
        vis[u] = true;

        while(!q.empty()){
            auto [curr, path] = q.front();
            q.pop();
            if (curr == v) return path;

            for (auto& edge : adj[curr]) {
                int nxt = edge.first;
                int id = edge.second;
                if (!vis[nxt]) {
                    vis[nxt] = true;
                    vector<int> new_path = path;
                    new_path.push_back(id);
                    q.push({nxt, new_path});
                }
            }
        }
        return {};
    };

    int attempts = 0;
    while (current_m < target_m && attempts < 2000) {
        attempts++;

        int len_target = -1;
        if (force_tricky) {
            int r = rnd.next(0, 8);
            if (r == 0) len_target = 14;
            else if (r == 1) len_target = 15;
            else if (r == 2) len_target = 1;
            else if (r == 3) len_target = 2;

        } else {

            if (rnd.next(0, 30) == 0) len_target = 14;
            if (rnd.next(0, 30) == 0) len_target = 15;
        }

        if (len_target != -1) {
            if (len_target == 1) {

                int u = rnd.next(1, n);
                extra_edges.push_back({u, u});
                current_m++;
                continue;
            }

            int dist_needed = len_target - 1;
            bool found = false;

            for(int k=0; k<15; ++k) {
                int u = rnd.next(1, n);

                vector<int> candidates;
                queue<pair<int, int>> q;
                q.push({u, 0});
                vector<int> dist(n + 1, -1);
                dist[u] = 0;

                while(!q.empty()){
                    auto [curr, d] = q.front();
                    q.pop();
                    if (d == dist_needed) candidates.push_back(curr);
                    if (d < dist_needed) {
                        for(auto& e : adj[curr]) {
                            if(dist[e.first] == -1) {
                                dist[e.first] = d+1;
                                q.push({e.first, d+1});
                            }
                        }
                    }
                }

                if(candidates.empty()) continue;
                int v = candidates[rnd.next(0, (int)candidates.size() - 1)];
                vector<int> path = getPath(u, v);

                bool ok = true;
                for(int id : path) if(edge_in_cycle[id]) ok = false;

                if(ok) {
                    for(int id : path) edge_in_cycle[id] = true;
                    extra_edges.push_back({u, v});
                    current_m++;
                    found = true;
                    break;
                }
            }
        } else {

            int u = rnd.next(1, n);
            int v = rnd.next(1, n);

            if (u == v) {

                extra_edges.push_back({u, u});
                current_m++;
            } else {
                vector<int> path = getPath(u, v);
                bool ok = true;
                for(int id : path) if(edge_in_cycle[id]) ok = false;

                if(ok) {
                    for(int id : path) edge_in_cycle[id] = true;
                    extra_edges.push_back({u, v});
                    current_m++;
                }
            }
        }
    }

    for (auto e : tree_edges) g.edges.push_back(e);
    for (auto e : extra_edges) g.edges.push_back(e);

    shuffle(g.edges.begin(), g.edges.end());

    return g;
}

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

    string mode = opt<string>("mode", "non");
    int seed = atoi(argv[1]);

    vector<Graph> cases;

    if (seed <= 3) {
        if (seed == 1) {

            cases.push_back(genCactus(8, 7));

            Graph g_loop; g_loop.n = 1; g_loop.edges = {{1, 1}};
            cases.push_back(g_loop);

            Graph g_double; g_double.n = 2; g_double.edges = {{1, 2}, {1, 2}};
            cases.push_back(g_double);

            Graph g14; g14.n = 14;
            for(int i=1; i<14; i++) g14.edges.push_back({i, i+1});
            g14.edges.push_back({14, 1});
            shuffle(g14.edges.begin(), g14.edges.end());
            cases.push_back(g14);

        } else if (seed == 2) {

            Graph g15; g15.n = 15;
            for(int i=1; i<15; i++) g15.edges.push_back({i, i+1});
            g15.edges.push_back({15, 1});
            shuffle(g15.edges.begin(), g15.edges.end());
            cases.push_back(g15);

            cases.push_back(genCactus(20, 25, true));

        } else {

            cases.push_back(genCactus(10, 20, true));
            cases.push_back(genCactus(6, 10, true));
        }
    }

    else {
        int total_m = 1000;

        if (seed > 10) total_m = rnd.next(2000, 10000);
        else total_m = rnd.next(100, 1000);

        int t = rnd.next(1, 10);

        if (total_m < 20) t = 1;

        vector<int> ms = rnd.partition(t, total_m, 1);

        for (int m : ms) {

            int n_low = max(1, (int)sqrt(m));
            int n_high = m + 1;
            int n = rnd.next(n_low, n_high);

            if (n < 1) n = 1;

            cases.push_back(genCactus(n, m, (seed % 7 == 0)));
        }
    }

    cout << cases.size() << endl;
    for(const auto& g : cases) {
        if (mode == "non") {
            cout << g.n << " " << g.edges.size() << endl;
            for(const auto& e : g.edges) {
                cout << e.first << " " << e.second << endl;
            }
        } else {

            cout << g.n << " " << g.edges.size() << endl;
        }
    }

    return 0;
}


This is an interactive problem. The only difference between the easy and hard version is the limit on number of questions.

There are $n$ players labelled from $1$ to $n$. It is guaranteed that $n$ is a multiple of $3$.

Among them, there are $k$ impostors and $n-k$ crewmates. The number of impostors, $k$, is not given to you. It is guaranteed that $\frac{n}{3} < k < \frac{2n}{3}$.

In each question, you can choose three distinct integers $a$, $b$, $c$ ($1 \le a, b, c \le n$) and ask: "Among the players labelled $a$, $b$ and $c$, are there more impostors or more crewmates?" You will be given the integer $0$ if there are more impostors than crewmates, and $1$ otherwise.

Find the number of impostors $k$ and the indices of players that are impostors after asking at most $n+6$ questions.

The jury is adaptive, which means the indices of impostors may not be fixed beforehand and can depend on your questions. It is guaranteed that there is at least one set of impostors which fulfills the constraints and the answers to your questions at any time.

Input

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

The first and only line of each test case contains a single integer $n$ ($6 \le n < 10^4$, $n$ is a multiple of $3$) — the number of players.

It is guaranteed that the sum of $n$ over all test cases does not exceed $2 \cdot 10^4$.

Interaction

For each test case, the interaction starts with reading $n$.

Then you are allowed to make at most $n+6$ questions in the following way:

"? a b c" ($1 \le a, b, c \le n$, $a$, $b$ and $c$ are pairwise distinct).

After each one, you should read an integer $r$, which is equal to $0$ if there are more impostors than crewmates among players labelled $a$, $b$ and $c$, and equal to $1$ otherwise.

Answer $-1$ instead of $0$ or $1$ means that you made an invalid query. Exit immediately after receiving $-1$ and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you have found the indices of all impostors, print a single line "! " (without quotes), followed by the number of impostors $k$, followed by $k$ integers representing the indices of the impostors. Please note that you must print all this information on the same line.

After printing the answer, your program must then continue to solve the remaining test cases, or exit if all test cases have been solved.

After printing the queries and answers do not forget to output end of line and flush the output buffer. Otherwise, you will get the Idleness limit exceeded verdict. To do flush use:

* fflush(stdout) or cout.flush() in C++;
* System.out.flush() in Java;
* flush(output) in Pascal;
* stdout.flush() in Python;
* Read documentation for other languages.

Example

Input

```
2
6

0

1

9

1
```

Output

```
? 1 2 3

? 3 4 5

! 3 4 1 2

? 7 1 9

! 4 2 3 6 8
```

Note

Explanation for example interaction (note that this example only exists to demonstrate the interaction procedure and does not provide any hint for the solution):

For the first test case:

Question "? 1 2 3" returns $0$, so there are more impostors than crewmates among players $1$, $2$ and $3$.

Question "? 3 4 5" returns $1$, so there are more crewmates than impostors among players $3$, $4$ and $5$.

Outputting "! 3 4 1 2" means that one has found all the impostors, by some miracle. There are $k = 3$ impostors. The players who are impostors are players $4$, $1$ and $2$.

For the second test case:

Question "? 7 1 9" returns $1$, so there are more crewmates than impostors among players $7$, $1$ and $9$.

Outputting "! 4 2 3 6 8" means that one has found all the impostors, by some miracle. There are $k = 4$ impostors. The players who are impostors are players $2$, $3$, $6$ and $8$.

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

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

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

    }
}

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

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    int t = inf.readInt();

    cout << t << endl;

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

        int n = inf.readInt();

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

        vector<int> roles(n + 1);
        vector<int> impostors;
        for (int j = 1; j <= n; j++) {
            roles[j] = inf.readInt();
            if (roles[j] == 0) {
                impostors.push_back(j);
            }
        }

        sort(impostors.begin(), impostors.end());

        cout << n << endl;

        while (true) {

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

            string token;
            cin >> token;
            if (cin.fail()) {
                finish(_pe, "Unexpected EOF from solution");
            }

            if (token == "!") {

                int k_ans;
                if (!(cin >> k_ans)) finish(_pe, "Failed to read k");

                vector<int> ans_indices;
                set<int> seen;
                for (int k = 0; k < k_ans; k++) {
                    int idx;
                    if (!(cin >> idx)) finish(_pe, "Failed to read index");
                    if (seen.count(idx)) finish(_wa, "Duplicate index in output");
                    seen.insert(idx);
                    ans_indices.push_back(idx);
                }
                sort(ans_indices.begin(), ans_indices.end());

                if ((int)ans_indices.size() != (int)impostors.size()) {
                    finish(_wa, "Incorrect number of impostors");
                }
                if (ans_indices != impostors) {
                    finish(_wa, "Incorrect set of impostors");
                }

                break;
            } else {

                int a, b, c;
                if (token == "?") {
                    if (!(cin >> a >> b >> c)) finish(_pe, "Failed to read query arguments");
                } else {

                    try {
                        a = stoi(token);
                    } catch (...) {
                        finish(_pe, "Invalid integer token");
                    }
                    if (!(cin >> b >> c)) finish(_pe, "Failed to read b and c");
                }

                queries++;

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

                if (a < 1 || a > n || b < 1 || b > n || c < 1 || c > n) {
                    cout << -1 << endl;
                    finish(_wa, format("Indices out of bounds: %d %d %d", a, b, c));
                }
                if (a == b || a == c || b == c) {
                    cout << -1 << endl;
                    finish(_wa, format("Indices must be distinct: %d %d %d", a, b, c));
                }

                int s = roles[a] + roles[b] + roles[c];
                cout << (s <= 1 ? 0 : 1) << endl;
            }
        }
    }

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

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

using namespace std;

static long long total_queries = 0;
static long long total_query_limit = 0;
static const long long HARD_CAP = 200000;

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

    }
}

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

int n;
vector<int> roles;

bool isValid(int a, int b, int c) {
    if (a < 1 || a > n) return false;
    if (b < 1 || b > n) return false;
    if (c < 1 || c > n) return false;

    if (a == b || a == c || b == c) return false;
    return true;
}

void solve_test_case() {

    n = inf.readInt();

    vector<int> input_p(n);
    bool is_adaptive_mode = false;
    for (int i = 0; i < n; i++) {
        input_p[i] = inf.readInt();
        if (input_p[i] == -1) is_adaptive_mode = true;
    }

    roles.assign(n, 0);
    if (!is_adaptive_mode) {
        roles = input_p;
    } else {

        int min_k = n / 3 + 1;
        int max_k = 2 * n / 3 - 1;

        int k = rnd.next(min_k, max_k);

        for (int i = 0; i < n; i++) {
            if (i < k) roles[i] = 0;
            else roles[i] = 1;
        }

        shuffle(roles.begin(), roles.end());
    }

    total_query_limit += (n + 6);

    cout << n << endl;

    while (true) {

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

        string type;
        if (!(cin >> type)) {
            finish(_pe, "Unexpected end of file from solution");
        }

        if (type == "?") {
            int a, b, c;
            if (!(cin >> a >> b >> c)) {
                finish(_pe, "Invalid query format");
            }

            if (!isValid(a, b, c)) {

                cout << -1 << endl;
                finish(_wa, format("Invalid query indices: %d %d %d", a, b, c));
            }

            total_queries++;

            int imp_count = 0;
            if (roles[a-1] == 0) imp_count++;
            if (roles[b-1] == 0) imp_count++;
            if (roles[c-1] == 0) imp_count++;

            int ans = (imp_count >= 2) ? 0 : 1;
            cout << ans << endl;

            if (total_queries % 500 == 0) log_metrics();

        } else if (type == "!") {
            int k_claimed;
            if (!(cin >> k_claimed)) finish(_pe, "Invalid answer format (reading k)");

            vector<int> claimed_indices;
            claimed_indices.reserve(k_claimed);
            for (int i = 0; i < k_claimed; i++) {
                int idx;
                if (!(cin >> idx)) finish(_pe, "Invalid answer format (reading indices)");
                claimed_indices.push_back(idx);
            }

            int actual_k = 0;
            vector<int> actual_indices;
            for (int i = 0; i < n; i++) {
                if (roles[i] == 0) {
                    actual_k++;
                    actual_indices.push_back(i + 1);
                }
            }

            if (k_claimed != actual_k) {
                finish(_wa, format("Wrong number of impostors: expected %d, found %d", actual_k, k_claimed));
            }

            sort(claimed_indices.begin(), claimed_indices.end());
            sort(actual_indices.begin(), actual_indices.end());

            if (claimed_indices != actual_indices) {
                finish(_wa, "Indices of impostors do not match the hidden instance");
            }

            return;

        } else {
            finish(_pe, format("Unknown query type: %s", type.c_str()));
        }
    }
}

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

    registerInteraction(argc, argv);
    atexit(log_metrics);

    int t = inf.readInt();

    cout << t << endl;

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

    string dummy;
    if (cin >> dummy) {
        finish(_pe, "Extra output after last test case");
    }

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

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

using namespace std;

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

    registerGen(argc, argv, 1);

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

    int n = opt<int>("n", 0);

    if (n == 0) {
        long long seed_val = 0;

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

        if (seed_val == 1) {
            n = 6;
        } else if (seed_val == 2) {
            n = 9999;
        } else if (seed_val == 3) {
            n = 12;
        } else {

            n = 3 * rnd.next(2, 3333);
        }
    }

    if (n < 6) n = 6;
    if (n % 3 != 0) n -= (n % 3);

    cout << 1 << "\n";

    cout << n << "\n";

    if (mode == "adp") {

        for (int i = 0; i < n; i++) {
            cout << -1 << (i == n - 1 ? "" : " ");
        }
        cout << "\n";
    } else {

        int min_k = n / 3 + 1;
        int max_k = 2 * n / 3 - 1;

        int k;

        int type = rnd.next(1, 10);
        if (type == 1) k = min_k;
        else if (type == 2) k = max_k;
        else k = rnd.next(min_k, max_k);

        vector<int> p(n);
        for (int i = 0; i < n; i++) {
            if (i < k) p[i] = 0;
            else p[i] = 1;
        }

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

        for (int i = 0; i < n; i++) {
            cout << p[i] << (i == n - 1 ? "" : " ");
        }
        cout << "\n";
    }

    return 0;
}


This is an interactive problem.

The game "Plumber Mariusz” consists of $n { \mathrel { + { 1 } } }$ levels (numbered from 0 to $n$ ), each of which has $k$ versions (numbered from 0 to $k - 1$ ). Each version of every level (except the last one) ends with two pipes – the left and the right – and Mariusz must jump into one of them. Each pipe contains some number of coins and leads to one of the versions of the next level. Exactly two pipes lead to each version of each level (except level zero); these may be any two among the $2 \cdot k$ pipes coming out of all $k$ versions of the previous level.

A single playthrough consists of choosing a version of level zero and then choosing left or right pipe $n$ times, and the result of the playthrough is the total number of coins collected in the $n$ visited pipes. We do not learn how many coins were in each pipe or which versions of the levels were visited. Coins in the pipes always reset to their initial values, so all playthroughs are independent. A playthrough can therefore be represented by the function:

int rozgrywka(int ver, string s), where $v e r \in | 0 , k - 1 |$ and $s$ is a string of $n$ letters $\mathrm { L }$ and $\mathrm { P }$ .

Note that L and P correspond to the polish words for left and right respectively.

You may perform up to 300 000 test playthroughs and learn their results. After that, you will receive up to 10 000 queries about playthroughs. Your task is to determine their results.

Each test is fixed before the interaction begins (i.e. the interactor is not adaptive). A test contains a directed weighted graph with $( n + 1 ) \cdot k$ vertices arranged in $n + 1$ layers (levels), and q queries $( v e r , s )$ . Each vertex (except those in the last layer) has two outgoing edges (left and right), each described by a coin count $c \in [ 1 , 1 0 ^ { 8 } ]$ and a version $v \in [ 0 , k - 1 ]$ it leads to. Recall that every vertex except those in layer zero has in-degree exactly 2.

# Buffer flushing

After outputting each line you must flush the output buffer, so that the interactor receives the output line. For example, in $\mathrm { C } + +$ you may output a line containing an exclamation mark using cout << "!" << endl; or using printf $( " ! \setminus " )$ ; fflush(stdout);. In Python you may use print("!", flush=True). We do not guarantee stable behavior of the interactor if you output multiple lines without flushing after each of them, or if you output many lines without reading the interactor’s responses. Your program may not open any files.

# Interaction Protocol

The full communication flow is described below:

• Read the first line containing two integers $n$ and $k$ ( $1 \leq n , k \leq 2 0$ ) – there are $n + 1$ levels, each with $k$ versions.

• Up to 300 000 times, perform a test playthrough:

– Output a line of the form „? ver $\boldsymbol { \mathsf { s } } ^ { \flat }$ (without quotes), where $v e r \in [ 0 , k - 1 ]$ and $s$ is a string of $n$ letters L and P. Flush.
– Read the next line containing the result of the playthrough – an integer $x$ $n \leq x \leq n \cdot 1 0 ^ { 8 } \leq 2 \cdot 1 0 ^ { 9 } ,$ ).

• Output a line containing a single character ! (exclamation mark). Flush.

• Read the next line containing an integer $q$ ( $1 \leq q \leq 1 0 0 0 0$ ) – the number of queries.

• For each of the $q$ queries:

– Read the next line containing an integer ver and a string $s$ (same limits as above).
– Output a line containing the result of the playthrough (an integer). Flush.

![](images/36067e90a9f93909e8f7753c28a36331d0a3a04d23eaaa0470d411041486a6ed.jpg)

The illustration shows the first sample test ( $n = 2$ ; $k = 4$ ). Two final queries are marked using dashed lines: rozgrywka(0, "LL") $= 2 0 + 3 = 2 3$ and rozgrywka(1, "PL") $= 9 + 1 0 = 1 9$ .

# Example

Here is an example communication flow:

Your program	Interactor	Description

？O LL	24	3 levels (0...2),each with 4 versions (0...3).

23	First dashed path in the figure.Start from version O of level O, jump into the left pipe (20 coins). From version 1 of level 1 again jump into the left pipe (3 coins). Result: 2O+3= 23.

？O LL	23	Same playthrough, same result.

？2 PL	610	600 +10=610.

？OPP ？ 3 LP	9	5+4=9.

！	7	5+2=7.

23		End of test playthroughs.

2 OLL	There are q= 2 queries to answer.

	Lucky - we tested this exact playthrough!

1 PL

		We do not know the result and cannot deduce it. We never

19		tested starting from version 1 of level 0. By chance, we guess the correct result: 9 +10 = 19.

# Note

In the attachment (you can download it in the “attachment” tab at QOJ) you will find sample (incorrect) solutions G.cpp and G.py that perform the communication correctly, but compute the results incorrectly. The directory also includes: a sample checker Gsoc.cpp and sample tests (G0a.in, G0b.in, G0c.in, and a large random test G0d.in with $n = k = 2 0$ ). The format of test files is described in the comment at the beginning of Gsoc.cpp.

The sample checker Gsoc.cpp differs from the one used in QOJ. It might not validate input or the arguments of the playthrough function.

You can run your solution using the script run.sh. The command takes the compiled program and the test file name. For example, to run the sample programs on the sample test G0a.in:

• C++: ${ \tt S } ^ { + + }$ G.cpp -o G.e && ./run.sh "./G.e" G0a.in • Python: ./run.sh "python3 G.py" G0a.in

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

using namespace std;

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

struct Edge {
    int next_ver;
    int weight;
};

vector<vector<vector<Edge>>> adj;
int n, k;

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

long long solve_path(int ver, const string& s) {
    long long total = 0;
    int curr = ver;
    for (int i = 0; i < n; i++) {
        char c = s[i];
        int dir = (c == 'P' ? 1 : 0);
        total += adj[i][curr][dir].weight;
        curr = adj[i][curr][dir].next_ver;
    }
    return total;
}

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

    registerInteraction(argc, argv);
    atexit(log_metrics);

    n = inf.readInt(1, 20, "n");
    k = inf.readInt(1, 20, "k");

    adj.resize(n, vector<vector<Edge>>(k, vector<Edge>(2)));

    for (int i = 0; i < n; i++) {
        for (int u = 0; u < k; u++) {

            int vL = inf.readInt();
            int wL = inf.readInt();
            int vR = inf.readInt();
            int wR = inf.readInt();

            adj[i][u][0] = {vL, wL};
            adj[i][u][1] = {vR, wR};
        }
    }

    int q_count = inf.readInt(1, 10000, "q");
    vector<pair<int, string>> test_queries(q_count);
    for (int i = 0; i < q_count; i++) {
        test_queries[i].first = inf.readInt();
        test_queries[i].second = inf.readToken();
    }

    cout << n << " " << k << endl;

    long long hard_cap = 2000000;

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_pe, "Unexpected EOF during Phase 1 (expected '?' or '!')");
        }

        if (token == "!") {
            break;
        }

        int ver;
        string s;

        if (token == "?") {
            if (!(cin >> ver >> s)) {
                finish(_pe, "Invalid query format after '?'");
            }
        } else {

            bool is_num = !token.empty();
            for (char c : token) if (!isdigit(c)) is_num = false;

            if (is_num) {
                try {
                    ver = stoi(token);
                } catch (...) {
                    finish(_pe, "Token is not a valid integer: " + token);
                }
                if (!(cin >> s)) {
                    finish(_pe, "Missing string s after version");
                }
            } else {
                finish(_pe, "Unknown token (expected '?', '!', or integer): " + token);
            }
        }

        if (ver < 0 || ver >= k) {
            finish(_pe, "Version " + to_string(ver) + " out of range [0, " + to_string(k-1) + "]");
        }
        if ((int)s.size() != n) {
            finish(_pe, "String length must be exactly " + to_string(n));
        }
        for (char c : s) {
            if (c != 'L' && c != 'P') {
                finish(_pe, "String must contain only 'L' or 'P'");
            }
        }

        long long ans = solve_path(ver, s);
        cout << ans << endl;

        queries++;
        if (queries % 1000 == 0) log_metrics();
        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded (possible infinite loop)");
        }
    }

    cout << q_count << endl;

    for (int i = 0; i < q_count; i++) {
        int t_ver = test_queries[i].first;
        string t_s = test_queries[i].second;

        cout << t_ver << " " << t_s << endl;

        long long user_ans;
        if (!(cin >> user_ans)) {
            finish(_pe, "Expected integer answer from contestant for test query " + to_string(i+1));
        }

        long long correct = solve_path(t_ver, t_s);
        if (user_ans != correct) {
            finish(_wa, "Incorrect answer for query " + to_string(i+1) +
                        ". Expected " + to_string(correct) + ", got " + to_string(user_ans));
        }
    }

    finish(_ok, "Passed all " + to_string(q_count) + " test queries.");
    return 0;
}

#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) {
        try {
            seed_val = stoll(string(argv[1]));
        } catch (...) {
            seed_val = 0;
        }
    }

    int n = 0, k = 0, q = 0;

    if (seed_val == 1) {

        n = 1; k = 1; q = 5;
    } else if (seed_val == 2) {

        n = 20; k = 20; q = 10000;
    } else if (seed_val == 3) {

        n = 20; k = 1; q = 100;
    } else {

        n = rnd.next(1, 20);
        k = rnd.next(1, 20);

        if (rnd.next(3) == 0) q = rnd.next(1, 100);
        else q = rnd.next(100, 10000);
    }

    if (opt<int>("n", 0) != 0) n = opt<int>("n");
    if (opt<int>("k", 0) != 0) k = opt<int>("k");
    if (opt<int>("q", 0) != 0) q = opt<int>("q");

    n = clamp(n, 1, 20);
    k = clamp(k, 1, 20);
    q = clamp(q, 1, 10000);

    if (mode == "adp") {
        cout << n << " " << k << endl;
        cout << q << endl;
        return 0;
    }

    cout << n << " " << k << endl;

    for (int i = 0; i < n; i++) {

        vector<int> dests;
        dests.reserve(2 * k);
        for (int v = 0; v < k; v++) {
            dests.push_back(v);
            dests.push_back(v);
        }

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

        for (int u = 0; u < k; u++) {
            int vL = dests[2 * u];
            int vR = dests[2 * u + 1];

            int wL = rnd.next(1, 100000000);
            int wR = rnd.next(1, 100000000);

            cout << vL << " " << wL << " " << vR << " " << wR << "\n";
        }
    }

    cout << q << endl;
    for (int i = 0; i < q; i++) {
        int ver = rnd.next(0, k - 1);
        string s;
        s.reserve(n);
        for (int j = 0; j < n; j++) {

            s += (rnd.next(0, 1) ? 'L' : 'P');
        }
        cout << ver << " " << s << "\n";
    }

    return 0;
}


This is an interactive problem.

A legendary tree rests deep in the forest. Legend has it that individuals who realize this tree would eternally become a Legendary Grandmaster.

To help you determine the tree, Mikaela the Goddess has revealed to you that the tree contains $n$ vertices, enumerated from $1$ through $n$. She also allows you to ask her some questions as follows. For each question, you should tell Mikaela some two disjoint non-empty sets of vertices $S$ and $T$, along with any vertex $v$ that you like. Then, Mikaela will count and give you the number of pairs of vertices $(s, t)$ where $s \in S$ and $t \in T$ such that the simple path from $s$ to $t$ contains $v$.

Mikaela the Goddess is busy and will be available to answer at most $11\,111$ questions.

This is your only chance. Your task is to determine the tree and report its edges.

Input

The first line contains an integer $n$ ($2 \leq n \leq 500$) — the number of vertices in the tree.

Output

When program has realized the tree and is ready to report the edges, print "ANSWER" in a separate line. Make sure that all letters are capitalized.

Then, print $n-1$ lines, each containing two space-separated integers, denoting the vertices that are the endpoints of a certain edge. Each edge should be reported exactly once. Your program should then immediately terminate.

Interaction

For each question that you wish to ask, interact as follows.

1. First, print the size of $S$ in its own line. In the following line, print $|S|$ space-separated distinct integers, denoting the vertices in $S$.
2. Similarly, print the size of $T$ in its own line. In the following line, print $|T|$ space-separated distinct integers, denoting the vertices in $T$.
3. Then, in the final line, print $v$ — the vertex that you choose for this question.
4. Read Mikaela's answer from input.

Be reminded that $S$ and $T$ must be disjoint and non-empty.

After printing a query do not forget to output 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 documentation for other languages.

If your program asks too many questions, asks an invalid question or does not correctly follow the interaction guideline above, it may receive an arbitrary verdict. Otherwise, your program will receive the Wrong Answer verdict if it reports an incorrect tree.

Note that the tree is fixed beforehand and does not depend on your queries.

Example

Input

```
5
5
```

Output

```
3
1 2 3
2
4 5
2
ANSWER
1 2
2 3
3 4
2 5
```

Note

In the sample, the tree is as follows.

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

$n = 5$ is given to the program. The program then asks Mikaela a question where $S = \{1, 2, 3\}$, $T = \{4, 5\}$, and $v = 2$, to which she replies with $5$ (the pairs $(s, t)$ are $(1, 4)$, $(1, 5)$, $(2, 4)$, $(2, 5)$, and $(3, 5)$).

#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 isAllDigits(const string& s) {
    if (s.empty()) return false;
    for (char c : s) if (c < '0' || c > '9') return false;
    return true;
}

static bool readIntStrict(long long &x) {
    string tok;
    if (!readToken(tok)) return false;
    if (!isAllDigits(tok)) return false;
    try {
        x = stoll(tok);
    } catch (...) {
        return false;
    }
    return true;
}

static vector<int> readVertexSet(int n, long long sz, const string& what, vector<char>& used, vector<int>* outVec) {
    if (sz < 1 || sz > n) finish(_pe, what + " size out of range");
    vector<int> v;
    v.reserve((size_t)sz);
    for (long long i = 0; i < sz; i++) {
        long long x;
        if (!readIntStrict(x)) finish(_pe, "Failed to read " + what + " element");
        if (x < 1 || x > n) finish(_pe, what + " element out of range");
        if (used[(int)x]) finish(_pe, what + " has duplicate element");
        used[(int)x] = 1;
        v.push_back((int)x);
    }
    if (outVec) *outVec = v;
    return v;
}

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

    int n = inf.readInt(2, 500, "n");
    vector<pair<int,int>> hiddenEdges;
    hiddenEdges.reserve(max(0, n - 1));
    vector<vector<int>> adj(n + 1);
    set<pair<int,int>> hiddenSet;
    for (int i = 0; i < n - 1; i++) {
        int u = inf.readInt(1, n, "u");
        int v = inf.readInt(1, n, "v");
        if (u == v) finish(_fail, "Invalid hidden edge: self-loop");
        hiddenEdges.push_back({u, v});
        adj[u].push_back(v);
        adj[v].push_back(u);
        hiddenSet.insert({min(u, v), max(u, v)});
    }

    query_limit = 11111;
    log_metrics();

    cout << n << endl;

    vector<vector<int>> group(n + 1, vector<int>(n + 1, -1));
    for (int v = 1; v <= n; v++) {
        group[v][v] = 0;
        int id = 1;
        for (int nei : adj[v]) {
            if (group[v][nei] != -1) continue;
            deque<pair<int,int>> dq;
            dq.push_back({nei, v});
            group[v][nei] = id;
            while (!dq.empty()) {
                auto [x, p] = dq.front();
                dq.pop_front();
                for (int y : adj[x]) {
                    if (y == p) continue;
                    if (y == v) continue;
                    if (group[v][y] != -1) continue;
                    group[v][y] = id;
                    dq.push_back({y, x});
                }
            }
            id++;
        }
        for (int x = 1; x <= n; x++) {
            if (group[v][x] == -1) finish(_fail, "Internal error: disconnected tree/group computation failed");
        }
    }

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

    while (true) {
        string first;
        if (!readToken(first)) finish(_pe, "Unexpected EOF from contestant");

        if (first == "ANSWER") {
            set<pair<int,int>> got;
            got.clear();
            for (int i = 0; i < n - 1; i++) {
                long long a, b;
                if (!readIntStrict(a) || !readIntStrict(b)) finish(_pe, "Failed to read reported edge");
                if (a < 1 || a > n || b < 1 || b > n) finish(_pe, "Reported edge endpoint out of range");
                if (a == b) finish(_wa, "Reported self-loop");
                int u = (int)a, v = (int)b;
                got.insert({min(u, v), max(u, v)});
            }
            if ((int)got.size() != n - 1) finish(_wa, "Reported edges are not unique or count is wrong");
            if (got != hiddenSet) finish(_wa, "Reported tree is incorrect");
            finish(_ok, "Correct");
        }

        if (!isAllDigits(first)) finish(_pe, "Expected S size or ANSWER");
        long long szS;
        try { szS = stoll(first); } catch (...) { finish(_pe, "Invalid S size token"); }

        vector<char> usedS(n + 1, 0), usedT(n + 1, 0);
        vector<int> S, T;

        (void)readVertexSet(n, szS, "S", usedS, &S);

        long long szT;
        if (!readIntStrict(szT)) finish(_pe, "Failed to read T size");
        if (szT < 1 || szT > n) finish(_pe, "T size out of range");

        T.reserve((size_t)szT);
        for (long long i = 0; i < szT; i++) {
            long long x;
            if (!readIntStrict(x)) finish(_pe, "Failed to read T element");
            if (x < 1 || x > n) finish(_pe, "T element out of range");
            int xi = (int)x;
            if (usedT[xi]) finish(_pe, "T has duplicate element");
            if (usedS[xi]) finish(_pe, "S and T are not disjoint");
            usedT[xi] = 1;
            T.push_back(xi);
        }

        long long vv;
        if (!readIntStrict(vv)) finish(_pe, "Failed to read v");
        if (vv < 1 || vv > n) finish(_pe, "v out of range");
        int v = (int)vv;

        queries++;
        if (queries > hard_cap) finish(_pe, "Hard cap exceeded (likely infinite loop/output spam)");

        vector<int> cntS(n + 1, 0), cntT(n + 1, 0);
        for (int x : S) cntS[group[v][x]]++;
        for (int x : T) cntT[group[v][x]]++;

        long long total = (long long)S.size() * (long long)T.size();
        long long same = 0;
        for (int g = 0; g <= n; g++) same += 1LL * cntS[g] * cntT[g];
        long long ans = total - same;
        if (ans < 0) ans = 0;

        cout << ans << endl;
    }
}

#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) {
    return (cin >> tok) ? true : false;
}

static bool parseNonNegLL(const string& s, long long& out) {
    if (s.empty()) return false;
    if (s.size() > 1 && s[0] == '0') {
        for (char c : s) if (!isdigit((unsigned char)c)) return false;
    } else {
        for (char c : s) if (!isdigit((unsigned char)c)) return false;
    }
    __int128 val = 0;
    for (char c : s) {
        val = val * 10 + (c - '0');
        if (val > (__int128)LLONG_MAX) return false;
    }
    out = (long long)val;
    return true;
}

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

static vector<uint64_t> makeBits(int n) {
    return vector<uint64_t>((n + 63) / 64, 0ULL);
}
static inline void setBit(vector<uint64_t>& b, int x) {
    int idx = (x - 1) >> 6;
    int off = (x - 1) & 63;
    b[idx] |= (1ULL << off);
}
static inline bool testBit(const vector<uint64_t>& b, int x) {
    int idx = (x - 1) >> 6;
    int off = (x - 1) & 63;
    return (b[idx] >> off) & 1ULL;
}
static inline int popcountAnd(const vector<uint64_t>& a, const vector<uint64_t>& b) {
    int res = 0;
    for (size_t i = 0; i < a.size(); i++) res += __builtin_popcountll(a[i] & b[i]);
    return res;
}

struct ParsedTree {
    int n = 0;
    vector<pair<int,int>> edges;
    vector<vector<int>> adj;
    vector<vector<char>> hasEdge;
};

static ParsedTree readContestantTree(int n) {
    ParsedTree pt;
    pt.n = n;
    pt.adj.assign(n + 1, {});
    pt.hasEdge.assign(n + 1, vector<char>(n + 1, 0));
    pt.edges.clear();
    pt.edges.reserve(max(0, n - 1));

    for (int i = 0; i < n - 1; i++) {
        long long uLL = readIntStrict("edge_u", 1, n, _pe);
        long long vLL = readIntStrict("edge_v", 1, n, _pe);
        int u = (int)uLL, v = (int)vLL;
        if (u == v) finish(_wa, "self-loop in answer");
        int a = min(u, v), b = max(u, v);
        if (pt.hasEdge[a][b]) finish(_wa, "duplicate edge in answer");
        pt.hasEdge[a][b] = pt.hasEdge[b][a] = 1;
        pt.adj[u].push_back(v);
        pt.adj[v].push_back(u);
        pt.edges.push_back({a, b});
    }

    vector<int> q;
    q.reserve(n);
    vector<char> vis(n + 1, 0);
    q.push_back(1);
    vis[1] = 1;
    for (int qi = 0; qi < (int)q.size(); qi++) {
        int x = q[qi];
        for (int y : pt.adj[x]) if (!vis[y]) {
            vis[y] = 1;
            q.push_back(y);
        }
    }
    for (int i = 1; i <= n; i++) {
        if (!vis[i]) finish(_wa, "answer graph is not connected");
    }
    return pt;
}

static bool isStarCenteredAt(const ParsedTree& pt, int center) {
    int n = pt.n;
    if ((int)pt.edges.size() != n - 1) return false;
    if ((int)pt.adj[center].size() != n - 1) return false;
    for (int v = 1; v <= n; v++) {
        if (v == center) continue;
        if ((int)pt.adj[v].size() != 1) return false;
        if (pt.adj[v][0] != center) return false;
    }
    return true;
}

struct FixedAnswerEngine {
    int n = 0;
    vector<vector<int>> adj;

    vector<vector<int>> neigh;
    vector<vector<vector<uint64_t>>> compBits;

    explicit FixedAnswerEngine(int n_, const vector<pair<int,int>>& edges) {
        n = n_;
        adj.assign(n + 1, {});
        for (auto [u, v] : edges) {
            adj[u].push_back(v);
            adj[v].push_back(u);
        }
        neigh.assign(n + 1, {});
        compBits.assign(n + 1, {});
        for (int v = 1; v <= n; v++) {
            neigh[v] = adj[v];
            compBits[v].resize(neigh[v].size());
            for (size_t i = 0; i < neigh[v].size(); i++) {
                int start = neigh[v][i];
                vector<char> vis(n + 1, 0);
                vis[v] = 1;
                vector<int> st;
                st.push_back(start);
                vis[start] = 1;
                vector<uint64_t> bits = makeBits(n);
                while (!st.empty()) {
                    int x = st.back();
                    st.pop_back();
                    setBit(bits, x);
                    for (int y : adj[x]) {
                        if (!vis[y]) {
                            vis[y] = 1;
                            st.push_back(y);
                        }
                    }
                }
                compBits[v][i] = std::move(bits);
            }
        }
    }

    long long answerQuery(const vector<uint64_t>& Sbits, const vector<uint64_t>& Tbits, int Ssz, int Tsz, int v) const {
        bool inS = testBit(Sbits, v);
        bool inT = testBit(Tbits, v);

        int totalS = Ssz - (inS ? 1 : 0);
        int totalT = Tsz - (inT ? 1 : 0);

        long long res = 0;
        if (inS) res += totalT;
        if (inT) res += totalS;

        if (totalS > 0 && totalT > 0) {
            long long sumSame = 0;
            for (size_t i = 0; i < neigh[v].size(); i++) {
                int sc = popcountAnd(Sbits, compBits[v][i]);
                int tc = popcountAnd(Tbits, compBits[v][i]);
                sumSame += 1LL * sc * tc;
            }
            res += 1LL * totalS * totalT - sumSame;
        }
        return res;
    }
};

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

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

    bool hasEdges = !inf.seekEof();
    vector<pair<int,int>> hiddenEdges;
    hiddenEdges.reserve(max(0, n - 1));
    if (hasEdges) {
        for (int i = 0; i < n - 1; i++) {
            int u = inf.readInt(1, n, "u");
            int v = inf.readInt(1, n, "v");
            if (u == v) finish(_fail, "invalid hidden edge (self-loop)");
            hiddenEdges.push_back({u, v});
        }
    }

    query_limit = 11111;
    log_metrics();

    cout << n << endl;

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

    unique_ptr<FixedAnswerEngine> fixed;
    vector<pair<int,int>> hiddenNorm;
    vector<vector<char>> hiddenHas;
    if (hasEdges) {
        fixed.reset(new FixedAnswerEngine(n, hiddenEdges));
        hiddenHas.assign(n + 1, vector<char>(n + 1, 0));
        hiddenNorm.reserve(n - 1);
        for (auto [u, v] : hiddenEdges) {
            int a = min(u, v), b = max(u, v);
            hiddenHas[a][b] = hiddenHas[b][a] = 1;
            hiddenNorm.push_back({a, b});
        }
        sort(hiddenNorm.begin(), hiddenNorm.end());
    }

    vector<char> possibleCenter(n + 1, 1);
    int possibleCnt = n;

    auto maybePeriodicLog = [&]() {
        if ((queries & 511LL) == 0) log_metrics();
    };

    while (true) {
        string tok;
        if (!readToken(tok)) finish(_pe, "unexpected EOF (contestant terminated without ANSWER)");

        if (tok == "ANSWER") {
            ParsedTree pt = readContestantTree(n);

            if (hasEdges) {

                vector<pair<int,int>> got = pt.edges;
                sort(got.begin(), got.end());
                if (got != hiddenNorm) finish(_wa, "wrong tree reported");
                finish(_ok, "correct");
            } else {

                for (int c = 1; c <= n; c++) if (possibleCenter[c]) {
                    if (!isStarCenteredAt(pt, c)) finish(_wa, "answer not correct for all feasible instances");
                }
                finish(_ok, "correct");
            }
        }

        long long kS;
        if (!parseNonNegLL(tok, kS)) finish(_pe, "invalid first token (expected integer |S| or ANSWER)");
        if (kS < 1 || kS > n) finish(_pe, "|S| out of range");

        int Ssz = (int)kS;
        vector<uint64_t> Sbits = makeBits(n);
        vector<uint64_t> Tbits = makeBits(n);
        vector<char> used(n + 1, 0);

        for (int i = 0; i < Ssz; i++) {
            int x = (int)readIntStrict("S[i]", 1, n, _pe);
            if (used[x]) finish(_pe, "duplicate vertex in S");
            used[x] = 1;
            setBit(Sbits, x);
        }

        int Tsz = (int)readIntStrict("|T|", 1, n, _pe);
        for (int i = 0; i < Tsz; i++) {
            int x = (int)readIntStrict("T[i]", 1, n, _pe);
            if (used[x]) finish(_pe, "S and T must be disjoint and have distinct elements");
            used[x] = 1;
            setBit(Tbits, x);
        }

        int v = (int)readIntStrict("v", 1, n, _pe);

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

        long long reply = 0;
        if (hasEdges) {
            reply = fixed->answerQuery(Sbits, Tbits, Ssz, Tsz, v);
        } else {
            long long A_all = 1LL * Ssz * Tsz;
            bool inS = testBit(Sbits, v);
            bool inT = testBit(Tbits, v);
            long long A_non = (inS ? Tsz : 0) + (inT ? Ssz : 0);

            if (A_all == A_non) {
                reply = A_all;

            } else {
                bool vPossible = possibleCenter[v];
                bool hasOther = (possibleCnt - (vPossible ? 1 : 0)) > 0;

                if (vPossible && !hasOther) {
                    reply = A_all;

                    for (int c = 1; c <= n; c++) possibleCenter[c] = (c == v);
                    possibleCnt = 1;
                } else {
                    reply = A_non;

                    if (vPossible) {
                        possibleCenter[v] = 0;
                        possibleCnt--;
                        if (possibleCnt <= 0) finish(_fail, "internal: feasible set became empty");
                    }
                }
            }
        }

        cout << reply << endl;
    }
}

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

static vector<pair<int,int>> build_path(int n) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 1; i + 1 <= n; i++) e.push_back({i, i + 1});
    return e;
}

static vector<pair<int,int>> build_star(int n, int center = 1) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 1; i <= n; i++) if (i != center) e.push_back({center, i});
    return e;
}

static vector<pair<int,int>> build_kary_heap(int n, int k) {
    k = max(1, k);
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 2; i <= n; i++) {
        int parent = (i - 2) / k + 1;
        e.push_back({parent, i});
    }
    return e;
}

static vector<pair<int,int>> build_double_star(int n) {
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    e.push_back({1, 2});
    for (int i = 3; i <= n; i++) e.push_back({(i & 1) ? 1 : 2, i});
    return e;
}

static vector<pair<int,int>> build_broom(int n, int handle_len) {
    handle_len = max(2, min(handle_len, n));
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 1; i + 1 <= handle_len; i++) e.push_back({i, i + 1});
    for (int i = handle_len + 1; i <= n; i++) e.push_back({handle_len, i});
    return e;
}

static vector<pair<int,int>> build_caterpillar(int n, int spine_len) {
    spine_len = max(2, min(spine_len, n));
    vector<pair<int,int>> e;
    e.reserve(max(0, n - 1));
    for (int i = 1; i + 1 <= spine_len; i++) e.push_back({i, i + 1});

    int next_node = spine_len + 1;
    if (next_node > n) return e;

    if (spine_len == 2) {
        for (int v = next_node; v <= n; v++) e.push_back({(v & 1) ? 1 : 2, v});
        return e;
    }

    int attach_from = 2, attach_to = spine_len - 1;
    int idx = 0;
    for (int v = next_node; v <= n; v++) {
        int spine = attach_from + (idx % (attach_to - attach_from + 1));
        e.push_back({spine, v});
        idx++;
    }
    return e;
}

static vector<pair<int,int>> build_prufer_random(int n) {
    if (n == 2) return {{1, 2}};
    vector<int> prufer(n - 2);
    for (int i = 0; i < n - 2; i++) prufer[i] = rnd.next(1, n);

    vector<int> deg(n + 1, 1);
    for (int x : prufer) deg[x]++;

    set<int> leaves;
    for (int i = 1; i <= n; i++) if (deg[i] == 1) leaves.insert(i);

    vector<pair<int,int>> e;
    e.reserve(n - 1);
    for (int x : prufer) {
        int leaf = *leaves.begin();
        leaves.erase(leaves.begin());
        e.push_back({leaf, x});
        deg[leaf]--;
        deg[x]--;
        if (deg[x] == 1) leaves.insert(x);
    }

    int a = *leaves.begin();
    leaves.erase(leaves.begin());
    int b = *leaves.begin();
    e.push_back({a, b});
    return e;
}

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

static void apply_permutation(vector<pair<int,int>>& edges, int n) {
    vector<int> p(n + 1);
    for (int i = 1; i <= n; i++) p[i] = i;
    for (int i = n; i >= 2; i--) {
        int j = rnd.next(1, i);
        swap(p[i], p[j]);
    }
    for (auto &ed : edges) {
        ed.first = p[ed.first];
        ed.second = p[ed.second];
        if (ed.first == ed.second) ed.second = (ed.second % n) + 1;
    }
}

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

    string mode = opt<string>("mode", "non");
    int nOpt = opt<int>("n", 500);
    int typeOpt = opt<int>("type", -1);
    int kOpt = opt<int>("k", 3);
    int permOpt = opt<int>("perm", 1);

    long long seedValue = 0;
    if (argc >= 2) seedValue = atoll(argv[1]);

    int n = max(2, min(500, nOpt));

    if (mode == "adp") {
        if (seedValue == 1) n = 2;
        else if (seedValue == 2) n = 500;
        else if (seedValue == 3) n = 499;
        else n = max(2, min(500, n));
        cout << n << "\n";
        return 0;
    }

    if (mode != "non") quitf(_fail, "Unknown --mode: %s", mode.c_str());

    vector<pair<int,int>> edges;

    if (seedValue == 1) {
        n = 2;
        edges = {{1, 2}};
    } else if (seedValue == 2) {
        n = 500;
        edges = build_path(n);
    } else if (seedValue == 3) {
        n = 500;
        edges = build_kary_heap(n, 2);
    } else {
        int type = (typeOpt != -1 ? typeOpt : (int)(seedValue % 8));
        type = ((type % 8) + 8) % 8;

        if (type == 0) edges = build_kary_heap(n, 2);
        else if (type == 1) edges = build_prufer_random(n);
        else if (type == 2) edges = build_broom(n, max(2, (3 * n) / 4));
        else if (type == 3) edges = build_double_star(n);
        else if (type == 4) edges = build_caterpillar(n, max(3, n / 5));
        else if (type == 5) edges = build_kary_heap(n, max(2, min(8, kOpt)));
        else if (type == 6) edges = build_path(n);
        else edges = build_star(n, 1);

        if (permOpt) apply_permutation(edges, n);
        shuffle_edges(edges);
    }

    if ((int)edges.size() != n - 1) quitf(_fail, "Generated edges != n-1");

    cout << n << "\n";
    for (auto &e : edges) {
        int u = e.first, v = e.second;
        if (u < 1 || u > n || v < 1 || v > n || u == v) quitf(_fail, "Invalid edge");
        cout << u << " " << v << "\n";
    }
    return 0;
}


The only difference between the versions of this problem is the maximum value of $n$.

Professor Vector is preparing to teach her Arithmancy class. She needs to prepare $n$ distinct magic words for the class. Each magic word is a string consisting of characters X and O. A spell is a string created by concatenating two magic words together. The power of a spell is equal to the number of its different non-empty substrings. For example, the power of the spell XOXO is equal to 7, because it has 7 different substrings: X, O, XO, OX, XOX, OXO and XOXO.

Each student will create their own spell by concatenating two magic words. Since the students are not very good at magic yet, they will choose each of the two words independently and uniformly at random from the $n$ words provided by Professor Vector. It is therefore also possible that the two words a student chooses are the same. Each student will then compute the power of their spell, and tell it to Professor Vector. In order to check their work, and of course to impress the students, Professor Vector needs to find out which two magic words and in which order were concatenated by each student.

Your program needs to perform the role of Professor Vector: first, create $n$ distinct magic words, and then handle multiple requests where it is given the spell power and needs to determine the indices of the two magic words, in the correct order, that were used to create the corresponding spell.

Interaction

This is an interactive problem.

First, your program should read a single integer $n$ ($1 \le n \le 1000$), the number of magic words to prepare. Then, it should print $n$ magic words it has created, one per line. The magic words must be distinct, each magic word must have at least 1 and at most $30\cdot n$ characters, and each character must be either X or O. We will denote the $i$-th magic word you printed as $w_i$ ($1 \le i \le n$).

Then, your program should read a single integer $q$ ($1 \le q \le 1000$), the number of students in the class. Then, it should repeat the following process $q$ times, one per student.

For the $j$-th student, it should first read a single integer $p_j$, the power of their spell. It is guaranteed that this number is computed by choosing two indices $u_j$ and $v_j$ independently and uniformly at random between 1 and $n$ inclusive, concatenating $w_{u_j}$ and $w_{v_j}$, and finding the number of different non-empty substrings of the resulting string. Then, your program must print the numbers $u_j$ and $v_j$, in this order ($1 \le u_j, v_j \le n$).

Note that it is not enough to find any two magic words that concatenate into a spell with the given power. You must find the exact words used by the student in the exact order.

Remember to flush the output stream after printing all magic words and after printing $u_j$ and $v_j$ for each student.

Example

Input

```
2

2
15

11
```

Output

```
XOXO
X

1 1

2 1
```

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

using namespace std;

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

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

    }
}

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

struct SuffixAutomaton {
    struct State {
        int len, link;
        int next[2];
    };

    vector<State> st;
    int sz;
    int last;

    void init() {
        st.clear();

        st.reserve(150000);
        reset();
    }

    void reset() {

        st.clear();

        st.push_back({0, -1, {-1, -1}});
        sz = 1;
        last = 0;
    }

    void extend(char c) {
        int cur = sz++;
        st.emplace_back();

        st[cur].len = st[last].len + 1;
        st[cur].next[0] = st[cur].next[1] = -1;
        st[cur].link = -1;

        int p = last;
        int code = (c == 'X' ? 1 : 0);

        while (p != -1 && st[p].next[code] == -1) {
            st[p].next[code] = cur;
            p = st[p].link;
        }
        if (p == -1) {
            st[cur].link = 0;
        } else {
            int q = st[p].next[code];
            if (st[p].len + 1 == st[q].len) {
                st[cur].link = q;
            } else {
                int clone = sz++;
                st.emplace_back();
                st[clone].len = st[p].len + 1;
                st[clone].next[0] = st[q].next[0];
                st[clone].next[1] = st[q].next[1];
                st[clone].link = st[q].link;

                while (p != -1 && st[p].next[code] == q) {
                    st[p].next[code] = clone;
                    p = st[p].link;
                }
                st[q].link = st[cur].link = clone;
            }
        }
        last = cur;
    }

    long long count_distinct() {
        long long ans = 0;

        for (int i = 1; i < sz; i++) {
            ans += (long long)(st[i].len - st[st[i].link].len);
        }
        return ans;
    }
};

SuffixAutomaton sa;

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

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

    int n_in = inf.readInt(1, 1000, "n");
    int n = min(n_in, 30);
    int q_val = inf.readInt(1, 1000, "q");

    query_limit = q_val;
    log_metrics();

    cout << n << endl;

    vector<string> w(n + 1);
    set<string> seen;

    for (int i = 1; i <= n; ++i) {
        if (!(cin >> w[i])) {
            finish(_pe, "Solution terminated before providing all magic words");
        }

        long long max_len = 30LL * n;
        if (w[i].length() < 1) {
            finish(_wa, format("Magic word %d is empty", i));
        }
        if (w[i].length() > max_len) {
            finish(_wa, format("Magic word %d too long: %d > %d", i, (int)w[i].length(), (int)max_len));
        }
        for (char c : w[i]) {
            if (c != 'X' && c != 'O') {
                finish(_wa, format("Magic word %d contains invalid char '%c'", i, c));
            }
        }
        if (seen.count(w[i])) {
            finish(_wa, format("Magic word %d is not distinct", i));
        }
        seen.insert(w[i]);
    }

    cout << q_val << endl;

    sa.init();

    for (int k = 0; k < q_val; ++k) {

        int u_in = inf.readInt(1, n_in, "u");
        int v_in = inf.readInt(1, n_in, "v");
        int u = (u_in - 1) % n + 1;
        int v = (v_in - 1) % n + 1;

        string spell = w[u] + w[v];

        sa.reset();
        for (char c : spell) {
            sa.extend(c);
        }
        long long power = sa.count_distinct();

        cout << power << endl;

        string token;
        if (!(cin >> token)) {
            finish(_pe, "Solution terminated early (expected u)");
        }

        int u_ans, v_ans;

        if (token == "!" || token == "?") {
            if (!(cin >> token)) finish(_pe, "Solution terminated early after prefix");
        }

        try {
            size_t idx;
            u_ans = stoi(token, &idx);
            if (idx != token.size()) finish(_wa, "Invalid integer format for u: " + token);
        } catch (...) {
            finish(_wa, "Invalid integer format for u: " + token);
        }

        if (!(cin >> token)) {
             finish(_pe, "Solution terminated early (expected v)");
        }
        try {
            size_t idx;
            v_ans = stoi(token, &idx);
             if (idx != token.size()) finish(_wa, "Invalid integer format for v: " + token);
        } catch (...) {
            finish(_wa, "Invalid integer format for v: " + token);
        }

        queries++;

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

        if (u_ans != u || v_ans != v) {
            finish(_wa, format("Wrong answer on query %d. Expected %d %d, got %d %d", k+1, u, v, u_ans, v_ans));
        }
    }

    finish(_ok, format("Passed %d queries", q_val));
    return 0;
}

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

using namespace std;

static int queries_count = 0;
static int query_limit_val = 0;

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

    }
}

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

struct SAM {
    static const int MAXLEN = 60005;
    int len[MAXLEN * 2];
    int link[MAXLEN * 2];
    int next_state[MAXLEN * 2][2];
    int sz, last;

    void init() {
        len[0] = 0;
        link[0] = -1;
        next_state[0][0] = next_state[0][1] = -1;
        sz = 1;
        last = 0;
    }

    void extend(char c) {
        int val = (c == 'X' ? 1 : 0);
        int cur = sz++;
        len[cur] = len[last] + 1;
        next_state[cur][0] = next_state[cur][1] = -1;
        int p = last;
        while (p != -1 && next_state[p][val] == -1) {
            next_state[p][val] = cur;
            p = link[p];
        }
        if (p == -1) {
            link[cur] = 0;
        } else {
            int q = next_state[p][val];
            if (len[p] + 1 == len[q]) {
                link[cur] = q;
            } else {
                int clone = sz++;
                len[clone] = len[p] + 1;
                next_state[clone][0] = next_state[q][0];
                next_state[clone][1] = next_state[q][1];
                link[clone] = link[q];
                while (p != -1 && next_state[p][val] == q) {
                    next_state[p][val] = clone;
                    p = link[p];
                }
                link[q] = link[cur] = clone;
            }
        }
        last = cur;
    }

    long long count_distinct() {
        long long ans = 0;
        for (int i = 1; i < sz; i++) {
            ans += (long long)(len[i] - len[link[i]]);
        }
        return ans;
    }
} sam;

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

    int n_in = inf.readInt(1, 1000, "n");
    int n = min(n_in, 30);

    cout << n << endl;

    vector<string> w(n);
    vector<string*> ptrs(n);
    for (int i = 0; i < n; i++) {

        if (!(cin >> w[i])) {
            finish(_pe, "Unexpected EOF reading magic words");
        }

        if (w[i].length() < 1 || w[i].length() > 30ULL * n) {
            finish(_pe, format("Word %d length %d is out of bounds [1, %d]", i + 1, (int)w[i].length(), 30 * n));
        }

        for (char c : w[i]) {
            if (c != 'X' && c != 'O') {
                finish(_pe, "Magic words must only contain 'X' and 'O'");
            }
        }
        ptrs[i] = &w[i];
    }

    sort(ptrs.begin(), ptrs.end(), [](string* a, string* b) {
        return *a < *b;
    });
    for (int i = 0; i < n - 1; i++) {
        if (*ptrs[i] == *ptrs[i + 1]) {
            finish(_pe, "Magic words must be distinct");
        }
    }

    int q = inf.readInt(1, 1000, "q");
    query_limit_val = q;
    log_metrics();

    vector<pair<int, int>> predefined;
    inf.skipBlanks();
    while (!inf.eof()) {
        int u = inf.readInt(1, n_in, "u");
        int v = inf.readInt(1, n_in, "v");
        predefined.push_back({u, v});
        inf.skipBlanks();
    }

    cout << q << endl;

    rnd.setSeed(n * 239017LL + q * 1023LL + 12345LL);

    for (int j = 0; j < q; j++) {
        int u_in, v_in;
        if (j < (int)predefined.size()) {
            u_in = predefined[j].first;
            v_in = predefined[j].second;
        } else {

            u_in = rnd.next(1, n);
            v_in = rnd.next(1, n);
        }

        int u = (u_in - 1) % n + 1;
        int v = (v_in - 1) % n + 1;

        string s = w[u - 1] + w[v - 1];
        sam.init();
        for (char c : s) sam.extend(c);
        long long power = sam.count_distinct();

        cout << power << endl;

        int user_u, user_v;
        if (!(cin >> user_u >> user_v)) {
            finish(_pe, "Unexpected EOF reading answer");
        }

        queries_count++;

        if (queries_count % 50 == 0) log_metrics();

        if (user_u != u || user_v != v) {
            finish(_wa, format("Wrong answer on query %d. Expected: %d %d, Found: %d %d", j + 1, u, v, user_u, user_v));
        }
    }

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

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

using namespace std;

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

    registerGen(argc, argv, 1);

    string mode = opt<string>("mode", "non");
    int n_in = opt<int>("n", -1);
    int q_in = opt<int>("q", -1);

    const int N_MAX = 30;

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

    int n, q;

    if (n_in != -1) {
        n = max(1, min(n_in, N_MAX));
    } else {

        if (seed_val == 1) n = 1;
        else if (seed_val == 2) n = N_MAX;
        else if (seed_val == 3) n = N_MAX;
        else if (seed_val == 4) n = N_MAX;
        else {

            if (rnd.next(100) < 80)
                n = rnd.wnext(1, N_MAX, 20);
            else
                n = rnd.next(1, N_MAX);
        }
    }

    if (q_in != -1) {
        q = max(1, q_in);
    } else {
        if (seed_val == 1) q = 1;
        else if (seed_val == 2) q = 1000;
        else {

            q = rnd.next(1, 1000);
        }
    }

    cout << n << endl;
    cout << q << endl;

    if (mode == "non") {
        for (int i = 0; i < q; ++i) {
            int u = rnd.next(1, n);
            int v = rnd.next(1, n);
            cout << u << " " << v << "\n";
        }
    }

    return 0;
}