// Original C++ solution (slower):
//Coded by not_surrender

#pragma GCC optimize ("O3")



#include <bits/stdc++.h>



#define MAXN 300003

#define MOD 1000000007

#define oo (1<<20)

#define mid ((a+b)/2)

#define pb push_back

#define sz size()

#define fastCpp() ios_base::sync_with_stdio( false ), cin.tie( NULL ), cout.tie( NULL )



using namespace std;



typedef long long ll;

typedef unsigned long long ull;

typedef vector <int> vi;



struct Data{

	int n1, n2;

	Data(int n1 = 0, int n2 = 0):n1(n1),n2(n2){}

}dp[MAXN];



int N, M, ans;

 

int main(){



    #ifndef ONLINE_JUDGE

		//~ freopen( "a.txt", "r", stdin );

    #endif // ONLINE_JUDGE

    

    fastCpp();

    

    scanf( "%d", &N );

    

    M = (1<<N);

    

    for ( int i = 0; i < M; ++i )

		scanf( "%d", &dp[i].n1 );

    

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

		for ( int j = M-1, nxt; j > 0; --j ){

			nxt = j-(j&(1<<i));

			if ( nxt < j ){

				if ( dp[nxt].n1 > dp[j].n1 )

					dp[j].n2 = dp[j].n1, dp[j].n1 = dp[nxt].n1;

				else

					dp[j].n2 = max( dp[j].n2, dp[nxt].n1 );

			}

		}

	}

	

	for ( int i = 1, ans = 0; i < M; ++i ){

		ans = max( ans, dp[i].n1+dp[i].n2 );

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

	}

	

return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



int b[1 << 21], *a;

int Max[1 << 20], __Max[1 << 20], ans[1 << 20];



int main() {

	

	ios::sync_with_stdio(0);

	cin.tie(0), cout.tie(0);

	

	a = b + 10;

	int n; cin >> n;

	for (int i = 0; i < (1 << n); i++) cin >> a[i];

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

		Max[s] = s, __Max[s] = -1;

		for (int i = 0; i < n; i++) if (s >> i & 1) {

			auto t = s ^ (1 << i);

			if (a[Max[s]] == a[Max[t]]) {

				if (Max[s] == Max[t]) {

					if (a[__Max[s]] < a[__Max[t]]) __Max[s] = __Max[t];

				} else __Max[s] = Max[t];

			}

			if (a[Max[s]] > a[Max[t]]) {

				if (a[__Max[s]] < a[Max[t]]) __Max[s] = Max[t];

			}

			if (a[Max[s]] < a[Max[t]]) {

				if (a[Max[s]] < a[__Max[t]]) __Max[s] = __Max[t];

				else __Max[s] = Max[s];

				Max[s] = Max[t];

			}

		}

	}

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

		if (s == 0) ans[s] = a[Max[s]];

		else ans[s] = max(a[Max[s]] + a[__Max[s]], ans[s - 1]);

	}

	for (int s = 1; s < (1 << n); s++) cout << ans[s] << "\n";

	

	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;

	}