You have N items that you want to put them into a knapsack. Item i has value vi and weight wi.

You want to find a subset of items to put such that:

* The total value of the items is as large as possible.
* The items have combined weight at most W, that is capacity of the knapsack.



Find the maximum total value of items in the knapsack.

Constraints

* 1 ≤ N ≤ 100
* 1 ≤ vi ≤ 100
* 1 ≤ wi ≤ 10,000,000
* 1 ≤ W ≤ 1,000,000,000

Input


N W
v1 w1
v2 w2
:
vN wN


The first line consists of the integers N and W. In the following N lines, the value and weight of the i-th item are given.

Output

Print the maximum total values of the items in a line.

Examples

Input

4 5
4 2
5 2
2 1
8 3


Output

13


Input

2 20
5 9
4 10


Output

9
#include    <bits/stdc++.h>
using   namespace   std;
typedef long long ll;

#define INF (1<<30)
//1,073,741,824
//= 536,870,912 *2

#define Rep0(i, n)  for (int i=0; i<n; i++)
#define Rep1(i, n)  for (int i=1; i<=n; i++)

struct  Item {
    int v=0;
    ll  w=0;
};

int main() {
    // Input
    int N;
    ll W;
    cin >>N >>W;
    vector<Item> V(N);
    Rep0(i, N)
        cin >>V.at(i).v >>V.at(i).w;
    int VMax=N*100;
    // DP table: Item# x Value holds Weight
    vector<vector<ll>> DP(N+1, vector<ll> (VMax+1, INF));
    DP.at(0).at(0)=0; // Case skipping Item #0
    DP.at(0).at(V.at(0).v)=V.at(0).w; // Case selecteing Item #0
    Rep1(i, N-1) { // From Item #1 to #N-1
        int vv=V.at(i).v;
        ll ww=V.at(i).w;
        Rep0(v1, VMax+1) { // For each availabe value for previous Item
            if (INF==DP.at(i-1).at(v1)) // Skip unavailable values
                continue;
            DP.at(i).at(v1)=min(DP.at(i).at(v1), DP.at(i-1).at(v1)); // Skip
            if (v1+vv<=VMax)
                DP.at(i).at(v1+vv)=min(DP.at(i).at(v1+vv), DP.at(i-1).at(v1)+ww); // Select
        }
    }
    // Search for the best
    int S=0;
    Rep0(v1, VMax+1)
        if (DP.at(N-1).at(v1)<=W)
            S=v1;
    cout <<S <<endl;
    return 0;
}
