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

import sys
import random
import collections

test = False
edges = [(1, 2) ,(1, 3) ,(1, 4) ,(2, 5) ,(2, 6) ,(3, 7) ,(3, 8) ,(4, 9) ,(4, 10) ,(5, 11) ,(5, 12)]
adj = collections.defaultdict(list)
for u,v in edges:
	adj[u].append(v)
	adj[v].append(u)

def ask(l, n):

	if test:
		q = collections.deque([(l,0)])
		vis = set([l])
		h = [+float('inf') for _ in range(0, n+1)]
		while(q):
			u,dis = q.popleft()
			h[u] = dis
			for v in adj[u]:
				if v not in vis:
					vis.add(v)
					q.append((v,dis+1))

		return h[1:]

	query = '? {}'.format(l)
	print query
	sys.stdout.flush()
	return map(int,raw_input().split())


def work(u, bis, res):
	for v,val in enumerate(bis):
		if val == 1:
			uu,vv = u, v+1
			if uu > vv:
				uu,vv = vv,uu
			res.add((uu,vv))



n = int(raw_input()) if not(test) else 12
bis = ask(1, n)
res = set([])

cc = collections.defaultdict(collections.deque)
for i,di in enumerate(bis):
	if i == 0:
		work(1, bis, res)
		continue
	cc[di % 2].append(i+1)

for u in (cc[1] if len(cc[1]) <= len(cc[0]) else cc[0]):
	work(u, ask(u,n), res)

print '!'
for u,v in res:
	print u,v
#print res  == set(edges)
sys.stdout.flush()