stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <iostream>

#include <stdio.h>

#include <cmath>

#include <cstring>

#include <string>

#include <set>

#include <map>

#include <algorithm>

#include <queue>

#include <vector>

#define f first

#define s second

#define mp make_pair

#define pb push_back

#define ll long long



using namespace std;



const int inf = 1e9 + 5;

const ll INF = 1e18 + 5;

const int maxn = 2e5 + 5;



ll n, a[maxn], w[maxn], s;

ll dp[maxn];



int main(){

    cin.tie(0);

    cout.tie(0);

    ios_base::sync_with_stdio(NULL);

	cin >> n >> s;

	memset(dp, -1, sizeof(dp));

	dp[0] = 0;

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

		int w, cost;

		cin >> w >> cost;

		for (int j = s - w; j >= 0; j--) {

			if (dp[j] != -1)

				dp[j + w] = max(dp[j + w], dp[j] + cost);

		}

	}

	ll ans = -1;

	for (int i = 0; i <= s; i++)

		ans = max(ans, dp[i]);

	cout << ans;

	return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>



using namespace std;



long long mem[100005][2];



int a[105];

int b[105];



int main()

{

    int n,k;

    scanf("%d %d",&n,&k);

    int i;

    for(i=0;i<n;i++)

    {

        scanf("%d %d",&a[i],&b[i]);

    }

    for(i=0;i<=k;i++)

    {

        mem[i][0] = -1e9;

        mem[i][1] = -1e9;

    }

    mem[0][0] = 0;

    mem[0][1] = 0;

    bool flag = 0;

    for(i=0;i<n;i++)

    {

        flag = !flag;

        int j;

        for(j=0;j<=k;j++)

        {

            if(j-a[i]>=0)mem[j][flag] = max(mem[j][!flag],mem[j-a[i]][!flag] + b[i]);

            else mem[j][flag] = mem[j][!flag];

        }

    }

    long long ans = 0;

    for(i=0;i<=k;i++)

    {

        ans = max(mem[i][flag],ans);

    }

    printf("%lld",ans);

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

const int maxn = 1e5 + 5;

typedef long long ll;

int main(){

	ll dp[maxn];

	ll n,W;

	ll w[105],v[105];

	memset(dp,0,sizeof(dp));

	scanf("%lld%lld",&n,&W);

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

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

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

		for(ll j = W;j >= 1;j--){

			if(j >= w[i]) dp[j] = max(dp[j],dp[j-w[i]] + v[i]);

		}

	}

	printf("%lld\n",dp[W]);

	return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define INF 0x3f3f3f3f

#define LL long long

using namespace std;

const int maxn = 1e5+10;

int a[maxn];

LL b[maxn];

LL dp[maxn];

int main()

{

    int n,w;

    scanf("%d%d",&n,&w);

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

    {

        scanf("%d%lld",a+i,b+i);

    }

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

    {

        for(int j=w;j>=0;j--)

        {

            if(j-a[i]>=0)

            {

                dp[j]=max(dp[j],dp[j-a[i]]+b[i]);

            }

        }

    }

    printf("%lld\n",dp[w]);

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>



#define SORT(v) sort(v.begin(),v.end())

#define si(n) scanf("%d",&n)

#define sii(n,m) scanf("%d %d",&n,&m)

#define sl(n) scanf("%lld",&n)

#define sll(n,m) scanf("%lld %lld",&n,&m)

#define ss(cad) scanf("%s",cad)

#define fst first

#define scn second

#define DBG(x) cerr << #x << " = " << (x) << endl; 

#define M 1000000007

#define N_MAX 100010



using namespace std;



typedef long long ll;

typedef vector<int> vi;

typedef vector<bool> vb;

typedef vector<ll> vl;

typedef pair<int,int> pi;

typedef pair<ll, ll> pll;

typedef vector<pi> vp;



ll dp[110][100100];

ll pesos[110];

ll costo[110];



int main(){

	int n, w;

	sii(n, w);



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

		sl(pesos[i]);

		sl(costo[i]);

	}



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

		for(int j = 0; j <= 100000; j++){

			ll ans = 0;

			ans = dp[i-1][j];

			if(j-pesos[i] >= 0)

				ans = max(ans, costo[i] + dp[i-1][j-pesos[i]]);

			dp[i][j] = ans;

		}

	}

	printf("%lld\n", dp[n][w]);

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define INF 0x3f3f3f3f

#define LL long long

using namespace std;

const int maxn = 1e5+10;

int a[maxn];

LL b[maxn];

LL dp[maxn];

int main()

{

    int n,w;

    scanf("%d%d",&n,&w);

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

    {

        scanf("%d%lld",a+i,b+i);

    }

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

    {

        for(int j=w;j>=0;j--)

        {

            if(j-a[i]>=0)

            {

                dp[j]=max(dp[j],dp[j-a[i]]+b[i]);

            }

        }

    }

    printf("%lld\n",dp[w]);

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;



typedef long long llt;



const int MaxN = 100 + 5, MaxW = 100000 + 5;



int N, W;

int w[MaxN]; llt v[MaxN];

llt dp[MaxW];



void init() {

  scanf("%d %d", &N, &W);

  for (int i = 1; i <= N; ++i)

    scanf("%d %lld", &w[i], &v[i]);

}



void solve() {

  for (int i = 1; i <= N; ++i)

    for (int j = W; j >= w[i]; --j)

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

  llt ans = 0;

  for (int i = 1; i <= W; ++i) ans = max(ans, dp[i]);

  cout << ans << endl;

}



int main() {

  init();

  solve();

  return 0;

}

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



const int MaxN = 100 + 5, MaxM = 100000 + 5;



int N, M;

int W[MaxN], V[MaxN];

long long Dp[MaxM];



template <typename T>

inline T max(T x, T y) { return x > y ? x : y; }



void init() {

  scanf("%d %d", &N, &M);

  for (int i = 1; i <= N; ++i)

    scanf("%d %d", &W[i], &V[i]);

}



void solve() {

  for (int i = 1; i <= N; ++i)

    for (int j = M; j >= W[i]; --j)

      Dp[j] = max(Dp[j], Dp[j - W[i]] + V[i]);

  long long ans = 0;

  for (int i = 0; i <= M; ++i)

    ans = max(ans, Dp[i]);

  printf("%lld\n", ans);

}



int main() {

  init();

  solve();

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define pb push_back

#define mod 1000000007

#define null NULL

#define test cout<<"#"

#define maX 1000000000

 

ll ans[100001];



void solve(vector<ll> &w, vector<ll> &v, ll n, ll wt)

{	

	for(ll x = 0; x < n; x++)

	{

		for(ll y = wt; y>=0; y--)

		{

			if(w[x]<=y)

				ans[y] = max(ans[y], ans[y - w[x]]+v[x]);

		}

	}

}



int main()

{

    ios_base::sync_with_stdio(false);

    cin.tie(0);

	memset(ans, 0, sizeof(ans));

    ll n, w;

	cin>>n>>w;

    vector<ll> a(n);

	vector<ll> b(n);

    for(ll x = 0; x < n; x++)

	{

		cin>>a[x];

		cin>>b[x];

	}

	solve(a, b, n, w);

	cout<<ans[w];

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

#define mod 1000000007

#define pb push_back

#define test cout<<"#"



int main()

{

	ios_base::sync_with_stdio(false);

	cin.tie(0);

	cout.tie(0);

	ll n, wt;

	cin>>n>>wt;

	vector<ll> w(n);

	vector<ll> val(n);

	for(ll x = 0; x < n; x++)

		cin>>w[x]>>val[x];

	ll ans[wt+1] ={0};

	for(ll x = 0; x<n; x++)

	{

		for(ll y = wt; y>=0; y--)

		{

			if(w[x]<=y)

				ans[y] = max(ans[y], ans[y-w[x]]+val[x]);

		}

	}

	cout<<ans[wt];

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <map>

#include <set>

#include <list>

#include <cmath>

#include <ctime>

#include <deque>

#include <queue>

#include <chrono>

#include <stack>

#include <string>

#include <bitset>

#include <unordered_map>

#include <cstdio>

#include <limits>

#include <vector>

#include <climits>

#include <cstring>

#include <cstdlib>

#include <fstream>

#include <numeric>

#include <sstream>

#include <cassert>

#include <tuple>

#include <iomanip>

#include <random>

#include <iostream>

#include <algorithm>

#include <stdio.h>



using namespace std;



#define ll long long



const unsigned long long MAXN = (int)3e5 + 5;

const int MAXI = (int)2e9;

const int K = 3;



int main(){

    ll n,sz;cin >> n >> sz;

    vector<ll> dp(MAXN, 0);

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

        int w,v;cin >> w >> v;

        for (ll have = sz - w;have >= 0;have --) {

            dp[have + w] = max(dp[have + w], dp[have] + v);

        }

    }

    ll ans = 0;

    for (int i = 1;i <= sz;i ++)

        ans = max(ans, dp[i]);

    cout << ans;

    return 0;

}

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

#include <set>

#include <list>

#include <cmath>

#include <ctime>

#include <deque>

#include <queue>

#include <chrono>

#include <stack>

#include <string>

#include <bitset>

#include <unordered_map>

#include <cstdio>

#include <limits>

#include <vector>

#include <climits>

#include <cstring>

#include <cstdlib>

#include <fstream>

#include <numeric>

#include <sstream>

#include <cassert>

#include <tuple>

#include <iomanip>

#include <random>

#include <iostream>

#include <algorithm>

#include <stdio.h>



using namespace std;



#define ll long long



const unsigned long long MAXN = (int)3e5 + 5;

const int MAXI = (int)2e9;

const ll INF = (1e18);

const int K = 3;



int main(){

    int n,sz;cin >> n >> sz;

    vector<ll> dp(sz + 100);

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

        int w,v;cin >> w >> v;

        for (int have = sz - w;have >= 0;have --) {

            dp[have + w] = max(dp[have + w], dp[have] + v);

        }

    }

    ll ans = 0;

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

        ans = max(ans, dp[i]);

    }

    cout << ans;

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

#define ll long long int

#define MAX 100005

int n,w;

vector<int> wt(MAX);

vector<int> val(MAX);

vector<int> test(12);



void max_self(ll&a ,ll b)

{

    a = max(a,b);

}



int main()

{

    cin >> n >> w;

    

    vector<ll> dp(w+1);

    // dp[i] -> the maximum total value for weight exactly

    for(int item = 0;item < n; ++item)

    {

        int weight,value;

        cin >> weight >> value;

        for(int wt_done = w-weight;wt_done>=0;--wt_done)

        max_self(dp[wt_done+weight],dp[wt_done]+value);

    }



    ll ans = 0;

    for(int i=0;i<=w;i++)

    max_self(ans,dp[i]);

    cout << ans;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;



#define int long long 



void max_self(int &a, int b)

{

	a = max(a,b);

}



signed main()

{

	int n,w;

	cin >> n >> w;

	vector<int> dp(w+1); // 0...W

	// dp[i] - max total value that can be obtained with total weight exactly i

	dp[0] = 0;

	for(int item = 0;item < n; ++item)

	{

		int weight,val;

		cin >> weight >> val;

			for(int weight_added = w-weight; weight_added >= 0; --weight_added)

			max_self(dp[weight_added + weight],dp[weight_added] + val);

		

	}

	int ans = 0;

	for(auto x:dp)

	{

		max_self(ans,x);

	}

	cout << ans;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

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

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

const int MAX_N = 110;

const int MAX_W = 100100;



int main() {

    int N, W;

    cin >> N >> W;

    long long dp[MAX_W] = {0};

    vector<int> weight(N), value(N);

    for (int i = 0; i < N; i++) { cin >> weight[i] >> value[i]; }

    

    for (int i = 0; i < N; i++) {

        for (int w = MAX_W; w >= 0; w--) {

            if (0 <= w-weight[i]) chmax(dp[w], dp[w-weight[i]] + value[i]);

        }

    }

    

    cout << dp[W] << endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;



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

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

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

#define all(v) v.begin(), v.end()

#define rall(v) v.rbegin(), v.rend()

#define YesorNo(a) printf(a ? "Yes\n" : "No\n")

#define endl '\n'

using ll = long long;

using P = pair<int,int>;

using Pl = pair<ll,ll>;

using vi = vector<int>;

using vii = vector<vi>;

using vl = vector<ll>;

using vll = vector<vl>;

using vs = vector<string>;

using vb = vector<bool>;

const int dx[] = {0,1,0,-1,1,1,-1,-1};

const int dy[] = {1,0,-1,0,1,-1,-1,1};

const int inf = (1<<30)-1;

const ll infll = (1LL<<62)-1;

ll ceil(const ll &a, const ll &b){return ((a)+(b)-1)/b;}

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

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



ll dp[110][100100] = {};



int main(){

  ios::sync_with_stdio(false);

  cin.tie(nullptr);



  ll n, mx_w;

  cin >> n >> mx_w;

  vl w(n), v(n);

  rep(i,n) cin >> w[i] >> v[i];



  rep(i,n) {

    rep(j,mx_w+1) {

      if(j >= w[i]) chmax(dp[i+1][j], dp[i][j-w[i]] + v[i]);

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

    }

  }

  cout << dp[n][mx_w] << endl;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef vector<int> vi;

typedef vector<ll> vll;

typedef vector<string> vs;

ll llmax = LLONG_MAX;

string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

string alp = "abcdefghijklmnopqrstuvwxyz";

vi d1 = {1, 0, -1, 0}, d2 = {0, 1, 0, -1};

void Yes() {cout << "Yes" << endl;}

void No() {cout << "No" << endl;}

void YES() {cout << "YES" << endl;}

void NO() {cout << "NO" << endl;}

void neg() {cout << -1 << endl;}



int main() {

  ll n, ww;

  cin >> n >> ww;

  vll w(n), v(n);

  for (ll i = 0; i < n; i++) cin >> w[i] >> v[i];

  vll dp(100001, 0);

  vector<vll> check(1, vll(n, 0));

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

    dp[i] = dp[i - 1];

    ll memo = -1;

    for (ll j = 0; j < n; j++) {

      if (i < w[j]) continue;

      if (check[i - w[j]][j] == 1) continue;

      if (dp[i] < dp[i - w[j]] + v[j]) {

        dp[i] = dp[i - w[j]] + v[j];

        memo = j;

      }

    }

    if (memo != -1) {

      vll x = check[i - w[memo]];

      x[memo] = 1;

      check.emplace_back(x);

    }

    else check.emplace_back(check[i - 1]);

  }

  cout << dp[ww] << endl;

}


// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;



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

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

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

#define all(v) v.begin(), v.end()

#define rall(v) v.rbegin(), v.rend()

#define YesorNo(a) printf(a ? "Yes\n" : "No\n")

#define endl '\n'

using ll = long long;

using P = pair<int,int>;

using Pl = pair<ll,ll>;

using vi = vector<int>;

using vii = vector<vi>;

using vl = vector<ll>;

using vll = vector<vl>;

using vs = vector<string>;

using vb = vector<bool>;

const int dx[] = {0,1,0,-1,1,1,-1,-1};

const int dy[] = {1,0,-1,0,1,-1,-1,1};

const int inf = (1<<30)-1;

const ll infll = (1LL<<62)-1;

ll ceil(const ll &a, const ll &b){return ((a)+(b)-1)/b;}

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

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



ll dp[110][100100] = {};



int main(){

  ios::sync_with_stdio(false);

  cin.tie(nullptr);



  ll n, mx_w;

  cin >> n >> mx_w;

  vl w(n), v(n);

  rep(i,n) cin >> w[i] >> v[i];



  rep(i,n) {

    rep(j,mx_w+1) {

      if(j >= w[i]) chmax(dp[i+1][j], dp[i][j-w[i]] + v[i]);

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

    }

  }

  cout << dp[n][mx_w] << endl;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):




#include<bits/stdc++.h>







#define loop(i,a,b) for(int i=a;i<b;i++) 

#define rep(i,a) loop(i,0,a)



using namespace std;



template <class T>

using vec = std::vector<T>;

typedef long long ll;

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

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



const long long INF = 1LL<<60;



int lcm(int a,int b){

    //最小公倍数

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

}











int main()

{

    int n,W;cin>>n>>W;

    vec<int> weight(n+10);

    vec<int> val(n+10);

    rep(i,n){

        cin>>weight[i]>>val[i];

    }

    vec<vec<ll>> dp(n+100,vec<ll> (W+100,0)); //dp[(商品id)][(総重量w以下)]



    rep(i,n){

        rep(w,W+1){

            if(w<weight[i]) dp[i+1][w]=dp[i][w];

            else dp[i+1][w]=max(dp[i][w],dp[i][w-weight[i]]+val[i]);

            

        }

    }



    cout<<dp[n][W]<<endl;



    return 0;



}






// Optimized solution to the same problem (faster):




#include<bits/stdc++.h>







#define loop(i,a,b) for(int i=a;i<b;i++) 

#define rep(i,a) loop(i,0,a)



using namespace std;



template <class T>

using vec = std::vector<T>;

typedef long long ll;

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

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



const long long INF = 1LL<<60;



int lcm(int a,int b){

    //最小公倍数

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

}





// int型の2次元配列(3×4要素の)の宣言

// vector<vector<int>> data(3, vector<int>(4));









int main()

{

    int n,W;cin>>n>>W;

    vec<int> weight(n+10,0),val(n+10,0);

    rep(i,n) cin>>weight[i]>>val[i];

    vec<ll> dp(W+10,0);



    rep(i,n){

        for(int w=W;w>=0;w--){

            if(w>=weight[i]) dp[w]=max(dp[w],dp[w-weight[i]]+val[i]);

        }

    }



    cout<<dp[W]<<endl;

    return 0;



}






// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



const int N = 1e2 + 5;

const int W = 1e5 + 5;



long long dp [W];



int main () {

  int n, w;

  cin >> n >> w;

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

    int tempo, lucro;

    cin >> tempo >> lucro;

    vector<long long> cache (W);

    for (int j = tempo; j <= w; j++) {

      cache[j] = dp[j - tempo] + lucro;

    }

    for (int j = tempo; j <= w; j++) {

      dp[j] = max (dp[j], cache[j]);

    }

  }

  cout << dp[w] << '\n';

  return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



const int N = 1e2 + 5;

const int W = 1e5 + 5;



long long dp [W];

long long cache [W];



int main () {

  ios::sync_with_stdio(0);

  cin.tie(0);

  int n, w;

  cin >> n >> w;

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

    int tempo, lucro;

    cin >> tempo >> lucro;

    for (int j = tempo; j <= w; j++) {

      cache[j] = dp[j - tempo] + lucro;

    }

    for (int j = tempo; j <= w; j++) {

      dp[j] = max (dp[j], cache[j]);

    }

  }

  cout << dp[w] << '\n';

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std ;



#define int long long

const int N = 1e5 + 10 ;

int tp = N ;

int dp[N] ;

int32_t main(){

	int n, val; 

	cin >> n >> val ;

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

		int w , v ; 

		cin >> w >> v ;

		for(int j = tp - w - 1 ; j >= 0 ; j--){

			dp[j+w] = max(dp[j+w] , dp[j] + v) ;

		}

	}

	cout << dp[val] ;

	return 0 ;

}




// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std ;



#define int long long



int32_t main(){

	int n , w ;

	cin >> n >> w ;

	int dp[w+1] = {} ;

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

		int x , y ; 

		cin >> x >> y ;

		for(int j = w - x ; j >= 0 ; j--){

			dp[j+x] = max(dp[j+x] , dp[j] + y) ;

		}

	}

	cout << dp[w] ;

	return 0 ;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <string>

#include <vector>



using namespace std;



struct item {

    int w, v;

};



void knapsack1(){

    vector<item> items;

    int n, w;

    cin >> n >> w;

    long maxVal[n + 1][w + 1];

    items.push_back({0,0});

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

        int wt, vl;

        cin >> wt >> vl;

        items.push_back({wt, vl});

    }

    for (int i = 0; i <= w; i++){

        maxVal[0][i] = 0;

    }

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

        maxVal[i][0] = 0;

    }

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

        for (int j = 1; j <= w; j++) {

            if (j < items[i].w) {

                maxVal[i][j] = maxVal[i - 1][j];

            }

            else

                maxVal[i][j] = max(maxVal[i - 1][j], maxVal[i - 1][j - items[i].w] + items[i].v);

        }

    }

    cout << maxVal[n][w];

}



int main() {

    knapsack1();

}






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

#include <cstring>

#include <algorithm>

using namespace std;

int n,m,w,v;

long long f[100005];

int main()

{

	scanf("%d%d",&n,&m);

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

		scanf("%d%d",&w,&v);

		for(int j=m;j>=w;--j)

			f[j]=max(f[j],f[j-w]+v);

	}

	printf("%lld\n",f[m]);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#include <limits.h>

#include <algorithm>  

#include <numeric>

 

#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

using namespace std;

 

#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

#define endl '\n'

using ll = long long;

 

const int precision = 3;

const int modulo =  1000000007; // 10^9 + 7

const ll lmodulo =  1000000007; // 10^9 + 7

 

const double EPS = 1e-9;

const ll inf = 1e18;



// void solve () {

// 	int n, W; cin >> n >> W;

// 	vector<vector<ll>> dp(n + 1, vector<ll>(W + 1));



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

// 		int cw, v; cin >> cw >> v;

// 		for (int w = W; w >= 0; --w) {

// 			dp[i][w] = dp[i - 1][w];

// 			if(w - cw >= 0)

// 				dp[i][w] = max(dp[i][w], v + dp[i - 1][w - cw]);

// 		} 

// 	}

// 	cout << dp[n][W] << endl;

// }



void solve () {

	int n, W; cin >> n >> W;

	vector<vector<ll>> dp(2, vector<ll>(W + 1));



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

		int cw, v; cin >> cw >> v;

		auto & cur = dp[i % 2];

		const auto & prev = dp[(i - 1) % 2];

		for (int w = W; w >= 0; --w) {

			cur[w] = prev[w];

			if(w - cw >= 0) {

				cur[w] = max(cur[w], v + prev[w - cw]);

			}

		}

	}



	cout << dp[n % 2][W];

}



int main() {

  ios_base::sync_with_stdio(false);

  cin.tie(nullptr);

  cout.tie(nullptr);

  cout.precision(precision);

  cout.setf(ios_base::fixed);

  solve();

  return 0;

}




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

#include <cstring>

#include <algorithm>

using namespace std;

int n,m,w,v;

long long f[100005];

int main()

{

	scanf("%d%d",&n,&m);

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

		scanf("%d%d",&w,&v);

		for(int j=m;j>=w;--j)

			f[j]=max(f[j],f[j-w]+v);

	}

	printf("%lld\n",f[m]);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<cstdio>

#include<iostream>

#define ll long long

using namespace std;



ll dp[100000 +10], w[100000 +10];

ll v[100000 +10];

int main()

{

	int n,m; cin>>n>>m;

	int i,j;

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

	

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

	{

		for(j=m;j>=w[i];j--)

		{

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

		}

	}

	printf("%lld\n",dp[m]);

	return 0;

}

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

#include <cstring>

#include <algorithm>

using namespace std;

int n,m,w,v;

long long f[100005];

int main()

{

	scanf("%d%d",&n,&m);

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

		scanf("%d%d",&w,&v);

		for(int j=m;j>=w;--j)

			f[j]=max(f[j],f[j-w]+v);

	}

	printf("%lld\n",f[m]);

	return 0;

}

// Fastest known solution for this problem: