#include <bits/stdc++.h>

using namespace std;


#ifdef zxc

#include <sys/resource.h>
#include "debug.h"
#include "profile.h"

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define profile(X) LOG_DURATION(X)
#else
#define debug(...) 42
#define profile(...) 42
#endif

using ll = int64_t;
using ld = long double;
const ld EPS = 1e-9;
//const ll MOD = 924844033;
const ld PI = 3.141592653589793;
const int maxn = 600001;
const ll MOD = 1e9 + 7;
using cd = complex<double>;

void fast_io() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
}

struct basis {
    ll pivot[60];
    bool empty = false;

    void add(ll val) {
        for (int i = 0; i < 60; ++i) {
            if (val & (1ll << i)) {
                val ^= (pivot[i]);
            }
        }
        for (int i = 0; i < 60; ++i) {
            if (val & (1ll << i)) {
                pivot[i] = val;
                for (int e = 0; e < 60; ++e) {
                    if (e == i) {
                        continue;
                    }
                    if (pivot[e] & (1ll << i)) {
                        pivot[e] ^= pivot[i];
                    }
                }
                break;
            }
        }
    }

    bool has(ll val) {
        for (int i = 0; i < 60; ++i) {
            if (val & (1ll << i)) {
                val ^= pivot[i];
            }
        }
        return val == 0;
    }
};

int dp[101][101][301];

signed main() {
#ifdef zxc
    struct rlimit rl;
    const rlim_t kStackSize = 512L * 1024L * 1024L;
    assert(!getrlimit(RLIMIT_STACK, &rl));
    rl.rlim_cur = kStackSize;
    assert(!setrlimit(RLIMIT_STACK, &rl));
    freopen("../input.txt", "r", stdin);
//    freopen("../kolya_output.txt", "w", stdout);
#else
    //    mt19937 mt(std::chrono::high_resolution_clock::now().time_since_epoch().count());
    //            freopen("", "r", stdin);
    //        freopen("hack.out", "w", stdout);
#endif

    auto solve = [&](int _) {
        int n;
        cin >> n;
        ll w;
        cin >> w;
        vector<int> weight(n + 1);
        vector<int> v(n + 1);
        for (int i = 1; i <= n; ++i) {
            cin >> weight[i] >> v[i];
        }
        for (int i = 1; i <= n; ++i) {
            int cur_add = weight[i] - weight[1];
            for (int take = 0; take <= i; ++take) {
                for (int add_weight = 0; add_weight <= 300; ++add_weight) {
                    dp[i][take][add_weight] = dp[i - 1][take][add_weight];
//                    cout << dp[i][take][add_weight];
                    if (add_weight >= cur_add && take >= 1) {
                        dp[i][take][add_weight] = max(dp[i][take][add_weight],
                                                      dp[i - 1][take - 1][add_weight - cur_add] + v[i]);
                    }
//                    cout << dp[i][take][add_weight] << endl;
                }
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            for (int cnt = 0; cnt <= i; ++cnt) {
                for (int add = 0; add <= 300; ++add) {
                    ll cur = add + 1ll * cnt * weight[1];
                    if (cur <= w) {
                        ans = max(ans, dp[i][cnt][add]);
                    }
                }
            }
        }
        cout << ans;
    };

    fast_io();
    cout.precision(9);
    cout << fixed;
    auto start = chrono::steady_clock::now();

    for (int i = 1; i <= 1; ++i) solve(i);
    auto end = chrono::steady_clock::now();

    debug("time", chrono::duration_cast<chrono::milliseconds>(end - start).count() / 1000.0);

}


Measured memory_bytes: 10368