#include <bits/stdc++.h>
using namespace std;
unsigned long long int gcd(unsigned long long int a, unsigned long long int b) {
  return (b == 0LL ? a : gcd(b, a % b));
}
long double dist(long double x, long double arayikhalatyan, long double x2,
                 long double y2) {
  return sqrt((x - x2) * (x - x2) +
              (arayikhalatyan - y2) * (arayikhalatyan - y2));
}
unsigned long long int S(unsigned long long int a) {
  return (a * (a + 1LL)) / 2;
}
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
char vow[] = {'a', 'e', 'i', 'o', 'u'};
int dx[] = {1, -1, 0, 0, -1, -1, 1, 1, 0};
int dy[] = {0, 0, 1, -1, -1, 1, -1, 1, 0};
const int N = 1e5 + 30;
const unsigned long long int mod = 1e9 + 7;
const long double pi = acos(-1);
const int T = 238;
const long double e = 1e-13;
unsigned long long int bp(unsigned long long int a,
                          unsigned long long int b = mod - 2LL) {
  unsigned long long int ret = 1;
  while (b) {
    if (b & 1) ret *= a, ret %= mod;
    a *= a;
    a %= mod;
    b >>= 1;
  }
  return ret;
}
ostream& operator<<(ostream& c, pair<int, int> a) {
  c << a.first << " " << a.second;
  return c;
}
int n;
int nx, nw = 1, i1 = 2;
int a1[2200][2200];
int ask(int i, int j) {
  if (a1[i][j]) return a1[i][j];
  cout << "? " << i << " " << j << endl;
  int sm;
  cin >> sm;
  a1[i][j] = a1[j][i] = sm;
  return sm;
}
int stg(int a, int b) {
  if (a == b) return a;
  int i1 = 0;
  do {
    i1 = 1 + rnd() % n;
  } while (i1 == a || i1 == b);
  int sm = ask(a, i1);
  bool bl1, bl2;
  bl1 = bl2 = false;
  for (int j = 0; j < 12; j++) {
    if ((1 << j) & nx) {
      if (!((1 << j) & sm)) bl1 = true;
    } else {
      if ((1 << j) & sm) bl2 = true;
    }
  }
  if (bl1 && bl2) {
    return a;
  } else if (bl1) {
    return b;
  } else if (bl2) {
    return stg(b, a);
  } else {
    return b;
  }
}
vector<int> pat;
int b[2200];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  ;
  cin >> n;
  nx = ask(1, 2);
  for (int i = 3; i <= n; i++) {
    b[i - 3] = i;
  }
  random_shuffle(b, b + n - 2);
  for (int i = 0; i <= n - 3; i++) {
    int sm = ask(nw, b[i]);
    bool bl1, bl2;
    bl1 = bl2 = false;
    for (int j = 0; j < 12; j++) {
      if ((1 << j) & nx) {
        if (!((1 << j) & sm)) bl1 = true;
      } else {
        if ((1 << j) & sm) bl2 = true;
      }
    }
    if (bl1 && bl2) {
      if (i < n - 3) {
        nx = ask(nw, b[i + 1]);
        i1 = b[i + 1];
        i++;
      } else {
        i1 = nw;
      }
    } else if (bl1) {
      nx = sm;
      i1 = b[i];
    } else if (bl2) {
      continue;
    } else {
      nw = i1;
      i1 = b[i];
      nx = ask(nw, i1);
    }
  }
  nw = stg(nw, i1);
  for (int i = 1; i <= n; i++) {
    if (i == nw)
      pat.push_back(0);
    else
      pat.push_back(ask(i, nw));
  }
  cout << "! ";
  for (auto p : pat) cout << p << " ";
  cout << endl;
  return 0;
}
