Discription

You are given an array a consisting of n integers, and additionally an integer m. You have to choose some sequence of indices b1, b2, ..., bk (1 ≤ b1 < b2 < ... < bk ≤ n) in such a way that the value of Codeforces 888E Maximum Subsequence is maximized. Chosen sequence can be empty.

Print the maximum possible value of Codeforces 888E Maximum Subsequence.

Input

The first line contains two integers n and m (1 ≤ n ≤ 35, 1 ≤ m ≤ 109).

The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ 109).

Output

Print the maximum possible value of Codeforces 888E Maximum Subsequence.

Example

Input
4 4
5 2 4 1
Output
3
Input
3 20
199 41 299
Output
19

Note

In the first example you can choose a sequence b = {1, 2}, so the sum Codeforces 888E Maximum Subsequence is equal to 7 (and that's 3 after taking it modulo 4).

In the second example you can choose a sequence b = {3}.

 

(感觉看到n<=35的第一反应已经是折半搜索了hhh)

显然可以先搜出前n/2个数和后面剩的数可以得到的所有子集(包括空集)的结果(对m取模后)。

然后答案肯定就是从前面选一个子集,后面再选一个子集,把两个拼起来。

假设我们在前n/2中选的子集的权值是s,那么怎么在后面的数中找最优子集呢?

假设我们在后面的数中找的子集的权值是p,那么有两种情况:

1.s+p<m

2.m<=s+p<2*m

对于第一种情况,我们找到<m-s的最大的p即可;

对于第二种情况,我们找到最大的p即可(肯定得减掉一个m,所以p肯定是越大越好)

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#define ll long long
#define maxn 500005
using namespace std;
int a[maxn],n,m,b[maxn];
int num[105],tot,haf,ha;
int ans=0;

void dfs1(int x,int sum){
    if(sum>=ha) sum-=ha;
    if(x==haf){
        a[++n]=sum;
        return;
    }
    dfs1(x+1,sum);
    dfs1(x+1,sum+num[x+1]);
}

void dfs2(int x,int sum){
    if(sum>=ha) sum-=ha;
    if(x==tot){
        b[++m]=sum;
        return;
    }
    dfs2(x+1,sum);
    dfs2(x+1,sum+num[x+1]);
}

int main(){
    scanf("%d%d",&tot,&ha);
    for(int i=1;i<=tot;i++){
        scanf("%d",num+i);
        if(num[i]>=ha) num[i]-=num[i]/ha*ha;
    }
    haf=tot>>1;
    
    dfs1(0,0);
    dfs2(haf,0); 
    
    sort(a+1,a+n+1);
    sort(b+1,b+m+1);
    
    for(int i=1;i<=n;i++){
        int pos=lower_bound(b+1,b+m+1,ha-a[i])-b;
        ans=max(ans,a[i]+b[pos-1]);
        ans=max(ans,a[i]+b[m]-ha);
    }
    
    printf("%d\n",ans);
    return 0;
}

 

相关文章: