// Original C++ solution (slower):
#include <algorithm>

#include <cmath>

#include <deque>

#include <iostream>

#include <numeric>

#include <queue>

#include <sstream>

#include <string>

#include <string.h>

#include <tuple>

#include <vector>



#define REP(i,x) for(int i{ 0 }; i < (int)(x); i++)

#define REPC(i,x) for(int i{ 0 }; i <= (int)(x); i++)

#define RREP(i,x) for(int i{ (int)(x) - 1 }; i >= 0 ;i--)

#define RREPC(i,x) for(int i{ (int)(x)}; i >= 0; i--)

#define REP1O(i,x) for(int i{ 1 }; i < (int)(x); i++)

#define REP1C(i,x) for(int i{ 1 }; i <= (int)(x); i++)



#define PB push_back

#define MP make_pair

#define F first

#define S second

#define SZ(x) ((int)(x).size())

#define ALL(x) (x).begin(),(x).end()



using namespace std;



typedef int64_t ll;

typedef vector<int> vi;

typedef vector<ll> vll;

typedef vector<vector<int>> vvi;

typedef vector<vector<ll>> vvll;

typedef pair<int, int> pii;

typedef tuple<int, int, int> tupiii;

typedef tuple<ll, ll, ll> tuplll;



const int INTMAX = 2147483647;

const ll LLMAX = 9223372036854775807;

const int MOD = 1000000007;



template<class T> inline bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }

template<class T> inline bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }

inline void swap(ll& a, ll& b) { a ^= b; b ^= a; a ^= b; }

inline void swap(int& a, int& b) { a ^= b; b ^= a; a ^= b; }







int n;

ll V, w;

const ll inf = 1LL << 60;

const ll maxV = 1000;

vll vw, vv;

vvll dp;



void init()

{

	cin >> n >> w;

	vw.resize(n); vv.resize(n);

	V = n * maxV;



	REP(i, n) cin >> vw[i] >> vv[i];



	dp.resize(n + 1, vll(V + 1, inf));

	dp[0][0] = 0;

}



void print(const vvll& v)

{

	REP(i, SZ(v))

	{

		REP(j, SZ(v[i]))

			cout << v[i][j] << " ";

		cout << endl;

	}

}



int main()

{

	init();



	REP(i, n)

		REPC(j, V)

	{

		chmin(dp[i + 1][j], dp[i][j]);

		if (j + vv[i] <= V)

			chmin(dp[i + 1][j + vv[i]], dp[i][j] + vw[i]);

	}



	int ans = 0;

	REPC(j, V)

		if (dp[n][j] <= w)

			ans = j;



	cout << ans << endl;



}


// Optimized solution to the same problem (faster):
#include <algorithm>

#include <cmath>

#include <deque>

#include <iostream>

#include <numeric>

#include <queue>

#include <sstream>

#include <string>

#include <string.h>

#include <tuple>

#include <vector>



#define REP(i,x) for(int i{ 0 }; i < (int)(x); i++)

#define REPC(i,x) for(int i{ 0 }; i <= (int)(x); i++)

#define RREP(i,x) for(int i{ (int)(x) - 1 }; i >= 0 ;i--)

#define RREPC(i,x) for(int i{ (int)(x)}; i >= 0; i--)

#define REP1O(i,x) for(int i{ 1 }; i < (int)(x); i++)

#define REP1C(i,x) for(int i{ 1 }; i <= (int)(x); i++)



#define PB push_back

#define MP make_pair

#define F first

#define S second

#define SZ(x) ((int)(x).size())

#define ALL(x) (x).begin(),(x).end()



using namespace std;



typedef int64_t ll;

typedef vector<int> vi;

typedef vector<ll> vll;

typedef vector<vector<int>> vvi;

typedef vector<vector<ll>> vvll;

typedef pair<int, int> pii;

typedef tuple<int, int, int> tupiii;

typedef tuple<ll, ll, ll> tuplll;



const int INTMAX = 2147483647;

const ll LLMAX = 9223372036854775807;

const int MOD = 1000000007;



template<class T> inline bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }

template<class T> inline bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }

inline void swap(ll& a, ll& b) { a ^= b; b ^= a; a ^= b; }

inline void swap(int& a, int& b) { a ^= b; b ^= a; a ^= b; }







int n, V;

ll W;

const ll inf = 1LL << 60;

const int maxV = 1000;

vll dp;



void init()

{

	cin >> n >> W;

	V = n * maxV;

	dp.resize(V + 1, inf);

	dp[0] = 0;

}



int main()

{

	init();



	REP(_i, n)

	{

		ll w;

		int v;

		cin >> w >> v;



		RREPC(i, V - v)

			chmin(dp[i + v], dp[i] + w);

	}



	int ans = 0;

	REPC(i, V)

		if (dp[i] <= W)

			ans = i;



	cout << ans << endl;



}


// Fastest known solution for this problem: