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

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

map<int,set<int>> edges;
int known[2005];


int main()
{
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    ll n;
    cin >> n;

    deque<int> nex_node = {1};


    while(nex_node.size()){
        int i = nex_node.front();
        nex_node.pop_front();

        if(known[i])continue;
        known[i] = 1;
        cout << "? "<<i<<endl;

        pair<int,int> d[2005];
        for(int j=0;j<n;j++){
            cin >> d[j].first;
            d[j].second = j+1;
        }
        sort(d, d+n);
        int node = i;
        int pos = 1;
        while(1){
            vector<int> same_dep;
            same_dep.push_back(d[pos].second);
            while(d[pos+1].first == d[pos].first){
                same_dep.push_back(d[pos+1].second);
                pos++;
                if(pos==n)break;
            }


            // further values should be processed next
            int old_pos = pos;
            if(pos<n-1){
                pos++;
                nex_node.push_back(d[pos].second);
                while(pos+1<n && d[pos+1].first == d[pos].first){
                    pos++;
                    nex_node.push_back(d[pos].second);
                }
            }


            for(int j:same_dep){
                if(j==0)continue;
                edges[min(node,j)].insert(max(node,j));
                known[j] = 1;
            }


            if(same_dep.size()>1){

                break;
            }
            same_dep.clear();
            node = same_dep[0];
            pos = old_pos + 1;
        }
    }
    cout << "!"<<endl;
    for(auto i:edges){
        for(int j:i.second){
            cout << i.first << " " << j << "\n";
        }
    }
    cout << endl;



    return 0;
}
