Problem: cf2022_d1
Difficulty: medium
Categories: data structures
Time limit: 2500 ms, memory limit: 256 MB

This is the easy version of the problem. In this version, you can ask at most $n+69$ questions.

This is an interactive problem.

It is a tradition in Mexico's national IOI trainings to play the game "Asesino", which is similar to "Among Us" or "Mafia".

Today, $n$ players, numbered from $1$ to $n$, will play "Asesino" with the following three roles:

* Knight: a Knight is someone who always tells the truth.
* Knave: a Knave is someone who always lies.
* Impostor: an Impostor is someone everybody thinks is a Knight, but is secretly a Knave.

Each player will be assigned a role in the game. There will be exactly one Impostor but there can be any (possible zero) number of Knights and Knaves.

As the game moderator, you have accidentally forgotten the roles of everyone, but you need to determine the player who is the Impostor.

To determine the Impostor, you will ask some questions. In each question, you will pick two players $i$ and $j$ ($1 \leq i, j \leq n$; $i \neq j$) and ask if player $i$ thinks that player $j$ is a Knight. The results of the question is shown in the table below.

|  |  |  |  |
| --- | --- | --- | --- |
|  | Knight | Knave | Impostor |
| Knight | Yes | No | Yes |
| Knave | No | Yes | No |
| Impostor | No | Yes | — |

The response of the cell in row $a$ and column $b$ is the result of asking a question when $i$ has role $a$ and $j$ has row $b$. For example, the "Yes" in the top right cell belongs to row "Knight" and column "Impostor", so it is the response when $i$ is a Knight and $j$ is an Impostor. 

Find the Impostor in at most $n + 69$ questions.

Note: the grader is adaptive: the roles of the players are not fixed in the beginning and may change depending on your questions. However, it is guaranteed that there exists an assignment of roles that is consistent with all previously asked questions under the constraints of this problem.

Input

The first line of input contains a single integer $t$ ($1 \leq t \leq 10^3$) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($3 \le n \le 10^5$) — the number of people playing the game.

It is guaranteed that the sum of $n$ over all test cases does not exceed $10^5$.

Interaction

To ask a question, output a line in the following format:

* "? i j" ($1 \leq i,j \leq n$; $i \neq j$) — to ask player $i$ if they think player $j$ is a Knight.

The jury will output a "1" if player $i$ thinks player $j$ is a Knight, and "0" otherwise.

When you have determined which player the Impostor is, output a line in the following format:

* "! i" ($1 \leq i \leq n$) — the Impostor is player $i$.

Note that answering does not count to your limit of $n+69$ questions.

If you have made an invalid output, used more than $n+69$ questions or wrongly determined the Impostor, the jury will respond with "-1" and you will receive a Wrong Answer verdict. Upon receiving "-1", your program must terminate immediately. Otherwise, you may receive an arbitrary verdict because your solution might be reading from a closed stream.

After printing a query do not forget to output the end of the 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;
* sys.stdout.flush() in Python;
* std::io::stdout().flush() in Rust;
* see the documentation for other languages.

Example

Input

```
2
7

1

0

0

1

1

0

0

1

4

0

1

1

1
```

Output

```
? 1 3

? 7 6

? 2 5

? 6 2

? 4 5

? 4 6

? 1 4

? 2 4

! 4

? 1 2

? 2 3

? 3 4

? 4 1

! 3
```

Note

Note that the example test cases do not represent an optimal strategy for asking questions and are only shown for the sake of demonstrating the interaction format. Specifically, we cannot determine which player is the Impostor from the questions asked in the examples.

In the first test case of the example, players at indices $2$ and $6$ are Knights, players at indices $1$, $3$, $5$, and $7$ are Knaves, and the Impostor is at index $4$. The following is an explanation of the questions asked:

* In the first query, player $i$ is a Knave and player $j$ is a Knave. The answer is "yes" since Knaves always lie.
* In the second query, player $i$ is a Knave and player $j$ is a Knight. The answer is "no" since Knaves always lie.
* In the third query, player $i$ is a Knight and player $j$ is a Knave. The answer is "no" since Knights always tell the truth.
* In the fourth query, player $i$ is a Knight and player $j$ is a Knight. The answer is "yes" since Knights always tell the truth.
* In the fifth query, player $i$ is a Impostor and player $j$ is a Knave. The answer is "yes" since the Impostor always lies.
* In the sixth query, player $i$ is a Impostor and player $j$ is a Knight. The answer is "no" since the Impostor always lies.
* In the seventh query, player $i$ is a Knave and player $j$ is a Impostor. The answer is "no" since Knaves always lie and Knaves thinks that the Impostor is a Knight.
* In the eighth query, player $i$ is a Knight and player $j$ is a Impostor. The answer is "yes" since Knights always tell the truth and Knights think that the Impostor is a Knight.

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


const int KNIGHT = 0;
const int KNAVE = 1;
const int IMPOSTOR = 2;


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


bool is_number(const string& s) {
    if (s.empty()) return false;
    for (char c : s) {
        if (!isdigit(c)) return false;
    }
    return true;
}

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

    
    int t = inf.readInt();
    cout << t << endl; 

    for (int case_idx = 0; case_idx < t; ++case_idx) {
        
        int n = inf.readInt();
        vector<int> roles(n + 1);
        int impostor_idx = -1;
        for (int i = 1; i <= n; ++i) {
            roles[i] = inf.readInt();
            if (roles[i] == IMPOSTOR) impostor_idx = i;
        }

        
        
        queries = 0;
        query_limit = n + 69;
        hard_cap = max((long long)200000, 10 * query_limit);
        
        log_metrics(); 
        
        cout << n << endl; 

        bool active = true;
        while (active) {
            string token;
            
            if (!(cin >> token)) {
                finish(_pe, "Unexpected EOF reading token");
            }

            bool is_ans = false;
            int u = -1, v = -1;

            
            
            
            if (token == "!") {
                is_ans = true;
                if (!(cin >> u)) finish(_pe, "Unexpected EOF reading answer index");
            } else if (token == "?") {
                if (!(cin >> u >> v)) finish(_pe, "Unexpected EOF reading query indices");
            } else {
                
                if (!is_number(token)) {
                    cout << "-1" << endl;
                    finish(_pe, format("Invalid token: '%s' (expected '?', '!', or number)", token.c_str()));
                }
                try {
                    u = stoi(token);
                } catch (...) {
                    cout << "-1" << endl;
                    finish(_pe, "Token integer overflow");
                }
                if (!(cin >> v)) finish(_pe, "Unexpected EOF reading second index");
            }

            if (is_ans) {
                if (u == impostor_idx) {
                    
                    active = false; 
                } else {
                    
                    cout << "-1" << endl; 
                    finish(_wa, format("Wrong answer: guessed %d, expected %d", u, impostor_idx));
                }
            } else {
                
                if (u < 1 || u > n || v < 1 || v > n || u == v) {
                    cout << "-1" << endl;
                    finish(_wa, format("Invalid query indices: %d %d (N=%d)", u, v, n));
                }

                queries++;
                if (queries > hard_cap) {
                    finish(_pe, "Hard query limit exceeded");
                }
                
                
                if (queries % 100 == 0) log_metrics();

                
                
                
                
                
                
                
                bool asker_truthful = (roles[u] == KNIGHT);
                bool target_is_knight_like = (roles[v] != KNAVE);
                
                
                
                bool response = (asker_truthful == target_is_knight_like);
                
                cout << (response ? 1 : 0) << endl;
            }
        }
    }

    finish(_ok, "Passed all test cases");
    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 = 0;



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


static void finish(TResult verdict, const string& msg) {
    
    
    
    
    if (verdict != _ok) {
        cout << "-1" << endl;
    }
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}








const int TYPE_TRUE = 1;  
const int TYPE_FALSE = 0; 






struct State {
    int n;
    int imp; 
    vector<int> roles; 
    
    
    
    int get_type(int p) const {
        if (p == imp) return TYPE_FALSE;
        return roles[p]; 
    }
    
    
    
    int get_perc(int p) const {
        if (p == imp) return TYPE_TRUE; 
        return roles[p];
    }
    
    
    
    
    
    
    
    int query(int i, int j) const {
        return (get_type(i) == get_perc(j)) ? 1 : 0;
    }
};

struct HistoryItem {
    int i, j, ans;
};
vector<HistoryItem> history;



vector<int> dsu_parent;
vector<int> dsu_xor;     
vector<int> dsu_fixed;   

void dsu_reset(int n) {
    if ((int)dsu_parent.size() <= n) {
        dsu_parent.resize(n + 1);
        dsu_xor.resize(n + 1);
        dsu_fixed.resize(n + 1);
    }
    for(int i=1; i<=n; ++i) {
        dsu_parent[i] = i;
        dsu_xor[i] = 0;
        dsu_fixed[i] = -1;
    }
}

pair<int, int> dsu_find(int i) {
    if (dsu_parent[i] == i) return {i, 0};
    pair<int, int> root = dsu_find(dsu_parent[i]);
    dsu_parent[i] = root.first;
    dsu_xor[i] = dsu_xor[i] ^ root.second;
    return {dsu_parent[i], dsu_xor[i]};
}


bool dsu_unite(int i, int j, int w) {
    auto r1 = dsu_find(i);
    auto r2 = dsu_find(j);
    int root1 = r1.first;
    int root2 = r2.first;
    int p1 = r1.second;
    int p2 = r2.second;
    
    int required = p1 ^ p2 ^ w;
    
    if (root1 != root2) {
        
        dsu_parent[root1] = root2;
        dsu_xor[root1] = required;
        
        if (dsu_fixed[root1] != -1) {
            int val_r2_implied = dsu_fixed[root1] ^ required;
            if (dsu_fixed[root2] != -1 && dsu_fixed[root2] != val_r2_implied) return false;
            dsu_fixed[root2] = val_r2_implied;
        }
        return true;
    } else {
        return (required == 0);
    }
}


bool dsu_fix(int i, int val) {
    auto r = dsu_find(i);
    int root = r.first;
    int current_xor = r.second; 
    
    
    int required_root = val ^ current_xor;
    
    if (dsu_fixed[root] != -1 && dsu_fixed[root] != required_root) return false;
    dsu_fixed[root] = required_root;
    return true;
}


bool is_consistent(int n, int cand, const vector<HistoryItem>& hist) {
    dsu_reset(n);
    
    for (const auto& q : hist) {
        int i = q.i;
        int j = q.j;
        int ans = q.ans;
        
        if (i == cand) {
            
            
            
            
            
            if (!dsu_fix(j, 1 - ans)) return false;
        } else if (j == cand) {
            
            
            
            
            if (!dsu_fix(i, ans)) return false;
        } else {
            
            
            
            if (!dsu_unite(i, j, 1 - ans)) return false;
        }
    }
    return true;
}


struct TestCaseData {
    int n;
    bool has_roles;
    vector<int> roles; 
    int imp_idx;
};

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

    
    
    
    vector<int> buffer;
    while (!inf.seekEof()) {
        buffer.push_back(inf.readInt());
    }
    
    int buf_pos = 0;
    int t = buffer[buf_pos++];
    vector<TestCaseData> cases;
    
    for (int k = 0; k < t; ++k) {
        TestCaseData tc;
        tc.n = buffer[buf_pos++];
        tc.has_roles = false;
        
        
        if (buf_pos < (int)buffer.size() && buffer[buf_pos] < 3) {
            tc.has_roles = true;
            tc.roles.resize(tc.n + 1);
            for (int i = 1; i <= tc.n; ++i) {
                tc.roles[i] = buffer[buf_pos++];
                if (tc.roles[i] == 2) tc.imp_idx = i;
            }
        }
        cases.push_back(tc);
    }
    
    
    cout << t << endl; 
    
    for (int k = 0; k < t; ++k) {
        TestCaseData& tc = cases[k];
        
        
        queries = 0;
        query_limit = tc.n + 69;
        log_metrics(); 
        
        
        State current_state;
        current_state.n = tc.n;
        current_state.roles.assign(tc.n + 1, 0);
        
        if (tc.has_roles) {
            
            current_state.imp = tc.imp_idx;
            for(int i=1; i<=tc.n; ++i) {
                if (i != tc.imp_idx) {
                    
                    if (tc.roles[i] == 0) current_state.roles[i] = TYPE_TRUE;
                    else current_state.roles[i] = TYPE_FALSE;
                }
            }
        } else {
            
            current_state.imp = rnd.next(1, tc.n);
            for(int i=1; i<=tc.n; ++i) {
                if (i == current_state.imp) continue;
                current_state.roles[i] = rnd.next(0, 1);
            }
        }
        
        
        cout << tc.n << endl;
        
        
        history.clear();
        bool active = true;
        
        while (active) {
            string type;
            if (!(cin >> type)) {
                
                finish(_wa, "Unexpected EOF (contestant output ended)");
            }
            
            if (type == "?") {
                int u, v;
                if (!(cin >> u >> v)) finish(_wa, "Invalid query format");
                
                
                if (u < 1 || u > tc.n || v < 1 || v > tc.n || u == v) {
                    finish(_wa, "Invalid query range or u==v");
                }
                
                queries++;
                
                if (queries % 100 == 0) log_metrics();
                
                
                if (queries > tc.n + 200) {
                    finish(_pe, "Too many queries (hard cap exceeded)");
                }
                
                
                int ans = current_state.query(u, v);
                history.push_back({u, v, ans});
                
                cout << ans << endl;
                
            } else if (type == "!") {
                int u;
                if (!(cin >> u)) finish(_wa, "Invalid answer format");
                
                
                if (u < 1 || u > tc.n) {
                    finish(_wa, "Invalid answer range");
                }
                
                bool correct = false;
                
                if (u == current_state.imp) {
                    
                    
                    if (!tc.has_roles) {
                        
                        
                        vector<int> candidates(tc.n);
                        iota(candidates.begin(), candidates.end(), 1);
                        shuffle(candidates.begin(), candidates.end());
                        
                        bool found_alternative = false;
                        int checks = 0;
                        int max_checks = min(tc.n, 300); 
                        
                        for (int y : candidates) {
                            if (y == u) continue;
                            if (checks++ >= max_checks) break;
                            
                            if (is_consistent(tc.n, y, history)) {
                                found_alternative = true;
                                break;
                            }
                        }
                        
                        if (found_alternative) {
                            
                            
                            correct = false;
                        } else {
                            
                            correct = true;
                        }
                    } else {
                        
                        correct = true;
                    }
                } else {
                    
                    
                    correct = false;
                }
                
                if (correct) {
                    
                    active = false; 
                } else {
                    finish(_wa, "Wrong Answer: Impostor incorrect or ambiguous");
                }
                
            } else {
                finish(_wa, "Invalid query type");
            }
        }
    }
    
    finish(_ok, "All cases passed");
    return 0;
}


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


const int KNIGHT = 0;
const int KNAVE = 1;
const int IMPOSTOR = 2;

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);
    
    
    string mode = opt<string>("mode", "non");

    
    const int MAX_SUM_N = 100000;
    const int MIN_N = 3;
    const int MAX_T = 1000;

    
    vector<int> ns;
    int rem = MAX_SUM_N;
    
    
    
    
    
    
    int strategy = rnd.next(4);
    
    while (rem >= MIN_N && (int)ns.size() < MAX_T) {
        
        if ((int)ns.size() == MAX_T - 1) {
            ns.push_back(rem);
            rem = 0;
            break;
        }

        
        int n_limit = rem;
        if (strategy == 0) n_limit = 20;
        else if (strategy == 1) n_limit = 1000;
        else if (strategy == 3) {
             ns.push_back(rem);
             rem = 0;
             break;
        }
        
        int upper = min(rem, n_limit);
        
        if (upper < MIN_N) {
            ns.push_back(rem);
            rem = 0;
            break;
        }
        
        int n = rnd.next(MIN_N, upper);
        
        
        if (rem - n < MIN_N && rem - n != 0) {
            n += (rem - n);
        }
        
        ns.push_back(n);
        rem -= n;
    }
    
    
    if (rem > 0 && !ns.empty()) {
        ns.back() += rem;
        rem = 0;
    }
    
    
    println(ns.size());
    
    for (int n : ns) {
        println(n);
        
        if (mode == "non") {
            
            vector<int> roles(n);
            
            
            int imp = rnd.next(n);
            roles[imp] = IMPOSTOR;
            
            
            
            
            
            
            
            int subtype = rnd.next(5);
            
            for (int i = 0; i < n; i++) {
                if (i == imp) continue;
                
                if (subtype == 0) roles[i] = KNIGHT;
                else if (subtype == 1) roles[i] = KNAVE;
                else if (subtype == 2) roles[i] = rnd.next(0, 1);
                else if (subtype == 3) roles[i] = rnd.wnext(2, -2); 
                else roles[i] = rnd.wnext(2, 2); 
            }
            
            println(roles);
        } 
        
    }
    
    return 0;
}