// O(m*log(m)*n*x / w) time where m is the number of distinct values #include using namespace std; typedef unsigned long long ull; const int BITS = 64; vector Reduce(vector &X) { sort(X.begin(), X.end()); while (true) { int maxV = X.back(); vector freq(maxV+1, 0); for (auto &x: X) ++freq[x]; vector Y; for (int x = 1; x <= maxV; ++x) { if (!freq[x]) continue; int tot = 0, vals = 0, mul; for (mul = 1; mul <= 1 + tot && mul*x <= maxV; ++mul) { for (int _ = freq[mul*x]; _ > 0; --_) { tot += mul; ++vals; } } int nvals = 0, maxp = 1; for (maxp = 1; 2*maxp-1 <= tot; maxp *= 2, ++nvals); if (tot > maxp-1) ++nvals; if (nvals < vals) { for (maxp = 1; 2*maxp-1 <= tot; maxp *= 2) Y.push_back(x*maxp); if (tot > maxp-1) Y.push_back(x*(tot-(maxp-1))); for (int i = 1; i < mul; ++i) { freq[i*x] = 0; } } } for (int x = 1; x <= maxV; ++x) for (int i = 0; i < freq[x]; ++i) Y.push_back(x); sort(Y.begin(), Y.end()); if (Y == X) return Y; X = Y; } } int SubsetSum(vector &X, int t) { X = Reduce(X); int n = X.size(); fprintf(stderr, "reduce to %d items, t = %d\n", n, t); vector Poss(t/BITS + 2, 0); Poss[0] = 1; int tot = 0; for (int i = 0; i < n; tot += X[i], ++i) { int big_shift = X[i] / BITS, small_shift = X[i] % BITS; ull LO = small_shift ? (1ULL << (BITS - small_shift)) - 1 : ~0ULL; ull HI = ~0ULL ^ LO; for (int v = min(t-X[i], tot)/BITS; v >= 0; --v) { Poss[v+big_shift+1] |= (Poss[v] & HI) >> (BITS - small_shift); Poss[v+big_shift] |= (Poss[v] & LO) << small_shift; } } for (int v = t; v >= 0; --v) if (Poss[v/BITS] & (1ULL << (v % BITS))) return tot - v; } int main(void) { int n, x; scanf("%d%d", &n, &x); vector T(n); for (int &t: T) scanf("%d", &t); sort(T.begin(), T.end()); int max_T = T.back(); while (!T.empty() && T.back() > x) T.pop_back(); int ans; if (T.size() > 4) { vector Jobs; int tot = 0; for (int i = 4; i < T.size(); ++i) { Jobs.push_back(x+1-T[i]); tot += Jobs.back(); } ans = x+1 + SubsetSum(Jobs, tot/2); } else if (T.size() > 2) { ans = x+1; } else ans = max_T; printf("%d\n", max(max_T, ans)); }