//
// Created by Mrlaolu on 2024/7/10.
//
#include<bits/stdc++.h>
#define x first
#define y second
typedef std::pair<int,int> PII;
using namespace std;
bool cmp(PII &a,PII &b){
return a.y - a.x < b.y - b.x; //长度比较
}
void solve() {
//code here
int n;cin >> n;
int nn = 2 * n;
vector<int>arr(nn + 2); //存原始数据数组
vector<PII>pos(n + 1); //1-n数字对的左位置和右位置
for(int i = 1;i <= nn;++i){ //初始数据处理
cin >> arr[i];
if(pos[arr[i]].x)pos[arr[i]].y = i;
else pos[arr[i]].x = i;
}
vector<PII>up(n + 1); //用于复制pos数组
pos.push_back({0,nn+1}); //为了方便,最后遍历整个数组时而加入。与for(0~nn+1)没有本质区别
up = pos;
sort(up.begin(),up.end(),cmp);
//用于复制pos数组,并按照区间长度从小到大排序
//目的是为了让小区间先进行合并,大区间后合并,方便大区间包含“整个”小区间时,直接取max决策这个小区间是合并了贡献大还是不合并贡献大
//如不懂可以先放着看下面
vector<int>tmp(nn + 2); //用于每个区间遍历时存值
vector<int>dp(nn + 2); //存每个区间遍历完后的值 dp[y] 为 区间[x,y]整合后的最大值(注意:这个值仅存于dp[y]
//目的是方便下面那行max决策时取值
for(auto [l,r] : up){ //相当于int l = up[i].x ,int r = up[i].y;
tmp[l] = arr[l]; //tmp[i] 遍历这个区间时暂时存合并这个最优值(合并好(如果能合并更小的区间)还是不合并好)
for(int i = l + 1;i <= r;++i){
tmp[i] = tmp[i - 1] + arr[l]; //不考虑其他,只是遍历
int left = pos[arr[i]].x; //假设这个位置存的值是右值 去存当前位置的这个值的左值
if(left != i && left > l){ //如果当前确实是左值 且在这个大区间里 我就取max进行决策(到底是”合并这个区间值大“还是”不合并大“)
tmp[i] = max(tmp[i],tmp[left - 1] + dp[i]); //重点! dp[i]就是合并这个小区间所获得的值(被合并的值都在dp[i]里),因为被取,所以左边剩下的tmp[left-1]
}
}
dp[r] = tmp[r] ; //遍历完后 将合并这个区间的最优解放在dp[r]里
}
cout << dp[nn + 1] << endl; //输出整个区间的最优解
}