#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int INF = 0x3f3f3f3f;
const long long int llINF = 0x3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int n;
int z[20];
int idx;
int ans[3000];
int memo[3000][3000];
int ran(int N) { return uniform_int_distribution<int>(1, N)(rng); }
int query(int i, int j) {
  if (memo[j][i] != -1) return memo[i][j];
  cout << '?' << ' ' << i << ' ' << j << endl;
  int x;
  cin >> x;
  memo[i][j] = memo[j][i] = x;
  return x;
}
void build_z() {
  int comp = 0;
  while (comp < 11) {
    int i, j;
    i = j = 0;
    while (i == j) {
      i = ran(n);
      j = ran(n);
    }
    int x = query(i, j);
    for (int k = 0; k < 11; k++) {
      if ((x & (1 << k)) == 0)
        if (z[k] == 0) {
          z[k] = i;
          comp++;
        }
    }
  }
}
int magic(int ind) {
  int ans = (1 << 11) - 1;
  for (int i = 0; i < 11; i++) {
    if (ind != z[i])
      ans = ans & query(ind, z[i]);
    else if (ans & (1 << i)) {
      ans = ans ^ (1 << i);
    }
  }
  return ans;
}
void find_0() {
  idx = 1;
  int val = magic(idx);
  for (int i = 2; i <= n; i++) {
    int x = query(idx, i);
    if ((val | x) == val) {
      idx = i;
      val = magic(i);
    }
  }
}
void build_ans() {
  for (int i = 1; i <= n; i++) {
    if (i != idx) ans[i] = query(i, idx);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n;
  memset(memo, -1, sizeof(memo));
  build_z();
  find_0();
  build_ans();
  cout << '!' << ' ';
  for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
  cout << endl;
}
