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

The only difference between easy and hard versions is the maximum number of queries. In this version, you are allowed to ask at most $1000$ queries.

This is an interactive problem.

You are playing a game. The circle is divided into $n$ sectors, sectors are numbered from $1$ to $n$ in some order. You are in the adjacent room and do not know either the number of sectors or their numbers. There is also an arrow that initially points to some sector. Initially, the host tells you the number of the sector to which the arrow points. After that, you can ask the host to move the arrow $k$ sectors counterclockwise or clockwise at most $1000$ times. And each time you are told the number of the sector to which the arrow points.

Your task is to determine the integer $n$ — the number of sectors in at most $1000$ queries.

It is guaranteed that $1 \le n \le 10^6$.

Input

The input consists of a single integer $x$ ($1 \le x \le n$) — the number of the initial sector.

Output

After you determine the integer $n$ — the number of sectors, you should output "! n" ($1 \le n \le 10^6$). After that the program should immediately terminate.

Note that, printing the answer does not count as a query.

It is guaranteed that the integer $n$ and the numbers of the sectors are fixed initially and will not be changed by the jury program depending on the queries.

Interaction

After reading the description of the input, you may ask queries. Queries can be of two types:

1. "+ k" ($0 \le k \le 10^9$) — ask to move the arrow $k$ sectors clockwise.
2. "- k" ($0 \le k \le 10^9$) — ask to move the arrow $k$ sectors counterclockwise.

After each query, you should read an integer $x$ ($1 \le x \le n$) — the number of the current sector to which the arrow points.

You are allowed to make at most $1000$ queries in total.

If you make too many queries, you will get Wrong answer.

After printing a query or the answer, do not forget to output a 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.

Example

Input

```
1

5

6

7

2

10

9

8

4

3

1
```

Output

```
+ 1

+ 1

+ 1

+ 1

+ 1

+ 1

+ 1

+ 1

+ 1

+ 1

! 10
```

Note

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


static long long queries = 0;
static long long query_limit = 1000;
static const long long HARD_CAP = 200000;


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(1, 1000000, "n");
    vector<int> p(n);
    for (int i = 0; i < n; ++i) {
        p[i] = inf.readInt(1, n, format("p[%d]", i));
    }

    
    
    query_limit = 1000;
    
    
    
    int current_pos = 0;

    
    
    cout << p[current_pos] << endl;
    
    
    log_metrics();

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

        string token;
        if (!(cin >> token)) {
            finish(_pe, "Unexpected EOF: expected query or answer");
        }

        
        if (token == "?") {
            if (!(cin >> token)) {
                finish(_pe, "Unexpected EOF after '?'");
            }
        }

        if (token == "!") {
            
            long long ans_n;
            if (!(cin >> ans_n)) {
                finish(_pe, "Expected number after '!'");
            }

            if (ans_n == n) {
                finish(_ok, format("Correct! n=%d, queries=%lld", n, queries));
            } else {
                finish(_wa, format("Wrong answer. Expected n=%d, found %lld", n, ans_n));
            }
        } 
        else if (token == "+" || token == "-") {
            
            long long k;
            if (!(cin >> k)) {
                finish(_pe, "Expected integer k after operation");
            }

            
            if (k < 0 || k > 1000000000LL) {
                finish(_pe, format("k out of bounds: %lld", k));
            }

            
            if (token == "+") {
                
                current_pos = (int)((current_pos + k) % n);
            } else {
                
                long long step = k % n;
                current_pos = (int)((current_pos - step + n) % n);
            }

            queries++;

            
            cout << p[current_pos] << endl;

            
            if (queries % 10 == 0) {
                log_metrics();
            }
        } 
        else {
            finish(_pe, format("Invalid token: '%s'", token.c_str()));
        }
    }

    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 = 1000;
static const long long HARD_CAP = 20000;


static void log_metrics() {
    try {
        
        if (tout.is_open()) {
            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(1, 1000000, "n");

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

    
    
    vector<int> sector_labels(n, -1);
    
    
    
    long long current_index = 0;
    
    
    sector_labels[current_index] = available_labels.back();
    available_labels.pop_back();
    
    
    cout << sector_labels[current_index] << endl;

    
    while (true) {
        
        
        if (queries > HARD_CAP) {
            finish(_pe, "Hard query limit exceeded");
        }
        
        
        string type;
        if (!(cin >> type)) {
            finish(_pe, "Unexpected end of file from contestant");
        }
        
        if (type == "!") {
            
            long long ans;
            if (!(cin >> ans)) {
                finish(_pe, "Expected integer after '!'");
            }
            
            if (ans == n) {
                finish(_ok, "Correct");
            } else {
                finish(_wa, format("Wrong answer: expected %d, found %lld", n, ans));
            }
        } else if (type == "+" || type == "-") {
            
            long long k;
            if (!(cin >> k)) {
                finish(_pe, "Expected integer k after +/-");
            }
            
            
            if (k < 0 || k > 1000000000LL) {
                 finish(_pe, format("k is out of range: %lld", k));
            }
            
            
            queries++;
            
            
            if (type == "+") {
                current_index = (current_index + k) % n;
            } else {
                
                long long rem = (current_index - k) % n;
                if (rem < 0) rem += n;
                current_index = rem;
            }
            
            
            if (sector_labels[current_index] == -1) {
                sector_labels[current_index] = available_labels.back();
                available_labels.pop_back();
            }
            
            
            cout << sector_labels[current_index] << endl;
            
        } else {
            finish(_pe, "Unknown query type: " + type);
        }
    }
    
    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<int>("n", -1);

    if (n == -1) {
        
        string seed_str = argv[1];
        long long seed_val = 0;
        bool is_small_seed = true;
        
        for (char c : seed_str) {
            if (!isdigit(c)) {
                is_small_seed = false;
                break;
            }
            seed_val = seed_val * 10 + (c - '0');
            if (seed_val > 100) { 
                is_small_seed = false; 
                break; 
            }
        }

        if (is_small_seed && seed_val >= 1 && seed_val <= 10) {
            
            switch (seed_val) {
                case 1: n = 1; break;
                case 2: n = 2; break;
                case 3: n = 1000000; break; 
                case 4: n = 999999; break;  
                case 5: n = 1000; break;    
                case 6: n = 1001; break;    
                case 7: n = 500000; break;  
                case 8: n = 3; break;
                case 9: n = 10; break;
                case 10: n = rnd.next(1, 100); break;
            }
        } else {
            
            
            int t = rnd.next(100);
            if (t < 5) n = rnd.next(1, 100);
            else if (t < 15) n = rnd.next(101, 1000);
            else if (t < 30) n = rnd.next(1001, 100000);
            else if (t < 95) n = rnd.next(900000, 1000000); 
            else n = rnd.next(1, 1000000);
        }
    }

    
    n = max(1, min(n, 1000000));

    
    cout << n << endl;

    if (mode == "non") {
        
        
        vector<int> p = rnd.perm(n, 1);
        println(p);
    } else if (mode == "adp") {
        
        
    }

    return 0;
}