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

ws = []

vs = []

for i in range(N):

    w,v = list(map(int, input().split()))

    ws.append(w)

    vs.append(v)

ws_m = [w-ws[0] for w in ws]



"""

i番目まで見て、n個選んでいて、重さがwのときのvの最大値

ただし、wはN個選んだときにW-N*[w[0]]となっているので、そこをmaxとする

dp[i][n][w] 

"""



dp = [[[-1]*(3*N+1) for i in range(N+1)] for j in range(N+1)]

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

for i,(w,v)  in enumerate(zip(ws_m,vs)):

    for n in range(i+1):

        for j in range(3*N):

            if dp[i][n][j] == -1:continue

            dp[i+1][n+1][j+w] = max(dp[i][n][j] + v, dp[i][n][j+w])

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



ans = 0

for i,a in enumerate(dp[N]):

    w = W - i*ws[0]

    if w >= 0:

        ans = max(ans,max(a[:w+1]))

print(ans)   

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

wvs = []

for i in range(N):

    w,v = list(map(int, input().split()))

    wvs.append((w,v))

# dp : n個入っていて、合計がwのときの最大値

w0 = wvs[0][0]

dp = [[[-1]*(330) for i in range(110)] for k in range(110)]

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

for i in range(N):

    w, v = wvs[i]

    dw = w-w0

    for j in range(i+1):

        for k in range(310):

            # if k - dw >= 0:

            if dp[i][j][j] == -1:continue

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

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



d = dp[N]

ans = 0

for j in range(N+1):

    if W-j*w0 >= 0:

        a = max(d[j][:W-j*w0+1])

        ans = max(ans, a)

print(ans)
N, W = list(map(int, input().split()))
ws = []
vs = []
for i in range(N):
    w, v = list(map(int, input().split()))
    ws.append(w)
    vs.append(v)
ws_m = [w - ws[0] for w in ws]
"""
i番目まで見て、n個選んでいて、重さがwのときのvの最大値
ただし、wはN個選んだときにW-N*[w[0]]となっているので、そこをmaxとする
dp[i][n][w] 
"""
dp = [[[-1] * (3 * N + 1) for i in range(N + 1)] for j in range(N + 1)]
dp[0][0][0] = 0
for i, (w, v) in enumerate(zip(ws_m, vs)):
    for n in range(i + 1):
        for j in range(3 * N):
            if dp[i][n][j] == -1:
                continue
            dp[i + 1][n + 1][j + w] = max(dp[i][n][j] + v, dp[i][n][j + w])
            dp[i + 1][n][j] = max(dp[i + 1][n][j], dp[i][n][j])
ans = 0
for i, a in enumerate(dp[N]):
    w = W - i * ws[0]
    if w >= 0:
        ans = max(ans, max(a[: w + 1]))
print(ans)

N, W = list(map(int, input().split()))
wvs = []
for i in range(N):
    w, v = list(map(int, input().split()))
    wvs.append((w, v))
# dp : n個入っていて、合計がwのときの最大値
w0 = wvs[0][0]
dp = [[[-1] * (330) for i in range(110)] for k in range(110)]
dp[0][0][0] = 0
for i in range(N):
    w, v = wvs[i]
    dw = w - w0
    for j in range(i + 1):
        for k in range(310):
            # if k - dw >= 0:
            if dp[i][j][j] == -1:
                continue
            dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k])
            dp[i + 1][j + 1][k + dw] = max(dp[i][j][k] + v, dp[i + 1][j + 1][k + dw])
d = dp[N]
ans = 0
for j in range(N + 1):
    if W - j * w0 >= 0:
        a = max(d[j][: W - j * w0 + 1])
        ans = max(ans, a)
print(ans)

-ws = [] -vs = [] +wvs = [] -    ws.append(w) -    vs.append(v) -ws_m = [w - ws[0] for w in ws] -""" -i番目まで見て、n個選んでいて、重さがwのときのvの最大値 -ただし、wはN個選んだときにW-N*[w[0]]となっているので、そこをmaxとする -dp[i][n][w] -""" -dp = [[[-1] * (3 * N + 1) for i in range(N + 1)] for j in range(N + 1)] +    wvs.append((w, v)) +# dp : n個入っていて、合計がwのときの最大値 +w0 = wvs[0][0] +dp = [[[-1] * (330) for i in range(110)] for k in range(110)] -for i, (w, v) in enumerate(zip(ws_m, vs)): -    for n in range(i + 1): -        for j in range(3 * N): -            if dp[i][n][j] == -1: +for i in range(N): +    w, v = wvs[i] +    dw = w - w0 +    for j in range(i + 1): +        for k in range(310): +            # if k - dw >= 0: +            if dp[i][j][j] == -1: -            dp[i + 1][n + 1][j + w] = max(dp[i][n][j] + v, dp[i][n][j + w]) -            dp[i + 1][n][j] = max(dp[i + 1][n][j], dp[i][n][j]) +            dp[i + 1][j][k] = max(dp[i + 1][j][k], dp[i][j][k]) +            dp[i + 1][j + 1][k + dw] = max(dp[i][j][k] + v, dp[i + 1][j + 1][k + dw]) +d = dp[N] -for i, a in enumerate(dp[N]): -    w = W - i * ws[0] -    if w >= 0: -        ans = max(ans, max(a[: w + 1])) +for j in range(N + 1): +    if W - j * w0 >= 0: +        a = max(d[j][: W - j * w0 + 1]) +        ans = max(ans, a)