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.*;
import java.util.*;

/*
polyakoff
*/

public class Main {

    static FastReader in;
    static PrintWriter out;
    static Random rand = new Random();
    static final int oo = (int) 1e9 + 10;
    static final long OO = (long) 1e18 + 10;
    static final int MOD = (int) 1e9 + 7;

    static int n;

    static void ask(int v, int[] d) {
        out.printf("? %d\n", v + 1);
        out.flush();
        for (int i = 0; i < n; i++) {
            d[i] = in.nextInt();
        }
    }

    static void solve() {
        n = in.nextInt();
        int[] d0 = new int[n];
        int v0 = rand.nextInt(n);
        ask(v0, d0);

        HashSet<Integer>[] g = new HashSet[n]; Arrays.setAll(g, i -> new HashSet<>());
        int cnt0 = 0, cnt1 = 0;
        for (int u = 0; u < n; u++) {
            if (d0[u] == 1) {
                g[v0].add(u);
                g[u].add(v0);
            }
            if (d0[u] % 2 == 0)
                cnt0++;
            else
                cnt1++;
        }
        int[] d = new int[n];
        for (int v = 0; v < n; v++) {
            if (v != v0 && ((d0[v] % 2 == 0 && cnt0 <= cnt1) || (d0[v] % 2 == 1 && cnt1 < cnt0))) {
                ask(v, d);
                for (int u = 0; u < n; u++) {
                    if (d[u] == 1) {
                        g[v].add(u);
                        g[u].add(v);
                    }
                }
            }
        }
        out.println("!");
        for (int v = 0; v < n; v++) {
            for (int u : g[v]) {
                if (v < u)
                    out.println((v + 1) + " " + (u + 1));
            }
        }

    }

    public static void main(String[] args) {
        in = new FastReader();
        out = new PrintWriter(System.out);

        int t = 1;
//        t = in.nextInt();
        while (t-- > 0) {
            solve();
        }

        out.flush();
        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader() {
            this(System.in);
        }
        FastReader(String file) throws FileNotFoundException {
            this(new FileInputStream(file));
        }
        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }
        String nextLine() {
            String line;
            try {
                line = br.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }
    }
}
