Problem: cf1887_e
Difficulty: easy
Categories: graph, search
Time limit: 2000 ms, memory limit: 256 MB

Alice suggested Bob to play a game. Bob didn't like this idea, but he couldn't refuse Alice, so he asked you to write a program that would play instead of him.

The game starts with Alice taking out a grid sheet of size $n \times n$, the cells of which are initially not colored. After that she colors some $2n$ cells with colors $1,2,\ldots, 2n$, respectively, and informs Bob about these cells.

In one move, Bob can point to a cell that has not been colored yet and ask Alice to color that cell. Alice colors that cell with one of the $2n$ colors of her choice, informing Bob of the chosen color. Bob can make no more than $10$ moves, after which he needs to find a good set of four cells.

A set of four cells is considered good if the following conditions are met:

* All the cells in the set are colored;
* No two cells in the set are colored with the same color;
* The centers of the cells form a rectangle with sides parallel to the grid lines.

Input

Each test consists of multiple test cases. The first line contains a single integer $t$ ($1 \le t \le 200$) — 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 1000$) — the size of the grid.

The $i$-th of the following $2n$ lines contains two integers $x_i$ and $y_i$ ($1 \le x_i, y_i \le n$) — the coordinates of the cell colored with the $i$-th color.

It is guaranteed that all coordinates $(x_i, y_i)$ are pairwise distinct for the same test case.

After reading the input data for each test case, continue the interaction as described below.

Interaction

You can make no more than $10$ moves. To make a move, output "? $x$ $y$" ($1 \leq x,y \leq n$). In response to this, the jury's program will output a single integer from $1$ to $2n$ — the color of cell $(x,y)$.

After all moves (it is not necessary to make all $10$ moves and it is not necessary to make at least one move), output a string in the format "! $x_1$ $x_2$ $y_1$ $y_2$" ($1 \leq x_1, x_2, y_1, y_2 \leq n, x_1 \ne x_2, y_1 \ne y_2$). If cells $(x_1, y_1)$, $(x_1, y_2)$, $(x_2, y_1)$, $(x_2, y_2)$ are colored with different colors, the jury's program will output "OK". After that, proceed to the next test case or terminate the program if there are no more test cases left.

Otherwise, if any of the specified cells are colored with the same color or one of the cells is not colored yet, the jury's program will output "ERROR". In this case, your program should immediately terminate its execution to receive the Wrong Answer verdict. Otherwise, you may receive an arbitrary verdict.

After each move or answer, do not forget to output the end of line and flush the output. Otherwise, you will get the 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.

Note that the interactor is adaptive, meaning that the color Alice will use to color the cells during Bob's moves is not fixed in advance.

Example

Input

```
2
3
1 2
1 3
2 1
2 3
3 1
3 2

1

OK
3
1 1
1 2
1 3
2 1
2 2
2 3

OK
```

Output

```
? 1 1

! 1 2 1 3

! 1 2 1 2
```

Note

In the first test case:

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

In the second test case, cells with coordinates $(1, 1), (1, 2), (2, 1), (2, 2)$ are initially colored by Alice in different colors.

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 << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {
        
    }
}


static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}


static bool is_integer(const string& s) {
    if (s.empty()) return false;
    if (s[0] == '-' && s.length() == 1) return false;
    for (size_t i = (s[0] == '-'); i < s.length(); ++i) {
        if (!isdigit(s[i])) return false;
    }
    return true;
}

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

    
    int t = inf.readInt();
    
    
    
    query_limit = (long long)t * 10;

    
    cout << t << endl;

    
    for (int i = 0; i < t; ++i) {
        
        int n = inf.readInt();
        cout << n << endl;

        
        vector<vector<int>> grid(n + 1, vector<int>(n + 1, 0));
        vector<vector<bool>> known(n + 1, vector<bool>(n + 1, false));

        
        for (int j = 0; j < 2 * n; ++j) {
            int r = inf.readInt();
            int c = inf.readInt();
            known[r][c] = true;
            
            cout << r << " " << c << endl;
        }

        
        for (int r = 1; r <= n; ++r) {
            for (int c = 1; c <= n; ++c) {
                grid[r][c] = inf.readInt();
            }
        }
        cout.flush(); 

        int case_queries = 0;
        bool case_solved = false;

        
        while (true) {
            
            log_metrics();

            string token;
            
            if (!(cin >> token)) {
                finish(_wa, "Unexpected EOF (waiting for query or answer)");
            }

            if (token == "!") {
                
                int x1, x2, y1, y2;
                if (!(cin >> x1 >> x2 >> y1 >> y2)) {
                    finish(_wa, "Invalid answer format");
                }

                
                if (x1 < 1 || x1 > n || x2 < 1 || x2 > n || y1 < 1 || y1 > n || y2 < 1 || y2 > n) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Answer coordinates out of bounds");
                }

                
                
                
                if (x1 == x2 || y1 == y2) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Invalid rectangle (x1==x2 or y1==y2)");
                }

                
                vector<pair<int, int>> p = {{x1, y1}, {x1, y2}, {x2, y1}, {x2, y2}};
                
                
                for (auto& pt : p) {
                    if (!known[pt.first][pt.second]) {
                        cout << "ERROR" << endl;
                        finish(_wa, "Answer uses a cell that has not been colored");
                    }
                }

                
                set<int> distinct_colors;
                for (auto& pt : p) {
                    distinct_colors.insert(grid[pt.first][pt.second]);
                }

                if (distinct_colors.size() == 4) {
                    cout << "OK" << endl; 
                    case_solved = true;
                    break; 
                } else {
                    cout << "ERROR" << endl;
                    finish(_wa, "Cells do not have distinct colors");
                }

            } else {
                
                int x, y;
                if (token == "?") {
                    if (!(cin >> x >> y)) finish(_wa, "Invalid query format after '?'");
                } else {
                    
                    if (!is_integer(token)) finish(_wa, "Invalid token (expected '?', '!', or integer)");
                    try {
                        x = stoi(token);
                    } catch (...) {
                        finish(_wa, "Invalid integer for x");
                    }
                    if (!(cin >> y)) finish(_wa, "Invalid query format (missing y)");
                }

                
                if (case_queries >= 10) {
                    finish(_wa, "Too many moves (limit 10 per test case)");
                }

                
                if (x < 1 || x > n || y < 1 || y > n) {
                    finish(_wa, "Query coordinates out of bounds");
                }
                
                
                if (known[x][y]) {
                    finish(_wa, "Cell already colored");
                }

                
                known[x][y] = true;
                queries++;
                case_queries++;

                cout << grid[x][y] << endl;
                
            }
        }

        if (!case_solved) {
            
            finish(_wa, "Test case loop exited unexpectedly");
        }
    }

    quitf(_ok, "Passed %d test cases", t);
    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) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}


int N;


vector<vector<pair<int, int>>> adj;

vector<vector<int>> grid_colors;


int get_color(int r, int c) {
    if (r < 1 || r > N || c < 1 || c > N) return 0;
    return grid_colors[r][c];
}


void add_edge(int r, int c, int color) {
    grid_colors[r][c] = color;
    adj[r].push_back({c + N, color});
    adj[c + N].push_back({r, color});
}





int solve_adaptive_color(int r, int c) {
    int start = r;
    int target = c + N;
    
    
    queue<int> q;
    q.push(start);
    
    
    int size = 2 * N + 5;
    vector<int> parent(size, 0);
    vector<int> parent_edge_color(size, 0);
    vector<bool> visited(size, false);
    visited[start] = true;
    
    bool found = false;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        if (u == target) {
            found = true;
            break;
        }
        for (auto& edge : adj[u]) {
            int v = edge.first;
            int col = edge.second;
            if (!visited[v]) {
                visited[v] = true;
                parent[v] = u;
                parent_edge_color[v] = col;
                q.push(v);
            }
        }
    }
    
    if (found) {
        vector<int> path_colors;
        int curr = target;
        while (curr != start) {
            path_colors.push_back(parent_edge_color[curr]);
            curr = parent[curr];
        }
        
        
        if (!path_colors.empty()) {
            return path_colors[0]; 
        }
    }
    
    
    return 1;
}

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

    
    int t = inf.readInt();
    
    cout << t << endl;
    
    
    query_limit = (long long)t * 10;
    
    
    log_metrics();

    for (int tc = 0; tc < t; tc++) {
        
        N = inf.readInt();
        cout << N << endl;
        
        
        adj.assign(2 * N + 5, vector<pair<int, int>>());
        grid_colors.assign(N + 1, vector<int>(N + 1, 0));
        
        
        for (int i = 0; i < 2 * N; i++) {
            int u = inf.readInt();
            int v = inf.readInt();
            int color = i + 1; 
            add_edge(u, v, color);
            cout << u << " " << v << endl;
        }
        
        bool case_active = true;
        while (case_active) {
            string type;
            if (!(cin >> type)) {
                finish(_pe, "Unexpected EOF (waiting for query or answer)");
            }
            
            if (type == "?") {
                queries++;
                
                if (queries > query_limit + 5000) {
                    finish(_pe, "Too many queries (hard cap hit)");
                }
                
                int r, c;
                if (!(cin >> r >> c)) finish(_pe, "Invalid query format");
                
                if (r < 1 || r > N || c < 1 || c > N) {
                    finish(_wa, format("Query out of bounds: %d %d", r, c));
                }
                
                if (grid_colors[r][c] != 0) {
                    
                    cout << grid_colors[r][c] << endl;
                } else {
                    
                    int color = solve_adaptive_color(r, c);
                    add_edge(r, c, color);
                    cout << color << endl;
                }
                
            } else if (type == "!") {
                int x1, x2, y1, y2;
                if (!(cin >> x1 >> x2 >> y1 >> y2)) finish(_pe, "Invalid answer format");
                
                
                bool ok = true;
                if (x1 < 1 || x1 > N || x2 < 1 || x2 > N) ok = false;
                if (y1 < 1 || y1 > N || y2 < 1 || y2 > N) ok = false;
                if (x1 == x2 || y1 == y2) ok = false; 
                
                if (!ok) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Invalid rectangle coordinates");
                }
                
                
                int c1 = get_color(x1, y1);
                int c2 = get_color(x1, y2);
                int c3 = get_color(x2, y1);
                int c4 = get_color(x2, y2);
                
                if (c1 == 0 || c2 == 0 || c3 == 0 || c4 == 0) {
                    cout << "ERROR" << endl;
                    finish(_wa, "Rectangle contains uncolored cells");
                }
                
                set<int> distinct;
                distinct.insert(c1);
                distinct.insert(c2);
                distinct.insert(c3);
                distinct.insert(c4);
                
                if (distinct.size() == 4) {
                    cout << "OK" << endl;
                    case_active = false; 
                } else {
                    cout << "ERROR" << endl;
                    finish(_wa, format("Colors not distinct: %d %d %d %d", c1, c2, c3, c4));
                }
                
            } else {
                finish(_pe, "Expected '?' or '!', got: " + type);
            }
        }
        
        
        log_metrics();
    }
    
    finish(_ok, "All test cases passed");
    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 = opt<int>("n", -1);

    
    int n;
    if (n_opt != -1) {
        n = n_opt;
    } else {
        
        
        int type = rnd.next(1, 10);
        if (type == 1) n = 3;                  
        else if (type == 2) n = rnd.next(3, 10); 
        else if (type == 3) n = 1000;          
        else n = rnd.next(10, 1000);           
    }
    
    
    n = max(3, min(n, 1000));

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

    vector<pair<int, int>> initial_cells;
    initial_cells.reserve(2 * n);

    for (int i = 0; i < n; i++) {
        
        initial_cells.push_back({rows[i], cols[i]});
        
        initial_cells.push_back({rows[i], cols[(i + 1) % n]});
    }

    
    
    shuffle(initial_cells.begin(), initial_cells.end());

    
    cout << 1 << endl; 
    cout << n << endl;
    for (const auto& cell : initial_cells) {
        cout << cell.first << " " << cell.second << endl;
    }

    
    
    if (mode == "non") {
        vector<vector<int>> grid(n + 1, vector<int>(n + 1, 0));

        
        for (int i = 0; i < 2 * n; i++) {
            grid[initial_cells[i].first][initial_cells[i].second] = i + 1;
        }

        
        for (int r = 1; r <= n; r++) {
            for (int c = 1; c <= n; c++) {
                if (grid[r][c] == 0) {
                    grid[r][c] = rnd.next(1, 2 * n);
                }
            }
        }

        
        for (int r = 1; r <= n; r++) {
            for (int c = 1; c <= n; c++) {
                cout << grid[r][c] << (c == n ? "" : " ");
            }
            cout << endl;
        }
    }
    
    

    return 0;
}