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.*;
 
public class D {
	
    public static void main(String[] args)
    {
    	FastScanner sc=new FastScanner();
    	int t=1;
    	while(t-->0) {
    		int n=sc.nextInt();
    		System.out.println("? 1");
    		int[] dist=new int[n];
    		for(int i=0;i<n;i++) {
    			dist[i]=sc.nextInt();
    		}
    		boolean[][] hasEdge=new boolean[n][n];
    		ArrayList<Integer> even=new ArrayList<>(),odd=new ArrayList<>();
    		for(int i=0;i<n;i++) {
    			if(dist[i]%2==0) {
    				if(i!=0) {
        				even.add(i);
    				}
    			} else {
    				odd.add(i);
    			}
    			if(dist[i]==1) {
    				hasEdge[0][i]=hasEdge[i][0]=true;
    			}
    		}
    		ArrayList<Integer> toCheck;
    		if(even.size()<=odd.size()) {
    			toCheck=even;
    		} else {
    			toCheck=odd;
    		}
    		for(int z:toCheck) {
    			System.out.println("? "+(z+1));
    			for(int i=0;i<n;i++) {
    				int val=sc.nextInt();
    				if(val==1) {
    					hasEdge[z][i]=hasEdge[i][z]=true;
    				}
    			}
    		}
    		System.out.println("!");
    		for(int i=0;i<n;i++) {
    			for(int j=i+1;j<n;j++) {
    				if(hasEdge[i][j]) {
        				System.out.println((i+1)+" "+(j+1));
    				}
    			}
    		}
    	}
    }
	
	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}
		
		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}