def solve():

    from itertools import accumulate



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



    e = tuple([] for _ in range(4))

    w1, v1 = list(map(int, input().split()))

    e[0].append(v1)



    for _ in range(N - 1):

        _w, _v = list(map(int, input().split()))

        e[_w - w1].append(_v)



    g = [None for _ in range(4)]

    for j in range(4):

        e[j].sort(reverse=True)

        g[j] = (0,) + tuple(accumulate(e[j]))



    ret = 0

    for a in range(len(e[0]) + 1):

        for b in range(len(e[1]) + 1):

            for c in range(len(e[2]) + 1):

                diff = W - (w1 * a + (w1 + 1) * b + (w1 + 2) * c)

                if diff < 0:

                    break

                d = min(len(e[3]), diff // (w1 + 3))

                ret = max(ret, g[0][a] + g[1][b] + g[2][c] + g[3][d])

    return ret





print((solve()))



# https://atcoder.jp/contests/arc073/submissions/2794675

# https://atcoder.jp/contests/arc073/submissions/7328854

def main():

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

    ctr = [0] * 4

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



    w1, v1 = list(map(int, input().split()))

    ctr[0] += 1

    goods[0].append(v1)



    for _ in range(N - 1):

        wi, vi = list(map(int, input().split()))

        wi -= w1

        ctr[wi] += 1

        goods[wi].append(vi)



    for i in range(4):

        goods[i].sort(reverse=True)



    def accumulate(a):

        s = 0

        yield s

        for x in a:

            s += x

            yield s



    accs = [list(accumulate(goods_i)) for goods_i in goods]



    ans = -1

    for c0 in range(N + 1):

        if ctr[0] < c0: break

        if w1 * c0 > W: break



        v0 = accs[0][c0]

        for c1 in range(N - c0 + 1):

            if ctr[1] < c1: break

            if w1 * c0 + (w1 + 1) * c1 > W: break



            v1 = v0 + accs[1][c1]

            for c2 in range(N - c0 - c1 + 1):

                if ctr[2] < c2: break

                if w1 * c0 + (w1 + 1) * c1 + (w1 + 2) * c2 > W: break



                v2 = v1 + accs[2][c2]

                for c3 in range(N - c0 - c1 - c2 + 1):

                    if ctr[3] < c3: break

                    if w1 * c0 + (w1 + 1) * c1 + (w1 + 2) * c2 + (w1 + 3) * c3 > W: break

                    v3 = v2 + accs[3][c3]

                    ans = max(ans, v3)



    print(ans)





if __name__ == '__main__':

    main()



# import sys

#

# sys.setrecursionlimit(10 ** 7)

#

# input = sys.stdin.readline

# rstrip()

# int(input())

# map(int, input().split())

def solve():
    from itertools import accumulate

    N, W = list(map(int, input().split()))
    e = tuple([] for _ in range(4))
    w1, v1 = list(map(int, input().split()))
    e[0].append(v1)
    for _ in range(N - 1):
        _w, _v = list(map(int, input().split()))
        e[_w - w1].append(_v)
    g = [None for _ in range(4)]
    for j in range(4):
        e[j].sort(reverse=True)
        g[j] = (0,) + tuple(accumulate(e[j]))
    ret = 0
    for a in range(len(e[0]) + 1):
        for b in range(len(e[1]) + 1):
            for c in range(len(e[2]) + 1):
                diff = W - (w1 * a + (w1 + 1) * b + (w1 + 2) * c)
                if diff < 0:
                    break
                d = min(len(e[3]), diff // (w1 + 3))
                ret = max(ret, g[0][a] + g[1][b] + g[2][c] + g[3][d])
    return ret


print((solve()))
# https://atcoder.jp/contests/arc073/submissions/2794675
# https://atcoder.jp/contests/arc073/submissions/7328854

def main():
    N, W = list(map(int, input().split()))
    ctr = [0] * 4
    goods = [[] for _ in range(4)]
    w1, v1 = list(map(int, input().split()))
    ctr[0] += 1
    goods[0].append(v1)
    for _ in range(N - 1):
        wi, vi = list(map(int, input().split()))
        wi -= w1
        ctr[wi] += 1
        goods[wi].append(vi)
    for i in range(4):
        goods[i].sort(reverse=True)

    def accumulate(a):
        s = 0
        yield s
        for x in a:
            s += x
            yield s

    accs = [list(accumulate(goods_i)) for goods_i in goods]
    ans = -1
    for c0 in range(N + 1):
        if ctr[0] < c0:
            break
        if w1 * c0 > W:
            break
        v0 = accs[0][c0]
        for c1 in range(N - c0 + 1):
            if ctr[1] < c1:
                break
            if w1 * c0 + (w1 + 1) * c1 > W:
                break
            v1 = v0 + accs[1][c1]
            for c2 in range(N - c0 - c1 + 1):
                if ctr[2] < c2:
                    break
                if w1 * c0 + (w1 + 1) * c1 + (w1 + 2) * c2 > W:
                    break
                v2 = v1 + accs[2][c2]
                for c3 in range(N - c0 - c1 - c2 + 1):
                    if ctr[3] < c3:
                        break
                    if w1 * c0 + (w1 + 1) * c1 + (w1 + 2) * c2 + (w1 + 3) * c3 > W:
                        break
                    v3 = v2 + accs[3][c3]
                    ans = max(ans, v3)
    print(ans)


if __name__ == "__main__":
    main()
# import sys
#
# sys.setrecursionlimit(10 ** 7)
#
# input = sys.stdin.readline
# rstrip()
# int(input())
# map(int, input().split())

-def solve(): -    from itertools import accumulate +def main(): +    N, W = list(map(int, input().split())) +    ctr = [0] * 4 +    goods = [[] for _ in range(4)] +    w1, v1 = list(map(int, input().split())) +    ctr[0] += 1 +    goods[0].append(v1) +    for _ in range(N - 1): +        wi, vi = list(map(int, input().split())) +        wi -= w1 +        ctr[wi] += 1 +        goods[wi].append(vi) +    for i in range(4): +        goods[i].sort(reverse=True) -    N, W = list(map(int, input().split())) -    e = tuple([] for _ in range(4)) -    w1, v1 = list(map(int, input().split())) -    e[0].append(v1) -    for _ in range(N - 1): -        _w, _v = list(map(int, input().split())) -        e[_w - w1].append(_v) -    g = [None for _ in range(4)] -    for j in range(4): -        e[j].sort(reverse=True) -        g[j] = (0,) + tuple(accumulate(e[j])) -    ret = 0 -    for a in range(len(e[0]) + 1): -        for b in range(len(e[1]) + 1): -            for c in range(len(e[2]) + 1): -                diff = W - (w1 * a + (w1 + 1) * b + (w1 + 2) * c) -                if diff < 0: +    def accumulate(a): +        s = 0 +        yield s +        for x in a: +            s += x +            yield s + +    accs = [list(accumulate(goods_i)) for goods_i in goods] +    ans = -1 +    for c0 in range(N + 1): +        if ctr[0] < c0: +            break +        if w1 * c0 > W: +            break +        v0 = accs[0][c0] +        for c1 in range(N - c0 + 1): +            if ctr[1] < c1: +                break +            if w1 * c0 + (w1 + 1) * c1 > W: +                break +            v1 = v0 + accs[1][c1] +            for c2 in range(N - c0 - c1 + 1): +                if ctr[2] < c2: -                d = min(len(e[3]), diff // (w1 + 3)) -                ret = max(ret, g[0][a] + g[1][b] + g[2][c] + g[3][d]) -    return ret +                if w1 * c0 + (w1 + 1) * c1 + (w1 + 2) * c2 > W: +                    break +                v2 = v1 + accs[2][c2] +                for c3 in range(N - c0 - c1 - c2 + 1): +                    if ctr[3] < c3: +                        break +                    if w1 * c0 + (w1 + 1) * c1 + (w1 + 2) * c2 + (w1 + 3) * c3 > W: +                        break +                    v3 = v2 + accs[3][c3] +                    ans = max(ans, v3) +    print(ans) -print((solve())) -# https://atcoder.jp/contests/arc073/submissions/2794675 -# https://atcoder.jp/contests/arc073/submissions/7328854 +if __name__ == "__main__": +    main() +# import sys +# +# sys.setrecursionlimit(10 ** 7) +# +# input = sys.stdin.readline +# rstrip() +# int(input()) +# map(int, input().split())