Problem: cf2037_e
Difficulty: easy
Categories: greedy
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem.

Kachina challenges you to guess her favorite binary string$^{\text{∗}}$ $s$ of length $n$. She defines $f(l, r)$ as the number of subsequences$^{\text{†}}$ of $\texttt{01}$ in $s_l s_{l+1} \ldots s_r$. Two subsequences are considered different if they are formed by deleting characters from different positions in the original string, even if the resulting subsequences consist of the same characters.

To determine $s$, you can ask her some questions. In each question, you can choose two indices $l$ and $r$ ($1 \leq l < r \leq n$) and ask her for the value of $f(l, r)$.

Determine and output $s$ after asking Kachina no more than $n$ questions. However, it may be the case that $s$ is impossible to be determined. In this case, you would need to report $\texttt{IMPOSSIBLE}$ instead.

Formally, $s$ is impossible to be determined if after asking $n$ questions, there are always multiple possible strings for $s$, regardless of what questions are asked. Note that if you report $\texttt{IMPOSSIBLE}$ when there exists a sequence of at most $n$ queries that will uniquely determine the binary string, you will get the Wrong Answer verdict.

$^{\text{∗}}$A binary string only contains characters $\texttt{0}$ and $\texttt{1}$.

$^{\text{†}}$A sequence $a$ is a subsequence of a sequence $b$ if $a$ can be obtained from $b$ by the deletion of several (possibly, zero or all) elements. For example, subsequences of $\mathtt{1011101}$ are $\mathtt{0}$, $\mathtt{1}$, $\mathtt{11111}$, $\mathtt{0111}$, but not $\mathtt{000}$ nor $\mathtt{11100}$.

Input

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

The first line of each test case contains a single integer $n$ ($2 \leq n \leq 10^4$) — the length of $s$.

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

Interaction

To ask a question, output a line in the following format (do not include quotes)

* "$\texttt{? l r}$" ($1 \leq l < r \leq n$)

The jury will return an integer $f(l, r)$.

When you are ready to print the answer, output a single line in the following format

* If $s$ is impossible to be determined, output "$\texttt{! IMPOSSIBLE}$"
* Otherwise, output "$\texttt{! s}$"

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

The interactor is not adaptive, meaning that the answer is known before the participant asks the queries and doesn't depend on the queries asked by the participant.

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

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

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

Example

Input

```
2
5

4

0

1

2

2

0
```

Output

```
? 1 5

? 2 4

? 4 5

? 3 5

! 01001

? 1 2

! IMPOSSIBLE
```

Note

In the first test case:

In the first query, you ask Kachina for the value of $f(1, 5)$, and she responds with $4$ in the input stream.

In the second query, you ask Kachina for the value of $f(2, 4)$. Because there are no subsequences of $\texttt{01}$ in the string $\texttt{100}$, she responds with $0$ in the input stream.

After asking $4$ questions, you report $\texttt{01001}$ as $s$, and it is correct.

In the second test case:

In the first query, you ask Kachina for the value of $f(1, 2)$, and she responds with $0$ in the input stream. Notice that this is the only distinct question you can ask.

However, notice that the strings $00$ and $11$ both have an answer of $0$, and it is impossible to differentiate between the two. Therefore, we report IMPOSSIBLE.

Please note that this example only serves to demonstrate the interaction format. It is not guaranteed the queries provided are optimal or uniquely determine the answer. However, it can be shown there exists a sequence of at most $5$ queries that does uniquely determine sample test case $1$.

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

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

static void log_metrics() {
    try {
        tout << "queries=" << queries << "\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 parseNonNegLL(const string& s, long long& out) {
    if (s.empty()) return false;
    long long val = 0;
    for (char c : s) {
        if (c < '0' || c > '9') return false;
        int d = c - '0';
        if (val > (LLONG_MAX - d) / 10) return false;
        val = val * 10 + d;
    }
    out = val;
    return true;
}

struct TestData {
    int n = 0;
    string s; 

    vector<long long> pref0, pref1, pref01; 

    void build() {
        pref0.assign(n + 1, 0);
        pref1.assign(n + 1, 0);
        pref01.assign(n + 1, 0);
        for (int i = 1; i <= n; i++) {
            char c = s[i - 1];
            pref0[i] = pref0[i - 1] + (c == '0');
            pref1[i] = pref1[i - 1] + (c == '1');
            pref01[i] = pref01[i - 1] + (c == '1' ? pref0[i - 1] : 0);
        }
    }

    long long f(int l, int r) const {
        
        long long total = pref01[r] - pref01[l - 1];
        long long zerosBefore = pref0[l - 1];
        long long onesInRange = pref1[r] - pref1[l - 1];
        return total - zerosBefore * onesInRange;
    }

    bool impossible() const {
        return f(1, n) == 0;
    }
};

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

    int t = 0;
    try {
        t = inf.readInt();
    } catch (...) {
        query_limit = 0;
        log_metrics();
        finish(_pe, "Bad hidden input: missing t");
    }
    if (t < 1 || t > 1000000) {
        query_limit = 0;
        log_metrics();
        finish(_pe, "Bad hidden input: invalid t");
    }

    vector<TestData> tests;
    tests.reserve(t);

    long long sumN = 0;
    for (int tc = 0; tc < t; tc++) {
        TestData td;
        td.n = inf.readInt();
        if (td.n < 2 || td.n > 1000000) finish(_pe, "Bad hidden input: invalid n");
        string tok;
        try {
            tok = inf.readToken();
        } catch (...) {
            finish(_pe, "Bad hidden input: missing s");
        }
        if ((int)tok.size() != td.n) finish(_pe, "Bad hidden input: s length != n");
        for (char c : tok) if (c != '0' && c != '1') finish(_pe, "Bad hidden input: s not binary");
        td.s = tok;
        td.build();
        sumN += td.n;
        tests.push_back(std::move(td));
    }

    query_limit = sumN;
    log_metrics(); 

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

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

    for (int tc = 0; tc < t; tc++) {
        const TestData& td = tests[tc];
        cout << td.n << "\n";
        cout.flush();

        while (true) {
            string op;
            if (!(cin >> op)) finish(_pe, "Unexpected EOF from contestant");

            if (op == "?") {
                string sl, sr;
                if (!(cin >> sl >> sr)) finish(_pe, "Malformed query: missing l/r");

                long long ll = -1, rr = -1;
                if (!parseNonNegLL(sl, ll) || !parseNonNegLL(sr, rr)) finish(_pe, "Malformed query: l/r not integers");

                if (ll < 1 || rr < 1 || ll > td.n || rr > td.n || ll >= rr) finish(_pe, "Query indices out of range");

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

                long long ans = td.f((int)ll, (int)rr);
                cout << ans << "\n";
                cout.flush();
            } else if (op == "!") {
                string ans;
                if (!(cin >> ans)) finish(_pe, "Malformed answer: missing token");

                bool isImp = (ans == "IMPOSSIBLE");
                bool hiddenImp = td.impossible();

                if (isImp) {
                    if (!hiddenImp) finish(_wa, "Answered IMPOSSIBLE but solution exists");
                } else {
                    if ((int)ans.size() != td.n) finish(_wa, "Wrong length answer");
                    for (char c : ans) if (c != '0' && c != '1') finish(_pe, "Answer is not a binary string");
                    if (hiddenImp) finish(_wa, "Expected IMPOSSIBLE");
                    if (ans != td.s) finish(_wa, "Wrong string");
                }
                break;
            } else {
                finish(_pe, "Unknown operation (expected ? or !)");
            }
        }
    }

    finish(_ok, "OK");
}


Adaptive interactor (C++):

Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static string buildImpossible(int n) {
    int onesPrefix = rnd.next(0, n); 
    string s;
    s.append(onesPrefix, '1');
    s.append(n - onesPrefix, '0');
    return s;
}

static string buildHardSolvable(int n, long long seed) {
    if (n == 2) return "01";
    if (n == 3) return "001";

    int A = (int)(n * 45LL / 100LL) + rnd.next(0, max(1, n / 20));
    A = min(A, n - 2);

    int B = (int)(n * 45LL / 100LL) + rnd.next(0, max(1, n / 20));
    if (A + B + 1 > n) B = n - A - 1;
    if (B < 1) {
        B = 1;
        A = min(A, n - 2);
        if (A + B + 1 > n) A = max(0, n - B - 1);
    }

    string s;
    s.reserve(n);

    s.append(A, '1');
    s.append(B, '0');
    s.push_back('1'); 

    int remaining = n - (int)s.size();
    int curBit = 0; 
    int blocks = 0;
    while (remaining > 0) {
        int cap = (blocks < 2 ? 80 : 18);
        int maxLen = min(remaining, cap);
        int len = rnd.next(1, maxLen);
        s.append(len, curBit ? '1' : '0');
        remaining -= len;
        blocks++;

        int p = rnd.next(0, 99);
        if (curBit == 0) {
            if (p < 35) curBit = 1;
        } else {
            if (p < 70) curBit = 0;
        }
    }

    
    int suf = min(n, 200);
    if (n >= 10) {
        int start = n - suf;
        char first = (seed & 1LL) ? '0' : '1';
        for (int i = start; i < n; i++) {
            s[i] = ((i - start) & 1) ? (first == '0' ? '1' : '0') : first;
        }
        
        
    }

    if ((int)s.size() != n) s.resize(n, '0');
    return s;
}

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

    string mode = opt<string>("mode", "non");
    int nArg = opt<int>("n", -1);
    int minn = opt<int>("minn", 2);
    int maxn = opt<int>("maxn", 10000);
    int impossibleArg = opt<int>("impossible", 0);

    ensuref(mode == "non" || mode == "adp", "Unknown --mode (expected non/adp)");
    ensuref(minn >= 2, "--minn must be >= 2");
    ensuref(maxn >= minn, "--maxn must be >= --minn");
    maxn = min(maxn, 10000);

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

    int n;
    if (seed == 1) n = 2;
    else if (seed == 2) n = 2;
    else if (seed == 3) n = 7;
    else {
        if (nArg != -1) n = nArg;
        else {
            int lo = max(minn, maxn - 2000);
            int hi = maxn;
            n = (seed % 13 == 0) ? maxn : rnd.next(lo, hi);
        }
    }
    n = max(n, 2);
    n = min(n, 10000);

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

    
    string s;
    if (seed == 1) {
        s = "01";
    } else if (seed == 2) {
        s = "00"; 
    } else if (seed == 3) {
        s = "1110001"; 
    } else {
        bool makeImpossible = (impossibleArg != 0) || (seed % 11 == 0);
        if (makeImpossible) s = buildImpossible(n);
        else s = buildHardSolvable(n, seed);
    }

    ensuref((int)s.size() == n, "Internal error: s.size()!=n");
    cout << n << "\n";
    cout << s << "\n";
    return 0;
}