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> vis(2001, 0);
vector<pair<int, int>> ans;
int query(int node) {
  if (ans.size() == n - 1) return 2003;
  cout << "? " << node << '\n';
  vector<pair<int, int>> disind(n + 1);
  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;
    disind[i].first = x;
    disind[i].second = i;
  }
  for (int i = 1; i <= n; i++) {
    if (vis[i] == 0 and disind[i].first == 1) {
      if (ans.size() == n - 1) return 2003;
      ans.push_back({node, i});
    }
  }
  if (ans.size() == n - 1) return 2003;
  sort(disind.rbegin(), disind.rend());
  int maxi = disind[0].first;
  if (maxi < 2) return 2003;
  for (int i = 1; i <= n; i++) {
    if (vis[disind[i].second] == 0 and disind[i].first < maxi and
        disind[i].first != 0) {
      return disind[i].second;
    }
  }
  return 2003;
}
int main() {
  int t;
  t = 1;
  while (t--) {
    cin >> n;
    int x = (n + 1) / 2;
    int f = 0;
    int next = 1;
    while (x--) {
      vis[next] = 1;
      next = query(next);
      if (ans.size() == n - 1) goto st;
      if (next == 2003) goto st;
    }
  st:
    cout << "!";
    for (int i = 0; i < ans.size(); i++)
      cout << ans[i].first << " " << ans[i].second << '\n';
    vis.clear();
  }
  return 0;
}
