#include <bits/stdc++.h>
using namespace std;
struct nod {
int fir; // 数字第一次出现的位置
int sec; // 数字第二次出现的位置
// 带默认参数的构造函数
nod(int f = 0, int s = 0) : fir(f), sec(s) {}
};
int main() {
int n;
cin >> n;
int len = 2 * n;
vector<int> arr(len + 1); // 存储原始数组(1-based)
vector<long long> pre_sum(len + 1, 0); // 前缀和数组,用long long防止溢出
vector<nod> pos(len + 1); // pos[x] 存储数字x的第一次/第二次出现位置
vector<long long> dp(len + 1, 0); // dp[i] 表示前i个位置能得到的最大和
// 1. 读取数组并构建前缀和、记录每个数字的位置
for (int i = 1; i <= len; ++i) {
cin >> arr[i];
pre_sum[i] = pre_sum[i - 1] + arr[i]; // 计算前缀和
int x = arr[i]; // 当前位置的数字值
if (pos[x].fir == 0) {
pos[x].fir = i; // 第一次出现,记录位置
} else {
pos[x].sec = i; // 第二次出现,记录位置
}
}
// 2. 动态规划计算最大和
for (int i = 1; i <= len; ++i) {
// 情况1:不选第i个位置,最大和等于dp[i-1]
dp[i] = dp[i - 1];
// 情况2:如果i是某个数字的第二次出现位置,尝试选这个区间
int x = arr[i];
if (pos[x].sec == i) { // 确认i是数字x的第二次出现位置
int first = pos[x].fir; // 数字x第一次出现的位置
// 选这个区间的和 = 前first-1个位置的最大和 + 该区间的和
long long sum = dp[first - 1] + (pre_sum[i] - pre_sum[first - 1]);
dp[i] = max(dp[i], sum); // 取两种情况的最大值
}
}
// 输出前2n个位置的最大和
cout << dp[len] << endl;
return 0;
}