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

from sys import stdin, stdout
input = stdin.readline

############ ---- Input Functions ---- ############
def inp():
    return(int(input()))
def inlt():
    return(list(map(int,input().split())))
def insr():
    s = input()
    return(list(s[:len(s) - 1]))
def invr():
    return(map(int,input().split()))

edges = []
def add_edges(i, d):
    for j in range(len(d)):
        if d[j] == 1:
            edges.append((i,j + 1))

n = inp()

print("? 1")
stdout.flush()
d = inlt()
levels = []
for i in range(max(d) + 1):
    levels.append([])
for i in range(len(d)):
    levels[d[i]].append(i + 1)
num_evens = 0
for i in range(0, len(levels), 2):
    num_evens += len(levels[i])

if num_evens <= n // 2:
    add_edges(1, d)
    for i in range(2, len(levels), 2):
        for j in levels[i]:
            print(f"? {j}")
            stdout.flush()
            d = inlt()
            add_edges(j, d)
else:
    for i in range(1, len(levels), 2):
        for j in levels[i]:
            print(f"? {j}")
            stdout.flush()
            d = inlt()
            add_edges(j, d)
print("!")
for e in edges:
    print(f"{e[0]} {e[1]}")

# Segfaults on cpp so we switched to the trusty python :)