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

// Parasparopagraho Jīvānām
 
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
 
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>
 
using namespace  __gnu_pbds ;
using namespace __gnu_cxx ;
using namespace std ; 
 
typedef long long ll ;
typedef long double ldb ;
 
typedef pair<int, int> pii ;
typedef pair<int, ll> pil ;
typedef pair<ll,ll> pll ;
 
typedef vector<int> vi ;
typedef vector<ll> vll ;
typedef vector<pii> vpi ;
typedef vector<pll> vpl ;
typedef vector<bool> vb ; 
typedef vector<pair<ll,int> > vpli ; 
typedef vector<int,pil> edges ;
typedef vector<vi> matrix ; 
typedef priority_queue<int> pqu ; 
 
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update> ;
 
#define rep(i,a,b) for (int i = (a); i <= (b); i++)
#define per(i,b,a) for (int i = (b); i >= (a); i--)
 
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define pob pop_back 
#define fi first
#define se second
#define ins insert 
#define bk back
#define con continue 
#define lbd lower_bound 
#define ubd upper_bound 
 
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
 
#define pr cout << // I don't like this but my laptop's 'O' key is not functioning well
 
/* Careful when using long long
__builtin_clz(int x) {} //: the number of zeros at the beginning of the number
__builtin_ctz(int x) {} //: the number of zeros at the end of the number
__builtin_popcount(int x) {} //: the number of ones in the number
__builtin_parity(int x) {} //: the parity (even or odd) of the number of ones */
 
const int mod1 = 1000000007 ;
const int mod2 = 998244353 ;
const ll  infl = 4e18 ;
const int infi = 2e9 ;
const int maxn = 1e6 + 5 ;
const int block = 500 ;
const int logn = 60 ;
const int alpha = 27 ;
const ldb pi = acos(-1) ;
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) ;
int rng_lr(int a, int b)
{
    int ret ;
    ret = uniform_int_distribution<int>(a, b)(rng) ;
    return ret ;
    // For shuffling use shuffle(all, rng) ; 
}
 
ll modpow(ll a, ll b, int MOD) { ll res = 1 ; while(b) { if(b&1) { res = res*a ; res %= MOD ; } a *= a ; a %= MOD ; b >>= 1 ; } return res%MOD ; }
void upmin(int &a, int b) { if(a < b) { a = b ; } }
void relax(int &a, int b) { if(a > b) { a = b ; } }
ll add(ll a, ll b, int MOD) { a += b ; if(a >= MOD) { a -= MOD ; } return  a ; }
ll sub(ll a, ll b, int MOD) { a -= b ; if(a < 0) { a += MOD ; } return a ; }
ll mul(ll a, ll b, int MOD) { b %= MOD ; a *= b ; a %= MOD ; return a ; }
ll inverse(ll a, ll MOD) { a = modpow(a, MOD - 2, MOD) ; return a ; }
ll lcm(ll a, ll b) { ll ret ; ll g = __gcd(a, b) ; ret = a/g ; ret = ret*b ; return ret ; }
int icast(char ch) { return int(ch-'a') ; }
void hyn(int a, int b) { if(a == b) cout << "YES\n" ; else cout << "NO\n" ; } 
void pyd(int a, int b) { if(a == b) cout << "First\n" ; else cout << "Second\n" ; } 

// Check constraints + overflows + types in typedef 
int n ; 
vi graf[2005] ; 
int par[2005] ; 
vi ask(int r) {
	vi ret(n) ; 
	pr "? " << r << endl ; 
	rep(i,0,n-1) {
		cin >> ret[i] ; 
	}
	return ret ; 
}
int main() 
{
    ios::sync_with_stdio(false) ;
    cin.tie(NULL) ;  
    cin >> n ; 
    vi d = ask(1) ; 
    vi lvl[n] ;
    rep(i,0,n-1) {
    	if(d[i] == 1) {
    		par[i] = 0 ; 
    	}
    	lvl[d[i]].pb(i) ; 
    }
    for(int i = 2 ; i < n ; i += 2) {
    	for(int j : lvl[i]) {
    		vi newd = ask(j+1) ; 
    	    rep(k,0,n-1) {
    	    	if(newd[k] == 1 && d[k] < d[j]) {
    	    		par[j] = k ; 
    	    	}
    	    }
    	}
    }
    pr "!" << endl ;
    rep(i,1,n-1) {
    	pr i + 1 << " " << par[i] + 1 << endl ; 
    }

    return 0 ; 
}
