//数的不重复组合 dfs dp
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
int nn[25],ans=0,zx=0x7fffffff,zd,bt[25],ddp[2005],zz[105];
/*
n 有 一共有n个砝码 m 要拿走m个砝码
nn数组为 存放全部砝码的
ans 存放最终答案
zx表示 所有砝码最小的那个
zd表示 所有砝码最大的那个
bt数组 存放 被选中的 n-m个砝码
ddp数组 选完 n-m个砝码后,01背包,dp出当前选出的砝码 能拼出的所有长度
zz数组 桶排数组
*/
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a>b?b:a;}
void dp(){
memset(ddp,0,sizeof(ddp));
ddp[0]=1;int sum=0;
for(int i=1;i<=n-m;i++)sum+=bt[i];
for(int i=1;i<=n-m;i++)
for(int j=sum;j>=bt[i];j--)
ddp[j]|=ddp[j-bt[i]];//如果 j-bt[i]能被 选出来的数构造出来 则j也可以
int test=0;
for(int i=1;i<=sum;i++)if(ddp[i])test++;
ans=max(test,ans);
}
void dfs(int x,int p){
if(x>n-m){
dp();
return;
}
for(int i=p;i>=zx;i--){
if(zz[i]){
zz[i]--;
bt[x]=i;
dfs(x+1,i);
zz[i]++;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){scanf("%d",&nn[i]);zx=min(nn[i],zx);zd=max(zd,nn[i]);zz[nn[i]]++;}
dfs(1,zd);
printf("%d",ans);
return 0;
}