///?
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <string>
#include <iomanip>
#include <utility>
//#include <conio.h> C++14 upper
#include <limits.h>
#include <random>  //mt19937
#include <unordered_map>
#include <unordered_set>
#include <math.h>
#include <queue> //priority queue
#include <time.h>  //clock_t
#include <deque>
#define taskname ""
#define faster ios_base::sync_with_stdio(false);\
cin.tie(nullptr);
#define debug(x) cout<<x<<". ";
#define debug1(a,n) for (int i=0;i<n;++i) cout<<a[i]<<":) ";
#define debug2(d,m,n) for (int i=0;i<m;++i){\
                        for (int j=0;j<n;++j) cout<<a[i][j]<<":)) ";\
                        cout<<"\n";\
                      }
#define pb push_back
#define min(a,b) ((a>b)?b:a)
#define max(a,b) ((a>b)?a:b)
#define ceil(a,b) ((a%b==0)?a/b:a/b+1)
#define XOR(a,b) (a^b)
#define AND(a,b) (a&b)
#define OR(a,b) (ab)
#define NOT(a) (~a)

using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;

const int Mod = 1000000007;
const int maxN = 2e3 + 1;
int tt, n;
int d[maxN];
vector <pair <int,int>> tree;
vector <int> odd, even;

void Init(){
    cin >> n;
    cout << "? 1" << endl;
    for (int i = 1; i <= n; ++i) cin >> d[i];
    int cnt = 0;
    for (int i = 2; i <= n; ++i){
        if (d[i] % 2 == 0){
            ++cnt;
            even.pb(i);
        }
        else odd.pb(i);
    }
    if (cnt < n - cnt - 1){
        for (int i = 2; i <= n; ++i)
            if (d[i] == 1)
                tree.pb({1, i});
        //check all even numbers
        for (int u: even){
            cout << "? " << u << endl;
            for (int v = 1; v <= n; ++v){
                cin >> d[v];
                if (d[v] == 1) tree.pb({u, v});
            }
        }
    }
    else{
        //check all odd numbers;
        for (int u: odd){
            cout << "? " << u << endl;
            for (int v = 1; v <= n; ++v){
                cin >> d[v];
                if (d[v] == 1) tree.pb({u, v});
            }
        }
    }
    cout << "!" << endl;
    for (auto i: tree) cout << i.first << " " << i.second << endl;
    return;
}

int main(){
    //freopen(taskname".INP","r",stdin);
    //freopen(taskname".OUT","w",stdout);
    Init();
}
