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>
    #include <unordered_map>
    #define ll long long int
    #define endl "\n"
    // Header files, namespaces,
    // macros as defined above

    #define debug(a) cout << a << endl
    using namespace std;
    // Important header files
    #include <ext/pb_ds/assoc_container.hpp> // Common file
    #include <ext/pb_ds/tree_policy.hpp>
    #include <functional> // for less

    #include <ext/pb_ds/tree_policy.hpp>
    using namespace __gnu_pbds;
    #define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>

    const ll inf = 10e15;
    void I_O()
    {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
    #ifndef ONLINE_JUDGE
        // for getting input from input.txt
        freopen("T:\\input_output\\input.txt", "r", stdin);
        // for writing output to output.txt
        freopen("T:\\input_output\\output.txt", "w", stdout);
    #endif
    }
   
    const int N=2*1e3+2;
    int dis[N];
    int n;
    void read(int r){
        cout<<"?"<<" "<<r<<"\n";
        cout.flush();
        for(int i=1;i<=n;i++){
            cin>>dis[i];
        }
    }
    int main()
    {
       // I_O();

        cin>>n;
        read(1);
        set<pair<int,int>>edges;
        vector<int>s[2];
        for(auto i=2;i<=n;i++){
            s[dis[i]&1].push_back(1);
        }
        if(s[0].size()>s[1].size()) swap(s[0],s[1]);
        for(int i=1;i<=n;i++){
            if(dis[i]==1){
                edges.insert({1,i});
            }
        }
        for(auto x: s[0]){
            read(x);
            for(auto i=1;i<=n;i++){
                if(dis[i]==1){
                    int a=x,b=i;
                    if(a>b) swap(a,b);
                    edges.insert({a,b});
                }
            }
            cout.flush();
        }
        cout << ('!') << '\n';
     for (auto itr: edges)
        cout << (itr).first << ' ' << (itr).second << '\n';
        cout.flush();
          
    }

