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.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Hello1 {
	static FastReader s = new FastReader();
	public static int[] query(int i, int n) {
		System.out.println("? " + i);
		System.out.println();
		System.out.flush();
		int[] a = new int[n + 1];
		for(int j = 1; j <= n; j++) {
			a[j] = s.nextInt();
		}
		
		return a;
	}
	
	public static void main(String[] args) throws IOException {
		int n = s.nextInt();
		ArrayList<ArrayList<Integer>> aList =  new ArrayList<ArrayList<Integer> >(n + 1);
        for (int i = 1; i <= n + 1; i++) { 
            ArrayList<Integer> list = new ArrayList<>(); 
            aList.add(list); 
        }
		int[] a1 = query(1, n);
		int[][] matrix = new int[n + 1][n + 1];
		//System.out.println(Arrays.toString(a1));
		for(int i = 2; i <= n; i++) {
			int dist = a1[i];
			aList.get(dist).add(i);
			if(dist == 1) {
				matrix[i][1] = 1;
				matrix[i][1] = 1;
			}
		}
		int odd = 0; int even = 0;
		for(int i = 1; i <= n; i++ ) {
			if(i % 2 == 0) even = even + aList.get(i).size();
			else odd = odd + aList.get(i).size();
		}
		int lev = 2; int q = 1;
		if(odd <= even) lev = 1;
		//System.out.println(odd + " " + even);
//		for(int  i = 1; i <= n ; i++) {
//			System.out.println(aList.get(i).toString());
//		}
		//System.out.println(aList.size());
		while(lev < aList.size() && aList.get(lev).size() > 0) {
				for(int j = 0; j < aList.get(lev).size(); j++) {
					int[] a2 = query(aList.get(lev).get(j), n);
					q = q + 1;
					for(int k = 1; k <= n; k++) {
						if(a2[k] == 1) {
							matrix[aList.get(lev).get(j)][k] = 1;
							matrix[k][aList.get(lev).get(j)] = 1;
						}
					}
				lev = lev + 2;
				
			}
		}
			System.out.println("! ");
			
//			for(int i = 1; i <= n; i++) {
//				System.out.println(Arrays.toString(matrix[i]));
//			}
			for(int i = 1; i <= n; i ++) {
				for(int j = 1; j <= i; j++) {
					//System.out.print(matrix[i][j]);
					if(matrix[i][j] == 1) {
						System.out.println(i + " " + j);	
					}
				}
				//System.out.println();
				
			}
			System.out.println();
			System.out.flush();
			
			
		
		
		}
		
		
			
		
	}

	
	
class FastReader {
    BufferedReader br;
    StringTokenizer st;
    public FastReader() {
        br = new BufferedReader(new InputStreamReader(System.in));
    }
    String next() {
        while (st == null || !st.hasMoreElements()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    String nextLine() {
        String str = "";
        try {
            str = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }
}

