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 collections import defaultdict
import sys

g = defaultdict(list)


def query(r):
    print(f"? {r + 1}")
    sys.stdout.flush()

    li = list(map(int, input().split()))
    return li


def dfs(cur, par):
    for to in g[cur]:
        if to == par:
            continue
        print(f"{cur + 1} {to + 1}")
        sys.stdout.flush()

        dfs(to, cur)


def add_edges():
    for k in range(n):
        if t_li[k] == 1:
            g[j].append(k)
            g[k].append(j)


for _ in range(1):
    n = int(input())
    li = query(0)
    for i in range(n):
        if li[i] == 1:
            g[0].append(i)
            g[i].append(0)
    for i in range(2, n, 2):
        for j in range(n):
            if li[j] == i:
                t_li = query(j)
                add_edges()
    print("!")
    sys.stdout.flush()

    dfs(0, -1)
    sys.stdout.flush()
