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
# sys.stdin = open('input.txt', 'r') 
# sys.stdout = open('output.txt', 'w')
import math
import collections
from sys import stdin,stdout,setrecursionlimit
import bisect as bs
setrecursionlimit(2**20)
M = 10**9+7

def query(ind):
	print('?',ind+1,flush="True");
	return list(map(int,input().strip().split()))

def solve():
	n = int(input())

	vis = [0]*n

	edges = []

	
	node = 0
	count = (n+1)//2
	while count>0:
		cur = []
		cur = query(node)
		maxx = 0
		vis[node] = 1
		
		for i in range(n):
			if cur[i]==1:
				edges.append([node,i])
				vis[i] = 1
		for i in range(n):
			if vis[i]==0:
				maxx = max(maxx,cur[i])
		node = -1

		for i in range(n):
			if vis[i]==0 and cur[i]<maxx:
				node = i
				break
		if node==-1:
			for i in range(n):
				if vis[i]==0:
					node = i
					break
		if node==-1:
			break
		count-=1;

	print("!")
	for i in edges:
		print(i[0]+1,i[1]+1)


t = 1
if __name__ == "__main__":
    for _ in range(t):
        solve()
    
    
# n = int(stdin.readline())
# n,m = list(map(int,stdin.readline().split()))
# h = list(map(int,stdin.readline().split()))
# q = list(map(int,stdin.readline().split()))
# b = list(map(int,stdin.readline().split()))
# s = stdin.readline().strip('\n')