#####################################################################################################

##### ナップサック問題　（価値が小さい場合）

#####################################################################################################

"""



経路を状態の添え字に取るような事は無い

経路の末端の情報のみを横軸の添え字に取ることが多い

例：一年生　⇒　k項目までの総和

   パスタ　⇒　k日目に食べたパスタ

   暑い日々⇒　k日目に着た服



DPテーブルにおいて、ある値以降の全てで 1 となる場合、

その値でDPテーブルを切ってしまって、

indexがその値を超えるごとに、DPテーブルの上限に +1 をしていくというアイデアで計算量を減らせる

例: https://atcoder.jp/contests/tdpc/submissions/14958104



初期条件を常に意識するように！



ベンチマーク

（重複なし）

http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4641577#1

(重複あり)

http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4641577#1



"""





import sys

input = sys.stdin.readline







M, W = list(map(int, input().split()))                                # M: 品物の種類 W: 重量制限

single = True                                                   # True = 重複なし



price_list = [0]

weight_list = [0]

for _ in range(M):

    weight, price = list(map(int, input().split()))

    price_list.append(price)

    weight_list.append(weight)





################################################################################################################################################



V = sum(price_list)

dp_max = W + 1                                                  # 総和重量の最大値





dp = [[dp_max] * (V + 1) for _ in range(M + 1)]                 # 左端と上端の境界条件で W, M を一個ずつ多めに取る

""" dp[item <= M ][weight <= V] = 価値を固定した時の"最小"重量 """



for item in range(M+1):                                         # 左端の境界条件

    dp[item][0] = 0                                             # 価値 0 を実現するのに必要な品物の個数は 0 個



# for weight in range(W+1):                                     # 上端の境界条件

#     dp[0][weight] = dp_min                                    # 0 種類の品物で実現できる価値総額は存在しない　（dpの初期化で自動的に課せる場合が多い）





for item in range(1,M+1):                                       # 境界条件を除いた M 回のループ（※ f[item] = g.f[item-i] の漸化式なので、list index out of range となる）

    for price in range(1, V+1):

        if price < price_list[item]:                            # price (総価値) < price_list[item] (品物の価値) の時は無視してよい

            dp[item][price] = dp[item - 1][price]

        else:

            temp = dp[item - single][price - price_list[item]] + weight_list[item]  # single = True: 重複なし

            if temp < dp[item-1][price]:                        # min(dp[item-1][price], temp)

                dp[item][price] = temp

            else:

                dp[item][price] = dp[item-1][price]



print((max(price for price in range(V+1) if dp[M][price] <= W)))
def knapsack_price(single=True):

    """

    重さが小さい時のナップサックDP

    :param single: True = 重複なし

    """

    """ dp[price <= V] = 価値を固定した時の最小重量 """

    V = sum(price_list)

    dp_max = W+1

    dp = [dp_max] * (V + 1)

    dp[0] = 0   # 境界条件：　価値0 の時は重さは0



    for item in range(N):

        if single:

            S = reversed(list(range(price_list[item], V + 1)))

        else:

            S = list(range(price_list[item], V + 1))

        for price in S:

            dp[price] = min2(dp[price], dp[price - price_list[item]] + weight_list[item])

    return max(price for price in range(V+1) if dp[price] <= W)





#######################################################################################################

import sys

input = sys.stdin.readline





def max2(x, y):

    """ pythonの組み込み関数 max は2変数に対しては遅い！！ """

    if x > y:

        return x

    else:

        return y



def min2(x, y):

    """ pythonの組み込み関数 min は2変数に対しては遅い！！ """

    if x < y:

        return x

    else:

        return y





N, W = list(map(int, input().split()))                                # N: 品物の種類 W: 重量制限



price_list = []

weight_list = []

for _ in range(N):

    """ price と weight が逆転して入力されている場合有り """

    weight, price = list(map(int, input().split()))

    price_list.append(price)

    weight_list.append(weight)



print((knapsack_price(single=True)))
#####################################################################################################
##### ナップサック問題　（価値が小さい場合）
#####################################################################################################
"""
経路を状態の添え字に取るような事は無い
経路の末端の情報のみを横軸の添え字に取ることが多い
例：一年生　⇒　k項目までの総和
   パスタ　⇒　k日目に食べたパスタ
   暑い日々⇒　k日目に着た服
DPテーブルにおいて、ある値以降の全てで 1 となる場合、
その値でDPテーブルを切ってしまって、
indexがその値を超えるごとに、DPテーブルの上限に +1 をしていくというアイデアで計算量を減らせる
例: https://atcoder.jp/contests/tdpc/submissions/14958104
初期条件を常に意識するように！
ベンチマーク
（重複なし）
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4641577#1
(重複あり)
http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4641577#1
"""
import sys

input = sys.stdin.readline
M, W = list(map(int, input().split()))  # M: 品物の種類 W: 重量制限
single = True  # True = 重複なし
price_list = [0]
weight_list = [0]
for _ in range(M):
    weight, price = list(map(int, input().split()))
    price_list.append(price)
    weight_list.append(weight)
################################################################################################################################################
V = sum(price_list)
dp_max = W + 1  # 総和重量の最大値
dp = [[dp_max] * (V + 1) for _ in range(M + 1)]  # 左端と上端の境界条件で W, M を一個ずつ多めに取る
""" dp[item <= M ][weight <= V] = 価値を固定した時の"最小"重量 """
for item in range(M + 1):  # 左端の境界条件
    dp[item][0] = 0  # 価値 0 を実現するのに必要な品物の個数は 0 個
# for weight in range(W+1):                                     # 上端の境界条件
#     dp[0][weight] = dp_min                                    # 0 種類の品物で実現できる価値総額は存在しない　（dpの初期化で自動的に課せる場合が多い）
for item in range(
    1, M + 1
):  # 境界条件を除いた M 回のループ（※ f[item] = g.f[item-i] の漸化式なので、list index out of range となる）
    for price in range(1, V + 1):
        if price < price_list[item]:  # price (総価値) < price_list[item] (品物の価値) の時は無視してよい
            dp[item][price] = dp[item - 1][price]
        else:
            temp = (
                dp[item - single][price - price_list[item]] + weight_list[item]
            )  # single = True: 重複なし
            if temp < dp[item - 1][price]:  # min(dp[item-1][price], temp)
                dp[item][price] = temp
            else:
                dp[item][price] = dp[item - 1][price]
print((max(price for price in range(V + 1) if dp[M][price] <= W)))

def knapsack_price(single=True):
    """
    重さが小さい時のナップサックDP
    :param single: True = 重複なし
    """
    """ dp[price <= V] = 価値を固定した時の最小重量 """
    V = sum(price_list)
    dp_max = W + 1
    dp = [dp_max] * (V + 1)
    dp[0] = 0  # 境界条件：　価値0 の時は重さは0
    for item in range(N):
        if single:
            S = reversed(list(range(price_list[item], V + 1)))
        else:
            S = list(range(price_list[item], V + 1))
        for price in S:
            dp[price] = min2(
                dp[price], dp[price - price_list[item]] + weight_list[item]
            )
    return max(price for price in range(V + 1) if dp[price] <= W)


#######################################################################################################
import sys

input = sys.stdin.readline


def max2(x, y):
    """pythonの組み込み関数 max は2変数に対しては遅い！！"""
    if x > y:
        return x
    else:
        return y


def min2(x, y):
    """pythonの組み込み関数 min は2変数に対しては遅い！！"""
    if x < y:
        return x
    else:
        return y


N, W = list(map(int, input().split()))  # N: 品物の種類 W: 重量制限
price_list = []
weight_list = []
for _ in range(N):
    """price と weight が逆転して入力されている場合有り"""
    weight, price = list(map(int, input().split()))
    price_list.append(price)
    weight_list.append(weight)
print((knapsack_price(single=True)))

-##################################################################################################### -##### ナップサック問題　（価値が小さい場合） -##################################################################################################### -""" -経路を状態の添え字に取るような事は無い -経路の末端の情報のみを横軸の添え字に取ることが多い -例：一年生　⇒　k項目までの総和 -   パスタ　⇒　k日目に食べたパスタ -   暑い日々⇒　k日目に着た服 -DPテーブルにおいて、ある値以降の全てで 1 となる場合、 -その値でDPテーブルを切ってしまって、 -indexがその値を超えるごとに、DPテーブルの上限に +1 をしていくというアイデアで計算量を減らせる -例: https://atcoder.jp/contests/tdpc/submissions/14958104 -初期条件を常に意識するように！ -ベンチマーク -（重複なし） -http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4641577#1 -(重複あり) -http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4641577#1 -""" +def knapsack_price(single=True): +    """ +    重さが小さい時のナップサックDP +    :param single: True = 重複なし +    """ +    """ dp[price <= V] = 価値を固定した時の最小重量 """ +    V = sum(price_list) +    dp_max = W + 1 +    dp = [dp_max] * (V + 1) +    dp[0] = 0  # 境界条件：　価値0 の時は重さは0 +    for item in range(N): +        if single: +            S = reversed(list(range(price_list[item], V + 1))) +        else: +            S = list(range(price_list[item], V + 1)) +        for price in S: +            dp[price] = min2( +                dp[price], dp[price - price_list[item]] + weight_list[item] +            ) +    return max(price for price in range(V + 1) if dp[price] <= W) + + +####################################################################################################### -M, W = list(map(int, input().split()))  # M: 品物の種類 W: 重量制限 -single = True  # True = 重複なし -price_list = [0] -weight_list = [0] -for _ in range(M): + + +def max2(x, y): +    """pythonの組み込み関数 max は2変数に対しては遅い！！""" +    if x > y: +        return x +    else: +        return y + + +def min2(x, y): +    """pythonの組み込み関数 min は2変数に対しては遅い！！""" +    if x < y: +        return x +    else: +        return y + + +N, W = list(map(int, input().split()))  # N: 品物の種類 W: 重量制限 +price_list = [] +weight_list = [] +for _ in range(N): +    """price と weight が逆転して入力されている場合有り""" -################################################################################################################################################ -V = sum(price_list) -dp_max = W + 1  # 総和重量の最大値 -dp = [[dp_max] * (V + 1) for _ in range(M + 1)]  # 左端と上端の境界条件で W, M を一個ずつ多めに取る -""" dp[item <= M ][weight <= V] = 価値を固定した時の"最小"重量 """ -for item in range(M + 1):  # 左端の境界条件 -    dp[item][0] = 0  # 価値 0 を実現するのに必要な品物の個数は 0 個 -# for weight in range(W+1):                                     # 上端の境界条件 -#     dp[0][weight] = dp_min                                    # 0 種類の品物で実現できる価値総額は存在しない　（dpの初期化で自動的に課せる場合が多い） -for item in range( -    1, M + 1 -):  # 境界条件を除いた M 回のループ（※ f[item] = g.f[item-i] の漸化式なので、list index out of range となる） -    for price in range(1, V + 1): -        if price < price_list[item]:  # price (総価値) < price_list[item] (品物の価値) の時は無視してよい -            dp[item][price] = dp[item - 1][price] -        else: -            temp = ( -                dp[item - single][price - price_list[item]] + weight_list[item] -            )  # single = True: 重複なし -            if temp < dp[item - 1][price]:  # min(dp[item-1][price], temp) -                dp[item][price] = temp -            else: -                dp[item][price] = dp[item - 1][price] -print((max(price for price in range(V + 1) if dp[M][price] <= W))) +print((knapsack_price(single=True)))