#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define pii pair<int, int>
#define endl '\n'
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define vvl vector<vl>
#define vld vector<ld>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vpii vector<pii>
#define vvpii vector<vpii>
#define vpll vector<pll>
#define rep(s, l, r) for (int s = l; s < r; s++)
#define per(s, r, l) for (int s = r - 1; s >= l; s--)
#define all(x) x.begin(), x.end()
typedef long long ll;
typedef long double ld;
using namespace std;
template<class T> using minheap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> void setmax(T& a, T b) { a = max(a, b); };
template<typename T> void setmin(T& a, T b) { a = min(a, b); };
template<typename T> bool in(T lo, T v, T hi) { return lo <= v && v <= hi; };

template<ll MOD>
struct ModInt {
  ll x = 0;
  ModInt() { x = 0; }
  ModInt(ll _x) {
    x = _x;
    if (x >= MOD || x <= -MOD) x %= MOD;
    if (x < 0) x += MOD;
  }
  friend ModInt operator+(ModInt a, ModInt b) {
    return ModInt(a.x + b.x);
  }
  friend ModInt operator-(ModInt a, ModInt b) {
    return ModInt(a.x - b.x);
  }
  friend ModInt operator*(ModInt a, ModInt b) {
    return ModInt(a.x * b.x);
  }
  friend ModInt operator/(ModInt a, ModInt b) {
    return a * inv(b);
  }
  friend ModInt power(ModInt a, ll b) {
    if (b == 0) return 1;
    ModInt c = power(a, b / 2);
    return c * c * ((b & 1) ? a : 1);
  }
  friend ModInt inv(ModInt a) {
    // this only works for nonzero elements
    return power(a, MOD - 2);
  }
  friend ostream& operator<<(ostream &os, const ModInt a) {
    os << a.x;
    return os;
  }
};

using mint = ModInt<1000000007>;
using vm = vector<mint>;
using vvm = vector<vm>;

struct Solution {
  vl get(vl x) {
    int n = x.size();
    vl res(1 << n);
    rep(mask, 0, (1 << n)) {
      rep(i, 0, n) if (mask >> i & 1) res[mask] += x[i];
    }
    sort(all(res));
    res.resize(unique(all(res)) - res.begin());
    return res;
  }
  void solve() {
    int n;
    cin >> n;
    ll t;
    cin >> t;
    vl a(n);
    rep(i, 0, n) cin >> a[i];
    if (n == 1) {
      int res = a[0] < t ? a[0] : 0;
      cout << res << endl;
      return;
    }
    int h = n / 2;
    vl x, y;
    rep(i, 0, n) {
      if (i < h) x.pb(a[i]);
      else y.pb(a[i]);
    }
    vl u = get(x);
    vl v = get(y);
    sort(all(u));
    sort(all(v));
    ll best = 0;
    for (ll tt : u) {
      if (tt > t) break;
      setmax(best, tt);
      ll rem = t - tt;
      auto it = upper_bound(all(v), rem);
      --it;
      setmax(best, tt + *it);
    }
    for (ll tt : v) if (tt <= t) setmax(best, tt);
    cout << best << endl;
  }
};

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int t = 1;
  while (t--) {
    Solution s;
    s.solve();
  }

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define sz(v) (int)v.size() 
#define all(v) v.begin(), v.end()
void dbg_out() { cerr << "\b\b]\n"; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T){ cerr << H << ", "; dbg_out(T...);}
#define watch(...) cerr << "[" << #__VA_ARGS__ << "]: [", dbg_out(__VA_ARGS__)


/****************************** CODE IS HERE ***********************************/


int main(){
    ios_base::sync_with_stdio(false); cin.tie(nullptr);

    int n, m; cin >> n >> m;
    vector <int> A(n);
    for (int &i: A) cin >> i;
    int k1 = (n + 1) / 2, k2 = n / 2;
    
    vector <ll> X, Y;
    for (int i = 0; i < (1 << k1); ++i) {
        ll sum = 0;
        for (int j = 0; j < k1; ++j) {
            if (i >> j & 1) {
                sum += A[j];
            }
        }
        if (sum <= m) {
            X.push_back(sum);
        }
    }


    for (int i = 0; i < (1 << k2); ++i) {
        ll sum = 0;
        for (int j = 0; j < k2; ++j) {
            if (i >> j & 1) {
                sum += A[j + k1];
            }
        }
        if (sum <= m) {
            Y.push_back(sum);
        }
    }


    sort(all(Y));

    ll ans = 0;

    for (ll i: X) {
        int pos = lower_bound(all(Y), m - i) - Y.begin();
        if (pos >= sz(Y) or Y[pos] + i > m) pos--;
        ans = max(ans, i + Y[pos]);
    
    }

    cout << ans;

    return 0;
}

/*

--------- Meet in the middle Technique ---------------
Like brute force but here we divide the original array into two parts and apply the brute forces individually and merge them.


*/