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 <iostream>
#include <vector>
using namespace std;

typedef long long ll;
#define fi first
#define se second
#define mp make_pair

vector <int> query(int i, int n) {
    cout << "? " << i + 1 << endl;
    vector <int> d(n);
    for (int i = 0; i < n; i++) {
        cin >> d[i];
    }
    return d;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n; cin >> n;
    vector < vector <int> > adj(n, vector <int> (n));
    vector < vector <int> > dep(n);
    vector <int> depth = query(0, n);
    int cnt_odd = 0, cnt_even = 0;
    for (int i = 0; i < n; i++) {
        if (depth[i] == 1) {
            adj[0][i] = 1; adj[i][0] = 1;
        }
        (depth[i] % 2 ? cnt_odd++ : cnt_even++);
        dep[depth[i]].push_back(i);
    }
    int cur = 1 + (cnt_even <= cnt_odd);
    while (cur < n) {
        for (int i = 0; i < dep[cur].size(); i++) {
            int u = dep[cur][i];
            vector <int> d = query(u, n);
            for (int v = 0; v < n; v++) {
                if (d[v] == 1) {
                    adj[u][v] = 1; adj[v][u] = 1;
                }
            }
        }
        cur += 2;
    }
    cout << "! " << endl;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (adj[i][j]) {
                cout << i + 1 << ' ' << j + 1 << endl;
            }
        }
    }
    return 0;
}