Problem: arc142_c
Difficulty: easy
Categories: graph, math
Time limit: 2000 ms, memory limit: 1024 MB

### Problem Statement

There is a tree with $N$ vertices, numbered $1, \ldots, N$.  
For each pair of integers $u,v\, (1 \leq u,v \leq N)$, the distance $d_{u,v}$ between Vertices $u, v$ is defined as the following.

* The number of edges contained in the shortest path connecting Vertices $u$ and $v$.

You are allowed to ask between $0$ and $2N$ questions (inclusive) in the following form.

* Ask the distance $d_{u,v}$ between Vertices $u,v$ for integers $u,v$ of your choice such that $1\leq u,v \leq N$ and $u+v>3$.

Find the distance $d_{1,2}$ between Vertices $1,2$.

### Constraints

* $3 \leq N \leq 100$
* $N$ is an integer.
* The tree is determined before the start of the interaction between your program and the judge.

### Input and Output

**This is an interactive task**, in which your program and the judge interact via input and output.

First, your program is given a positive integer $N$ from Standard Input:

```
$N$
```

Then, you get to ask questions.  
A question should be printed in the following format (with a newline at the end):

```
? $u$ $v$
```

If the question is valid, the response $d_{u,v}$ is given from Standard Input:

```
$d_{u,v}$
```

If the question is judged invalid because, for example, it is malformed or you have asked too many questions, you get `-1` instead of the response:

```
-1
```

At this point, your submission is already judged incorrect. The judge's program then terminates; yours should too, desirably.

When you find the answer $d_{1,2}$, print it to Standard Output in the following format (with a newline at the end):

```
! $d_{1,2}$
```

### Notices

* **Flush Standard Output after each output. Otherwise, you might get the TLE verdict.**
* After printing the answer (or receiving `-1`), immediately terminate the program normally. Otherwise, the verdict would be indeterminate.
* The verdict for the case of a malformed output would be indeterminate.
* Specifically, note that too many newlines would also be seen as a malformed output.

---

### Sample Input and Output

The following is a sample interaction for the tree shown in this image.

![](https://img.atcoder.jp/arc142/1435f0bc323a9e21cf3abf1c4911e826.png)

| Input | Output | Description |
| --- | --- | --- |
| `3` |  | Interaction starts with the integer $N$. |
|  | `?` `1` `3` | As the $1$-st question, you ask the distance between Vertices $1$ and $3$. |
| `1` |  | The distance between Vertices $1,3$ is returned. |
|  | `?` `2` `2` | As the $2$-nd question, you ask the distance between Vertices $2$ and $2$. |
| `0` |  | The distance between Vertices $2,2$ is returned. |
|  | `?` `2` `3` | As the $3$-rd question, you ask the distance between Vertices $2$ and $3$. |
| `1` |  | The distance between Vertices $2,3$ is returned. |
|  | `?` `3` `1` | As the $4$-th question, you ask the distance between Vertices $3$ and $1$. |
| `1` |  | The distance between Vertices $3,1$ is returned. |
|  | `?` `3` `2` | As the $5$-th question, you ask the distance between Vertices $3$ and $2$. |
| `1` |  | The distance between Vertices $3,2$ is returned. |
|  | `?` `2` `2` | As the $6$-th question, you ask the distance between Vertices $2$ and $2$. |
| `0` |  | The distance between Vertices $2,2$ is returned. |
|  | `!` `2` | You guess the distance between Vertices $1,2$ and terminate. The actual distance between them is $2$, so you would get the AC verdict. |

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


const int MAXN = 105;
const int INF = 1e9;
int dist_mat[MAXN][MAXN];
int N;

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

    
    
    N = inf.readInt();
    query_limit = 2 * N; 

    
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= N; ++j) {
            dist_mat[i][j] = (i == j) ? 0 : INF;
        }
    }

    
    for (int i = 0; i < N - 1; ++i) {
        int u = inf.readInt();
        int v = inf.readInt();
        if (u >= 1 && u <= N && v >= 1 && v <= N) {
            dist_mat[u][v] = 1;
            dist_mat[v][u] = 1;
        }
    }

    
    
    for (int k = 1; k <= N; ++k) {
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= N; ++j) {
                if (dist_mat[i][k] != INF && dist_mat[k][j] != INF) {
                    dist_mat[i][j] = min(dist_mat[i][j], dist_mat[i][k] + dist_mat[k][j]);
                }
            }
        }
    }

    
    
    cout << N << endl;

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

    while (true) {
        
        if (queries > hard_cap) {
            finish(_pe, "Interaction hard cap exceeded");
        }

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

        if (token == "!") {
            
            int ans;
            if (!(cin >> ans)) {
                finish(_wa, "Malformed answer (expected integer after '!')");
            }

            int expected = dist_mat[1][2];
            if (ans == expected) {
                finish(_ok, format("Correct! Distance is %d", expected));
            } else {
                finish(_wa, format("Wrong answer. Expected %d, found %d", expected, ans));
            }

        } else {
            
            
            int u, v;
            if (token == "?") {
                if (!(cin >> u >> v)) {
                    finish(_wa, "Malformed query (expected 'u v' after '?')");
                }
            } else {
                
                try {
                    size_t pos;
                    u = stoi(token, &pos);
                    if (pos != token.size()) throw exception();
                } catch (...) {
                    finish(_wa, "Invalid token '" + token + "' (expected '?', '!' or integer)");
                }
                if (!(cin >> v)) {
                    finish(_wa, "Malformed query (expected 'v' after 'u')");
                }
            }

            
            bool range_ok = (u >= 1 && u <= N && v >= 1 && v <= N);
            
            bool condition_ok = (u + v > 3);

            if (!range_ok) {
                cout << "-1" << endl;
                finish(_wa, format("Invalid query vertices (%d, %d) out of range [1, %d]", u, v, N));
            }
            if (!condition_ok) {
                cout << "-1" << endl;
                finish(_wa, format("Invalid query vertices (%d, %d): sum must be > 3", u, v));
            }

            
            queries++;
            if (queries > query_limit) {
                cout << "-1" << endl;
                finish(_wa, format("Query limit exceeded (%d > %d)", queries, query_limit));
            }

            
            if (queries % 10 == 0) log_metrics();

            
            cout << dist_mat[u][v] << endl;
        }
    }

    return 0;
}


Adaptive interactor (C++):

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

    
    if (N == -1) {
        
        if (rnd.next(100) < 15) {
            N = rnd.next(3, 10);
        } else {
            N = rnd.next(11, 100);
        }
    }

    
    if (mode == "adp") {
        cout << N << endl;
        return 0;
    }

    
    cout << N << endl;

    
    
    
    
    
    
    
    
    
    
    int type = rnd.next(8);

    
    if (N == 3) {
        
        if (type == 3) type = 2; 
        if (type == 1) type = 6;
    } else if (N == 4) {
        
    }

    vector<pair<int,int>> edges;

    if (type == 0) {
        
        vector<int> p(N);
        iota(p.begin(), p.end(), 1);
        shuffle(p.begin(), p.end());
        for (int i = 1; i < N; i++) {
            edges.push_back({p[i], p[rnd.next(i)]});
        }
    } else if (type == 1) {
        
        vector<int> mid;
        for(int i = 3; i <= N; i++) mid.push_back(i);
        shuffle(mid.begin(), mid.end());
        int u = 1;
        for (int v : mid) {
            edges.push_back({u, v});
            u = v;
        }
        edges.push_back({u, 2});
    } else if (type == 2) {
        
        edges.push_back({1, 2});
        vector<int> in_tree = {1, 2};
        vector<int> others;
        for(int i = 3; i <= N; i++) others.push_back(i);
        shuffle(others.begin(), others.end());
        for (int v : others) {
            edges.push_back({v, in_tree[rnd.next(in_tree.size())]});
            in_tree.push_back(v);
        }
    } else if (type == 3) {
        
        if (N >= 4) {
            vector<int> others;
            for(int i = 3; i <= N; i++) others.push_back(i);
            shuffle(others.begin(), others.end());
            int a = others.back(); others.pop_back();
            int b = others.back(); others.pop_back();
            edges.push_back({1, a});
            edges.push_back({a, b});
            edges.push_back({b, 2});
            vector<int> in_tree = {1, 2, a, b};
            for (int v : others) {
                edges.push_back({v, in_tree[rnd.next(in_tree.size())]});
                in_tree.push_back(v);
            }
        } else {
            
            edges.push_back({1, 3});
            edges.push_back({3, 2});
        }
    } else if (type == 4) {
        
        for (int i = 2; i <= N; i++) edges.push_back({1, i});
    } else if (type == 5) {
        
        for (int i = 1; i <= N; i++) if (i != 2) edges.push_back({2, i});
    } else if (type == 6) {
        
        int c = rnd.next(3, N);
        for (int i = 1; i <= N; i++) if (i != c) edges.push_back({c, i});
    } else if (type == 7) {
        
        vector<int> others;
        for(int i = 3; i <= N; i++) others.push_back(i);
        shuffle(others.begin(), others.end());
        
        int nodes_on_path = rnd.next(0, (int)others.size());
        
        if (nodes_on_path == 0) {
            
            edges.push_back({1, 2});
            vector<int> in_tree = {1, 2};
            for (int v : others) {
                edges.push_back({v, in_tree[rnd.next(in_tree.size())]});
                in_tree.push_back(v);
            }
        } else {
            int u = 1;
            vector<int> in_tree = {1};
            for (int i = 0; i < nodes_on_path; i++) {
                int v = others[i];
                edges.push_back({u, v});
                in_tree.push_back(v);
                u = v;
            }
            edges.push_back({u, 2});
            in_tree.push_back(2);
            
            for (size_t i = nodes_on_path; i < others.size(); i++) {
                int v = others[i];
                edges.push_back({v, in_tree[rnd.next(in_tree.size())]});
                in_tree.push_back(v);
            }
        }
    }

    
    vector<int> p(N + 1);
    p[1] = 1;
    p[2] = 2;
    vector<int> perm;
    for (int i = 3; i <= N; i++) perm.push_back(i);
    shuffle(perm.begin(), perm.end());
    for (int i = 0; i < (int)perm.size(); i++) {
        p[3 + i] = perm[i];
    }

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

    for (auto& e : edges) {
        cout << p[e.first] << " " << p[e.second] << "\n";
    }

    return 0;
}