Problem: cf1010_b
Difficulty: easy
Categories: search
Time limit: 1000 ms, memory limit: 256 MB

This is an interactive problem.

Natasha is going to fly to Mars. Finally, Natasha sat in the rocket. She flies, flies... but gets bored. She wishes to arrive to Mars already! So she decides to find something to occupy herself. She couldn't think of anything better to do than to calculate the distance to the red planet.

Let's define $x$ as the distance to Mars. Unfortunately, Natasha does not know $x$. But it is known that $1 \le x \le m$, where Natasha knows the number $m$. Besides, $x$ and $m$ are positive integers.

Natasha can ask the rocket questions. Every question is an integer $y$ ($1 \le y \le m$). The correct answer to the question is $-1$, if $x<y$, $0$, if $x=y$, and $1$, if $x>y$. But the rocket is broken — it does not always answer correctly. Precisely: let the correct answer to the current question be equal to $t$, then, if the rocket answers this question correctly, then it will answer $t$, otherwise it will answer $-t$.

In addition, the rocket has a sequence $p$ of length $n$. Each element of the sequence is either $0$ or $1$. The rocket processes this sequence in the cyclic order, that is $1$-st element, $2$-nd, $3$-rd, $\ldots$, $(n-1)$-th, $n$-th, $1$-st, $2$-nd, $3$-rd, $\ldots$, $(n-1)$-th, $n$-th, $\ldots$. If the current element is $1$, the rocket answers correctly, if $0$ — lies. Natasha doesn't know the sequence $p$, but she knows its length — $n$.

You can ask the rocket no more than $60$ questions.

Help Natasha find the distance to Mars. Assume, that the distance to Mars does not change while Natasha is asking questions.

Your solution will not be accepted, if it does not receive an answer $0$ from the rocket (even if the distance to Mars is uniquely determined by the already received rocket's answers).

Input

The first line contains two integers $m$ and $n$ ($1 \le m \le 10^9$, $1 \le n \le 30$) — the maximum distance to Mars and the number of elements in the sequence $p$.

Interaction

You can ask the rocket no more than $60$ questions.

To ask a question, print a number $y$ ($1\le y\le m$) and an end-of-line character, then do the operation flush and read the answer to the question.

If the program reads $0$, then the distance is correct and you must immediately terminate the program (for example, by calling exit(0)). If you ignore this, you can get any verdict, since your program will continue to read from the closed input stream.

If at some point your program reads $-2$ as an answer, it must immediately end (for example, by calling exit(0)). You will receive the "Wrong answer" verdict, and this will mean that the request is incorrect or the number of requests exceeds $60$. If you ignore this, you can get any verdict, since your program will continue to read from the closed input stream.

If your program's request is not a valid integer between $-2^{31}$ and $2^{31}-1$ (inclusive) without leading zeros, then you can get any verdict.

You can get "Idleness limit exceeded" if you don't print anything or if you forget to flush the output.

To flush the output buffer you can use (after printing a query 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 2  
1  
-1  
-1  
1  
0
```

Output

```
1  
2  
4  
5  
3
```


Really:

on the first query ($1$) the correct answer is $1$, the rocket answered correctly: $1$;

on the second query ($2$) the correct answer is $1$, the rocket answered incorrectly: $-1$;

on the third query ($4$) the correct answer is $-1$, the rocket answered correctly: $-1$;

on the fourth query ($5$) the correct answer is $-1$, the rocket answered incorrectly: $1$;

on the fifth query ($3$) the correct and incorrect answer is $0$.

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 bool parseStrictInt32(const string& s, int& out) {
    if (s.empty()) return false;
    int i = 0;
    bool neg = false;
    if (s[0] == '-') {
        neg = true;
        i = 1;
        if ((int)s.size() == 1) return false;
    }
    for (int j = i; j < (int)s.size(); j++) {
        if (s[j] < '0' || s[j] > '9') return false;
    }
    if (i < (int)s.size() && s[i] == '0' && (int)s.size() - i > 1) return false;
    if (neg && (int)s.size() - i == 1 && s[i] == '0') return false; 

    long long val = 0;
    for (int j = i; j < (int)s.size(); j++) {
        val = val * 10 + (s[j] - '0');
        if (!neg && val > (long long)INT_MAX) return false;
        if (neg && val > 2147483648LL) return false; 
    }
    if (!neg) {
        out = (int)val;
        return true;
    } else {
        if (val == 2147483648LL) out = INT_MIN;
        else out = -(int)val;
        return true;
    }
}

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

    try {
        long long m = inf.readLong();
        int n = inf.readInt();
        long long x = inf.readLong();
        string p = inf.readToken();

        if (m < 1 || m > 1000000000LL) finish(_pe, "Invalid m in input.");
        if (n < 1 || n > 30) finish(_pe, "Invalid n in input.");
        if (x < 1 || x > m) finish(_pe, "Invalid x in input.");
        if ((int)p.size() != n) finish(_pe, "Invalid p length in input.");
        for (char c : p) if (c != '0' && c != '1') finish(_pe, "Invalid p character in input.");

        query_limit = 60;
        log_metrics(); 

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

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

        int idx = 0;
        while (true) {
            if (queries >= hard_cap) finish(_pe, "Hard cap exceeded (possible infinite loop).");

            string tok;
            if (!(cin >> tok)) {
                finish(_wa, "Contestant terminated without receiving answer 0.");
            }

            int y32;
            if (!parseStrictInt32(tok, y32)) {
                
                try {
                    cout << -2 << "\n";
                    cout.flush();
                } catch (...) {}
                finish(_wa, "Invalid integer format in query.");
            }

            long long y = (long long)y32;
            queries++;

            if (queries > query_limit) {
                try {
                    cout << -2 << "\n";
                    cout.flush();
                } catch (...) {}
                finish(_wa, "Query limit exceeded.");
            }

            if (y < 1 || y > m) {
                try {
                    cout << -2 << "\n";
                    cout.flush();
                } catch (...) {}
                finish(_wa, "Query out of range.");
            }

            int t = 0;
            if (x < y) t = -1;
            else if (x > y) t = 1;
            else t = 0;

            int ans = t;
            if (t != 0 && p[idx] == '0') ans = -t;

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

            idx++;
            if (idx == n) idx = 0;

            if (t == 0) {
                finish(_ok, "OK");
            }
        }
    } catch (const std::exception& e) {
        finish(_pe, string("Exception: ") + e.what());
    } catch (...) {
        finish(_pe, "Unknown exception.");
    }
}


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

struct SplitMix64 {
    uint64_t x;
    explicit SplitMix64(uint64_t seed) : x(seed) {}
    uint64_t next() {
        uint64_t z = (x += 0x9e3779b97f4a7c15ULL);
        z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
        z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
        return z ^ (z >> 31);
    }
};

static bool parseInt32TokenStrict(const string& s, long long& out) {
    if (s.empty()) return false;
    int pos = 0;
    bool neg = false;
    if (s[0] == '-') {
        neg = true;
        pos = 1;
        if (pos >= (int)s.size()) return false;
    }
    if (s[pos] == '0' && (int)s.size() - pos > 1) return false; 
    unsigned long long v = 0;
    for (int i = pos; i < (int)s.size(); i++) {
        char c = s[i];
        if (c < '0' || c > '9') return false;
        v = v * 10ULL + (unsigned long long)(c - '0');
        if (!neg && v > 2147483647ULL) return false;
        if (neg && v > 2147483648ULL) return false;
    }
    if (neg && v == 0ULL) return false; 
    out = neg ? -(long long)v : (long long)v;
    return true;
}

static long long m = 0;
static int n = 0;

static bool fixed_instance = false;
static bool decided = false;
static long long x_hidden = -1;
static vector<int> p_bits;
static long long query_index = 0;

static void decide_instance(long long first_y) {
    uint64_t seed = 0x243f6a8885a308d3ULL;
    seed ^= (uint64_t)m + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2);
    seed ^= (uint64_t)(unsigned)n + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2);
    seed ^= (uint64_t)first_y + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2);

    SplitMix64 rng(seed);

    p_bits.assign(n, 1);
    for (int i = 0; i < n; i++) {
        
        int bit = ((int)(rng.next() % 100ULL) < 38) ? 1 : 0;
        p_bits[i] = bit;
    }
    if (n > 1) {
        bool has0 = false, has1 = false;
        for (int b : p_bits) has0 |= (b == 0), has1 |= (b == 1);
        if (!has0) p_bits[(int)(rng.next() % (uint64_t)n)] = 0;
        if (!has1) p_bits[(int)(rng.next() % (uint64_t)n)] = 1;
    }

    if (m == 1) {
        x_hidden = 1;
    } else {
        long long base;
        if (m >= 2) {
            unsigned long long span = (unsigned long long)(m - 1); 
            base = 2 + (long long)(rng.next() % span);
        } else {
            base = 1;
        }
        if (base == first_y) {
            if (base < m) base++;
            else base--;
        }
        if (base < 1) base = 1;
        if (base > m) base = m;
        x_hidden = base;
    }

    decided = true;
}

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

    try {
        m = inf.readLong(1, 1000000000LL, "m");
        n = inf.readInt(1, 30, "n");

        query_limit = 60;
        log_metrics(); 

        
        if (!inf.seekEof()) {
            long long x_in = inf.readLong();
            string p_in = "";
            if (!inf.seekEof()) p_in = inf.readToken();

            if (x_in < 1 || x_in > m) {
                
                x_in = min(max(1LL, x_in), m);
            }
            vector<int> bits(n, 1);
            bool ok = ((int)p_in.size() == n);
            if (ok) {
                for (int i = 0; i < n; i++) {
                    if (p_in[i] == '0') bits[i] = 0;
                    else if (p_in[i] == '1') bits[i] = 1;
                    else { ok = false; break; }
                }
            }
            if (!ok) {
                for (int i = 0; i < n; i++) bits[i] = (i & 1);
            }

            fixed_instance = true;
            decided = true;
            x_hidden = x_in;
            p_bits = std::move(bits);
        } else {
            fixed_instance = false;
            decided = false;
            p_bits.clear();
            x_hidden = -1;
        }

        cout << m << " " << n << endl;

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

        while (true) {
            string tok;
            if (!(cin >> tok)) {
                finish(_wa, "contestant terminated without receiving 0");
            }

            long long y_ll = 0;
            if (!parseInt32TokenStrict(tok, y_ll)) {
                
                finish(_pe, "invalid integer token");
            }

            if (y_ll < 1 || y_ll > m) {
                cout << -2 << endl;
                finish(_pe, "query out of range");
            }

            long long y = y_ll;

            if (!decided) {
                decide_instance(y);
            }

            int truth = 0;
            if (x_hidden < y) truth = -1;
            else if (x_hidden > y) truth = 1;
            else truth = 0;

            int bit = p_bits[(int)(query_index % (long long)n)];
            query_index++;
            queries++;
            if (queries > hard_cap) {
                finish(_pe, "too many queries (hard cap exceeded)");
            }

            int ans = (truth == 0 ? 0 : (bit ? truth : -truth));

            cout << ans << endl;

            if (ans == 0) {
                finish(_ok, "found x");
            }
        }
    } catch (const std::exception& e) {
        finish(_pe, string("exception: ") + e.what());
    } catch (...) {
        finish(_pe, "unknown exception");
    }
}


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

static string makeStructuredPattern(int n) {
    vector<int> p(n, 1);

    
    for (int i = 0; i < n; i++) p[i] = (rnd.next(0, 99) < 62 ? 0 : 1);

    int blocks = rnd.next(3, 7);
    int pos = 0;
    for (int b = 0; b < blocks && pos < n; b++) {
        int len = rnd.next(2, 8);
        int bit = (b % 2 == 0 ? 0 : 1);
        if (rnd.next(0, 99) < 35) bit ^= 1;
        for (int k = 0; k < len && pos < n; k++, pos++) p[pos] = bit;
    }
    while (pos < n) {
        p[pos] = (rnd.next(0, 99) < 55 ? 0 : 1);
        pos++;
    }

    string s;
    s.reserve(n);
    for (int v : p) s.push_back(char('0' + v));
    return s;
}

static string makeAlternating(int n, int start) {
    string s;
    s.reserve(n);
    for (int i = 0; i < n; i++) s.push_back(char('0' + ((start + i) & 1)));
    return s;
}

static string makeAll(int n, char bit) { return string(n, bit); }

static string makeBiasedRandom(int n, int p_one_percent) {
    p_one_percent = max(0, min(100, p_one_percent));
    string s;
    s.reserve(n);
    for (int i = 0; i < n; i++) s.push_back(rnd.next(0, 99) < p_one_percent ? '1' : '0');
    return s;
}

static string makePattern(int n, int kind) {
    
    switch (kind) {
        case 0: return makeAll(n, '0');
        case 1: return makeAll(n, '1');
        case 2: return makeAlternating(n, 0);
        case 3: return makeAlternating(n, 1);
        case 4: return makeBiasedRandom(n, 20); 
        case 5: return makeBiasedRandom(n, 80); 
        case 6: return makeStructuredPattern(n);
        default: return makeBiasedRandom(n, 50);
    }
}

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

    string mode = opt<string>("mode", "non");
    int custom = opt<int>("custom", 0);

    if (mode != "non" && mode != "adp") {
        mode = "non";
    }

    if (mode != "non" && mode != "adp") mode = "non";

    
    
    
    long long m = opt<long long>("m", 1000000000LL);
    int n = opt<int>("n", 30);
    long long x = opt<long long>("x", -1);
    string p = opt<string>("p", "");

    int seedInt = atoi(argv[1]);

    if (!custom) {
        
        if (seedInt == 1) {
            m = 1;
            n = 1;
            x = 1;
            p = "1";
        } else if (seedInt == 2) {
            m = 1000000000LL;
            n = 30;
            x = m;
            p = makePattern(n, 0); 
        } else if (seedInt == 3) {
            m = 1000000000LL;
            n = 30;
            x = 2;
            p = makePattern(n, 1); 
        } else if (seedInt == 4) {
            m = 1000000000LL;
            n = 30;
            x = m - 1;
            p = makePattern(n, 2); 
        } else if (seedInt == 5) {
            m = 2;
            n = 30;
            x = 2;
            p = makePattern(n, 3); 
        } else {
            m = 1000000000LL;
            n = (seedInt % 7 == 0 ? 29 : 30);

            
            
            int xKind = seedInt % 8;
            if (xKind == 0) x = 1;
            else if (xKind == 1) x = 2;
            else if (xKind == 2) x = m;
            else if (xKind == 3) x = m - 1;
            else if (xKind == 4) x = m / 2;
            else if (xKind == 5) x = m / 2 + 1;
            else x = rnd.next(2LL, m);

            int pat = seedInt % 7; 
            p = makePattern(n, pat);
        }
    }

    m = max(1LL, min(1000000000LL, m));
    n = max(1, min(30, n));

    if (x < 1 || x > m) {
        x = (m == 1 ? 1 : rnd.next(1LL, m));
    }

    if ((int)p.size() != n) {
        p = makePattern(n, 6);
    } else {
        for (char& c : p) {
            if (c != '0' && c != '1') c = (rnd.next(0, 1) ? '1' : '0');
        }
    }

    cout << m << " " << n << "\n";
    cout << x << "\n";
    cout << p << "\n";
    return 0;
}