#include "fish.h"
#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int MAX=3e3+5;
vector<pii> fish[MAX];
int costl[MAX][MAX],costr[MAX][MAX];
ll dp[MAX][2];
long long max_weights(int N, int M, std::vector<int> X, std::vector<int> Y, std::vector<int> W){
assert(N<=3000);
for (int i=0;i<M;i++) fish[X[i]].push_back({Y[i],i});
for (int i=0;i<N;i++) sort(fish[i].begin(),fish[i].end());
for (int i=0;i<N;i++){
vector<pair<ll,int>> vct={{0,0}};
for (int j=i;j<N;j++){
vector<pair<ll,int>> nxt;
int k=0;
for (auto [a,fi]:fish[j]){
while (k<(int)vct.size()-1&&vct[k+1].first<a) k++;
if (vct[k].first>=a) continue;
nxt.push_back({a,vct[k].second+W[fi]});
}
if (!nxt.size()) break;
vct=nxt;
if (j<N-1) costr[i][j+1]=vct.back().second;
}
vct={{0,0}};
for (int j=i;j>=0;j--){
vector<pair<ll,int>> nxt;
int k=0;
for (auto [a,fi]:fish[j]){
while (k<(int)vct.size()-1&&vct[k+1].first<a) k++;
if (vct[k].first>=a) continue;
nxt.push_back({a,vct[k].second+W[fi]});
}
if (!nxt.size()) break;
vct=nxt;
if (j>0) costl[j-1][i]=vct.back().second;
}
}
/*
for (int i=0;i<N;i++){
for (int j=0;j<N;j++) cout<<costl[i][j]<<' ';
cout<<'\n';
}
cout<<'\n';
for (int i=0;i<N;i++){
for (int j=0;j<N;j++) cout<<costr[i][j]<<' ';
cout<<'\n';
}
*/
for (int i=0;i<N;i++) for (int j=0;j<i;j++){
dp[i][0]=max(dp[i][0],costr[j][i]+(j==0?0:max(dp[j-1][0],dp[j-1][1])));
dp[i][1]=max(dp[i][1],costl[j][i]+max(dp[j][0],(j==0?0:dp[j-1][1])));
}
return max(dp[N-1][0],dp[N-1][1]);
}