You are given n numbers a1, a2, ..., an. You can perform at most k operations. For each operation you can multiply one of the numbers by x. We want to make <image> as large as possible, where <image> denotes the bitwise OR. 

Find the maximum possible value of <image> after performing at most k operations optimally.

Input

The first line contains three integers n, k and x (1 ≤ n ≤ 200 000, 1 ≤ k ≤ 10, 2 ≤ x ≤ 8).

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

Output

Output the maximum value of a bitwise OR of sequence elements after performing operations.

Examples

Input

3 1 2
1 1 1


Output

3


Input

4 2 3
1 2 4 8


Output

79

Note

For the first sample, any possible choice of doing one operation will result the same three numbers 1, 1, 2 so the result is <image>. 

For the second sample if we multiply 8 by 3 two times we'll get 72. In this case the numbers will become 1, 2, 4, 72 so the OR value will be 79 and is the largest possible result.
import java.io.*;
import java.util.*;

import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.max;
import static java.lang.Long.parseLong;
import static java.lang.Math.abs;
import static java.lang.System.exit;


public class Main {

    static BufferedReader in;
    static PrintWriter out;
    static StringTokenizer tok;

    int n, k, x, a[];
    long dp[][];

    long myPow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if (n % 2 == 1) res *= a;
            n /= 2;
            a *= a;
        }
        return res;
    }


    long f(int i, int k) {
        if (i == n) return 0;
        if (dp[k][i] != -1) return dp[k][i];

        long ans = f(i + 1, k) | a[i];
        for (int j = 1; j <= k; j++) {
            ans = max(ans, f(i + 1, k - j) | a[i] * myPow(x, j));
        }
        return dp[k][i] = ans;
    }

    long fr(int i, int k) {
        if (i < 0) return 0;
        if (dp[k][i] != -1) return dp[k][i];

        long ans = fr(i - 1, k) | a[i];
        for (int j = 1; j <= k; j++) {
            ans = max(ans, fr(i - 1, k - j) | a[i] * myPow(x, j));
        }
        return dp[k][i] = ans;
    }

    void solve() throws Exception {
        n = nextInt();
        k = nextInt();
        x = nextInt();
        a = na(n);
        dp = new long[k+1][n];
        for (int i = 0; i < k+1; i++)
            Arrays.fill(dp[i], -1);
        long ans = f(0, k);
        for (int i = 0; i < k+1; i++)
            Arrays.fill(dp[i], -1);
        ans = max(ans, fr(n - 1, k));
        out.println(ans);
    }


    // call it like this: lower_bound(a, x + 1) ( /!\ + 1 )
    public static int lower_bound(int[] a, int v) {
        int low = -1, high = a.length;
        while (high - low > 1) {
            int h = high + low >>> 1;
            if (a[h] >= v) {
                high = h;
            } else {
                low = h;
            }
        }
        return high;
    }

    static class LCA {
        public int[][] par;
        public int[] depth;
        public final int LOG;
        public final int n;
        public ArrayList<Integer>[] a;

        public LCA(int n, ArrayList<Integer>[] aa) {
            a = aa;
            this.n = n;
            LOG = log2(n) + 1;
            par = new int[n][LOG];
            depth = new int[n];
        }

        public void build(int u) {
            dfs(u, -1, 0);
            for (int j = 1; j < LOG; j++)
                for (int i = 0; i < n; i++) {
                    par[i][j] = -1;
                    if (par[i][j - 1] != -1) par[i][j] = par[par[i][j - 1]][j - 1];
                }
        }

        public void dfs(int cur, int p, int l) {
            par[cur][0] = p;
            depth[cur] = l;
            for (int i : a[cur]) if (i != p) dfs(i, cur, l + 1);
        }

        public int findLcaOf(int u, int v) {
            if (depth[u] < depth[v]) {
                int t = u;
                u = v;
                v = t;
            }
            int dis = depth[u] - depth[v];
            while (dis > 0) {
                int raise = log2(dis);
                u = par[u][raise];
                dis ^= 1 << raise;
            }
            if (u == v) return u;
            for (int i = LOG - 1; i >= 0; i--) {
                if (par[u][i] != -1 && par[u][i] != par[v][i]) {
                    u = par[u][i];
                    v = par[v][i];
                }
            }
            return par[u][0];
        }

        public int dist(int u, int v) {
            return depth[u] + depth[v] - (depth[findLcaOf(u, v)] << 1);
        }

        public int log2(int i) {
            int cnt = -1;
            while (i > 0) {
                i >>= 1;
                cnt++;
            }
            return cnt;
        }

        int getDepth(int u) {
            return depth[u];
        }

        int getKthParent(int u, int k) {
            return par[u][k];
        }

    }

    private String getFraction(int a, int b) {
        assert b != 0;
        String sign = (a > 0 && b > 0) || (a < 0) && (b < 0) ? "+" : "-";
        a = abs(a);
        b = abs(b);
        int gcd = gcd(a, b);
        return sign + (a / gcd) + "/" + (b / gcd);
    }

    private int gcd(int a, int b) {
        while (b > 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }

    private int lcm(int a, int b) {
        return a * (b / gcd(a, b));
    }


    int[] sort(int[] arr) {
        sort(arr, 0, arr.length - 1);
        return arr;
    }

    void sort(int arr[], int l, int r) {
        if (l < r) {
            int m = (l + r) / 2;
            sort(arr, l, m);
            sort(arr, m + 1, r);
            merge(arr, l, m, r);
        }
    }

    void merge(int arr[], int l, int m, int r) {
        int n1 = m - l + 1;
        int n2 = r - m;
        int L[] = new int[n1];
        int R[] = new int[n2];
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];
        int i = 0, j = 0;
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }


    // return all subsets in range 0..n-1 [ {0}, {1,4}, {2, 5}, ..., {1,2,..,n}, {n} ]
    List<List<Integer>> gen_subsets(int n) {
        List<List<Integer>> h = new ArrayList<>();
        for (int mask = 0; mask < (1 << n); mask++) {
            List<Integer> tmp = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                if ((mask & (1 << i)) != 0) {
                    tmp.add(i);
                }
            }
            h.add(tmp);
        }
        return h;
    }

    public static class Dijkstra {
        int n;
        long[] dist;
        ArrayList<Pair>[] list;
        final long inf = Long.MAX_VALUE / 10;

        public Dijkstra(int n) {
            this.n = n;
            this.dist = new long[n];
            list = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                list[i] = new ArrayList<>();
                dist[i] = inf;
            }
        }

        public void initialize() {
            Arrays.fill(dist, inf);
        }

        public void addEdge(int from, int to, long cost) {
            list[from].add(new Pair(to, cost));
            list[to].add(new Pair(from, cost));
        }

        public void setSource(int s) {
            PriorityQueue<Pair> Q = new PriorityQueue<>();
            Q.add(new Pair(s, 0));
            boolean[] used = new boolean[n];
            while (!Q.isEmpty()) {
                Pair p = Q.poll();
                if (used[p.to]) continue;
                used[p.to] = true;
                dist[p.to] = p.cost;
                for (Pair edge : list[p.to]) {
                    Q.add(new Pair(edge.to, p.cost + edge.cost));
                }
            }
        }

        public long getShrtestDistanceFromSource(int to) {
            return dist[to];
        }

        class Pair implements Comparable<Pair> {
            int to;
            long cost;

            Pair(int to, long cost) {
                this.to = to;
                this.cost = cost;
            }

            public int compareTo(Pair p) {
                return Long.compare(cost, p.cost);
            }
        }
    }

    public static long pow(long a, long n, long mod) {
        long ret = 1;
        int x = 63 - Long.numberOfLeadingZeros(n);
        for (; x >= 0; x--) {
            ret = ret * ret % mod;
            if (n << 63 - x < 0)
                ret = ret * a % mod;
        }
        return ret;
    }

    class BIT {
        int BITree[];

        public BIT(int n) {
            BITree = new int[n + 1];
            for (int i = 1; i <= n; i++)
                BITree[i] = 0;
        }

        // sum [l, r]
        int getSum(int l, int r) {
            return getSum(r) - getSum(l - 1);
        }

        // sum [0, index]
        int getSum(int index) {
            int sum = 0;
            index = index + 1;
            while (index > 0) {
                sum += BITree[index];
                index -= index & (-index);
            }
            return sum;
        }

        // add val to range [l, r]
        void updateRange(int n, int val, int l, int r) {
            updateBIT(n, l, val);
            updateBIT(n, r + 1, -val);
        }

        void updateBIT(int n, int index, int val) {
            index = index + 1;
            while (index <= n) {
                BITree[index] += val;
                index += index & (-index);
            }
        }
    }

    public static boolean nextPermutation(Integer[] a) {
        int n = a.length;
        int i;
        for (i = n - 2; i >= 0 && a[i] >= a[i + 1]; i--) ;
        if (i == -1)
            return false;
        int j;
        for (j = i + 1; j < n && a[i] < a[j]; j++) ;
        int d = a[i];
        a[i] = a[j - 1];
        a[j - 1] = d;
        for (int p = i + 1, q = n - 1; p < q; p++, q--) {
            d = a[p];
            a[p] = a[q];
            a[q] = d;
        }
        return true;
    }

    void print(Object x) {
        out.print(String.valueOf(x));
        out.flush();
    }

    void println(Object x) {
        out.println(String.valueOf(x));
        out.flush();
    }

    private class MapCount<K> {
        Map<K, Integer> map;

        MapCount() {
            map = new HashMap<>();
        }

        public void add(K key) {
            map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
        }

        public Integer getCount(K key) {
            return map.getOrDefault(key, 0);
        }

        public Set<K> keySet() {
            return map.keySet();
        }
    }

    // for Map with custom key/value, override toString in your custom class
    void printMap(Map map) {
        if (map.keySet().size() == 0) return;
        Object firstValue = map.keySet().iterator().next();
        if (map.get(firstValue) instanceof Queue || map.get(firstValue) instanceof List) {
            for (Object key : map.keySet()) {
                out.print(String.valueOf(key) + ": ");
                Collection values = (Collection) map.get(key);
                for (Object value : values) out.print(String.valueOf(value) + " ");
                out.println();
            }
        } else if (map.get(firstValue).getClass().isArray()) {
            for (Object key : map.keySet()) {
                out.print(String.valueOf(key) + ": ");
                Object[] values = (Object[]) map.get(key);
                for (Object value : values) out.print(String.valueOf(value) + " ");
                out.println();
            }
        } else {
            for (Object key : map.keySet()) {
                out.println(String.valueOf(key) + ": " + map.get(key));
            }
        }
    }

    private int[] na(int n) throws IOException {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = nextInt();
        return a;
    }

    private long[] nal(int n) throws IOException {
        long[] a = new long[n];
        for (int i = 0; i < n; i++) a[i] = nextLong();
        return a;
    }

    int nextInt() throws IOException {
        return parseInt(next());
    }

    long nextLong() throws IOException {
        return parseLong(next());
    }

    double nextDouble() throws IOException {
        return parseDouble(next());
    }

    String next() throws IOException {
        while (tok == null || !tok.hasMoreTokens()) {
            tok = new StringTokenizer(in.readLine());
        }
        return tok.nextToken();
    }

    public static void main(String[] args) throws Exception {
        try {
            boolean isLocal = false;
            if (isLocal) {
                in = new BufferedReader(new FileReader("solution.in"));
                out = new PrintWriter(new BufferedWriter(new FileWriter("solution.out")));
            } else {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(new OutputStreamWriter(System.out));
            }

            //long lStartTime = System.currentTimeMillis();
            new Main().solve();
            //long lEndTime = System.currentTimeMillis();
            //out.println("Elapsed time in seconds: " + (double)(lEndTime - lStartTime) / 1000.0);
            in.close();
            out.close();
        } catch (Throwable e) {
            e.printStackTrace();
            exit(1);
        }
    }
}