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)

max_v = n*max(v)

c = [[0 for j in range(max_v)] for i in range(n)]



for i in range(max_v):

    if i+1 > v[0]:

        c[0][i] = float('inf')

    else:

        c[0][i] = w[0]



for i in range(1,n):

    for j in range(max_v):

        if j+1 > v[i]:

            c[i][j] = min(c[i-1][j], w[i]+c[i-1][j-v[i]])

        else:

            c[i][j] = min(c[i-1][j], w[i])

        # if j+1 < w[i]:

        #     c[i][j] = c[i-1][j]

        # else:

        #     diff = (j+1)-w[i]

        #     if diff > 0:

        #         c[i][j] = max(c[i-1][j], v[i]+c[i-1][diff-1])

        #     else:

        #         c[i][j] = max(c[i-1][j], v[i])

for i in range(1,max_v+1)[::-1]:

    if c[-1][i-1] <= W:

        print(i)

        break

# 横軸:重さ

def knapsack(W,weight,value):

    n = len(weight)#or len(value)

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

    # 初期化

    for j in range(W):

        dp[0][j] = 0

    for i in range(n):

        for j in range(W+1):

            if weight[i] <= j:

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

            else:

                dp[i+1][j] = dp[i][j]

    sol = dp[-1][-1]

    return dp,sol



# Wが大きい時

# 横軸:価値

# 価値が小さい必要がある

# https://qiita.com/drken/items/dc53c683d6de8aeacf5a#e-%E5%95%8F%E9%A1%8C---knapsack-2

def knapsack2(W,weight,value):

    n = len(weight)

    max_v = n*max(value)

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

    

    for i in range(max_v):

        if i+1 > value[0]:

            dp[0][i] = float('inf')

        else:

            dp[0][i] = weight[0]

    

    for i in range(1,n):

        for j in range(max_v):

            if j+1 > value[i]:

                dp[i][j] = min(dp[i-1][j], weight[i]+dp[i-1][j-value[i]])

            else:

                dp[i][j] = min(dp[i-1][j], weight[i])

    for i in range(1,max_v+1)[::-1]:

        if dp[-1][i-1] <= W:

            sol = i

            break

    return dp,sol



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

values, weights = [],[]

for _ in range(N):

    ｗ,ｖ = list(map(int,input().split()))

    values.append(v)

    weights.append(w)



W = min(W,sum(weights))

dp,sol = knapsack2(W,weights,values)

print(sol)

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)
max_v = n * max(v)
c = [[0 for j in range(max_v)] for i in range(n)]
for i in range(max_v):
    if i + 1 > v[0]:
        c[0][i] = float("inf")
    else:
        c[0][i] = w[0]
for i in range(1, n):
    for j in range(max_v):
        if j + 1 > v[i]:
            c[i][j] = min(c[i - 1][j], w[i] + c[i - 1][j - v[i]])
        else:
            c[i][j] = min(c[i - 1][j], w[i])
        # if j+1 < w[i]:
        #     c[i][j] = c[i-1][j]
        # else:
        #     diff = (j+1)-w[i]
        #     if diff > 0:
        #         c[i][j] = max(c[i-1][j], v[i]+c[i-1][diff-1])
        #     else:
        #         c[i][j] = max(c[i-1][j], v[i])
for i in range(1, max_v + 1)[::-1]:
    if c[-1][i - 1] <= W:
        print(i)
        break

# 横軸:重さ
def knapsack(W, weight, value):
    n = len(weight)  # or len(value)
    dp = [[0] * (W + 1) for _ in range(n + 1)]
    # 初期化
    for j in range(W):
        dp[0][j] = 0
    for i in range(n):
        for j in range(W + 1):
            if weight[i] <= j:
                dp[i + 1][j] = max(dp[i][j - weight[i]] + value[i], dp[i][j])
            else:
                dp[i + 1][j] = dp[i][j]
    sol = dp[-1][-1]
    return dp, sol


# Wが大きい時
# 横軸:価値
# 価値が小さい必要がある
# https://qiita.com/drken/items/dc53c683d6de8aeacf5a#e-%E5%95%8F%E9%A1%8C---knapsack-2
def knapsack2(W, weight, value):
    n = len(weight)
    max_v = n * max(value)
    dp = [[0 for j in range(max_v)] for i in range(n)]
    for i in range(max_v):
        if i + 1 > value[0]:
            dp[0][i] = float("inf")
        else:
            dp[0][i] = weight[0]
    for i in range(1, n):
        for j in range(max_v):
            if j + 1 > value[i]:
                dp[i][j] = min(dp[i - 1][j], weight[i] + dp[i - 1][j - value[i]])
            else:
                dp[i][j] = min(dp[i - 1][j], weight[i])
    for i in range(1, max_v + 1)[::-1]:
        if dp[-1][i - 1] <= W:
            sol = i
            break
    return dp, sol


N, W = list(map(int, input().split()))
values, weights = [], []
for _ in range(N):
    ｗ, ｖ = list(map(int, input().split()))
    values.append(v)
    weights.append(w)
W = min(W, sum(weights))
dp, sol = knapsack2(W, weights, values)
print(sol)

-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) -max_v = n * max(v) -c = [[0 for j in range(max_v)] for i in range(n)] -for i in range(max_v): -    if i + 1 > v[0]: -        c[0][i] = float("inf") -    else: -        c[0][i] = w[0] -for i in range(1, n): -    for j in range(max_v): -        if j + 1 > v[i]: -            c[i][j] = min(c[i - 1][j], w[i] + c[i - 1][j - v[i]]) +# 横軸:重さ +def knapsack(W, weight, value): +    n = len(weight)  # or len(value) +    dp = [[0] * (W + 1) for _ in range(n + 1)] +    # 初期化 +    for j in range(W): +        dp[0][j] = 0 +    for i in range(n): +        for j in range(W + 1): +            if weight[i] <= j: +                dp[i + 1][j] = max(dp[i][j - weight[i]] + value[i], dp[i][j]) +            else: +                dp[i + 1][j] = dp[i][j] +    sol = dp[-1][-1] +    return dp, sol + + +# Wが大きい時 +# 横軸:価値 +# 価値が小さい必要がある +def knapsack2(W, weight, value): +    n = len(weight) +    max_v = n * max(value) +    dp = [[0 for j in range(max_v)] for i in range(n)] +    for i in range(max_v): +        if i + 1 > value[0]: +            dp[0][i] = float("inf") -            c[i][j] = min(c[i - 1][j], w[i]) -        # if j+1 < w[i]: -        #     c[i][j] = c[i-1][j] -        # else: -        #     diff = (j+1)-w[i] -        #     if diff > 0: -        #         c[i][j] = max(c[i-1][j], v[i]+c[i-1][diff-1]) -        #     else: -        #         c[i][j] = max(c[i-1][j], v[i]) -for i in range(1, max_v + 1)[::-1]: -    if c[-1][i - 1] <= W: -        print(i) -        break +            dp[0][i] = weight[0] +    for i in range(1, n): +        for j in range(max_v): +            if j + 1 > value[i]: +                dp[i][j] = min(dp[i - 1][j], weight[i] + dp[i - 1][j - value[i]]) +            else: +                dp[i][j] = min(dp[i - 1][j], weight[i]) +    for i in range(1, max_v + 1)[::-1]: +        if dp[-1][i - 1] <= W: +            sol = i +            break +    return dp, sol + + +N, W = list(map(int, input().split())) +values, weights = [], [] +for _ in range(N): +    ｗ, ｖ = list(map(int, input().split())) +    values.append(v) +    weights.append(w) +W = min(W, sum(weights)) +dp, sol = knapsack2(W, weights, values) +print(sol)