#pragma GCC optimize("unroll-loops")
#pragma gcc optimize("Ofast")
#pragma GCC optimization("Ofast")
#pragma optimize(Ofast)
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define str string
#define fastio ios::sync_with_stdio(0), cin.tie(0);
#define fs first
#define ss second
#define endl '\n'
#define all(x) (x).begin(), (x).end()
#define len(x) x.size()

#define print(a)          \
    for (auto &x : a)     \
        cout << x << " "; \
    cout << endl;

#define printmp(a)    \
    for (auto &x : a) \
        cout << x.fs << " " << x.ss << endl;

const int mod = 1e9 + 7;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n);
    map<int, int> mp;
    for(int i = 0; i < n; i ++)
        cin >> a[i], mp[a[i]] ++;
    int k = 0, m = n;
    while(m){
        k ++;
        m /= 2;
    }
    sort(all(a));
    if(mp.size() != (1 << (k - 1))){
        cout << -1;
        return;
    }
    multiset<pair<int, int>, greater<pair<int, int>>> ml;
    for(auto x : mp)
        ml.insert({x.ss, x.fs});
    pair<int, int> x = *ml.begin();
    if(x.ss != a[0] or x.fs != k){
        cout << -1;
        return;
    }
    vector<int> ans((1 << (k - 1)));
    ans[0] = a[0];
    ml.erase(ml.begin());
    set<pair<int, pair<int, int>>, greater<pair<int, pair<int, int>>>> q;
    q.insert({k - 1, {1, 0}});
    while(!ml.empty() and !q.empty()){
        pair<int, pair<int, int>> x = *q.begin();
        q.erase(q.begin());
        pair<int, int> y = *ml.begin();

        if(y.fs == x.fs){
            q.insert({x.fs - 1, {x.ss.fs, x.ss.ss}});
            q.insert({x.fs - 1, {y.ss, x.ss.ss + (1 << (x.fs - 1))}});
            ml.erase(ml.begin());
            ans[x.ss.ss + (1 << (x.fs - 1))] = y.ss;
        }
        else{
            cout << -1;
            return;
        }
    }
    print(ans)
}

signed main()
{
    fastio int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
        cout << endl;
    }
}