Problem: Kuroni isn't good at economics. So he decided to found a new financial pyramid called Antihype. It has the following rules:

  1. You can join the pyramid for free and get 0 coins. 
  2. If you are already a member of Antihype, you can invite your friend who is currently not a member of Antihype, and get a number of coins equal to your age (for each friend you invite). 



n people have heard about Antihype recently, the i-th person's age is a_i. Some of them are friends, but friendship is a weird thing now: the i-th person is a friend of the j-th person if and only if a_i  AND  a_j = 0, where AND denotes the [bitwise AND operation](https://en.wikipedia.org/wiki/Bitwise_operation#AND).

Nobody among the n people is a member of Antihype at the moment. They want to cooperate to join and invite each other to Antihype in a way that maximizes their combined gainings. Could you help them? 

Input

The first line contains a single integer n (1≤ n ≤ 2⋅ 10^5) — the number of people.

The second line contains n integers a_1, a_2, ..., a_n (0≤ a_i ≤ 2⋅ 10^5) — the ages of the people.

Output

Output exactly one integer — the maximum possible combined gainings of all n people.

Example

Input


3
1 2 3


Output


2

Note

Only the first and second persons are friends. The second can join Antihype and invite the first one, getting 2 for it.

Solution (in JAVA):

Solution:
/**
 * author: derrick20
 * created: 11/8/20 2:09 PM
 */
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class KuroniAntihypeSlick {
    public static void main(String[] args) {
        FastScanner sc = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        
        int N = sc.nextInt();
        int MAXBIT = 1 << 18;
        int[] freq = new int[MAXBIT];
        freq[0]++;
        long initial = 0;
        for (int v : sc.nextInts(N)) {
            freq[v]++;
            initial += v; // key bug: need to know the initial number of nodes to have the proper degree -1 subtraction!
        }
        id = new int[MAXBIT];
        Arrays.setAll(id, i -> i);
        int[] deg = new int[MAXBIT];
        /*
        Intuition:
        In any graph, all parent nodes contribute (deg - 1) to the answer. (except root, which
        gives deg, but adding a supernode 0 as the root lets us ignore that).
        So, we want to maximize sum{deg[node] * age[node]} in a spanning tree. This equates to
        each edge having weight age[u] + age[v], so we just want to pick edges in the greedy way.

        If we accept that the optimal matching can be restated as always picking the largest
        sum edges, then we can greedily go from high to low and consider edges such that their
        sum is that. (We use a directed manner from parent > child for a constant boost).

        If we can merge for a given parent-child pairing, we do so since there's no better option
        (no higher sum was possible yet).

        One issue is if there are duplicates of a given age, but we can imagine linking them
        up in an alternating chain (1-2-1-2-1), which gives total nodes - 1 extra degree, and
        since it's bipartite, each node receives that extra degree.

        Then, the number of distinct components with those ages now become one.
         */
        for (int sum = MAXBIT - 1; sum >= 0; sum--) {
            for (int parent = sum; parent > (sum ^ parent); parent = (parent - 1) & sum) {
//                ASSERT(Integer.highestOneBit(parent) == Integer.highestOneBit(sum));
                int child = sum ^ parent;
                if (find(parent) != find(child) && freq[parent] > 0 && freq[child] > 0) {
                    unite(parent, child);
                    int edges = freq[parent] + freq[child] - 1;
                    deg[parent] += edges;
                    deg[child] += edges;
                    freq[parent] = freq[child] = 1;
                }
            }
        }
        long ans = 0;
//        System.out.println(Arrays.toString(deg));
        for (int age = 0; age < MAXBIT; age++) {
            if (deg[age] > 0)
                ans += (long) age * deg[age];
        }
        out.println(ans - initial);
        out.close();
    }

    static int[] id;

    static int find(int u) {
        return id[u] == u ? u : (id[u] = find(id[u]));
    }

    static void unite(int u, int v) {
        if ((u = find(u)) != (v = find(v))) {
            id[v] = u;
        }
    }

    static class FastScanner {
        private int BS = 1 << 16;
        private char NC = (char) 0;
        private byte[] buf = new byte[BS];
        private int bId = 0, size = 0;
        private char c = NC;
        private double cnt = 1;
        private BufferedInputStream in;

        public FastScanner() {
            in = new BufferedInputStream(System.in, BS);
        }

        public FastScanner(String s) {
            try {
                in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
            } catch (Exception e) {
                in = new BufferedInputStream(System.in, BS);
            }
        }

        private char getChar() {
            while (bId == size) {
                try {
                    size = in.read(buf);
                } catch (Exception e) {
                    return NC;
                }
                if (size == -1) return NC;
                bId = 0;
            }
            return (char) buf[bId++];
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public int[] nextInts(int N) {
            int[] res = new int[N];
            for (int i = 0; i < N; i++) {
                res[i] = (int) nextLong();
            }
            return res;
        }

        public long[] nextLongs(int N) {
            long[] res = new long[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextLong();
            }
            return res;
        }

        public long nextLong() {
            cnt = 1;
            boolean neg = false;
            if (c == NC) c = getChar();
            for (; (c < '0' || c > '9'); c = getChar()) {
                if (c == '-') neg = true;
            }
            long res = 0;
            for (; c >= '0' && c <= '9'; c = getChar()) {
                res = (res << 3) + (res << 1) + c - '0';
                cnt *= 10;
            }
            return neg ? -res : res;
        }

        public double nextDouble() {
            double cur = nextLong();
            return c != '.' ? cur : cur + nextLong() / cnt;
        }

        public double[] nextDoubles(int N) {
            double[] res = new double[N];
            for (int i = 0; i < N; i++) {
                res[i] = nextDouble();
            }
            return res;
        }

        public String next() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c > 32) {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public String nextLine() {
            StringBuilder res = new StringBuilder();
            while (c <= 32) c = getChar();
            while (c != '\n') {
                res.append(c);
                c = getChar();
            }
            return res.toString();
        }

        public boolean hasNext() {
            if (c > 32) return true;
            while (true) {
                c = getChar();
                if (c == NC) return false;
                else if (c > 32) return true;
            }
        }
    }
    static void ASSERT(boolean assertion, String message) {
        if (!assertion) throw new AssertionError(message);
    }
    static void ASSERT(boolean assertion) {
        if (!assertion) throw new AssertionError();
    }
}