import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda :sys.stdin.readline().rstrip()



from collections import defaultdict

def resolve():

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

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



    weight=set()

    for i in range(n+1):

        if(WV[0][0]*i>W): break

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

            if(WV[0][0]*i+j>W): break

            weight.add(WV[0][0]*i+j)

    weight=sorted(weight)



    dp=defaultdict(int)

    for i in range(n):

        ndp=defaultdict(int)

        w,v=WV[i]

        for key in weight:

            ndp[key]=max(ndp[key],dp[key])

            if(key+w<=W): ndp[key+w]=max(ndp[key+w],dp[key]+v)

        dp=ndp



    print((max(dp.values())))

resolve()
import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda :sys.stdin.readline().rstrip()

def resolve():

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

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

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

    V[0].append(v)

    for _ in range(n-1):

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

        V[w-w0].append(v)

    for i in range(4):

        V[i].sort(reverse=1)

        for j in range(len(V[i])-1):

            V[i][j+1]+=V[i][j]

    for i in range(4):

        V[i].insert(0,0)



    ans=0

    from itertools import product

    for a,b,c,d in product(list(range(len(V[0]))),list(range(len(V[1]))),list(range(len(V[2]))),list(range(len(V[3])))):

        v=V[0][a]+V[1][b]+V[2][c]+V[3][d]

        if(a*w0+b*(w0+1)+c*(w0+2)+d*(w0+3)<=W): ans=max(ans,v)

    print(ans)

resolve()
import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()
from collections import defaultdict


def resolve():
    n, W = list(map(int, input().split()))
    WV = [tuple(map(int, input().split())) for _ in range(n)]
    weight = set()
    for i in range(n + 1):
        if WV[0][0] * i > W:
            break
        for j in range(3 * i + 1):
            if WV[0][0] * i + j > W:
                break
            weight.add(WV[0][0] * i + j)
    weight = sorted(weight)
    dp = defaultdict(int)
    for i in range(n):
        ndp = defaultdict(int)
        w, v = WV[i]
        for key in weight:
            ndp[key] = max(ndp[key], dp[key])
            if key + w <= W:
                ndp[key + w] = max(ndp[key + w], dp[key] + v)
        dp = ndp
    print((max(dp.values())))


resolve()

import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()


def resolve():
    n, W = list(map(int, input().split()))
    w0, v = list(map(int, input().split()))
    V = [[] for _ in range(4)]
    V[0].append(v)
    for _ in range(n - 1):
        w, v = list(map(int, input().split()))
        V[w - w0].append(v)
    for i in range(4):
        V[i].sort(reverse=1)
        for j in range(len(V[i]) - 1):
            V[i][j + 1] += V[i][j]
    for i in range(4):
        V[i].insert(0, 0)
    ans = 0
    from itertools import product

    for a, b, c, d in product(
        list(range(len(V[0]))),
        list(range(len(V[1]))),
        list(range(len(V[2]))),
        list(range(len(V[3]))),
    ):
        v = V[0][a] + V[1][b] + V[2][c] + V[3][d]
        if a * w0 + b * (w0 + 1) + c * (w0 + 2) + d * (w0 + 3) <= W:
            ans = max(ans, v)
    print(ans)


resolve()

-from collections import defaultdict -    WV = [tuple(map(int, input().split())) for _ in range(n)] -    weight = set() -    for i in range(n + 1): -        if WV[0][0] * i > W: -            break -        for j in range(3 * i + 1): -            if WV[0][0] * i + j > W: -                break -            weight.add(WV[0][0] * i + j) -    weight = sorted(weight) -    dp = defaultdict(int) -    for i in range(n): -        ndp = defaultdict(int) -        w, v = WV[i] -        for key in weight: -            ndp[key] = max(ndp[key], dp[key]) -            if key + w <= W: -                ndp[key + w] = max(ndp[key + w], dp[key] + v) -        dp = ndp -    print((max(dp.values()))) +    w0, v = list(map(int, input().split())) +    V = [[] for _ in range(4)] +    V[0].append(v) +    for _ in range(n - 1): +        w, v = list(map(int, input().split())) +        V[w - w0].append(v) +    for i in range(4): +        V[i].sort(reverse=1) +        for j in range(len(V[i]) - 1): +            V[i][j + 1] += V[i][j] +    for i in range(4): +        V[i].insert(0, 0) +    ans = 0 +    from itertools import product + +    for a, b, c, d in product( +        list(range(len(V[0]))), +        list(range(len(V[1]))), +        list(range(len(V[2]))), +        list(range(len(V[3]))), +    ): +        v = V[0][a] + V[1][b] + V[2][c] + V[3][d] +        if a * w0 + b * (w0 + 1) + c * (w0 + 2) + d * (w0 + 3) <= W: +            ans = max(ans, v) +    print(ans)