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 oj() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
}
long long n;
vector<long long> query(long long x) {
  vector<long long> temp(n);
  cout << "?"
       << " " << x << "\n";
  cout.flush();
  for (long long i = 0; i < n; i++) cin >> temp[i];
  return temp;
}
void solve() {
  cin >> n;
  if (n == 2) {
    cout << "!"
         << "\n";
    cout.flush();
    cout << 1 << " " << 2 << "\n";
    cout.flush();
    return;
  }
  vector<bool> vis(n + 1, false);
  set<pair<long long, long long>> ans;
  long long cnt = 0;
  bool ok = true;
  long long curr = 1;
  while (ok && cnt < (n + 1) / 2 && curr > 0) {
    auto temp = query(curr);
    unordered_map<long long, vector<long long>> mp;
    for (long long i = 0; i < temp.size(); i++) mp[temp[i]].push_back(i + 1);
    for (auto el : mp) {
      if (el.second.size() == 1) {
        for (auto x : mp[el.first + 1])
          ans.insert({min(el.second[0], x), max(el.second[0], x)});
      }
    }
    cnt++;
    curr = -1, ok = false;
    long long maxi = -1;
    for (long long i = 0; i < temp.size(); i++) {
      if (temp[i] > maxi && vis[i] == false) {
        maxi = temp[i];
        curr = i + 1;
      }
    }
  }
  cout << "!"
       << "\n";
  cout.flush();
  for (auto el : ans) {
    cout << el.first << " " << el.second << "\n";
    cout.flush();
  }
}
signed main() {
  oj();
  solve();
  return 0;
}
