This is an interactive problem.

This is the easy version of the problem. The only difference is that $n \le 845$ in this version.

There is a hidden permutation $p$, which is a permutation of $\{1,2,\ldots,n\}$. Let $pos_i$ denote the position of the value $i$ in $p$, i.e., $pos_{p_i} = i$.

To find this permutation, you can ask four types of queries:

* "$1\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ \ldots,\ i_m$ must be distinct). Let $k = \min(60, m)$. The jury will return the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, \ldots, p_{i_m}]$ in increasing order.
* "$2\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ \ldots,\ i_m$ must be distinct). Let $k = \min(60, m)$. The jury will return the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.
* "$3\ m\ i_1\ i_2\ ...\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ ...,\ i_m$ must be distinct). Let $k = \min(300, m)$. The jury will return the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, ..., p_{i_m}]$ in increasing order.
* "$4\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1,\ i_2,\ \ldots,\ i_m$ must be distinct). Let $k = \min(300, m)$. The jury will return the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.

Let $c_i$ be the usage count of queries of type $i$ $(1 \le i \le 4)$. Your query count must satisfy the following constraints:

* $c_1+c_2+c_3+c_4 \le 30.$
* $c_3+c_4 \le 1.$

Input

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

Interaction

The first line of each test case contains one integer $n$ ($2 \le n \le 845$). At this moment, the permutation $p$ is chosen. The interactor in this task is not adaptive. In other words, the permutation $p$ is fixed in every test case and does not change during the interaction.

To ask a query of type $1$, you need to print the line of the following form (without quotes):

* "$1\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(60,m)$ integer(s) — the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, \ldots, p_{i_m}]$ in increasing order.

To ask a query of type $2$, you need to print the line of the following form (without quotes):

* "$2\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(60,m)$ integer(s) — the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.

To ask a query of type $3$, you need to print the line of the following form (without quotes):

* "$3\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(300,m)$ integer(s) — the top $k$ largest number(s) in $[p_{i_1}, p_{i_2}, \ldots, p_{i_m}]$ in increasing order.

To ask a query of type $4$, you need to print the line of the following form (without quotes):

* "$4\ m\ i_1\ i_2\ \ldots\ i_m$" ($1 \leq m \leq n$, $i_1, i_2, \ldots, i_m$ must be distinct)

After that, you receive $k=\min(300,m)$ integer(s) — the top $k$ largest number(s) in $[pos_{i_1}, pos_{i_2}, \ldots, pos_{i_m}]$ in increasing order.

Next, if your program has found the permutation $p$, print the line of the following form (without quotes):

* "$!\ p_1\ p_2\ \ldots\ p_n$"

Note that this line is not considered a query and is not taken into account when counting the number of queries asked.

After this, proceed to the next test case.

After printing a query or the answer for a test case, do not forget to output the end of the line and flush the output. Otherwise, you will get the verdict Idleness Limit Exceeded. To do this, use:

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

Example

Input

```
2
3

2 3

3

2

2
```

Output

```
3 2 3 1

2 1 2

! 3 1 2

4 1 1

! 2 1
```

Note

In the first test case, the hidden permutation is $p = [3, 1, 2]$, thus $pos = [2, 3, 1]$.

For the query "3 2 3 1", the jury returns $2$ and $3$ because $2$ and $3$ are the top $k$ largest number(s) in $[p_3, p_1]$, where $k = \min(300, m) = \min(300, 2) = 2$.

For the query "2 1 2", the jury returns $3$ because $3$ is the top $k$ largest number in $[pos_2]$, where $k = \min(60, m) = \min(60, 1) = 1$.

Note that the example is only for understanding the statement and does not guarantee finding the unique permutation $p$.

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

static bool readLL(long long &x) {
    if (!(cin >> x)) return false;
    return true;
}

static vector<int> topKIncreasing(const vector<int>& vals, int k) {
    vector<int> v = vals;
    sort(v.begin(), v.end());
    int m = (int)v.size();
    vector<int> ans;
    ans.reserve(k);
    for (int i = m - k; i < m; i++) ans.push_back(v[i]);
    sort(ans.begin(), ans.end());
    return ans;
}

static void writeReply(const vector<int>& ans) {
    for (int i = 0; i < (int)ans.size(); i++) {
        if (i) cout << ' ';
        cout << ans[i];
    }
    cout << "\n";
    cout.flush();
}

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

    int t = 0;
    try {
        t = inf.readInt();
    } catch (...) {
        finish(_pe, "failed to read t from inf");
    }
    if (t < 1 || t > 1000000) finish(_pe, "invalid t in inf");

    query_limit = 30LL * t;
    log_metrics();

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

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

    for (int tc = 1; tc <= t; tc++) {
        int n = 0;
        try {
            n = inf.readInt();
        } catch (...) {
            finish(_pe, "failed to read n from inf");
        }
        if (n < 2 || n > 2000000) finish(_pe, "invalid n in inf");

        vector<int> p(n + 1, 0);
        vector<int> pos(n + 1, 0);
        vector<int> seen(n + 1, 0);

        for (int i = 1; i <= n; i++) {
            int x = 0;
            try {
                x = inf.readInt();
            } catch (...) {
                finish(_pe, "failed to read permutation from inf");
            }
            if (x < 1 || x > n) finish(_pe, "permutation value out of range in inf");
            if (seen[x]) finish(_pe, "duplicate permutation value in inf");
            seen[x] = 1;
            p[i] = x;
        }
        for (int i = 1; i <= n; i++) pos[p[i]] = i;

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

        bool answered = false;
        while (!answered) {
            string tok;
            if (!(cin >> tok)) finish(_pe, "unexpected EOF from contestant");

            if (tok == "!") {
                vector<int> ans(n + 1, 0);
                vector<int> used(n + 1, 0);
                for (int i = 1; i <= n; i++) {
                    long long xll = 0;
                    if (!readLL(xll)) finish(_pe, "EOF while reading final answer");
                    if (xll < 1 || xll > n) finish(_wa, "final answer value out of range");
                    int x = (int)xll;
                    if (used[x]) finish(_wa, "final answer is not a permutation");
                    used[x] = 1;
                    ans[i] = x;
                }
                for (int i = 1; i <= n; i++) {
                    if (ans[i] != p[i]) finish(_wa, "wrong permutation");
                }
                answered = true;
                continue;
            }

            if (tok.size() != 1 || tok[0] < '1' || tok[0] > '4') {
                finish(_pe, "invalid command token");
            }
            int type = tok[0] - '0';

            long long mll = 0;
            if (!readLL(mll)) finish(_pe, "EOF while reading m");
            if (mll < 1 || mll > n) finish(_pe, "m out of range");
            int m = (int)mll;

            vector<int> idx;
            idx.reserve(m);
            vector<char> used(n + 1, 0);
            for (int j = 0; j < m; j++) {
                long long ill = 0;
                if (!readLL(ill)) finish(_pe, "EOF while reading indices");
                if (ill < 1 || ill > n) finish(_pe, "index out of range");
                int ii = (int)ill;
                if (used[ii]) finish(_pe, "duplicate index in query");
                used[ii] = 1;
                idx.push_back(ii);
            }

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

            int lim = (type == 1 || type == 2) ? 60 : 300;
            int k = min(lim, m);

            vector<int> vals;
            vals.reserve(m);
            if (type == 1 || type == 3) {
                for (int x : idx) vals.push_back(p[x]);
            } else {
                for (int x : idx) vals.push_back(pos[x]);
            }

            vector<int> reply = topKIncreasing(vals, k);
            writeReply(reply);
        }
    }

    finish(_ok, "all testcases solved");
    return 0;
}

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

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

static vector<int> makeBlockScramble(int n, int B) {
    vector<vector<int>> blocks;
    for (int s = 1; s <= n; s += B) {
        int e = min(n, s + B - 1);
        vector<int> block;
        block.reserve(e - s + 1);
        for (int x = s; x <= e; x++) block.push_back(x);
        reverse(block.begin(), block.end());
        blocks.push_back(std::move(block));
    }
    reverse(blocks.begin(), blocks.end());
    vector<int> p;
    p.reserve(n);
    for (auto &b : blocks) for (int x : b) p.push_back(x);
    return p;
}

static vector<int> makeBitReversal(int n) {
    int bits = 0;
    while ((1 << bits) < n) bits++;
    vector<pair<int,int>> v;
    v.reserve(n);
    for (int i = 0; i < n; i++) {
        int x = i, r = 0;
        for (int b = 0; b < bits; b++) {
            r = (r << 1) | (x & 1);
            x >>= 1;
        }
        v.push_back({r, i});
    }
    sort(v.begin(), v.end());
    vector<int> p(n);
    for (int pos = 0; pos < n; pos++) p[pos] = v[pos].second + 1;
    return p;
}

static vector<int> makeModMul(int n) {
    int a;
    while (true) {
        a = rnd.next(1, n - 1);
        if (std::gcd(a, n) == 1) break;
    }
    int b = rnd.next(0, n - 1);
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        long long val = (1LL * a * i + b) % n;
        p[i] = (int)val + 1;
    }
    return p;
}

static vector<int> makeDominators(int n, int D) {
    D = min(D, n);
    vector<int> p(n, 0);

    vector<int> pos = rnd.perm(n);
    vector<int> domPos(pos.begin(), pos.begin() + D);

    vector<int> domVals;
    domVals.reserve(D);
    for (int x = n - D + 1; x <= n; x++) domVals.push_back(x);

    vector<int> ord = rnd.perm(D);
    vector<int> domValsShuf;
    domValsShuf.reserve(D);
    for (int i = 0; i < D; i++) domValsShuf.push_back(domVals[ord[i]]);

    for (int i = 0; i < D; i++) {
        p[domPos[i]] = domValsShuf[i];
    }

    vector<int> restVals;
    restVals.reserve(n - D);
    for (int x = 1; x <= n - D; x++) restVals.push_back(x);

    vector<int> remIdx;
    remIdx.reserve(n - D);
    for (int i = 0; i < n; i++) if (p[i] == 0) remIdx.push_back(i);

    int m = (int)remIdx.size();
    int bits = 0;
    while ((1 << bits) < m) bits++;
    vector<pair<int,int>> br;
    br.reserve(m);
    for (int i = 0; i < m; i++) {
        int x = i, r = 0;
        for (int b = 0; b < bits; b++) {
            r = (r << 1) | (x & 1);
            x >>= 1;
        }
        br.push_back({r, i});
    }
    sort(br.begin(), br.end());
    for (int k = 0; k < m; k++) {
        int idx = remIdx[br[k].second];
        p[idx] = restVals[k];
    }

    return p;
}

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

static bool isPerm1toN(const vector<int> &p) {
    int n = (int)p.size();
    vector<int> seen(n + 1, 0);
    for (int x : p) {
        if (x < 1 || x > n) return false;
        if (seen[x]) return false;
        seen[x] = 1;
    }
    return true;
}

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

    string mode = opt<string>("mode", "non");
    int maxn = opt<int>("maxn", 845);
    int nOpt = opt<int>("n", 0);

    long long seedVal = 0;
    if (argc >= 2) {
        seedVal = atoll(argv[1]);
        if (seedVal < 0) seedVal = -seedVal;
    }

    int n;
    if (nOpt >= 2) n = min(nOpt, maxn);
    else {
        if (seedVal >= 1 && seedVal <= 3) n = maxn;
        else n = rnd.next(800, maxn);
    }
    if (n < 2) n = 2;

    if (mode == "adp") {
        cout << 1 << "\n";
        cout << n << "\n";
        return 0;
    }

    vector<int> p;

    if (seedVal == 1) {
        n = 2;
        p = {2, 1};
    } else if (seedVal == 2) {
        n = maxn;
        p = makeBlockScramble(n, 60);
        applyRandomSwaps(p, 25);
    } else if (seedVal == 3) {
        n = maxn;
        p = makeDominators(n, 300);
        applyRandomSwaps(p, 10);
    } else {
        int style = (int)(seedVal % 5);
        if (style == 0) {
            p = makeDominators(n, 300);
            applyRandomSwaps(p, rnd.next(5, 25));
        } else if (style == 1) {
            p = makeAlternHighLow(n);
            applyRandomSwaps(p, rnd.next(10, 40));
        } else if (style == 2) {
            int B = rnd.next(55, 65);
            p = makeBlockScramble(n, B);
            applyRandomSwaps(p, rnd.next(10, 35));
        } else if (style == 3) {
            p = makeBitReversal(n);
            applyRandomSwaps(p, rnd.next(10, 35));
        } else {
            p = makeModMul(n);
            applyRandomSwaps(p, rnd.next(10, 35));
        }
    }

    if (!isPerm1toN(p)) {

        vector<int> perm0 = rnd.perm(n);
        p.resize(n);
        for (int i = 0; i < n; i++) p[i] = perm0[i] + 1;
    }

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


MisoilePunch♪ - 彩

This is an interactive problem!

On a normal day at the hidden office in A.R.C. Markland-N, Rin received an artifact, given to her by the exploration captain Sagar.

After much analysis, she now realizes that this artifact contains data about a strange flower, which has existed way before the New Age. However, the information about its chemical structure has been encrypted heavily.

The chemical structure of this flower can be represented as a string $p$. From the unencrypted papers included, Rin already knows the length $n$ of that string, and she can also conclude that the string contains at most three distinct letters: "C" (as in Carbon), "H" (as in Hydrogen), and "O" (as in Oxygen).

At each moment, Rin can input a string $s$ of an arbitrary length into the artifact's terminal, and it will return every starting position of $s$ as a substring of $p$.

However, the artifact has limited energy and cannot be recharged in any way, since the technology is way too ancient and is incompatible with any current A.R.C.'s devices. To be specific:

* The artifact only contains $\frac{7}{5}$ units of energy.
* For each time Rin inputs a string $s$ of length $t$, the artifact consumes $\frac{1}{t^2}$ units of energy.
* If the amount of energy reaches below zero, the task will be considered failed immediately, as the artifact will go black forever.

Since the artifact is so precious yet fragile, Rin is very nervous to attempt to crack the final data. Can you give her a helping hand?

Interaction

The interaction starts with a single integer $t$ ($1 \le t \le 500$), the number of test cases. The interaction for each testcase is described below:

First, read an integer $n$ ($4 \le n \le 50$), the length of the string $p$.

Then you can make queries of type "? s" ($1 \le |s| \le n$) to find the occurrences of $s$ as a substring of $p$.

After the query, you need to read its result as a series of integers in a line:

* The first integer $k$ denotes the number of occurrences of $s$ as a substring of $p$ ($-1 \le k \le n$). If $k = -1$, it means you have exceeded the energy limit or printed an invalid query, and you need to terminate immediately, to guarantee a "Wrong answer" verdict, otherwise you might get an arbitrary verdict because your solution will continue to read from a closed stream.
* The following $k$ integers $a_1, a_2, \ldots, a_k$ ($1 \le a_1 < a_2 < \ldots < a_k \le n$) denote the starting positions of the substrings that match the string $s$.

When you find out the string $p$, print "! $p$" to finish a test case. This query doesn't consume any energy. The interactor will return an integer $1$ or $0$. If the interactor returns $1$, you can proceed to the next test case, or terminate the program if it was the last testcase.

If the interactor returns $0$, it means that your guess is incorrect, and you should to terminate to guarantee a "Wrong answer" verdict.

Note that in every test case the string $p$ is fixed beforehand and will not change during the queries, i.e. the interactor is not adaptive.

After printing any query do not forget to print end of line and flush the output. Otherwise, you might get Idleness limit exceeded. To do this, use:

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

Examples

Input

```
1
4

2 1 2

1 2

0

1
```

Output

```? C? CH? CCHO! CCHH
```

Input

```
2
5

0

2 2 3

1
8

1 5

1 5

1 3

2 1 2

1
```

Output

```? O? HHH! CHHHH? COO? COOH? HCCOO? HH! HHHCCOOH
```

Note

Note that the example interaction contains extra empty lines so that it's easier to read. The real interaction doesn't contain any empty lines and you shouldn't print any extra empty lines as well.

#include "testlib.h"
#include <algorithm>
#include <csignal>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

static int queries = 0;
static long long query_limit = 1000000000LL;

void log_queries() {
    tout << "queries=" << queries << "\n";
    tout << "query_limit=" << query_limit << "\n";
}

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

int main(int argc, char* argv[]) {
    registerInteraction(argc, argv);
    signal(SIGPIPE, SIG_IGN);
    atexit(log_queries);

    const int t = inf.readInt();
    cout << t << "\n" << flush;

    for (int tc = 0; tc < t; tc++) {
        const int n = inf.readInt();
        const string p = inf.readToken();
        if ((int)p.size() != n) {
            quit_with(_fail, "Invalid hidden string length");
        }

        cout << n << "\n" << flush;

        long double energy = 7.0L / 5.0L;

        while (true) {
            string tok;
            if (!(cin >> tok)) {
                quit_with(_pe, "Unexpected EOF");
            }

            if (tok == "?") {
                string s;
                if (!(cin >> s)) {
                    quit_with(_pe, "Invalid query");
                }
                queries++;

                const int len = (int)s.size();
                if (len < 1 || len > n) {
                    cout << "-1\n" << flush;
                    quit_with(_wa, "Invalid query length");
                }

                energy -= 1.0L / (static_cast<long double>(len) * static_cast<long double>(len));
                if (energy < -1e-12L) {
                    cout << "-1\n" << flush;
                    quit_with(_wa, "Energy limit exceeded");
                }

                vector<int> pos;
                for (int i = 0; i + len <= n; i++) {
                    if (p.compare(i, len, s) == 0) {
                        pos.push_back(i + 1);
                    }
                }

                cout << pos.size();
                for (int x : pos) {
                    cout << " " << x;
                }
                cout << "\n" << flush;
                continue;
            }

            if (!tok.empty() && tok[0] == '?' && tok.size() > 1) {

                string s = tok.substr(1);
                queries++;

                const int len = (int)s.size();
                if (len < 1 || len > n) {
                    cout << "-1\n" << flush;
                    quit_with(_wa, "Invalid query length");
                }

                energy -= 1.0L / (static_cast<long double>(len) * static_cast<long double>(len));
                if (energy < -1e-12L) {
                    cout << "-1\n" << flush;
                    quit_with(_wa, "Energy limit exceeded");
                }

                vector<int> pos;
                for (int i = 0; i + len <= n; i++) {
                    if (p.compare(i, len, s) == 0) {
                        pos.push_back(i + 1);
                    }
                }

                cout << pos.size();
                for (int x : pos) {
                    cout << " " << x;
                }
                cout << "\n" << flush;
                continue;
            }

            if (tok == "!") {
                string guess;
                if (!(cin >> guess)) {
                    quit_with(_pe, "Missing guess");
                }
                const bool ok = (guess == p);
                cout << (ok ? "1" : "0") << "\n" << flush;
                if (!ok) {
                    quit_with(_wa, "Wrong guess");
                }
                break;
            }

            quit_with(_pe, "Unknown command: " + tok);
        }
    }

    quit_with(_ok, "All tests correct");
}

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

static string gen_string(int n, int mode) {
    static const string ALPH = "CHO";
    string p;
    p.reserve(n);

    if (mode == 0) {

        char ch = ALPH[rnd.next(0, 2)];
        p.assign(n, ch);
        return p;
    }
    if (mode == 1) {

        for (int i = 0; i < n; i++) p.push_back(ALPH[i % 3]);
        return p;
    }
    if (mode == 2) {

        char a = ALPH[rnd.next(0, 2)];
        char b = ALPH[rnd.next(0, 2)];
        while (b == a) b = ALPH[rnd.next(0, 2)];
        for (int i = 0; i < n; i++) p.push_back((i % 2) ? b : a);
        return p;
    }
    if (mode == 3) {

        char ch = ALPH[rnd.next(0, 2)];
        p.assign(n, ch);
        int flips = max(1, n / 10);
        for (int i = 0; i < flips; i++) {
            int pos = rnd.next(0, n - 1);
            char other = ALPH[rnd.next(0, 2)];
            while (other == ch) other = ALPH[rnd.next(0, 2)];
            p[pos] = other;
        }
        return p;
    }

    for (int i = 0; i < n; i++) p.push_back(ALPH[rnd.next(0, 2)]);
    return p;
}

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

    const long long seed = (argc >= 2) ? atoll(argv[1]) : 1;

    int t = 10;
    if (seed == 1) t = 1;
    else if (seed == 2) t = 2;
    else if (seed <= 5) t = 5;
    else if (seed <= 20) t = 10;
    else t = 20;
    t = max(1, min(500, t));

    cout << t << "\n";
    for (int tc = 0; tc < t; tc++) {
        int n = 50;
        if (seed == 1) n = 4;
        else if (seed == 2) n = 5;
        else if (seed <= 10) n = 10 + (int)seed;
        else n = 50;
        n = max(4, min(50, n));

        int mode = (int)((seed + tc) % 6);
        string p = gen_string(n, mode);

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


This is the hard version of the problem. In this version, the limit of commands you can send is described in the statement.

This is an interactive problem.

Welcome, Duelists! In this interactive challenge, there is an unknown integer $x$ ($1 \le x \le 10^9$). You must make it equal to a given integer in the input $n$. By harnessing the power of "Mathmech" monsters, you can send a command to do one of the following:

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
| Command | Constraint | Result | Case | Update | Jury's response |
| "add $y$" | $-10^{18} \le y \le 10^{18}$ | $\mathrm{res} = x + y$ | $\text{if } 1 \le \mathrm{res} \le 10^{18}$ | $x \leftarrow \mathrm{res}$ | "1" |
| $\mathrm{else}$ | $x \leftarrow x$ | "0" |
| "mul $y$" | $1 \le y \le 10^{18}$ | $\mathrm{res} = x \cdot y$ | $\text{if } 1 \le \mathrm{res} \le 10^{18}$ | $x \leftarrow \mathrm{res}$ | "1" |
| $\mathrm{else}$ | $x \leftarrow x$ | "0" |
| "div $y$" | $1 \le y \le 10^{18}$ | $\mathrm{res} = x/y$ | $\text{if } y$ divides $x$ | $x \leftarrow \mathrm{res}$ | "1" |
| $\mathrm{else}$ | $x \leftarrow x$ | "0" |
| "digit" | — | $\mathrm{res} = S(x)$$^{\text{∗}}$ | — | $x \leftarrow \mathrm{res}$ | "1" |

Let $f(n)$ be the minimum integer such that there is a sequence of $f(n)$ commands that transforms $x$ into $n$ for all $x(1 \le x \le 10^9)$. You do not know the value of $x$ in advance. Find $f(n)$ such that, no matter what $x$ is, you can always transform it into $n$ using at most $f(n)$ commands.

Your task is to change $x$ into $n$ using at most $f(n)$ commands.

$^{\text{∗}}$$S(n)$ is a function that returns the sum of all the individual digits of a non-negative integer $n$. For example, $S(123) = 1 + 2 + 3 = 6$

Input

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

The first and only line of each test case contains one integer $n$ ($1 \le n \le 10^9$).

Interaction

The interaction for each test case begins by reading the integer $n$.

To send a command, output a line in the following format:

* "add $y$" Add some integer $y$ ($-10^{18} \le y \le 10^{18}$) to $x$.

  The jury will output "1" if $x + y$ is within $[1, 10^{18}]$ (successful), and "0" otherwise. If successful, update $x \leftarrow x + y$.
* "mul $y$" Multiply $x$ by a positive integer $y$ ($1 \le y \le 10^{18}$).

  The jury will output "1" if $x \cdot y$ is within $[1, 10^{18}]$ (successful), and "0" otherwise. If successful, update $x \leftarrow x \cdot y$.
* "div $y$" Divide $x$ by a positive integer $y$ ($1 \le y \le 10^{18}$).

  The jury will output "1" if $y$ is a divisor of $x$ (successful), and "0" otherwise. If successful, update $x \leftarrow \frac{x}{y}$.
* "digit" Make $x$ equal to the sum of its digits.

  The jury will always output "1" and update $x \leftarrow S(x)$.

Note that commands are case sensitive.

When you have determined that $x$ is equal to $n$, output a line in the following format:

* "!" — where the jury will output a "1" if $n$ is equal to $x$, and "-1" otherwise.

Note that answering does not count toward your limit of commands.

If your program makes more than $f(n)$ commands ($f(n)$ is described above) for one test case, or makes an invalid command, then the response to the command will be "-1". After receiving such a response, your program should immediately terminate to receive the verdict Wrong Answer. Otherwise, it may receive any other verdict.

After printing a command, do not forget to output the end of the 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;
* sys.stdout.flush() in Python;
* std::io::stdout().flush() in Rust;
* see the documentation for other languages.

The interactor is non-adaptive. The unknown integer $x$ does not change during the interaction.

Example

Input

```
2
100

0

1

1

1

5

1

1

1
```

Output

```
add -10

add 1

mul 10

!

digit

div 2

!
```

Note

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | $\texttt{2}$ | There are 2 test cases. |
|  | $\texttt{100}$ | In the first test case, the unknown integer $x = 9$ and we have to make it equal to $n = 100$. |
| $\texttt{add -10}$ | $\texttt{0}$ | The answer to "add -10" is "0". This means that the addition command was not successful as $x + y = 9 + (-10) \le 0$, and $x$ remains $9$ after the command |
| $\texttt{add 1}$ | $\texttt{1}$ | The answer to "add 1" is "1". This means that the addition command was successful as $x + y = 9 + 1 = 10$, and $x$ changes to $10$ after the command. |
| $\texttt{mul 10}$ | $\texttt{1}$ | The answer to "mul 10" is "1". This means that the multiplication command was successful as $x \cdot y = 10 \cdot 10 = 100$, and $x$ changes to $100$ after the command. |
| $\texttt{!}$ | $\texttt{1}$ | The answer to "!" is "1". This means you have determined that $x$ equals $n$. |
|  | $\texttt{5}$ | In the second test case, the unknown integer $x = 1234$ and we have to make it equal to $n = 5$. |
| $\texttt{digit}$ | $\texttt{1}$ | The answer to "digit" is "1". This means that $x$ turned into the sum of its digits $1 + 2 + 3 + 4 = 10$, and $x$ changes to $10$ after the command. |
| $\texttt{div 2}$ | $\texttt{1}$ | The answer to "div 2" is "1". This means that the division command was successful as $y = 2$ is a divisor of $x = 10$, and $x$ changes to $\frac{x}{y} = \frac{10}{2} = 5$ after the command. |
| $\texttt{!}$ | $\texttt{1}$ | The answer to "!" is "1". This means you have determined that $x$ equals $n$. |

Note that the empty lines in the example input and output are for the sake of clarity, and do not occur in the real interaction.

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

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

static const int LIMIT_PER_CASE = 150;

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 digit_sum(long long val) {
    string s = to_string(val);
    long long sum = 0;
    for (char c : s) sum += (c - '0');
    return sum;
}

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    int t = inf.readInt();

    cout << t << endl;

    query_limit = (long long)t * LIMIT_PER_CASE;
    log_metrics();

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

        long long n = inf.readLong();
        long long x = inf.readLong();

        cout << n << endl;

        int case_queries = 0;
        bool case_active = true;

        while (case_active) {
            string token;
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF while reading command (test case " + to_string(i+1) + ")");
            }

            if (token == "?") {
                if (!(cin >> token)) {
                    finish(_wa, "Unexpected EOF after '?'");
                }
            }

            if (token == "!") {
                if (x == n) {
                    cout << "1" << endl;
                    case_active = false;
                } else {
                    cout << "-1" << endl;
                    finish(_wa, "Wrong Answer: guessed x=" + to_string(x) + " but expected n=" + to_string(n));
                }

                continue;
            }

            if (case_queries >= LIMIT_PER_CASE) {
                cout << "-1" << endl;
                finish(_wa, "Query limit exceeded for test case " + to_string(i+1));
            }

            queries++;
            case_queries++;

            string reply = "0";
            bool success = false;

            if (token == "add") {
                long long y;
                if (!(cin >> y)) finish(_wa, "Invalid format for add command");

                if (y < -1000000000000000000LL || y > 1000000000000000000LL) {
                    cout << "-1" << endl;
                    finish(_wa, "Argument y out of range for add command");
                }

                __int128 res = (__int128)x + y;
                if (res >= 1 && res <= 1000000000000000000LL) {
                    x = (long long)res;
                    success = true;
                }
            }
            else if (token == "mul") {
                long long y;
                if (!(cin >> y)) finish(_wa, "Invalid format for mul command");

                if (y < 1 || y > 1000000000000000000LL) {
                    cout << "-1" << endl;
                    finish(_wa, "Argument y out of range for mul command");
                }

                __int128 res = (__int128)x * y;
                if (res >= 1 && res <= 1000000000000000000LL) {
                    x = (long long)res;
                    success = true;
                }
            }
            else if (token == "div") {
                long long y;
                if (!(cin >> y)) finish(_wa, "Invalid format for div command");

                if (y < 1 || y > 1000000000000000000LL) {
                    cout << "-1" << endl;
                    finish(_wa, "Argument y out of range for div command");
                }

                if (x % y == 0) {
                    x = x / y;
                    success = true;
                }
            }
            else if (token == "digit") {

                x = digit_sum(x);
                success = true;
            }
            else {

                cout << "-1" << endl;
                finish(_wa, "Unknown command: " + token);
            }

            reply = success ? "1" : "0";
            cout << reply << endl;
        }
    }

    finish(_ok, "All cases passed");
    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 = atoll(argv[1]);

    vector<long long> ns;
    vector<long long> xs;

    auto add = [&](long long n, long long x) {
        ns.push_back(n);
        if (mode == "non") {
            xs.push_back(x);
        }
    };

    auto rndC = [&]() { return rnd.next(1LL, 1000000000LL); };

    if (seed_val == 1) {

        add(1, 1);
        add(1000000000, 1000000000);
        add(1, 1000000000);
        add(1000000000, 1);
        add(100, 9);
    } else if (seed_val == 2) {

        add(2, 3);
        add(3, 2);
        add(5, 1234);
        add(10, 100);
        add(12345, 67890);
    } else if (seed_val == 3) {

        add(10, 1000);
        add(1000, 10);
        add(999, 1000);
        add(1000, 999);
        add(123, 6);
    } else {

        int t = 100;
        for (int i = 0; i < t; ++i) {
            long long n, x;
            int type = rnd.next(1, 6);

            if (type == 1) {
                n = rnd.next(1, 100);
                x = rnd.next(1, 100);
            } else if (type == 2) {
                n = rnd.next(900000000LL, 1000000000LL);
                x = rnd.next(900000000LL, 1000000000LL);
            } else if (type == 3) {
                n = rndC();
                long long delta = rnd.next(-2000, 2000);
                x = n + delta;
                if (x < 1) x = 1;
                if (x > 1000000000) x = 1000000000;
            } else if (type == 4) {
                n = rndC();
                x = rndC();
            } else if (type == 5) {
                long long base = rnd.next(1, 10000);
                long long mult = rnd.next(1, 10000);
                long long val1 = base;
                long long val2 = base * mult;

                if (val2 > 1000000000) {
                     val2 = base * (1000000000 / base);
                     if (val2 == 0) val2 = 1000000000;
                }
                if (rnd.next(2)) {
                    n = val1; x = val2;
                } else {
                    n = val2; x = val1;
                }
            } else {
                 x = rndC();
                 long long temp = x;
                 long long sum = 0;
                 while(temp > 0) { sum += temp % 10; temp /= 10; }
                 n = sum;

                 if (rnd.next(2)) swap(n, x);
            }
            add(n, x);
        }
    }

    cout << ns.size() << "\n";
    for (size_t i = 0; i < ns.size(); ++i) {
        cout << ns[i];
        if (mode == "non") {

            cout << " " << xs[i];
        }
        cout << "\n";
    }

    return 0;
}


There is a $2 \times 2$ box of treasure hidden somewhere in a $5 \times 5$ grid. The rows are numbered from 1 to 5, as are the columns, with cell $( 1 , 1 )$ being the top left corner of the grid. Your goal is to find the treasure within 5 queries. You can query a grid cell and ask if there is any part of the treasure chest in that grid cell. After at most 5 queries, you must output the upper left coordinate of the treasure box.

![](images/cfa6a6b1da416e71773006f5c5e9e69980a2138d2ce241dc1a2d1d9fc71423eb.jpg)

# Interaction

Your program can make up to 5 queries for the location of the treasure. To make a query, print a new line of the form

$\textit { ? i j }$

where $i$ and $j$ are integers between 1 and 5. You are asking is the cell at the $i ^ { t h }$ row and $j ^ { t h }$ column has a part of the treasure box. After each query, the interactor will respond with a 0 if the cell does not contain any part of the treasure, or a 1 if the cell does.

After determining the correct answer, output the answer on a new line in the form

! i $j$

specifying the upper left coordinate of the treasure box. After outputting the answer, your program must exit. If you attempt to read a response after outputting an answer, you will receive an arbitrary verdict.

Do not forget to flush the output after each query you output.

If the interactor receives any invalid or unexpected input, the interactor will output $- 1$ and then immediately terminate. Your program must cleanly exit in order to receive a correct verdict, otherwise the verdict that it receives may be an arbitrary verdict indicating that your submission is incorrect.

A testing tool is provided in python. Use it as follows (You may have to replace python3 by just python):

python3 testing_tool.py However-you-run-your-program

The tool is provided as-is, and you should feel free to make whatever alterations or augmentations you like to it. The tool attempts to detect and report common errors, but it is not guaranteed that a program that passes the testing tool will be accepted.

Read	Sample Interaction 1

	？33	Write

0

		？22

1

		？11

0

		？13

1

		！12

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

using namespace std;

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

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

    }
}

static void finish(TResult verdict, const char* fmt, ...) {
    log_metrics();

    char buf[4096];
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    quitf(verdict, "%s", buf);
}

static void die(const char* fmt, ...) {
    cout << -1 << endl;

    log_metrics();

    char buf[4096];
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    quitf(_wa, "%s", buf);
}

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

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

    int hidden_r = inf.readInt(1, 4, "hidden_r");
    int hidden_c = inf.readInt(1, 4, "hidden_c");

    while (true) {

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

        string token;

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

        int r_in = -1, c_in = -1;
        bool is_answer = false;

        if (token == "!") {
            is_answer = true;
            if (!(cin >> r_in >> c_in)) {
                finish(_wa, "Incomplete answer coordinates");
            }
        } else if (token == "?") {
            if (!(cin >> r_in >> c_in)) {
                die("Incomplete query coordinates");
            }
        } else {

            try {
                size_t pos;
                r_in = stoi(token, &pos);
                if (pos != token.size()) throw exception();
            } catch (...) {
                die("Invalid token '%s' (expected '?', '!' or integer)", token.c_str());
            }
            if (!(cin >> c_in)) {
                die("Incomplete query coordinates (missing column)");
            }
        }

        if (is_answer) {

            if (r_in == hidden_r && c_in == hidden_c) {
                finish(_ok, "Correct answer: (%d, %d)", hidden_r, hidden_c);
            } else {
                finish(_wa, "Wrong answer. Expected (%d, %d), found (%d, %d)", hidden_r, hidden_c, r_in, c_in);
            }
        } else {

            if (r_in < 1 || r_in > 5 || c_in < 1 || c_in > 5) {
                die("Query coordinates (%d, %d) out of bounds [1,5]", r_in, c_in);
            }

            queries++;

            log_metrics();

            bool hit = (r_in >= hidden_r && r_in <= hidden_r + 1) &&
                       (c_in >= hidden_c && c_in <= hidden_c + 1);

            cout << (hit ? 1 : 0) << endl;
        }
    }

    return 0;
}

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

using namespace std;

static long long queries = 0;
static const long long query_limit = 5;

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

    }
}

void finish(TResult verdict, string msg) {
    log_metrics();

    if (verdict == _pe) {
        cout << -1 << endl;
    }
    quitf(verdict, "%s", msg.c_str());
}

struct Rect {
    int r, c;

    bool covers(int qr, int qc) const {

        return (qr >= r && qr <= r + 1 && qc >= c && qc <= c + 1);
    }
};

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

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

    log_metrics();

    while (!inf.seekEof()) {
        inf.readToken();
    }

    vector<Rect> candidates;
    for (int r = 1; r <= 4; ++r) {
        for (int c = 1; c <= 4; ++c) {
            candidates.push_back({r, c});
        }
    }

    int hard_cap = 200;

    while (true) {
        string type;

        if (!(cin >> type)) {

            finish(_wa, "Unexpected EOF. Expected '?' or '!'");
        }

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

            if (qr < 1 || qr > 5 || qc < 1 || qc > 5) {
                finish(_pe, format("Query coordinates (%d, %d) out of bounds [1, 5]", qr, qc));
            }

            queries++;
            log_metrics();

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

            vector<Rect> group0, group1;
            for (const auto& rect : candidates) {
                if (rect.covers(qr, qc)) {
                    group1.push_back(rect);
                } else {
                    group0.push_back(rect);
                }
            }

            int resp = 0;
            if (group1.size() > group0.size()) {
                resp = 1;
                candidates = group1;
            } else {
                resp = 0;
                candidates = group0;
            }

            cout << resp << endl;

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

            if (ans_r < 1 || ans_r > 4 || ans_c < 1 || ans_c > 4) {
                finish(_wa, format("Answer coordinates (%d, %d) out of bounds [1, 4]", ans_r, ans_c));
            }

            bool possible = false;
            for (const auto& rect : candidates) {
                if (rect.r == ans_r && rect.c == ans_c) {
                    possible = true;
                    break;
                }
            }

            if (!possible) {
                finish(_wa, format("Answer (%d, %d) is inconsistent with query history", ans_r, ans_c));
            } else if (candidates.size() > 1) {
                finish(_wa, format("Solution not unique (%d candidates remain). Contestant guessed.", (int)candidates.size()));
            } else {
                finish(_ok, format("Correct! Found treasure at (%d, %d)", ans_r, ans_c));
            }

        } else {
            finish(_pe, format("Unknown token '%s'. Expected '?' or '!'", type.c_str()));
        }
    }

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

    if (mode == "non") {

        int s = atoi(argv[1]);
        int r, c;

        if (s >= 1 && s <= 16) {
            int idx = s - 1;
            r = 1 + (idx / 4);
            c = 1 + (idx % 4);
        } else {

            r = rnd.next(1, 4);
            c = rnd.next(1, 4);
        }

        println(r, c);

    } else {

        long long adaptive_seed = rnd.next(1LL, 4000000000000000000LL);
        println(adaptive_seed);
    }

    return 0;
}


For security reasons, TU Delft is going to place locks with numeric keypads on the doors of a large number of rooms. Each room will have its own pass code. The task of setting up the server on which all codes will be stored is given to Harry and Sharon.

Having paid attention in cybersecurity class, they know that the codes should be passed through a hash function, preferably multiple times, before storing.

Sharon came up with the nifty idea of letting the room number be the number of times the code is passed through the hash function. That way, even if two rooms happen to have the same pass code, they will not (necessarily) end up with the same hash value. However, they find that for some combinations of room number and code, the hash value happens to be the same as the original code, presenting a security risk.

Not to be outdone by Sharon, Harry came up with an idea of his own: to switch the roles, that is, let the code be the number of times the hash function is applied to the room number. In other words, if $c$ is the code and $r$ is the room number, the hash value will be $f ^ { c } ( r ) = f ( \cdot \cdot \cdot f ( r ) \cdot \cdot \cdot )$ . | {z }c times

After some thought, Sharon claimed that, regardless of what the function $f$ is, it would always still be the case for some room numbers and codes that the hash value is the same as the code; that is, that $f ^ { c } ( r ) = c$ . In fact, Sharon thinks it would not be too difficult to find two such numbers, even without knowing the full details of $f$ .

![](images/bcd1cf821dfc39b537f6cac4b79379a2a494956d1fa38951ab4473bb05241bfe.jpg)
Silhouettes free to use from pxfuel.com

This dismissive statement made Harry angry, who believed that Sharon was just jealous of his idea. After a big argument that led nowhere, Harry decided to make Sharon prove her claim: he has written a program that, upon sending it a query, will return the hash value $f ^ { c } ( r )$ for the $c$ and $r$ given in the query, using a secret hash function $f$ he has chosen. The hash function accepts any $r$ in $\{ 1 , \ldots , n \}$ , where $n$ is given, and returns a value in the same range. The value of $c$ should also be in the same range. The challenge for Sharon is to find $c$ and $r$ such that $f ^ { c } ( r ) = c$ , using a limited number of queries.

You know that Sharon is right about her claim and decide to help her.

In the first sample case, the value of $n$ is 6, and the hidden function is given by $f ( 1 ) = 4$ , $f ( 2 ) = 3$ , $f ( 3 ) = 5$ , $f ( 4 ) = 2$ , $f ( 5 ) = 4$ , and $f ( 6 ) = 6$ . In the second sample, $n = 4$ , and $f ( 1 ) = 2$ , $f ( 2 ) = 4$ , $f ( 3 ) = 2$ , and $f ( 4 ) = 2$ .

# Interaction

This is an interactive problem. Your submission will be run against an interactor, which reads the standard output of your submission and writes to the standard input of your submission. This interaction needs to follow a specific protocol:

The interactor first sends one line with an integer $n$ $( 1 \leq n \leq 2 \cdot 1 0 ^ { 5 } )$ ), indicating that the domain of the hidden function $f$ is $\{ 1 , \ldots , n \}$ .

Then, your program should make at most 1000 queries to find the answer. Each query is made by printing one line of the form “? c r” $( 1 \leq c , r \leq n )$ . The interactor will respond with an integer $h$ $( 1 \leq h \leq n )$ , the value of $f ^ { c } ( r )$ .

When you have determined some values of $c$ and $r$ such that $f ^ { c } ( r ) = c$ , print one line of the form “! c $r ^ { , , }$ $( 1 \leq c , r \leq n )$ , after which the interaction will stop. Printing the answer does not count as a query.

If there are multiple valid solutions, you may output any one of them.

The interactor is not adaptive: the hidden function $f$ is fixed up front, and does not depend on your queries.

Make sure you flush the buffer after each write.

A testing tool is provided to help you develop your solution.

Using more than 1000 queries will result in a wrong answer.

Read	Sample Interaction 1	Write

6

	？24

3

	？41

5

	？55

4

	？16

6

	？21

2	！21

# Sample Interaction 2

Write

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

using namespace std;

static int queries = 0;
static constexpr int QUERY_LIMIT = 1000;

static void log_queries() {
    tout << "queries=" << queries << '\n';
    tout << "query_limit=" << QUERY_LIMIT << '\n';
}

[[noreturn]] static void quit_with(TResult verdict, const string& msg) {
    log_queries();
    quitf(verdict, "%s", msg.c_str());
}

static int jump(const vector<vector<int>>& up, int x, int steps) {
    int cur = x;
    for (int k = 0; k < (int)up.size(); k++) {
        if (steps & (1 << k)) {
            cur = up[k][cur];
        }
    }
    return cur;
}

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

    const int n = inf.readInt(1, 200000, "n");
    vector<int> f(n + 1);
    for (int i = 1; i <= n; i++) {
        f[i] = inf.readInt(1, n, "f");
    }

    int LOG = 0;
    while ((1LL << LOG) <= n) {
        LOG++;
    }
    LOG = max(LOG, 1);

    vector<vector<int>> up(LOG, vector<int>(n + 1));
    for (int i = 1; i <= n; i++) {
        up[0][i] = f[i];
    }
    for (int k = 1; k < LOG; k++) {
        for (int i = 1; i <= n; i++) {
            up[k][i] = up[k - 1][up[k - 1][i]];
        }
    }

    cout << n << endl;

    while (true) {
        string cmd;
        if (!(cin >> cmd)) {
            quit_with(_pe, "Unexpected EOF");
        }

        if (cmd == "?") {
            int c = 0;
            int r = 0;
            if (!(cin >> c >> r)) {
                quit_with(_pe, "Invalid query");
            }
            if (c < 1 || c > n || r < 1 || r > n) {
                quit_with(_pe, "Query out of range");
            }

            queries++;
            if (queries > QUERY_LIMIT) {
                quit_with(_wa, "Too many queries");
            }

            cout << jump(up, r, c) << endl;
            continue;
        }

        if (cmd == "!") {
            int c = 0;
            int r = 0;
            if (!(cin >> c >> r)) {
                quit_with(_pe, "Invalid answer");
            }
            if (c < 1 || c > n || r < 1 || r > n) {
                quit_with(_pe, "Answer out of range");
            }

            const int h = jump(up, r, c);
            if (h == c) {
                quit_with(_ok, "Correct");
            }
            quit_with(_wa, "Wrong answer");
        }

        quit_with(_pe, "Unknown command: " + cmd);
    }
}

#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 s_val = 0;
    string seed_str = argv[1];
    bool is_num = true;
    for (char c : seed_str) if (!isdigit(c)) is_num = false;
    if (is_num && !seed_str.empty()) {
        try { s_val = stoll(seed_str); } catch (...) { s_val = 0; }
    }

    int n;

    if (opt<int>("n", 0) != 0) {
        n = opt<int>("n");
    } else {

        if (s_val == 1) n = 6;
        else if (s_val == 2) n = 4;
        else if (s_val >= 3 && s_val <= 6) n = 200000;
        else {

            if (rnd.next(10) == 0) n = rnd.next(1, 100);
            else n = rnd.next(100000, 200000);
        }
    }

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

    vector<int> f(n + 1);

    if (s_val == 1) {

        vector<int> vals = {0, 4, 3, 5, 2, 4, 6};
        if (n == 6) f = vals;
        else {

            for (int i = 1; i <= n; ++i) f[i] = vals[(i - 1) % 6 + 1];
        }
    } else if (s_val == 2) {

        vector<int> vals = {0, 2, 4, 2, 2};
        if (n == 4) f = vals;
        else {
            for (int i = 1; i <= n; ++i) f[i] = vals[(i - 1) % 4 + 1];
        }
    } else {

        int type = 0;
        if (s_val == 3) type = 1;
        else if (s_val == 4) type = 2;
        else if (s_val == 5) type = 3;
        else if (s_val == 6) type = 4;
        else type = rnd.next(1, 4);

        if (type == 1) {

            vector<int> p(n);
            iota(p.begin(), p.end(), 1);
            shuffle(p.begin(), p.end());
            for (int i = 0; i < n; ++i) {
                f[p[i]] = p[(i + 1) % n];
            }
        } else if (type == 2) {

            int max_cycle = max(1, (int)sqrt(n) * 10);
            int min_cycle = min(100, max_cycle);
            int cycle_len = rnd.next(min_cycle, max_cycle);
            if (cycle_len > n) cycle_len = n;
            if (cycle_len < 1) cycle_len = 1;

            int path_len = n - cycle_len;

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

            for (int i = 0; i < path_len; ++i) {
                f[p[i]] = p[i + 1];
            }

            for (int i = path_len; i < n; ++i) {
                int next_idx = path_len + (i - path_len + 1) % cycle_len;
                f[p[i]] = p[next_idx];
            }
        } else if (type == 3) {

            for (int i = 1; i <= n; ++i) {
                f[i] = rnd.next(1, n);
            }
        } else if (type == 4) {

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

            int cur = 0;
            while (cur < n) {
                int rem = n - cur;
                int len;
                if (rem <= 5) len = rem;
                else len = rnd.next(2, min(rem, 50000));

                for (int i = 0; i < len; ++i) {
                    f[p[cur + i]] = p[cur + (i + 1) % len];
                }
                cur += len;
            }
        }
    }

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

    return 0;
}


D. Jamie and To-do List

Why I have to finish so many assignments???

Jamie is getting very busy with his school life. He starts to forget the assignments that he has to do. He decided to write the things down on a to-do list. He assigns a value priority for each of his assignment (lower value means more important) so he can decide which he needs to spend more time on.

After a few days, Jamie finds out the list is too large that he can't even manage the list by himself! As you are a good friend of Jamie, help him write a program to support the following operations on the to-do list:

* *set* *a**i* *x**i* — Add assignment *a**i* to the to-do list if it is not present, and set its priority to *x**i*. If assignment *a**i* is already in the to-do list, its priority is changed to *x**i*.
* *remove* *a**i* — Remove assignment *a**i* from the to-do list if it is present in it.
* *query* *a**i* — Output the number of assignments that are more important (have a smaller priority value) than assignment *a**i*, so Jamie can decide a better schedule. Output  - 1 if *a**i* is not in the to-do list.
* *undo* *d**i* — Undo all changes that have been made in the previous *d**i* days (not including the day of this operation)

At day 0, the to-do list is empty. In each of the following *q* days, Jamie will do exactly one out of the four operations. If the operation is a *query*, you should output the result of the query before proceeding to the next day, or poor Jamie cannot make appropriate decisions.

Input

The first line consists of a single integer *q* (1 ≤ *q* ≤ 105) — the number of operations.

The following *q* lines consists of the description of the operations. The *i*-th line consists of the operation that Jamie has done in the *i*-th day. The query has the following format:

The first word in the line indicates the type of operation. It must be one of the following four: set, remove, query, undo.

* If it is a set operation, a string *a**i* and an integer *x**i* follows (1 ≤ *x**i* ≤ 109). *a**i* is the assignment that need to be set to priority *x**i*.
* If it is a remove operation, a string *a**i* follows. *a**i* is the assignment that need to be removed.
* If it is a query operation, a string *a**i* follows. *a**i* is the assignment that needs to be queried.
* If it is a undo operation, an integer *d**i* follows (0 ≤ *d**i* < *i*). *d**i* is the number of days that changes needed to be undone.

All assignment names *a**i* only consists of lowercase English letters and have a length 1 ≤ |*a**i*| ≤ 15.

It is guaranteed that the last operation is a query operation.

Output

For each query operation, output a single integer — the number of assignments that have a priority lower than assignment *a**i*, or  - 1 if *a**i* is not in the to-do list.

Interaction

If the operation is a *query*, you should output the result of the query and flush the output stream before proceeding to the next operation. Otherwise, you may get the verdict Idleness Limit Exceed.

For flushing the output stream, please refer to the documentation of your chosen programming language. The flush functions of some common programming languages are listed below:

* C: fflush(stdout);
* C++: cout « flush;
* Java: System.out.flush();

Examples

Input

```
8
set chemlabreport 1
set physicsexercise 2
set chinesemockexam 3
query physicsexercise
query chinesemockexam
remove physicsexercise
query physicsexercise
query chinesemockexam
```

Output

```
1
2
-1
1
```

Input

```
8
set physicsexercise 2
set chinesemockexam 3
set physicsexercise 1
query physicsexercise
query chinesemockexam
undo 4
query physicsexercise
query chinesemockexam
```

Output

```
0
1
0
-1
```

Input

```
5
query economicsessay
remove economicsessay
query economicsessay
undo 2
query economicsessay
```

Output

```
-1
-1
-1
```

Input

```
5
set economicsessay 1
remove economicsessay
undo 1
undo 1
query economicsessay
```

Output

```
-1
```

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

const int MAX_NODES = 12000000;
const int MAXQ = 100005;

struct Node {
    int l, r;
    int val;
} tree[MAX_NODES];
int nodes_ptr = 0;

int new_node() {
    return ++nodes_ptr;
}

int copy_node(int src) {
    int id = ++nodes_ptr;
    tree[id] = tree[src];
    return id;
}

int build(int tl, int tr) {
    int id = new_node();
    tree[id].val = 0;
    if (tl == tr) return id;
    int tm = (tl + tr) / 2;
    tree[id].l = build(tl, tm);
    tree[id].r = build(tm + 1, tr);
    return id;
}

int update_cnt(int old_id, int tl, int tr, int pos, int diff) {
    int id = copy_node(old_id);
    if (tl == tr) {
        tree[id].val += diff;
        return id;
    }
    int tm = (tl + tr) / 2;
    if (pos <= tm) tree[id].l = update_cnt(tree[old_id].l, tl, tm, pos, diff);
    else tree[id].r = update_cnt(tree[old_id].r, tm + 1, tr, pos, diff);
    tree[id].val = tree[tree[id].l].val + tree[tree[id].r].val;
    return id;
}

int update_val(int old_id, int tl, int tr, int pos, int v) {
    int id = copy_node(old_id);
    if (tl == tr) {
        tree[id].val = v;
        return id;
    }
    int tm = (tl + tr) / 2;
    if (pos <= tm) tree[id].l = update_val(tree[old_id].l, tl, tm, pos, v);
    else tree[id].r = update_val(tree[old_id].r, tm + 1, tr, pos, v);

    return id;
}

int query_cnt(int id, int tl, int tr, int ql, int qr) {
    if (ql > qr) return 0;
    if (ql == tl && qr == tr) return tree[id].val;
    int tm = (tl + tr) / 2;
    return query_cnt(tree[id].l, tl, tm, ql, min(qr, tm)) +
           query_cnt(tree[id].r, tm + 1, tr, max(ql, tm + 1), qr);
}

int query_val(int id, int tl, int tr, int pos) {
    if (tl == tr) return tree[id].val;
    int tm = (tl + tr) / 2;
    if (pos <= tm) return query_val(tree[id].l, tl, tm, pos);
    else return query_val(tree[id].r, tm + 1, tr, pos);
}

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

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

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

struct Op {
    string type;
    string s;
    int x;
    int d;
};

int roots_cnt[MAXQ];
int roots_val[MAXQ];

map<string, int> str_to_id;
vector<int> distinct_priorities;

int get_prio_rank(int p) {
    return lower_bound(distinct_priorities.begin(), distinct_priorities.end(), p) - distinct_priorities.begin() + 1;
}

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

    int Q = inf.readInt();
    vector<Op> ops(Q);

    for (int i = 0; i < Q; ++i) {
        ops[i].type = inf.readToken();
        if (ops[i].type == "set") {
            ops[i].s = inf.readToken();
            ops[i].x = inf.readInt();
            str_to_id[ops[i].s] = 0;
            distinct_priorities.push_back(ops[i].x);
        } else if (ops[i].type == "remove") {
            ops[i].s = inf.readToken();
            str_to_id[ops[i].s] = 0;
        } else if (ops[i].type == "query") {
            ops[i].s = inf.readToken();
            str_to_id[ops[i].s] = 0;
            query_limit++;
        } else if (ops[i].type == "undo") {
            ops[i].d = inf.readInt();
        }
    }

    int M = 0;
    for (auto& kv : str_to_id) {
        kv.second = ++M;
    }
    if (M == 0) M = 1;

    sort(distinct_priorities.begin(), distinct_priorities.end());
    distinct_priorities.erase(unique(distinct_priorities.begin(), distinct_priorities.end()), distinct_priorities.end());
    int K = distinct_priorities.size();
    if (K == 0) K = 1;

    roots_cnt[0] = build(1, K);
    roots_val[0] = build(1, M);

    log_metrics();

    cout << Q << endl;

    for (int i = 1; i <= Q; ++i) {
        const auto& op = ops[i-1];

        if (op.type == "set") cout << "set " << op.s << " " << op.x << endl;
        else if (op.type == "remove") cout << "remove " << op.s << endl;
        else if (op.type == "query") cout << "query " << op.s << endl;
        else if (op.type == "undo") cout << "undo " << op.d << endl;

        if (op.type == "undo") {

            int target_idx = (i - 1) - op.d;
            roots_cnt[i] = roots_cnt[target_idx];
            roots_val[i] = roots_val[target_idx];
        } else {

            roots_cnt[i] = roots_cnt[i-1];
            roots_val[i] = roots_val[i-1];

            if (op.type == "set") {
                int sid = str_to_id[op.s];
                int pid = get_prio_rank(op.x);

                int old_pid = query_val(roots_val[i], 1, M, sid);
                if (old_pid != 0) {

                    roots_cnt[i] = update_cnt(roots_cnt[i], 1, K, old_pid, -1);
                }

                roots_cnt[i] = update_cnt(roots_cnt[i], 1, K, pid, 1);

                roots_val[i] = update_val(roots_val[i], 1, M, sid, pid);

            } else if (op.type == "remove") {
                int sid = str_to_id[op.s];
                int old_pid = query_val(roots_val[i], 1, M, sid);

                if (old_pid != 0) {
                    roots_cnt[i] = update_cnt(roots_cnt[i], 1, K, old_pid, -1);
                    roots_val[i] = update_val(roots_val[i], 1, M, sid, 0);
                }

            } else if (op.type == "query") {

                int sid = str_to_id[op.s];
                int current_pid = query_val(roots_val[i], 1, M, sid);

                int expected = -1;
                if (current_pid != 0) {

                    expected = query_cnt(roots_cnt[i], 1, K, 1, current_pid - 1);
                }

                int user_ans;

                if (!(cin >> user_ans)) {
                    finish(_pe, "Expected integer answer for query");
                }
                queries++;

                if (user_ans != expected) {
                    finish(_wa, format("Query #%d ('%s'): expected %d, got %d", i, op.s.c_str(), expected, user_ans));
                }

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

    finish(_ok, "All queries correct");
}

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

const int MAX_NODES = 6000000;

struct Node {
    int lc, rc;
    int val;
} nodes[MAX_NODES];

int node_ptr = 0;

int new_node() {
    int id = ++node_ptr;
    nodes[id] = {0, 0, 0};
    return id;
}

int copy_node(int u) {
    int v = ++node_ptr;
    nodes[v] = nodes[u];
    return v;
}

int update_map(int u, int l, int r, int pos, int val) {
    int v = (u == 0 ? new_node() : copy_node(u));
    if (l == r) {
        nodes[v].val = val;
        return v;
    }
    int mid = l + (r - l) / 2;
    if (pos <= mid) nodes[v].lc = update_map(nodes[u].lc, l, mid, pos, val);
    else nodes[v].rc = update_map(nodes[u].rc, mid + 1, r, pos, val);
    return v;
}

int query_map(int u, int l, int r, int pos) {
    if (!u) return 0;
    if (l == r) return nodes[u].val;
    int mid = l + (r - l) / 2;
    if (pos <= mid) return query_map(nodes[u].lc, l, mid, pos);
    else return query_map(nodes[u].rc, mid + 1, r, pos);
}

int update_cnt(int u, int l, int r, int pos, int diff) {
    int v = (u == 0 ? new_node() : copy_node(u));
    if (l == r) {
        nodes[v].val += diff;
        return v;
    }
    int mid = l + (r - l) / 2;
    if (pos <= mid) nodes[v].lc = update_cnt(nodes[u].lc, l, mid, pos, diff);
    else nodes[v].rc = update_cnt(nodes[u].rc, mid + 1, r, pos, diff);

    nodes[v].val = (nodes[v].lc ? nodes[nodes[v].lc].val : 0) +
                   (nodes[v].rc ? nodes[nodes[v].rc].val : 0);
    return v;
}

int query_cnt(int u, int l, int r, int ql, int qr) {
    if (!u || l > qr || r < ql) return 0;
    if (l >= ql && r <= qr) return nodes[u].val;
    int mid = l + (r - l) / 2;
    return query_cnt(nodes[u].lc, l, mid, ql, qr) +
           query_cnt(nodes[u].rc, mid + 1, r, ql, qr);
}

struct Op {
    string type;
    string arg_s;
    int arg_x;
    int arg_d;
};

int root_map[100005];
int root_cnt[100005];

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int Q = inf.readInt();
    query_limit = Q;

    cout << Q << endl;

    vector<Op> ops(Q);
    vector<string> all_strings;
    vector<int> all_prio;

    for (int i = 0; i < Q; ++i) {
        ops[i].type = inf.readToken();
        if (ops[i].type == "set") {
            ops[i].arg_s = inf.readToken();
            ops[i].arg_x = inf.readInt();
            all_strings.push_back(ops[i].arg_s);
            all_prio.push_back(ops[i].arg_x);
        } else if (ops[i].type == "remove") {
            ops[i].arg_s = inf.readToken();
            all_strings.push_back(ops[i].arg_s);
        } else if (ops[i].type == "query") {
            ops[i].arg_s = inf.readToken();
            all_strings.push_back(ops[i].arg_s);
        } else if (ops[i].type == "undo") {
            ops[i].arg_d = inf.readInt();
        }
    }

    sort(all_strings.begin(), all_strings.end());
    all_strings.erase(unique(all_strings.begin(), all_strings.end()), all_strings.end());

    sort(all_prio.begin(), all_prio.end());
    all_prio.erase(unique(all_prio.begin(), all_prio.end()), all_prio.end());

    int num_str = (int)all_strings.size();
    int num_prio = (int)all_prio.size();

    auto get_str_id = [&](const string& s) {
        return (int)(lower_bound(all_strings.begin(), all_strings.end(), s) - all_strings.begin()) + 1;
    };
    auto get_prio_id = [&](int p) {
        return (int)(lower_bound(all_prio.begin(), all_prio.end(), p) - all_prio.begin()) + 1;
    };

    root_map[0] = 0;
    root_cnt[0] = 0;

    log_metrics();

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

        if (ops[i].type == "set") {
            cout << "set " << ops[i].arg_s << " " << ops[i].arg_x << endl;
        } else if (ops[i].type == "remove") {
            cout << "remove " << ops[i].arg_s << endl;
        } else if (ops[i].type == "query") {
            cout << "query " << ops[i].arg_s << endl;
        } else if (ops[i].type == "undo") {
            cout << "undo " << ops[i].arg_d << endl;
        }

        int r_map = root_map[i];
        int r_cnt = root_cnt[i];

        if (ops[i].type == "set") {
            int sid = get_str_id(ops[i].arg_s);
            int pid = get_prio_id(ops[i].arg_x);
            int old_raw = query_map(r_map, 1, num_str, sid);

            if (old_raw != 0) {
                int old_pid = get_prio_id(old_raw);
                r_cnt = update_cnt(r_cnt, 1, num_prio, old_pid, -1);
            }

            r_cnt = update_cnt(r_cnt, 1, num_prio, pid, 1);

            r_map = update_map(r_map, 1, num_str, sid, ops[i].arg_x);

            root_map[i+1] = r_map;
            root_cnt[i+1] = r_cnt;

        } else if (ops[i].type == "remove") {
            int sid = get_str_id(ops[i].arg_s);
            int old_raw = query_map(r_map, 1, num_str, sid);

            if (old_raw != 0) {
                int old_pid = get_prio_id(old_raw);
                r_cnt = update_cnt(r_cnt, 1, num_prio, old_pid, -1);
                r_map = update_map(r_map, 1, num_str, sid, 0);
            }
            root_map[i+1] = r_map;
            root_cnt[i+1] = r_cnt;

        } else if (ops[i].type == "undo") {
            int d = ops[i].arg_d;

            root_map[i+1] = root_map[i-d];
            root_cnt[i+1] = root_cnt[i-d];

        } else if (ops[i].type == "query") {

            root_map[i+1] = r_map;
            root_cnt[i+1] = r_cnt;

            long long user_ans;
            if (!(cin >> user_ans)) {
                finish(_pe, "Expected integer answer from contestant");
            }

            int sid = get_str_id(ops[i].arg_s);
            int raw_val = query_map(r_map, 1, num_str, sid);
            long long expected = -1;

            if (raw_val != 0) {
                int pid = get_prio_id(raw_val);

                if (pid == 1) expected = 0;
                else expected = query_cnt(r_cnt, 1, num_prio, 1, pid - 1);
            }

            if (user_ans != expected) {
                finish(_wa, "Day " + to_string(i+1) + " query " + ops[i].arg_s +
                       ": expected " + to_string(expected) + ", got " + to_string(user_ans));
            }
        }

        queries++;
        if (i % 5000 == 0) log_metrics();
    }

    finish(_ok, "Passed " + to_string(Q) + " operations");
    return 0;
}

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

string gen_str(int len = -1) {
    if (len == -1) len = rnd.next(1, 15);
    string s = "";
    for (int i = 0; i < len; ++i) s += (char)rnd.next('a', 'z');
    return s;
}

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

    string mode = opt<string>("mode", "non");
    long long seed_val = atoll(argv[1]);
    int q_opt = opt<int>("q", -1);

    if (seed_val == 1) {
        cout << "8\n";
        cout << "set chemlabreport 1\n";
        cout << "set physicsexercise 2\n";
        cout << "set chinesemockexam 3\n";
        cout << "query physicsexercise\n";
        cout << "query chinesemockexam\n";
        cout << "remove physicsexercise\n";
        cout << "query physicsexercise\n";
        cout << "query chinesemockexam\n";
        return 0;
    }
    if (seed_val == 2) {
        cout << "8\n";
        cout << "set physicsexercise 2\n";
        cout << "set chinesemockexam 3\n";
        cout << "set physicsexercise 1\n";
        cout << "query physicsexercise\n";
        cout << "query chinesemockexam\n";
        cout << "undo 4\n";
        cout << "query physicsexercise\n";
        cout << "query chinesemockexam\n";
        return 0;
    }
    if (seed_val == 3) {

        cout << "5\n";
        cout << "set a 1\n";
        cout << "undo 1\n";
        cout << "set b 2\n";
        cout << "undo 2\n";
        cout << "query a\n";
        return 0;
    }

    int Q = 100000;
    if (q_opt != -1) Q = q_opt;
    else if (seed_val <= 10) Q = 20;

    cout << Q << "\n";

    vector<string> pool;
    int pool_size;
    if (mode == "adp") pool_size = 200;
    else pool_size = max(1, Q / 5);

    for (int i = 0; i < pool_size; ++i) pool.push_back(gen_str());

    for (int i = 1; i <= Q; ++i) {

        if (i == Q) {
            cout << "query " << pool[rnd.next(pool_size)] << "\n";
            continue;
        }

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

            int p = rnd.next(100);
            if (p < 30) type = 0;
            else if (p < 50) type = 1;
            else if (p < 80) type = 3;
            else type = 2;
        } else {

            int p = rnd.next(100);
            if (p < 35) type = 0;
            else if (p < 50) type = 1;
            else if (p < 90) type = 2;
            else type = 3;
        }

        if (type == 0) {
            string s = pool[rnd.next(pool_size)];
            int x = rnd.next(1, 1000000000);
            cout << "set " << s << " " << x << "\n";
        } else if (type == 1) {
            string s = pool[rnd.next(pool_size)];
            cout << "remove " << s << "\n";
        } else if (type == 2) {
            string s = pool[rnd.next(pool_size)];
            cout << "query " << s << "\n";
        } else {

            int limit = i - 1;
            if (limit == 0) {
                cout << "undo 0\n";
            } else {
                int d;
                if (mode == "adp") {

                    if (rnd.next(2)) d = rnd.next(max(0, limit - 500), limit);
                    else d = rnd.next(0, min(limit, 10));
                } else {
                    d = rnd.next(0, limit);
                }
                cout << "undo " << d << "\n";
            }
        }
    }

    return 0;
}


This is an interactive problem. Remember to flush your output while communicating with the testing program. You may use fflush(stdout) in C++, system.out.flush() in Java, stdout.flush() in Python or flush(output) in Pascal to flush the output. If you use some other programming language, consult its documentation. You may also refer to the guide on interactive problems: [link omitted].

There is a city in which Dixit lives. In the city, there are $n$ houses. There is  exactly one directed road between every pair of houses. For example, consider two houses A and B, then there is a directed road either from A to B or from B to A but not both. The number of roads leading to the $i$-th house is $k_i$.

Two houses A and B are bi-reachable if A is reachable from B and B is reachable from A. We say that house B is reachable from house A when there is a path from house A to house B.

Dixit wants to buy two houses in the city, that is, one for living and one for studying. Of course, he would like to travel from one house to another. So, he wants to find a pair of bi-reachable houses A and B. Among all such pairs, he wants to choose one with the maximum value of $|k_A - k_B|$, where $k_i$ is the number of roads leading to the house $i$. If more than one optimal pair exists, any of them is suitable.

Since Dixit is busy preparing CodeCraft, can you help him find the desired pair of houses, or tell him that no such houses exist?

In the problem input, you are not given the direction of each road. You are given — for each house — only the number of incoming roads to that house ($k_i$).

You are allowed to ask only one type of query from the judge: give two houses A and B, and the judge answers whether B is reachable from A. There is no upper limit on the number of queries. But, you cannot ask more queries after the judge answers "Yes" to any of your queries. Also, you cannot ask the same query twice.

Once you have exhausted all your queries (or the judge responds "Yes" to any of your queries), your program must output its guess for the two houses and quit.

See the Interaction section below for more details.

Input

The first line contains a single integer $n$ ($3 \le n \le 500$) denoting the number of houses in the city. The next line contains $n$ space-separated integers $k_1, k_2, \dots, k_n$ ($0 \le k_i \le n - 1$), the $i$-th of them represents the number of incoming roads to the $i$-th house.

Interaction

To ask a query, print "? A B" $(1 \leq A,B \leq N, A\neq B)$. The judge will respond "Yes" if house B is reachable from house A, or "No" otherwise.

To output the final answer, print "! A B", where A and B are bi-reachable with the maximum possible value of $|k_A - k_B|$. If there does not exist such pair of houses A and B, output "! 0 0".

After outputting the final answer, your program must terminate immediately, otherwise you will receive Wrong Answer verdict.

You cannot ask the same query twice. There is no upper limit to the number of queries you ask, but, you cannot ask more queries after the judge answers "Yes" to any of your queries. Your program must now output the final answer ("! A B" or "! 0 0") and terminate.

If you ask a query in incorrect format or repeat a previous query, you will get Wrong Answer verdict.

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

Examples

Input

```
3
1 1 1
Yes
```

Output

```? 1 2! 1 2
```

Input

```
4
1 2 0 3
No
No
No
No
No
No
```

Output

```? 2 1? 1 3? 4 1? 2 3? 4 2? 4 3! 0 0
```

Note

In the first sample input, we are given a city of three houses with one incoming road each. The user program asks one query: "? 1 2": asking whether we can reach from house $1$ to house $2$. The judge responds with "Yes". The user program now concludes that this is sufficient information to determine the correct answer. So, it outputs "! 1 2" and quits.

In the second sample input, the user program queries for six different pairs of houses, and finally answers "! 0 0" as it is convinced that no two houses as desired in the question exist in this city.

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

using namespace std;

long long queries = 0;

long long query_limit = 250000;

int n;
vector<int> degrees;
vector<bitset<500>> reach;
int max_diff = -1;
bool yes_answered = false;
set<pair<int,int>> history;

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

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

    signal(SIGPIPE, SIG_IGN);

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

    n = inf.readInt();
    degrees.resize(n);
    for(int i = 0; i < n; ++i) {
        degrees[i] = inf.readInt();
    }

    reach.resize(n);
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n; ++j) {
            int edge = inf.readInt();
            if(edge) {
                reach[i][j] = 1;
            }
        }
        reach[i][i] = 1;
    }

    for(int k = 0; k < n; ++k) {
        for(int i = 0; i < n; ++i) {
            if(reach[i][k]) {
                reach[i] |= reach[k];
            }
        }
    }

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

            if(reach[i][j] && reach[j][i]) {
                int diff = abs(degrees[i] - degrees[j]);
                if(diff > max_diff) {
                    max_diff = diff;
                }
            }
        }
    }

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

    while(true) {

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

        string token;
        if(!(cin >> token)) {
            finish(_pe, "Unexpected EOF (contestant exited without answer)");
        }

        if(token == "!") {
            int u, v;
            if(!(cin >> u >> v)) {
                finish(_pe, "Invalid answer format");
            }

            if(u == 0 && v == 0) {
                if(max_diff == -1) {
                    finish(_ok, "Correct (no solution)");
                } else {
                    finish(_wa, "Contestant found no solution, but one exists with diff " + to_string(max_diff));
                }
            } else {

                if(u < 1 || u > n || v < 1 || v > n || u == v) {
                    finish(_wa, "Invalid house indices in answer");
                }

                int u_idx = u - 1;
                int v_idx = v - 1;

                if(!reach[u_idx][v_idx] || !reach[v_idx][u_idx]) {
                    finish(_wa, "Houses are not bi-reachable");
                }

                int diff = abs(degrees[u_idx] - degrees[v_idx]);
                if(diff < max_diff) {
                    finish(_wa, "Found valid pair but difference (" + to_string(diff) +
                                ") is not maximum (max=" + to_string(max_diff) + ")");
                }

                finish(_ok, "Correct");
            }
        } else {

            int u, v;
            if(token == "?") {
                if(!(cin >> u >> v)) finish(_pe, "Invalid query format");
            } else {

                try {
                    u = stoi(token);
                } catch(...) {
                    finish(_pe, "Invalid token '" + token + "'");
                }
                if(!(cin >> v)) finish(_pe, "Invalid query format (missing second integer)");
            }

            if(yes_answered) {
                finish(_wa, "Protocol violation: query asked after receiving 'Yes'");
            }
            if(u < 1 || u > n || v < 1 || v > n || u == v) {
                finish(_wa, "Invalid query indices");
            }
            if(history.count({u, v})) {
                finish(_wa, "Repeated query");
            }
            history.insert({u, v});

            bool res = (reach[u-1][v-1] == 1);
            cout << (res ? "Yes" : "No") << endl;

            queries++;
            if(res) yes_answered = true;

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

    return 0;
}

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

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

int n;
vector<int> k;
vector<int> block;
int global_max_diff = -1;

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

void compute_blocks() {

    vector<pair<int, int>> sorted_k(n);
    for (int i = 1; i <= n; i++) {
        sorted_k[i - 1] = {k[i], i};
    }
    sort(sorted_k.begin(), sorted_k.end());

    block.assign(n + 1, 0);
    long long current_sum = 0;
    int current_block = 0;
    vector<int> current_indices;

    for (int j = 0; j < n; j++) {
        current_sum += sorted_k[j].first;
        current_indices.push_back(sorted_k[j].second);

        long long count = j + 1;

        if (current_sum == count * (count - 1) / 2) {

            for (int u : current_indices) {
                block[u] = current_block;
            }

            if (current_indices.size() >= 2) {
                for (size_t a = 0; a < current_indices.size(); a++) {
                    for (size_t b = a + 1; b < current_indices.size(); b++) {
                        int u = current_indices[a];
                        int v = current_indices[b];
                        int diff = abs(k[u] - k[v]);
                        if (diff > global_max_diff) {
                            global_max_diff = diff;
                        }
                    }
                }
            }

            current_block++;
            current_indices.clear();
        }
    }
}

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

    n = inf.readInt();
    k.assign(n + 1, 0);
    for (int i = 1; i <= n; i++) {
        k[i] = inf.readInt();
    }

    query_limit = (long long)n * (n - 1) + 1000;

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

    log_metrics();

    compute_blocks();

    bool answered_yes = false;
    set<pair<int, int>> history;

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF (did not receive final answer)");
        }

        if (token == "!") {
            int u, v;
            if (!(cin >> u >> v)) finish(_wa, "Invalid answer format");

            if (u == 0 && v == 0) {
                if (global_max_diff != -1) {
                    finish(_wa, "Contestant said no solution (! 0 0), but a pair exists");
                }
                finish(_ok, "Correct (no solution)");
            } else {
                if (u < 1 || u > n || v < 1 || v > n || u == v) {
                    finish(_wa, "Invalid indices in answer");
                }

                if (global_max_diff == -1) {
                    finish(_wa, "Contestant output a pair, but no valid pair exists");
                }

                if (block[u] != block[v]) {
                    finish(_wa, "Proposed pair is not bi-reachable");
                }

                int diff = abs(k[u] - k[v]);
                if (diff == global_max_diff) {
                    finish(_ok, "Correct");
                } else {
                    finish(_wa, "Not maximum difference");
                }
            }
        }
        else if (token == "?") {
            if (answered_yes) {
                finish(_wa, "Queries not allowed after receiving 'Yes'");
            }

            int u, v;
            if (!(cin >> u >> v)) finish(_wa, "Invalid query format");

            if (u < 1 || u > n || v < 1 || v > n || u == v) {
                finish(_wa, "Invalid indices in query");
            }

            if (history.count({u, v})) {
                finish(_wa, "Repeated query");
            }
            history.insert({u, v});

            queries++;

            if (queries > 300000) {
                finish(_pe, "Query limit exceeded hard cap");
            }

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

            bool result = (block[u] <= block[v]);

            cout << (result ? "Yes" : "No") << endl;

            if (result) answered_yes = true;
        }
        else {
            finish(_wa, "Invalid token (expected ? or !)");
        }
    }
}

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

using namespace std;

vector<vector<int>> gen_random_tournament(int n) {
    vector<vector<int>> adj(n, vector<int>(n, 0));
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (rnd.next(2)) {
                adj[i][j] = 1;
                adj[j][i] = 0;
            } else {
                adj[i][j] = 0;
                adj[j][i] = 1;
            }
        }
    }
    return adj;
}

vector<vector<int>> gen_blocks(int n) {
    vector<int> parts;
    int type = rnd.next(3);

    if (n < 5) type = 0;

    if (type == 0) {

        int rem = n;
        while (rem > 0) {
            int s = rnd.next(1, min(rem, 5));
            parts.push_back(s);
            rem -= s;
        }
    } else if (type == 1) {

        int k = rnd.next(2, max(2, min(n, 5)));
        parts = rnd.partition(k, n, 1);
    } else {

        int k = rnd.next(1, n);
        parts = rnd.partition(k, n, 1);
    }

    vector<vector<int>> adj(n, vector<int>(n, 0));

    int current = 0;
    for (int s : parts) {

        for (int i = current; i < current + s; i++) {
            for (int j = i + 1; j < current + s; j++) {
                if (rnd.next(2)) {
                    adj[i][j] = 1;
                } else {
                    adj[j][i] = 1;
                }
            }
        }

        for (int i = current; i < current + s; i++) {
            for (int j = current + s; j < n; j++) {
                adj[i][j] = 1;
            }
        }
        current += s;
    }

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

    vector<vector<int>> final_adj(n, vector<int>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            final_adj[p[i]][p[j]] = adj[i][j];
        }
    }
    return final_adj;
}

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

    string mode = opt<string>("mode", "non");
    long long seed_val = atoll(argv[1]);

    int n;

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

        if (rnd.next(3) == 0) n = rnd.next(3, 20);
        else n = rnd.next(21, 500);
    }

    vector<vector<int>> adj;

    if (seed_val == 1) {

        adj = vector<vector<int>>(3, vector<int>(3, 0));

        adj[0][1] = 1; adj[1][2] = 1; adj[0][2] = 1;

        vector<int> p(3); iota(p.begin(), p.end(), 0);
        shuffle(p.begin(), p.end());
        vector<vector<int>> permed(3, vector<int>(3));
        for(int i=0; i<3; ++i)
            for(int j=0; j<3; ++j)
                permed[p[i]][p[j]] = adj[i][j];
        adj = permed;
    }
    else if (seed_val == 2) {

        adj = gen_blocks(4);
    }
    else {

        if (rnd.next(100) < 30) {
            adj = gen_random_tournament(n);
        } else {
            adj = gen_blocks(n);
        }
    }

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

    cout << n << "\n";

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

    if (mode == "non") {

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

    return 0;
}