Problem: cf1812_h
Difficulty: medium
Categories: bit, math
Time limit: 3000 ms, memory limit: 256 MB

This is an interactive problem.

There is an array $a_1, a_2, \dots, a_n$ of $n$ integers hidden from you. Your task is to find the smallest element of the array.

To do this, you can ask several queries. In each query, you can pick two integers $l$ and $r$ ($1 \leq l \leq r \leq n$). In return, you will be given the value of $\max(a_l, a_{l+1}, \dots, a_r)$. In other words, you will be told the maximum value of the subarray from $a_l$ to $a_r$.

Find the minimum of the array. You can ask at most $\mathbf{624}$ queries.

It is guaranteed that the values $a_1, a_2, \dots, a_n$ are chosen uniformly at random between $0$ and $2^{32}-1$ (inclusive).

Interaction

Begin the interaction by reading an integer $n$ ($1 \le n \le 10^4$) on a separate line.

To ask a query, print a line in the form $\texttt{?}\;\;l\;\;r$ ($1 \le l \le r \le n$). Then you should read a single line containing the answer to your query.

After you have determined the answer, print a line in the form $\texttt{!}\;\;x$ where $x$ is the minimum value.

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.

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

Example

Input

```
3

1295320727

984617979

1295320727

167316954
```

Output

```
? 1 3

? 1 1

? 2 2

? 3 3

! 167316954
```

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


static long long queries = 0;

static const long long query_limit = 624;


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


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

static 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;
}

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

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

    const long long case_id = (argc >= 2) ? parse_case_id(argv[1]) : 0;
    const uint32_t seed = (uint32_t)(0xC0FFEEU ^ (uint32_t)case_id ^ (uint32_t)n * 2654435761U);
    std::mt19937 rng(seed);

    vector<uint32_t> a((size_t)n + 1);
    uint32_t true_min = 0;
    for (int i = 1; i <= n; i++) {
        a[i] = rng();
        if (i == 1 || a[i] < true_min) true_min = a[i];
    }

    
    cout << n << endl;

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

        string token;
        cin >> token;

        if (cin.fail()) {
            
            finish(_wa, "Unexpected end of stream (expected query or answer)");
        }

        if (token == "!") {
            
            long long ans;
            cin >> ans;
            if (cin.fail()) {
                finish(_wa, "Failed to read answer value");
            }

            if (ans == true_min) {
                finish(_ok, "Correct minimum found");
            } else {
                finish(_wa, format("Wrong answer: expected %lld, found %lld", true_min, ans));
            }
        } else {
            
            
            int l, r;
            if (token == "?") {
                cin >> l >> r;
            } else {
                
                try {
                    l = stoi(token);
                } catch (...) {
                    finish(_wa, format("Invalid token '%s' (expected '?', '!', or integer)", token.c_str()));
                }
                cin >> r;
            }

            if (cin.fail()) {
                finish(_wa, "Failed to read query coordinates");
            }

            queries++;
            if (queries > query_limit) {
                cout << -1 << endl;
                finish(_wa, "Query limit exceeded");
            }

            
            if (l < 1 || l > r || r > n) {
                
                cout << -1 << endl;
                finish(_wa, format("Invalid query range: %d %d (N=%d)", l, r, n));
            }

            
            
            uint32_t current_max = 0;
            for (int i = l; i <= r; i++) current_max = max(current_max, a[i]);

            cout << current_max << endl;

            
            if (queries % 100 == 0) {
                log_metrics();
            }
        }
    }

    return 0;
}


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


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


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


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

static 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;
}

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

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

    const long long case_id = (argc >= 2) ? parse_case_id(argv[1]) : 0;
    const uint32_t seed = (uint32_t)(0xC0FFEEU ^ (uint32_t)case_id ^ (uint32_t)n * 2654435761U);
    std::mt19937 rng(seed);

    vector<uint32_t> a((size_t)n + 1);
    uint32_t min_val = 0;
    for (int i = 1; i <= n; i++) {
        a[i] = rng();
        if (i == 1 || a[i] < min_val) min_val = a[i];
    }

    
    
    cout << n << endl;

    
    
    int hard_cap = 20000;
    int ops = 0;

    while (true) {
        if (ops++ > hard_cap) {
            finish(_pe, "Hard cap on interactions exceeded");
        }

        string type;
        
        if (!(cin >> type)) {
            finish(_wa, "Unexpected EOF (expected '?' or '!')");
        }

        if (type == "?") {
            int l, r;
            if (!(cin >> l >> r)) {
                finish(_wa, "Invalid query format");
            }

            
            if (l < 1 || l > n || r < 1 || r > n || l > r) {
                finish(_wa, format("Invalid query range: %d %d", l, r));
            }

            queries++;
            if (queries > query_limit) {
                cout << -1 << endl;
                finish(_wa, "Query limit exceeded");
            }
            
            if (queries % 50 == 0) log_metrics();

            
            uint32_t current_max = 0;
            for (int i = l; i <= r; i++) current_max = max(current_max, a[i]);

            cout << current_max << endl;

        } else if (type == "!") {
            long long ans;
            if (!(cin >> ans)) {
                finish(_wa, "Invalid answer format");
            }

            
            if (ans == min_val) {
                finish(_ok, format("Correct! Found min %lld in %d queries", min_val, queries));
            } else {
                finish(_wa, format("Wrong answer. Expected %lld, found %lld", min_val, ans));
            }

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

    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;
    long long seed_val = 0;
    if (argc > 1) seed_val = atoll(argv[1]);

    if (seed_val == 1) {
        n = 1;
    } else if (seed_val == 2) {
        n = 10000; 
    } else if (seed_val == 3) {
        n = 100;   
    } else {
        n = rnd.next(1, 10000);
    }

    
    
    
    
    vector<long long> a(n);
    for (int i = 0; i < n; i++) {
        a[i] = rnd.next(0LL, 4294967295LL);
    }

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

    return 0;
}