CodeEff/ECCO huggingface dataset:
# Original solution
N,W = list(map(int, input().split()))
v_max = (10**3)*(N+1)
inf = float('inf')
dp = [inf for _ in range(v_max+1)]
dp[0] = 0
for _ in range(N):
	w,v = list(map(int, input().split()))
	for j in range(v_max,-1,-1):
		if j==0:
			dp[j] = 0
		else:
			a = dp[j]
			b = w + dp[j-v]		
			if v>j:
				dp[j] = a
			else:
				dp[j] = min(a,b)
ans = None
for i in range(v_max,-1,-1):
	z = dp[i]
	if z<=W and z!=inf:
		ans = i
		break
print(ans)

# Optimized solution
import sys
input = sys.stdin.buffer.readline
N,W = list(map(int, input().split()))
v_max = (10**3)*N
inf = float('inf')
dp = [inf for _ in range(v_max+1)]
dp[0] = 0
for _ in range(N):
	w,v = list(map(int, input().split()))
	for j in range(v_max,v-1,-1):
		b = w + dp[j-v]		
		if b<dp[j]:
			dp[j] = b

ans = None
for i in range(v_max+1):
	z = dp[i]
	if z<=W:
		ans = i

print(ans)
# Original solution
N,W=list(map(int,input().split()))
w=[]
v=[]
for _ in range(N):
    a,b=list(map(int,input().split()))
    w.append(a)
    v.append(b)
V=sum(v)

dp=[[V+1 for _ in range(V+1)] for _ in range(N+1)]
dp[0][0]=0
ans=0

for i in range(N): #i番目の荷物を拾うかどうか
    for j in range(V+1): #価値jを超える重量の最小値
        dp[i+1][j]=min(dp[i][j],dp[i][max(0,j-v[i])]+w[i])
        if dp[i+1][j]<=W:
            ans=max(ans,j)
        
print(ans)

# Optimized solution
N,W=list(map(int,input().split()))
w=[]
v=[]
for _ in range(N):
    a,b=list(map(int,input().split()))
    w.append(a)
    v.append(b)
V=sum(v)

dp=[[10**9 for _ in range(V+1)] for _ in range(N+1)]
dp[0][0]=0
ans=0

for i in range(N): #i番目の荷物を拾うかどうか
    for j in range(V+1): #価値jを超える重量の最小値
        dp[i+1][j]=min(dp[i][j],dp[i][max(0,j-v[i])]+w[i])
        if dp[i+1][j]<=W:
            ans=max(ans,j)
        
print(ans)
# Original solution
#E
inf = float("inf")
N,W = list(map(int,input().split()))
WV = [list(map(int,input().split())) for _ in range(N)]

dp = [[inf for j in range(10**5+1)] for i in range(N+1)] #dp[i][v] = W

for i in range(N):
    dp[i][0] = 0

for i in range(N):
    w,v = WV[i]
    for j in range(10**5+1):
        if j+v <= 10**5:
            dp[i+1][j+v] = min(dp[i][j]+w,dp[i][j+v])
        dp[i+1][j] = min(dp[i][j],dp[i+1][j])

#print(dp)
ans = 0
for j in range(10**5+1):
    w = dp[N][j]
    if w <= W:
        ans = j
        
print(ans)


# Optimized solution


n, w = list(map(int, input().split()))
wv = [list(map(int, input().split())) for _ in range(n)]
v_max = 10 ** 5
w_max = 10 ** 18
dp = [[w_max for _ in range(v_max + 1)] for _ in range(n + 1)]

for i in range(n):
    dp[i][0] = 0

for i in range(n):
    w_, v_ = wv[i]
    for j in range(v_max + 1):
        if j + v_ <= v_max:
            dp[i+1][j+v_] = min(dp[i][j] + w_, dp[i][j + v_])
        dp[i+1][j] = min(dp[i][j], dp[i+1][j])


ans = 0
for i in range(v_max + 1):
    w_ = dp[n][i]
    if w_ <= w:
        ans = i
print(ans)
# Original solution
n,W=list(map(int,input().split()))
w=[]
v=[]
for i in range(n):
  a,b=list(map(int,input().split()))
  w.append(a)
  v.append(b)
V=sum(v)
INF=10**18
dp=[[INF for _ in range(V+1)] for _ in range(n+1)]
dp[0][0]=0
for i in range(n):
  for j in range(V+1):
    if j<v[i]:dp[i+1][j]=dp[i][j]
    else:dp[i+1][j]=min(dp[i][j],dp[i][j-v[i]]+w[i])
for i in range(V+1):
  if dp[n][i]<=W:ans=i
print(ans)

# Optimized solution
INF=10**18
n,m=list(map(int,input().split()))
w=[0]*n
v=[0]*n
for i in range(n):
  w[i],v[i]=list(map(int,input().split()))
k=sum(v)
dp=[INF]*(k+1)
dp[0]=0
for i in range(n):
  for j in range(k,-1,-1):
    if j>=v[i] and dp[j-v[i]]!=INF:dp[j]=min(dp[j],dp[j-v[i]]+w[i])
for i,x in enumerate(dp):
  if x<=m:ans=i
print(ans)
# Original solution
# /usr/bin/python
# -*- coding: utf-8 -*-
#
import sys

N,W = list(map(int, input().split()))
v = [0] * N
w = [0] * N
for i in range(N):
  w[i],v[i] = list(map(int, input().split()))

dp = [float('inf')] * (10**5+1)
dp[0] = 0

MAX_V = 0
for i in range(N):
  MAX_V += v[i]
  for j in range(MAX_V,-1,-1):
    if j >= v[i] and dp[j-v[i]]+w[i] <= W:
      dp[j] = min(dp[j], dp[j-v[i]]+w[i])

ans = 0
for i in range(len(dp)):
  if dp[i] < float('inf'):
    ans = max(ans, i)
print(ans)

# Optimized solution
# /usr/bin/python
# -*- coding: utf-8 -*-
#
import sys

N,W = list(map(int, input().split()))
v = [0] * N
w = [0] * N
for i in range(N):
  w[i],v[i] = list(map(int, input().split()))

dp = [float('inf')] * (sum(v)+1)
dp[0] = 0

MAX_V = 0
ans = 0
for i in range(N):
  MAX_V += v[i]
  for j in range(MAX_V,-1,-1):
    if j >= v[i] and dp[j-v[i]]+w[i] <= W:
      ans = max(ans,j)
      dp[j] = min(dp[j], dp[j-v[i]]+w[i])
print(ans)
# Original solution
N,W = list(map(int,input().split()))
weight = [0]
value = [0]
for i in range(N):
    w,v = list(map(int,input().split()))
    weight.append(w)
    value.append(v)
maxValue = N*1000
dp = [[float("inf") for i in range(maxValue+1)] for j in range(N+1)]
for i in range(N+1):
    dp[i][0] = 0

for i in range(1,N+1):
    for v in range(1,maxValue+1):
        dp[i][v] = dp[i-1][v]
        if value[i] > v: continue;
        dp[i][v] = min(dp[i][v],weight[i] + dp[i-1][v-value[i]])
ans = 0
for x in range(maxValue+1):
    if dp[N][x] <= W:
        ans = x
print(ans)

# Optimized solution

N,W = list(map(int,input().split()))
weight = [0]
value = [0]
for i in range(N):
    w,v = list(map(int,input().split()))
    weight.append(w)
    value.append(v)
    
maxValue = sum(value)
dp = [[float("inf") for i in range(maxValue+1)] for j in range(N+1)]
for i in range(N+1):
    dp[i][0] = 0
for i in range(1,N+1):
    for v in range(1,maxValue+1):
        dp[i][v] = dp[i-1][v]
        if value[i] <= v:
            dp[i][v] = min(dp[i][v],weight[i] + dp[i-1][v-value[i]])
ans = 0
for x in range(maxValue+1):
    if dp[N][x] <= W:
        ans = x
print(ans)
# Original solution
N,W = list(map(int,input().split()))
INF = 10**9+7
NV = (10**3)*N
dp = [[0]+[INF for j in range(NV)] for i in range(N+1)]

for i in range(1,N+1):
    w,v = list(map(int,input().split()))
    for j in range(NV+1):
        if j < v:
            dp[i][j] = min(dp[i-1][j], w)
        else:
            dp[i][j] = min(dp[i-1][j], dp[i-1][j-v]+w)

ans = 0
for j in range(NV+1):
    if dp[N][j] <= W:
        ans = j
print(ans)


# Optimized solution
N,W = list(map(int,input().split()))
INF = 10**9+7
NV = (10**3)*N
dp = [[INF for j in range(NV+1)] for i in range(N+1)]
dp[0][0] = 0
for i in range(1,N+1):
    w,v = list(map(int,input().split()))
    for j in range(NV+1):
        if j < v:
            dp[i][j] = min(dp[i-1][j], w)
        else:
            dp[i][j] = min(dp[i-1][j], dp[i-1][j-v]+w)
ans = 0
for j in range(NV+1):
    if dp[N][j] <= W:
        ans = j
print(ans)
# Original solution
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()))

V = sum(v)
# dp[i][j]:i番目までの品物から価値がj以上になるよう選んだときの重さの総和の最小値
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0

for i in range(N):
    for j in range(V + 1):
        # i+1番目を入れる場合vs入れない場合（前の段階から足し合わせることで価値がj以上になる場合）
        if j - v[i] >= 0:
            dp[i + 1][j] = min(dp[i][j], dp[i][j - v[i]] + w[i])
        else:
            dp[i + 1][j] = dp[i][j]

# dp[N][j]がW以下であるようなjの最大値が答えになる
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)

# Optimized solution
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()))

V = sum(v)
Vi=[0] * N
for i in range(N):
    if i==0:
        Vi[i]=v[i]
    else:
        Vi[i]=Vi[i-1]+v[i]

# dp[i][j]:i番目までの品物から価値がj以上になるよう選んだときの重さの総和の最小値
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0

for i in range(N):
    for j in range(Vi[i] + 1):
        # i+1番目を入れる場合vs入れない場合（前の段階から足し合わせることで価値がj以上になる場合）
        if j - v[i] >= 0:
            dp[i + 1][j] = min(dp[i][j], dp[i][j - v[i]] + w[i])
        else:
            dp[i + 1][j] = dp[i][j]

# dp[N][j]がW以下であるようなjの最大値が答えになる
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)
# Original solution
import sys


def solve():
    input = sys.stdin.readline
    mod = 10 ** 9 + 7
    n, w = list(map(int, input().rstrip('\n').split()))
    dp = [10 ** 10] * (1000 * n + 1)
    dp[0] = 0
    mw = 0
    for _ in range(n):
        wv, vv = list(map(int, input().rstrip('\n').split()))
        for i in range(1000 * n - vv, -1, -1):
            dp[i+vv] = min(dp[i+vv], dp[i] + wv)
    mt = 0
    for i in range(len(dp)):
        if dp[i] <= w:
            mt = max(mt, i)
    print(mt)


if __name__ == '__main__':
    solve()


# Optimized solution
import sys


def solve():
    input = sys.stdin.readline
    mod = 10 ** 9 + 7
    n, w = list(map(int, input().rstrip('\n').split()))
    dp = [10 ** 10] * (n * 10 ** 3 + 1)
    dp[0] = 0
    mv = 0
    for i in range(n):
        wv, vv = list(map(int, input().rstrip('\n').split()))
        for j in range(mv, -1, -1):
            dp[j+vv] = min(dp[j+vv], dp[j] + wv)
            mv = max(mv, j+vv if dp[j+vv] != 10 ** 10 else mv)
    mi = 0
    for i in range(len(dp)):
        if dp[i] <= w:
            mi = i
    print(mi)


if __name__ == '__main__':
    solve()
# Original solution
#import
#import math
#import numpy as np
#= int(input())
#= input()
N, W = list(map(int, input().split()))
#= list(map(int, input().split()))
#= [input(), input()]

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

dp = [[10**10] * (10 ** 5 + 10) for _ in range(N + 1)]

dp[0][0] = 0

#  i:N個目 j:価値

for i, (w, v) in enumerate(x, 1):
    for j in range(10**5 + 1):
        dp[i][j] = dp[i - 1][j]
        if j != 0 and v <= j:
            dp[i][j] = min(dp[i][j], dp[i - 1][j - v] + w)

for i in range(10 ** 5, -1, -1):
    if dp[-1][i] <= W:
        print(i)
        exit()


# Optimized solution
#!/usr/bin/env python3

#import
#import math
#import numpy as np
N, W = list(map(int, input().split()))
wv = [list(map(int, input().split())) for _ in range(N)]

dp = [10 ** 10] * (10 ** 5 + 1)
dp[0] = 0

for w, v in wv:
    for i in range(10 ** 5, 0, -1):
        if i - v < 0:
            break

        dp[i] = min(dp[i], dp[i - v] + w)

for i in range(10 ** 5, 0, -1):
    if dp[i] <= W:
        print(i)
        exit()
# Original solution
N,W = list(map(int,input().split()))
src = [tuple(map(int,input().split())) for i in range(N)]

dp = [{0:0} for i in range(N+1)]
for i,(w,v) in enumerate(src):
    for v0,w0 in list(dp[i].items()):
        if v0 in dp[i+1]:
            dp[i+1][v0] = min(dp[i+1][v0], w0)
        else:
            dp[i+1][v0] = w0
        if w0+w > W: continue
        if v0+v in dp[i+1]:
            dp[i+1][v0+v] = min(dp[i+1][v0+v], w0+w)
        else:
            dp[i+1][v0+v] = w0+w
print((max(dp[-1].keys())))

# Optimized solution
N,W = list(map(int,input().split()))
wv = [tuple(map(int,input().split())) for i in range(N)]

dp = [{} for i in range(N+1)]
dp[0][0] = 0
for i,(w,v) in enumerate(wv):
    for v0,w0 in list(dp[i].items()):
        if v0 in dp[i+1]:
            dp[i+1][v0] = min(dp[i+1][v0], w0)
        else:
            dp[i+1][v0] = w0
        if w0+w > W: continue
        if v0+v in dp[i+1]:
            dp[i+1][v0+v] = min(dp[i+1][v0+v], w0+w)
        else:
            dp[i+1][v0+v] = w0+w
print((max(dp[-1].keys())))
# Original solution
def main():
    N, W = list(map(int, input().split()))
    w = [0] * N
    v = [0] * N
    for i in range(N):
        w[i], v[i] = list(map(int, input().split()))

    max_v = max(v)
    dp = [[float('inf')] * (max_v * N + 5) for _ in range(N + 5)]

    dp[0][0] = 0

    for i in range(N):
        for j in range(max_v * N):
            if j + v[i] <= max_v * N:
                dp[i+1][j + v[i]] = min(dp[i+1][j + v[i]], dp[i][j] + w[i])
            dp[i+1][j] = min(dp[i+1][j], dp[i][j]) 

    ans = 0
    for j in range(max_v * N + 1):
        if dp[N][j] <= W:
            ans = j

    print(ans)

if __name__ == "__main__":
    main()

# Optimized solution
def main():
    N, W = list(map(int, input().split()))
    weight = [0] * N
    value = [0] * N
    for i in range(N):
        weight[i], value[i] = list(map(int, input().split()))
    V = sum(value)
    dp = [[float('inf')] * (V + 5) for _ in range(N + 5)]
    dp[0][0] = 0
    for i in range(N):
        for v in range(V+1):
            if v - value[i] >= 0:
                dp[i+1][v] = min(dp[i][v-value[i]] + weight[i], dp[i][v])
            else:
                dp[i+1][v] = dp[i][v]
    ans = 0
    for v in range(V+1):
        if dp[N][v] <= W:
            ans = v
    print(ans)

if __name__ == "__main__":
    main()
# Original solution
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()))

V = sum(v)
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
"""
for j in range(V + 1):
	dp[0][j] = 0
"""
dp[0][0] = 0
# dp[i][j]:i番目までの品物から価値がj以上になるよう選んだときの重さの総和の最小値
for i in range(N):
	for j in range(V + 1):
		# i+1番目を選ぶ場合
		if j - v[i] >= 0:
			dp[i + 1][j] = min(dp[i + 1][j], dp[i][j - v[i]] + w[i])
		# i+1番目を選ばない場合
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])

# print(dp)

# dp[N][j]がW以下であるようなjの最大値が答えになる
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)


# Optimized solution
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()))

V = sum(v)
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
	for j in range(V + 1):
		if j - v[i] >= 0:
			dp[i + 1][j] = min(dp[i + 1][j], dp[i][j - v[i]] + w[i])
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])

ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)
# Original solution
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()))

V = sum(v)
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
	for j in range(V + 1):
		if j - v[i] >= 0:
			dp[i + 1][j] = min(dp[i + 1][j], dp[i][j - v[i]] + w[i])
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])

ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)


# Optimized solution
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()))

V = sum(v)
# dp[i][j]:i番目までの品物から価値がj以上になるよう選んだときの重さの総和の最小値
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
	for j in range(V + 1):
		# i+1番目を選ぶ場合
		if j - v[i] >= 0:
			dp[i + 1][j] = min(dp[i + 1][j], dp[i][j - v[i]] + w[i])
		# i+1番目を選ばない場合
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])

# dp[N][j]がW以下であるようなjの最大値が答えになる
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)
# Original solution
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()))

V = sum(v)
# dp[i][j]:i番目までの品物から価値がj以上になるよう選んだときの重さの総和の最小値
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
	for j in range(V + 1):
		# i+1番目を選ぶ場合
		if j - v[i] >= 0:
			dp[i + 1][j] = min(dp[i + 1][j], dp[i][j - v[i]] + w[i])
		# i+1番目を選ばない場合
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])

# dp[N][j]がW以下であるようなjの最大値が答えになる
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j

print(ans)


# Optimized solution
import sys
input = sys.stdin.readline

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()))
V = sum(v)
dp = [[float("inf")] * (V + 1) for _ in range(N + 1)]
dp[0][0] = 0
for i in range(N):
	for j in range(V + 1):
		if j - v[i] >= 0:
			dp[i + 1][j] = dp[i][j - v[i]] + w[i]
		dp[i + 1][j] = min(dp[i + 1][j], dp[i][j])
ans = 0
for j in range(V + 1):
	if dp[N][j] <= W:
		ans = j
print(ans)
# Original solution
n,k = list(map(int,input().split()))
w=[]
v=[]
MAX_N = 110
MAX_V=100100
dp =[[float("inf") for i in range(MAX_V)] for j in range(MAX_N)]
dp[0][0] = 0

for i in range(n):
    a,b = list(map(int,input().split()))
    w.append(a)
    v.append(b)
for i in range(n):
    for sum_v in range(MAX_V):
        if sum_v - v[i] >=0:
            dp[i+1][sum_v]=min(dp[i][sum_v],dp[i][sum_v - v[i]] + w[i])
        
        dp[i+1][sum_v]=min(dp[i][sum_v],dp[i+1][sum_v])
for sum_v in range(MAX_V):
    if dp[n][sum_v] <= k:
        res = sum_v
print(res)

# Optimized solution
N, W = list(map(int, input().split()))
a = []
for i in range(N):
    x,y = list(map(int,input().split()))
    a.append([x,y])
max_v, inf = 10**5, float("inf")
dp = [0] + [inf]*max_v
 
for w, v in a:
    for i, j in zip(list(range(max_v-v, -1, -1)), list(range(max_v, -1, -1))):
        if dp[i]+w <= W and dp[j] > dp[i]+w:
            dp[j] = dp[i]+w
 
for weight, value in zip(dp[::-1], list(range(max_v, -1, -1))):
    if weight != inf:
        print(value)
        break
# Original solution
n, w = list(map(int, input().split()))
weights, values = list(zip(*[tuple(map(int, input().split())) for _ in range(n)]))
UV = 10**5
INF = 10**10
dp = [[INF]*(UV+1) for _ in range(n+1)]
for i in range(n+1):
    dp[i][0] = 0
    
for i in range(1, n+1):
    for j in range(1, UV+1):
        dp[i][j] = dp[i-1][j]
        if 0 <= j-values[i-1]:
            dp[i][j] = min(dp[i][j], dp[i-1][j-values[i-1]]+weights[i-1])

ans = 0
for i in reversed(list(range(UV+1))):
    if dp[-1][i] <= w:
        ans = i
        break
print(ans)

# Optimized solution
n, w = list(map(int, input().split()))
weights, values = list(zip(*[tuple(map(int, input().split())) for _ in range(n)]))
UV = 10**5
INF = 10**10
dp = [INF]*(UV+1)
dp[0] = 0

for i in range(1, n+1):
    for j in reversed(list(range(1, UV+1))):
        if j-values[i-1] < 0:
            continue
        dp[j] = min(dp[j], dp[j-values[i-1]]+weights[i-1])

ans = 0
for j in reversed(list(range(UV+1))):
    if dp[j] <= w:
        ans = j
        break
print(ans)
# Original solution
# coding: utf-8
# Your code here!
# coding: utf-8
# Your code here!
N,W=list(map(int,input().split()))

l=[10**10]*(10**5+1)
l[0]=0
dp=l[:]

#indexが価値　itemが重さ
for i in range(N):
    w,v=list(map(int,input().split()))
    for index,item in enumerate(l):
        if item!=10**10 and item+w<=W:
            dp[index+v]=min(l[index+v],item+w)
    l=dp[:]

ans=0
for index, item in enumerate(l):
    if item!=10**10:
        ans=index
    else:
        continue
print(ans)



# Optimized solution
# coding: utf-8
# Your code here!
N,W=list(map(int,input().split()))

jwels=[]

for _ in range(N):
    jwels.append(list(map(int,input().split())))

dp=[10**10]*(10**5+1)
dp[0]=0

for w,v in jwels:
    for i in range(10**5+1)[::-1]:
        if dp[i]!=10**10 and i+v<=10**5:
            dp[i+v]=min(dp[i]+w,dp[i+v])

#print(dp[:100])

for i in range(10**5+1)[::-1]:
    if dp[i]<=W:
        print(i)
        break
# Original solution
N, W = list(map(int, input().split()))

MAX_V = N * (10 ** 3)
w, v = [], []
for _ in range(N):
    a, b = list(map(int, input().split()))
    w.append(a)
    v.append(b)

dp = [[10**9+7 for _ in range(MAX_V + 1)] for _ in range(N + 1)]
dp[0][0] = 0

for i in range(N):
    for j in range(MAX_V + 1):
        if j - v[i] >= 0:
            dp[i + 1][j] = min(dp[i][j],dp[i][j - v[i]] + w[i])
        else:
            dp[i + 1][j] = dp[i][j]

mv = 0
for i in range(MAX_V + 1):
    if dp[N][i] <= W:
        mv = i
print(mv)


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

MAX_V = N * (10 ** 3)
w, v = [], []
for _ in range(N):
    a, b = list(map(int, input().split()))
    w.append(a)
    v.append(b)

dp = [10**9+7 for _ in range(MAX_V + 1)]
dp[0] = 0

for i in range(N):
    for j in range(MAX_V, -1, -1):
        if j - v[i] >= 0:
            dp[j] = min(dp[j],dp[j - v[i]] + w[i])
        else:
            dp[j] = dp[j]

mv = 0
for i in range(MAX_V + 1):
    if dp[i] <= W:
        mv = i

print(mv)
# Original solution
N, W = list(map(int, input().split()))
items = [None] * N
for n in range(N):
    w, v = list(map(int, input().split()))
    items[n] = (w, v)
V = 10 ** 6 + 1

dp = [[10 ** 9 + 1] * V for _ in range(N + 1)]
dp[0][0] = 0

for i in range(N):
    for j in range(V):
        w, v = items[i]
        if j >= v:
            dp[i + 1][j] = min(dp[i][j - v] + w, dp[i][j])
        else:
            dp[i + 1][j] = dp[i][j]

ans = 0
for v in range(V):
    if dp[N][v] <= W:
        ans = v
print(ans)


# Optimized solution
N, W = list(map(int, input().split()))
items = [None] * N
for n in range(N):
    w, v = list(map(int, input().split()))
    items[n] = (w, v)
V = 10 ** 5 + 1

dp = [[10 ** 9 + 1] * V for _ in range(N + 1)]
dp[0][0] = 0

for i in range(N):
    for j in range(V):
        w, v = items[i]
        if j >= v:
            dp[i + 1][j] = min(dp[i][j - v] + w, dp[i][j])
        else:
            dp[i + 1][j] = dp[i][j]

ans = 0
for v in range(V):
    if dp[N][v] <= W:
        ans = v
print(ans)
# Original solution
N, W = [int(i) for i in input().split()]
weight, value = [0] * (N + 1), [0] * (N + 1)

for i in range(1, N + 1):
    weight[i], value[i] = [int(i) for i in input().split()]
#%%
sum_value = sum(value)
dp = [[float("inf")] * (sum_value + 1) for _ in range(N + 1)]
dp[0][0] = 0

for i in range(1, N + 1):
    for j in range(sum_value + 1):
        if j >= value[i]:
            dp[i][j] = weight[i] + dp[i - 1][j - value[i]]
        
        dp[i][j] = min(dp[i][j], dp[i -1][j])
        
ans = 0
for i in range(sum_value + 1):
    if dp[N][i] <= W:
        ans = i

print(ans)


# Optimized solution
N, W = [int(i) for i in input().split()]
weight, value = [0] * (N + 1), [0] * (N + 1)

for i in range(1, N + 1):
    weight[i], value[i] = [int(i) for i in input().split()]

#%%

sum_value = sum(value)
dp = [[float("inf")] * (sum_value + 1) for _ in range(N + 1)]
dp[0][0] = 0

for i in range(1, N + 1):
    for j in range(sum_value + 1):
        if j >= value[i]:
            dp[i][j] = min(dp[i - 1][j], weight[i] + dp[i - 1][j - value[i]])
        else:
            dp[i][j] = dp[i -1][j]
        
ans = 0
for i in range(sum_value + 1):
    if dp[N][i] <= W:
        ans = i

print(ans)
# Original solution
N, W = [int(_) for _ in input().split()]
WV = [[int(_) for _ in input().split()] for _ in range(N)]
dp = {}
dp[0] = 0
for w, v in WV:
    dp_o = dp.copy()
    for k in dp_o:
        if k + w <= W:
            dp[k + w] = max(dp_o.get(k + w, 0), dp_o[k] + v)
print((max([v for k, v in list(dp.items())])))


# Optimized solution
N, W = [int(_) for _ in input().split()]
WV = [[int(_) for _ in input().split()] for _ in range(N)]
dp = {}
dp[0] = 0
for w, v in WV:
    dp_o = dp.copy()
    for k in dp_o:
        dp[k + v] = min(dp_o.get(k + v, float('inf')), dp_o[k] + w)
print((max([k for k, v in list(dp.items()) if v <= W])))
# Original solution
from collections import defaultdict

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

dp = defaultdict(int)
dp[0] = 0
idx2check = {0}
for _ in range(N):
    w, v = list(map(int, input().split()))
    new_idx2check = set()
    for k in idx2check:
        dp[k + w] = max(dp[k + w], dp[k] + v)
        new_idx2check.add(k+w)

    idx2check |= new_idx2check

ans = 0
for k, v in list(dp.items()):
    if k <= W:
        ans = max(ans, v)

print(ans)


# Optimized solution
from collections import defaultdict

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

dp = defaultdict(lambda: 1e9)
dp[0] = 0
ans = 0
for _ in range(N):
    w, v = list(map(int, input().split()))
    keys = sorted(list(dp.keys()), reverse=True)
    for k in keys:
        dp[k + v] = min(dp[k + v], dp[k] + w)
        if dp[k + v] <= W:
            ans = max(ans, k + v)


print(ans)