n, W = list(map(int, input().split()))

wv = [list(map(int, input().split())) for _ in range(n)]



dp = [[[-1] * (3 * n + 1) for _ in range(n + 1)] for _ in range(n + 1)]

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

w1 = wv[0][0]



for i, (w, v) in enumerate(wv):

    for j in range(i + 1):

        for k in range(3 * n + 1):

            if dp[i][j][k] != -1:

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

                w_diff = w - w1

                if j + 1 <= n and k + w_diff <= 3 * n:

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



ans = 0

for j in range(n + 1):

    w_diff_mx = min(W - w1 * j, 3 * n)

    for k in range(w_diff_mx + 1):

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



print(ans)

from itertools import accumulate



n, W = list(map(int, input().split()))

wv = [list(map(int, input().split())) for _ in range(n)]



w1 = wv[0][0]

weights = [[] for _ in range(4)]



for w, v in wv:

    w_diff = w - w1

    weights[w_diff].append(v)



for i in range(4):

    weights[i].sort(reverse=True)



acc = [[0] + list(accumulate(li)) for li in weights]



ans = 0

for i, e1 in enumerate(acc[0]):

    for j, e2 in enumerate(acc[1]):

        for k, e3 in enumerate(acc[2]):

            for l, e4 in enumerate(acc[3]):

                if w1 * i + (w1 + 1) * j + (w1 + 2) * k + (w1 + 3) * l <= W:

                    ans = max(ans, e1 + e2 + e3 + e4)



print(ans)

n, W = list(map(int, input().split()))
wv = [list(map(int, input().split())) for _ in range(n)]
dp = [[[-1] * (3 * n + 1) for _ in range(n + 1)] for _ in range(n + 1)]
dp[0][0][0] = 0
w1 = wv[0][0]
for i, (w, v) in enumerate(wv):
    for j in range(i + 1):
        for k in range(3 * n + 1):
            if dp[i][j][k] != -1:
                dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k])
                w_diff = w - w1
                if j + 1 <= n and k + w_diff <= 3 * n:
                    dp[i + 1][j + 1][k + w_diff] = max(
                        dp[i + 1][j + 1][k + w_diff], dp[i][j][k] + v
                    )
ans = 0
for j in range(n + 1):
    w_diff_mx = min(W - w1 * j, 3 * n)
    for k in range(w_diff_mx + 1):
        ans = max(ans, dp[n][j][k])
print(ans)

from itertools import accumulate

n, W = list(map(int, input().split()))
wv = [list(map(int, input().split())) for _ in range(n)]
w1 = wv[0][0]
weights = [[] for _ in range(4)]
for w, v in wv:
    w_diff = w - w1
    weights[w_diff].append(v)
for i in range(4):
    weights[i].sort(reverse=True)
acc = [[0] + list(accumulate(li)) for li in weights]
ans = 0
for i, e1 in enumerate(acc[0]):
    for j, e2 in enumerate(acc[1]):
        for k, e3 in enumerate(acc[2]):
            for l, e4 in enumerate(acc[3]):
                if w1 * i + (w1 + 1) * j + (w1 + 2) * k + (w1 + 3) * l <= W:
                    ans = max(ans, e1 + e2 + e3 + e4)
print(ans)

+from itertools import accumulate + -dp = [[[-1] * (3 * n + 1) for _ in range(n + 1)] for _ in range(n + 1)] -dp[0][0][0] = 0 -for i, (w, v) in enumerate(wv): -    for j in range(i + 1): -        for k in range(3 * n + 1): -            if dp[i][j][k] != -1: -                dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k]) -                w_diff = w - w1 -                if j + 1 <= n and k + w_diff <= 3 * n: -                    dp[i + 1][j + 1][k + w_diff] = max( -                        dp[i + 1][j + 1][k + w_diff], dp[i][j][k] + v -                    ) +weights = [[] for _ in range(4)] +for w, v in wv: +    w_diff = w - w1 +    weights[w_diff].append(v) +for i in range(4): +    weights[i].sort(reverse=True) +acc = [[0] + list(accumulate(li)) for li in weights] -for j in range(n + 1): -    w_diff_mx = min(W - w1 * j, 3 * n) -    for k in range(w_diff_mx + 1): -        ans = max(ans, dp[n][j][k]) +for i, e1 in enumerate(acc[0]): +    for j, e2 in enumerate(acc[1]): +        for k, e3 in enumerate(acc[2]): +            for l, e4 in enumerate(acc[3]): +                if w1 * i + (w1 + 1) * j + (w1 + 2) * k + (w1 + 3) * l <= W: +                    ans = max(ans, e1 + e2 + e3 + e4)