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

import java.lang.*;

public class Practice {
	public static long mod = (long) Math.pow(10, 9) + 7;
	public static long mod2 = 998244353;
	public static long tt = 0;
	public static int[] ttt = new int[2];
	public static long[] fac = new long[500000];
	public static ArrayList<Integer> prime;

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);

		// int t = Integer.parseInt(br.readLine());
		// while (t-- > 0) {
		int n = Integer.parseInt(br.readLine());

		HashMap[] edg = new HashMap[n + 1];
		for (int i = 0; i <= n; i++) {
			edg[i] = new HashMap<Integer, Integer>();
		}
		HashMap<String, Integer> map = new HashMap<>();
		int[] done = new int[n + 1];
		System.out.println("? " + 1);
		System.out.flush();
		String[] s1 = br.readLine().split(" ");
		int even = 0, odd = 0;
		done[1] = 1;
		for (int i = 0; i < n; i++) {
			if (Integer.valueOf(s1[i]) == 1) {
				odd++;
				done[i + 1] = 1;
				map.put(1 + " " + (i + 1), 1);
			} else if (Integer.valueOf(s1[i]) == 2) {
				even++;
			} else if (Integer.valueOf(s1[i]) > 0 && Integer.valueOf(s1[i]) % 2 == 0) {
				even++;
			} else if (Integer.valueOf(s1[i]) > 0 && Integer.valueOf(s1[i]) % 2 == 1) {
				odd++;
			}
		}
		// System.out.println(three);
		if (odd >= even) {
			for (int i = 0; i < n; i++) {
				if (Integer.valueOf(s1[i]) == 2) {
					if (done[i + 1] == 0) {
						getAnsEven(i + 1, done, map, br, n);
					}
				}
			}
		} else {
			for (int i = 0; i < n; i++) {
				if (Integer.valueOf(s1[i]) == 1) {
					// System.out.println("****************** " + i);
					getAnsEven(i + 1, done, map, br, n);

				}
			}
		}
		// System.out.println(map);
		System.out.println("!");
		for (String aa : map.keySet()) {
			System.out.println(aa);
		}
		System.out.flush();
		// }
		pw.close();

	}

	private static void getAnsEven(int i, int[] done, HashMap<String, Integer> map, BufferedReader br, int n)
			throws IOException {
		// TODO Auto-generated method stub
		System.out.println("? " + i);
		System.out.flush();
		String[] s1 = br.readLine().split(" ");
		done[i] = 1;
		int two = 0;

		for (int j = 0; j < n; j++) {
			if (Integer.valueOf(s1[j]) == 1) {
				int min = Math.min(i, j + 1);
				int max = Math.max(i, j + 1);
				map.put(min + " " + max, 1);
			} else if (Integer.valueOf(s1[j]) == 2) {
				if (done[j + 1] != 1) {
					getAnsEven(j + 1, done, map, br, n);
					two++;
				}
			}
		}
	}

//0 1 1 2 2 2 2 3 3 3 3 3
//2 3 1 0 4 2 4 5 3 3 1 1
//2 3 1 2 4 0 4 5 1 1 3 3 
//2 1 3 4 0 4 2 3 5 5 5 5
//2 1 3 4 2 4 0 1 5 5 5 5

//	private static long power(long a, long p) {
//		// TODO Auto-generated method stub
//		long res = 1;
//		while (p > 0) {
//			if (p % 2 == 1) {
//				res = (res * a) % mod;
//			}
//			p = p / 2;
//			a = (a * a) % mod;
//		}
//		return res;
//	}
//
//	private static void fac() {
//		fac[0] = 1;
//		// TODO Auto-generated method stub
//		for (int i = 1; i < fac.length; i++) {
//			if (i == 1) {
//				fac[i] = 1;
//			} else {
//				fac[i] = i * fac[i - 1];
//			}
//			if (fac[i] > mod) {
//				fac[i] = fac[i] % mod;
//			}
//		}
//	}
//
//	private static int getLower(Long long1, Long[] st) {
//		// TODO Auto-generated method stub
//		int left = 0, right = st.length - 1;
//		int ans = -1;
//		while (left <= right) {
//			int mid = (left + right) / 2;
//			if (st[mid] <= long1) {
//				ans = mid;
//				left = mid + 1;
//			} else {
//				right = mid - 1;
//			}
//		}
//		return ans;
//	}

}
//	private static long getGCD(long l, long m) {
//
//		long t1 = Math.min(l, m);
//		long t2 = Math.max(l, m);
//		while (true) {
//			long temp = t2 % t1;
//			if (temp == 0) {
//				return t1;
//			}
//			t2 = t1;
//			t1 = temp;
//		}
//	}