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()))



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

# dp[i][j](j=0,1,...,W)の値が求まっている状態で、dp[i+1][j]を更新することを考える

for i in range(N):

	for j in range(W + 1):

		# 品物(w[i],v[i])を選ぶとき、j-w[i]>=0に限って、価値v[i]が加算される

		if j - w[i] >= 0:

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

		# 品物(w[i],v[i])を選ばないとき、何も加算しない

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

print((dp[N][W]))
n, W = list(map(int,input().split()))

items = [[0,0] for _ in range(n+1)]

for i in range(n):

    items[i+1] = list(map(int, input().split()))



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

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

    weight, value = items[i][0], items[i][1]

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

        if w_limit - weight >= 0:

            dp[i][w_limit] = max(dp[i-1][w_limit], dp[i-1][w_limit-weight] + value)

        else:

            dp[i][w_limit] = dp[i-1][w_limit]

print((dp[n][W]))



        
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()))
dp = [[0] * (W + 1) for _ in range(N + 1)]
# dp[i][j](j=0,1,...,W)の値が求まっている状態で、dp[i+1][j]を更新することを考える
for i in range(N):
    for j in range(W + 1):
        # 品物(w[i],v[i])を選ぶとき、j-w[i]>=0に限って、価値v[i]が加算される
        if j - w[i] >= 0:
            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j - w[i]] + v[i])
        # 品物(w[i],v[i])を選ばないとき、何も加算しない
        dp[i + 1][j] = max(dp[i + 1][j], dp[i][j])
print((dp[N][W]))

n, W = list(map(int, input().split()))
items = [[0, 0] for _ in range(n + 1)]
for i in range(n):
    items[i + 1] = list(map(int, input().split()))
dp = [[0] * (W + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    weight, value = items[i][0], items[i][1]
    for w_limit in range(1, W + 1):
        if w_limit - weight >= 0:
            dp[i][w_limit] = max(
                dp[i - 1][w_limit], dp[i - 1][w_limit - weight] + value
            )
        else:
            dp[i][w_limit] = dp[i - 1][w_limit]
print((dp[n][W]))

-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())) -dp = [[0] * (W + 1) for _ in range(N + 1)] -# dp[i][j](j=0,1,...,W)の値が求まっている状態で、dp[i+1][j]を更新することを考える -for i in range(N): -    for j in range(W + 1): -        # 品物(w[i],v[i])を選ぶとき、j-w[i]>=0に限って、価値v[i]が加算される -        if j - w[i] >= 0: -            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j - w[i]] + v[i]) -        # 品物(w[i],v[i])を選ばないとき、何も加算しない -        dp[i + 1][j] = max(dp[i + 1][j], dp[i][j]) -print((dp[N][W])) +n, W = list(map(int, input().split())) +items = [[0, 0] for _ in range(n + 1)] +for i in range(n): +    items[i + 1] = list(map(int, input().split())) +dp = [[0] * (W + 1) for _ in range(n + 1)] +for i in range(1, n + 1): +    weight, value = items[i][0], items[i][1] +    for w_limit in range(1, W + 1): +        if w_limit - weight >= 0: +            dp[i][w_limit] = max( +                dp[i - 1][w_limit], dp[i - 1][w_limit - weight] + value +            ) +        else: +            dp[i][w_limit] = dp[i - 1][w_limit] +print((dp[n][W]))