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

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



dp = [[0] * (W+1) for _ in range(N+1)]





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

    for w in range(1, W+1):

        if w >= WV[i-1][0]:

            dp[i][w] = max(dp[i-1][w], dp[i-1][w-WV[i-1][0]] + WV[i-1][1])

        else:

            dp[i][w] = dp[i-1][w]

print((dp[N][W]))

import numpy as np



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

w, v = [0] * n, [0] * n

for i in range(n):

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

ndp = np.zeros(W + 1, dtype=np.int64)



for w, v in zip(w, v):

    # [:w]は品物の重量がナップサックの空きよりも重いので更新しない。

    # ndp[w:] は通常DPでのdp[i][w]=dp[i-1][w]。そのままでの更新。

    # ndp[:-w] + v は[:-w]が[w-weight]に相当。

    np.maximum(ndp[:-w] + v, ndp[w:], out=ndp[w:])



print((ndp[-1]))

N, W = list(map(int, input().split()))
WV = [tuple(map(int, input().split())) for _ in range(N)]
dp = [[0] * (W + 1) for _ in range(N + 1)]
for i in range(1, N + 1):
    for w in range(1, W + 1):
        if w >= WV[i - 1][0]:
            dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - WV[i - 1][0]] + WV[i - 1][1])
        else:
            dp[i][w] = dp[i - 1][w]
print((dp[N][W]))

import numpy as np

n, W = list(map(int, input().split()))
w, v = [0] * n, [0] * n
for i in range(n):
    w[i], v[i] = list(map(int, input().split()))
ndp = np.zeros(W + 1, dtype=np.int64)
for w, v in zip(w, v):
    # [:w]は品物の重量がナップサックの空きよりも重いので更新しない。
    # ndp[w:] は通常DPでのdp[i][w]=dp[i-1][w]。そのままでの更新。
    # ndp[:-w] + v は[:-w]が[w-weight]に相当。
    np.maximum(ndp[:-w] + v, ndp[w:], out=ndp[w:])
print((ndp[-1]))

-N, W = list(map(int, input().split())) -WV = [tuple(map(int, input().split())) for _ in range(N)] -dp = [[0] * (W + 1) for _ in range(N + 1)] -for i in range(1, N + 1): -    for w in range(1, W + 1): -        if w >= WV[i - 1][0]: -            dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - WV[i - 1][0]] + WV[i - 1][1]) -        else: -            dp[i][w] = dp[i - 1][w] -print((dp[N][W])) +import numpy as np + +n, W = list(map(int, input().split())) +w, v = [0] * n, [0] * n +for i in range(n): +    w[i], v[i] = list(map(int, input().split())) +ndp = np.zeros(W + 1, dtype=np.int64) +for w, v in zip(w, v): +    # [:w]は品物の重量がナップサックの空きよりも重いので更新しない。 +    # ndp[w:] は通常DPでのdp[i][w]=dp[i-1][w]。そのままでの更新。 +    # ndp[:-w] + v は[:-w]が[w-weight]に相当。 +    np.maximum(ndp[:-w] + v, ndp[w:], out=ndp[w:]) +print((ndp[-1]))