Problem: cf1428_h
Difficulty: hard
Categories: search, math
Time limit: 1000 ms, memory limit: 256 MB

This is an interactive problem.

To prevent the mischievous rabbits from freely roaming around the zoo, Zookeeper has set up a special lock for the rabbit enclosure. This lock is called the Rotary Laser Lock.

The lock consists of $n$ concentric rings numbered from $0$ to $n-1$. The innermost ring is ring $0$ and the outermost ring is ring $n-1$. All rings are split equally into $nm$ sections each. Each of those rings contains a single metal arc that covers exactly $m$ contiguous sections. At the center of the ring is a core and surrounding the entire lock are $nm$ receivers aligned to the $nm$ sections.

The core has $nm$ lasers that shine outward from the center, one for each section. The lasers can be blocked by any of the arcs. A display on the outside of the lock shows how many lasers hit the outer receivers.

 ![](https://espresso.codeforces.com/32f94ff5242137b3aec3a5ef6f5dfcc9b456bcce.png) 

In the example above, there are $n=3$ rings, each covering $m=4$ sections. The arcs are colored in green (ring $0$), purple (ring $1$), and blue (ring $2$) while the lasers beams are shown in red. There are $nm=12$ sections and $3$ of the lasers are not blocked by any arc, thus the display will show $3$ in this case.

Wabbit is trying to open the lock to free the rabbits, but the lock is completely opaque, and he cannot see where any of the arcs are. Given the relative positions of the arcs, Wabbit can open the lock on his own.

To be precise, Wabbit needs $n-1$ integers $p_1,p_2,\ldots,p_{n-1}$ satisfying $0 \leq p_i < nm$ such that for each $i$ $(1 \leq i < n)$, Wabbit can rotate ring $0$ clockwise exactly $p_i$ times such that the sections that ring $0$ covers perfectly aligns with the sections that ring $i$ covers. In the example above, the relative positions are $p_1 = 1$ and $p_2 = 7$.

To operate the lock, he can pick any of the $n$ rings and rotate them by $1$ section either clockwise or anti-clockwise. You will see the number on the display after every rotation.

Because his paws are small, Wabbit has asked you to help him to find the relative positions of the arcs after all of your rotations are completed. You may perform up to $15000$ rotations before Wabbit gets impatient.

Input

The first line consists of 2 integers $n$ and $m$ $(2 \leq n \leq 100, 2 \leq m \leq 20)$, indicating the number of rings and the number of sections each ring covers.

Interaction

To perform a rotation, print on a single line "? x d" where $x$ $(0 \leq x < n)$ is the ring that you wish to rotate and $d$ $(d \in \{-1,1\})$ is the direction that you would like to rotate in. $d=1$ indicates a clockwise rotation by $1$ section while $d=-1$ indicates an anticlockwise rotation by $1$ section.

For each query, you will receive a single integer $a$: the number of lasers that are not blocked by any of the arcs after the rotation has been performed.

Once you have figured out the relative positions of the arcs, print ! followed by $n-1$ integers $p_1, p_2, \ldots, p_{n-1}$.

Do note that the positions of the rings are predetermined for each test case and won't change during the interaction process.

After printing a query do not forget to output the end of line and flush the output. Otherwise, you will get Idleness limit exceeded verdict.

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 documentation for other languages.

Example

Input

```
3 4

4

4

3
```

Output

```
? 0 1

? 2 -1

? 1 1

! 1 5
```

Note

For the first test, the configuration is the same as shown on the picture from the statement.

After the first rotation (which is rotating ring $0$ clockwise by $1$ section), we obtain the following configuration:

 ![](https://espresso.codeforces.com/a3ca503acc94f61b8b25428e93aa5bb3edc3c761.png) 

After the second rotation (which is rotating ring $2$ counter-clockwise by $1$ section), we obtain the following configuration:

 ![](https://espresso.codeforces.com/955a2f5c4f50184d87789b5a97e5ad7c3310c859.png) 

After the third rotation (which is rotating ring $1$ clockwise by $1$ section), we obtain the following configuration:

 ![](https://espresso.codeforces.com/71f95f75b83b810f4f92837351386d9060df2b2c.png) 

If we rotate ring $0$ clockwise once, we can see that the sections ring $0$ covers will be the same as the sections that ring $1$ covers, hence $p_1=1$.

If we rotate ring $0$ clockwise five times, the sections ring $0$ covers will be the same as the sections that ring $2$ covers, hence $p_2=5$.

Note that if we will make a different set of rotations, we can end up with different values of $p_1$ and $p_2$ at the end.

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


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(2, 100, "n");
    int m = inf.readInt(2, 20, "m");
    int total_sections = n * m;

    
    
    vector<int> pos(n);
    for (int i = 0; i < n; i++) {
        pos[i] = inf.readInt(0, total_sections - 1, format("pos[%d]", i));
    }

    
    log_metrics();

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

    string token;
    
    while (cin >> token) {
        if (token == "!") {
            
            
            vector<int> ans(n - 1);
            for (int i = 0; i < n - 1; i++) {
                string val_s;
                if (!(cin >> val_s)) {
                    finish(_pe, "Unexpected end of output while reading answer");
                }
                try {
                    ans[i] = stoi(val_s);
                } catch (...) {
                    finish(_pe, "Answer elements must be integers");
                }
            }

            
            
            
            
            vector<int> expected(n - 1);
            for (int i = 1; i < n; i++) {
                int val = (pos[i] - pos[0]) % total_sections;
                if (val < 0) val += total_sections;
                expected[i - 1] = val;
            }

            
            bool ok = true;
            for (int i = 0; i < n - 1; i++) {
                if (ans[i] != expected[i]) {
                    ok = false;
                    break;
                }
            }

            if (ok) {
                finish(_ok, format("Correct! Used %lld queries.", queries));
            } else {
                string exp_s = "", fnd_s = "";
                int limit_disp = min((int)expected.size(), 5);
                for (int i = 0; i < limit_disp; ++i) exp_s += to_string(expected[i]) + " ";
                for (int i = 0; i < limit_disp; ++i) fnd_s += to_string(ans[i]) + " ";
                if (expected.size() > 5) { exp_s += "..."; fnd_s += "..."; }
                finish(_wa, format("Wrong answer. Expected (first 5): %s Found: %s", exp_s.c_str(), fnd_s.c_str()));
            }
        } else {
            
            
            int x = -1, d = 0;

            if (token == "?") {
                string s_x, s_d;
                if (!(cin >> s_x >> s_d)) finish(_pe, "Unexpected end of output reading query args");
                try {
                    x = stoi(s_x);
                    d = stoi(s_d);
                } catch (...) {
                    finish(_pe, "Query args must be integers");
                }
            } else {
                
                try {
                    x = stoi(token);
                } catch (...) {
                    finish(_pe, "Expected '?' or integer ring index");
                }
                
                string s_d;
                if (!(cin >> s_d)) finish(_pe, "Unexpected end of output reading direction");
                try {
                    d = stoi(s_d);
                } catch (...) {
                    finish(_pe, "Direction must be integer");
                }
            }

            
            if (x < 0 || x >= n) {
                finish(_pe, format("Ring index %d out of bounds [0, %d)", x, n));
            }
            if (d != 1 && d != -1) {
                finish(_pe, format("Direction %d invalid, must be 1 or -1", d));
            }

            queries++;
            
            if (queries > 200000) {
                finish(_pe, "Too many queries (hard cap exceeded)");
            }

            
            pos[x] = (pos[x] + d) % total_sections;
            if (pos[x] < 0) pos[x] += total_sections;

            
            
            static vector<int> counts;
            if ((int)counts.size() != total_sections) counts.assign(total_sections, 0);
            else fill(counts.begin(), counts.end(), 0);

            for (int i = 0; i < n; i++) {
                int p = pos[i];
                
                for (int k = 0; k < m; k++) {
                    int idx = p + k;
                    if (idx >= total_sections) idx -= total_sections;
                    counts[idx]++;
                }
            }

            int visible = 0;
            for (int i = 0; i < total_sections; i++) {
                if (counts[i] == 0) visible++;
            }

            
            cout << visible << endl;

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

    finish(_pe, "Unexpected end of output (did not receive answer)");
    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 = 15000; 
static const int HARD_CAP = 30000;    



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


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();
    int m = inf.readInt();
    int nm = n * m;

    
    
    
    vector<int> s(n);
    bool input_ok = true;
    for (int i = 0; i < n; i++) {
        
        if (inf.seekEof()) {
            input_ok = false;
            break;
        }
        s[i] = inf.readInt();
    }

    
    
    if (!input_ok) {
        mt19937 rng(1337);
        for (int i = 0; i < n; i++) {
            s[i] = rng() % nm;
        }
    }

    
    log_metrics();

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

    
    vector<bool> covered(nm);

    while (true) {
        
        if (queries > HARD_CAP) {
            finish(_pe, "Too many queries (hard cap exceeded)");
        }

        
        string type;
        if (!(cin >> type)) {
            
            finish(_pe, "Unexpected end of output from contestant");
        }

        if (type == "!") {
            
            vector<int> p_ans(n - 1);
            for (int i = 0; i < n - 1; i++) {
                if (!(cin >> p_ans[i])) {
                    finish(_pe, "Incomplete final answer");
                }
            }

            
            
            
            
            
            
            for (int i = 1; i < n; i++) {
                int expected = (s[i] - s[0]);
                if (expected < 0) expected += nm;
                expected %= nm;

                if (p_ans[i - 1] != expected) {
                    finish(_wa, format("Wrong relative position for ring %d. Expected %d, found %d", 
                                       i, expected, p_ans[i - 1]));
                }
            }

            finish(_ok, "Correct relative positions found");

        } else if (type == "?") {
            
            int x, d;
            if (!(cin >> x >> d)) {
                finish(_pe, "Invalid query format");
            }

            queries++;

            
            if (x < 0 || x >= n) {
                finish(_pe, format("Ring index %d out of bounds [0, %d)", x, n));
            }
            if (d != 1 && d != -1) {
                finish(_pe, format("Invalid direction %d. Must be 1 (CW) or -1 (CCW)", d));
            }

            
            
            s[x] += d;
            if (s[x] >= nm) s[x] -= nm;
            if (s[x] < 0) s[x] += nm;

            
            
            fill(covered.begin(), covered.end(), false);

            
            for (int i = 0; i < n; i++) {
                int start = s[i];
                
                
                for (int k = 0; k < m; k++) {
                    int idx = start + k;
                    if (idx >= nm) idx -= nm;
                    covered[idx] = true;
                }
            }

            
            int unblocked = 0;
            for (int k = 0; k < nm; k++) {
                if (!covered[k]) unblocked++;
            }

            
            cout << unblocked << endl;

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

        } else {
            finish(_pe, "Unknown query type '" + type + "'. Expected '?' or '!'");
        }
    }

    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);
    int m = opt<int>("m", -1);

    
    
    long long seed_val = 0;
    if (argc > 1 && argv[1][0] != '-') {
        try {
            seed_val = stoll(argv[1]);
        } catch (...) {
            seed_val = 0;
        }
    }

    
    if (n == -1) {
        if (seed_val == 1) n = 2;
        else if (seed_val == 2) n = 100;
        else if (seed_val == 3) n = 100;
        else if (seed_val == 4) n = 2;
        else {
            
            int t = rnd.next(10);
            if (t < 2) n = rnd.next(2, 5);       
            else if (t < 5) n = rnd.next(90, 100); 
            else n = rnd.next(2, 100);          
        }
    }

    
    if (m == -1) {
        if (seed_val == 1) m = 2;
        else if (seed_val == 2) m = 20;
        else if (seed_val == 3) m = 2;
        else if (seed_val == 4) m = 20;
        else {
            int t = rnd.next(10);
            if (t < 3) m = 2;                   
            else if (t < 6) m = 20;             
            else m = rnd.next(2, 20);           
        }
    }

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

    
    
    if (mode == "non") {
        vector<int> p(n);
        int total = n * m;
        
        
        
        
        
        
        int strategy = 0;
        
        
        
        if (seed_val > 4 || seed_val <= 0) {
            int roll = rnd.next(100);
            if (roll < 70) strategy = 0;
            else if (roll < 85) strategy = 1;
            else if (roll < 95) strategy = 2;
            else strategy = 3;
        }

        if (strategy == 0) {
            for (int i = 0; i < n; i++) {
                p[i] = rnd.next(0, total - 1);
            }
        } else if (strategy == 1) {
            int center = rnd.next(0, total - 1);
            int range = max(1, total / 15);
            for (int i = 0; i < n; i++) {
                int delta = rnd.next(-range, range);
                int val = (center + delta) % total;
                if (val < 0) val += total;
                p[i] = val;
            }
        } else if (strategy == 2) {
            int start = rnd.next(0, total - 1);
            int step = total / n;
            if (step == 0) step = 1;
            for (int i = 0; i < n; i++) {
                p[i] = (start + i * step) % total;
            }
            shuffle(p.begin(), p.end());
        } else {
            int val = rnd.next(0, total - 1);
            fill(p.begin(), p.end(), val);
        }

        println(p);
    }

    return 0;
}