Problem: cf2077_b
Difficulty: hard
Categories: bit, math
Time limit: 2000 ms, memory limit: 256 MB

ALTER EGO - Yuta Imai vs Qlarabelle

This is an interactive problem.

There are two hidden non-negative integers $x$ and $y$ ($0 \leq x, y < 2^{30}$). You can ask no more than $2$ queries of the following form.

* Pick a non-negative integer $n$ ($0 \leq n < 2^{30}$). The judge will respond with the value of $(n \mathbin{|} x) + (n \mathbin{|} y)$, where $|$ denotes the bitwise OR operation.

After this, the judge will give you another non-negative integer $m$ ($0 \leq m < 2^{30}$). You must answer the correct value of $(m \mathbin{|} x) + (m \mathbin{|} y)$.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10^4$). The description of the test cases follows.

Interaction

Two hidden integers $x$ and $y$ are chosen ($0 \leq x, y < 2^{30}$). Note that $x$ and $y$ might be different for different test cases.

The interactor in this task is not adaptive. In other words, the integers $x$ and $y$ do not change during the interaction.

To ask a query, pick an integer $n$ ($0 \leq n < 2^{30}$) and print only the integer $n$ to a line.

You will receive a single integer, the value of $(n \mathbin{|} x) + (n \mathbin{|} y)$.

You may make no more than $2$ queries of the following form.

After you finish your queries, output "!" in a line. You will receive an integer $m$ ($0 \leq m < 2^{30}$). Note that the value of $m$ is also fixed before interaction.

You must output only the value of $(m \mathbin{|} x) + (m \mathbin{|} y)$ in a line. Note that this line is not considered a query and is not taken into account when counting the number of queries asked.

After this, proceed to the next test case.

If you make more than $2$ queries during an interaction, your program must terminate immediately, and you will receive the Wrong Answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.

After printing a query do not forget to output 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

```
2

3

4

1

0

1
```

Output

```
0

1!

4

0!

2
```

Note

In the first test, the interaction proceeds as follows.

|  |  |  |
| --- | --- | --- |
| Solution | Jury | Explanation |
|  | $\texttt{2}$ | There are 2 test cases. |
|  | $\texttt{}$ | In the first test case, $x=1$ and $y=2$. |
| $\texttt{0}$ | $\texttt{3}$ | The solution requests $(0 \mathbin{|} 1) + (0 \mathbin{|} 2)$, and the jury responds with $3$. |
| $\texttt{1}$ | $\texttt{4}$ | The solution requests $(1 \mathbin{|} 1) + (1 \mathbin{|} 2)$, and the jury responds with $4$. |
| $\texttt{!}$ | $\texttt{1}$ | The solution requests the value of $m$, and the jury responds with $1$. |
| $\texttt{4}$ |  | The solution knows that $(1 \mathbin{|} x) + (1 \mathbin{|} y)=4$ because of earlier queries. |
|  | $\texttt{}$ | In the second test case, $x=0$ and $y=0$. |
| $\texttt{0}$ | $\texttt{0}$ | The solution requests $(0 \mathbin{|} 0) + (0 \mathbin{|} 0)$, and the jury responds with $0$. |
| $\texttt{!}$ | $\texttt{1}$ | The solution requests the value of $m$, and the jury responds with $1$. |
| $\texttt{2}$ |  | The solution somehow deduces that $x=y=0$, so it responds with $(1 \mathbin{|} 0) + (1 \mathbin{|} 0)=2$. |

Note that the empty lines in the example input and output are for the sake of clarity and do not occur in the real interaction.

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 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 t = inf.readInt();
    cout << t << endl; 

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

    
    log_metrics();

    for (int i = 0; i < t; ++i) {
        
        
        long long x = inf.readInt();
        long long y = inf.readInt();
        long long m = inf.readInt();

        
        while (true) {
            
            if (queries % 10 == 0) log_metrics();

            string token;
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF while expecting query or '!'");
            }

            
            if (token == "!") {
                break;
            }

            
            long long n;
            if (token == "?") {
                
                if (!(cin >> n)) {
                    finish(_wa, "Unexpected EOF after '?' token");
                }
            } else {
                
                try {
                    size_t idx;
                    n = stoll(token, &idx);
                    if (idx != token.size()) {
                        finish(_wa, "Invalid query format (trailing characters): " + token);
                    }
                } catch (...) {
                    finish(_wa, "Invalid query format (not an integer): " + token);
                }
            }

            
            if (n < 0 || n >= (1LL << 30)) {
                finish(_wa, "Query parameter 'n' out of range [0, 2^30)");
            }

            
            queries++;
            if (queries > hard_cap) {
                finish(_pe, "Hard query limit exceeded (potential infinite loop)");
            }

            
            long long resp = (n | x) + (n | y);
            cout << resp << endl;
        }

        
        cout << m << endl;

        
        string ans_token;
        if (!(cin >> ans_token)) {
            finish(_wa, "Unexpected EOF while expecting answer");
        }

        
        
        
        if (ans_token == "!") {
            if (!(cin >> ans_token)) {
                finish(_wa, "Unexpected EOF after extra '!' prefix in answer");
            }
        }

        long long ans;
        try {
            size_t idx;
            ans = stoll(ans_token, &idx);
            if (idx != ans_token.size()) {
                finish(_wa, "Invalid answer format (trailing characters): " + ans_token);
            }
        } catch (...) {
            finish(_wa, "Invalid answer format (not an integer): " + ans_token);
        }

        
        long long correct = (m | x) + (m | y);
        if (ans != correct) {
            finish(_wa, "Incorrect answer for test case " + to_string(i + 1));
        }
    }

    finish(_ok, "Correct");
    return 0;
}


Adaptive interactor (C++):

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

using namespace std;



const int MAX_VAL = (1 << 30) - 1;

struct TestCase {
    int x, y, m;
};

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

    
    
    
    string mode = opt<string>("mode", "non");
    bool adaptive = (mode == "adp");

    
    
    int seed = atoi(argv[1]);
    
    vector<TestCase> cases;

    if (seed == 1) {
        
        cases.push_back({0, 0, 0});
        cases.push_back({MAX_VAL, MAX_VAL, MAX_VAL});
        cases.push_back({0, MAX_VAL, 0});
        cases.push_back({MAX_VAL, 0, MAX_VAL});
        cases.push_back({0, 0, MAX_VAL});
        cases.push_back({MAX_VAL, MAX_VAL, 0});
        cases.push_back({0, MAX_VAL, 1234567});
        
        cases.push_back({0x2AAAAAAA, 0x15555555, 0});
        cases.push_back({0x2AAAAAAA, 0x15555555, MAX_VAL});
    } 
    else if (seed == 2) {
        
        for (int i = 0; i < 30; ++i) {
            cases.push_back({1 << i, 0, 1 << i});
            cases.push_back({0, 1 << i, 1 << i});
            cases.push_back({1 << i, 1 << i, 0});
        }
    } 
    else if (seed == 3) {
        
        for (int i = 0; i < 100; ++i) {
            int x = rnd.next(0, MAX_VAL);
            int y = rnd.next(0, MAX_VAL) & ~x; 
            int m = rnd.next(0, MAX_VAL);
            cases.push_back({x, y, m});
        }
        for (int i = 0; i < 100; ++i) {
            int y = rnd.next(0, MAX_VAL);
            int x = y & rnd.next(0, MAX_VAL); 
            int m = rnd.next(0, MAX_VAL);
            cases.push_back({x, y, m});
        }
    } 
    else {
        
        
        int t = rnd.next(1000, 10000); 
        for (int i = 0; i < t; ++i) {
            int x = rnd.next(0, MAX_VAL);
            int y = rnd.next(0, MAX_VAL);
            int m = rnd.next(0, MAX_VAL);
            
            
            int type = rnd.next(20);
            if (type == 0) y = x;             
            else if (type == 1) x = 0;        
            else if (type == 2) m = x | y;    
            else if (type == 3) m = 0;        
            
            cases.push_back({x, y, m});
        }
    }

    
    if (cases.empty()) {
        cases.push_back({17, 17, 17});
    }

    
    
    cout << cases.size() << endl;

    
    for (const auto& c : cases) {
        if (adaptive) {
            
            
            cout << c.m << endl;
        } else {
            
            cout << c.x << " " << c.y << " " << c.m << endl;
        }
    }

    return 0;
}