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;
long long d[2005];
long long f[2005];
long long n;
long long tot = 0;
struct node {
  long long l, r;
} t[2005];
queue<long long> q;
long long ask(long long x) {
  cout << "? " << x << endl;
  for (long long i = 1; i <= n; i++) cin >> d[i];
}
int main() {
  cin >> n;
  q.push(1);
  while (!q.empty()) {
    long long p = q.front();
    q.pop();
    f[p] = 1;
    ask(p);
    long long ma = 0;
    for (long long i = 1; i <= n; i++)
      if (!f[i]) ma = max(ma, d[i]);
    for (long long len = 1; len <= n; len++) {
      long long sum = 0;
      for (long long i = 1; i <= n; i++)
        if (d[i] == len && !f[i]) {
          tot++;
          t[tot].l = p, t[tot].r = i;
          sum++;
        }
      if (sum == 0 || len >= ma)
        break;
      else if (sum == 1)
        f[t[tot].r] = 1, p = t[tot].r;
      else {
        for (long long i = 1; i <= n; i++)
          if (d[i] == len + 1 && !f[i]) q.push(i);
        break;
      }
    }
  }
  cout << "!" << endl;
  for (long long i = 1; i <= tot; i++) cout << t[i].l << " " << t[i].r << endl;
  return 0;
}
