Problem:
Score : 700 points

Problem Statement

There is an integer sequence of length 2^N: A_0, A_1, ..., A_{2^N-1}. (Note that the sequence is 0-indexed.)

For every integer K satisfying 1 \leq K \leq 2^N-1, solve the following problem:

Let i and j be integers. Find the maximum value of A_i + A_j where 0 \leq i < j \leq 2^N-1 and (i or j) \leq K.
Here, or denotes the bitwise OR.

Constraints

1 \leq N \leq 18

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_0 A_1 ... A_{2^N-1}

Output

Print 2^N-1 lines.
In the i-th line, print the answer of the problem above for K=i.

Sample Input 1

2
1 2 3 1

Sample Output 1

3
4
5

For K=1, the only possible pair of i and j is (i,j)=(0,1), so the answer is A_0+A_1=1+2=3.

For K=2, the possible pairs of i and j are (i,j)=(0,1),(0,2).
When (i,j)=(0,2), A_i+A_j=1+3=4. This is the maximum value, so the answer is 4.

For K=3, the possible pairs of i and j are (i,j)=(0,1),(0,2),(0,3),(1,2),(1,3),(2,3) .
When (i,j)=(1,2), A_i+A_j=2+3=5. This is the maximum value, so the answer is 5.

Sample Input 2

3
10 71 84 33 6 47 23 25

Sample Output 2

81
94
155
155
155
155
155

Sample Input 3

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

Sample Output 3

101
120
147
156
156
178
194
194
194
194
194
194
194
194
194

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Competitive
{
    internal class Solution
    {
        public int _N;
        public int N;
        public int[] A;
        public int[] V1, I1; // iまでの1番目に大きい数, index
        public int[] V2, I2; // iまでの2番目に大きい数, index

        public void Run()
        {
            _N = Input.ReadInt();
            N = 1;
            for (int i = 0; i < _N; i++)
                N *= 2;
            A = Input.ReadIntArray();

            V1 = new int[N];
            V2 = new int[N];
            I1 = new int[N];
            I2 = new int[N];

            for (int i = 0; i < N; i++)
            {
                int v1 = A[i];
                int i1 = i;
                int v2 = -1;
                int i2 = -1;

                for (int b = 0; b <= 20; b++)
                {
                    int ii = (1 << b) ^ i;
                    if (i > ii)
                    {
                        // update
                        if (V1[ii] >= v1 && I1[ii] != i1 && I1[ii] != i2)
                        {
                            v2 = v1;
                            i2 = i1;
                            v1 = V1[ii];
                            i1 = I1[ii];
                        }
                        else if (V1[ii] >= v2 && I1[ii] != i1 && I1[ii] != i2)
                        {
                            v2 = V1[ii];
                            i2 = I1[ii];
                        }

                        if (V2[ii] >= v1 && I2[ii] != i1 && I2[ii] != i2)
                        {
                            v2 = v1;
                            i2 = i1;
                            v1 = V2[ii];
                            i1 = I2[ii];
                        }
                        else if (V2[ii] >= v2 && I2[ii] != i1 && I2[ii] != i2)
                        {
                            v2 = V2[ii];
                            i2 = I2[ii];
                        }
                    }
                }

                V1[i] = v1;
                V2[i] = v2;
                I1[i] = i1;
                I2[i] = i2;
            }

            int mx = 0;
            for (int i = 1; i < N; i++)
            {
                mx = Math.Max(mx, V1[i] + V2[i]);
                Console.WriteLine(mx);
            }
        }
    }

    // libs ----------
    

    // common ----------

    internal static class Input
    {
        public static string ReadString()
        {
            string line = Console.ReadLine();
            return line;
        }

        public static int ReadInt()
        {
            string line = Console.ReadLine();
            return int.Parse(line);
        }

        public static int[] ReadIntArray()
        {
            string line = Console.ReadLine();
            return line.Split(' ').Select(int.Parse).ToArray();            
        }

        public static long ReadLong()
        {
            string line = Console.ReadLine();
            return long.Parse(line);
        }

        public static long[] ReadLongArray()
        {
            string line = Console.ReadLine();
            return line.Split(' ').Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            string line = Console.ReadLine();
            return line.Split(' ').Select(double.Parse).ToArray();
        }
    }
    
    internal class Program
    {
        public static void Main(string[] args)
        {
            var s = new Solution();
            s.Run();
        }
    }
}