5
5 3
2 4
3 1
4 5
 4
2 4
3 2
2 1
 5
5 3
2 4
3 1
4 5
 2
1 2
 4
3 4
2 3
3 1
 10
8 10
2 9
7 8
4 1
7 3
4 7
2 5
2 4
4 6
 5
3 4
3 2
3 1
1 5
 3
1 2
2 3
 5
1 2
1 3
1 4
1 5

1 2
2 3
2 4
 1 3
2 4
3 5
4 5
 1 2
 1 3
2 3
3 4
 1 4
2 4
2 5
2 9
3 7
4 6
4 7
7 8
8 10
 1 3
1 5
2 3
3 4
 1 2
2 3
 1 2
1 3
1 4
1 5

#include <bits/stdc++.h>
using namespace std;
int n;
vector<int> d;
vector<pair<int, int>> edges;
vector<vector<bool>> vis;

void ask(int x) {
    cout << "? " << x << endl;
    for(int i = 1; i <= n; i++) {
        cin >> d[i];
    }
}



signed main() {
    cin >> n;
    d = vector<int>(n + 1);
    vector<int> p[2];
    vis = vector<vector<bool>>(n + 1, vector<bool>(n + 1, false));
    ask(1);
    for(int i = 2; i <= n; i++) {
        if(d[i] == 1 && !vis[i][1] && !vis[1][i]) {
            vis[1][i] = vis[i][1] = true;
            edges.push_back({1, i});
        }
        p[d[i] & 1].push_back(i);
    }
    if((int)p[0].size() > (int)p[1].size()) {
        swap(p[0], p[1]);
    }
    for(int x: p[0]) {
        ask(x);
        for(int i = 1; i <= n; i++) {
            if(d[i] == 1 && !vis[i][x] && !vis[x][i]) {
                vis[i][x] = vis[x][i] = true;
                edges.push_back({x, i});
            }
        }
    }
    assert((int)edges.size() == n - 1);
    cout << "!" << endl;
    for(int i = 0; i < n - 1; i++) {
        cout << edges[i].first << " " << edges[i].second << endl;
    }
    
    return 0;
}