#include using namespace std; using ll = long long; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N; long long W; cin >> N >> W; vector> items(N); int maxW = 0; for (int i = 0; i < N; ++i) { int v,w; cin >> v >> w; items[i] = {v,w}; maxW = max(maxW, w); } int B = maxW; long long W0 = min(W, 1LL * B * B); vector dp(W0 + 1, 0); for (int i = 0; i < N; ++i) { int v = items[i].first; int w = items[i].second; for (int c = w; c <= W0; ++c) { dp[c] = max(dp[c], dp[c - w] + v); } } if (W <= W0) { cout << dp[W] << '\n'; return 0; } int idx = 0; for (int i = 1; i < N; ++i) { long long vi = items[i].first, wi = items[i].second; long long vj = items[idx].first, wj = items[idx].second; if (vi * wj > vj * wi) idx = i; } long long vk = items[idx].first; long long wk = items[idx].second; long long maxX = W / wk; long long minX; minX = (W - W0 + wk - 1) / wk; if (minX < 0) minX = 0; if (minX > maxX) { long long ans = 0; for (long long x = 0; x <= maxX; ++x) { long long rem = W - x*wk; if (rem <= W0) { long long cand = dp[rem] + x * vk; ans = max(ans, cand); } } cout << ans << '\n'; return 0; } long long ans = 0; for (long long x = minX; x <= maxX; ++x) { long long rem = W - x * wk; if (rem < 0 || rem > W0) continue; long long cand = dp[rem] + x * vk; ans = max(ans, cand); } cout << ans << '\n'; return 0; }