This is an interactive problem.

Jury initially had a sequence $a$ of length $n$, such that $a_i = i$.

The jury chose three integers $i$, $j$, $k$, such that $1 \leq i < j < k \leq n$, $j - i > 1$. After that, Jury reversed subsegments $[i, j - 1]$ and $[j, k]$ of the sequence $a$.

Reversing a subsegment $[l, r]$ of the sequence $a$ means reversing the order of elements $a_l, a_{l+1}, \ldots, a_r$ in the sequence, i. e. $a_l$ is swapped with $a_r$, $a_{l+1}$ is swapped with $a_{r-1}$, etc.

You are given the number $n$ and you should find $i$, $j$, $k$ after asking some questions.

In one question you can choose two integers $l$ and $r$ ($1 \leq l \leq r \leq n$) and ask the number of inversions on the subsegment $[l, r]$ of the sequence $a$. You will be given the number of pairs $(i, j)$ such that $l \leq i < j \leq r$, and $a_i > a_j$.

Find the chosen numbers $i$, $j$, $k$ after at most $40$ questions.

The numbers $i$, $j$, and $k$ are fixed before the start of your program and do not depend on your queries.

Input

Each test consists of multiple test cases. The first line contains a single integer $t$ ($1 \leq t \leq 100$) — the number of test cases. Description of the test cases follows.

The single line of each test case contains a single integer $n$ ($4 \leq n \leq 10^9$). After reading it you should start an interaction process by asking questions for that test case. After giving an answer you should:

* Terminate your program if that is the last test case.
* Proceed to the next test case otherwise.

Interaction

To ask number of inversions on a subsegment $[l, r]$, print "? l r", where ($1 \leq l \leq r \leq n$). You can ask at most $40$ questions in each test case. As a result you should read a single integer $x$.

* If $x = -1$, your program made an invalid question or you exceeded the number of questions for that test case. Your program should terminate immediately (otherwise it can get any verdict instead of "Wrong Answer").
* Otherwise $x$ is equal to the number of inversions on the subsegment $[l, r]$ of the sequence $a$.

To give the answer, print "! i j k", where $i$, $j$, $k$ are the numbers you found. You should continue solving the next test cases or terminate the program after that.

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

3

3

5

2

2

1
```

Output

```
? 1 5

? 2 5

? 3 5

! 1 3 5

? 1 5

? 2 5

? 3 5

! 2 4 5
```

Note

In the first test case, $i = 1$, $j = 3$, $k = 5$, so the sequence $a$ is $[2, 1, 5, 4, 3]$.

In the second test case, $i = 2$, $j = 4$, $k = 5$, so the sequence $a$ is $[1, 3, 2, 5, 4]$.

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

struct Triple {
    long long i;
    long long j;
    long long k;
};

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 (...) {

    }
}

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

static long long choose2(long long x) {
    if (x <= 1) return 0;
    return x * (x - 1) / 2;
}

static long long isect_len(long long l, long long r, long long a, long long b) {
    long long L = max(l, a);
    long long R = min(r, b);
    if (L > R) return 0;
    return R - L + 1;
}

static long long inversions_on_segment(long long l, long long r, const Triple& t) {
    long long len1 = isect_len(l, r, t.i, t.j - 1);
    long long len2 = isect_len(l, r, t.j, t.k);
    return choose2(len1) + choose2(len2);
}

static void validate_hidden(long long n, const Triple& t) {
    if (!(1 <= t.i && t.i < t.j && t.j < t.k && t.k <= n)) {
        finish(_fail, "Invalid hidden triple bounds");
    }
    if (t.j - t.i <= 1) {
        finish(_fail, "Invalid hidden triple: j-i must be > 1");
    }
}

static void run_one_test(long long n, const Triple& t) {
    int used = 0;
    string cmd;
    while (cin >> cmd) {
        if (cmd == "?") {
            long long l, r;
            if (!(cin >> l >> r)) finish(_pe, "Invalid query format");
            if (!(1 <= l && l <= r && r <= n)) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Query out of range");
            }

            used++;
            queries++;
            if (used > 40) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Query limit exceeded");
            }

            cout << inversions_on_segment(l, r, t) << "\n";
            cout.flush();
            continue;
        }

        if (cmd == "!") {
            long long i, j, k;
            if (!(cin >> i >> j >> k)) finish(_pe, "Invalid answer format");
            if (i == t.i && j == t.j && k == t.k) {
                return;
            }
            finish(_wa, "Wrong answer");
        }

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

    finish(_pe, "Unexpected EOF");
}

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

    const int tc = inf.readInt(1, 100, "t");
    query_limit = 40LL * tc;

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

    for (int ti = 0; ti < tc; ti++) {
        const long long n = inf.readLong(4, 1000000000LL, "n");
        Triple t;
        t.i = inf.readLong(1, n, "i");
        t.j = inf.readLong(1, n, "j");
        t.k = inf.readLong(1, n, "k");
        validate_hidden(n, t);

        cout << n << "\n";
        cout.flush();
        run_one_test(n, t);
    }

    finish(_ok, "OK");
}

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

struct Triple {
    long long i;
    long long j;
    long long k;
};

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 (...) {

    }
}

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

static long long choose2(long long x) {
    if (x <= 1) return 0;
    return x * (x - 1) / 2;
}

static long long isect_len(long long l, long long r, long long a, long long b) {
    long long L = max(l, a);
    long long R = min(r, b);
    if (L > R) return 0;
    return R - L + 1;
}

static long long inversions_on_segment(long long l, long long r, const Triple& t) {
    long long len1 = isect_len(l, r, t.i, t.j - 1);
    long long len2 = isect_len(l, r, t.j, t.k);
    return choose2(len1) + choose2(len2);
}

static long long parse_case_id(const char* case_path) {
    string s(case_path ? case_path : "");
    size_t slash = s.find_last_of("/\\");
    if (slash != string::npos) s = s.substr(slash + 1);
    size_t dot = s.find_last_of('.');
    if (dot != string::npos) s = s.substr(0, dot);
    long long id = 0;
    bool any = false;
    for (unsigned char ch : s) {
        if (isdigit(ch)) {
            any = true;
            id = id * 10 + (ch - '0');
        }
    }
    return any ? id : 0;
}

static Triple gen_triple(long long n) {

    long long total = rnd.next(4LL, n);
    long long L1 = rnd.next(2LL, total - 2);
    long long L2 = total - L1;
    long long i = rnd.next(1LL, n - total + 1);
    Triple t;
    t.i = i;
    t.j = i + L1;
    t.k = t.j + L2 - 1;
    return t;
}

static void run_one_test(long long n, const Triple& t) {
    int used = 0;
    string cmd;
    while (cin >> cmd) {
        if (cmd == "?") {
            long long l, r;
            if (!(cin >> l >> r)) finish(_pe, "Invalid query format");
            if (!(1 <= l && l <= r && r <= n)) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Query out of range");
            }

            used++;
            queries++;
            if (used > 40) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Query limit exceeded");
            }

            cout << inversions_on_segment(l, r, t) << "\n";
            cout.flush();
            continue;
        }

        if (cmd == "!") {
            long long i, j, k;
            if (!(cin >> i >> j >> k)) finish(_pe, "Invalid answer format");
            if (i == t.i && j == t.j && k == t.k) return;
            finish(_wa, "Wrong answer");
        }

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

    finish(_pe, "Unexpected EOF");
}

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

    long long case_id = (argc >= 2) ? parse_case_id(argv[1]) : 0;

    const int tc = inf.readInt(1, 100, "t");
    query_limit = 40LL * tc;

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

    for (int ti = 0; ti < tc; ti++) {
        const long long n = inf.readLong(4, 1000000000LL, "n");
        rnd.setSeed(1000003LL * (case_id + 1) + 97LL * (ti + 1) + n);
        const Triple t = gen_triple(n);
        if (!(1 <= t.i && t.i < t.j && t.j < t.k && t.k <= n && t.j - t.i > 1)) {
            finish(_fail, "Internal error: generated invalid triple");
        }

        cout << n << "\n";
        cout.flush();
        run_one_test(n, t);
    }

    finish(_ok, "OK");
}

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

static long long clampLL(long long x, long long lo, long long hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

struct Triple {
    long long i, j, k;
};

static Triple makeFromLengths(long long i, long long L1, long long L2) {
    Triple t;
    t.i = i;
    t.j = i + L1;
    t.k = t.j + L2 - 1;
    return t;
}

static void ensureValid(long long n, const Triple& t) {
    ensuref(1 <= t.i && t.i < t.j && t.j < t.k && t.k <= n, "Invalid i<j<k or bounds");
    ensuref(t.j - t.i > 1, "Invalid: j-i must be > 1");
}

static long long pickTotalLenCloseToN(long long n) {
    long long slack = min(2000LL, n - 4);
    if (slack < 0) slack = 0;
    long long totalLen = n - rnd.next(0LL, slack);
    if (totalLen < 4) totalLen = 4;
    if (totalLen > n) totalLen = n;
    return totalLen;
}

static Triple genNonHandcrafted(long long seedVal) {
    if (seedVal == 1) {
        long long n = 4;
        return {1, 3, 4};
    }
    if (seedVal == 2) {

        return {1, 4, 5};
    }
    if (seedVal == 3) {

        return {333333333LL, 666666666LL, 1000000000LL};
    }
    if (seedVal == 4) {

        return {1, 6, 9};
    }
    return {-1, -1, -1};
}

static pair<long long, Triple> genNonRandom(long long nmin, long long nmax, long long nFixed, int patternForced, long long seedVal) {
    long long n;
    if (nFixed != -1) {
        n = nFixed;
    } else if (seedVal == 1) {
        n = 4;
    } else if (seedVal == 2) {
        n = 5;
    } else if (seedVal == 3) {
        n = 1000000000LL;
    } else if (seedVal == 4) {
        n = 9;
    } else {

        int roll = rnd.next(0, 99);
        if (roll < 75) {
            long long lo = max(nmin, nmax - 1000000LL);
            n = rnd.next(lo, nmax);
        } else if (roll < 95) {
            long long lo = max(nmin, 1000000LL);
            n = rnd.next(lo, nmax);
        } else {
            long long hi = min(nmax, 1000000LL);
            if (hi < nmin) hi = nmin;
            n = rnd.next(nmin, hi);
        }
        n = clampLL(n, nmin, nmax);
        if (n < 4) n = 4;
    }

    Triple hand = genNonHandcrafted(seedVal);
    if (hand.i != -1) {
        ensureValid(n, hand);
        return {n, hand};
    }

    int pattern = patternForced;
    if (pattern == -1) pattern = rnd.next(0, 7);

    long long L1 = 2, L2 = 2;
    long long i = 1;

    auto pickIForTotalLen = [&](long long totalLen) -> long long {
        long long maxStart = n - totalLen + 1;
        if (maxStart <= 1) return 1;
        if (maxStart <= 3) return rnd.next(1LL, maxStart);

        long long center = (maxStart + 1) / 2;
        long long delta = min(1000000LL, center - 1);
        long long lo = center - delta;
        long long hi = min(maxStart, center + delta);
        if (lo > hi) lo = 1, hi = maxStart;
        return rnd.next(lo, hi);
    };

    if (pattern == 0) {

        long long totalLen = pickTotalLenCloseToN(n);
        L1 = rnd.next(2LL, totalLen - 2);
        L2 = totalLen - L1;
        i = 1;
    } else if (pattern == 1) {

        long long totalLen = pickTotalLenCloseToN(n);
        L2 = rnd.next(2LL, totalLen - 2);
        L1 = totalLen - L2;
        i = n - totalLen + 1;
    } else if (pattern == 2) {

        long long totalLenLo = max(4LL, n / 2);
        long long totalLenHi = n;
        long long totalLen = rnd.next(totalLenLo, totalLenHi);
        if (totalLen < 4) totalLen = 4;
        if (totalLen > n) totalLen = n;

        long long loL1 = max(2LL, totalLen / 3);
        long long hiL1 = totalLen - 2;
        if (loL1 > hiL1) loL1 = 2, hiL1 = totalLen - 2;
        L1 = rnd.next(loL1, hiL1);
        L2 = totalLen - L1;
        i = pickIForTotalLen(totalLen);
    } else if (pattern == 3) {

        L1 = 2;
        long long maxL2 = n - L1;
        if (maxL2 < 2) { L1 = 2; L2 = 2; i = 1; }
        else {
            long long L2lo = max(2LL, maxL2 - 2000LL);
            long long L2hi = maxL2;
            L2 = rnd.next(L2lo, L2hi);
            long long totalLen = L1 + L2;
            i = pickIForTotalLen(totalLen);
        }
    } else if (pattern == 4) {

        L2 = 2;
        long long maxL1 = n - L2;
        if (maxL1 < 2) { L1 = 2; L2 = 2; i = 1; }
        else {
            long long L1lo = max(2LL, maxL1 - 2000LL);
            long long L1hi = maxL1;
            L1 = rnd.next(L1lo, L1hi);
            long long totalLen = L1 + L2;
            i = pickIForTotalLen(totalLen);
        }
    } else if (pattern == 5) {

        L1 = 5; L2 = 4;
        long long totalLen = L1 + L2;
        if (n < totalLen) {
            n = totalLen;
        }
        i = pickIForTotalLen(totalLen);
    } else if (pattern == 6) {

        L1 = 1000000LL + rnd.next(0LL, 12345LL);
        L2 = 1000000LL + rnd.next(0LL, 12345LL);
        long long totalLen = L1 + L2;
        if (totalLen > n) {

            totalLen = min(n, max(4LL, n - rnd.next(0LL, min(1000LL, n - 4))));
            L1 = max(2LL, totalLen / 2);
            L2 = totalLen - L1;
            if (L2 < 2) { L2 = 2; L1 = totalLen - 2; }
        }
        i = pickIForTotalLen(L1 + L2);
    } else {

        long long totalLen = rnd.next(4LL, n);
        if (totalLen < 4) totalLen = 4;
        if (totalLen > n) totalLen = n;
        L1 = rnd.next(2LL, totalLen - 2);
        L2 = totalLen - L1;
        i = rnd.next(1LL, n - totalLen + 1);
    }

    if (L1 < 2) L1 = 2;
    if (L2 < 2) L2 = 2;
    if (L1 + L2 > n) {
        long long totalLen = n;
        L1 = max(2LL, totalLen / 2);
        L2 = totalLen - L1;
        if (L2 < 2) { L2 = 2; L1 = totalLen - 2; }
        i = 1;
    }

    Triple t = makeFromLengths(i, L1, L2);
    ensureValid(n, t);
    return {n, t};
}

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    string mode = opt<string>("mode", "non");

    long long nmin = opt<long long>("nmin", 4LL);
    long long nmax = opt<long long>("nmax", 1000000000LL);
    long long nFixed = opt<long long>("n", -1LL);
    int patternForced = opt<int>("pattern", -1);

    if (nmin < 4) nmin = 4;
    if (nmax < nmin) nmax = nmin;

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

    if (mode != "non" && mode != "adp") {
        quitf(_fail, "Unknown --mode: %s (expected non/adp)", mode.c_str());
    }

    cout << 1 << "\n";

    if (mode == "adp") {
        long long n;
        if (nFixed != -1) n = nFixed;
        else if (seedVal == 1) n = 4;
        else if (seedVal == 2) n = 5;
        else if (seedVal == 3) n = 1000000000LL;
        else {
            int roll = rnd.next(0, 99);
            if (roll < 85) {
                long long lo = max(nmin, nmax - 1000000LL);
                n = rnd.next(lo, nmax);
            } else {
                n = rnd.next(nmin, nmax);
            }
        }
        n = clampLL(n, nmin, nmax);
        if (n < 4) n = 4;
        cout << n << "\n";
        return 0;
    }

    auto [n, t] = genNonRandom(nmin, nmax, nFixed, patternForced, seedVal);
    cout << n << " " << t.i << " " << t.j << " " << t.k << "\n";
    return 0;
}


After years of planning and construction, you finally succeeded in making your own spacecraft! Immediately hopping aboard, you take the spaceship on a maiden voyage to the Big Anthropomorphic Pig Constellation. After a couple of years, you reach the constellation and land on the nearest planet to take some pictures and hopefully score some souvenirs. While haggling with a local souvenir seller using the built-in translator of your spacecraft, you are suddenly notified that the craft is low on fuel! Your extensive use of the translator has drained more fuel than expected, and you cannot get back to Earth. Frantically, you look for a refuelling station. Luckily, a local points you to a shady store, strikingly similar to the petrol stations you know from home.

![](images/b5252c04ee6fc2b3d4ea3a874c18fff1300914c2841f2665cc66154f8268b6bb.jpg)
The inspiration for your spaceship. CC BY-SA 3.0 by Edwtie on Wikimedia Commons

While the outside of the refuelling station may look similar to those on Earth, the inside is completely different. On a long shelf are a number of fuel canisters, with strange symbols on the side. From your research on rocket fuel, you deduce that these symbols probably denote the oxydilation level of the fuel in the canister. None of the rocket fuels burn on their own. Instead, combining two rocket fuels with oxydilation levels $o _ { x }$ and $o _ { y }$ yields a fuel with burn time $\sqrt { \left| o _ { x } - o _ { y } \right| }$ . You can afford to buy three full canisters, and the burn time of rocket fuel is additive, so that combining rocket fuels with oxydilation levels $o _ { x }$ , $o _ { y }$ and $o _ { z }$ results in a total burn time of

$$
\sqrt { | o _ { x } - o _ { y } | } + \sqrt { | o _ { y } - o _ { z } | } + \sqrt { | o _ { z } - o _ { x } | } .
$$

You can only decode the symbols denoting the oxydilation levels with the translator of your spacecraft. Unfortunately, due to the low fuel levels of the spacecraft, you can only use your translator for 50 items, before the fuel fully runs out. Luckily, you know that rocket fuel is always stored in non-decreasing order of oxydilation levels. Can you figure out which three canisters of rocket fuel to buy to maximize total burn time?

# Interaction

This is an interactive problem. Your submission will be run against an interactor, which reads from 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$ ( $3 \leq n \leq 2 \cdot 1 0 ^ { 5 }$ ), the number of types of rocket fuel.

Then, your program should make at most 50 queries to find the optimal three fuel canisters. Each query is made by printing one line of the form $\begin{array} { r l } { ^ { 6 6 } ? } & { { } i ^ { 9 } } \end{array}$ ( $1 \leq i \leq n$ ). The interactor will respond with one line with an integer $o _ { i }$ ( $\left| o _ { i } \right| \le 1 0 ^ { 6 }$ ), the oxydilation value of the fuel in the $_ i$ th canister.

When you have determined the optimal three distinct canisters $x$ , $y$ , and $z$ ( $1 \leq x , y , z \leq n$ , $x \neq y$ , $x \neq z$ , $y \ne z$ ), print one line of the form “! $x$ y $z ^ { \dag }$ , 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 oxydilation levels of the fuel canisters are fixed up front, and do 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 50 queries will result in a wrong answer.

![](images/397fef922c4051b2c900399c2f7116c17ad3d9fc1d5e366138f23e57fa18c18a.jpg)

![](images/23b44cc66da72db561b69dcbbb72d414a1022948389afb3dfef824340d1ed4f4.jpg)

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

static long long queries = 0;
static long long query_limit = 50;
static const long long HARD_CAP = 2000;

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

    }
}

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

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

    registerInteraction(argc, argv);

    atexit(log_metrics);
    log_metrics();

    int n = inf.readInt(3, 200000, "n");
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        a[i] = inf.readInt(-1000000, 1000000, format("a[%d]", i).c_str());
    }

    double max_score = -1.0;
    double base_term = sqrt((double)abs(a[n] - a[1]));

    if (n == 3) {

        max_score = base_term + sqrt((double)abs(a[2] - a[1])) + sqrt((double)abs(a[n] - a[2]));
    } else {

        for (int j = 2; j < n; j++) {
            double current_score = base_term + sqrt((double)abs(a[j] - a[1])) + sqrt((double)abs(a[n] - a[j]));
            if (current_score > max_score) {
                max_score = current_score;
            }
        }
    }

    cout << n << endl;

    while (true) {

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

        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF: contestant did not provide an answer.");
        }

        if (token == "!") {

            int x, y, z;
            if (!(cin >> x >> y >> z)) {
                finish(_pe, "Malformed answer: expected 3 integers.");
            }

            if (x < 1 || x > n || y < 1 || y > n || z < 1 || z > n) {
                finish(_wa, format("Indices (%d, %d, %d) out of bounds [1, %d].", x, y, z, n));
            }
            if (x == y || x == z || y == z) {
                finish(_wa, "Indices must be distinct.");
            }

            double user_score = sqrt((double)abs(a[x] - a[y])) +
                                sqrt((double)abs(a[y] - a[z])) +
                                sqrt((double)abs(a[z] - a[x]));

            if (user_score >= max_score - 1e-7) {
                finish(_ok, format("Correct! Score: %.9f", user_score));
            } else {
                finish(_wa, format("Suboptimal solution. User: %.9f, Optimal: %.9f", user_score, max_score));
            }
        } else {

            queries++;

            int idx;
            bool valid = false;

            if (token == "?") {
                if (cin >> idx) valid = true;
            } else {
                try {
                    size_t pos;
                    idx = stoi(token, &pos);
                    if (pos == token.size()) valid = true;
                } catch (...) {
                    valid = false;
                }
            }

            if (!valid) {
                finish(_pe, format("Invalid query format. Token: '%s'", token.c_str()));
            }

            if (idx < 1 || idx > n) {
                finish(_wa, format("Query index %d out of bounds [1, %d].", idx, n));
            }

            cout << a[idx] << endl;
        }
    }

    return 0;
}

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

using namespace std;

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

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

    int seed_int = 0;
    if (argc > 1) {
        try {
            seed_int = stoi(string(argv[1]));
        } catch (...) {
            seed_int = 0;
        }
    }

    const int MIN_VAL = -1000000;
    const int MAX_VAL = 1000000;
    const int LIMIT_N = 200000;

    int n = n_opt;
    if (n == -1) {

        if (seed_int >= 1 && seed_int <= 5) {
            if (seed_int == 1) n = 3;
            else if (seed_int == 2) n = 4;
            else if (seed_int == 3) n = 10;
            else if (seed_int == 4) n = 50;
            else n = LIMIT_N;
        } else {

            int t = rnd.next(10);
            if (t < 2) n = rnd.next(3, 100);
            else if (t < 4) n = rnd.next(100, 5000);
            else n = rnd.next(LIMIT_N - 20000, LIMIT_N);
        }
    }

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

    vector<int> a(n);
    int type = 0;

    if (seed_int >= 1 && seed_int <= 6) type = seed_int;
    else type = rnd.next(1, 8);

    if (type == 1) {

        for (int i = 0; i < n; i++) a[i] = rnd.next(MIN_VAL, MAX_VAL);
    } else if (type == 2) {

        for (int i = 0; i < n; i++) {
            if (rnd.next(2)) a[i] = rnd.next(MIN_VAL, MIN_VAL + 2000);
            else a[i] = rnd.next(MAX_VAL - 2000, MAX_VAL);
        }
    } else if (type == 3) {

        int mid = (MIN_VAL + MAX_VAL) / 2;
        a[0] = mid;
        for (int i = 1; i < n; i++) {
            if (rnd.next(2)) a[i] = rnd.next(MIN_VAL, MIN_VAL + 5000);
            else a[i] = rnd.next(MAX_VAL - 5000, MAX_VAL);
        }
    } else if (type == 4) {

        for (int i = 0; i < n; i++) {
            double p = rnd.next(0.0, 1.0);
            p = p * p * p;
            if (rnd.next(2)) a[i] = MIN_VAL + (int)(p * (MAX_VAL - MIN_VAL));
            else a[i] = MAX_VAL - (int)(p * (MAX_VAL - MIN_VAL));
        }
    } else if (type == 5) {

        int k = rnd.next(3, 10);
        vector<int> centers(k);
        for(int &c : centers) c = rnd.next(MIN_VAL, MAX_VAL);
        for(int i = 0; i < n; i++) {
            a[i] = centers[rnd.next(k)] + rnd.next(-500, 500);
            a[i] = max(MIN_VAL, min(MAX_VAL, a[i]));
        }
    } else if (type == 6) {

        long long step = (long long)(MAX_VAL - MIN_VAL) / (n > 1 ? n - 1 : 1);
        if (step == 0) step = 1;
        long long cur = MIN_VAL;
        for(int i=0; i<n; i++) {
            a[i] = (int)min((long long)MAX_VAL, cur);
            cur += step;
            if (rnd.next(5) == 0) cur += rnd.next(-10, 10);
        }
    } else {

        for (int i = 0; i < n; i++) a[i] = rnd.next(MIN_VAL, MAX_VAL);
    }

    if (n == 3 && type == 1) {
        a[0] = MIN_VAL; a[1] = 0; a[2] = MAX_VAL;
    }

    for (int& x : a) x = max(MIN_VAL, min(MAX_VAL, x));

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

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

    return 0;
}


This is an interactive problem.

There is an $n$ by $n$ grid of conveyor belts, in positions $(1, 1)$ through $(n, n)$ of a coordinate plane. Every other square in the plane is empty. Each conveyor belt can be configured to move boxes up ('^'), down ('v'), left ('<'), or right ('>'). If a box moves onto an empty square, it stops moving.

However, one of the $n^2$ belts is stuck, and will always move boxes in the same direction, no matter how it is configured. Your goal is to perform a series of tests to determine which conveyor belt is stuck, and the direction in which it sends items.

To achieve this, you can perform up to $25$ tests. In each test, you assign a direction to all $n^2$ belts, place a box on top of one of them, and then turn all of the conveyors on.

![](https://espresso.codeforces.com/3914cfd55bb4a91bdd525023ad83966f6c6a23cc.png)One possible result of a query with $n=4$. In this case, the box starts at $(2, 2)$. If there were no stuck conveyor, it would end up at $(5, 4)$, but because of the stuck '>' conveyor at $(3, 3)$, it enters an infinite loop.

The conveyors move the box around too quickly for you to see, so the only information you receive from a test is whether the box eventually stopped moving, and if so, the coordinates of its final position.

Interaction

You begin the interaction by reading a single integer $n$ ($2 \le n\le 100$) — the number of rows and columns in the grid.

Then, you can make at most $25$ queries.

Each query should begin with a line of the form ? r c, where r and c are the initial row and column of the box, respectively.

The next $n$ lines of the query should contain $n$ characters each. The $j$th character of the $i$th row should be one of '^', 'v', '<', or '>', indicating the direction of conveyor $(i, j)$ for this query.

After each query, you will receive two integers $x$ and $y$. If $x = y = -1$, then the box entered an infinite loop. Otherwise, its final position was $(x, y)$.

If you make too many queries or make an invalid query, you will receive the Wrong Answer verdict.

After you have found the stuck conveyor and its direction, print a single line ! r c dir, where r and c are the row and column of the stuck conveyor, respectively, and dir is one of '^', 'v', '<', or '>', indicating the direction of the stuck conveyor. Note that printing this answer does not count towards your total of $25$ queries. After printing this line, your program should terminate.

The interactor is non-adaptive. This means that the location and direction of the stuck belt is fixed at the start of the interaction, and does not change after the queries.

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

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

Examples

Input

```
3

-1 -1

0 2
```

Output

```
? 2 2
>><
>>v
^<<

? 1 1
>><
>>v
^<<

! 1 2 ^
```

Input

```
4

-1 -1
```

Output

```
? 2 2
v>v<
^v<v
v>v^
>v>v

! 3 3 >
```

Note

For the first query of the first sample input, the box starts on $(2, 2)$ and enters an infinite loop containing rows $2$ and $3$. Because the stuck conveyor is in row $1$, it does not affect the outcome of the query.

For the second query of the first sample input, the conveyors are configured in the same way, but the box starts on $(1, 1)$. If there were no stuck conveyor, it would enter an infinite loop between $(1, 2)$ and $(1, 3)$. However, the stuck conveyor redirects it to $(0, 2)$.

After these two queries, the program is able to determine that the stuck conveyor is at $(1, 2)$ and directs items upward.

The query for the second sample input corresponds to the picture above. After asking the query, there are many possibilities for the stuck conveyor, but the program correctly guesses that it is at $(3, 3)$ and directs items to the right.

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

using namespace std;

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

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

    }
}

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

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

    registerInteraction(argc, argv);

    atexit(log_metrics);

    int n = inf.readInt(2, 100, "n");
    int h_r = inf.readInt(1, n, "hidden_r");
    int h_c = inf.readInt(1, n, "hidden_c");
    string h_dir_str = inf.readToken("[\\^v<>]+", "hidden_dir");
    char h_dir = h_dir_str[0];

    log_metrics();

    cout << n << endl;

    string token;
    while (cin >> token) {
        if (token == "!") {

            int ans_r, ans_c;
            string ans_dir_str;
            if (!(cin >> ans_r >> ans_c >> ans_dir_str)) {
                finish(_pe, "Invalid answer format: expected 'r c dir' after '!'");
            }

            char ans_dir = ans_dir_str.empty() ? '?' : ans_dir_str[0];

            if (ans_r == h_r && ans_c == h_c && ans_dir == h_dir) {
                finish(_ok, "Correct stuck conveyor location and direction");
            } else {
                finish(_wa, format("Incorrect answer. Expected (%d, %d, %c), Got (%d, %d, %c)",
                                   h_r, h_c, h_dir, ans_r, ans_c, ans_dir));
            }

        } else {

            int q_r, q_c;
            if (token == "?") {
                if (!(cin >> q_r >> q_c)) {
                    finish(_pe, "Invalid query format: expected 'r c' after '?'");
                }
            } else {

                try {
                    q_r = stoi(token);
                } catch (...) {
                    finish(_pe, format("Expected '?' or integer row index, got '%s'", token.c_str()));
                }
                if (!(cin >> q_c)) {
                    finish(_pe, "Invalid query format: expected column index after row");
                }
            }

            vector<string> grid(n);
            for (int i = 0; i < n; ++i) {
                if (!(cin >> grid[i])) {
                    finish(_pe, "Unexpected end of input while reading grid");
                }
                if ((int)grid[i].length() != n) {
                    finish(_pe, format("Grid row %d length is %d, expected %d", i + 1, (int)grid[i].length(), n));
                }

                for (char c : grid[i]) {
                    if (c != '^' && c != 'v' && c != '<' && c != '>') {
                        finish(_pe, format("Invalid character '%c' in grid", c));
                    }
                }
            }

            if (q_r < 1 || q_r > n || q_c < 1 || q_c > n) {
                finish(_wa, format("Query start position (%d, %d) is out of bounds [1, %d]", q_r, q_c, n));
            }

            queries++;

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

            int curr_r = q_r;
            int curr_c = q_c;

            static vector<vector<bool>> vis;
            vis.assign(n + 1, vector<bool>(n + 1, false));

            bool infinite_loop = false;
            while (true) {

                if (curr_r < 1 || curr_r > n || curr_c < 1 || curr_c > n) {
                    break;
                }

                if (vis[curr_r][curr_c]) {
                    infinite_loop = true;
                    break;
                }
                vis[curr_r][curr_c] = true;

                char d;
                if (curr_r == h_r && curr_c == h_c) {
                    d = h_dir;
                } else {
                    d = grid[curr_r - 1][curr_c - 1];
                }

                if (d == '^') curr_r--;
                else if (d == 'v') curr_r++;
                else if (d == '<') curr_c--;
                else if (d == '>') curr_c++;
            }

            if (infinite_loop) {
                cout << "-1 -1" << endl;
            } else {
                cout << curr_r << " " << curr_c << endl;
            }

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

    finish(_wa, "Unexpected EOF: solution terminated without providing an answer");
    return 0;
}

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

using namespace std;

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

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

    long long seedVal = 0;
    bool isHandCrafted = false;
    if (argc > 1) {
        try {
            seedVal = stoll(string(argv[1]));
            if (seedVal >= 1 && seedVal <= 3) {
                isHandCrafted = true;
            }
        } catch (...) {

        }
    }

    if (n == -1) {
        if (isHandCrafted) {
            if (seedVal == 1) n = 2;
            else n = 100;
        } else {

            if (rnd.next(10) == 0) {
                n = rnd.next(2, 100);
            } else {
                n = rnd.wnext(2, 100, 15);
            }
        }
    }

    cout << n << endl;

    if (mode == "non") {

        int r, c;
        char dir;
        string dirs = "^v<>";

        if (isHandCrafted) {
            if (seedVal == 1) {

                r = 1; c = 1; dir = '^';
            } else if (seedVal == 2) {

                r = n; c = n; dir = '>';
            } else {

                r = n / 2; c = n / 2; dir = 'v';
            }
        } else {

            r = rnd.next(1, n);
            c = rnd.next(1, n);
            dir = dirs[rnd.next(4)];
        }
        cout << r << " " << c << " " << dir << endl;
    }

    return 0;
}


This is an interactive problem.

Farmer Stanley grows corn on a rectangular field of size $ n \times m $ meters with corners in points $(0, 0)$, $(0, m)$, $(n, 0)$, $(n, m)$. This year the harvest was plentiful and corn covered the whole field.

The night before harvest aliens arrived and poisoned the corn in a single $1 \times 1$ square with sides parallel to field borders. The corn inside the square must not be eaten, but you cannot distinguish it from ordinary corn by sight. Stanley can only collect a sample of corn from an arbitrary polygon and bring it to the laboratory, where it will be analyzed and Stanley will be told the amount of corn in the sample that was poisoned. Since the harvest will soon deteriorate, such a study can be carried out no more than $5$ times.

More formally, it is allowed to make no more than $5$ queries, each of them calculates the area of intersection of a chosen polygon with a square of poisoned corn. It is necessary to find out the coordinates of the lower-left corner of the drawn square (the vertex of the square with the smallest $x$ and $y$ coordinates).

Input

First line contains two integers $n$ and $m$ ($1 \le n, m \le 100$) — field sizes.

Interaction

In order to query the area of intersection of a polygon with $k$ ($3 \le k \le 1000$) vertices at points with coordinates $(x_1, y_1),\; \dots ,\;(x_k, y_k)$ with a square of poisoned corn print $k+1$ lines. In the first of these lines print "? k". In the $i$-th of the next $k$ lines print two real numbers $x_i$ and $y_i$ ($|x_i|, |y_i| \le 10^4$) with at most $15$ digits after decimal place.

The polygon must have strictly positive area and contain no self-intersections.

In response to this query you will receive a real number $s$ ($0 \le s \le 1$) with $15$ digits after decimal place — the area of intersection of the square with the given polygon. If the polygon is invalid, there is no guarantee on the valid response.

When you have identified the drawn square, print on a separate line "! x y", where $x$ and $y$ are real numbers with at most $15$ digits after decimal place representing the coordinates of its lower-left corner ($0 \le x \le n - 1$, $0 \le y \le m - 1$), and then you have to terminate your program.

Your answer will be considered correct if its absolute or relative error on both coordinates does not exceed $10^{-6}$. Formally let your answer be $a$, jury answer be $b$. Your answer will be considered correct if $\frac{|a-b|}{max(1,|b|)} \le 10^{-6}$.

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

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

Example

Input

```
3 3

0.5

0.5
```

Output

```
? 4
0 0
2 0
2 3
0 3

? 4
0 0
0 1
3 1
3 0

! 1.5 0.5
```

Note

In the first test from the statement, the aliens poisoned a square of corn with vertices at points with coordinates $(1.5, 0.5)$, $(1.5, 1.5)$, $(2.5, 1.5)$, $(2.5, 0.5)$. In the picture, it is red, the polygon selected in the query is blue, and their intersection is green.

Picture for the first query:

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

Picture for the second query:

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

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

using namespace std;

struct Pt {
    double x;
    double y;
};

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

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

    }
}

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

static double polygon_area_abs(const vector<Pt>& poly) {
    if (poly.size() < 3) return 0.0;
    long double s = 0.0L;
    for (size_t i = 0; i < poly.size(); i++) {
        const auto& a = poly[i];
        const auto& b = poly[(i + 1) % poly.size()];
        s += (long double)a.x * (long double)b.y - (long double)b.x * (long double)a.y;
    }
    return (double)fabsl(s * 0.5L);
}

static Pt intersect_x(const Pt& a, const Pt& b, double x) {
    const double dx = b.x - a.x;
    if (fabs(dx) < 1e-18) return {x, a.y};
    const double t = (x - a.x) / dx;
    return {x, a.y + t * (b.y - a.y)};
}

static Pt intersect_y(const Pt& a, const Pt& b, double y) {
    const double dy = b.y - a.y;
    if (fabs(dy) < 1e-18) return {a.x, y};
    const double t = (y - a.y) / dy;
    return {a.x + t * (b.x - a.x), y};
}

static vector<Pt> clip_x_ge(const vector<Pt>& in, double x0) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.x >= x0 - 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_x(prev, cur, x0));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_x(prev, cur, x0));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static vector<Pt> clip_x_le(const vector<Pt>& in, double x1) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.x <= x1 + 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_x(prev, cur, x1));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_x(prev, cur, x1));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static vector<Pt> clip_y_ge(const vector<Pt>& in, double y0) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.y >= y0 - 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_y(prev, cur, y0));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_y(prev, cur, y0));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static vector<Pt> clip_y_le(const vector<Pt>& in, double y1) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.y <= y1 + 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_y(prev, cur, y1));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_y(prev, cur, y1));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static double intersection_area_with_unit_square(const vector<Pt>& poly, double x0, double y0) {
    vector<Pt> cur = poly;
    cur = clip_x_ge(cur, x0);
    cur = clip_x_le(cur, x0 + 1.0);
    cur = clip_y_ge(cur, y0);
    cur = clip_y_le(cur, y0 + 1.0);
    double a = polygon_area_abs(cur);
    if (a < 0.0) a = 0.0;
    if (a > 1.0) a = 1.0;
    return a;
}

static bool within_1e6(double got, double expected) {
    const double diff = fabs(got - expected);
    const double denom = max(1.0, fabs(expected));
    return diff / denom <= 1e-6;
}

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

    const int n = inf.readInt(1, 100, "n");
    const int m = inf.readInt(1, 100, "m");
    const double x0 = inf.readDouble(0.0, max(0, n - 1), "x");
    const double y0 = inf.readDouble(0.0, max(0, m - 1), "y");

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

    string tok;
    while (cin >> tok) {
        if (tok == "?") {
            int k = 0;
            if (!(cin >> k)) finish(_pe, "Malformed query: expected k");
            if (k < 3 || k > 1000) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Invalid k");
            }
            queries++;
            if (queries > query_limit) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Query limit exceeded");
            }

            vector<Pt> poly;
            poly.reserve((size_t)k);
            for (int i = 0; i < k; i++) {
                double x, y;
                if (!(cin >> x >> y)) finish(_pe, "Malformed query: expected point");
                poly.push_back({x, y});
            }
            if (polygon_area_abs(poly) <= 0.0) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Invalid polygon (zero area)");
            }

            const double ans = intersection_area_with_unit_square(poly, x0, y0);
            cout << fixed << setprecision(15) << ans << "\n";
            cout.flush();
            log_metrics();
            continue;
        }

        if (tok == "!") {
            double x, y;
            if (!(cin >> x >> y)) finish(_pe, "Malformed answer");
            if (within_1e6(x, x0) && within_1e6(y, y0)) finish(_ok, "OK");
            finish(_wa, format("Wrong answer: expected (%0.15f, %0.15f), got (%0.15f, %0.15f)", x0, y0, x, y));
        }

        cout << -1 << "\n";
        cout.flush();
        finish(_pe, format("Unknown token: '%s'", tok.c_str()));
    }

    finish(_pe, "Unexpected EOF");
}

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

using namespace std;

struct Pt {
    double x;
    double y;
};

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

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

    }
}

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

static long long parse_case_id(const char* case_path) {
    string s(case_path ? case_path : "");
    size_t slash = s.find_last_of("/\\");
    if (slash != string::npos) s = s.substr(slash + 1);
    size_t dot = s.find_last_of('.');
    if (dot != string::npos) s = s.substr(0, dot);
    long long id = 0;
    bool any = false;
    for (unsigned char ch : s) {
        if (isdigit(ch)) {
            any = true;
            id = id * 10 + (ch - '0');
        }
    }
    return any ? id : 0;
}

static double polygon_area_abs(const vector<Pt>& poly) {
    if (poly.size() < 3) return 0.0;
    long double s = 0.0L;
    for (size_t i = 0; i < poly.size(); i++) {
        const auto& a = poly[i];
        const auto& b = poly[(i + 1) % poly.size()];
        s += (long double)a.x * (long double)b.y - (long double)b.x * (long double)a.y;
    }
    return (double)fabsl(s * 0.5L);
}

static Pt intersect_x(const Pt& a, const Pt& b, double x) {
    const double dx = b.x - a.x;
    if (fabs(dx) < 1e-18) return {x, a.y};
    const double t = (x - a.x) / dx;
    return {x, a.y + t * (b.y - a.y)};
}

static Pt intersect_y(const Pt& a, const Pt& b, double y) {
    const double dy = b.y - a.y;
    if (fabs(dy) < 1e-18) return {a.x, y};
    const double t = (y - a.y) / dy;
    return {a.x + t * (b.x - a.x), y};
}

static vector<Pt> clip_x_ge(const vector<Pt>& in, double x0) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.x >= x0 - 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_x(prev, cur, x0));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_x(prev, cur, x0));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static vector<Pt> clip_x_le(const vector<Pt>& in, double x1) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.x <= x1 + 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_x(prev, cur, x1));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_x(prev, cur, x1));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static vector<Pt> clip_y_ge(const vector<Pt>& in, double y0) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.y >= y0 - 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_y(prev, cur, y0));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_y(prev, cur, y0));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static vector<Pt> clip_y_le(const vector<Pt>& in, double y1) {
    vector<Pt> out;
    if (in.empty()) return out;
    auto inside = [&](const Pt& p) { return p.y <= y1 + 1e-12; };
    Pt prev = in.back();
    bool prev_in = inside(prev);
    for (const auto& cur : in) {
        bool cur_in = inside(cur);
        if (prev_in && cur_in) {
            out.push_back(cur);
        } else if (prev_in && !cur_in) {
            out.push_back(intersect_y(prev, cur, y1));
        } else if (!prev_in && cur_in) {
            out.push_back(intersect_y(prev, cur, y1));
            out.push_back(cur);
        }
        prev = cur;
        prev_in = cur_in;
    }
    return out;
}

static double intersection_area_with_unit_square(const vector<Pt>& poly, double x0, double y0) {
    vector<Pt> cur = poly;
    cur = clip_x_ge(cur, x0);
    cur = clip_x_le(cur, x0 + 1.0);
    cur = clip_y_ge(cur, y0);
    cur = clip_y_le(cur, y0 + 1.0);
    double a = polygon_area_abs(cur);
    if (a < 0.0) a = 0.0;
    if (a > 1.0) a = 1.0;
    return a;
}

static bool within_1e6(double got, double expected) {
    const double diff = fabs(got - expected);
    const double denom = max(1.0, fabs(expected));
    return diff / denom <= 1e-6;
}

static double gen_coord(int lim, mt19937_64& rng) {
    if (lim <= 1) return 0.0;
    uniform_int_distribution<int> pick(1, 100);
    int t = pick(rng);

    if (t <= 20) {
        uniform_int_distribution<int> dist(0, lim - 1);
        return (double)dist(rng);
    }
    if (t <= 40) {
        uniform_int_distribution<int> dist(0, lim - 2);
        return (double)dist(rng) + 0.5;
    }
    if (t <= 50) {
        uniform_int_distribution<int> dist(0, lim - 1);
        double val = (double)dist(rng);
        const double eps = 1e-7;
        if (val < 0.5) val += eps;
        else if (val > lim - 1.5) val -= eps;
        else val += ((rng() & 1ULL) ? eps : -eps);
        val = max(0.0, min((double)lim - 1.0, val));
        return val;
    }

    uniform_real_distribution<double> dist(0.0, 1.0);
    return dist(rng) * (lim - 1);
}

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

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

    const long long case_id = (argc >= 2) ? parse_case_id(argv[1]) : 0;
    mt19937_64 rng(0xBADC0FFEEULL ^ (uint64_t)case_id ^ (uint64_t)n * 1315423911ULL ^ (uint64_t)m * 2654435761ULL);

    const double x0 = gen_coord(n, rng);
    const double y0 = gen_coord(m, rng);

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

    string tok;
    while (cin >> tok) {
        if (tok == "?") {
            int k = 0;
            if (!(cin >> k)) finish(_pe, "Malformed query: expected k");
            if (k < 3 || k > 1000) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Invalid k");
            }
            queries++;
            if (queries > query_limit) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Query limit exceeded");
            }

            vector<Pt> poly;
            poly.reserve((size_t)k);
            for (int i = 0; i < k; i++) {
                double x, y;
                if (!(cin >> x >> y)) finish(_pe, "Malformed query: expected point");
                poly.push_back({x, y});
            }
            if (polygon_area_abs(poly) <= 0.0) {
                cout << -1 << "\n";
                cout.flush();
                finish(_wa, "Invalid polygon (zero area)");
            }

            const double ans = intersection_area_with_unit_square(poly, x0, y0);
            cout << fixed << setprecision(15) << ans << "\n";
            cout.flush();
            log_metrics();
            continue;
        }

        if (tok == "!") {
            double x, y;
            if (!(cin >> x >> y)) finish(_pe, "Malformed answer");
            if (within_1e6(x, x0) && within_1e6(y, y0)) finish(_ok, "OK");
            finish(_wa, format("Wrong answer: expected (%0.15f, %0.15f), got (%0.15f, %0.15f)", x0, y0, x, y));
        }

        cout << -1 << "\n";
        cout.flush();
        finish(_pe, format("Unknown token: '%s'", tok.c_str()));
    }

    finish(_pe, "Unexpected EOF");
}

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

using namespace std;

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

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

    int seed = atoi(argv[1]);

    if (n == -1) {
        if (seed == 1) {
            n = 1; m = 1;
        } else if (seed == 2) {
            n = 100; m = 100;
        } else if (seed == 3) {

            n = 3; m = 3;
        } else {
            n = rnd.next(1, 100);
            m = rnd.next(1, 100);
        }
    }

    if (m == -1) {
        m = rnd.next(1, 100);
    }

    cout << n << " " << m << endl;

    if (mode == "non") {

        auto get_coord = [&](int lim) {
            if (lim == 1) return 0.0;

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

            if (t <= 20) {
                return (double)rnd.next(0, lim - 1);
            }

            if (t <= 40) {
                return rnd.next(0, lim - 2) + 0.5;
            }

            if (t <= 50) {
                double val = rnd.next(0, lim - 1);
                double eps = 1e-7;

                if (val < 0.5) val += eps;
                else if (val > lim - 1.5) val -= eps;
                else val += (rnd.next(0, 1) ? eps : -eps);
                return val;
            }

            return rnd.next() * (lim - 1);
        };

        double x, y;

        if (seed == 3 && n == 3 && m == 3) {
            x = 1.5; y = 0.5;
        }

        else if (seed == 1 && n == 1 && m == 1) {
            x = 0; y = 0;
        }
        else {
            x = get_coord(n);
            y = get_coord(m);
        }

        cout << fixed << setprecision(15) << x << " " << y << endl;
    }

    return 0;
}


This temple only magnifies the mountain's power.

Badeline

This is an interactive problem.

You are given two positive integers $n$ and $m$ ($\bf{n \le m}$).

The jury has hidden from you a rectangular matrix $a$ with $n$ rows and $m$ columns, where $a_{i,j} \in \{ -1, 0, 1 \}$ for all $1 \le i \le n$ and $1 \le j \le m$. The jury has also selected a cell $(i_0, j_0)$. Your goal is to find $(i_0,j_0)$.

In one query, you give a cell $(i, j)$, then the jury will reply with an integer.

* If $(i, j) = (i_0, j_0)$, the jury will reply with $0$.
* Else, let $S$ be the sum of $a_{x,y}$ over all $x$ and $y$ such that $\min(i, i_0) \le x \le \max(i, i_0)$ and $\min(j, j_0) \le y \le \max(j, j_0)$. Then, the jury will reply with $|i - i_0| + |j - j_0| + |S|$.

Find $(i_0, j_0)$ by making at most $n + 225$ queries.

Note: the grader is not adaptive: $a$ and $(i_0,j_0)$ are fixed before any queries are made.

Input

Each test contains multiple test cases. The first line of input contains a single integer $t$ ($1 \le t \le 50$) — the number of test cases. The description of the test cases follows.

The only line of each test case contains two integers $n$ and $m$ ($1 \le n \le m \le 5000$) — the numbers of rows and the number of columns of the hidden matrix $a$ respectively.

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

Interaction

The interaction for each test case begins by reading the integers $n$ and $m$.

To make a query, output "? i j" ($1 \le i \le n, 1 \le j \le m$) without quotes. Afterwards, you should read one single integer — the answer to your query.

If you receive the integer $-1$ instead of an answer or a valid value of $n$ or $m$, it means your program has made an invalid query, has exceeded the limit of queries, or has given an incorrect answer on the previous test case. Your program must terminate immediately to receive a Wrong Answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

When you are ready to give the final answer, output "! i j" ($1 \le i \le n, 1 \le j \le m$) without quotes — the indices of the hidden cell. After solving a test case, your program should move to the next one immediately. After solving all test cases, your program should be terminated immediately.

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

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

Example

Input

```
2
3 4

5

3

5

1 1

0
```

Output

```
? 1 1

? 3 3

? 3 2

! 1 4

? 1 1

! 1 1
```

Note

The hidden matrix in the first test case:

|  |  |  |  |
| --- | --- | --- | --- |
| $1$ | $0$ | $1$ | $\color{red}{\textbf{0}}$ |
| $1$ | $0$ | $0$ | $1$ |
| $0$ | $-1$ | $-1$ | $-1$ |

The hidden matrix in the second test case:

|  |
| --- |
| $\color{red}{\textbf{0}}$ |

Note that the line breaks 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 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());
}

struct TestCase {
    int n = 0, m = 0;
    int i0 = 0, j0 = 0;
    vector<int8_t> a;
};

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

static bool readToken(string& out) {
    if (!(cin >> out)) return false;
    return true;
}

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

    vector<TestCase> tests;
    int t = 0;

    try {
        t = inf.readInt();
        if (t < 1 || t > 50) finish(_pe, "Invalid t in hidden input");
        tests.resize(t);

        long long totalLimit = 0;

        for (int tc = 0; tc < t; tc++) {
            int n = inf.readInt();
            int m = inf.readInt();
            if (n < 1 || n > 5000 || m < 1 || m > 5000) finish(_pe, "Invalid n/m in hidden input");
            if (n > m) finish(_pe, "Hidden input violates n <= m");

            int i0 = inf.readInt();
            int j0 = inf.readInt();
            if (i0 < 1 || i0 > n || j0 < 1 || j0 > m) finish(_pe, "Invalid (i0,j0) in hidden input");

            TestCase& cs = tests[tc];
            cs.n = n; cs.m = m; cs.i0 = i0; cs.j0 = j0;
            cs.a.resize((size_t)n * (size_t)m);

            for (long long k = 0; k < 1LL * n * m; k++) {
                int v = inf.readInt();
                if (v != -1 && v != 0 && v != 1) finish(_pe, "Matrix value not in {-1,0,1}");
                cs.a[(size_t)k] = (int8_t)v;
            }

            totalLimit += (long long)n + 225;
        }

        query_limit = totalLimit;
    } catch (const exception& e) {

        finish(_pe, string("Exception while reading hidden input: ") + e.what());
    } catch (...) {
        finish(_pe, "Unknown exception while reading hidden input");
    }

    log_metrics();

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

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

    for (int tc = 0; tc < t; tc++) {
        const TestCase& cs = tests[tc];
        const int n = cs.n, m = cs.m;
        const int i0 = cs.i0, j0 = cs.j0;

        const int cols = m + 1;
        vector<int> pref((size_t)(n + 1) * (size_t)(m + 1), 0);

        for (int i = 1; i <= n; i++) {
            int rowSum = 0;
            const int prefRow = i * cols;
            const int prefPrev = (i - 1) * cols;
            const size_t aRow = (size_t)(i - 1) * (size_t)m;
            for (int j = 1; j <= m; j++) {
                rowSum += (int)cs.a[aRow + (size_t)(j - 1)];
                pref[prefRow + j] = pref[prefPrev + j] + rowSum;
            }
        }

        auto rectSum = [&](int r1, int c1, int r2, int c2) -> long long {

            if (r1 > r2) swap(r1, r2);
            if (c1 > c2) swap(c1, c2);
            long long A = pref[r2 * cols + c2];
            long long B = pref[(r1 - 1) * cols + c2];
            long long C = pref[r2 * cols + (c1 - 1)];
            long long D = pref[(r1 - 1) * cols + (c1 - 1)];
            return A - B - C + D;
        };

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

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

            string tok;
            if (!readToken(tok)) finish(_pe, "Unexpected EOF from contestant");

            if (tok == "?") {
                long long ii, jj;
                if (!readLongLong(ii) || !readLongLong(jj)) finish(_pe, "Malformed query arguments");
                if (ii < 1 || ii > n || jj < 1 || jj > m) finish(_pe, "Query indices out of range");

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

                long long ans = 0;
                if ((int)ii == i0 && (int)jj == j0) {
                    ans = 0;
                } else {
                    long long dist = llabs(ii - (long long)i0) + llabs(jj - (long long)j0);
                    long long S = rectSum((int)ii, (int)jj, i0, j0);
                    ans = dist + llabs(S);
                }

                cout << ans << "\n";
                cout.flush();
            } else if (tok == "!") {
                long long ii, jj;
                if (!readLongLong(ii) || !readLongLong(jj)) finish(_pe, "Malformed final answer arguments");
                if (ii < 1 || ii > n || jj < 1 || jj > m) finish(_pe, "Final answer indices out of range");
                if ((int)ii != i0 || (int)jj != j0) finish(_wa, "Wrong final answer");
                break;
            } else {
                finish(_pe, "Unknown command token");
            }
        }
    }

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

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

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

static void log_metrics() {
    try {
        tout << "queries=" << queries << "\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 void sendMinusOne() {
    cout << -1 << "\n";
    cout.flush();
}

static uint64_t fnv1a64(const string& s) {
    uint64_t h = 1469598103934665603ULL;
    for (unsigned char c : s) {
        h ^= (uint64_t)c;
        h *= 1099511628211ULL;
    }
    return h;
}

static uint64_t splitmix64(uint64_t& x) {
    uint64_t z = (x += 0x9e3779b97f4a7c15ULL);
    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
    z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
    return z ^ (z >> 31);
}

struct MatrixParams {
    int n = 0, m = 0;
    int i0 = 0, j0 = 0;

    int pPos = 92;
    int pNeg = 6;
    uint32_t A = 1, B = 1, C = 0;

    int stripeW = 1;
    int stripePos = 1;
    int blockH = 1;
    int blockW = 1;
    int zeroRad = 0;
    bool allOnes = false;
};

static inline int clampi(int x, int lo, int hi) {
    if (x < lo) return lo;
    if (x > hi) return hi;
    return x;
}

static MatrixParams makeParams(int n, int m, int tc, uint64_t baseSeed) {
    MatrixParams p;
    p.n = n;
    p.m = m;

    uint64_t x = baseSeed;
    x ^= (uint64_t)n * 0x9e3779b97f4a7c15ULL;
    x ^= (uint64_t)m * 0xbf58476d1ce4e5b9ULL;
    x ^= (uint64_t)(tc + 1) * 0x94d049bb133111ebULL;

    p.i0 = 1 + (int)(splitmix64(x) % (uint64_t)n);
    p.j0 = 1 + (int)(splitmix64(x) % (uint64_t)m);

    p.allOnes = ((splitmix64(x) & 31ULL) == 0ULL);

    int baseRad = min(60, max(6, min(n, m) / 25));
    int radWiggle = (int)(splitmix64(x) % 11ULL) - 5;
    p.zeroRad = clampi(baseRad + radWiggle, 0, n + m);

    p.pPos = 92;
    p.pNeg = 6;
    int posWiggle = (int)(splitmix64(x) % 7ULL) - 3;
    p.pPos = clampi(p.pPos + posWiggle, 50, 98);
    int negWiggle = (int)(splitmix64(x) % 7ULL) - 3;
    p.pNeg = clampi(p.pNeg + negWiggle, 1, 100 - p.pPos);

    p.A = 1 + (uint32_t)(splitmix64(x) % 1000000000ULL);
    p.B = 1 + (uint32_t)(splitmix64(x) % 1000000000ULL);
    p.C = (uint32_t)(splitmix64(x) % 1000000000ULL);

    int baseStripeW = max(1, m / 97);
    int stripeWiggle = (int)(splitmix64(x) % 9ULL) - 4;
    p.stripeW = clampi(baseStripeW + stripeWiggle, 1, m);
    p.stripePos = 1 + (int)(splitmix64(x) % (uint64_t)(m - p.stripeW + 1));

    int baseBlockH = max(1, n / 3);
    int baseBlockW = max(1, m / 3);
    int bhWiggle = (int)(splitmix64(x) % 201ULL) - 100;
    int bwWiggle = (int)(splitmix64(x) % 201ULL) - 100;
    p.blockH = clampi(baseBlockH + bhWiggle, 1, n);
    p.blockW = clampi(baseBlockW + bwWiggle, 1, m);

    return p;
}

static inline int cellValue(const MatrixParams& p, int i, int j) {
    if (p.allOnes) return 1;

    bool inZeroDisk = (abs(i - p.i0) + abs(j - p.j0) <= p.zeroRad);
    if (inZeroDisk) return 0;

    bool inNegBlock = (i <= p.blockH && j <= p.blockW);
    bool inStripe = (j >= p.stripePos && j < p.stripePos + p.stripeW);

    int v = 1;
    if (inNegBlock || inStripe) {
        v = -1;
    } else {
        uint64_t x = (uint64_t)(uint32_t)i * (uint64_t)p.A + (uint64_t)(uint32_t)j * (uint64_t)p.B + (uint64_t)p.C;
        x ^= x >> 23;
        x *= 0x2127599bf4325c37ULL;
        x ^= x >> 47;
        int r = (int)(x % 100ULL);
        if (r < p.pPos) v = 1;
        else if (r < p.pPos + p.pNeg) v = -1;
        else v = 0;
        if (v == 0) v = 1;
    }

    if (i == 1 || i == p.n || j == 1 || j == p.m) v = (v == -1 ? -1 : 1);

    if (((i ^ j ^ p.i0 ^ p.j0) & 31) == 0) v = -v;

    return v;
}

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

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

    int t = inf.readInt(1, 50, "t");

    vector<pair<int, int>> dims;
    dims.reserve(t);
    long long totalLimit = 0;
    for (int tc = 0; tc < t; tc++) {
        int n = inf.readInt(1, 5000, "n");
        int m = inf.readInt(1, 5000, "m");
        if (n > m) finish(_fail, "hidden input violates n <= m");
        dims.push_back({n, m});
        totalLimit += (long long)n + 225LL;
    }

    query_limit = totalLimit;
    log_metrics();

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

    const uint64_t baseSeed = fnv1a64(inf.name);

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

    for (int tc = 0; tc < t; tc++) {
        const int n = dims[tc].first;
        const int m = dims[tc].second;

        const long long per_case_limit = (long long)n + 225LL;
        long long used = 0;

        MatrixParams params = makeParams(n, m, tc, baseSeed);

        const int cols = m + 1;
        vector<int> pref((size_t)(n + 1) * (size_t)(m + 1), 0);
        for (int i = 1; i <= n; i++) {
            int rowSum = 0;
            const size_t prefRow = (size_t)i * (size_t)cols;
            const size_t prefPrev = (size_t)(i - 1) * (size_t)cols;
            for (int j = 1; j <= m; j++) {
                rowSum += cellValue(params, i, j);
                pref[prefRow + (size_t)j] = pref[prefPrev + (size_t)j] + rowSum;
            }
        }

        auto rectSum = [&](int r1, int c1, int r2, int c2) -> long long {
            if (r1 > r2) swap(r1, r2);
            if (c1 > c2) swap(c1, c2);
            long long A = pref[(size_t)r2 * (size_t)cols + (size_t)c2];
            long long B = pref[(size_t)(r1 - 1) * (size_t)cols + (size_t)c2];
            long long C = pref[(size_t)r2 * (size_t)cols + (size_t)(c1 - 1)];
            long long D = pref[(size_t)(r1 - 1) * (size_t)cols + (size_t)(c1 - 1)];
            return A - B - C + D;
        };

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

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

            string tok;
            if (!(cin >> tok)) finish(_pe, "unexpected EOF from contestant");

            if (tok == "?") {
                long long ii, jj;
                if (!(cin >> ii >> jj)) {
                    sendMinusOne();
                    finish(_pe, "malformed query arguments");
                }
                if (ii < 1 || ii > n || jj < 1 || jj > m) {
                    sendMinusOne();
                    finish(_wa, "query indices out of range");
                }

                queries++;
                used++;
                if (queries > hard_cap) finish(_pe, "hard cap exceeded");
                if (used > per_case_limit) {
                    sendMinusOne();
                    finish(_wa, "query limit exceeded");
                }

                long long ans = 0;
                if ((int)ii == params.i0 && (int)jj == params.j0) {
                    ans = 0;
                } else {
                    long long dist = llabs(ii - (long long)params.i0) + llabs(jj - (long long)params.j0);
                    long long S = rectSum((int)ii, (int)jj, params.i0, params.j0);
                    ans = dist + llabs(S);
                }

                cout << ans << "\n" << flush;
            } else if (tok == "!") {
                long long ii, jj;
                if (!(cin >> ii >> jj)) {
                    sendMinusOne();
                    finish(_pe, "malformed final answer arguments");
                }
                if (ii < 1 || ii > n || jj < 1 || jj > m) {
                    sendMinusOne();
                    finish(_wa, "final answer indices out of range");
                }
                if ((int)ii != params.i0 || (int)jj != params.j0) {
                    sendMinusOne();
                    finish(_wa, "wrong final answer");
                }
                break;
            } else {
                sendMinusOne();
                finish(_pe, "unknown command token");
            }
        }
    }

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

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

static inline void appendVal(string& s, int v) {
    if (!s.empty()) s.push_back(' ');
    if (v == 1) {
        s.push_back('1');
    } else if (v == 0) {
        s.push_back('0');
    } else {
        s.push_back('-');
        s.push_back('1');
    }
}

struct Hasher {
    uint64_t A, B, C;
    int pPos, pNeg;

    int base(int i, int j) const {
        uint64_t x = (uint64_t)(uint32_t)i * A + (uint64_t)(uint32_t)j * B + C;
        x ^= x >> 23;
        x *= 0x2127599bf4325c37ULL;
        x ^= x >> 47;
        int r = (int)(x % 100ULL);
        if (r < pPos) return 1;
        if (r < pPos + pNeg) return -1;
        return 0;
    }
};

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

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

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

    int nOpt = opt<int>("n", -1);
    int mOpt = opt<int>("m", -1);

    int n, m;
    if (nOpt != -1 || mOpt != -1) {
        n = (nOpt == -1 ? 5000 : nOpt);
        m = (mOpt == -1 ? 5000 : mOpt);
    } else {
        if (seed == 1) {
            n = 1; m = 1;
        } else if (seed == 2) {
            n = 1; m = 5000;
        } else if (seed == 3) {
            n = 5000; m = 5000;
        } else {
            n = 5000; m = 5000;
        }
    }

    if (n < 1) n = 1;
    if (m < 1) m = 1;
    if (n > 5000) n = 5000;
    if (m > 5000) m = 5000;
    if (n > m) swap(n, m);

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

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

    int i0Opt = opt<int>("i0", -1);
    int j0Opt = opt<int>("j0", -1);

    int i0, j0;
    if (i0Opt != -1 && j0Opt != -1) {
        i0 = i0Opt;
        j0 = j0Opt;
    } else {
        if (seed == 1) {
            i0 = 1; j0 = 1;
        } else if (seed == 2) {
            i0 = 1; j0 = (m + 1) / 2;
        } else if (seed == 3) {
            i0 = (n + 1) / 2; j0 = (m + 1) / 2;
        } else {
            i0 = rnd.next(1, n);
            j0 = rnd.next(1, m);
        }
    }
    if (i0 < 1) i0 = 1;
    if (i0 > n) i0 = n;
    if (j0 < 1) j0 = 1;
    if (j0 > m) j0 = m;

    cout << 1 << "\n";
    cout << n << " " << m << "\n";
    cout << i0 << " " << j0 << "\n";

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

    if (seed == 3) {
        string line;
        line.reserve((size_t)m * 2 + 16);
        for (int i = 1; i <= n; i++) {
            line.clear();
            for (int j = 1; j <= m; j++) appendVal(line, 1);
            cout << line << "\n";
        }
        return 0;
    }

    int pPos = opt<int>("pPos", (seed == 2 ? 50 : 92));
    int pNeg = opt<int>("pNeg", (seed == 2 ? 50 : 6));
    if (pPos < 0) pPos = 0;
    if (pNeg < 0) pNeg = 0;
    if (pPos > 100) pPos = 100;
    if (pNeg > 100 - pPos) pNeg = 100 - pPos;

    Hasher hasher;
    hasher.A = (uint64_t)(uint32_t)rnd.next(1, 1000000000);
    hasher.B = (uint64_t)(uint32_t)rnd.next(1, 1000000000);
    hasher.C = (uint64_t)(uint32_t)rnd.next(0, 1000000000);
    hasher.pPos = pPos;
    hasher.pNeg = pNeg;

    int stripeW = opt<int>("stripeW", max(1, m / 97));
    if (stripeW < 1) stripeW = 1;
    if (stripeW > m) stripeW = m;
    int stripePos = opt<int>("stripePos", rnd.next(1, m - stripeW + 1));

    int blockH = opt<int>("blockH", max(1, n / 3));
    int blockW = opt<int>("blockW", max(1, m / 3));
    if (blockH > n) blockH = n;
    if (blockW > m) blockW = m;

    int zeroRad = opt<int>("zeroRad", min(60, max(6, min(n, m) / 25)));
    if (zeroRad < 0) zeroRad = 0;

    string line;
    line.reserve((size_t)m * 3 + 16);

    for (int i = 1; i <= n; i++) {
        line.clear();
        for (int j = 1; j <= m; j++) {
            int v;

            bool inNegBlock = (i <= blockH && j <= blockW);
            bool inStripe = (j >= stripePos && j < stripePos + stripeW);
            bool inZeroDisk = (abs(i - i0) + abs(j - j0) <= zeroRad);

            if (seed == 2) {

                if (inZeroDisk && (j % 7 == 0)) v = 0;
                else v = ((j & 1) ? 1 : -1);
            } else {
                if (inZeroDisk) {
                    v = 0;
                } else if (inNegBlock) {
                    v = -1;
                } else if (inStripe) {
                    v = -1;
                } else {
                    v = hasher.base(i, j);

                    if (v == 0) v = 1;
                }

                if (i == 1 || i == n || j == 1 || j == m) {
                    if (!inZeroDisk) v = (v == -1 ? -1 : 1);
                }

                if (!inZeroDisk && ((i ^ j ^ i0 ^ j0) & 31) == 0) v = -v;
            }

            appendVal(line, v);
        }
        cout << line << "\n";
    }

    return 0;
}


### Problem Statement

This is an **interactive task** (where your program and the judge interact via Standard Input and Output).

You are given an integer $N$ and an **odd number** $K$.
The judge has a hidden length-$N$ sequence $A = (A_1, A_2, \dots, A_N)$ consisting of $0$ and $1$.

While you cannot directly access the elements of sequence $A$,
you are allowed to ask the judge the following query at most $N$ times.

* Choose distinct integers $x_1, x_2, \dots$, and $x_K$ between $1$ and $N$, inclusive, to ask the parity of $A_{x_1} + A_{x_2} + \dots + A_{x_K}$.

Determine $(A_1, A_2, \dots, A_N)$ by at most $N$ queries, and print the answer.
Here, **the judge is adaptive**. In other words, the judge may modify the contents of $A$ as long as it is consistent with the responses to the past queries.
Therefore, your program is considered correct if the output satisfies the following condition, and incorrect otherwise:

* your program prints a sequence consistent with the responses to the queries so far, and that is the only such sequence.

### Constraints

* $1 \leq K \lt N \leq 1000$
* $K$ is odd.
* $A_i$ is $0$ or $1$.

### Input and Output

This is an **interactive task** (where your program and the judge interact via Standard Input and Output).

First of all, receive $N$ and $K$ from Standard Input.

```
$N$ $K$
```

Then, repeat asking queries until you can uniquely determine $(A_1, A_2, \dots, A_N)$.
Each query should be printed to Standard Output in the following format, where $x_1, x_2, \dots$, and $x_K$ are $K$ distinct integers between $1$ and $N$, inclusive.

```
$?$ $x_1$ $x_2$ $\dots$ $x_K$
```

The response to the query is given from Standard Input in the following format.

```
$T$
```

Here, $T$ denotes the response to the query.

* $T$ is `0` when $A_{x_1} + A_{x_2} + \dots + A_{x_K}$ is even, and
* $T$ is `1` when $A_{x_1} + A_{x_2} + \dots + A_{x_K}$ is odd.

However, if $x_1, x_2, \dots$ and $x_K$ do not satisfy the constraints, or the number of queries exceeds $N$, then $T$ is `-1`.

If the judge returns `-1`, your program is already considered incorrect, so terminate the program immediately.

When you can determine all the elements of $A$, print those elements in the following format, and terminate the program immediately.

```
$!$ $A_1$ $A_2$ $\dots$ $A_N$
```

### Notes

* **Print a newline and flush Standard Output at the end of each message. Otherwise, you may get a TLE verdict.**
* **The verdict will be indeterminate if there is malformed output during the interaction or your program quits prematurely.**
* Terminate the program immediately after printing the answer, or the verdict will be indeterminate.
* The judge for this problem is adaptive. This means that the judge may modify the contents of $A$ as long as it is consistent with the responses to the past queries.

### Sample Interaction

In the following interaction, $N=5$ and $K=3$. **Note that the following output itself will result in WA.**
Here, $A = (1, 0, 1, 1, 0)$ is indeed consistent with the responses, but so is $(0, 0, 1, 0, 0)$, so sequence $A$ is not uniquely determined. Thus, this program is considered incorrect.

| Input | Output | Description |
| --- | --- | --- |
| `5 3` |  | First, you are given integers $N$ and $K$. |
|  | `? 2 4 1` | You ask a query with $(x_1, x_2, x_3) = (2, 4, 1)$. |
| `0` |  | The response to the query is $0$, so the judge returns that value. |
|  | `? 5 3 2` | You ask a query with $(x_1, x_2, x_3) = (5, 3, 2)$. |
| `1` |  | The response to the query is $1$, so the judge returns that value. |
|  | `! 1 0 1 1 0` | You print $(1, 0, 1, 1, 0)$ to guess $A$. Since sequence $A$ is not uniquely determined, the verdict will be WA. |

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

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

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

    }
}

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

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

    registerInteraction(argc, argv);

    tout.open(argv[2]);

    atexit(log_metrics);

    int N = inf.readInt(2, 1000, "N");
    int K = inf.readInt(1, N - 1, "K");

    if (K % 2 == 0) {
        finish(_fail, "K must be odd according to constraints");
    }

    vector<int> A(N);
    for (int i = 0; i < N; i++) {
        A[i] = inf.readInt(0, 1, format("A[%d]", i + 1));
    }

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

    cout << N << " " << K << endl;

    string token;
    while (cin >> token) {

        if (token == "!") {
            vector<int> guess(N);
            for (int i = 0; i < N; i++) {
                if (!(cin >> guess[i])) {
                    finish(_pe, "Could not read answer element " + to_string(i + 1));
                }
                if (guess[i] != 0 && guess[i] != 1) {
                    finish(_pe, "Answer elements must be 0 or 1");
                }
            }

            if (guess == A) {
                finish(_ok, "Correct sequence");
            } else {
                finish(_wa, "Incorrect sequence");
            }
            return 0;
        }

        vector<int> indices;
        indices.reserve(K);

        if (token == "?") {

            for (int i = 0; i < K; i++) {
                int val;
                if (!(cin >> val)) finish(_pe, "Failed to read query index");
                indices.push_back(val);
            }
        } else {

            try {
                size_t pos;
                int val = stoi(token, &pos);
                if (pos != token.size()) finish(_pe, "Invalid token in query: " + token);
                indices.push_back(val);
            } catch (...) {
                finish(_pe, "Invalid token in query: " + token);
            }

            for (int i = 1; i < K; i++) {
                int val;
                if (!(cin >> val)) finish(_pe, "Failed to read query index");
                indices.push_back(val);
            }
        }

        vector<int> sorted_idxs = indices;
        sort(sorted_idxs.begin(), sorted_idxs.end());
        bool distinct = true;
        for (int i = 0; i < K; i++) {
            if (sorted_idxs[i] < 1 || sorted_idxs[i] > N) {
                finish(_pe, "Query index out of range: " + to_string(sorted_idxs[i]));
            }
            if (i > 0 && sorted_idxs[i] == sorted_idxs[i-1]) {
                distinct = false;
            }
        }
        if (!distinct) {
            finish(_pe, "Query indices must be distinct");
        }

        queries++;

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

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

        int sum_val = 0;
        for (int idx : indices) {
            sum_val += A[idx - 1];
        }

        cout << (sum_val % 2) << endl;
    }

    finish(_pe, "Unexpected EOF (did not receive answer)");
}

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

using namespace std;

static long long queries = 0;
static long long query_limit = 0;
static bool finished = false;

static void log_metrics() {
    if (!tout.is_open()) return;
    tout << "queries=" << queries << endl;
    tout << "query_limit=" << query_limit << endl;
}

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

void cleanup() {
    if (!finished) log_metrics();
}

const int MAXN = 1005;

struct LinearBasis {
    int N;

    bitset<MAXN> basis[MAXN];

    int rhs[MAXN];
    int rank;

    LinearBasis(int n) : N(n), rank(0) {
        for (int i = 0; i < N; ++i) rhs[i] = 0;
    }

    int query(const vector<int>& indices) {
        bitset<MAXN> vec;
        for (int x : indices) vec.set(x - 1);

        int current_val = 0;

        for (int i = 0; i < N; ++i) {
            if (!vec.test(i)) continue;

            if (basis[i].any()) {

                vec ^= basis[i];
                current_val ^= rhs[i];
            } else {

                basis[i] = vec;
                rhs[i] = current_val;
                rank++;
                return 0;
            }
        }

        return current_val;
    }

    vector<int> get_unique_solution() {
        if (rank < N) return {};

        vector<int> res(N);

        for (int i = N - 1; i >= 0; --i) {
            int val = rhs[i];
            for (int j = i + 1; j < N; ++j) {
                if (basis[i].test(j)) {
                    val ^= res[j];
                }
            }
            res[i] = val;
        }
        return res;
    }
};

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

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

    int n = inf.readInt();
    int k = inf.readInt();

    query_limit = n;

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

    LinearBasis lb(n);

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

    while (true) {
        string token;

        if (!(cin >> token)) {
            finish(_wa, "Unexpected end of output from contestant");
        }

        if (token == "?") {
            queries++;

            vector<int> q(k);
            vector<int> distinct_check;
            distinct_check.reserve(k);

            for (int i = 0; i < k; ++i) {
                if (!(cin >> q[i])) {
                    finish(_wa, "Malformed query: expected integer");
                }

                if (q[i] < 1 || q[i] > n) {
                    finish(_wa, format("Query index %d out of range [1, %d]", q[i], n));
                }
                distinct_check.push_back(q[i]);
            }

            sort(distinct_check.begin(), distinct_check.end());
            if (unique(distinct_check.begin(), distinct_check.end()) != distinct_check.end()) {
                finish(_wa, "Query indices must be distinct");
            }

            if (queries > query_limit) {

                cout << -1 << endl;
                finish(_wa, "Query limit exceeded");
            }

            if (queries > hard_cap) {
                finish(_pe, "Too many queries (hard cap exceeded)");
            }

            int ans = lb.query(q);
            cout << ans << endl;

        } else if (token == "!") {

            vector<int> user_ans(n);
            for (int i = 0; i < n; ++i) {
                if (!(cin >> user_ans[i])) {
                    finish(_wa, "Malformed final answer");
                }
                if (user_ans[i] != 0 && user_ans[i] != 1) {
                    finish(_wa, "Answer elements must be 0 or 1");
                }
            }

            vector<int> expected = lb.get_unique_solution();

            if (expected.empty()) {

                finish(_wa, "Sequence A is not uniquely determined by the queries asked");
            } else {
                if (user_ans == expected) {
                    finish(_ok, "Correct");
                } else {
                    finish(_wa, "Incorrect sequence");
                }
            }

        } else {
            finish(_wa, format("Expected '?' or '!', found '%s'", token.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");
    long long seed_val = 0;
    if (argc > 1) seed_val = atoll(argv[1]);

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

    if (N == 0) {
        if (seed_val == 1) {

            N = 2; K = 1;
        } else if (seed_val == 2) {

            N = 1000; K = 1;
        } else if (seed_val == 3) {

            N = 1000; K = 999;
        } else if (seed_val == 4) {

            N = 1000; K = 501;
        } else if (seed_val == 5) {

            N = 50; K = 25;
        } else if (seed_val <= 10) {

            N = rnd.next(2, 20);
        } else {

            N = rnd.next(2, 1000);
        }
    }

    if (K == 0) {

        int max_K = N - 1 - (N % 2);
        if (max_K < 1) max_K = 1;

        int num_odds = (max_K + 1) / 2;
        int idx = rnd.next(0, num_odds - 1);
        K = 2 * idx + 1;
    }

    if (N < 2) N = 2;
    if (N > 1000) N = 1000;

    if (K >= N) K = N - 1 - (N % 2);
    if (K < 1) K = 1;

    if (K % 2 == 0) K--;

    cout << N << " " << K << endl;

    if (mode == "non") {
        vector<int> A(N);

        int type = rnd.next(1, 10);
        if (type == 1) {

            fill(A.begin(), A.end(), 0);
        } else if (type == 2) {

            fill(A.begin(), A.end(), 1);
        } else if (type == 3) {

            for (int i = 0; i < N; i++) A[i] = i % 2;
        } else {

            for (int i = 0; i < N; i++) A[i] = rnd.next(0, 1);
        }
        println(A);
    }

    return 0;
}