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

#!/usr/bin/env python3

import sys, math

class Node:
    def __init__(self, id):
        self.id     = id
        self.links  = set()

    def connectTo(self, other):
        self.links  |= {other}
        other.links |= {self}

    def processDistances(self, arr, N):
        last        = None
        prev_d      = None
        finished    = 0
        arr         = sorted(arr)

        for i, (d, id) in enumerate(arr):
            if finished and d > finished:
                return
            if last:
                last.connectTo(N[id])
            if prev_d == d:
                finished = d
            if i != len(arr) - 1 and arr[i + 1][0] != d:
                last = N[id]
            prev_d = d

    def describe(self, listed=set()):
        for child in self.links:
            key = (*sorted([self.id, child.id]),)
            if key not in listed:
                print(*key)
                child.describe(listed | {key})


n = int(input())
N = {id: Node(id) for id in range(1, n + 1)}

for id in range(1, n + 1):
    if not N[id].links:
        print("?", id)
        arr = [(d, i + 1) for i, d in enumerate(map(int, input().split()))]
        N[id].processDistances(arr, N)
        # print("===")
        # N[id].describe()
        # print("===")

print("!")
N[1].describe()
