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>
#define mod 1000000007
#define pb push_back
#define ff first
#define ss second
#define ll long long
#define ii pair<ll,ll>
#define vi vector<ll>
#define vii vector<ii>
#define INF 1000000000
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); 
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
  
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define ordered_multiset tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>
 map<ll,set<ll>>m;
 vector<ll>v2(2001,0);
 void dfs(ll x){
	 v2[x]=1;
	 for(auto y:m[x]){
		 if(!v2[y]){
			 cout<<x<<" "<<y<<"\n";
			 dfs(y);
		 }
	 }

 }
int main(){
	IOS
	ll t;
	t=1;
	while(t--)
	{
     ll n;
	 cin>>n;
	 vector<ll>v1(n+1,0);
	 ll x=1;ll qu=(n+1)/2;
	 while((qu--)&&x<=n){
        cout<<"? "<<x<<"\n";
		cout.flush();
		v1[x]=1;
		ll c=0;
		vector<ll>v(n+1);ll y;
		for(ll i=1;i<=n;i++){
			cin>>v[i];
			if(v[i]==1){c++;m[x].insert(i);m[i].insert(x);v1[i]=1;y=i;}
		}
		if(c==1){
           for(ll i=1;i<=n;i++){
			if(v[i]==2){m[y].insert(i);m[i].insert(y);v1[i]=1;}
		}
		}
		vector<pair<ll,ll>>vxx;
		for(ll i=1;i<=n;i++){
			vxx.push_back({v[i],i});
		}
		sort(vxx.begin(),vxx.end());
		x=-1;
		for(ll i=n;i>=1;i--){
			if(!v1[vxx[i-1].second]){x=vxx[i-1].second;break;}
		}
		if(x==-1)break;
		
	 }
	 cout<<"!"<<"\n";
	 dfs(1);
     cout.flush();

	}

return 0;
}