//code by lynmisakura.wish to be accepted!
/****************************/
#include<iostream>
#include<iomanip>
#include<math.h>
#include<vector>
#include<string>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<bitset>
#include <climits>
#include<set>
#include<bitset>
using namespace std;
/***************************/
typedef long long ll;
typedef long long ijt;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef pair<int, int> pi;
typedef vector<pair<int, int>> vpi;

const long long INF = 1LL << 55;

#define itn int
#define endl '\n'
#define pb push_back
#define mp make_pair
#define ss second
#define ff first
#define dup(x,y) ((x) + (y) - 1)/(y)
#define mins(x,y) x = min(x,y)
#define maxs(x,y) x = max(x,y)
#define all(x) (x).begin(),(x).end()
#define Rep(n) for(int i = 0;i < n;i++)
#define rep(i,n) for(int i = 0;i < n;i++)
#define rrep(i,n) for(int i = n - 1;i >= 0;i--)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() )

ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
ll qp(ll a, ll b) { ll ans = 1; do { if (b & 1)ans = 1ll * ans*a; a = 1ll * a*a; } while (b >>= 1); return ans; }
ll qp(ll a, ll b, int mo) { ll ans = 1; do { if (b & 1)ans = 1ll * ans*a%mo; a = 1ll * a*a%mo; } while (b >>= 1); return ans; }

#define _GLIBCXX_DEBUG
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

#define MAX_N 300030
ijt n;
vector<ijt> a(MAX_N);
vector<ijt> G[20*MAX_N];
vector<pair<ijt, int>> b(MAX_N);
vector<int> i_a(MAX_N);
vector<pair<ijt,ijt>> A(20*MAX_N);
//グラフを構成する
void make_graph() {
	
	ijt m = 1LL << n;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if(i == 0)A[j] = mp(i_a[j], i_a[j]);
			else A[m*i + j] = mp(i_a[j], i_a[j]);
		}
	}
	for (int i = 0; i < n; i++)
	{
		//各頂点に対して(1<<i)をorしたindexに対して辺を張る
		for (int j = 0; j < (1LL<<n); j++)
		{	
			//直下
			set<ijt,greater<ijt>> s,t;

			ijt x = 0;
			t.insert(A[m*i + j].first); t.insert(A[m*i + j].second);
			t.insert(A[m*(i+1) + j].first); t.insert(A[m*(i+1) + j].second);
			for (auto k : t) {
				if (x == 0)A[m*(i + 1) + j].first = k;
				if (x == 1)A[m*(i + 1) + j].second = k;
				if (x > 1) break;
				x++;
			}

			
			s.insert(A[m*i + j].first); s.insert(A[m*i + j].second);
			s.insert(A[(i + 1)*m + (j | (1<<(i)))].first); s.insert(A[(i + 1)*m + (j | (1 << (i)))].second);
			x = 0;
			//for (auto k : s)cout << k << " ";
			//cout << endl;
			for (auto k : s) {
				//cout << "next insert : " << k << endl;
				if (x == 0)A[(i + 1)*m + (j | (1 << (i)))].first = k;
				if (x == 1)A[(i + 1)*m + (j | (1 << (i)))].second = k;
				if(x > 1) break;
				x++;
			}
		}
		
	}
	ijt pre;
	for (int i = 1; i < m; i++) {
		//cout << b[a[A[m*n + i].first]].ff + b[a[A[m*n + i].second]].ff << endl;
		int x = A[n*m + i].ff;
		int y = A[n*m + i].ss;
		if(i!=1 and b[x].first + b[y].first < pre)cout << pre << endl;
		else {cout << b[x].first + b[y].first << endl; pre = b[x].first + b[y].first;}
	}

}

int main() {
	cin >> n;
	
	
	for (int i = 0; i < (1LL<<n); i++)
	{
		cin >> a[i];
		b[i] = mp(a[i],i);
	}
	b.resize(1<<n);
	sort(all(b));
	for (int i = 0; i < (1<<n); i++)
	{
		i_a[b[i].second] = i;
	}
	
	//a.resize(1LL << n);
	make_graph();
	return 0;

}

Measured memory_bytes: 245632