#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for(ll i = 0;i < n;i++)
#define ll long long
#define MOD 1000000007LL
//#define MOD 998244353LL
using vi = vector<ll>; // intの1次元の型に vi という別名をつける
using vvi = vector<vi>; // intの2次元の型に vvi という別名をつける
using vvvi = vector<vvi>; // intの2次元の型に vvi という別名をつける
const ll llMAX=9223372036854775807LL; 
const ll llMIN=-9223372036854775808LL;

void myprint1D(vi &data)
{
  REP(i,data.size())
    cout<<data[i]<<" ";
  cout<<endl;
}

//配列を[y][x]で表示
void myprint2D_T(vvi &data)
{
  REP(i,data.size())
    myprint1D(data[i]);
}

//配列を[x][y]で表示
void myprint2D(vvi &data)
{
  ll l1=data.size();
  ll l2=data[0].size();
  REP(j,l2){
    REP(i,l1)
      cout<<data[i][j]<<" ";
    cout<<endl;
  }
}

//print(a,b...)って使い方
void print1(ll a){cout<<a<<endl;}
void print2(ll a,ll b){cout<<a<<" "<<b<<endl;}
void print3(ll a,ll b,ll c){cout<<a<<" "<<b<<" "<<c<<endl;}
void print4(ll a,ll b,ll c,ll d){cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;}
void print5(ll a,ll b,ll c,ll d,ll e){cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<endl;}


ll n,k,x,y;

int main(){
  ll ans=0;
  cin >> n >> k;
  vi a(40,0),b(1048576),c(1048576);
  REP(i,n) cin>>a[i];

  REP(i,1048576){
    REP(j,20){
      if ((i>>j)%2==1)b[i]+=a[j];
    }
  }
  REP(i,1048576){
    REP(j,20){
      if ((i>>j)%2==1)c[i]+=a[j+20];
    }
  }


  sort(b.begin(), b.end());
  sort(c.begin(), c.end());


  REP(i,1048576){
    ll bb=b[i];
    if (k<bb)continue;
    if (k==bb){ans=k;break;}
    ll y=k-bb;
    //y未満の数の個数を求めたい
    auto Iter = lower_bound(c.begin(),c.end(), y);
    ll ynum=(Iter-c.begin());
    if (ynum==0){
      continue;
    }
    ans=max(c[ynum-1]+bb,ans);
    if (c[ynum]==y){ans=k;break;}
  }






  cout<<ans<<endl;
  return 0;
}
#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
#include<algorithm>//next_permutation
#define rep(i,n) for (int i = 0;i < (n);i++)
#define all(v) v.begin(),v.end()
#define dec(n) cout << fixed << setprecision(n);
#define large "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define small "abcdefghijklmnopqrstuvwxyz"
using namespace std;
using ll = long long;
using P = pair<ll,ll>;
using vl = vector<ll>;
using vvl = vector<vl>;

ll gcd(ll a,ll b){
  if(b == 0) return a;
  return gcd(b , a % b);
}

const ll MOD = 1000000007;
const ll MAX = 2000001;

ll mod(ll a){
  return a % MOD;
}

ll lcm(ll a,ll b){
  return (a*b)/gcd(a,b);
}


struct UnionFind {
    //自身が親であれば、その集合に属する頂点数に-1を掛けたもの
    //そうでなければ親のid
    vector<int> r;
    vector<map<int,int>> mp;
 
    UnionFind(int N) {
        r = vector<int>(N, -1);
        mp = vector<map<int,int>>(N);
    }
 
    int root(int x) {
        if (r[x] < 0) return x;
        return r[x] = root(r[x]);
    }
 
    bool unite(int x, int y) {
        x = root(x);
        y = root(y);
        if (x == y) return false;
        if (abs(-r[x]) > abs(-r[y])) swap(x, y);
        //xの集合の方が要素数が小さい
        for(auto p : mp[x]){
          mp[y][p.first] += p.second;
        }

        mp[x] = map<int,int>();
        r[y] += r[x];
        r[x] = y;
        return true;
    }
 
    int size(int x) {
        return -r[root(x)];
    }
  
};




int main(){
  ll a,b,c,d; cin >> a >> b >> c >> d;

  cout << a*d - b*c << endl;

}