/**
  --------------------------------------------------
  |   made by Matvey Bunos (@nyashenotik) with <3  |
  |           2021 - Lyceum BSU - 10 IM	       	   |
  |          *** All rights reserved *** 	       |
  --------------------------------------------------
                                                    **/

#include <iostream>
#include <fstream>
#include <math.h>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <climits>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int MAXN = 5e5 + 1;
const int mod = 1e9 + 7;


int64_t binpow(int64_t a, int b) {
    int64_t res = 1;
    if(!b)
        return 1;
    if(b == 1)
        return a % mod;
    while(b > 0) {
        if(b & 1)
            res = (a * res) % mod;
        a *= a;
        a %= mod;
        b >>= 1;
    }

    return res % mod;
}

int n;
set <int> g [MAXN];
bool used[MAXN];

vector <int> ans(int v) {
    used[v] = true;
    cout << "? " << v + 1 << '\n';
    cout.flush();

    vector <int> d(n);

    for(int i = 0; i < n; i ++) {
        cin >> d[i];

        if(d[i] == 1 )
            g[min(v, i)].insert(max(i, v));
    }
    return d;
}

void slv() {
    cin >> n;

    vector <int> d = ans(0);
    int cnt[2] = {0, 0};
    for(int i = 0; i < n; i ++)
        if(d[i] > 0)
            cnt[d[i] % 2] ++;

    bool biggest = 0;

    if(cnt[0] > cnt[1])
        biggest = 1;

    for(int i = 1; i < n; i ++)
        if(d[i] % 2 == biggest)
            ans(i);

    cout << "!\n";
    for(int i = 0; i < n; i ++)
        for(int j : g[i])
            cout << i + 1 << ' ' << j + 1 << '\n';
}


int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t = 1;
    //cin >> t;

    while(t --) {
        slv();
        cout << '\n';
    }
    return 0;
}