Problem: cf1007_c
Difficulty: medium
Categories: search
Time limit: 2000 ms, memory limit: 256 MB

This is an interactive problem.

Vasya and Vitya play a game. Vasya thought of two integers $a$ and $b$ from $1$ to $n$ and Vitya tries to guess them. Each round he tells Vasya two numbers $x$ and $y$ from $1$ to $n$. If both $x=a$ and $y=b$ then Vitya wins. Else Vasya must say one of the three phrases:

1. $x$ is less than $a$;
2. $y$ is less than $b$;
3. $x$ is greater than $a$ or $y$ is greater than $b$.

Vasya can't lie, but if multiple phrases are true, he may choose any of them. For example, if Vasya thought of numbers $2$ and $4$, then he answers with the phrase $3$ to a query $(3, 4)$, and he can answer with the phrase $1$ or phrase $3$ to a query $(1, 5)$.

Help Vitya win in no more than $600$ rounds.

Input

The first line contains a single integer $n$ ($1 \leq n \leq 10^{18}$) — the upper limit of the numbers.

Interaction

First, you need to read the number $n$, after that you can make queries.

To make a query, print two integers: $x$ and $y$ ($1 \leq x, y \leq n$), then flush the output.

After each query, read a single integer $ans$ ($0 \leq ans \leq 3$).

If $ans > 0$, then it is the number of the phrase said by Vasya.

If $ans = 0$, it means that you win and your program should terminate.

If you make more than $600$ queries or make an incorrect query, you will get Wrong Answer.

Your solution will get Idleness Limit Exceeded, if you don't print anything or forget to flush the output.

To flush you need to do the following right after printing a query and a line end:

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

Example

Input

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

Output

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

Note

Let's analyze the sample test. The chosen numbers are $2$ and $4$. The interactor was given two instructions.

For the query $(4, 3)$, it can return $2$ or $3$. Out of the two instructions the second one is chosen, so the interactor returns $a^{23}_2=3$.

For the query $(3, 4)$, it can return only $3$.

For the query $(3, 3)$, it can return $2$ or $3$. Out of the two instructions the first one is chosen (since in case of equal values, the least number is preferred), so the interactor returns $a^{23}_1=2$.

For the query $(1, 5)$, it can return $1$ or $3$. Out of the two instructions the first one is chosen, so the interactor returns $a^{13}_1=1$.

In the fifth query $(2, 4)$, the numbers are guessed correctly, the player wins.

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 = 600;


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


#define FINISH(verdict, ...) { log_metrics(); quitf(verdict, __VA_ARGS__); }

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

    
    
    
    long long n = inf.readLong();
    long long a = inf.readLong();
    long long b = inf.readLong();

    
    cout << n << endl;
    
    
    log_metrics();

    while (true) {
        
        string token;
        if (!(cin >> token)) {
            
            FINISH(_wa, "Unexpected end of stream (solution exited?)");
        }

        
        
        if (token == "?" || token == "!") {
            if (!(cin >> token)) {
                FINISH(_wa, "Unexpected end of stream after prefix");
            }
        }

        
        long long x;
        try {
            x = stoll(token);
        } catch (...) {
            FINISH(_wa, "Invalid integer format for x: %s", token.c_str());
        }

        
        long long y;
        if (!(cin >> y)) {
            FINISH(_wa, "Unexpected end of stream before y");
        }

        
        queries++;
        
        
        if (queries > query_limit) {
            FINISH(_wa, "Query limit exceeded (%lld > %lld)", queries, query_limit);
        }

        
        if (x < 1 || x > n || y < 1 || y > n) {
            FINISH(_wa, "Coordinates out of bounds: (%lld, %lld), n=%lld", x, y, n);
        }

        
        if (x == a && y == b) {
            cout << 0 << endl;
            FINISH(_ok, "Guessed correctly in %lld queries", queries);
        }

        
        
        
        
        vector<int> valid;
        if (x < a) valid.push_back(1);
        if (y < b) valid.push_back(2);
        if (x > a || y > b) valid.push_back(3);

        if (valid.empty()) {
            FINISH(_fail, "Internal logic error: no valid response for guess (%lld, %lld) with target (%lld, %lld)", x, y, a, b);
        }

        
        
        int response = valid[rnd.next(valid.size())];

        cout << response << endl;
    }

    return 0;
}


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

using namespace std;



typedef __int128_t int128;

struct Rect {
    long long x1, x2, y1, y2;
    int128 area() const {
        if (x1 > x2 || y1 > y2) return 0;
        return (int128)(x2 - x1 + 1) * (int128)(y2 - y1 + 1);
    }
};

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


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());
}


int128 total_area(const vector<Rect>& rects) {
    int128 sum = 0;
    for (const auto& r : rects) sum += r.area();
    return sum;
}





vector<Rect> apply_move(const vector<Rect>& current, int type, long long x, long long y) {
    vector<Rect> next_rects;
    if (type == 1) { 
        
        for (auto r : current) {
            r.x1 = max(r.x1, x + 1);
            if (r.x1 <= r.x2 && r.y1 <= r.y2) next_rects.push_back(r);
        }
    } else if (type == 2) { 
        
        for (auto r : current) {
            r.y1 = max(r.y1, y + 1);
            if (r.x1 <= r.x2 && r.y1 <= r.y2) next_rects.push_back(r);
        }
    } else if (type == 3) { 
        
        
        for (auto r : current) {
            long long ix1 = max(r.x1, x);
            long long ix2 = r.x2; 
            long long iy1 = max(r.y1, y);
            long long iy2 = r.y2;
            
            
            if (ix1 > ix2 || iy1 > iy2) {
                next_rects.push_back(r);
            } else {
                
                
                
                long long rx1 = r.x1;
                long long rx2 = min(r.x2, x - 1);
                if (rx1 <= rx2) {
                    next_rects.push_back({rx1, rx2, r.y1, r.y2});
                }
                
                
                long long bx1 = max(r.x1, x);
                long long bx2 = r.x2;
                long long by1 = r.y1;
                long long by2 = min(r.y2, y - 1);
                if (bx1 <= bx2 && by1 <= by2) {
                    next_rects.push_back({bx1, bx2, by1, by2});
                }
            }
        }
    }
    return next_rects;
}

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

    
    long long n = inf.readLong();
    

    
    cout << n << endl;

    
    vector<Rect> feasible;
    feasible.push_back({1, n, 1, n});

    
    
    
    int hard_cap = 2000;

    while (true) {
        long long x, y;
        
        if (!(cin >> x >> y)) {
            finish(_wa, "Unexpected EOF or invalid query format");
        }
        
        queries++;
        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded");
        }

        
        if (x < 1 || x > n || y < 1 || y > n) {
            finish(_wa, format("Query (%lld, %lld) out of range [1, %lld]", x, y, n));
        }

        
        
        vector<Rect> f1 = apply_move(feasible, 1, x, y);
        int128 a1 = total_area(f1);

        
        vector<Rect> f2 = apply_move(feasible, 2, x, y);
        int128 a2 = total_area(f2);

        
        vector<Rect> f3 = apply_move(feasible, 3, x, y);
        int128 a3 = total_area(f3);

        
        int128 max_a = a1;
        int ans = 1;
        
        if (a2 > max_a) {
            max_a = a2;
            ans = 2;
        }
        
        
        
        if (a3 > max_a) {
            max_a = a3;
            ans = 3;
        } else if (a3 == max_a && max_a > 0) {
            
            
            ans = 3;
        }

        if (max_a == 0) {
            
            
            cout << 0 << endl;
            finish(_ok, format("Guessed correctly in %lld queries", queries));
        } else {
            
            if (ans == 1) feasible = f1;
            else if (ans == 2) feasible = f2;
            else feasible = f3;

            cout << ans << endl;
        }
    }

    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");
    
    
    long long n = opt<long long>("n", -1);
    
    
    int seed = atoi(argv[1]);
    
    
    if (n == -1) {
        if (seed == 1) n = 5; 
        else if (seed == 2) n = 3; 
        else if (seed == 3) n = 1; 
        else if (seed == 4) n = 1000000000000000000LL; 
        else if (seed == 5) n = 999999999999999999LL; 
        else {
            
            
            if (rnd.next(2)) {
                n = rnd.next(1LL, 1000000000000000000LL);
            } else {
                int p = rnd.next(0, 18);
                long long lower = 1;
                for (int i = 0; i < p; ++i) lower *= 10;
                long long upper = lower * 10 - 1;
                if (p == 18) upper = 1000000000000000000LL;
                if (upper > 1000000000000000000LL) upper = 1000000000000000000LL;
                n = rnd.next(lower, upper);
            }
        }
    }

    if (mode == "non") {
        long long a, b;
        
        
        
        if (seed == 1 && n == 5) {
            a = 2; b = 4; 
        } else if (seed == 2 && n == 3) {
            a = 3; b = 1; 
        } else if (seed == 3 && n == 1) {
            a = 1; b = 1;
        } else {
            
            int strategy = rnd.next(10);
            if (strategy == 0) {
                
                a = 1; b = 1;
            } else if (strategy == 1) {
                
                a = n; b = n;
            } else if (strategy == 2) {
                
                a = 1; b = n;
            } else if (strategy == 3) {
                
                a = n; b = 1;
            } else if (strategy < 6) {
                
                a = rnd.next(1LL, n);
                b = rnd.next(1LL, n);
            } else if (strategy < 8) {
                
                a = rnd.next(1LL, n);
                b = a + rnd.next(-100LL, 100LL);
                b = max(1LL, min(n, b));
            } else {
                
                a = rnd.next(1LL, n);
                b = n - a + rnd.next(-100LL, 100LL);
                b = max(1LL, min(n, b));
            }
        }
        cout << n << "\n" << a << " " << b << endl;
    } 
    else if (mode == "adp") {
        
        
        cout << n << endl;
    } 
    else {
        quitf(_fail, "Unknown mode: %s", mode.c_str());
    }

    return 0;
}