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 int ll;
typedef long long unsigned int ull;
typedef pair<ll, ll> llpair;

typedef std::numeric_limits<double> dbl;

#if defined(_USE_MATH_DEFINES) && !defined(_MATH_DEFINES_DEFINED)
#define _MATH_DEFINES_DEFINED
#define M_E 2.71828182845904523536
#define M_LOG2E 1.44269504088896340736
#define M_LOG10E 0.434294481903251827651
#define M_LN2 0.693147180559945309417
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.785398163397448309616
#define M_1_PI 0.318309886183790671538
#define M_2_PI 0.636619772367581343076
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT1_2 0.707106781186547524401
#endif

void prepareIO()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.precision(dbl::max_digits10);
}

/*
unordered_map<int,int>mp;
mp.reserve(1024);
mp.max_load_factor(0.25);
*/

struct HASH
{
    size_t operator()(const llpair &x) const
    {
        return hash<long long>()(x.first ^ (x.second) << 32);
    }
};

const ll MOD = 1e9 + 7;

const ll N = 1e5 + 5;

ll ceil(ll a, ll b)
{
    return (a / b) + (a % b != 0);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("../input.txt", "r", stdin);
    freopen("../output.txt", "w", stdout);
#endif
    prepareIO();

    ll n;
    cin >> n;

    vector<ll> set1, set2, smallSet;
    ll dis;
    set<llpair> vis;
    vector<llpair> ans;

    cout << "? " << 1 << endl;

    for (ll i = 1; i <= n; i++)
    {
        cin >> dis;

        if (dis == 0)
        {
            continue;
        }

        if (dis % 2 == 0)
        {
            set1.push_back(i);
        }
        else
        {
            set2.push_back(i);
        }

        if (dis == 1 && vis.find({1, i}) == vis.end())
        {
            ans.push_back({1, i});
            vis.insert({1, i});
            vis.insert({i, 1});
        }
    }

    if (set1.size() <= set2.size())
    {
        smallSet = set1;
    }
    else
    {
        smallSet = set2;
    }

    // cout << smallSet.size() << endl;

    for (ll u : smallSet)
    {
        cout << "? " << u << endl;

        for (ll i = 1; i <= n; i++)
        {
            cin >> dis;

            if (dis == 1 && vis.find({u, i}) == vis.end())
            {
                ans.push_back({u, i});
                vis.insert({u, i});
                vis.insert({i, u});
            }
        }
    }

    cout << "!\n";
    for (llpair p : ans)
    {
        cout << p.first << " " << p.second << "\n";
    }
    cout << endl;

    return 0;
}