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 mod = 1e9 + 7;
long long power(long long x, long long y) {
  long long res = 1;
  while (y) {
    if (y & 1) res = (res % mod * x % mod) % mod;
    y = y >> 1;
    x = (x % mod * x % mod) % mod;
  }
  return res % mod;
}
const long long fact_val = 1000005;
const long long prime_val = 1005;
long long fact[fact_val], inv[fact_val];
vector<long long> prime;
long long is_prime[prime_val + 1];
void pre() {
  fact[0] = 1;
  inv[0] = 1;
  for (long long i = 1; i < fact_val; i++) {
    fact[i] = (fact[i - 1] * i) % mod;
    inv[i] = power(fact[i], mod - 2);
  }
}
long long C(long long n, long long r) {
  if (r > n) return 0;
  long long ans = ((fact[n] % mod * inv[r] % mod) % mod + mod) % mod;
  ans = ((ans * inv[n - r]) % mod + mod) % mod;
  return ans;
}
int gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
void sieve() {
  for (long long i = 1; i <= prime_val; i++) {
    is_prime[i] = 1;
  }
  is_prime[1] = 0;
  is_prime[0] = 0;
  for (long long p = 2; p * p <= prime_val; p++) {
    if (is_prime[p] == 1) {
      for (long long i = p * p; i <= prime_val; i += p) is_prime[i] = 0;
    }
  }
  for (long long p = 2; p <= prime_val; p++) {
    if (is_prime[p]) prime.push_back(p);
  }
}
long long n;
long long vis[2005];
vector<long long> v[2005];
void dfs(long long p) {
  vis[p] = 1;
  long long arr[n + 1], i;
  cout << "? " << p << endl;
  long long cnt1 = 0, cnt2 = 0;
  for (i = 1; i <= n; i++) {
    cin >> arr[i];
    if (arr[i] == 1) {
      v[p].push_back(i);
      v[i].push_back(p);
      cnt1++;
    }
    if (arr[i] == 2) {
      cnt2++;
    }
  }
  if (cnt1 < cnt2) {
    for (i = 1; i <= n; i++) {
      if (arr[i] == 1) {
        dfs(i);
      }
    }
  } else {
    for (i = 1; i <= n; i++) {
      if (arr[i] == 2 && vis[i] == 0) {
        dfs(i);
      }
    }
  }
}
void dfss(long long node, long long parent) {
  for (int i = 0; i < v[node].size(); i++) {
    if (parent != v[node][i]) {
      cout << node << " " << v[node][i] << endl;
      dfss(v[node][i], node);
    }
  }
}
int main() {
  cin >> n;
  memset(vis, 0, sizeof(vis));
  long long p = 1, i, j;
  dfs(p);
  for (i = 1; i <= n; i++) {
    set<long long> s;
    for (j = 0; j < v[i].size(); j++) {
      s.insert(v[i][j]);
    }
    v[i].clear();
    for (auto it = s.begin(); it != s.end(); it++) {
      long long x = *it;
      v[i].push_back(x);
    }
  }
  dfss(1, 0);
}
