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;
typedef long long LL;
#define N 501010
const LL MOD=1e9+7;
int a[N];
bool v[N];
set<pair<int,int> >hop1;
set<pair<int,int> >hop2;
bool jud(int n1,int n2,const set<pair<int,int> > &mys)
{
	if(mys.find({n1,n2})==mys.end())return 0;
	return 1;
}
int main()
{	
	ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
	int n;
	int cnt=0;
	cin>>n;
	int ub=n/2;
	if(n%2==1)ub+=1;
	queue<int>q;
	q.push(1);
	while(!q.empty()&&hop1.size()/2<n-1)
	{
		int t=q.front();
		q.pop();
		if(v[t])continue;
		v[t]=1;
		cout<<"? "<<t<<endl;
		++cnt;
		if(cnt>ub)while(1);
		cout.flush();
		vector<int> vec1,vec2,vec3;
		for(int i=1;i<=n;++i)
		{
			cin>>a[i];
			if(a[i]==1&&!jud(t,i,hop1))vec1.push_back(i);
			if(a[i]==2&&!jud(t,i,hop2))vec2.push_back(i);
			if(a[i]==3)vec3.push_back(i);
		}
		for(auto i:vec1)
		{
			v[i]=1;
			hop1.insert({t,i});
			hop1.insert({i,t});
			for(auto j:vec1)
			{
				if(i!=j)
				{
					hop2.insert({i,j});
					hop2.insert({j,i});
				}
			}
		}
		for(auto i:vec2)
		{
			hop2.insert({t,i});
			hop2.insert({i,t});
		}
		if(vec1.size()==1)
		{
			int d1=vec1[0];
			v[d1]=1;
			for(auto i:vec2)
			{
				v[i]=1;
				hop1.insert({d1,i});
				hop1.insert({i,d1});
				for(auto j:vec2)
				{
					if(i!=j)
					{
						hop2.insert({i,j});
						hop2.insert({j,i});
					}
				}
			}
			for(auto i:vec3)if(!v[i])q.push(i);
		}
		else for(auto i:vec2)if(!v[i])q.push(i);
	}
	cout<<"!\n";
	for(auto &e:hop1)if(e.first<e.second)cout<<e.first<<" "<<e.second<<endl;
	cout.flush();
}