#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <fstream>
#include <bitset>
#include <cassert>
#include <functional>
#include <cstring>
#include <ctime>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#define sec second
#define fir first
#define pb push_back
#define mp make_pair
#define REP(i , n) for (int i = 0 ; i < (n) ; i++)
#define BACK(i , n) for (int i = (n) - 1 ; i >= 0 ; i--)
using namespace std;
using vi = vector<int>;
using vii = vector<vi>;
using pii = pair<int , int>;
using ll = long long;
using ld = long double;
const int MAX = 1e9 , MIN = - MAX , MOD = 1e9 + 7;
const ll MAX_LL = 1e18 , MIN_LL = -MAX_LL;
int N , T , ans = 0 , arr[40];
vector<int> vec = {0};
void gener(int tot , int idx){
    if (tot > T)
        return;
    if (idx == N)
        vec.push_back(tot);
    else if (idx == N / 2){
        int l = 0 , r = vec.size() - 1;
        while(l < r){
            int mid = (l + r >> 1) + (l + r & 1);
            if (vec[mid] + tot > T)
                r = mid - 1;
            else
                l = mid;
        }
        ans = max(ans , vec[l] + tot);
    }
    else{
        gener(tot + arr[idx] , idx + 1);
        gener(tot , idx + 1);
    }
}
int main(){
    cin >> N >> T;
    REP(i , N)
        cin >> arr[i];
    if (N == 1)
        return 0 * printf("%d\n" , arr[0] <= T ? arr[0] : 0);
    gener(arr[N / 2] , N / 2 + 1);
    gener(0 , N / 2 + 1);
    sort(begin(vec) , end(vec));
    gener(0 , 0);
    cout << ans << endl;
}

//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("Ofast,unroll-loops")
//#pragma GCC target("avx,avx2,fma")
#include <algorithm>
#include <array>
#include <cassert>
//#include <chrono>
#include <cmath>
//#include <cstring>
//#include <functional>
//#include <iomanip>
#include <iostream>
#include <map>
//#include <numeric>
//#include <queue>
//#include <random>
#include <set>
#include <vector>
using namespace std;
#define FAST  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
//#include <ext/pb_ds/assoc_container.hpp> 
//#include <ext/pb_ds/tree_policy.hpp> 
//using namespace __gnu_pbds; 
#define int long long 
#define ll int
#define all(a) a.begin(),a.end()    
#define rev(a) a.rbegin(),a.rend()    
//typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; //less_equal for multiset
#define ar array
#define pb push_back
#define fi(a,b) for(int i=a;i<(b);i++)
#define fj(a,b) for(int j=a;j<(b);j++)
#define fk(a,b) for(int k=a;k<(b);k++)
const double pi=acosl(-1);



void solve()
{
    int n,t;
    cin>>n>>t;
    int mid=n/2;
    vector<int> a(n);
    fi(0,n)
    {
        cin>>a[i];
    }
    set<int> s;
    fi(0,(1<<mid))
    {
        int sum=0;
        fj(0,mid)
        {
            if(i&(1LL<<j))
                sum+=a[j];
        }
        if(sum<t)
        {
            s.insert(sum);
        }
    }
    mid=n-mid;
    s.insert(0);
    int ans=0;
    fi(0,(1<<mid))
    {
        int sum=0;
        fj(0,mid)
        {
            if(i&(1LL<<j))
                sum+=a[j+n/2];
        }
        if(sum>t) continue;
        auto it=s.upper_bound(t-sum);
        it--;
        ans=max(ans,sum+*it);
    }
    cout<<ans<<'\n';
    
    
}

signed main()
{
    FAST;
    int tt=1;
    //cin>>tt;    
    while(tt--)
    {
        solve();
    }    
}










//int dx[] = {+1,-1,+0,+0,-1,-1,+1,+1}; // Eight Directions
//int dy[] = {+0,+0,+1,-1,+1,-1,-1,+1}; // Eight Directions
//int dx[]= {-2,-2,-1,1,-1,1,2,2}; // Knight moves
//int dy[]= {1,-1,-2,-2,2,2,-1,1}; // Knight moves
// For (a^b)%mod, where b is large, replace b by b%(mod-1)..{because we solve this by introducing log ..do same for general cases}
// a+b = (a|b)+(a&b)
// a+b = 2*(a&b)+(a^b)
