#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll M, L;
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> M >> L;
ll n = 2*M + 1;
vector<ll> a(n), c(n);
for(ll i=0; i<n; ++i) cin >> a[i];
c = a;
ll sum = 0;
for(ll i=0; i<n; ++i) sum += (i-M) * a[i];
// cout << sum << "\n";
//Compute the greedy (c[i] - taken by the greedy)
ll took = 0;
if(sum < L) {
for(ll i=M; i<n; ++i) {
took += (i-M) * a[i];
}
if(took < L) {
cout << "impossible\n";
return 0;
}
for(ll i=M-1; i>=0; --i) {
if(took + (i-M) * a[i] >= L) {
took += (i-M) * a[i];
} else {
c[i] = (took - L)/(M-i);
took += (i-M) * ((took - L)/(M-i));
}
}
} else {
for(ll i=0; i<=M; ++i) {
took += (i-M) * a[i];
}
if(took > L) {
cout << "impossible\n";
return 0;
}
for(ll i=M+1; i<n; ++i) {
if(took + (i-M) * a[i] <= L) {
took += (i-M) * a[i];
} else {
c[i] = (L-took)/(i-M);
took += (i-M) * ((L-took)/(i-M));
}
}
}
// cout << took << "\n";
ll cnt = 0;
for(ll i=0; i<n; ++i) {
cnt += c[i];
// cout << c[i] << " ";
}
// cout << "\n";
//Lower amount of items from M^2 to MlogM
ll M2 = M*M; ll N = 2*M2 + 1;
vector<vector<ll>> items(N);
for(ll i=0; i<n; ++i) {
for(ll j=0; j<min(2*M+5, c[i]); ++j) items[M-i+M2].push_back(-1);
for(ll j=0; j<min(2*M+5, a[i]-c[i]); ++j) items[i-M+M2].push_back(1);
}
// for(ll i=0; i<n; ++i) cout << c[i] << " "; cout << "\n";
// for(ll i=0; i<n; ++i) cout << a[i]-c[i] << " "; cout << "\n";
for(ll i=N-1; i>M2; --i) {
if(items[i].size()==0) continue;
vector<ll> ilev(2), Vv = {-1, 1};
while(items[i].size()) {
if(items[i].back()==-1) ilev[0]++;
else ilev[1]++;
items[i].pop_back();
}
for(ll k : {0,1}) {
ll ile = ilev[k];
ll W = i-M2; ll V = Vv[k];
while(ile > 0 && abs(W) < abs(M2)) {
ll dodaj = (ile%2 ? ile%2 : 2);
if(abs(2*W) > abs(M2)) dodaj = min(3LL, ile);
for(ll x=0; x<dodaj; ++x) items[W+M2].push_back(V);
ile-=dodaj;
ile/=2;
V*=2; W*=2;
}
}
}
// cout << "xd\n"; return 0;
for(ll i=0; i<M2; ++i) {
if(items[i].size()==0) continue;
vector<ll> ilev(2), Vv = {-1, 1};
while(items[i].size()) {
if(items[i].back()==-1) ilev[0]++;
else ilev[1]++;
items[i].pop_back();
}
for(ll k : {0,1}) {
ll ile = ilev[k];
ll W = i-M2; ll V = Vv[k];
while(ile > 0 && abs(W) < abs(M2)) {
ll dodaj = (ile%2 ? ile%2 : 2);
if(abs(2*W) > abs(M2)) dodaj = min(3LL, ile);
for(ll x=0; x<dodaj; ++x) items[W+M2].push_back(V);
ile-=dodaj;
ile/=2;
V*=2; W*=2;
}
}
}
// cout << N << "\n";
// for(ll i=0; i<N; ++i) { for(auto v : items[i]) cout << i-M2 << " " << v << "\n"; }
//Regret the greedy using dp and fact that we can always mallaing the transition inside tha [L-M, L+M] and obtaining same weight twice can only worsen our solution (for prove look in editorial - https://www.boi2022.de/wp-content/uploads/2022/05/boi2022-day1-vault-spoiler.pdf)
vector<ll> dp(N, -2e18);
ll offset = L-M2;
dp[took-offset] = cnt;
auto add = [&](ll W, ll V) {
vector<ll> ndp = dp;
ll L = max(0LL, W);
ll R = min(N-1, N-1+W);
for(ll i=L; i<=R; ++i) {
ndp[i] = max(dp[i], dp[i-W] + V);
}
swap(dp, ndp);
};
for(ll i=0; i<N; ++i) {
for(auto v : items[i]) add(i-M2, v);
}
if(dp[L - offset]<=0) cout << "impossible\n";
else cout << dp[L-offset] << "\n";
return 0;
}