//数的不重复组合 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;
}