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;
void dfs(vector<long long int> &dvisited,
         map<long long int, vector<long long int> > &g, long long int ele) {
  dvisited[ele] = 1;
  for (long long int i = 0; i < g[ele].size(); i++) {
    if (!dvisited[g[ele][i]]) {
      cout << ele << " " << g[ele][i] << endl;
      dfs(dvisited, g, g[ele][i]);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  long long int n;
  cin >> n;
  vector<long long int> visited(n + 1, 0);
  queue<long long int> q;
  q.push(1);
  map<long long int, vector<long long int> > g;
  visited[1] = 1;
  while (!q.empty()) {
    long long int ele = q.front();
    q.pop();
    vector<long long int> res;
    cout << '?' << " " << ele << endl;
    for (long long int i = 0; i < n; i++) {
      long long int ans;
      cin >> ans;
      if (ans == -1) return 0;
      res.push_back(ans);
    }
    int mini = *min_element(res.begin(), res.end());
    for (long long int i = 0; i < res.size(); i++) {
      if (res[i] == 1) {
        g[i + 1].push_back(ele);
        g[ele].push_back(i + 1);
      }
      if (res[i] == mini && !visited[i + 1]) {
        q.push(i + 1);
        visited[i + 1] = 1;
      }
    }
  }
  vector<long long int> dvisited(n + 1, 0);
  cout << "!" << endl;
  dfs(dvisited, g, 1);
  cout.flush();
}
