Problem:
Score : 1600 points

Problem Statement

You are given a string S of length 2N, containing N occurrences of a and N occurrences of b.

You will choose some of the characters in S. Here, for each i = 1,2,...,N, it is not allowed to choose exactly one of the following two: the i-th occurrence of a and the i-th occurrence of b. (That is, you can only choose both or neither.) Then, you will concatenate the chosen characters (without changing the order).

Find the lexicographically largest string that can be obtained in this way.

Constraints

1 \leq N \leq 3000

S is a string of length 2N containing N occurrences of a and N occurrences of b.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the lexicographically largest string that satisfies the condition.

Sample Input 1

3
aababb

Sample Output 1

abab

A subsequence of T obtained from taking the first, third, fourth and sixth characters in S, satisfies the condition.

Sample Input 2

3
bbabaa

Sample Output 2

bbabaa

You can choose all the characters.

Sample Input 3

6
bbbaabbabaaa

Sample Output 3

bbbabaaa

Sample Input 4

9
abbbaababaababbaba

Sample Output 4

bbaababababa

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

/*
    _____
  .'     '.
 /  0   0  \
|     ^     |
|  \     /  |
 \  '---'  /
  '._____.'
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

struct chash
{
	int operator()(int x) const
	{
		x ^= (x >> 20) ^ (x >> 12);
		return x ^ (x >> 7) ^ (x >> 4);
	}
};

template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename T, typename U> using hashtable = gp_hash_table<T, U, chash>;
random_device(rd);
mt19937 rng(rd());

template<class T>
void readi(T &x)
{
	T input = 0;
	bool negative = false;
	char c = ' ';
	while (c < '-')
	{
		c = getchar();
	}
	if (c == '-')
	{
		negative = true;
		c = getchar();
	}
	while (c >= '0')
	{
		input = input * 10 + (c - '0');
		c = getchar();
	}
	if (negative)
	{
		input = -input;
	}
	x = input;
}
template<class T>
void printi(T output)
{
	if (output == 0)
	{
		putchar('0');
		return;
	}
	if (output < 0)
	{
		putchar('-');
		output = -output;
	}
	int aout[20];
	int ilen = 0;
	while(output)
	{
		aout[ilen] = ((output % 10));
		output /= 10;
		ilen++;
	}
	for (int i = ilen - 1; i >= 0; i--)
	{
		putchar(aout[i] + '0');
	}
	return;
}
template<class T>
void ckmin(T &a, T b)
{
	a = min(a, b);
}
template<class T>
void ckmax(T &a, T b)
{
	a = max(a, b);
}
template<class T, class U>
T nmod(T &x, U mod)
{
	if (x >= mod) x -= mod;
}
template<class T>
T randomize(T mod)
{
	return (uniform_int_distribution<T>(0, mod - 1))(rng);
}

#define y0 ___y0
#define y1 ___y1
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define PF push_front
#define LB lower_bound
#define UB upper_bound
#define fi first
#define se second
#define debug(x) cerr << #x << " = " << x << endl;

const long double PI = 4.0 * atan(1.0);
const long double EPS = 1e-10;

#define MAGIC 347
#define SINF 10007
#define CO 1000007
#define INF 1000000007
#define BIG 1000000931
#define LARGE 1696969696967ll
#define GIANT 2564008813937411ll
#define LLINF 2696969696969696969ll
#define MAXN 6013

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;

int N, K;
int arr[MAXN], pref[MAXN];
int blocks[MAXN];
int partner[MAXN];
bitset<MAXN> typ;
vector<pii> idx[MAXN];
vector<bool> dp[MAXN];
vector<bool> ans;
bitset<MAXN> flag;

bool operator < (const vector<bool> &a, const vector<bool> &b)
{
	for (int i = 0; i < min(a.size(), b.size()); i++)
	{
		if (a[i] != b[i])
		{
			return a[i] < b[i];
		}
	}
	return (a.size() < b.size());
}
bool operator > (const vector<bool> &a, const vector<bool> &b)
{
	return b < a;
}

int32_t main()
{
	ios_base::sync_with_stdio(0);
	// cout << fixed << setprecision(10);
	// cerr << fixed << setprecision(10);
	// freopen ("file.in", "r", stdin);
	// freopen ("file.out", "w", stdout);
	cin >> N;
	N *= 2;
	string temps;
	cin >> temps;
	for (int i = 0; i < N; i++)
	{
		arr[i] = (temps[i] == 'a' ? 1 : -1);
		pref[i + 1] = pref[i] + arr[i];
	}
	for (int i = 1; i <= N; i++)
	{
		if (pref[i] == 0)
		{
			K++;
			blocks[K] = i - 1;
		}
	}
	blocks[0] = -1;
	for (int i = 1; i <= K; i++)
	{
		int lt = blocks[i - 1] + 1, rt = blocks[i];
		idx[i].resize((rt - lt + 1) / 2);
		int iter = 0;
		for (int j = lt; j <= rt; j++)
		{
			if (arr[j] == 1)
			{
				idx[i][iter].fi = j;
				iter++;
			}
		}
		iter = 0;
		for (int j = lt; j <= rt; j++)
		{
			if (arr[j] == -1)
			{
				idx[i][iter].se = j;
				iter++;
			}
		}
		// cerr << "block " << i << endl;
		for (pii p : idx[i])
		{
			partner[p.fi] = p.se;
			partner[p.se] = p.fi;
			// cerr << p.fi << ' ' << p.se << endl;
		}
		typ[i] = (bool) (idx[i][0].fi > idx[i][0].se);
	}
	for (int i = 1; i <= K; i++)
	{
		//if typ[i] is true, it's abababababab
		//if typ[i] is false, it's babababababa
		int lt = blocks[i - 1] + 1, rt = blocks[i];
		if (typ[i])
		{
			//babababa
			vector<bool> temp;
			for (int j = idx[i].size() - 1; j >= 0; j--)
			{
				flag[idx[i][j].fi] = true;
				flag[idx[i][j].se] = true;
				temp.clear();
				for (int k = lt; k <= rt; k++)
				{
					if (flag[k])
					{
						temp.PB(arr[k] - 1);
					}
				}
				if (temp > dp[i])
				{
					dp[i] = temp;
				}
				// for (bool b : dp[i])
				// {
				// 	cerr << (b ? 'b' : 'a');
				// }
				// cerr << endl;
			}
		}
		else
		{
			//ababababab
			for (int j = lt; j <= rt; j = partner[j] + 1)
			{
				dp[i].PB(0);
				dp[i].PB(1);
			}
		}
	}
	// cerr << "our dps\n";
	for (int i = 1; i <= K; i++)
	{
		// for (bool b : dp[i])
		// {
		// 	cerr << (b ? 'b' : 'a');
		// }
		// cerr << endl;
		bool used = true;
		for (int j = i + 1; j <= K; j++)
		{
			if (dp[j] > dp[i])
			{
				used = false;
				break;
			}
		}
		if (used)
		{
			for (bool b : dp[i])
			{
				ans.PB(b);
			}
		}
	}
	for (bool b : ans)
	{
		cout << (b ? 'b' : 'a');
	}
	cout << '\n';
	// cerr << "time elapsed = " << (clock() / (CLOCKS_PER_SEC / 1000)) << " ms" << endl;
	return 0;
}