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 C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include <cstdio>
#include <bitset>
#include <algorithm>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <string.h>
#include <cmath>
#include <utility>
#include <functional>
#include <map>
#include <set>
#include <cctype>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <cstring>
using namespace std;
using ll = long long;
#define ALL(a) (a).begin(), (a).end()

#define FOR(i, a, b) for (long long int i = (a); i <= (b); i++)
#define RFOR(i, a, b) for (long long int i = (a); i >= (b); i--)
#define MOD 1000000007
#define LLONG_MAXs 9223372036854775800 / 2

#define ALL(a) (a).begin(), (a).end()

#include <iostream>
#include <cmath>
using namespace std;

bool isPrimeNum(ll x)
{ // 素数である場合 true を返す
    if (x <= 1)
    { // 1以下である場合は素数でないことがすぐにわかる
        return false;
    }
    // sqrt( double型 ) は引数の平方根を double型で返すので、int型でキャスト
    int n = (int)sqrt((double)x);
    for (int i = 2; i <= n; i++)
    {
        if (x % i == 0)
        { // 割り切る整数がある場合、即判定終了
            return false;
        }
    }
    return true; // 割り切る整数がない場合、素数である
}

ll myPow(ll x, ll n, ll m)
{
    if (n == 0)
        return 1;
    if (n % 2 == 0)
        return myPow(x * x % m, n / 2, m);
    else
        return x * myPow(x, n - 1, m) % m;
}

constexpr ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
constexpr ll lcm(ll a, ll b) { return a * b / gcd(a, b); }
constexpr ll abs(ll a, ll b)
{
    if (a >= b)
        return a - b;
    if (a < b)
        return b - a;
}
constexpr double dabs(double a, double b)
{
    if (a >= b)
        return a - b;
    if (a < b)
        return b - a;
}
constexpr ll min(ll a, ll b)
{
    if (a >= b)
        return b;
    if (a < b)
        return a;
}

constexpr ll max(ll a, ll b)
{
    if (a >= b)
        return a;
    if (a < b)
        return b;
}

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int dx8[8] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy8[8] = {0, 1, 0, -1, 1, 1, -1, -1};

class UnionFind
{
public:
    //親の番号を格納する。親だった場合は-(その集合のサイズ)
    vector<int> Parent;

    //作るときはParentの値を全て-1にする
    //こうすると全てバラバラになる
    UnionFind(int N)
    {
        Parent = vector<int>(N, -1);
    }

    //Aがどのグループに属しているか調べる
    int root(int A)
    {
        if (Parent[A] < 0)
            return A;
        return Parent[A] = root(Parent[A]);
    }

    //自分のいるグループの頂点数を調べる
    int size(int A)
    {
        return -Parent[root(A)]; //親をとってきたい]
    }
    bool issame(int x, int y)
    {
        return root(x) == root(y);
    }
    //AとBをくっ付ける
    bool connect(int A, int B)
    {
        //AとBを直接つなぐのではなく、root(A)にroot(B)をくっつける
        A = root(A);
        B = root(B);
        if (A == B)
        {
            //すでにくっついてるからくっ付けない
            return false;
        }

        //大きい方(A)に小さいほう(B)をくっ付けたい
        //大小が逆だったらひっくり返しちゃう。
        if (size(A) < size(B))
            swap(A, B);

        //Aのサイズを更新する
        Parent[A] += Parent[B];
        //Bの親をAに変更する
        Parent[B] = A;

        return true;
    }
};

long long fac[510000], finv[510000], inv[510000];

// テーブルを作る前処理
void COMinit()
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < 510000; i++)
    {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

// 二項係数計算
long long COM(int n, int k)
{
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

long long modinv(long long a, long long m)
{
    long long b = m, u = 1, v = 0;
    while (b)
    {
        long long t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= m;
    if (u < 0)
        u += m;
    return u;
}
string replaceAll(string &replacedStr, string from, string to)
{
    unsigned int pos = replacedStr.find(from);
    int toLen = to.length();

    if (from.empty())
    {
        return replacedStr;
    }

    while ((pos = replacedStr.find(from, pos)) != std::string::npos)
    {
        replacedStr.replace(pos, from.length(), to);
        pos += toLen;
    }
    return replacedStr;
}

void yn(bool flag)
{
    if (flag)
    {
        cout << "Yes" << endl;
    }
    else
    {
        cout << "No" << endl;
    }
    return;
}
void YN(bool flag)
{
    if (flag)
    {
        cout << "YES" << endl;
    }
    else
    {
        cout << "NO" << endl;
    }
    return;
}

std::vector<ll> enum_div(ll n) //nの約数を列挙
{
    std::vector<ll> ret;
    for (ll i = 1; i * i <= n; ++i)
    {
        if (n % i == 0)
        {
            ret.push_back(i);
            if (i != 1 && i * i != n)
            {
                ret.push_back(n / i);
            }
        }
    }
    ret.push_back(n);
    return ret;
}

void Ssort(int no, char *month[])
{
    int i, j;
    char *temp;
    for (i = 0; i < no; i++)
    {
        for (j = i + 1; j < no; j++)
        {
            if (strcmp((month[i]), (month[j])) > 0)
            {
                temp = *(month + i);
                *(month + i) = *(month + j);
                *(month + j) = temp;
            }
        }
    }
}

// グラフセット
struct Edge
{
    ll to;     // 辺の行き先
    ll weight; // 辺の重み
    Edge(int t, int w) : to(t), weight(w) {}
};
//using Graph = vector<vector<Edge>>;
using Graph = vector<vector<int>>;

int main()
{

    ll N, K;
    cin >> N >> K;
    ll A[N];
    ll sum[N + 1];
    vector<ll> B;
    ll keta[45] = {};
    sum[0] = 0;
    FOR(i, 0, N - 1)
    {
        cin >> A[i];
        sum[i + 1] = sum[i] + A[i];
    }

    FOR(i, 0, N - 1)
    {
        FOR(j, i, N - 1)
        {
            ll tmp = sum[j + 1] - sum[i];
            B.push_back(tmp);
        }
    }

    ll ans = 0;
    ll index = -1;
    RFOR(k, 45, 0)
    {
        ll c = 0;
        FOR(i, 0, N * (N - 1) - 1)
        {
            //cout << B[i] << endl;
            if (B[i] & (1LL << k))
            //if(true)
            {
                //cout << "hit" << B[i] << " " << k << endl;
                //cout << "cmp" << (ans & B[i]) << " " << ans << endl;

                //if ((ans & B[i]) == ans)
                if (true)
                {
                    c++;
                }
            }
        }
        //cout << "res" << k << " " << c << endl;

        if (c >= K)
        {

            // ll kaizyou = k;
            //ll tasu = 1;
            // FOR(ii, 0, kaizyou - 1)
            // {
            //     tasu *= 2;
            // }
            ans += 5;
        }
    }
    cout << ans << endl;

    return 0;
}