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;
const double pi =
    3.14159265358979323846264338327950288419716939937510582097494459230;
long long powm(long long a, long long b, long long m) {
  long long res = 1;
  while (b) {
    if (b & 1) res = (res * a) % m;
    a = (a * a) % m;
    b >>= 1;
  }
  return res;
}
long long ceil(const long long &a, const long long &b) {
  if (a % b == 0) return a / b;
  return a / b + 1;
}
const long long N = 4e5 + 10;
long long vis[N];
vector<long long> g[N];
void dfs(long long node) {
  vis[node] = 1;
  for (auto it : g[node]) {
    if (vis[it] == 0) dfs(it);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long n, i, x;
  cin >> n;
  set<pair<long long, long long> > ans;
  cout << ('?') << " " << (1) << "\n";
  cout.flush();
  vector<long long> v, cnt[2];
  for (i = 1; i <= n; i++) {
    cin >> x;
    if (x == 1) ans.insert({1, i});
    cnt[x % 2].push_back(i);
  }
  if (cnt[0].size() < cnt[1].size()) {
    for (auto it : cnt[0]) v.push_back(it);
  } else {
    for (auto it : cnt[1]) v.push_back(it);
  }
  for (auto it : v) {
    if (it == 1) continue;
    cout << ('?') << " " << (it) << "\n";
    cout.flush();
    for (i = 1; i <= n; i++) {
      cin >> x;
      if (x == 1) {
        if (it < i)
          ans.insert({it, i});
        else
          ans.insert({i, it});
      }
    }
  }
  cout << ('!') << "\n";
  cout.flush();
  for (auto it : ans) {
    cout << (it.first) << " " << (it.second) << "\n";
    cout.flush();
  }
  return 0;
}
