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

 // "It does not matter how slowly you go as long as you do not stop." - Confucius
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// ordered_set s;  // *(s.find_by_order()) used in ordered_set and s.order_of_key()
// For ordered multiset, replace less above by less_equal
#define pb push_back
#define ff(i,a,b) for(int i=a;i<b;++i)
#define ffr(i,b,a) for(int i=b;i>=a;--i)
#define fflr(i,b,a) for(long long i=b;i>=a;--i)
#define ffl(i,a,b) for(long long i=a;i<b;++i)
#define all(v) v.begin(), v.end() 
#define endl '\n'
#define Yes cout << "Yes" << endl
#define No cout << "No" << endl
#define YES cout << "YES" << endl
#define NO cout << "NO" << endl
#define trav(a,x) for (auto& a : x)
#define lb lower_bound
#define ub upper_bound
#define ins insert
#define X first
#define Y second
#define mp make_pair
#define mt make_tuple
typedef long double ld;
typedef std::pair<int,int> pii;
typedef pair<ll,ll> pll; 
typedef std::vector<int> vec;
typedef vector<pii> vii;
typedef vector<pll> vll;
typedef std::vector<long long> vecl;
typedef map<int,int> mii;
typedef map<ll,ll> mll;

void FAST() {	// FAST Input Output, DONT use both scnaf,printf / cin,cout , Use any ONE system
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

const ll md = 1000000007;
#define pi 3.141592653589793238462643383279
const ll inf = 1e18L + 5;  // max 1000*inf
const char nl = '\n';
const int thirty_Two_Bit_Integer_Max_Value=2147483647;  // INT_MAX
const int N=200005;

/********************************************************************************************/

vector<vec> g(2001); 
int n;

vector<int> query(int j){     // For INTERACTIVE PROBLEMS, do flush after every printing, answer also
    vector<int> v(n+1,0);
    cout<<"? "<<j<<"\n";
    cout.flush();
    ff(i,1,n+1)cin>>v[i];
    return v;
}

int main() {
	FAST();
    int tt{},T{};tt=1;  //cin>>tt;T=tt;
    
 	while(tt--){
        string str,sa,sb,sc;   //cout<<"--------Test:"<<T-tt<<endl;
        int m{},ans{},k{},a{},b{},c{},x{},y{},f{};  
        
        
        cin>>n; //vec v(n); ff(i,0,n)cin>>v[i];
        k=n/2;
        if(n%2)++k;
        vec v,w;
        vector<set<int>> gg(2001);
        mii mm;
        queue<int> q;
        q.push(1);
        c=0;
        while(!q.empty()&&c<k){
            ++c;
            int i=q.front();
            mm[i]=1;
            q.pop();
            w=v;
            v=query(i);
            ff(j,1,n+1){
                if(v[j]==1){
                    if(!mm[j])q.push(j);
                    g[i].pb(j);
                }
            }
            if(i>1){
                ff(j,1,n+1){
                    if(w[j]==2&&v[j]==3){
                        gg[j].insert(i);
                    }
                }
            }
        }
        
        cout<<"!\n";
        cout.flush();
        
        set<int> s;
        ff(i,1,n+1)s.insert(i);
        
        map<pii,int> ma;
        
        ff(i,1,n+1){
            trav(e,g[i]){
                if(s.find(i)!=s.end())s.erase(i);
                if(s.find(e)!=s.end())s.erase(e);
                if(ma[{i,e}]==1||ma[{e,i}]==1)continue;
                ma[{i,e}]=ma[{e,i}]=1;
                cout<<i<<" "<<e<<"\n";
                cout.flush();
            }
        }
        
        if(s.size()){
            a=*s.begin();
            s.erase(a);
            ffr(i,n,1){
                if(gg[a].find(i)==gg[a].end()){
                    cout<<a<<" "<<i<<"\n";
                    cout.flush();
                    break;
                }
            }
        }
        
    }
    
	return 0;
}