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;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pib = pair<int, bool>;
using vi = vector<int>;
const char br = '\n';
const int INF = (int)1e9;
const ll INFLL = (long long)2e18;
const int MOD = (int)1e9 + 7;
const int N = (int)1e6 + 5;
const double EPS = 1E-9;
const double EPS_ANG = 1E-16;
const static double PI = 3.141592653589793;
const int dx[8] = {+0, +0, +1, -1, +1, +1, -1, -1};
const int dy[8] = {+1, -1, +0, +0, +1, -1, +1, -1};
vector<int> query(int x, int n) {
  cout << "? " << x << br;
  cout.flush();
  static vector<int> v(n);
  for (int& x : v) cin >> x;
  return v;
}
int main(int argc, char** argv) {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t = 1;
  for (int cas = 1; cas <= t; ++cas) {
    int n;
    cin >> n;
    set<pii> ans;
    vector<int> v = query(1, n);
    vector<int> even, odd;
    for (int i = 0; i < n; ++i) {
      if (v[i] & 1)
        odd.push_back(i + 1);
      else
        even.push_back(i + 1);
    }
    vector<int> color;
    if (odd.size() <= (n + 1) / 2)
      color = odd;
    else {
      for (int i = 0; i < n; ++i) {
        if (v[i] == 1) ans.insert({1, i + 1});
      }
      for (int x : even) {
        if (x - 1) color.push_back(x);
      }
    }
    for (int x : color) {
      v = query(x, n);
      for (int i = 0; i < n; ++i) {
        if (v[i] == 1) ans.insert({min(x, i + 1), max(x, i + 1)});
      }
    }
    cout << "!\n";
    for (auto p : ans) cout << p.first << " " << p.second << br;
  }
  return 0;
}
