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;

#define ll              long long
#define pb              push_back
#define mp              make_pair
#define F               first
#define S               second 
#define all(x)          x.begin(),x.end()
#define rall(x)         x.rbegin(),x.rend()
#define loop(i,m,n)     for(ll i=m; i<n; i++)
#define rloop(i,m,n)    for(int i=m; i>=n; i--)
#define print(x)        for(auto t : x){cout << t << " ";}cout <<"\n";
#define printnl(x)      for(auto t : x)cout << t <<"\n";

#define MOD  1000000007
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

typedef pair<ll,ll>   pii; 
typedef vector<int>     vi;   
typedef vector<ll>      vl;  
typedef vector<double>  vd;  
typedef vector<char>    vc;  
typedef vector<string>  vs;  
typedef set<int>        si;  
typedef set<ll>         sl;  
typedef set<double>     sd;  
typedef set<char>       sc;  
typedef set<string>     ss;  
typedef map<int,int>    mi;  
typedef map<ll,int>     ml;  
typedef map<double,int> md;  
typedef map<char,int>   mc;  
typedef map<string,int> ms;  

// **************************************************************************************
ll n;
vector<bool> v(2005,0);
vector<ll> dist(2005);
set<pii> ans;

void query(ll u){
    v[u]=1;
    cout<<"? "<<u<<endl;
    loop(i,1,n+1){
        cin>>dist[i];
        if(dist[i]==1)ans.insert({min(u,i),max(u,i)});
    }
}

/* tree is bipartite, min(number of black, number of white) nodes is ≤ [n/2]
   To figure out which set is smaller, we can just query any node and look at which 
   nodes have odd depth and which ones have even depth
   whichever are less push them to queue*/

void solve(){
    cin>>n;
    queue<ll> q;

    query(1);
    ll even_count=0, odd_count=0;
    loop(i,1,n+1){
        if(dist[i]&1)odd_count++;
        else even_count++;
    }
    if(even_count>odd_count){
        loop(i,1,n+1){
            if(dist[i]%2==1 && v[i]==0)q.push(i);
        }
    }
    else{
        loop(i,1,n+1){
            if(dist[i]%2==0 && v[i]==0)q.push(i);
        }
    }

    while(!q.empty()){
        ll temp = q.front();
        q.pop();
        query(temp);
    }
    
    cout<<"!"<<endl;
    for(auto i:ans){
        cout<<i.F<<" "<<i.S<<"\n";
    }
    return;
}

int main(){
    fast

    int tc = 1;
    // cin>>tc;
    while(tc--){
        solve();
    }

    return 0;
}