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 java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.StringTokenizer;

public class E {

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        HashSet<String> ans = new HashSet<>();
        System.out.println("? " + 1);
        int[] ls = new int[n];
        StringTokenizer st = new StringTokenizer(br.readLine());
        int r1 = 0;
        for (int i = 0; i < n; i++) {
            ls[i] = Integer.parseInt(st.nextToken());
            if (ls[i] == 1) {
                ans.add("1 " + (i + 1));
            }
            r1 += ls[i] % 2;
        }
        int r0 = n - r1 - 1;
        for (int i = 0; i < n && ans.size() < n - 1; i++) {
            if ((r0 < r1 && ls[i] % 2 == 0 && i != 0) || (r1 <= r0 && ls[i] % 2 == 1)) {
                System.out.println("? " + (i + 1));
                System.out.flush();
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < n; j++) {
                    int l = Integer.parseInt(st.nextToken());
                    String key = i < j ? (i + 1) + " " + (j + 1) : (j + 1) + " " + (i + 1);
                    if (l == 1 && !ans.contains(key)) {
                        ans.add(key);
                    }
                }
            }
        }
        System.out.println("!");
        for (String edge : ans) {
            System.out.println(edge);
        }

    }

}
