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

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

w1 = wv[0][0]



w_to_idx = {0:0}

idx_to_w = {0:0}

idx_W = 0

def calc():

  global w_to_idx, idx_to_w, idx_W

  idx = 1

  w_max = 0

  for i in range(1, N+1):

    w = w1*i

    for j in range(3*i + 1):

      ww = w + j

      if ww in w_to_idx:

        continue

      w_to_idx[ww] = idx

      idx_to_w[idx] = ww

      if w_max < ww <= W:

        w_max = ww

        idx_W = idx

      idx += 1



calc()

n = len(w_to_idx)

dp = [[0]*n for i in range(N+1)]

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

  for j in range(n):

    dp[i][j] = dp[i-1][j]

    ww = idx_to_w[j]

    if ww >= w and ww-w in w_to_idx:

      jj = w_to_idx[ww - w]

      dp[i][j] = max(dp[i][j], dp[i-1][jj] + v)



print((max(dp[-1][:idx_W+1])))
from itertools import accumulate



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

wv = {}

w1 = 0

for i in range(N):

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

  if i == 0:

    w1 = w

  if w in wv:

    wv[w].append(v)

  else:

    wv[w] = [v]



for w in wv:

  wv[w].sort(reverse=True)

  wv[w] = [0] + list(accumulate(wv[w]))



w2 = w1+1; w3 = w1+2; w4 = w1+3

for w in [w1, w1+1, w1+2, w1+3]:

  if w not in wv:

    wv[w] = [0]



ans = 0

for n1 in range(len(wv[w1])):

  for n2 in range(len(wv[w2])):

    for n3 in range(len(wv[w3])):

      for n4 in range(len(wv[w4])):

        w = w1*n1 + w2*n2 + w3*n3 + w4*n4

        if w <= W:

          ans = max(ans, wv[w1][n1]+wv[w2][n2]+wv[w3][n3]+wv[w4][n4])



print(ans)
N, W = list(map(int, input().split()))
wv = [list(map(int, input().split())) for i in range(N)]
w1 = wv[0][0]
w_to_idx = {0: 0}
idx_to_w = {0: 0}
idx_W = 0


def calc():
    global w_to_idx, idx_to_w, idx_W
    idx = 1
    w_max = 0
    for i in range(1, N + 1):
        w = w1 * i
        for j in range(3 * i + 1):
            ww = w + j
            if ww in w_to_idx:
                continue
            w_to_idx[ww] = idx
            idx_to_w[idx] = ww
            if w_max < ww <= W:
                w_max = ww
                idx_W = idx
            idx += 1


calc()
n = len(w_to_idx)
dp = [[0] * n for i in range(N + 1)]
for i, (w, v) in enumerate(wv, 1):
    for j in range(n):
        dp[i][j] = dp[i - 1][j]
        ww = idx_to_w[j]
        if ww >= w and ww - w in w_to_idx:
            jj = w_to_idx[ww - w]
            dp[i][j] = max(dp[i][j], dp[i - 1][jj] + v)
print((max(dp[-1][: idx_W + 1])))

from itertools import accumulate

N, W = list(map(int, input().split()))
wv = {}
w1 = 0
for i in range(N):
    w, v = list(map(int, input().split()))
    if i == 0:
        w1 = w
    if w in wv:
        wv[w].append(v)
    else:
        wv[w] = [v]
for w in wv:
    wv[w].sort(reverse=True)
    wv[w] = [0] + list(accumulate(wv[w]))
w2 = w1 + 1
w3 = w1 + 2
w4 = w1 + 3
for w in [w1, w1 + 1, w1 + 2, w1 + 3]:
    if w not in wv:
        wv[w] = [0]
ans = 0
for n1 in range(len(wv[w1])):
    for n2 in range(len(wv[w2])):
        for n3 in range(len(wv[w3])):
            for n4 in range(len(wv[w4])):
                w = w1 * n1 + w2 * n2 + w3 * n3 + w4 * n4
                if w <= W:
                    ans = max(ans, wv[w1][n1] + wv[w2][n2] + wv[w3][n3] + wv[w4][n4])
print(ans)

+from itertools import accumulate + -wv = [list(map(int, input().split())) for i in range(N)] -w1 = wv[0][0] -w_to_idx = {0: 0} -idx_to_w = {0: 0} -idx_W = 0 - - -def calc(): -    global w_to_idx, idx_to_w, idx_W -    idx = 1 -    w_max = 0 -    for i in range(1, N + 1): -        w = w1 * i -        for j in range(3 * i + 1): -            ww = w + j -            if ww in w_to_idx: -                continue -            w_to_idx[ww] = idx -            idx_to_w[idx] = ww -            if w_max < ww <= W: -                w_max = ww -                idx_W = idx -            idx += 1 - - -calc() -n = len(w_to_idx) -dp = [[0] * n for i in range(N + 1)] -for i, (w, v) in enumerate(wv, 1): -    for j in range(n): -        dp[i][j] = dp[i - 1][j] -        ww = idx_to_w[j] -        if ww >= w and ww - w in w_to_idx: -            jj = w_to_idx[ww - w] -            dp[i][j] = max(dp[i][j], dp[i - 1][jj] + v) -print((max(dp[-1][: idx_W + 1]))) +wv = {} +w1 = 0 +for i in range(N): +    w, v = list(map(int, input().split())) +    if i == 0: +        w1 = w +    if w in wv: +        wv[w].append(v) +    else: +        wv[w] = [v] +for w in wv: +    wv[w].sort(reverse=True) +    wv[w] = [0] + list(accumulate(wv[w])) +w2 = w1 + 1 +w3 = w1 + 2 +w4 = w1 + 3 +for w in [w1, w1 + 1, w1 + 2, w1 + 3]: +    if w not in wv: +        wv[w] = [0] +ans = 0 +for n1 in range(len(wv[w1])): +    for n2 in range(len(wv[w2])): +        for n3 in range(len(wv[w3])): +            for n4 in range(len(wv[w4])): +                w = w1 * n1 + w2 * n2 + w3 * n3 + w4 * n4 +                if w <= W: +                    ans = max(ans, wv[w1][n1] + wv[w2][n2] + wv[w3][n3] + wv[w4][n4]) +print(ans)