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

l0=[]

l1=[]

l2=[]

l3=[]

for i in range(N):

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

    if i == 0:

        w1 = w

    if w == w1:

        l0.append(v)

    elif w == w1+1:

        l1.append(v)

    elif w == w1+2:

        l2.append(v)

    elif w == w1+3:

        l3.append(v)



l0.sort()

l0.reverse()

l1.sort()

l1.reverse()

l2.sort()

l2.reverse()

l3.sort()

l3.reverse()

l0 = [0]+l0

l1 = [0]+l1

l2 = [0]+l2

l3 = [0]+l3

import numpy as np

l0 = np.cumsum(np.array(l0))

l1 = np.cumsum(np.array(l1))

l2 = np.cumsum(np.array(l2))

l3 = np.cumsum(np.array(l3))



ans = 0

for i in range(len(l0)):

    for j in range(len(l1)):

        for k in range(len(l2)):

            for l in range(len(l3)):

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

                    if ans < l0[i]+l1[j]+l2[k]+l3[l]:

                         ans = l0[i]+l1[j]+l2[k]+l3[l]



print(ans)
from collections import defaultdict

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

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

w1 = wv[0][0]

ws = []

ijkl = [0,0,0,0]

for i in range(N):

    w = wv[i][0]

    ijkl[w-w1] += 1

for i in range(ijkl[0]+1):

    for j in range(ijkl[1]+1):

        for k in range(ijkl[2]+1):

            for l in range(ijkl[3]+1):

                w = i*w1+j*(w1+1)+k*(w1+2)+l*(w1+3)

                if w <= W:

                    ws.append(w)

ws = list(set(ws))

ws.sort()

dp = [defaultdict(lambda:-float('inf')) for _ in range(N+1)]

dp[0][0] = 0

for i in range(N):

    for j in ws:

        w,v = wv[i]

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

print((max(dp[N].values())))
N, W = list(map(int, input().split()))
l0 = []
l1 = []
l2 = []
l3 = []
for i in range(N):
    w, v = list(map(int, input().split()))
    if i == 0:
        w1 = w
    if w == w1:
        l0.append(v)
    elif w == w1 + 1:
        l1.append(v)
    elif w == w1 + 2:
        l2.append(v)
    elif w == w1 + 3:
        l3.append(v)
l0.sort()
l0.reverse()
l1.sort()
l1.reverse()
l2.sort()
l2.reverse()
l3.sort()
l3.reverse()
l0 = [0] + l0
l1 = [0] + l1
l2 = [0] + l2
l3 = [0] + l3
import numpy as np

l0 = np.cumsum(np.array(l0))
l1 = np.cumsum(np.array(l1))
l2 = np.cumsum(np.array(l2))
l3 = np.cumsum(np.array(l3))
ans = 0
for i in range(len(l0)):
    for j in range(len(l1)):
        for k in range(len(l2)):
            for l in range(len(l3)):
                if i * w1 + j * (w1 + 1) + k * (w1 + 2) + l * (w1 + 3) <= W:
                    if ans < l0[i] + l1[j] + l2[k] + l3[l]:
                        ans = l0[i] + l1[j] + l2[k] + l3[l]
print(ans)

from collections import defaultdict

N, W = list(map(int, input().split()))
wv = [list(map(int, input().split())) for _ in range(N)]
w1 = wv[0][0]
ws = []
ijkl = [0, 0, 0, 0]
for i in range(N):
    w = wv[i][0]
    ijkl[w - w1] += 1
for i in range(ijkl[0] + 1):
    for j in range(ijkl[1] + 1):
        for k in range(ijkl[2] + 1):
            for l in range(ijkl[3] + 1):
                w = i * w1 + j * (w1 + 1) + k * (w1 + 2) + l * (w1 + 3)
                if w <= W:
                    ws.append(w)
ws = list(set(ws))
ws.sort()
dp = [defaultdict(lambda: -float("inf")) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
    for j in ws:
        w, v = wv[i]
        dp[i + 1][j] = max(dp[i][j], dp[i][j - w] + v)
print((max(dp[N].values())))

+from collections import defaultdict + -l0 = [] -l1 = [] -l2 = [] -l3 = [] +wv = [list(map(int, input().split())) for _ in range(N)] +w1 = wv[0][0] +ws = [] +ijkl = [0, 0, 0, 0] -    w, v = list(map(int, input().split())) -    if i == 0: -        w1 = w -    if w == w1: -        l0.append(v) -    elif w == w1 + 1: -        l1.append(v) -    elif w == w1 + 2: -        l2.append(v) -    elif w == w1 + 3: -        l3.append(v) -l0.sort() -l0.reverse() -l1.sort() -l1.reverse() -l2.sort() -l2.reverse() -l3.sort() -l3.reverse() -l0 = [0] + l0 -l1 = [0] + l1 -l2 = [0] + l2 -l3 = [0] + l3 -import numpy as np - -l0 = np.cumsum(np.array(l0)) -l1 = np.cumsum(np.array(l1)) -l2 = np.cumsum(np.array(l2)) -l3 = np.cumsum(np.array(l3)) -ans = 0 -for i in range(len(l0)): -    for j in range(len(l1)): -        for k in range(len(l2)): -            for l in range(len(l3)): -                if i * w1 + j * (w1 + 1) + k * (w1 + 2) + l * (w1 + 3) <= W: -                    if ans < l0[i] + l1[j] + l2[k] + l3[l]: -                        ans = l0[i] + l1[j] + l2[k] + l3[l] -print(ans) +    w = wv[i][0] +    ijkl[w - w1] += 1 +for i in range(ijkl[0] + 1): +    for j in range(ijkl[1] + 1): +        for k in range(ijkl[2] + 1): +            for l in range(ijkl[3] + 1): +                w = i * w1 + j * (w1 + 1) + k * (w1 + 2) + l * (w1 + 3) +                if w <= W: +                    ws.append(w) +ws = list(set(ws)) +ws.sort() +dp = [defaultdict(lambda: -float("inf")) for _ in range(N + 1)] +dp[0][0] = 0 +for i in range(N): +    for j in ws: +        w, v = wv[i] +        dp[i + 1][j] = max(dp[i][j], dp[i][j - w] + v) +print((max(dp[N].values())))