//#include <iostream>
//#include <string>
//#include <algorithm>
//#include <climits>
//#include <map>
//#include <cstdlib>
//#include <cstdio>
//#include <vector>
//#include <climits>
//using namespace std;
//
//typedef vector<int> vi;
//typedef vector<vi> vvi;
//typedef pair<int, int> pi;
//typedef long long int ll;
//
//
////int memo[1000010] = {0,0,1};
//double PI = 3.14159265359;
//
//ll MOD = 10e9 + 7;
//
//ll dataA[100010];
//ll dataB[100010];
//
//class fenwick {
//public:
//
//    void Add(int a, int b, int x, int k, int l, int r) {
//        if (a <= l && r <= b) {
//            dataA[k] += x;
//        }
//        else if (l < b && a < r) {
//            //cout << a << ":" << b << endl;
//            dataB[k] += (min(b, r) - max(a, l))*x;
//            Add(a, b, x, k * 2 + 1, l, (l + r) / 2);
//            Add(a, b, x, k * 2 + 2, (l + r) / 2, r);
//        }
//
//    }
//
//    ll sum(int a, int b, int k, int l, int r) {
//        if (b <= l || r <= a) {
//            return 0;
//        }
//        else if (a <= l && r <= b) {
//            return dataA[k] * (r - l) + dataB[k];
//        }
//        else {
//            ll res = (min(b, r) - max(a, l)) * dataA[k];
//            res += sum(a, b, k * 2 + 1, l, (l + r) / 2);
//            res += sum(a, b, k * 2 + 2, (l + r) / 2, r);
//            return res;
//        }
//    }
//};
//
//vector<pair<int,pair<int,int>>> gift;
//
//int main(void) {
//    // Here your code !
//    ll n,m;
//    cin >> n >> m;
//
//    for (int i = 0; i < n; i++) {
//        int l,r;
//        cin >> l >> r;
//        gift.push_back(pair<int, pair<int, int>>(r-l+1,pair<int,int>(l,r)));
//    }
//
//    fenwick fwk;
//
//    sort(gift.begin(),gift.end());
//    int t = 0;
//
//    //cout << endl;
//
//    for (int i = 1; i <= m; i++) {
//
//        for (; t < n; t++) {
//            if (gift[t].first <= i) {
//                //cout << gift[t].second.first << " " << gift[t].second.second << endl;
//                fwk.Add(gift[t].second.first,gift[t].second.second+1,1,0,0,m+1);
//            }
//            else {
//                break;
//            }
//        }
//
//        ll res = n-t;
//        //cout << res << endl;
//
//        for (int j = 0; j <= m; j+=i) {
//            res += fwk.sum(j,j+1,0,0,m+1);
//        }
//
//        cout << res << endl;
//
//    }
//
//
//}




#include <iostream>
#include <numeric>
#include <vector>
#include <string>

#include <algorithm>
using namespace std;

using ll = long long int;

//何番目か
//何個入れたか
//重さ
ll dp[110][110][500] = {};

ll w[110];
ll v[110];

int main(void) {

    ll N,W,Min = 1000000007;
    cin >> N >> W;

    for (int i = 0; i < N; i++) {
        cin >> w[i] >> v[i];

        Min = min(w[i],Min);
    }

    for (int i = 0; i < N; i++) {
        w[i] -= Min;
    }

    for(int i = 0; i < 110; i++)
        for(int j = 0; j < 110; j++)
            for(int k = 0; k < 500; k++)
                dp[i][j][k] = -1;


    dp[0][0][0] = 0;
    //何番目か
    for (int i = 0; i < N; i++) {
        //何個入れたか
        for (int j = 0; j < N; j++) {

            //重さ
            for (int k = 499; k >= 0; k--) {
                if (dp[i][j][k] != -1) {
                    dp[i+1][j+1][k+w[i]] = max(dp[i + 1][j + 1][k + w[i]] ,  dp[i][j][k] + v[i]);
                    dp[i+1][j][k] = max(dp[i + 1][j][k], dp[i][j][k]);
                }
            }
        }
    }

    ll result = 0;

    //何番目か
    for (int i = 0; i < N+1; i++) {
        //何個入れたか
        for (int j = 0; j < N+1; j++) {

            //重さ
            for (int k = 499; k >= 0; k--) {
                if (dp[i][j][k] != -1 && W >= j*Min + k) {
                    //cout << i << " " << j << " " << k << ":" << dp[i][j][k] << endl;
                    result = max(result,dp[i][j][k]);
                }
            }
        }
    }

    cout << result << endl;

    return 0;
}


Measured memory_bytes: 47488