#include <bits/stdc++.h>
using namespace std;
void read(int &x) {
  x = 0;
  int f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = -f;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  x *= f;
}
void print(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (!x) return;
  print(x / 10), putchar(x % 10 + 48);
}
void write(int x) {
  if (!x)
    putchar('0');
  else
    print(x);
  putchar('\n');
}
const int maxn = 1e6 + 10;
const int inf = 1e9;
const double eps = 1e-8;
const int mod = 1e9 + 7;
int v[maxn];
map<pair<int, int>, int> s;
int n, t, z[maxn], ans[maxn];
int query(int x, int y) {
  if (x > y) swap(x, y);
  if (s[make_pair(x, y)]) return s[make_pair(x, y)];
  printf("? %d %d\n", x, y);
  fflush(stdout);
  int a;
  read(a);
  assert(a != -1);
  return s[make_pair(x, y)] = a;
}
int get(int x) {
  int a = (1 << t) - 1;
  for (int i = 0; i < t; i++)
    if (x != z[i])
      a &= query(z[i], x);
    else if ((a >> i) & 1)
      a ^= 1 << i;
  return a;
}
int main() {
  srand(time(0));
  read(n);
  for (int i = 1; i < n; i <<= 1) t++;
  while (1) {
    int x = rand() % n + 1, y = rand() % n + 1, bo = 1;
    for (int i = 0; i < t; i++)
      if (!z[i]) bo = 0;
    if (bo) break;
    if (x == y) continue;
    int a = query(x, y);
    for (int i = 0; i < t; i++)
      if (!((a >> i) & 1)) z[i] = x;
  }
  int a = get(1), pre = 1;
  for (int i = 2; i <= n; i++)
    if (query(pre, i) == a) a = get(i), pre = i;
  for (int i = 1; i <= n; i++)
    if (i != pre) ans[i] = query(pre, i);
  printf("! ");
  for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
  puts("");
  return 0;
}
