// Slower C++ solution:
#include<bits/stdc++.h>

#define ll long long

#define ull unsigned long long

#define IO ios::sync_with_stdio(false), cin.tie(0)

#define endl '\n'

#define main() int main()

#define ff1(i,n) for(int i=1;i<=n;++i)

#define ff0(i,n) for(int i=0;i<n;++i)

#define pi acos(-1.0)

#define ms(a, x) memset(a, x, sizeof(a))

#define lowbit(x) ((x)&(-(x)))

#define pb push_back

#define binarycount __builtin_popcount(x)

#define tr t[root]

#define lson t[root << 1]

#define rson t[root << 1 | 1]

#define fir first

#define sec second

#define debug(x) cout<<x<<'\n'

#define sa(a) scanf("%d", &a)

#define sab(a, b) scanf("%d%d", &a, &b)

#define pa(a) printf("%d",a)

#define pab(a,b) printf("%d%d",a,b)

#define pii pair<string,int>

using namespace std;



#define maxn 1000010

const int inf = 0x3f3f3f3f;

const int mod = 9973;

const double eps = 1e-8;

ll gcd(ll a, ll b) {return b==0?a:gcd(b, a%b);}

ll lcm(ll a, ll b) {return a/gcd(a, b)*b;}

int max(int x,int y){if(x>y) return x;return y;}

ll powmod(ll a,ll b){

    ull ans = 1, pow = a%mod;

    while(b) { if(b&1) ans = (ans*pow)%mod; pow = (pow*pow)%mod; b >>= 1; }

    return ans%mod;

}

ll v[105],w[105];	

ll dp[maxn],n,W,ans;

main()

{

	IO;

	cin>>n>>W;

	for(ll i=1;i<=n;i++){

		cin>>w[i]>>v[i];

	}

	ans=0;

	ms(dp,0x3f);

	dp[0]=0;

	for(int i=1;i<=n;i++){

		for(int j=1e5;j>=v[i];j--){

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

			if(dp[j]<=W) ans=max(ans,(ll)j);

		}

	}

	cout<<ans<<endl;

} 

// Faster C++ solution for the same problem (measured speedup: 11.13645833378415x):
#include<bits/stdc++.h>

#define ll long long

#define pii pair<ll int,ll int>

#define PI 2*acos(0)

//#define mx 100005

#define INF 1e16

using namespace std;

const ll int p=1000000007;

//vector<ll > prime;

//bool mark[mx];

ll int mod(ll int a,ll int b)

{

    ll int m=a%b;

    if(m<0) m=(b<0)?(m-b):(m+b);

    return m;

}

ll maxpow(ll n)

{

    return (n & (~(n-1)));

}

bool isPrime(ll n)

{

    if(n<2) return false;

    if(n==2) return true;

    if(n%2==0) return false;

    for(ll i=3;i*i<=n;i+=2){

        if(n%i==0) return false;

    }

    return true;

}

/*void init()

{

    mark[1]=1;

    int i,j,limit=sqrt(mx*1.0)+2;

    prime.push_back(2);

    for(i=4;i<mx;i+=2) mark[i]=1;

    mark[2]=0;

    for(i=3;i<mx;i+=2){

        if(!mark[i]){

            prime.push_back(i);

            if(i<=limit){

                for(j=i*i;j<mx;j+=2*i){

                    mark[j]=1;

                }

            }

        }

    }

}*/

/*

ll maxdiv(ll n)

{

    ll i,ans=1;

    for(i=0;i<prime.size();i++){

        if(n%prime[i]==0){

            ans=n/prime[i];break;

            //return ans;

        }

    }

    return ans;

}*/

ll lcm(ll a,ll b)

{

    ll ans=a*b;

    return (ans/__gcd(a,b));

}

// ax+by and a>b

ll gcd(ll a,ll b,ll &x,ll &y)

{

    if(b==0){

        x=1;

        y=0;

        return a;

    }

    ll x1,y1;

    ll d=gcd(b,mod(a,b),x1,y1);

    x=y1;

    y=x1-y1*(a/b);

    return d;

}

ll abso(ll a)

{

    if(a>=0) return a;

    return -a;

}

int main()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    //ll mx=100005;

    //cout<<mx<<"\n";

    ll i,j,n,x;

    cin>>n>>x;

    ll w[n+1],v[n+1];

    ll V=0;

    for(i=1;i<=n;i++){ cin>>w[i]>>v[i]; V+=v[i]; }

    // dp[i] denotes the minimum total weight of items with total value exactly i;considering each item only once

    ll dp[V+1];

    for(i=1;i<=V;i++) dp[i]=INF;

    dp[0]=0;

    for(i=1;i<=n;i++){

        // considering the i th item ,as we are going from left to right ,we are considering each item only once

        for(j=V;j>=v[i];j--){

            // if this was an increasing loop then this program will make the mistake of using one item more than once

            // every element can be used only once ,therefore the loop is a decreasing loop

            // now we will see if taking the current item will effect any value

            // any value that can be updated can range from v[i] to V , so we will consider all the possibilities

            // before updating dp[j],let's think for a while , we have already updated the list upto (i-1) th item

            // either the j th value will change or it won't

            // we have two options , either we can take the i'th element (1) or not (2)

            // (1) the j th state will remain unchanged

            // (2) or it will be changed by dp[j-v[i]]+w[i]

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

            //cout<<"i="<<i<<" j="<<j<<" "<<dp[j]<<"\n";

        }

    }

    for(i=V;i>=0;i--){

        if(dp[i]<=x){

            cout<<i;

            return 0;

        }

    }

    return 0;

}

//1028C