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

#define taskname "OrPlusMax"

#define int long long

using namespace std;



vector<int> a;

void update(int i, pair<int, int> &p)

{

    if (i == p.first || i == -1) return;

    if (p.first == -1 || a[i] > a[p.first])

    {

        swap(p.first, p.second);

        p.first = i;

    }

    else if (p.second == -1 || a[i] > a[p.second]) p.second = i;

}



main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);   cout.tie(nullptr);

    if (ifstream("test.inp"))

    {

        freopen("test.inp", "r", stdin);

        #ifdef CHECKING

            freopen(taskname".out", "w", stdout);

        #else

            freopen("test.out", "w", stdout);

        #endif //CHECKING

    }

    else if (ifstream(taskname".inp"))

    {

        freopen(taskname".inp", "r", stdin);

        freopen(taskname".out", "w", stdout);

    }



    int n;  cin >> n;

    a.resize(1 << n);

    for (int &i : a) cin >> i;

    vector<pair<int, int>> v(1 << n, {-1, -1});

    vector<int> ans(1 << n, 0);

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

    {

        update(i, v[i]);

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

            if (((i >> (j - 1)) & 1) == 0)

            {

                int x = i ^ (1 << (j - 1));

                update(v[i].first, v[x]);

                update(v[i].second, v[x]);

            }

        if (i)

        {

            ans[i] = max(ans[i - 1], a[v[i].first] + a[v[i].second]);

            cout << ans[i] << '\n';

        }

    }

}


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

#include<algorithm>

#define rep(i,l,r) for (int i=(l); i<=(r); i++)

using namespace std;



const int N=300010;

int n,m,a[N],r[N],mx[N];



int main(){

    scanf("%d",&m); int n=1<<m;

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

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

        for (int j=i; j<n; j=(j+1)|i)

            r[j]=max(r[j],a[i]+mx[j]),mx[j]=max(mx[j],a[i]);

    for (int i=1; i<n; i++) printf("%d\n",r[i]=max(r[i],r[i-1]));

    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;

	}