#include <bits/stdc++.h>
using namespace std;
inline long long in() {
  int32_t x;
  scanf("%d", &x);
  return x;
}
inline long long lin() {
  long long x;
  scanf("%lld", &x);
  return x;
}
inline string get() {
  char ch[2000010];
  scanf("%s", ch);
  return ch;
}
inline void read(long long *a, long long n) {
  for (long long i = 0; i < n; i++) a[i] = in();
}
template <class blank>
inline void out(blank x) {
  cout << x << "\n";
  exit(0);
}
const long long maxn = 5e6 + 10;
const long long maxm = 1e6 + 10;
const long long maxlg = 31;
const long long base = 29;
const long long mod = 1e9 + 7;
const long long INF = 1e18 + 10;
const long long SQ = 317;
long long a[maxn];
long long nxt[maxn][2], num[maxn], cur = 0;
bool mark[maxn];
inline void insert(long long x) {
  bool fl = false;
  long long node = 0;
  for (long long i = maxlg - 1; i >= 0; i--) {
    bool has = (x >> i) & 1;
    if (fl == false && has == 0) continue;
    fl = true;
    if (!nxt[node][has]) {
      nxt[node][has] = ++cur;
      num[nxt[node][has]] = num[node] * 2 + has;
    }
    node = nxt[node][has];
  }
  assert(!mark[node]);
  mark[node] = true;
}
long long cc = 0;
long long b[maxn];
inline long long dfs(long long node, long long lim) {
  long long rem = mark[node];
  for (long long i = 0; i < 2; i++)
    if (nxt[node][i]) rem += dfs(nxt[node][i], lim);
  if (rem && num[node] && num[node] <= lim) {
    rem--;
    b[cc++] = num[node];
  }
  return rem;
}
inline bool can(long long lim) {
  cc = 0;
  return dfs(0, lim) == 0;
}
int32_t main() {
  long long n = in();
  read(a, n);
  for (long long i = 0; i < n; i++) insert(a[i]);
  long long low = 0, hi = *max_element(a, a + n);
  while (low + 1 < hi) {
    long long mid = (low + hi) >> 1;
    if (can(mid))
      hi = mid;
    else
      low = mid;
  }
  can(hi);
  for (long long i = 0; i < n; i++) cout << b[i] << " ";
}
