#include // #include // cout, endl, cin // #include // string, to_string, stoi // #include // vector // #include // min, max, swap, sort, reverse, lower_bound, upper_bound // #include // pair, make_pair // #include // tuple, make_tuple // #include // int64_t, int*_t // #include // printf // #include // map // #include // queue, priority_queue // #include // set // #include // stack // #include // deque // #include // unordered_map // #include // unordered_set // #include // bitset // #include // #include // #include // #include // #include // #include using namespace std; #define int long long #define pb push_back #define eb emplace_back // #define F first // #define S second #define FOR(i,a,b) for(int (i)=(a);(i)<(int)(b);(i)++) #define rep(i,n) FOR(i,0,n) #define RFOR(i,a,b) for(int (i)=(a);(i)>=(int)(b);(i)--) #define rrep(i,n) RFOR(i,n,0) #define all(a) (a).begin(),(a).end() #define rall(a) (a).rbegin(),(a).rend() #define ve vector #define vi vector #define vp vector> #define vvi vector> #define UNIQUE(a) sort(all(a)), a.erase(unique(all(a)), a.end()) #define Double double // #define endl '\n' template using pq = priority_queue,greater>; using ll = long long; using ld = long double; using UnWeightedGraph = vector>; ll INF = LLONG_MAX / 4 - 100; int IINF = INT_MAX / 4; ll mod = 1e9 + 7; int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1}; vector prime; long double pi = 3.141592653589793238; class fact { public: long long fmod = 1e9+7; vector fac, finv, inv; fact (int n, long long Mod = 1e9+7) { fmod = Mod; fac = vector(n + 1, 0); finv = vector(n + 1, 0); inv = vector(n + 1, 0); fac[0] = fac[1] = 1; finv[0] = finv[1] = 1; inv[1] = 1; for (int i = 2; i < n + 1; i++) { fac[i] = fac[i-1] * i % fmod; inv[i] = mod - inv[mod%i] * (mod/i) % mod; finv[i] = finv[i-1] * inv[i] % mod; } } ll nCr(ll n, ll r) {if(n < r) return 0; return fac[n] * finv[r] % fmod * finv[n-r] % fmod;} ll POW(ll a, ll b) {ll c = 1; while (b > 0) {if (b & 1) {c = a * c%fmod;}a = a * a%fmod; b >>= 1;}return c;} inline int operator [] (int i) {return fac[i];} ll DeBuG(ll n, ll r); }; void DEBUG(vector a) {for(int i=0;i 0) {if (b & 1) {c = a * c%mod;}a = a * a%mod; b >>= 1;}return c;} ld POW(ld a, ll b) {ld c = 1; while (b > 0) {if (b & 1) {c = a * c;}a = a * a; b >>= 1;}return c;} void PRI(ll n) {bool a[n + 1]; for (int i = 0; i < n + 1; i++) {a[i] = 1;}for (int i = 2; i < n + 1; i++) {if (a[i]) {prime.pb(i); ll b = i; while (b <= n) {a[b] = 0; b += i;}}}} template T chmin(T& a, T b) {if(a>b)a=b;return a;} template T chmax(T& a, T b) {if(a>19))^(t^(t>>8)) ); } uint64_t xor64(void) { static uint64_t x = 88172645463325252ULL; x = x ^ (x << 7); return x = x ^ (x >> 9); } long long extGCD(long long a, long long b, long long &x, long long &y) { if (b == 0) { x = 1; y = 0; return a; } long long d = extGCD(b, a%b, y, x); y -= a/b * x; return d; } int invs(vector &vec) { vector> val(vec.size()); vector bit(vec.size()+1); for (int i = 0; i < vec.size(); i++) { val[i] = {vec[i], i+1}; } sort(val.rbegin(), val.rend()); int ret = 0; for (int i = 0; i < val.size(); i++) { for (int j = val[i].second; j > 0; j -= j & -j) ret += bit[j]; for (int j = val[i].second; j <= vec.size(); j += j & -j) bit[j]++; } return ret; } void AND(int i, int j) { cout << "AND " << i << " " << j << endl; } void OR(int i, int j) { cout << "OR " << i << " " << j << endl; } void XOR(int i, int j) { cout << "XOR " << i << " " << j << endl; } int co(int n, int i, int j) { return (n*i+j); } pair req(int i, int j) { cout << "? " << i << " " << j << endl; int t1, t2; cin >> t1 >> t2; return {t1, t2}; } void solve() { int n; cin >> n; map cnt; map, vector> idx; vector> res(n*n-n); vector ans(n*n-n, -1); // cout << 1 << endl; rep (_, n*n-n-1) { cout << "? " << _+2 << " " << 1 << endl; cin >> res[_+1].first >> res[_+1].second; cnt[res[_+1].first]++, cnt[res[_+1].second]++; idx[{res[_+1]}].pb(_+1); } map posi; // cout << 1 << endl; for (auto e : cnt) if (e.first > 0) posi[e.second]++; if (posi.size() == 0) { int minp = idx[{-n+1, -n+2}][0]; // cout << minp << endl; ans[0] = n*n-1, ans[minp] = n; rep (i, n*n-n) { if (ans[i] != -1) continue; // cout << i << endl; if (res[i].first == res[i].second) ans[i] = n * (n-1+res[i].first) + n-1+res[i].first; else { set c1{co(n, n-1+res[i].first, n-1+res[i].second), co(n, n-1+res[i].second, n-1+res[i].first)}; pair tmp = req(i+1, minp+1); set c2{co(n, 1+tmp.first, tmp.second), co(n, 1+tmp.second, tmp.first)}; for (auto e : c1) { for (auto e2 : c2) { // cout << e << " " << e2 << endl; if (e == e2) ans[i] = e; } } c1.erase(ans[i]); for (auto e : idx[res[i]]) if (ans[e] == -1) ans[e] = *c1.begin(); } } } else if (posi.size() == 1) { ans[0] = co(n, n-1-posi.begin()->second, n-1-posi.begin()->second); vector dgs({n-1-posi.begin()->second, n-1-posi.begin()->second}); int minp = idx[{-(n-1-posi.begin()->second), -(n-1-posi.begin()->second)+1}][0]; ans[minp] = n; rep (i, n*n-n) { if (ans[i] != -1) continue; if (res[i].first == res[i].second) ans[i] = co (n, dgs[0]+res[i].first, dgs[1]+res[i].first); else { set c1{co(n, dgs[0]+res[i].first, dgs[1]+res[i].second), co(n, dgs[0]+res[i].second, dgs[1]+res[i].first)}; pair tmp = req(i+1, minp+1); set c2{co(n, 1+tmp.first, tmp.second), co(n, 1+tmp.second, tmp.first)}; for (auto e : c1) { for (auto e2 : c2) { // cout << e << " " << e2 << endl; if (e == e2) ans[i] = e; } } c1.erase(ans[i]); for (auto e : idx[res[i]]) if (ans[e] == -1) ans[e] = *c1.begin(); } } } else if (posi.begin()->first == n) { vector dgs({n-1-posi.rbegin()->second-posi.begin()->second, n-1-posi.rbegin()->second}); ans[0] = co(n, dgs[0], dgs[1]); int minp = idx[{-dgs[0]+1, -dgs[1]}][0]; ans[minp] = n; rep (i, n*n-n) { if (ans[i] != -1) continue; if (res[i].first == res[i].second) ans[i] = co (n, dgs[0]+res[i].first, dgs[1]+res[i].first); else { set c1{co(n, dgs[0]+res[i].first, dgs[1]+res[i].second), co(n, dgs[0]+res[i].second, dgs[1]+res[i].first)}; pair tmp = req(i+1, minp+1); set c2{co(n, 1+tmp.first, tmp.second), co(n, 1+tmp.second, tmp.first)}; for (auto e : c1) { for (auto e2 : c2) { // cout << e << " " << e2 << endl; if (e == e2) ans[i] = e; } } c1.erase(ans[i]); for (auto e : idx[res[i]]) if (ans[e] == -1) ans[e] = *c1.begin(); } } } else { vector dgs({n-1-posi.rbegin()->second, n-1-posi.rbegin()->second-posi.begin()->second}); ans[0] = co(n, dgs[0], dgs[1]); int maxp = idx[{n-1-dgs[0], n-1-dgs[1]}][0]; ans[maxp] = n*n-1; rep (i, n*n-n) { if (ans[i] != -1) continue; if (res[i].first == res[i].second) ans[i] = co (n, dgs[0]+res[i].first, dgs[1]+res[i].first); else { set c1{co(n, dgs[0]+res[i].first, dgs[1]+res[i].second), co(n, dgs[0]+res[i].second, dgs[1]+res[i].first)}; pair tmp = req(maxp+1, i+1); set c2{co(n, n-1-tmp.first, n-1-tmp.second), co(n, n-1-tmp.second, n-1-tmp.first)}; for (auto e : c1) { for (auto e2 : c2) { // cout << e << " " << e2 << endl; if (e == e2) ans[i] = e; } } c1.erase(ans[i]); for (auto e : idx[res[i]]) if (ans[e] == -1) ans[e] = *c1.begin(); } } } DEBUG(ans); } signed main() { cin.tie(0); ios::sync_with_stdio(false); solve(); }