/*Bismillahir Rahmanir Rahim*///{
#include <bits/stdc++.h>
#include <ext/numeric>
using namespace std; using __gnu_cxx::power;
using ll = long long; using ull = unsigned long long; using ld = long double;
const ll llinf = (1ll<<61)-1;
const double eps = 1e-6, ldeps = 1e-9;
struct Dbg {
static constexpr auto &os = cout;   // replace by cerr in interactive.
template<class C> static auto dud(C *x)->decltype(os << *x, 0);
template<class C> static char dud(...);
template<class C> typename enable_if<sizeof dud<C>(0)!=1, Dbg&>::type operator<<(const C &x) { os << x; return *this; }
template<class C> Dbg &dump(C b, C e) {
    *this << "\n[";
    int cur = 0;
    for (C i = b; i!=e and cur<26; i++, cur++) *this << ", "+2*(i==b) << *i;
    return *this << ']';
}
template<class C> typename enable_if<sizeof dud<C>(0)==1, Dbg&>::type operator<<(const C &x) {
    return dump(begin(x), end(x));
}
template<class C, size_t X> typename enable_if<!is_same<C, const char>::value, Dbg&>::type operator <<(C (&x)[X]) {
    return dump(begin(x), end(x));
}
template<class B, class C> Dbg &operator <<(const pair<B, C> &x) {
    return *this << '{' << x.first << ", " << x.second << '}';
}
Dbg &operator<<(ostream&(*x)(std::ostream&)) { os << x; return *this; }
} dbg;
void err(istringstream *iss) { delete iss; }
template<class C, class... Args> void err(istringstream *iss, const C &val, const Args &... args) {
    string name; *iss >> name; if (name.back()==',') name.pop_back();
    dbg << name << " = " << val << "; ", err(iss, args...);
}
#define bug(args...) dbg << __LINE__ << ": ", err(new istringstream(#args), args), dbg << endl
#define cbug(a, args...) if (a) bug(args);
#define ASSERT(a, o, b, args...) if (!((a)o(b))) bug(a, b, ##args), assert((a)o(b));
#define sl(a) int(strlen(a))
#define sz(a) int(a.size())
int T, Q, cn;//}
const int inf = 1000000007, mxn = 18;


// for ll select all << and replace by ll<<
#define bin(m) bitset<6>(m)
#define test(m, p) (1&((m)>>(p)))
#define set_(m, p) ((m)|(1<<(p)))
#define setb(m, p) m = set_(m, p)
#define reset_(m, p) ((m)&~(1<<(p)))
#define resetb(m, p) m = reset_(m, p)
#define toggle_(m, p) ((m)^(1<<(p)))
#define toggleb(m, p) m = toggle_(m, p)
#define assign_(m, p, val) (val ? set_(m) : reset_(m))
#define assignb(m, p, val) m = assign_(m, p, val)
#define submask(s, m) s = (s-1)&m
#define getAllSet(p) ((1<<(p))-1)
#define allSet(m, p) (m) == getAllSet(p)
ll rol(ll m, int l, int w) { return ((m>>(w-l))|(m<<l))&((1<<w)-1); }

int n, a[1<<18|5];
pair<pair<int, int>, pair<int, int> > dp[1<<18|5];

signed main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); cout.precision(11);
/*
Classic example of easing condition for yourself:
Let, we have already calculated ans[K-1]. We only need (i|j)==K case now, which is tough. Instead of finding max for (i|j)==K,
we can find for (i and j both are submasks of K), then it surely covers (i|j)==K and other covered cases are surely (i|j) < K,
which is easier problem: as each dp contains all its submasks' max 2 elements, we can just switch off single on bits and ensure
that same element doesn't become max and 2nd max by saving index of source in dp.
*/
    cin >> n;
    for (int i = 0; i < 1<<n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < 1<<n; i++) {
        dp[i] = {{a[i], i}, {0, -1}};
        for (int j = 0; j < n; j++) {
            if (!test(i, j)) continue;
            int o = reset_(i, j);
            if (dp[o].first > dp[i].first) dp[i].second = dp[i].first, dp[i].first = dp[o].first;
            else if (dp[o].first.second!=dp[i].first.second and dp[o].first > dp[i].second) dp[i].second = dp[o].first;
            if (dp[o].second.second!=dp[i].first.second and dp[o].second > dp[i].second) dp[i].second = dp[o].second;
            // break;
        }
    }
    int o = 0;
    for (int i = 1; i <= (1<<n)-1; i++) {
        o = max(o, dp[i].first.first+dp[i].second.first);
        cout << o << '\n';
    }
}

Measured memory_bytes: 8192