Problem: cf1856_d
Difficulty: easy
Categories: search
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem.

The jury has hidden a permutation$^\dagger$ $p$ of length $n$.

In one query, you can pick two integers $l$ and $r$ ($1 \le l < r \le n$) by paying $(r - l)^2$ coins. In return, you will be given the number of inversions$^\ddagger$ in the subarray $[p_l, p_{l + 1}, \ldots p_r]$.

Find the index of the maximum element in $p$ by spending at most $5 \cdot n^2$ coins.

Note: the grader is not adaptive: the permutation is fixed before any queries are made.

$^\dagger$ A permutation of length $n$ is an array consisting of $n$ distinct integers from $1$ to $n$ in arbitrary order. For example, $[2,3,1,5,4]$ is a permutation, but $[1,2,2]$ is not a permutation ($2$ appears twice in the array), and $[1,3,4]$ is also not a permutation ($n=3$ but there is $4$ in the array).

$^\ddagger$ The number of inversions in an array is the number of pairs of indices $(i,j)$ such that $i < j$ and $a_i > a_j$. For example, the array $[10,2,6,3]$ contains $4$ inversions. The inversions are $(1,2),(1,3),(1,4)$, and $(3,4)$.

Input

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

The only line of each test case contains a single integer $n$ ($2 \le n \le 2000$) — the length of the hidden permutation $p$.

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

Interaction

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

To make a query, output "? l r" ($1 \le l < r \le n$) without quotes. Afterwards, you should read one single integer — the answer for your query.

If you receive the integer $-1$ instead of an answer or a valid value of $n$, it means your program has made an invalid query, has exceed 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" ($1 \le i \le n$) without quotes — the index of the maximum of the hidden permutation. 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
4

1

0

2

1
```

Output

```
? 1 3

? 3 4

! 4

? 1 2

! 1
```

Note

In the first test, the interaction proceeds as follows:

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | 2 | There are $2$ test cases. |
|  | 4 | In the first test case, the hidden permutation is $[1,3,2,4]$, with length $4$. |
| ? 1 3 | 1 | The solution requests the number of inversions in the subarray $[1,3,2]$ by paying $4$ coins, and the jury responds with $1$. |
| ? 3 4 | 0 | The solution requests the number of inversions in the subarray $[2,4]$ by paying $1$ coin, and the jury responds with $0$. |
| ! 4 |  | The solution has somehow determined that $p_4 = 4$, and outputs it. Since the output is correct, the jury continues to the next test case. |
|  | 2 | In the second test case, the hidden permutation is $[2,1]$, with length $2$. |
| ? 1 2 | 1 | The solution requests the number of inversions in the subarray $[2,1]$ by paying $1$ coin, and the jury responds with $1$. |
| ! 1 |  | The solution has somehow determined that $p_1 = 2$, and outputs it. Since the output is correct and there are no more test cases, the jury and the solution exit. |

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.

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 void sendMinusOne() {
    cout << -1 << "\n";
    cout.flush();
}

static int inversionCount(const vector<int>& p, int l, int r) {
    int inv = 0;
    for (int i = l - 1; i < r; i++) {
        for (int j = i + 1; j < r; j++) {
            if (p[i] > p[j]) inv++;
        }
    }
    return inv;
}

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

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

    int t = inf.readInt(1, 100, "t");
    vector<int> ns(t);
    vector<vector<int>> perms(t); 

    long long sumN = 0;
    for (int tc = 0; tc < t; tc++) {
        int n = inf.readInt(2, 2000, "n");
        ns[tc] = n;
        sumN += n;

        vector<int> p(n);
        vector<int> seen(n + 1, 0);
        for (int i = 0; i < n; i++) {
            int v = inf.readInt(1, n, "p[i]");
            p[i] = v;
            if (++seen[v] != 1) finish(_fail, "invalid hidden permutation: duplicates");
        }
        perms[tc] = std::move(p);

        query_limit += 5LL * n * n;
    }
    if (sumN > 2000) finish(_fail, "invalid hidden input: sum(n) exceeds 2000");

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

    
    log_metrics();

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

    for (int tc = 0; tc < t; tc++) {
        const int n = ns[tc];
        const vector<int>& p = perms[tc];

        const long long budget = 5LL * n * n;
        long long spent = 0;

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

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

            if (tok == "?") {
                long long l_ll, r_ll;
                if (!(cin >> l_ll >> r_ll)) {
                    sendMinusOne();
                    finish(_pe, "malformed query");
                }
                if (!(1 <= l_ll && l_ll < r_ll && r_ll <= n)) {
                    sendMinusOne();
                    finish(_wa, "invalid query range");
                }
                int l = (int)l_ll, r = (int)r_ll;

                long long d = (long long)(r - l);
                long long cost = d * d;
                if (spent + cost > budget) {
                    sendMinusOne();
                    finish(_wa, "coin budget exceeded");
                }
                spent += cost;
                queries += cost;

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

                cout << inversionCount(p, l, r) << "\n";
                cout.flush();
            } else if (tok == "!") {
                long long idx_ll;
                if (!(cin >> idx_ll)) {
                    sendMinusOne();
                    finish(_pe, "malformed final answer");
                }
                if (!(1 <= idx_ll && idx_ll <= n)) {
                    sendMinusOne();
                    finish(_wa, "final answer out of range");
                }
                int idx = (int)idx_ll;
                if (p[idx - 1] != n) {
                    sendMinusOne();
                    finish(_wa, "wrong final answer");
                }
                break;
            } else {
                sendMinusOne();
                finish(_pe, "unexpected token (expected '?' or '!')");
            }
        }
    }

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


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 void sendMinusOne() {
    cout << -1 << "\n";
    cout.flush();
}

static int inversionCount(const vector<int>& p, int l, int r) {
    int inv = 0;
    for (int i = l - 1; i < r; i++) {
        for (int j = i + 1; j < r; j++) {
            if (p[i] > p[j]) inv++;
        }
    }
    return inv;
}

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

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

    
    
    int t = inf.readInt(1, 100, "t");
    vector<int> ns(t);
    vector<vector<int>> perms(t); 

    long long sumN = 0;
    for (int tc = 0; tc < t; tc++) {
        int n = inf.readInt(2, 2000, "n");
        ns[tc] = n;
        sumN += n;

        vector<int> p(n);
        vector<int> seen(n + 1, 0);
        for (int i = 0; i < n; i++) {
            int v = inf.readInt(1, n, "p[i]");
            p[i] = v;
            if (++seen[v] != 1) finish(_fail, "invalid hidden permutation: duplicates");
        }
        perms[tc] = std::move(p);

        query_limit += 5LL * n * n;
    }
    if (sumN > 2000) finish(_fail, "invalid hidden input: sum(n) exceeds 2000");

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

    
    log_metrics();

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

    for (int tc = 0; tc < t; tc++) {
        const int n = ns[tc];
        const vector<int>& p = perms[tc];

        const long long budget = 5LL * n * n;
        long long spent = 0;

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

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

            if (tok == "?") {
                long long l_ll, r_ll;
                if (!(cin >> l_ll >> r_ll)) {
                    sendMinusOne();
                    finish(_pe, "malformed query");
                }
                if (!(1 <= l_ll && l_ll < r_ll && r_ll <= n)) {
                    sendMinusOne();
                    finish(_wa, "invalid query range");
                }
                int l = (int)l_ll, r = (int)r_ll;

                long long d = (long long)(r - l);
                long long cost = d * d;
                if (spent + cost > budget) {
                    sendMinusOne();
                    finish(_wa, "coin budget exceeded");
                }
                spent += cost;
                queries += cost;

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

                cout << inversionCount(p, l, r) << "\n";
                cout.flush();
            } else if (tok == "!") {
                long long idx_ll;
                if (!(cin >> idx_ll)) {
                    sendMinusOne();
                    finish(_pe, "malformed final answer");
                }
                if (!(1 <= idx_ll && idx_ll <= n)) {
                    sendMinusOne();
                    finish(_wa, "final answer out of range");
                }
                int idx = (int)idx_ll;
                if (p[idx - 1] != n) {
                    sendMinusOne();
                    finish(_wa, "wrong final answer");
                }
                break;
            } else {
                sendMinusOne();
                finish(_pe, "unexpected token (expected '?' or '!')");
            }
        }
    }

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


Test generator (C++):
#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 t_opt = opt<int>("t", -1);

    
    int seed = atoi(argv[1]);
    vector<int> ns;

    
    if (n_opt != -1 && t_opt != -1) {
        
        int cnt = t_opt;
        if (cnt > 100) cnt = 100; 
        
        
        long long total = (long long)cnt * n_opt;
        if (total > 2000) {
            if (n_opt >= 2000) {
                ns.push_back(2000);
            } else {
                cnt = 2000 / n_opt;
                for(int i = 0; i < cnt; ++i) ns.push_back(n_opt);
            }
        } else {
            for(int i = 0; i < cnt; ++i) ns.push_back(n_opt);
        }
    } else if (n_opt != -1) {
        
        ns.push_back(min(n_opt, 2000));
    } else if (t_opt != -1) {
        
        int cnt = min(t_opt, 100);
        
        ns = rnd.partition(cnt, 2000, 2);
    } else {
        
        
        if (seed == 1) {
            
            ns = {2};
        } else if (seed == 2) {
            
            ns = {2000};
        } else if (seed == 3) {
            
            ns = rnd.partition(100, 2000, 2);
        } else {
            
            int type = rnd.next(3);
            if (type == 0) {
                
                int cnt = rnd.next(1, 5);
                ns = rnd.partition(cnt, 2000, 2);
            } else if (type == 1) {
                
                int cnt = rnd.next(50, 100);
                ns = rnd.partition(cnt, 2000, 2);
            } else {
                
                int cnt = rnd.next(1, 100);
                int sum = rnd.next(max(cnt * 2, 1000), 2000);
                ns = rnd.partition(cnt, sum, 2);
            }
        }
    }

    
    cout << ns.size() << "\n";
    for (int n : ns) {
        cout << n << "\n";
        
        if (mode != "non" && mode != "adp") mode = "non";

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

        
        
        int structure = rnd.next(100);

        if (structure < 5) {
            
        } else if (structure < 10) {
            
            reverse(p.begin(), p.end());
        } else if (structure < 15) {
            
            rotate(p.begin(), p.begin() + 1, p.end());
        } else if (structure < 20) {
            
            reverse(p.begin(), p.end());
            rotate(p.begin(), p.begin() + 1, p.end());
        } else if (structure < 25) {
            
            swap(p[n - 1], p[n / 2]);
        } else {
            
            shuffle(p.begin(), p.end());
        }

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

    return 0;
}