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
edges = set([])
distances = {}
children = {}
parent = {1: None}
max_dist = None
n = int(input())
def query(m):
    print(f'? {m}')
    sys.stdout.flush()
    d = [int(x) for x in input().split()]
    return d

def process1(m):
    d = query(m)
    distances[m] = {}
    children[m] = set([])
    new_edges = []
    for i in range(1, n+1):
        if m==1:
            if d[i-1] not in distances[m]:
                distances[m][d[i-1]] = set([])
            distances[m][d[i-1]].add(i)
        else:
            my_parent = parent[m]
            if d[i-1]+1 in distances[my_parent]:
                if i in distances[my_parent][d[i-1]+1]:
                    if d[i-1] not in distances[m]:
                        distances[m][d[i-1]] = set([])
                    distances[m][d[i-1]].add(i)
        if d[i-1]==1 and (parent[m] != i):
            parent[i] = m
            edges.add((m, i))
            new_edges.append(i)
    return new_edges

def process(m):
    new_edges = process1(m)
    my_max = len(distances[m])-1
    R = len(new_edges)
    for i in range(R-1):
        a = new_edges[i]
        if a not in distances[m][my_max]:
            process(a)
            if len(edges)==n-1:
                break
    if len(new_edges)==0:
        return
    a = new_edges[-1]
    distances[a] = {}
    for x in distances[m]:
        if x-1 not in distances[a]:
            distances[a][x-1] = set([])
        for y in distances[m][x]:
            if y not in parent:
                distances[a][x-1].add(y)
    if 2 in distances[m]:
        for b in distances[m][2]:
            if b not in parent:
                parent[b] = a
                edges.add((a, b))
                if 2 != my_max:
                    process(b)
process(1)
print('!')
for a, b in edges:
    print(f'{a} {b}')
sys.stdout.flush()
