Problem:
Score : 400 points

Problem Statement

One day, Niwango-kun, an employee of Dwango Co., Ltd., found an integer sequence (a_1, ..., a_N) of length N.
He is interested in properties of the sequence a.

For a nonempty contiguous subsequence a_l, ..., a_r (1 \leq l \leq r \leq N) of the sequence a, its beauty is defined as a_l + ... + a_r. Niwango-kun wants to know the maximum possible value of the bitwise AND of the beauties of K nonempty contiguous subsequences among all N(N+1)/2 nonempty contiguous subsequences. (Subsequences may share elements.)

Find the maximum possible value for him.

Constraints

2 \leq N \leq 1000

1 \leq a_i \leq 10^9

1 \leq K \leq N(N+1)/2

All numbers given in input are integers

Input

Input is given from Standard Input in the following format:

N K
a_1 a_2 ... a_N

Output

Print the answer.

Sample Input 1

4 2
2 5 2 5

Sample Output 1

12

There are 10 nonempty contiguous subsequences of a. Let us enumerate them:

contiguous subsequences starting from the first element: \{2\}, \{2, 5\}, \{2, 5, 2\}, \{2, 5, 2, 5\}

contiguous subsequences starting from the second element: \{5\}, \{5, 2\}, \{5, 2, 5\}

contiguous subsequences starting from the third element: \{2\}, \{2, 5\}

contiguous subsequences starting from the fourth element: \{5\}

(Note that even if the elements of subsequences are equal, subsequences that have different starting indices are considered to be different.)

The maximum possible bitwise AND of the beauties of two different contiguous subsequences is 12.
This can be achieved by choosing \{5, 2, 5\} (with beauty 12) and \{2, 5, 2, 5\} (with beauty 14).

Sample Input 2

8 4
9 1 8 2 7 5 6 4

Sample Output 2

32

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.*;

public class Main {
	private static class Node {
		long val;
		String binStr;
		int tajuu = 1;

		public Node(long val, String binStr) {
			this.val = val;
			this.binStr = binStr;
		}
	}

	Comparator<Node> comp = new Comparator<Node>() {
		@Override
		public int compare(Node o1, Node o2) {
			if (o1.val < o2.val) {
				return 1;
			} else if (o1.val > o2.val) {
				return -1;
			} else {
				return 0;
			}
		}
	};
	int N, K;
	List<Long> a;
	List<Long> sums;
	Queue<Node> nodes;
	List<Node> targets;
	Node result;

	Main() {
		Scanner in = new Scanner(System.in);
		N = in.nextInt();
		K = in.nextInt();
		a = new ArrayList<>(N);
		for (int i = 0; i < N; ++i) {
			a.add(in.nextLong());
		}
		in.close();
		sums = new ArrayList<>(N * (N + 1) / 2);
	}

	long binStrAnd(String one, String another) {
		long addVal = 1L;
		long result = 0L;
		for (int i = 1; i <= Math.min(one.length(), another.length()); ++i) {
			int oneIndex = one.length() - i;
			int anotherIndex = another.length() - i;
			if (one.charAt(oneIndex) == '1' && another.charAt(anotherIndex) == '1') {
				result += addVal;
			}
			addVal *= 2;
		}
		return result;
	}

	long getMaxAndVal(List<String> binStrs) {
		long result = Long.MIN_VALUE;
		for (int i = 0; i < binStrs.size() - 1; ++i) {
			for (int j = 1; j < binStrs.size(); ++j) {
				long andVal = binStrAnd(binStrs.get(i), binStrs.get(j));
				result = Math.max(result, andVal);
			}
		}
		return result;
	}

	Node marge(Node one, Node another) {
		long val = binStrAnd(one.binStr, another.binStr);
		String binStr = Long.toBinaryString(val);
		Node result = new Node(val, binStr);
		result.tajuu = one.tajuu + another.tajuu;
		return result;
	}

	/**
	 * 先頭の多重度 >= K; それが答え 先頭の多重度 < K; 残りの要素とandを計算し，多重度を追加し，計算対象に加える
	 */
	void calc() {
		while (true) {
			Node head = targets.get(0);
			if (head.tajuu >= K) {
				// 答え
				result = head;
				break;
			} else {
				List<Node> list = new ArrayList<>(targets.size() - 1);
				for (int i = 1; i < targets.size(); ++i) {
					list.add(marge(head, targets.get(i)));
				}
				targets = list;
				Collections.sort(targets, comp);
			}
		}
	}

	void calcTargets() {
		this.targets = new ArrayList<>();
		int limitLength = this.nodes.peek().binStr.length();
		this.targets.add(this.nodes.poll());
		while (!this.nodes.isEmpty()) {
			Node node = this.nodes.poll();
			if (node.binStr.length() == limitLength) {
				targets.add(node);
			} else {
				if (this.targets.size() >= K) {
					// もう十分
					break;
				} else {
					limitLength = node.binStr.length();
					targets.add(node);
				}
			}
		}
	}

	void calcSums() {
		for (int i = 0; i < N; ++i) {
			long sum = 0;
			for (int j = i; j < N; ++j) {
				sum += a.get(j);
			}
			sums.add(sum);
		}
		Collections.sort(sums);

		// Nodeに格納する
		this.nodes = new PriorityQueue<Node>(comp);
		for (Long sum : sums) {
			String binStr = Long.toBinaryString(sum);
			this.nodes.add(new Node(sum, binStr));
		}
	}

	public static void main(String[] args) {
		Main ins = new Main();
		ins.calcSums();
		ins.calcTargets();
		ins.calc();
		System.out.println(ins.result.val);
	}

}