#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")

#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ll long long 
#define REP(i, a, b) for (ll i = a; i < b; i++)
#define REPI(i, a, b) for (ll i = b - 1; i >= a; i--)
#define i_os ios::sync_with_stdio(0);  cin.tie(0);  cout.tie(0);
#define INF (ll)1e18 + 100
#define endl "\n"
#define p0(a) cout << a << " "
#define p1(a) cout << a << endl
#define p2(a, b) cout << a << " " << b << endl
#define p3(a, b, c) cout << a << " " << b << " " << c << endl
#define p4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl
// SOME BITMASK KNOWLEDGE
// 1)x & (x - 1):sets the last one bit of x to zero
// power of two exactly when x & (x − 1) = 0.
// 2)x & -x:sets all the one bits to zero, except last one bit
// 3)x | (x - 1):inverts all the bits after the last one bit
#define o_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
#define o_setll tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
typedef tree<pair<ll, ll>,null_type,less<pair<ll, ll>>,rb_tree_tag,tree_order_statistics_node_update> indexed_set;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> indexed_set1;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> indexed_set2;
//1. order_of_key(k) : number of elements strictly lesser than k
//2. find_by_order(k) : k-th element in the set
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);

ll power(ll a,ll n,ll c){
    if(n == 0) return 1 % c;
    ll s = power(a,n/2,c);
    s = (s * s) % c;
    if(n % 2) s = (s * a) % c;
    return s;
}

int main()
{
    ll n,t;
    cin>>n>>t;
    ll arr1[n/2],arr2[n-n/2];
    REP(i,0,n/2) cin>>arr1[i];
    REP(i,0,n-n/2) cin>>arr2[i];
    set<ll> s;
    REP(i,0,(1 << (n/2))){
        ll sum = 0;
        REP(j,0,n/2){
            if((i >> j) & 1){
                sum += arr1[j];
            }
        }
        s.insert(sum);
    }
    vector<ll> v;
    for(auto it:s) v.push_back(it);
    sort(v.begin(),v.end());
    ll ans = 0;
    REP(i,0,(1 << (n - n/2))){
        ll sum = 0;
        REP(j,0,n - n/2){
            if((i >> j) & 1){
                sum += arr2[j];
            }
        }
        ll p = t - sum;
        if(p >= 0){
            ll p1 = upper_bound(v.begin(),v.end(),p) - v.begin();
            if(p1 > 0){
                ans = max(ans,sum + v[p1-1]);
            }
            else {
                ans = max(ans,sum);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
#pragma GCC optimize ("O2")
#pragma GCC target ("avx2")
#include<bits/stdc++.h>
//#include<atcoder/all>
//using namespace atcoder;

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

const int mod = 998244353;
constexpr ll modpow(ll A, ll B) {
	ll kotae = 1;
	while (B > 0) {
		if (B & 1) kotae = kotae * A % mod;
		A = A * A % mod;
		B >>= 1;
	}
	return kotae;
}

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


	ll N, M;
	cin >> N >> M;

	ll MI = modpow(M, mod - 2);
	ll kotae = 0;
	rep1(k, M) {
		ll tmp = 0;
		ll pre = 1;
		ll MK = (M - k) * MI % mod;
		rep(i, N) {
			kotae += tmp + pre;
			tmp += (k - 1) * MI % mod * pre % mod;
			tmp %= mod;
			pre = pre * MK % mod;
		}
	}

	kotae = kotae % mod * modpow(M, N - 1) % mod;

	co(kotae);

	Would you please return 0;
}