#include<bits/stdc++.h>
using namespace std;
int N,id[3000],vis[3000],ans[3000],zero;
vector<int>v[3000];
int get(int x,int y){
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int ret;
	scanf("%d",&ret);
	return ret;
}
int main(){
	scanf("%d",&N);
	srand(time(0));
	for (int i=1; i<=N; i++) id[i] = i;
	random_shuffle(id+1, id+N+1);
	int x = id[1], y = id[2], z = id[3], now = 4;
	int t1 = get(x,y), t2 = get(y,z);
	while (now <= N){
//		int t1 = get(x,y), t2 = get(y,z);
		for (int j=11; j>=0; j--){
			if (!(t1 & (1<<j))){
				v[j].push_back(x);
				v[j].push_back(y);
			}
		}
		for (int j=11; j>=0; j--){
			if(!(t2 & (1<<j))){
				v[j].push_back(y);
				v[j].push_back(z);
			}
		}
		if (t1 > t2){
			x = id[now++];
			t1 = get(x,y);
		} else if (t1 == t2){
			y = id[now++];
			t1 = get(x,y), t2 = get(y,z);
		} else {
			z = id[now++];
			t2 = get(y,z);
		}
	}
	int a,b;
	if (t1 > t2){
		a = y, b = z;
	} else if (t1 == t2){
		a = x, b = z;
	} else a = x, b = y;

	int p = get(a,b);
	if (N > 600){
		for (int i=11; i>=0; i--){
			if (p & (1<<i)) {
				if (v[i].size()>0 && v[i][0]!=a && v[i][0]!=b){
					int p1 = get(a,v[i][0]);
					int p2 = get(b,v[i][0]);
					if (p1 & (1<<i)) zero = b;
					if (p2 & (1<<i)) zero = a;
					break;
				} else {
					int f = rand()%N+1, g = rand()%N+1;
					int q;
					while (1){
						while (f == a || f == b) f = rand()%N+1;
						while (g == a || g == b || f == g) g = rand()%N+1;
						int p1 = get(f,g);
						if (p1 & (1<<i)) continue;
						q = f;
					}
					int p1 = get(a,q),p2 = get(b,q);
					if (p1 & (1<<i)) zero = b;
					else zero = a;
					break;
					}
				}
		}
	} else {
		vis[a] = vis[b] = 1;
		while (1){
			int p = rand()%N + 1;
			while (vis[p]) p = rand()%N + 1;
			vis[p] = 1;
			int t1 = get(a,p), t2 = get(b,p);
			if (t1 == t2) continue;
			if (t1 < t2) zero = a;
			else zero = b;
			break;
		}
	}
	for (int i=1; i<=N; i++){
		if (i == zero){
			ans[i] = 0;
			continue;
		}
		ans[i] = get(i,zero);
	}
	printf("! ");
	for (int i=1; i<=N; i++) printf("%d ",ans[i]);
	fflush(stdout);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int N,id[3000],vis[3000],ans[3000];
int get(int x,int y){
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int ret;
	scanf("%d",&ret);
	return ret;
}
int main(){
	scanf("%d",&N);
	srand(time(0));
	for (int i=1; i<=N; i++) id[i] = i;
	random_shuffle(id+1, id+N+1);
	int x = id[1], y = id[2], z = id[3], now = 4;
	while (now <= N){
		int t1 = get(x,y), t2 = get(y,z);
		if (t1 > t2){
			x = id[now++];
		} else if (t1 == t2){
			y = id[now++];
		} else z = id[now++];
	}
	int t1 = get(x,y), t2 = get(y,z);
	int a,b;
	if (t1 > t2){
		a = y, b = z;
	} else if (t1 == t2){
		a = x, b = z;
	} else a = x, b = y;
	vis[a] = vis[b] = 1;
	int zero;
	while (1){
		int p = rand()%N + 1;
		while (vis[p]) p = rand()%N + 1;
		vis[p] = 1;
		int t1 = get(a,p), t2 = get(b,p);
		if (t1 == t2) continue;
		if (t1 < t2) zero = a;
		else zero = b;
		break;
	}
	for (int i=1; i<=N; i++){
		if (i == zero){
			ans[i] = 0;
			continue;
		}
		ans[i] = get(i,zero);
	}
	printf("! ");
	for (int i=1; i<=N; i++) printf("%d ",ans[i]);
	fflush(stdout);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int N,id[3000],vis[3000],ans[3000],zero;
vector<int>v[3000];
int get(int x,int y){
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int ret;
	scanf("%d",&ret);
	return ret;
}
int main(){
	scanf("%d",&N);
	srand(time(0));
	for (int i=1; i<=N; i++) id[i] = i;
	random_shuffle(id+1, id+N+1);
	int x = id[1], y = id[2], z = id[3], now = 4;
	while (now <= N){
		int t1 = get(x,y), t2 = get(y,z);
		for (int j=11; j>=0; j--){
			if (!(t1 & (1<<j))){
				v[j].push_back(x);
				v[j].push_back(y);
			}
		}
		for (int j=11; j>=0; j--){
			if(!(t2 & (1<<j))){
				v[j].push_back(y);
				v[j].push_back(z);
			}
		}
		if (t1 > t2){
			x = id[now++];
		} else if (t1 == t2){
			y = id[now++];
		} else z = id[now++];
	}
	int t1 = get(x,y), t2 = get(y,z);
	int a,b;
	if (t1 > t2){
		a = y, b = z;
	} else if (t1 == t2){
		a = x, b = z;
	} else a = x, b = y;

	int p = get(a,b);
	if (N == 3){
		int op = 0;
		for (int i=1; i<=3; i++){
			if (i==a && i==b) continue;
			op = i;
		}
		int p1 = get(a,op);
		int p2 = get(b,op);
		for (int i=11; i>=0; i--)
			if ((p1 & (1<<i)) && (p & (1<<i)) ) zero = b; else zero = a;
	} else{
//	if (N > 600){
		for (int i=11; i>=0; i--){
			if (p & (1<<i)) {
				if (v[i].size()>0 && v[i][0]!=a && v[i][0]!=b){
					int p1 = get(a,v[i][0]);
					int p2 = get(b,v[i][0]);
					if (p1 & (1<<i)) zero = b;
					if (p2 & (1<<i)) zero = a;
					break;
				} else {
					int f = rand()%N+1, g = rand()%N+1;
					int q;
					while (1){
						while (f == a || f == b) f = rand()%N+1;
						while (g == a || g == b || f == g) g = rand()%N+1;
						int p1 = get(f,g);
						if (p1 & (1<<i)) continue;
						q = f;
					}
					int p1 = get(a,q),p2 = get(b,q);
					if (p1 & (1<<i)) zero = b;
					else zero = a;
					break;
				}
			}
		}
	}
//	} else {
//		vis[a] = vis[b] = 1;
//		while (1){
//			int p = rand()%N + 1;
//			while (vis[p]) p = rand()%N + 1;
//			vis[p] = 1;
//			int t1 = get(a,p), t2 = get(b,p);
//			if (t1 == t2) continue;
//			if (t1 < t2) zero = a;
//			else zero = b;
//			break;
//		}
//	}
	for (int i=1; i<=N; i++){
		if (i == zero){
			ans[i] = 0;
			continue;
		}
		ans[i] = get(i,zero);
	}
	printf("! ");
	for (int i=1; i<=N; i++) printf("%d ",ans[i]);
	fflush(stdout);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int N,id[3000],vis[3000],ans[3000],zero;
vector<int>v[3000];
int get(int x,int y){
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int ret;
	scanf("%d",&ret);
	return ret;
}
int main(){
	scanf("%d",&N);
	srand(time(0));
	for (int i=1; i<=N; i++) id[i] = i;
	random_shuffle(id+1, id+N+1);
	int x = id[1], y = id[2], z = id[3], now = 4;
	while (now <= N){
		int t1 = get(x,y), t2 = get(y,z);
		for (int j=11; j>=0; j--){
			if (!(t1 & (1<<j))){
				v[j].push_back(x);
				v[j].push_back(y);
			}
		}
		for (int j=11; j>=0; j--){
			if(!(t2 & (1<<j))){
				v[j].push_back(y);
				v[j].push_back(z);
			}
		}
		if (t1 > t2){
			x = id[now++];
		} else if (t1 == t2){
			y = id[now++];
		} else z = id[now++];
	}
	int t1 = get(x,y), t2 = get(y,z);
	int a,b;
	if (t1 > t2){
		a = y, b = z;
	} else if (t1 == t2){
		a = x, b = z;
	} else a = x, b = y;

	int p = get(a,b);
	if (N > 600){
		for (int i=11; i>=0; i--){
			if (p & (1<<i)) {
				int p1 = get(a,v[i][0]);
				int p2 = get(b,v[i][0]);
				if (p1 & (1<<i)) zero = b;
				if (p2 & (1<<i)) zero = a;
				break;
			}
		}
	} else {
		vis[a] = vis[b] = 1;
		while (1){
			int p = rand()%N + 1;
			while (vis[p]) p = rand()%N + 1;
			vis[p] = 1;
			int t1 = get(a,p), t2 = get(b,p);
			if (t1 == t2) continue;
			if (t1 < t2) zero = a;
			else zero = b;
			break;
		}
	}
	for (int i=1; i<=N; i++){
		if (i == zero){
			ans[i] = 0;
			continue;
		}
		ans[i] = get(i,zero);
	}
	printf("! ");
	for (int i=1; i<=N; i++) printf("%d ",ans[i]);
	fflush(stdout);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int N,id[3000],vis[3000],ans[3000],zero;
vector<int>v[3000];
int get(int x,int y){
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int ret;
	scanf("%d",&ret);
	return ret;
}
int main(){
	scanf("%d",&N);
	srand(time(0));
	for (int i=1; i<=N; i++) id[i] = i;
	random_shuffle(id+1, id+N+1);
	int x = id[1], y = id[2], z = id[3], now = 4;
	int t1 = get(x,y), t2 = get(y,z);
	while (now <= N){
//		int t1 = get(x,y), t2 = get(y,z);
		for (int j=11; j>=0; j--){
			if (!(t1 & (1<<j))){
				v[j].push_back(x);
				v[j].push_back(y);
			}
		}
		for (int j=11; j>=0; j--){
			if(!(t2 & (1<<j))){
				v[j].push_back(y);
				v[j].push_back(z);
			}
		}
		if (t1 > t2){
			x = id[now++];
			t1 = get(x,y);
		} else if (t1 == t2){
			y = id[now++];
			t1 = get(x,y), t2 = get(y,z);
		} else {
			z = id[now++];
			t2 = get(y,z);
		}
	}
	int a,b;
	if (t1 > t2){
		a = y, b = z;
	} else if (t1 == t2){
		a = x, b = z;
	} else a = x, b = y;

	int p = get(a,b);
	if (N == 3){
		int op = 0;
		for (int i=1; i<=3; i++){
			if (i==a || i==b) continue;
			op = i;
		}
		int p1 = get(a,op);
		int p2 = get(b,op);
		for (int i=11; i>=0; i--)
			if ((p1 & (1<<i)) && (p & (1<<i)) ) zero = b; else zero = a;
	} else {
		for (int i=11; i>=0; i--){
			if (p & (1<<i)) {
				if (v[i].size()>0 && v[i][0]!=a && v[i][0]!=b){
					int p1 = get(a,v[i][0]);
					int p2 = get(b,v[i][0]);
					if (p1 & (1<<i)) zero = b;
					if (p2 & (1<<i)) zero = a;
					break;
				} else {
					int f = rand()%N+1, g = rand()%N+1;
					int q;
					while (1){
						while (f == a || f == b) f = rand()%N+1;
						while (g == a || g == b || f == g) g = rand()%N+1;
						int p1 = get(f,g);
						if (p1 & (1<<i)) continue;
						q = f;
					}
					int p1 = get(a,q),p2 = get(b,q);
					if (p1 & (1<<i)) zero = b;
					else zero = a;
					break;
				}
			}
		}
	}
	for (int i=1; i<=N; i++){
		if (i == zero){
			ans[i] = 0;
			continue;
		}
		ans[i] = get(i,zero);
	}
	printf("! ");
	for (int i=1; i<=N; i++) printf("%d ",ans[i]);
	fflush(stdout);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int N,id[3000],vis[3000],ans[3000],zero;
vector<int>v[3000];
int get(int x,int y){
	printf("? %d %d\n",x,y);
	fflush(stdout);
	int ret;
	scanf("%d",&ret);
	return ret;
}
int main(){
	scanf("%d",&N);
	srand(time(0));
	for (int i=1; i<=N; i++) id[i] = i;
	random_shuffle(id+1, id+N+1);
	int x = id[1], y = id[2], z = id[3], now = 4;
	while (now <= N){
		int t1 = get(x,y), t2 = get(y,z);
		for (int j=11; j>=0; j--){
			if (!(t1 & (1<<j))){
				v[j].push_back(x);
				v[j].push_back(y);
			}
		}
		for (int j=11; j>=0; j--){
			if(!(t2 & (1<<j))){
				v[j].push_back(y);
				v[j].push_back(z);
			}
		}
		if (t1 > t2){
			x = id[now++];
		} else if (t1 == t2){
			y = id[now++];
		} else z = id[now++];
	}
	int t1 = get(x,y), t2 = get(y,z);
	int a,b;
	if (t1 > t2){
		a = y, b = z;
	} else if (t1 == t2){
		a = x, b = z;
	} else a = x, b = y;

	int p = get(a,b);
	if (N == 3){
		int op = 0;
		for (int i=1; i<=3; i++){
			if (i==a || i==b) continue;
			op = i;
		}
		int p1 = get(a,op);
		int p2 = get(b,op);
		for (int i=11; i>=0; i--)
			if ((p1 & (1<<i)) && (p & (1<<i)) ) zero = b; else zero = a;
	} else{
//	if (N > 600){
		for (int i=11; i>=0; i--){
			if (p & (1<<i)) {
				if (v[i].size()>0 && v[i][0]!=a && v[i][0]!=b){
					int p1 = get(a,v[i][0]);
					int p2 = get(b,v[i][0]);
					if (p1 & (1<<i)) zero = b;
					if (p2 & (1<<i)) zero = a;
					break;
				} else {
					int f = rand()%N+1, g = rand()%N+1;
					int q;
					while (1){
						while (f == a || f == b) f = rand()%N+1;
						while (g == a || g == b || f == g) g = rand()%N+1;
						int p1 = get(f,g);
						if (p1 & (1<<i)) continue;
						q = f;
					}
					int p1 = get(a,q),p2 = get(b,q);
					if (p1 & (1<<i)) zero = b;
					else zero = a;
					break;
				}
			}
		}
	}
//	} else {
//		vis[a] = vis[b] = 1;
//		while (1){
//			int p = rand()%N + 1;
//			while (vis[p]) p = rand()%N + 1;
//			vis[p] = 1;
//			int t1 = get(a,p), t2 = get(b,p);
//			if (t1 == t2) continue;
//			if (t1 < t2) zero = a;
//			else zero = b;
//			break;
//		}
//	}
//	printf("zero = %d\n",zero);
	for (int i=1; i<=N; i++){
		if (i == zero){
			ans[i] = 0;
			continue;
		}
		ans[i] = get(i,zero);
	}
	printf("! ");
	for (int i=1; i<=N; i++) printf("%d ",ans[i]);
	fflush(stdout);
	return 0;
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    int t = pow(2, m) - 1;
    if ((int)pow(2, m - 1) == n) t = pow(2, m - 1) - 1;
    int pro = 1;
    mfor(i, 1, m)
    {
        d[i] = t - pro;
        pro *= 2;
        //debug(d[i]);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (i == d[j]) continue;
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            cout << "? " << i << " " << d[j] << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = 0, f[d[j]][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[i][cnt] &= res % 2;
                f[d[j]][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            //mfor(k, 1, m) debug(f[i][k]);
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    if ((int)pow(2, m - 1) == n) m--;
    int t = pow(2, m) - 1;
    int pro = 1;
    mfor(i, 1, m)
    {
        d[i] = t - pro;
        pro *= 2;
        //debug(d[i]);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (i == d[j]) continue;
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            cout << "? " << i << " " << d[j] << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = 0, f[d[j]][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[i][cnt] &= res % 2;
                f[d[j]][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            //mfor(k, 1, m) debug(f[i][k]);
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, min(i + 500, n))
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, getnum(n))
        {
            f[i][j] = 1;
        }
    }
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, n)
        {
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            if (res == -1) continue;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, n)
        {
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            if (res == -1)
            {
                i=n;
                break;
            }
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    int t = pow(2, m) - 1;
    int pro = 1;
    mfor(i, 1, m)
    {
        d[i] = t - pro;
        pro *= 2;
        //debug(d[i]);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (i == d[j]) continue;
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            cout << "? " << i << " " << d[j] << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    int t = pow(2, m) - 1;
    int pro = 1;
    mfor(i, 1, m)
    {
        d[i] = t - pro;
        pro *= 2;
        //debug(d[i]);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (i == d[j]) continue;
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            cout << "? " << i << " " << d[j] << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = 0, f[d[j]][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[i][cnt] &= res % 2;
                f[d[j]][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            //mfor(k, 1, m) debug(f[i][k]);
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    int t = pow(2, m) - 1;
    int pro = 1;
    mfor(i, 1, m)
    {
        d[i] = t - pro;
        pro *= 2;
        //debug(d[i]);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            cout << "? " << i << " " << d[j] << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

int n, m;
set<int>d;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int query(int i, int j)
{
    cout << "? " << i << " " << j << endl;
    int res;
    cin >> res;
    return res;
}

map<int, bool>ind;

int cal(int x)
{
    int res = pow(2, m) - 1;
    for (auto it : d)
    {
        if (x == it) continue;
        res &= query(x, it);
    }
    return res;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    if ((int)pow(2, m - 1) == n) m--;
    int tot = 0;
    srand(time(0));
    while (ind.size() != m)
    {
        int a = rand() % n + 1;
        int b = rand() % n + 1;
        while (b == a) b = rand() % n + 1;
        int res = query(a, b);
        int cnt = 1;
        mfor(i, getnum(res) + 1, m) ind[i] = true, d.insert(a);
        while (res)
        {
            if (res % 2 == 0 && !ind[cnt]) ind[cnt] = true, d.insert(a);
            res /= 2;
            cnt++;
        }
        //debug(ind.size());
    }
    int pos = *d.begin();
    int t = cal(pos);
    mfor(i, 1, n)
    {
        if (pos == i) continue;
        if (query(pos, i) == t)
        {
            pos = i;
            t = cal(pos);
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        if (i == pos) cout << t << " ";
        else cout << query(pos, i) << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, min(i + 100, n))
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, min(i + 1000, n))
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro < d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    int t = pow(2, m) - 1;
    int pro = 1;
    mfor(i, 1, m)
    {
        d[i] = t - pro;
        pro *= 2;
        //debug(d[i]);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (i == d[j]) continue;
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            cout << "? " << i << " " << d[j] << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = 0, f[d[j]][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[i][cnt] &= res % 2;
                f[d[j]][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            //mfor(k, 1, m) debug(f[i][k]);
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;
//
#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

int n, m;
set<int>d;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int query(int i, int j)
{
    cout << "? " << i << " " << j << endl;
    int res;
    cin >> res;
    return res;
}

map<int, int>ind;

int cal(int x)
{
    int res = pow(2, m) - 1;
    //debug(res);
    for (auto it : d)
    {
        if (x == it)
        {
            for (auto it : ind)
            {
                int cnt = it.first - 1;
                if (it.second == x && (res & (1 << cnt))) res ^= (1 << cnt);
            }
        }
        else res &= query(x, it);
        //debug(res);
    }
    return res;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    if ((int)pow(2, m - 1) == n) m--;
    int tot = 0;
    srand(time(0));
    while (ind.size() != m)
    {
        int a = rand() % n + 1;
        int b = rand() % n + 1;
        while (b == a) b = rand() % n + 1;
        int res = query(a, b);
        int cnt = 1;
        mfor(i, getnum(res) + 1, m) ind[i] = a, d.insert(a);
        while (res)
        {
            if (res % 2 == 0 && !ind[cnt]) ind[cnt] = a, d.insert(a);
            res /= 2;
            cnt++;
        }
        //debug(ind.size());
    }
    int pos = *d.begin();
    int t = cal(pos);
    mfor(i, 1, n)
    {
        if (pos == i) continue;
        if (query(pos, i) == t)
        {
            pos = i;
            t = cal(pos);
        }
    }
    vector<int>ans;
    mfor(i, 1, n)
    {
        if (i == pos) ans.emplace_back(t);
        else ans.emplace_back(query(i, pos));
    }
    cout << "! ";
    for (auto it : ans)
    {
        cout << it << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

int n, m;
set<int>d;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int query(int i, int j)
{
    cout << "? " << i << " " << j << endl;
    int res;
    cin >> res;
    return res;
}

map<int, int>ind;

int cal(int x)
{
    int res = pow(2, m) - 1;
    //debug(res);
    for (auto it : d)
    {
        if (x == it)
        {
            for (auto it : ind)
            {
                int cnt = it.first - 1;
                if (it.second == x && (res & (1 << cnt))) res ^= (1 << cnt);
            }
        }
        else res &= query(x, it);
        //debug(res);
    }
    return res;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    if ((int)pow(2, m - 1) == n) m--;
    int tot = 0;
    srand(time(0));
    while (ind.size() != m)
    {
        int a = rand() % n + 1;
        int b = rand() % n + 1;
        while (b == a) b = rand() % n + 1;
        int res = query(a, b);
        int cnt = 1;
        mfor(i, getnum(res) + 1, m) ind[i] = a, d.insert(a);
        while (res)
        {
            if (res % 2 == 0 && !ind[cnt]) ind[cnt] = a, d.insert(a);
            res /= 2;
            cnt++;
        }
        //debug(ind.size());
    }
    int pos = *d.begin();
    int t = cal(pos);
    mfor(i, 1, n)
    {
        if (pos == i) continue;
        if (query(pos, i) == t)
        {
            pos = i;
            t = cal(pos);
        }
    }
    vector<int>ans;
    mfor(i, 1, n)
    {
        if (i == pos) ans.emplace_back(t);
        else ans.emplace_back(query(i, pos));
    }
    cout << "! ";
    for (auto it : ans)
    {
        cout << it << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, min(i + 3, n))
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n - 1)
    {
        mfor(j, i + 1, n)
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }
            int res;
            cout << "? " << i << " " << j << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<list>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<limits>
#include<cctype>
#pragma warning(disable:4996)
using namespace std;

#define debug(i) cout<<"<debug> "<<#i<<" "<<i<<" <\debug>"<<endl
#define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
#define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
#define lll __int128
#define Re register
#define mem(a,b) memset(a,(b),sizeof(a))
#define Design ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef pair<int, int> intpair;
typedef pair<long long int, long long int> llpair;
typedef long long int ll;
const int INF = 0x3f3f3f3f;
const long long int INFLL = 0x3f3f3f3f3f3f3f3f;

bool f[(1 << 11) + 10][20];
int n, m;
int d[20];

int getnum(int d)
{
    int pro = 1;
    int cnt = 0;
    while (pro <= d)
    {
        pro *= 2;
        cnt++;
    }
    return cnt;
}

int lowbit(int x)
{
    return x & -x;
}

int main()
{
    Design;
    cin >> n;
    m = getnum(n);
    int tn = n;
    mfor(i, 1, m)
    {
        d[i] = tn -= lowbit(tn);
    }
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            f[i][j] = 1;
        }
    }
    int tot = 0;
    mfor(i, 1, n)
    {
        mfor(j, 1, m)
        {
            if (tot == 4269)
            {
                i = n;
                break;
            }

            int res;
            //debug(d[j]);
            j = d[j];
            cout << "? " << i << " " << j << endl;
            cin >> res;
            int cnt = 1;
            mfor(k, getnum(res) + 1, m) f[i][k] = f[j][k] = 0;
            while (res)
            {
                //debug(j);
                //debug(f[i][cnt]);
                f[j][cnt] &= res % 2;
                f[i][cnt] &= res % 2;
                cnt++;
                res /= 2;
            }
            tot++;
        }
    }
    cout << "! ";
    mfor(i, 1, n)
    {
        int ans = 0;
        int pro = 1;
        mfor(j, 1, m)
        {
            //debug(f[i][j]);
            ans += pro * f[i][j];
            pro *= 2;
        }
        cout << ans << " ";
    }
    cout.flush();
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 22:20:48
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2048;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32], id[N];
map<pii, int> mp;

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(int x, int y) {
  if (x == y) exit(0);
  if (x > y) swap(x, y);
  if (mp.count({x, y})) return mp[{x, y}];
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return mp[{x, y}] = res;
}

int magic(const int &x) {
  int res = (1<<k)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  // rand order
  for (int i = 1; i <= n; ++i) id[i] = i;
  for (int i = 2, j; i <= n; ++i) {
    j = rnd()%(i-1)+1;
    swap(id[i], id[j]);
  }
  int x = id[1], y = id[2], v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, id[i]);
    add(y, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = id[i];
      v = t;
    } else {
      y = id[i];
      v = query(x, y);
      add(y, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 10:41:59
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2048;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32];

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(const int &x, const int &y) {
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return res;
}

int magic(const int &x) {
  int res = (1<<11)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  int x = 1, y = 2, v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, i);
    add(i, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = i;
    } else {
      y = i;
      v = query(x, y);
      add(i, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 19:52:58
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2048;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32];
map<pii, int> mp;

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(int x, int y) {
  if (x == y) exit(0);
  if (x > y) swap(x, y);
  if (mp.count({x, y})) return mp[{x, y}];
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return mp[{x, y}] = res;
}

int magic(const int &x) {
  int res = (1<<k)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  int x = 1, y = 2, v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, i);
    add(i, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = i;
      v = t;
    } else {
      y = i;
      v = query(x, y);
      add(i, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 22:22:45
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2100;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32], id[N];
map<pii, int> mp;

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(int x, int y) {
  if (x == y) exit(0);
  if (x > y) swap(x, y);
  if (mp.count({x, y})) return mp[{x, y}];
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return mp[{x, y}] = res;
}

int magic(const int &x) {
  int res = (1<<k)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  // rand order
  for (int i = 1; i <= n; ++i) id[i] = i;
  for (int i = 2, j; i <= n; ++i) {
    j = rnd()%(i-1)+1;
    swap(id[i], id[j]);
  }
  int x = id[1], y = id[2], v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, id[i]);
    add(y, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = id[i];
      v = t;
    } else {
      y = id[i];
      v = query(x, y);
      add(y, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 19:52:58
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2048;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32];
map<pii, int> mp;

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(int x, int y) {
  if (x == y) exit(0);
  if (x > y) swap(x, y);
  if (mp.count({x, y})) return mp[{x, y}];
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return mp[{x, y}] = res;
}

int magic(const int &x) {
  int res = (1<<k)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  int x = 1, y = 2, v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, i);
    add(i, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = i;
      v = t;
    } else {
      y = i;
      v = query(x, y);
      add(i, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 19:52:58
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2048;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32];
map<pii, int> mp;

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(int x, int y) {
  if (x == y) exit(0);
  if (x > y) swap(x, y);
  if (mp.count({x, y})) return mp[{x, y}];
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return mp[{x, y}] = res;
}

int magic(const int &x) {
  int res = (1<<k)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  int x = 1, y = 2, v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, i);
    add(i, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = i;
      v = t;
    } else {
      y = i;
      v = query(x, y);
      add(i, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


/*
 * @Author: Kaizyn
 * @Date: 2020-06-13 23:01:47
 * @LastEditTime: 2020-06-20 19:40:16
 */
#include <bits/stdc++.h>

// #define DEBUG

using namespace std;

const double eps = 1e-7;
const double PI = acos(-1);
typedef pair<int, int> pii;
const int MOD = 998244353;
const int INF = 0x3f3f3f3f;
const int N = 2048;
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

int n, m, k;
int a[N], b[32];
map<pii, int> mp;

void add(const int &x, const int &v) {
  for (int i = 0; i < k; ++i) {
    if ((v>>i)&1) continue;
    if (b[i]) continue;
    b[i] = x;
    ++m;
  }
}

int query(int x, int y) {
  if (x > y) swap(x, y);
  if (mp.count({x, y})) return mp[{x, y}];
  int res;
  cout << "? " << x << " " << y << endl;
  cin >> res;
  if (res == -1) exit(0);
  return mp[{x, y}] = res;
}

int magic(const int &x) {
  int res = (1<<11)-1;
  for (int i = 0; i < k; ++i) {
    if (b[i] == x) {
      res &= (1<<11)-1-(1<<i);
    } else {
      res &= query(x, b[i]);
    }
  }
  return res;
}

void answer() {
  cout << "!";
  for (int i = 1; i <= n; ++i) {
    cout << " " << a[i];
  }
  cout << endl;
}

inline void solve() {
  cin >> n;
  while (1<<k < n) ++k;
  int x = 1, y = 2, v = query(x, y);
  add(x, v);
  for (int i = 3, t; i <= n; ++i) {
    t = query(y, i);
    add(i, t);
    if (v < t) {
      continue;
    } else if (v > t) {
      x = i;
      v = t;
    } else {
      y = i;
      v = query(x, y);
      add(i, v);
    }
  }
  while (m < k) {
    int t1 = rnd()%n+1, t2 = rnd()%(n-1)+1;
    t2 = (t1-1+t2)%n+1;
    add(t1, query(t1, t2));
  }
  if (magic(x)) swap(x, y);
  for (int i = 1; i <= n; ++i) {
    a[i] = (i == x ? 0 : query(i, x));
  }
  answer();
}

signed main() {
  ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
  int T = 1;
  // cin >> T;
  for (int t = 1; t <= T; ++t) {
    solve();
  }
  return 0;
}


#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdio>
#include <cctype>
#include <random>
using namespace std;
mt19937 rnd(20041028);
int pos[2050],ans[2050];
inline int read()
{
	int x=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return x;
}
inline int ask(int x,int y)
{
	static int tot;
	assert(++tot<=4269);
	cout<<"? "<<x<<' '<<y<<endl;
	return read();
}
int main()
{
	int n=read();
	for(int i=1;i<=n;i++)
		pos[i]=i;
	random_shuffle(pos+1,pos+n+1);
	int x=pos[1],y=pos[2],val=ask(x,y);
	for(int i=3;i<=n;i++)
	{
		int tmp=ask(y,pos[i]);
		if(val>tmp) x=pos[i],val=tmp;
		else if(val==tmp) y=pos[i],val=ask(x,y);
	}
	int tmp0=-1;
	while(tmp0==-1)
	{
		int cur=(rnd()%n+n)%n+1;
		if(cur==x||cur==y) continue;
		int val1=ask(x,cur),val2=ask(y,cur);
		if(val1!=val2) tmp0=(val1<val2?x:y);
	}
	for(int i=1;i<=n;i++)
		if(i!=tmp0)
			ans[i]=ask(i,tmp0);
	printf("! ");
	for(int i=1;i<=n;i++)
		printf("%d%c",ans[i]," \n"[i==n]);
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			int t1, t2;
			t1 = lower_bound( b.begin(), b.end(), x ) - b.begin();
			t2 = lower_bound( b.begin(), b.end(), y ) - b.begin();
			if( t1 < b.size() && b[ t1 ] == x && t2 < b.size() && b[ t2 ] == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				if( t1 < b.size() && b[ t1 ] == x )
					tmp = y;
				else
					tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			if( tmp == b[ i ] )
				continue;
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & r ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			int t1, t2;
			t1 = lower_bound( b.begin(), b.end(), x ) - b.begin();
			t2 = lower_bound( b.begin(), b.end(), y ) - b.begin();
			if( t1 < b.size() && b[ t1 ] == x && t2 < b.size() && b[ t2 ] == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				if( t1 < b.size() && b[ t1 ] == x )
					tmp = y;
				else
					tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & r ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 1100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( int )log2( n ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			tmp = lower_bound( b.begin(), b.end(), x ) - b.begin();
			if( tmp < b.size() && b[ tmp ] == x )
				continue;
			tmp = lower_bound( b.begin(), b.end(), y ) - b.begin();
			if( tmp < b.size() && b[ tmp ] == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( x == tmp ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	if( m == 2 ) {
		while( true ) {
			tmp = id[ 1 ];
			while( tmp == id[ 1 ] || tmp == id[ 2 ] )
				tmp = rand() % n + 1;
			printf( "? %d %d\n", tmp, id[ 1 ] );
			fflush( stdout );
			scanf( "%d", &x );
			printf( "? %d %d\n", tmp, id[ 2 ] );
			fflush( stdout );
			scanf( "%d", &y );
			if( x < y )
				break;
			if( x > y ) {
				id[ 1 ] = id[ 2 ];
				break;
			}
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 2100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) + 1 ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		a[ 1 ] = 1023;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma )
				a[ 1 ] &= i;
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 1023;
	int tmp[ 1100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		for( int i = 1; i < n; ++i ) {
			for( int j = i + 1; j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= 3; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							break;
						}
					}
					break;
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i <= 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		for( int i = 0; i <= 2100; ++i ) {
			if( sum[ i ] == ma - 1 && i < n ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		int tmp = ma;
		while( tmp & 1 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < 2100; ++i ) {
			if( sum[ i ] == ma && i < n ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( int )log2( n ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			if( *lower_bound( b.begin(), b.end(), x ) == x )
				continue;
			if( *lower_bound( b.begin(), b.end(), y ) == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( x == tmp ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 1100 ];
int res[ 1100 ];
int sum[ 2100 ];

int main() {
	int n;
	int ma = 0, x;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	for( int i = 2; i <= n; ++i ) {
		printf( "? %d %d\n", 1, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < 2100; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ 1 ] = 0;
		x = 1;
	} else {
		for( int i = 0; i < 2100; ++i ) {
			if( sum[ i ] == ma - 1 && i < n ) {
				a[ 1 ] = i;
				break;
			}
		}
		for( int i = 2; i <= n; ++i ) {
			if( res[ i ] == a[ 1 ] ) {
				x = i;
				a[ i ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 2100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) + 1 ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int a[ 2100 ];
int res[ 2100 ];
int sum[ 4200 ];
vector< int > b;

int main() {
	int n;
	int ma = 0, x, y;
	int l, r, tmp;
	scanf( "%d", &n );
	if( n == 3 ) {
		bool fin = false;
		for( int i = 1; !fin && i < n; ++i ) {
			for( int j = i + 1; ! fin && j <= n; ++j ) {
				printf( "? %d %d\n", i, j );
				fflush( stdout );
				scanf( "%d", &x );
				if( x == 3 ) {
					for( int k = 1; k <= n; ++k ) {
						if( k != i && k != j ) {
							x = k;
							a[ x ] = 0;
							fin = true;
							break;
						}
					}
				}
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( i != x ) {
				printf( "? %d %d\n", x, i );
				fflush( stdout );
				scanf( "%d", &a[ i ] );
			}
		}
		printf( "!" );
		fflush( stdout );
		for( int i = 1; i <= n; ++i ) {
			printf( " %d", a[ i ] );
			fflush( stdout );
		}
		return 0;
	}
	srand( time( 0 ) );
	while( true ) {
		l = rand() % n + 1;
		r = l;
		while( r == l )
			r = rand() % n + 1;
		printf( "? %d %d\n", l, r );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( n ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= n; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", l, i );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		++sum[ res[ i ] ];
	}
	for( int i = 0; i < n; ++i )
		ma = max( ma, sum[ i ] );
	if( ma == 1 ) {
		a[ l ] = 0;
		x = l;
	} else {
		tmp = ma;
		while( tmp % 2 == 0 ) {
			tmp >>= 1;
		}
		if( tmp == 1 )
			--ma;
		for( int i = 0; i < n; ++i ) {
			if( sum[ i ] == ma ) {
				r = i;
				break;
			}
		}
		for( int i = 1; i <= n; ++i ) {
			if( res[ i ] == r )
				b.push_back( i );
		}
		b.push_back( l );
		sort( b.begin(), b.end() );
		while( true ) {
			x = rand() % n + 1;
			y = rand() % n + 1;
			if( x == y )
				continue;
			printf( "? %d %d\n", x, y );
			fflush( stdout );
			scanf( "%d", &tmp );
			if( ( tmp & r ) == 0 ) {
				tmp = x;
				break;
			}
		}
		for( int i = 0; i < b.size(); ++i ) {
			printf( "? %d %d\n", tmp, b[ i ] );
			fflush( stdout );
			scanf( "%d", &x );
			if( ( x & r ) == 0 ) {
				x = b[ i ];
				a[ x ] = 0;
				break;
			}
		}
	}
	for( int i = 1; i <= n; ++i ) {
		if( i != x ) {
			printf( "? %d %d\n", i, x );
			fflush( stdout );
			scanf( "%d", &a[ i ] );
		}
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", a[ i ] );
		fflush( stdout );
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 2100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( ( 1 << __builtin_popcount( x ) ) <= m  )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 1100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) + 1 ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}


#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define MAX_INF 0x7f
#define MAX_INF_VAL 0x7f7f7f7f
#define MAX_INF_VAL_LL 0x7f7f7f7f7f7f7f7f
#define pi 3.141592653589
#define eps 1e-6
//#define p 2173412051LL
//#define sz 2

using namespace std;

int n, m;
int ans[ 2100 ];
int res[ 2100 ];
int id[ 2100 ];

void fuck();

int main() {
	int ma = 0, x, y;
	int tmp;
	scanf( "%d", &n );
	for( int i = 1; i <= n; ++i )
		id[ i ] = i;
	srand( time( 0 ) );
	m = n;
 	while( m > 2 ) {
		fuck();
	}
	while( true ) {
		tmp = id[ 1 ];
		while( tmp == id[ 1 ] || tmp == id[ 2 ] )
			tmp = rand() % n + 1;
		printf( "? %d %d\n", tmp, id[ 1 ] );
		fflush( stdout );
		scanf( "%d", &x );
		printf( "? %d %d\n", tmp, id[ 2 ] );
		fflush( stdout );
		scanf( "%d", &y );
		if( x < y )
			break;
		if( x > y ) {
			id[ 1 ] = id[ 2 ];
			break;
		}
	}
	ans[ id[ 1 ] ] = 0;
	for( int i = 1; i <= n; ++i ) {
		if( i == id[ 1 ] )
			continue;
		printf( "? %d %d\n", id[ 1 ], i );
		fflush( stdout );
		scanf( "%d", &ans[ i ] );
	}
	printf( "!" );
	fflush( stdout );
	for( int i = 1; i <= n; ++i ) {
		printf( " %d", ans[ i ] );
		fflush( stdout );
	}
	return 0;
}

void fuck() {
	int mm = 0;
	int l, r, x;
	int val = 2047;
	int tmp[ 2100 ];
	while( true ) {
		l = rand() % m + 1;
		r = l;
		while( r == l )
			r = rand() % m + 1;
		printf( "? %d %d\n", id[ l ], id[ r ] );
		fflush( stdout );
		scanf( "%d", &x );
		if( __builtin_popcount( x ) <= ( ( int )log2( m ) + 2 ) / 2 )
			break;
	}
	for( int i = 1; i <= m; ++i ) {
		if( i == l ) {
			res[ i ] = -1;
			continue;
		}
		printf( "? %d %d\n", id[ l ], id[ i ] );
		fflush( stdout );
		scanf( "%d", &res[ i ] );
		val &= res[ i ];
	}
	for( int i = 1; i <= m; ++i ) {
		if( res[ i ] == val || res[ i ] == -1 )
			tmp[ ++mm ] = id[ i ];
	}
	for( int i = 1; i <= mm; ++i )
		id[ i ] = tmp[ i ];
	m = mm;
}