RT
#include<iostream>
#include<algorithm>
typedef long long Int;
constexpr int MAXN = 1000000;
constexpr int MAXW = 1000000;
int N, M, F[1 + MAXN], W[1 + MAXW], last[1 + MAXN] {}, lastlast[1 + MAXN] {};
enum OPTTYPE{
GETS, GETL, GETR, GETA
};
// 此题为单点修改,区间查询最大子段和
struct Seg{
int L, R;
Seg *ls, *rs;
Int sum, lmax, rmax, amax;
Seg (){
sum = lmax = rmax = amax = 0;
}
} sentry;
void build_tree(Seg *root, int L, int R){
root->L = L, root->R = R;
if (R - L <= 1){
return ;
}
root->ls = new Seg, root->rs = new Seg;
int mid = (L + R) >> 1;
build_tree(root->ls, L, mid);
build_tree(root->rs, mid, R);
}
void change(Seg *root, int pos, int X){
if (pos == 0) return ;
if (root->R - root->L <= 1){
root->sum = X;
root->lmax = X;
root->rmax = X;
root->amax = X;
return ;
}
if (pos < root->ls->R){
change(root->ls, pos, X);
} else if (pos >= root->rs->L){
change(root->rs, pos, X);
}
root->sum = root->ls->sum + root->rs->sum,
root->lmax = std:: max(root->ls->lmax, root->ls->sum + root->rs->lmax);
root->rmax = std:: max(root->ls->rmax + root->rs->sum, root->rs->rmax);
root->amax = std:: max(root->ls->rmax + root->rs->lmax, std:: max(root->ls->amax, root->rs->amax));
}
Int query(Seg *root, int R, char what){
if (root->R <= R){
if (what == OPTTYPE::GETS) return root->sum;
if (what == OPTTYPE::GETL) return root->lmax;
if (what == OPTTYPE::GETR) return root->rmax;
if (what == OPTTYPE::GETA) return root->amax;
}
if (root->rs->L < R){
if (what == OPTTYPE::GETS) return root->ls->sum + root->rs->sum;
if (what == OPTTYPE::GETL) return std:: max(root->ls->lmax, root->ls->sum + root->rs->lmax);
if (what == OPTTYPE::GETR) return std:: max(root->ls->rmax + root->rs->sum, root->rs->rmax);
if (what == OPTTYPE::GETA) return std:: max(root->ls->rmax + root->rs->lmax,std:: max(root->ls->amax, root->rs->amax));
} else {
if (what == OPTTYPE::GETS) return root->ls->sum;
if (what == OPTTYPE::GETL) return root->ls->lmax;
if (what == OPTTYPE::GETR) return root->ls->rmax;
if (what == OPTTYPE::GETA) return root->ls->amax;
}
}
int main(){
std:: ios:: sync_with_stdio(false);
std:: cin >> N >> M;
for (int i = 1 ; i <= N ; i++){
std:: cin >> F[i];
}
for (int i = 1 ; i <= M ; i++){
std:: cin >> W[i];
}
build_tree(&sentry, 1, N + 1);
Int ans = 0;
for (int i = 1 ; i <= N ; i++){
change(&sentry, i, W[F[i]]);
change(&sentry, last[F[i]], -W[F[i]]);
change(&sentry, lastlast[F[i]], 0);
lastlast[F[i]] = last[F[i]];
last[F[i]] = i;
ans = std:: max(ans, query(&sentry, i + 1, OPTTYPE::GETA));
}
std:: cout << ans << '\n';
return 0;
}