import std.stdio, std.array, std.conv, std.typecons, std.algorithm;

long impl(long n, long w, const ref long[] ws, const ref long[] vs, ref long[][] dp) {
    if(dp[n][w] == -1) {
        const auto prev_w = w-ws[n-1];
        const auto yes = prev_w >= 0 ? impl(n-1, prev_w, ws, vs, dp) + vs[n-1] : -1;
        const auto no = impl(n-1, w, ws, vs, dp);
        dp[n][w] = max(yes, no, dp[n][w]);
    }
    return dp[n][w];
}

long solve(long n, long w, const ref long[] ws, const ref long[] vs) {
    auto dp = new long[][](n+1, w+1);
    foreach(ref v ; dp[]) { v[] = -1;}
    dp[0][] = 0;
    return impl(n, w, ws, vs, dp);
}

void main() {
    immutable i1 = readln.split.to!(long[]);
    immutable n = i1[0], w = i1[1];
    auto ws = new long[n];
    auto vs = new long[n];

    for(auto i = 0; i < n; i++) {
        auto input = readln.split.to!(long[]);
        ws[i] = input[0];
        vs[i] = input[1];
    }

    writeln(solve(n, w, ws, vs));
}
