Problem: cf1179_e
Difficulty: medium
Categories: search
Time limit: 5000 ms, memory limit: 256 MB

We call a function good if its domain of definition is some set of integers and if in case it's defined in $x$ and $x-1$, $f(x) = f(x-1) + 1$ or $f(x) = f(x-1)$.

Tanya has found $n$ good functions $f_{1}, \ldots, f_{n}$, which are defined on all integers from $0$ to $10^{18}$ and $f_i(0) = 0$ and $f_i(10^{18}) = L$ for all $i$ from $1$ to $n$. It's an notorious coincidence that $n$ is a divisor of $L$.

She suggests Alesya a game. Using one question Alesya can ask Tanya a value of any single function in any single point. To win Alesya must choose integers $l_{i}$ and $r_{i}$ ($0 \leq l_{i} \leq r_{i} \leq 10^{18}$), such that $f_{i}(r_{i}) - f_{i}(l_{i}) \geq \frac{L}{n}$ (here $f_i(x)$ means the value of $i$-th function at point $x$) for all $i$ such that $1 \leq i \leq n$ so that for any pair of two functions their segments $[l_i, r_i]$ don't intersect (but may have one common point).

Unfortunately, Tanya doesn't allow to make more than $2 \cdot 10^{5}$ questions. Help Alesya to win!

It can be proved that it's always possible to choose $[l_i, r_i]$ which satisfy the conditions described above.

It's guaranteed, that Tanya doesn't change functions during the game, i.e. interactor is not adaptive

Input

The first line contains two integers $n$ and $L$ ($1 \leq n \leq 1000$, $1 \leq L \leq 10^{18}$, $n$ is a divisor of $L$)  — number of functions and their value in $10^{18}$.

Output

When you've found needed $l_i, r_i$, print $"!"$ without quotes on a separate line and then $n$ lines, $i$-th from them should contain two integers $l_i$, $r_i$ divided by space.

Interaction

To ask $f_i(x)$, print symbol "?" without quotes and then two integers $i$ and $x$ ($1 \leq i \leq n$, $0 \leq x \leq 10^{18}$). Note, you must flush your output to get a response.

After that, you should read an integer which is a value of $i$-th function in point $x$.

You're allowed not more than $2 \cdot 10^5$ questions.

To flush you can use (just after printing an integer and end-of-line):

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

Example

Input

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

Output

```
0
1
1
2
2
3
3
4
4
4
5
```

Note

In the example Tanya has $5$ same functions where $f(0) = 0$, $f(1) = 1$, $f(2) = 2$, $f(3) = 3$, $f(4) = 4$ and all remaining points have value $5$.

Alesya must choose two integers for all functions so that difference of values of a function in its points is not less than $\frac{L}{n}$ (what is $1$ here) and length of intersection of segments is zero.

One possible way is to choose pairs $[0$, $1]$, $[1$, $2]$, $[2$, $3]$, $[3$, $4]$ and $[4$, $5]$ for functions $1$, $2$, $3$, $4$ and $5$ respectively.

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

using namespace std;


static const long long MAX_COORD = 1000000000000000000LL;
static const long long LIMIT_QUERIES = 200000;
static const long long HARD_CAP = 400000; 


static int n;
static long long L;
static vector<pair<long long, long long>> funcs[1005];


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




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


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





long long get_func_val(int i, long long x) {
    long long val = 0;
    for (const auto& p : funcs[i]) {
        long long l = p.first;
        long long r = p.second;
        
        if (x <= l) continue;
        if (x >= r) val += (r - l);
        else val += (x - l);
    }
    return val;
}

int main(int argc, char* argv[]) {
    
    registerInteraction(argc, argv);
    
    
    
    n = inf.readInt();
    L = inf.readLong();
    
    for (int i = 1; i <= n; i++) {
        int k = inf.readInt();
        for (int j = 0; j < k; j++) {
            long long l = inf.readLong();
            long long r = inf.readLong();
            funcs[i].push_back({l, r});
        }
    }
    
    
    
    cout << n << " " << L << endl;
    
    
    log_metrics();
    
    
    string token;
    while (cin >> token) {
        if (token == "!") {
            break; 
        }
        
        int i_idx = -1;
        long long x_val = -1;
        bool parse_ok = true;
        
        
        if (token == "?") {
            if (!(cin >> i_idx >> x_val)) parse_ok = false;
        } else {
            
            try {
                i_idx = stoi(token);
            } catch (...) {
                parse_ok = false;
            }
            if (parse_ok && !(cin >> x_val)) parse_ok = false;
        }
        
        if (!parse_ok) {
            finish(_wa, "Invalid query format or unexpected EOF");
        }
        
        
        queries++;
        if (queries % 1000 == 0) log_metrics(); 
        
        if (queries > HARD_CAP) {
            finish(_pe, "Hard query limit exceeded");
        }
        
        
        if (i_idx < 1 || i_idx > n) {
            finish(_wa, format("Function index %d out of bounds [1, %d]", i_idx, n));
        }
        if (x_val < 0 || x_val > MAX_COORD) {
            finish(_wa, format("Coordinate %lld out of bounds [0, 10^18]", x_val));
        }
        
        
        long long ans = get_func_val(i_idx, x_val);
        cout << ans << endl;
    }
    
    
    
    vector<pair<long long, long long>> ans_intervals;
    ans_intervals.reserve(n);
    
    for (int i = 1; i <= n; i++) {
        long long l, r;
        if (!(cin >> l >> r)) {
            finish(_wa, "Failed to read answer intervals");
        }
        
        
        if (l < 0 || r > MAX_COORD || l > r) {
            finish(_wa, format("Invalid interval %d: [%lld, %lld]", i, l, r));
        }
        
        
        long long val_l = get_func_val(i, l);
        long long val_r = get_func_val(i, r);
        if (val_r - val_l < L / n) {
            finish(_wa, format("Insufficient value for function %d: %lld < %lld", i, val_r - val_l, L / n));
        }
        
        ans_intervals.push_back({l, r});
    }
    
    
    
    
    sort(ans_intervals.begin(), ans_intervals.end());
    
    for (size_t k = 0; k < ans_intervals.size() - 1; k++) {
        
        
        
        if (ans_intervals[k].second > ans_intervals[k+1].first) {
            finish(_wa, format("Intervals intersect: [%lld, %lld] and [%lld, %lld]", 
                ans_intervals[k].first, ans_intervals[k].second,
                ans_intervals[k+1].first, ans_intervals[k+1].second));
        }
    }
    
    finish(_ok, "Solution found");
    return 0;
}


Adaptive interactor (C++):

Test generator (C++):


















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

using namespace std;

using ll = long long;
const ll MAX_COORD = 1000000000000000000LL; 



vector<ll> partition_ll(int k, ll total_sum) {
    if (k <= 0) return {};
    if (k == 1) return {total_sum};
    vector<ll> seps;
    seps.reserve(k - 1);
    for (int i = 0; i < k - 1; ++i) {
        seps.push_back(rnd.next(0LL, total_sum));
    }
    seps.push_back(0);
    seps.push_back(total_sum);
    sort(seps.begin(), seps.end());
    
    vector<ll> res;
    res.reserve(k);
    for (int i = 0; i < k; ++i) {
        res.push_back(seps[i+1] - seps[i]);
    }
    return res;
}

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

    string mode = opt<string>("mode", "non");
    
    
    int n = opt<int>("n", -1);
    if (n == -1) {
        
        int r = rnd.next(100);
        if (r < 10) n = rnd.next(1, 10);          
        else if (r < 30) n = rnd.next(10, 100);   
        else n = rnd.next(100, 1000);             
    }

    
    ll L = opt<ll>("L", -1);
    if (L == -1) {
        
        ll max_mult = MAX_COORD / n;
        
        int r = rnd.next(100);
        ll mult;
        if (r < 10) mult = rnd.next(1LL, 100LL); 
        else if (r < 30) mult = rnd.next(100LL, min(1000000LL, max_mult));
        else mult = rnd.next(max_mult / 10 + 1, max_mult); 
        
        L = mult * n;
    }

    
    if (L % n != 0) {
        L = (L / n) * n;
        if (L == 0) L = n; 
    }
    if (L > MAX_COORD) L = (MAX_COORD / n) * n;

    
    cout << n << " " << L;

    if (mode == "adp") {
        
        cout << " " << rnd.next(1LL, MAX_COORD) << endl;
        return 0;
    }
    
    cout << endl;

    
    
    int fragmentation_type = rnd.next(3); 
    
    
    

    for (int i = 0; i < n; ++i) {
        int blocks = 1;
        if (fragmentation_type == 1) blocks = rnd.next(2, 5);
        else if (fragmentation_type == 2) blocks = rnd.next(5, 20);
        
        
        if (blocks > L) blocks = (int)L;
        if (blocks < 1) blocks = 1;

        
        vector<ll> ones = partition_ll(blocks, L);
        
        
        vector<ll> zeros = partition_ll(blocks + 1, MAX_COORD - L);
        
        
        
        vector<pair<ll, ll>> intervals;
        ll current_pos = 0;
        for (int j = 0; j < blocks; ++j) {
            current_pos += zeros[j]; 
            ll len = ones[j];
            if (len > 0) {
                intervals.push_back({current_pos, current_pos + len});
                current_pos += len;
            }
        }
        
        
        
        cout << intervals.size();
        for (auto &p : intervals) {
            cout << " " << p.first << " " << p.second;
        }
        cout << "\n";
    }

    return 0;
}