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

//code by thesixpathguy 

//libraries
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

//fast code execution
#pragma GCC optimize("Ofast")


//namespaces
using namespace std;
using namespace __gnu_pbds;

//template
#define lint                     long long 
#define setbits(x)              __builtin_popcountll(x)
#define zrbits(x)               __builtin_ctzll(x)
#define zlbits(x)               __builtin_clzll(x)
#define parsbits(x)             __builtin_parityll(x)
#define mem(a, b)               memset(a, (b), sizeof(a))
#define high(a,b)               (lint)ceil((long double)a/(long double)b)
#define low(a,b)                (lint)floor((long double)a/(long double)b)
#define MOD                     1000000007
#define prime_1                 911382323
#define prime_2                 972663749 //use as mod in string hashing
#define inf                     1e17 
#define neginf                  -1e17 
#define sp(x,y)                 fixed<<setprecision(x)<<y
#define testcase(t)             lint t; cin>>t; while(t--)
#define power(a,b)              (double)pow((double)a,(double)b)
#define FOR(i,n)                for(lint i=0;i<n;i++)
#define gcd(a,b)                __gcd(a,b)
#define PI                      3.1415926535
#define endl                    "\n"
#define pb                      push_back
#define ss                      second
#define ff                      first
#define XX                      real()
#define YY                      imag()
#define umap                    unordered_map           
#define ummap                   unordered_multimap
#define uset                    unordered_set
#define umset                   unordered_multiset
#define pq_greater              priority_queue <lint, vector<lint>, greater<lint>>
             
typedef unsigned long long   ull;

typedef tree<lint,null_type,less<lint>,rb_tree_tag,
tree_order_statistics_node_update> indexed_set;
//member functions :
//1. order_of_key(k) : number of elements strictly lesser than k
//2. find_by_order(k) : k-th element in the set, counting from 0
//less_equal

//debug statements start (does not debug array)
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
void debug_array(lint *arr,lint n)
{
    cerr<<"[";
    for(lint i=0;i<n;i++)
    {
        cerr<<arr[i]<<" ";
    }
    cerr<<"]";
    cerr<<endl;
}
//debug statements end
 
//fast input output and file handling         
void c_p_c()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen("C:\\Users\\pranjal bhatt\\Desktop\\code contests\\input1cc.txt", "r", stdin);
    freopen("C:\\Users\\pranjal bhatt\\Desktop\\code contests\\output1cc.txt", "w", stdout);
    #endif
}

//directions
//up,right,down,left (clockwise)
lint dx[]={0,1,0,-1};
lint dy[]={1,0,-1,0};

//useful functions
lint me(lint x, lint y, lint p)  
{  
    // (x^y)%p
    lint res=1;     
    x=x%p;           
    if(x==0)return 0;          
    while(y>0)  
    {                  
        if(y&1)  
        res=(res*x)%p;  
        y=y>>1;  
        x=(x*x)%p;  
    }  
    return res;  
}

lint  modInverse(lint a, lint m) 
{ 
    lint GCD=__gcd(a, m); 
    if (GCD!=1) 
        return -1;
    else
    { 
        return me(a, m-2, m); 
    } 
} 

//O(log m)
lint  modDivide(lint a,lint b,lint m) 
{   
    //(a/b)%m
    a=a%m; 
    lint inv=modInverse(b,m); 
    if (inv==-1) 
       return -1;
    else
       return (inv*a)%m; 
}

    /*---------------------------SOLUTION---------------------------------*/

//solve function
void solve(lint tc)
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    lint n;
    cin>>n;
    queue<lint> q;
    q.push(1);
    set<pair<lint,lint>> s;
    map<lint,lint> hash;
    hash[1]=1;
    while(s.size()!=n-1)
    {
        cout<<"? "<<q.front()<<endl;
        cout.flush();
        lint temp=q.front();
        q.pop();
        lint dist[n+1];
        for(lint i=0;i<n;i++)
        {
            cin>>dist[i+1];
        }
        lint c1=0;
        lint c2=0;
        for(lint i=0;i<n;i++)
        {
            if(hash[i+1]==0)
            {
                if(dist[i+1]==1)
                    c1++;
                if(dist[i+1]==2)
                    c2++;
            }
        }
        for(lint i=0;i<n;i++)
        {
            if(dist[i+1]==1)
            {
                s.insert({min(temp,i+1),max(temp,i+1)});
            }
        }
        if(c1>=c2)
        {
            for(lint i=0;i<n;i++)
            {
                if(hash[i+1]==0)
                {
                    if(dist[i+1]==2)
                    {
                        hash[i+1]=1;
                        q.push(i+1);
                    }
                }
            }
        }
        else
        {
            for(lint i=0;i<n;i++)
            {
                if(hash[i+1]==0)
                {
                    if(dist[i+1]==1)
                    {
                        hash[i+1]=1;
                        q.push(i+1);
                    }
                }
            }
        }
    }
    cout<<"!"<<endl;
    for(auto x:s)
        cout<<x.ff<<" "<<x.ss<<endl;



}

//main function
int main()
{
    c_p_c();
    lint flg99=0;
    if(flg99==1)
    {
        lint tc=1;
        testcase(t)
        {
            solve(tc);
            tc++;
        }
    }
    else
    {
        lint tc=1;
        solve(tc);
    }
    return 0;
            
}
