stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<queue>

#include<set>

using namespace std;

typedef long long ll;

const int inf=1<<29;

const ll Maxn=1e6;

const double pi=3.1415926536;



struct sumwv{

	int w,v;

}wv[105];



bool cmp(sumwv x,sumwv y){

	return x.v>y.v;

}



sumwv A[105],B[105],C[105],D[105];



int a=0,b=0,c=0,d=0;



ll wa[105],wb[105],wc[105],wd[105];

ll va[105],vb[105],vc[105],vd[105];



int main(void){

	int n,w;

	cin>>n>>w;

	for(int i=1;i<=n;i++){

		cin>>wv[i].w>>wv[i].v;

		if(wv[i].w==wv[1].w) A[++a]=wv[i];

		if(wv[i].w==wv[1].w+1) B[++b]=wv[i];

		if(wv[i].w==wv[1].w+2) C[++c]=wv[i];

		if(wv[i].w==wv[1].w+3) D[++d]=wv[i];

	}

	sort(A+1,A+1+a,cmp);

	sort(B+1,B+1+b,cmp);

	sort(C+1,C+1+c,cmp);

	sort(D+1,D+1+d,cmp);

	wa[0]=wb[0]=wc[0]=wd[0]=0;

	va[0]=vb[0]=vc[0]=vd[0]=0;

	for(int i=1;i<=a;i++){

		wa[i]=wa[i-1]+A[i].w;

		va[i]=va[i-1]+A[i].v;

	}

	for(int i=1;i<=b;i++){

		wb[i]=wb[i-1]+B[i].w;

		vb[i]=vb[i-1]+B[i].v;

	}

	for(int i=1;i<=c;i++){

		wc[i]=wc[i-1]+C[i].w;

		vc[i]=vc[i-1]+C[i].v;

	}

	for(int i=1;i<=d;i++){

		wd[i]=wd[i-1]+D[i].w;

		vd[i]=vd[i-1]+D[i].v;

	}

	ll sum;

	ll sim=0;

	for(int i=0;i<=a;i++){

		for(int j=0;j<=b;j++){

			for(int k=0;k<=c;k++){

				for(int l=0;l<=d;l++){

					sum=wa[i]+wb[j]+wc[k]+wd[l];

					if(sum<=w){

						sim=max(sim,va[i]+vb[j]+vc[k]+vd[l]);

					}

				}

			}

		}

	}

	printf("%lld\n",sim);

}

// Faster C++ solution for the same problem (measured speedup: 5.169889573102539x):
#include       <set>

#include       <map>

#include     <queue>

#include     <cmath>

#include    <cstdio>

#include    <cctype>

#include    <vector>

#include   <cstring>

#include <algorithm>

using namespace std;



typedef long long ll;

const ll mod = 1e9+7;

const double eps = 1e-7;

const int maxn = 105;



ll fast_pow(ll a,ll b,ll mod){

    ll ans = 1;

    while(b){

        if(b&1)

            ans = ans*a%mod;

        a = a*a%mod;

        b>>=1;

    }

    return ans;

}



int w[maxn], v[maxn];

int dp[maxn*4][maxn];



int main(){

    int n, W, c;

    scanf("%d%d",&n,&W);

    for(int i=0;i<n;i++)

        scanf("%d%d",&w[i],&v[i]);

    for(int i=1;i<n;i++)

        w[i] -= w[0]-1;

    c = w[0]-1;

    w[0] = 1;

    for(int i=0;i<n;i++)

        for(int j=(i+1)*4;j>=w[i];j--)

            for(int k=1;k<=i+1;k++){

                dp[j][k] = max(dp[j][k],dp[j-w[i]][k-1]+v[i]);

    }

    int ans = 0;

    for(int j=n*4;j>=0;j--)

        for(int k=1;k<=n;k++){

            if(1ll*k*c+j<=W){

                ans = max(ans,dp[j][k]);

            }

    }

    printf("%d\n",ans);

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

int main()

{

    long long n, w, i, j, k, t, p[200][200] = {0}, a[200], b[200], ans = 0;

    vector <long long> g[5];



    cin >> n >> w;



    for(i = 0; i < n; ++i)

    {

        cin >> a[i] >> b[i];

        g[a[i] - a[0]].push_back(b[i]);

    }

    sort(g[0].rbegin(), g[0].rend());

    sort(g[1].rbegin(), g[1].rend());

    sort(g[2].rbegin(), g[2].rend());

    sort(g[3].rbegin(), g[3].rend());



    for(i = 0; i < 4; ++i)

    {

        for(j = 1; j <= g[i].size(); ++j)

            p[i][j] = p[i][j - 1] + g[i][j - 1];

    }

    for(i = 0; i <= g[0].size(); ++i)

    {

        for(j = 0; j <= g[1].size(); ++j)

        {

            for(k = 0; k <= g[2].size(); ++k)

            {

                for(t = 0; t <= g[3].size(); ++t)

                {

                    if(i * a[0] + j * (a[0] + 1) + k * (a[0] + 2) + t * (a[0] + 3) <= w)

                        ans = max(ans, p[0][i] + p[1][j] + p[2][k] + p[3][t]);

                }

            }

        }

    }

    cout << ans;



return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.3182172669995773x):
#include <bits/stdc++.h>

using namespace std;

int n; 

int W;



vector <pair <long long, long long> > v;



map <pair <long long, long long>, long long> m;



long long inf = 1000000000000000000;



long long solve(long long k, long long w){

	

	if (k < 0)

		return -inf;

	if (w < 0)

		return -inf;

	

	if (k == 0 || w == 0)

		return 0;

	

	

	if (m.count(make_pair(k, w)) != 0){

		return m[make_pair(k, w)];

	}

	long long res = max(solve(k-1, w), solve(k - 1, w - v[k - 1].first) + v[k - 1].second);

	

		

	return m[make_pair(k, w)] = res;

}





int main(){

	cin >> n;

	cin >> W;

	v = vector <pair <long long, long long> > (n);

	for (int i = 0; i < n; i++){

		cin >> v[i].first >> v[i].second;

	}

	

	

	cout << solve(n, W) << endl;

	

	return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

int main()

{

    long long n, w, i, j, k, t, p[200][200] = {0}, a[200], b[200], ans = 0;

    vector <long long> g[5];



    cin >> n >> w;



    for(i = 0; i < n; ++i)

    {

        cin >> a[i] >> b[i];

        g[a[i] - a[0]].push_back(b[i]);

    }

    sort(g[0].rbegin(), g[0].rend());

    sort(g[1].rbegin(), g[1].rend());

    sort(g[2].rbegin(), g[2].rend());

    sort(g[3].rbegin(), g[3].rend());



    for(i = 0; i < 4; ++i)

    {

        for(j = 1; j <= g[i].size(); ++j)

            p[i][j] = p[i][j - 1] + g[i][j - 1];

    }

    for(i = 0; i <= g[0].size(); ++i)

    {

        for(j = 0; j <= g[1].size(); ++j)

        {

            for(k = 0; k <= g[2].size(); ++k)

            {

                for(t = 0; t <= g[3].size(); ++t)

                {

                    if(i * a[0] + j * (a[0] + 1) + k * (a[0] + 2) + t * (a[0] + 3) <= w)

                        ans = max(ans, p[0][i] + p[1][j] + p[2][k] + p[3][t]);

                }

            }

        }

    }

    cout << ans;



return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.2938493767322068x):
#include <bits/stdc++.h>

using namespace std ;



#define inf 0x3f3f3f3f

#define INF 1000111000111000111LL

#define mod 1000000007

#define endl '\n'

#define mp make_pair

#define mt make_tuple

#define pb push_back

#define fi first

#define se second

#define all(cc) (cc).begin(),(cc).end()

using lli = long long int ;

using pii = pair<int, int> ;

using vi = vector<int> ;

using vb = vector<bool> ;

using vvi = vector<vector<int>> ;

using vlli = vector<long long int> ;

using vpii = vector<pair<int, int>> ;



int main()

  {

    ios_base::sync_with_stdio (false) ; cin.tie(0) ; cout.tie(0) ;

    lli n, W, sum=0, ans=0, idx=1, w1=0, w2=0, w3=0, w4=0 ;

    cin>> n >> W ;

    vlli w(n), v(n) ;

    vector<vector<lli>> weight(5) ;

    map<lli, lli> cnc, ncn ;

    for(int i=0 ; i<n ; i++)

      {

        cin>> w[i] >> v[i] ;

        sum+=w[i] ;

        if(!cnc[w[i]])

          {

            cnc[w[i]]=idx ;

            ncn[idx++]=w[i] ;

          }

      }

    for(int i=0 ; i<n ; i++)

      weight[cnc[w[i]]].pb(v[i]) ;

    for(int i=1 ; i<=4 ; i++)

      {

        weight[i].pb(0) ;

        sort(weight[i].begin(), weight[i].end()) ;

        reverse(weight[i].begin()+1, weight[i].end()) ;

      }

    for(lli i=0 ; i<weight[1].size() ; i++)

      {

        w1+=weight[1][i] ; w2=w3=w4=0 ;

        for(lli j=0 ; j<weight[2].size() ; j++)

          {

            w2+=weight[2][j] ; w3=w4=0 ;

            for(lli k=0 ; k<weight[3].size() ; k++)

              {

                w3+=weight[3][k] ; w4=0 ;

                for(lli l=0 ; l<weight[4].size() ; l++)

                  {

                    w4+=weight[4][l] ;

                    if(i*ncn[1]+j*ncn[2]+k*ncn[3]+l*ncn[4]<=W)

                      ans=max(ans, w1+w2+w3+w4) ;

                  }

              }

          }

      }

    cout<< ans ;

  }
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

int main()

{

    long long n, w, i, j, k, t, p[200][200] = {0}, a[200], b[200], ans = 0;

    vector <long long> g[5];



    cin >> n >> w;



    for(i = 0; i < n; ++i)

    {

        cin >> a[i] >> b[i];

        g[a[i] - a[0]].push_back(b[i]);

    }

    sort(g[0].rbegin(), g[0].rend());

    sort(g[1].rbegin(), g[1].rend());

    sort(g[2].rbegin(), g[2].rend());

    sort(g[3].rbegin(), g[3].rend());



    for(i = 0; i < 4; ++i)

    {

        for(j = 1; j <= g[i].size(); ++j)

            p[i][j] = p[i][j - 1] + g[i][j - 1];

    }

    for(i = 0; i <= g[0].size(); ++i)

    {

        for(j = 0; j <= g[1].size(); ++j)

        {

            for(k = 0; k <= g[2].size(); ++k)

            {

                for(t = 0; t <= g[3].size(); ++t)

                {

                    if(i * a[0] + j * (a[0] + 1) + k * (a[0] + 2) + t * (a[0] + 3) <= w)

                        ans = max(ans, p[0][i] + p[1][j] + p[2][k] + p[3][t]);

                }

            }

        }

    }

    cout << ans;



return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.3272735897326904x):
#include<iostream>  

#include<algorithm> 

#include<cstdio>  

#include<cstring>    

using namespace std;  

int n,m,a,b,c,d;

long long sum,ans; 

struct node  

{  

    int w,v;  

}g[110];  

  

bool cmp(node a,node b)  

{  

    return a.v>b.v;  

}  

node A[110],B[110],C[110],D[110];  

  

long long swa[110],swb[110],swc[110],swd[110];  

long long sva[110],svb[110],svc[110],svd[110]; 

  

int main()  

{  

        cin>>n>>m; 

        for(int i=1;i<=n;i++)  

        {  

            cin>>g[i].w>>g[i].v;  

            if(g[i].w==g[1].w) A[++a]=g[i];  

            if(g[i].w==g[1].w+1) B[++b]=g[i];  

            if(g[i].w==g[1].w+2) C[++c]=g[i];  

            if(g[i].w==g[1].w+3) D[++d]=g[i];  

        }  

        sort(A+1,A+a+1,cmp);  

        sort(B+1,B+b+1,cmp);  

        sort(C+1,C+c+1,cmp);  

        sort(D+1,D+d+1,cmp);  

        

        for(int i=1;i<=a;i++)  

        {  

            swa[i]=swa[i-1]+A[i].w;  

            sva[i]=sva[i-1]+A[i].v;  

        }  

        for(int i=1;i<=b;i++)  

        {  

            swb[i]=swb[i-1]+B[i].w;  

            svb[i]=svb[i-1]+B[i].v;  

        }  

        for(int i=1;i<=c;i++)  

        {  

            swc[i]=swc[i-1]+C[i].w;  

            svc[i]=svc[i-1]+C[i].v;  

        }  

        for(int i=1;i<=d;i++)  

        {  

            swd[i]=swd[i-1]+D[i].w;  

            svd[i]=svd[i-1]+D[i].v;  

        }  

    

        for(int i=0;i<=a;i++)  

        for(int j=0;j<=b;j++)  

        for(int k=0;k<=c;k++)  

        for(int l=0;l<=d;l++)  

        {  

        sum=swa[i]+swb[j]+swc[k]+swd[l];  

        if(sum<=m)  

        ans=max(ans,sva[i]+svb[j]+svc[k]+svd[l]);  

              

        }  

        cout<<ans<<endl;  

    

  

    return 0;  

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

int main()

{

    long long n, w, i, j, k, t, p[200][200] = {0}, a[200], b[200], ans = 0;

    vector <long long> g[5];



    cin >> n >> w;



    for(i = 0; i < n; ++i)

    {

        cin >> a[i] >> b[i];

        g[a[i] - a[0]].push_back(b[i]);

    }

    sort(g[0].rbegin(), g[0].rend());

    sort(g[1].rbegin(), g[1].rend());

    sort(g[2].rbegin(), g[2].rend());

    sort(g[3].rbegin(), g[3].rend());



    for(i = 0; i < 4; ++i)

    {

        for(j = 1; j <= g[i].size(); ++j)

            p[i][j] = p[i][j - 1] + g[i][j - 1];

    }

    for(i = 0; i <= g[0].size(); ++i)

    {

        for(j = 0; j <= g[1].size(); ++j)

        {

            for(k = 0; k <= g[2].size(); ++k)

            {

                for(t = 0; t <= g[3].size(); ++t)

                {

                    if(i * a[0] + j * (a[0] + 1) + k * (a[0] + 2) + t * (a[0] + 3) <= w)

                        ans = max(ans, p[0][i] + p[1][j] + p[2][k] + p[3][t]);

                }

            }

        }

    }

    cout << ans;



return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.3089091475626982x):
#include<bits/stdc++.h>



using namespace std;



using ll=long long;



int main(){

    ll N,W;

    cin>>N>>W;

    vector<vector<int>>t(4);

    ll ww;

    int vv;

    cin>>ww>>vv;

    t[0].push_back(vv);

    for(int i=1;i<N;++i){

        int w,v;

        cin>>w>>v;

        t[w-ww].push_back(v);

    }

    sort(t[0].begin(),t[0].end(),greater<int>());

    sort(t[1].begin(),t[1].end(),greater<int>());

    sort(t[2].begin(),t[2].end(),greater<int>());

    sort(t[3].begin(),t[3].end(),greater<int>());

    for(int i=0;i<4;++i){

        int pre=0;

        for(auto& x:t[i]){

            x += pre;

            pre=x;

        }

    }

    t[0].insert(t[0].begin(),0);

    t[1].insert(t[1].begin(),0);

    t[2].insert(t[2].begin(),0);

    t[3].insert(t[3].begin(),0);

    int ans=0;

    for(ll i=0;i<=t[0].size()-1;++i){

        for(ll j=0;j<=t[1].size()-1;++j){

            for(ll k=0;k<=t[2].size()-1;++k){

                for(ll l=0;l<=t[3].size()-1;++l){

                    if(W<ww*(i+j+k+l)+j+2*k+3*l){

                        break;

                    }

                    ans=max(ans,t[0][i]+t[1][j]+t[2][k]+t[3][l]);

                }

            }

        }

    }

    cout<<ans<<endl;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0, i##_len = (n); i < i##_len; ++i)

#define rep2(i, x, n) for(int i = x, i##_len = (n); i < i##_len; ++i)

#define all(n) begin(n), end(n)

using ll = long long;

using P = pair<int, int>;

using vi = vector<int>;

using vl = vector<ll>;

using vs = vector<string>;

using vc = vector<char>;

using vb = vector<bool>;

using vd = vector<double>;

vi dir = {-1, 0, 1, 0, -1, -1, 1, 1, -1};



int main() {

  ll n, w;

  cin >> n >> w;

  vl c(n), v(n);

  rep(i, n) cin >> c[i] >> v[i];

  ll dp[n + 1][500][101] = {};

  rep(i, n + 1) rep(j, 500) rep(k, 101) dp[i][j][k] = -1;

  dp[0][0][0] = 0;

  rep(i, n) rep(j, 410) rep(k, 100) {

    if(dp[i][j][k] == -1) continue;

    dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k]);

    ll nj = j + c[i] - c[0];

    dp[i + 1][nj][k + 1] = max(dp[i + 1][nj][k + 1], dp[i][j][k] + v[i]);

  }

  ll ans = 0;

  rep(j, 410) rep(k, 101) if(j + k * c[0] <= w) ans = max(ans, dp[n][j][k]);

  cout << ans << endl;

}

// Faster C++ solution for the same problem (measured speedup: 2.4182333309188566x):
#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0, i##_len = (n); i < i##_len; ++i)

using ll = long long;

using vl = vector<ll>;



int main() {

  ll n, w;

  cin >> n >> w;

  vl c(n), v(n);

  rep(i, n) cin >> c[i] >> v[i];

  ll dp[500][101] = {};

  rep(j, 500) rep(k, 101) dp[j][k] = -1;

  dp[0][0] = 0;

  rep(i, n) for(int j = 400; j >= 0; j--) for(int k = 100; k >= 0; k--) {

    if(dp[j][k] == -1) continue;

    ll nj = j + c[i] - c[0];

    dp[nj][k + 1] = max(dp[nj][k + 1], dp[j][k] + v[i]);

  }

  ll ans = 0;

  rep(j, 410) rep(k, 101) if(j + k * c[0] <= w) ans = max(ans, dp[j][k]);

  cout << ans << endl;

}
// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <vector>

#include <queue>

#include <map>

using namespace std;

#define LL long long



int n;

LL W, w[105], v[105];

LL judge;



//int dfs(int now, LL rest, LL value)

//{

//    if(value >= judge) return 1;

//    if(now > n) return 0;

//    int flag1 = 0, flag2 = 0;

//    flag1 = dfs(now + 1, rest, value);

//    if(rest - w[now] >= 0) flag2 = dfs(now + 1, rest - w[now], value + v[now]);

//    if(flag1 + flag2 > 0) return 1;

//    return 0;

//}

//

//int C(LL x)

//{

//    judge = x;

//    if(dfs(1, W, 0)) return 1;

//    else return 0;

//}

//

//int main()

//{

//    while(~scanf("%d %lld", &n, &W))

//    {

//        LL sum = 0;

//        for(int i = 1; i <= n; ++i)

//        {

//            scanf("%lld %lld", &w[i], &v[i]);

//            sum += v[i];

//        }

//        LL l = 0, r = sum, mid;

//        while(l < r)

//        {

//            mid = (l + r) / 2;

//            if(C(mid)) l = mid + 1;

//            else r = mid;

//        }

//        mid = (l + r) / 2;

//        if(!C(mid)) l--;

//        printf("%lld\n", l);

//    }

//}



map<LL, LL> dp[105];



LL dfs(int i, LL cost)

{

    if(cost > W) return -10000000;

    if(i > n) return 0;

    if(dp[i].count(cost)) return dp[i][cost];

    return dp[i][cost] = max(dfs(i + 1, cost + w[i]) + v[i], dfs(i + 1, cost));

}



int main()

{

    while(~scanf("%d %lld", &n, &W))

    {

        for(int i = 1; i <= n; ++i) dp[i].clear();

        for(int i = 1; i <= n; ++i)

            scanf("%lld %lld", &w[i], &v[i]);

        LL ans = dfs(1, 0);

        printf("%lld\n", ans);

    }

}


// Faster C++ solution for the same problem (measured speedup: 5.176345982373565x):
#include       <set>

#include       <map>

#include     <queue>

#include     <cmath>

#include    <cstdio>

#include    <cctype>

#include    <vector>

#include   <cstring>

#include <algorithm>

using namespace std;



typedef long long ll;

const ll mod = 1e9+7;

const double eps = 1e-7;

const int maxn = 105;



ll fast_pow(ll a,ll b,ll mod){

    ll ans = 1;

    while(b){

        if(b&1)

            ans = ans*a%mod;

        a = a*a%mod;

        b>>=1;

    }

    return ans;

}



int w[maxn], v[maxn];

int dp[maxn*4][maxn];



int main(){

    int n, W, c;

    scanf("%d%d",&n,&W);

    for(int i=0;i<n;i++)

        scanf("%d%d",&w[i],&v[i]);

    for(int i=1;i<n;i++)

        w[i] -= w[0]-1;

    c = w[0]-1;

    w[0] = 1;

    for(int i=0;i<n;i++)

        for(int j=n*4;j>=w[i];j--)

            for(int k=1;k<=i+1;k++){

                dp[j][k] = max(dp[j][k],dp[j-w[i]][k-1]+v[i]);

    }

    int ans = 0;

    for(int j=n*4;j>=0;j--)

        for(int k=1;k<=n;k++){

            if(1ll*k*c+j<=W){

                ans = max(ans,dp[j][k]);

            }

    }

    printf("%d\n",ans);

    return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

//#pragma GCC optimize("O3")

//#pragma GCC target ("sse4")

using namespace std;

#define PB push_back

#define all(x) (x).begin(),(x).end()

#define MEM(x,a) memset((x),a,sizeof((x)))

#define F first

#define S second

#define imx INT_MAX

#define inI(x) scanf("%d",&x)

#define inI2(x,y) scanf("%d %d",&x,&y)

#define inI3(x,y,z) scanf("%d %d %d",&x,&y,&z)

const long long MOD = (long long)(1e9+7);

const long long MMX = (long long)(1e18);

typedef long long LL;

long long n,w,val[105],ww[105],k=MMX,dp[105][1000],ans=0;

int main()

{

    for(int i=0;i<105;i++)for(int j=0;j<1000;j++)dp[i][j]=-1;

    dp[0][0]=0;

    scanf("%lld %lld",&n,&w);

    for(int i=1;i<=n;i++)

    {

        scanf("%lld %lld",&ww[i],&val[i]);

        k=min(k,ww[i]);

    }

    for(int i=1;i<=n;i++)ww[i]-=k;

    for(int t=1;t<=n;t++)

    {

        for(int i=100;i>=0;i--)

        {

            for(int j=1000;j>=0;j--)

            {

                if(dp[i][j]!=-1)

                {

                    dp[i+1][j+ww[t]]=max(dp[i+1][j+ww[t]],dp[i][j]+val[t]);

                }

            }

        }

    }

    for(int i=0;i<105;i++)for(int j=0;j<1000;j++)if(((i*k)+j)<=w)ans=max(ans,dp[i][j]);

    printf("%lld",ans);

}


// Faster C++ solution for the same problem (measured speedup: 2.488134336771545x):
#include<bits/stdc++.h>

using namespace std;



#define PB(x) push_back(x)

#define MP(x,y) make_pair(x,y)



map<long long,long long> mp;

long long ty[5];

long long nty;

vector<long long> a[5];



main()

{

	long long n;

	long long w;

	scanf("%lld %lld",&n,&w);

	for(long long i=0;i<n;i++)

	{

		long long v;

		long long w;

		scanf("%lld %lld",&w,&v);

		if(mp[w]==0)

		{

			nty++;

			ty[nty]=w;

			mp[w]=nty;

			a[mp[w]].PB(v);

		}

		else

		{

			a[mp[w]].PB(v);

		}

	}

	for(long long i=1;i<=nty;i++)

		sort(a[i].begin(),a[i].end());

	long long ans=0;

	a[1].PB(0);

	a[2].PB(0);

	a[3].PB(0);

	a[4].PB(0);

	long long s1=0,s2=0,s3=0,s4=0;

	for(long long i=a[1].size()-1,ni=0;i>=0;i--,ni++)

	{

		long long all=0;

		long long wei=ni*ty[1];

		s1+=a[1][i];

		all=s1;

		if(wei>w)break;

		s2=0;

		ans=max(ans,all);

		for(long long j=a[2].size()-1,nj=0;j>=0;j--,nj++)

		{

			long long wei2=nj*ty[2];

			s2+=a[2][j];

			long long all2=s2;

			if(wei+wei2>w)break;

			s3=0;

			ans=max(ans,all+all2);

			for(long long k=a[3].size()-1,nk=0;k>=0;k--,nk++)

			{

				long long wei3=nk*ty[3];

				s3+=a[3][k];

				long long all3=s3;

				if(wei+wei2+wei3>w)break;

				s4=0;

				ans=max(ans,all+all2+all3);

				for(long long l=a[4].size()-1,nl=0;l>=0;l--,nl++)

				{

					long long wei4=nl*ty[4];

					s4+=a[4][l];

					long long all4=s4;

					if(wei+wei2+wei3+wei4>w)break;

					ans=max(ans,all+all2+all3+all4);

				}

			}

		}	

	}

	printf("%lld",ans);

}
// Slower C++ solution:
// glory be to the sky

#include<bits/stdc++.h> 

#define pb push_back

using namespace std;

	

typedef long long ll; 





ll W;

ll w[105], v[105];

int n;

map<pair<int, ll>, ll > mep;



ll f(int curr, ll rem) {

	if (curr == 0) return 0;

	pair<int, ll> param = make_pair(curr, rem);

	if (mep.count(param)) return mep[param];

	ll ans = 0, t1, t2;

	if (rem >= w[curr]) {

		t1 = f(curr - 1, rem - w[curr]) + v[curr];

		ans = max(ans, t1);

	}

	t2 = f(curr - 1, rem);

	ans = max(ans, t2);

	return mep[param] = ans;

}

int main(){



	ios::sync_with_stdio(false);

	cin.tie(0);



	cin >> n >> W;

	for (int i = 1; i <= n; i++) cin >> w[i] >> v[i];

	ll ans = f(n, W);

	cout << ans;

	return 0;	

}


// Faster C++ solution for the same problem (measured speedup: 5.28519597002774x):
#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

typedef long long LL;

struct huowu

{

	int w,v;

}g[105];

huowu A[105], B[105], C[105], D[105];

bool cmp(huowu a,huowu b)

{

	return a.v > b.v;

}

int n,W;

int main()

{

	scanf("%d %d",&n,&W);

	int a, b, c, d, f;

	a = b = c = d = f = 0;

	for(int i = 1;i <= n;i++)

	{

		scanf("%d %d",&g[i].w,&g[i].v);

		if(g[i].w == g[1].w)

		{

			A[++a] = g[i];

		}

		else if(g[i].w == g[1].w + 1)

		{

			B[++b] = g[i];

		}

		else if(g[i].w == g[1].w + 2)

		{

			C[++c] = g[i];

		}

		else if(g[i].w == g[1].w + 3)

		{

			D[++d] = g[i];

		}

	}

	sort(A + 1,A + 1 + a,cmp);

	sort(B + 1,B + 1 + b,cmp);

	sort(C + 1,C + 1 + c,cmp);

	sort(D + 1,D + 1 + d,cmp);

	LL swa[110],swb[110],swc[110],swd[110];

	LL sva[110],svb[110],svc[110],svd[110];

	swa[0] = swb[0] = swc[0] = swd[0] = 0;  

    sva[0] = svb[0] = svc[0] = svd[0] = 0;  

    for(int i = 1;i <= a;i++)  

    {  

        swa[i] = swa[i - 1] + A[i].w;  

        sva[i] = sva[i - 1] + A[i].v;  

    }  

    for(int i = 1;i <= b;i++)  

    {  

        swb[i] = swb[i - 1] + B[i].w;  

        svb[i] = svb[i - 1] + B[i].v;  

     }  

     for(int i = 1;i <= c;i++)  

     {  

         swc[i] = swc[i - 1] + C[i].w;  

         svc[i] = svc[i - 1] + C[i].v;  

     }  

     for(int i = 1;i <= d;i++)  

     {  

        swd[i] = swd[i - 1] + D[i].w;  

        svd[i] = svd[i - 1] + D[i].v;  

      }  

    int sumv = 0;  

    int ans = 0;  

	for(int i = 0;i <= a;i++)  

    {  

         for(int j = 0;j <= b;j++)  

         {  

            for(int k = 0;k <= c;k++)  

            {  

             for(int l = 0;l <= d;l++)  

              {  

			      LL sum = swa[i] + swb[j] + swc[k] + swd[l];  

					if(sum <= (LL)W)  

					{  

                      f = max((LL)f,sva[i] + svb[j] + svc[k] + svd[l]);  

					}  

			 }  

            }  

        }  

    }  

    printf("%d\n",f); 

    return 0;  

}