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

using namespace std;

typedef long long ll;



ll read(){

    ll x=0,f=1;char c=getchar();

    while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}

    while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}

    return x*f;

}



int n;

int a[1000100];

pair<int,int> b[1000100];



void upd(int x,int y){

    int num1=b[x].first,num2=b[x].second,num3=b[y].first,num4=b[y].second;

    b[x].first=max(num1,num3);

    if(num1>num3) b[x].second=max(num2,num3);

    else b[x].second=max(num1,num4);

}



int main(){

    #ifdef LZT

    freopen("in","r",stdin);

    #endif

    n=read();

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

        a[i]=read();

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

        b[i].first=a[i],b[i].second=-1e9;

    for(int k=0;k<n;k++){

        //cout<<k<<endl;

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

            if((i&(1<<k))!=0) continue;

            upd(i|(1<<k),i);

            //cout<<(i|(1<<k))<<' '<<i<<endl;

        }

    }/*

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

        upd(i+1,i);

    }*/

    int lastans=0;

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

        lastans=max(lastans,b[i].first+b[i].second);

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

    }

    return 0;

}



/*

2

1 2 3 1

*/

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

#include<cstring>

#include<cstdlib>

#include<algorithm>

#include<cmath>

#include<queue>

#include<vector>

#include<ctime>

#include<map>

#include<bitset>

#include<set>

#define LL long long

#define mp(x,y) make_pair(x,y)

#define pll pair<long long,long long>

#define pii pair<int,int>

using namespace std;

inline int read()

{

	int f=1,x=0;char ch=getchar();

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

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

	return x*f;

}

int stack[20];

inline void write(LL x)

{

	if(x<0){putchar('-');x=-x;}

    if(!x){putchar('0');return;}

    int top=0;

    while(x)stack[++top]=x%10,x/=10;

    while(top)putchar(stack[top--]+'0');

}

inline void pr1(int x){write(x);putchar(' ');}

inline void pr2(LL x){write(x);putchar('\n');}



const int MAX_N=20;

int bin[MAX_N];

#define pr pair<int,int>

#define FR first

#define SE second

#define MP make_pair

int a[1<<MAX_N];pr b[1<<MAX_N];

int gmax(int x,int y){return a[x]>a[y]?x:y;}

pr merge(pr x,pr y)

{

	if(a[x.FR]>a[y.FR]) return MP(x.FR,gmax(x.SE,y.FR));

	else return MP(y.FR,gmax(x.FR,y.SE));

}

void fwt(int n)

{

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

		for(int j=bin[n]-1;j>=0;j--) if(j&bin[i])

				b[j]=merge(b[j],b[j^bin[i]]);

}

int main()

{

	bin[0]=1;for(int i=1;i<MAX_N;i++) bin[i]=bin[i-1]<<1;

	

	int n;scanf("%d",&n);a[bin[n]]=0;

	for(int i=0;i<bin[n];i++) scanf("%d",&a[i]),b[i]=MP(i,bin[n]);

	fwt(n);

	int lst=0;

	for(int i=1;i<bin[n];i++)

	{

		lst=max(a[b[i].FR]+a[b[i].SE],lst);

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

	}

}

/*

4

75 26 45 72 81 47 97 97 2 2 25 82 84 17 56 32

*/


// 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;

	}