// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



const int maxn = (1<<18) + 5;

int n;

int a[maxn];

int x[maxn][2];

int num[maxn][2];



int main() {

	cin >> n;

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

		cin >> a[i];

	memset(x, 0, sizeof(x));

	memset(num, 0, sizeof(num));

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

		if (x[i][0] < a[0]) {

			x[i][0] = a[0];

			num[i][0] = 0;

		}

		else if (x[i][1] < a[0]){

			x[i][1] = a[0];

			num[i][1] = 0;

		}

	int last = 0;

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

		if (a[i] > x[i][0]) {

			swap(x[i][0], x[i][1]);

			swap(num[i][0], num[i][1]);

			x[i][0] = a[i];

			num[i][0] = i;

		}

		else if (a[i] > x[i][1]) {

			x[i][1] = a[i];

			num[i][1] = i;

		}

		last = max(last, x[i][0]+x[i][1]);

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

		for (int j = 1; j < (1<<n); j <<= 1) {

			if (x[i|j][0] < x[i][0]) {

				swap(x[i|j][0], x[i|j][1]);

				swap(num[i|j][0], num[i|j][1]);

				x[i|j][0] = x[i][0];

				num[i|j][0] = num[i][0];

				if (x[i|j][1] < x[i][1] && num[i|j][1] != num[i][1]) {

					x[i|j][1] = x[i][1];

					num[i|j][1] = num[i][1];

				}

			}

			else if (x[i|j][1] < x[i][0] && num[i|j][0] != num[i][0]) {

				x[i|j][1] = x[i][0];

				num[i|j][1] = num[i][0];

			}

			else if (x[i|j][1] < x[i][1]) {

				x[i|j][1] = x[i][1];

				num[i|j][1] = num[i][1];

			}

		}

	}

	return 0;

}

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

#include<ext/pb_ds/hash_policy.hpp>

#include<ext/pb_ds/assoc_container.hpp>

#define N 500005

using namespace __gnu_pbds;

using namespace std;

typedef long long LL;

typedef unsigned long long uLL;

struct custom_hash {

    static uint64_t splitmix64(uint64_t x) {

        x += 0x9e3779b97f4a7c15;

        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;

        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;

        return x ^ (x >> 31);

    }

    size_t operator()(uint64_t x) const {

        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();

        return splitmix64(x + FIXED_RANDOM);

    }

};

LL z = 1;

int read(){

	int x, f = 1;

	char ch;

	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;

	x = ch - '0';

	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;

	return x * f;

}

int ksm(int a, int b, int p){

	int s = 1;

	while(b){

		if(b & 1) s = z * s * a % p;

		a = z * a * a % p;

		b >>= 1;

	}

	return s;

}

int a[N];

int f[N];

struct node{

	int a, b;

}d[N];

void work(node &t, int x){

	if(t.a == x || t.b == x) return;

	if(a[t.a] < a[x]) t.b = t.a, t.a = x;

	else if(a[t.b] < a[x]) t.b = x;

}

int main(){

	int i, j, t, n, m;

	n = read();

	for(i = 0; i < (1 << n); i++) a[i] = read(), d[i].a = i;

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

		for(j = 0; j < n; j++){

			if(1 << j & i){

				t = i ^ (1 << j);

				work(d[i], d[t].a);

				work(d[i], d[t].b);

			}

		}

		f[i] = a[d[i].a] + a[d[i].b];

	}

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

		f[i] = max(f[i], f[i - 1]);

		printf("%d\n", f[i]);

	}

	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;

	}