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

using namespace std;



const int N = 330000;



int a[N];



vector<int> dp[N];



void insert(vector<int> &lhs, const vector<int> &rhs) {

	for (int x : rhs) lhs.push_back(x);

	sort(lhs.begin(), lhs.end());

	reverse(lhs.begin(), lhs.end());

	lhs.resize(2);

}



int main() {

	ios::sync_with_stdio(0);

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

	int n; cin >> n; int m = 1 << n;

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

	for (int i = 0; i < m; i++) dp[i].push_back(a[i]);

	for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (j & (1 << i)) insert(dp[j], dp[j ^ (1 << i)]);

	int ans = 0;

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

		ans = max(ans, dp[i][0] + dp[i][1]);

		cout << ans << "\n";

	}

	return 0;

}




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

using namespace std;

#define all(v) ((v).begin()),((v).end())

#define ll long long

#define fastIO cout << fixed << setprecision(12), ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)

double const EPS = 1e-12, PI = acos(-1);

const int N = 4e5 + 9, M = 5e3 + 9, OO = 1e9 + 7, MOD = 1e9 + 7;

const ll inf = 1e18;



int arr[N];

pair<int, int> DP[N];



pair<int, int> merge(pair<int, int> A, pair<int, int> B) {

  set<pair<int, int>> st; // maximum Val, without repeat index

  st.insert({-arr[A.first], A.first});

  st.insert({-arr[A.second], A.second});

  st.insert({-arr[B.first], B.first});

  st.insert({-arr[B.second], B.second});

  pair<int, int> ans;

  ans.first = (*st.begin()).second;

  st.erase(st.begin());

  ans.second = (*st.begin()).second;

  return ans;

}



int main() {

  fastIO;

#ifdef LOCAL

  freopen("input.in", "rt", stdin);

#endif

  // problem on SOS DP

  int n;

  cin >> n;

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

    cin >> arr[i];

    DP[i] = {i, (1 << n)};

  }

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

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

      if(mask & (1 << i)) {

        DP[mask] = merge(DP[mask], DP[mask ^ (1 << i)]); // SOS

      }

    }

  }

  int best = 0;

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

    best = max(best, arr[DP[i].first] + arr[DP[i].second]);

    if(i)

      cout << best << '\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;

	}