// Original C++ solution (slower):
#include <iostream>

#include <stdio.h>

#include <vector>

#include <stack>

#include <queue>

#include <set>

#include <map>

#include <string>

#include <cstring>

#include <algorithm>

#include <math.h>



using namespace std;



typedef long long ll;

typedef pair<int,int> ii;

typedef vector<int> vi;

typedef vector<ii> vii;



#define FOR(i,n,m) for(int i=n; i<(int)m; i++)

#define ROF(i,n,m) for(int i=n; i>(int)m; i--)

#define pb push_back

#define lb lower_bound

#define ub upper_bound

#define F first

#define S second

#define ri(a) scanf("%d",&a)

#define rii(a,b) ri(a),ri(b)

#define riii(a,b,c) rii(a,b),ri(c)

#define lri(a) scanf("%lld",&a)

#define lrii(a,b) lri(a),lri(b)

#define ms(obj,val) memset(obj,val,sizeof(obj))

#define all(x) x.begin(),x.end()

#define debug true

#define dprintf debug && printf



const int INF = 0x3f3f3f3f;

const ll INFLL = 1e18;

const int MOD = 1e9+7;

const int MAXN = 1<<19;



ii dp[MAXN];

int A[MAXN];

int n;



ii f(int mask){

    if(dp[mask].F != -1) return dp[mask];

    if(!mask) return dp[mask] = {0, -1};

    int mxi = 0, mxi2 = -1;

    for(int s = 0 ; s = (s - mask) & mask ;) {

        if(A[mxi] < A[s]) mxi2 = mxi, mxi = s;

        else if(mxi2 == -1 || A[mxi2] < A[s]) mxi2 = s;

    }

    return dp[mask] = {mxi, mxi2};

}



void mxze(int &a, int b){

    a = max(a,b);

}

void mnze(int &a, int b){

    a = min(a,b);

}



int main(){

    //ios_base::sync_with_stdio(false);

    //cin.tie(NULL);



    FOR(i,0,MAXN) dp[i] = {-1,-1};

    ri(n);

    FOR(i,0,1<<n) ri(A[i]);



    int ans = 0;

    FOR(i,1,1<<n){

        ii p = f(i);

        mxze(ans, A[p.F] + A[p.S]);

        printf("%d\n", ans);

    }



    return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <stdio.h>

#include <vector>

#include <stack>

#include <queue>

#include <set>

#include <map>

#include <string>

#include <cstring>

#include <algorithm>

#include <math.h>



using namespace std;



typedef long long ll;

typedef pair<int,int> ii;

typedef vector<int> vi;

typedef vector<ii> vii;



#define FOR(i,n,m) for(int i=n; i<(int)m; i++)

#define ROF(i,n,m) for(int i=n; i>(int)m; i--)

#define pb push_back

#define lb lower_bound

#define ub upper_bound

#define F first

#define S second

#define ri(a) scanf("%d",&a)

#define rii(a,b) ri(a),ri(b)

#define riii(a,b,c) rii(a,b),ri(c)

#define lri(a) scanf("%lld",&a)

#define lrii(a,b) lri(a),lri(b)

#define ms(obj,val) memset(obj,val,sizeof(obj))

#define all(x) x.begin(),x.end()

#define debug true

#define dprintf debug && printf



const int INF = 0x3f3f3f3f;

const ll INFLL = 1e18;

const int MOD = 1e9+7;

const int MAXN = 1<<19;



int A[MAXN];

int n;



void mxze(int &a, int b){

    a = max(a,b);

}

void mnze(int &a, int b){

    a = min(a,b);

}



int main(){

    //ios_base::sync_with_stdio(false);

    //cin.tie(NULL);



    ri(n);

    FOR(i,0,1<<n) ri(A[i]);



    int ans = 0;

    FOR(mask,1,1<<n){

        int mxi = A[0], mxi2 = -1;

        for(int s = 0 ; s = (s - mask) & mask ;) {

            if(mxi < A[s]) mxi2 = mxi, mxi = A[s];

            else if(mxi2 == -1 || mxi2 < A[s]) mxi2 = A[s];

        }

        mxze(ans, mxi + mxi2);

        printf("%d\n", ans);

    }



    return 0;

}


// Fastest known solution for this problem:
	#include <bits/stdc++.h>

	#define mx 300005

	using namespace std;



	int a[mx], n;

	vector<vector<bool> > vis(mx, vector<bool> (20, false));

	vector<vector<pair<int,int> > > memo(mx, vector<pair<int, int> > (20, {0, 0}));



	void dp(int num, int pos) {

		if(pos == 0) {

			memo[num][0].first = a[num];

			vis[num][0] = true;

			return;

		}

		if(vis[num][pos]) return;

 		vector<int> cons;

		dp(num, pos-1);

		cons.push_back(memo[num][pos-1].first);

		cons.push_back(memo[num][pos-1].second);

		if(num & (1<<(pos-1))) {

			dp(num ^ (1<<(pos-1)), pos-1);

			cons.push_back(memo[num ^ (1<<(pos-1))][pos-1].first);

			cons.push_back(memo[num ^ (1<<(pos-1))][pos-1].second);

		}

		sort(cons.begin(), cons.end(), greater<int>());

		memo[num][pos].first = cons[0];

		memo[num][pos].second = cons[1];

		vis[num][pos] = true;

	}



	int main() {

		ios_base::sync_with_stdio(false);

	    cin.tie(NULL);

	    cout.tie(NULL);



		cin >> n;

		for(int i = 0; i < (1<<n); ++i) {

			cin >> a[i];

			

		}

		for(int i = (1<<n) - 1; i >= 0; --i) {

			if(!vis[i][n]) {

				dp(i, n);

			}

		}

		int mxv = 0;

		for(int i = 1; i < 1<<n; ++i) {

			mxv = max(memo[i][n].first + memo[i][n].second, mxv);

			cout << mxv << "\n";	

		}

		return 0;

	}