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

IS_INTERACTIVE = True
input = input  # type: ignore

# input: function
if not IS_INTERACTIVE:
    *data, = sys.stdin.read().split("\n")[::-1]

    def input():  # type: ignore
        return data.pop()

def fprint(*args, **kwargs):
    print(*args, **kwargs, flush=True)

def eprint(*args, **kwargs):
    print(*args, **kwargs, file=sys.stderr)

def norm(i, j):
    if i > j:
        i, j = j, i
    return (i, j)

def query(v):
    global limiter
    assert limiter
    assert 0 <= v < n
    limiter -= 1
    fprint("?", v + 1)
    return [int(v) for v in input().split()]


def add(v, j):
    g[v].add(j)
    g[j].add(v)
    edges.add(norm(v, j))

n = int(input())
limiter = (n + 1) // 2
eprint("limit", limiter)
to_visit = set(range(n))
edges = set()
g = [set() for _ in range(n)]

while to_visit and len(edges) != n - 1:
    v = next(iter(to_visit))
    distances = query(v)
    assert distances[v] == 0
    to_visit.remove(v)
    pars = []
    count2ver = [[] for _ in range(n)]
    for j in range(n):
        count2ver[distances[j]].append(j)
    for d in range(n):
        if len(count2ver[d]) == 1:
            for j in count2ver[d]:
                if j in to_visit:
                    to_visit.remove(j)
                if d > 0:
                    for z in count2ver[d - 1]:
                        add(j, z)
                if d < n - 1:
                    for z in count2ver[d + 1]:
                        add(j, z)
    # print(edges)


fprint("!")
assert len(edges) == n - 1
for src, dst in sorted(edges):
    fprint(src + 1, dst + 1)
