Problem: You are given P, a permutation of (1,\ 2,\ ...\ N).

A string S of length N consisting of `0` and `1` is a good string when it meets the following criterion:

* The sequences X and Y are constructed as follows:
* First, let X and Y be empty sequences.
* For each i=1,\ 2,\ ...\ N, in this order, append P_i to the end of X if S_i= `0`, and append it to the end of Y if S_i= `1`.
* If X and Y have the same number of high elements, S is a good string. Here, the i-th element of a sequence is called high when that element is the largest among the elements from the 1-st to i-th element in the sequence.



Determine if there exists a good string. If it exists, find the lexicographically smallest such string.

Constraints

* 1 \leq N \leq 2 \times 10^5
* 1 \leq P_i \leq N
* P_1,\ P_2,\ ...\ P_N are all distinct.
* All values in input are integers.

Input

Input is given from Standard Input in the following format:


N
P_1 P_2 ... P_N


Output

If a good string does not exist, print `-1`. If it exists, print the lexicographically smallest such string.

Examples

Input

6
3 1 4 6 2 5


Output

001001


Input

5
1 2 3 4 5


Output

-1


Input

7
1 3 2 5 6 4 7


Output

0001101


Input

30
1 2 6 3 5 7 9 8 11 12 10 13 16 23 15 18 14 24 22 26 19 21 28 17 4 27 29 25 20 30


Output

000000000001100101010010011101

Solution (in CPP):

Solution:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
struct SegmentTree {
	struct Node {
		int lc, rc;
		int tag, Max;
	} a[MAXN * 2];
	int n, root, size;
	void build(int &root, int l, int r) {
		root = ++size;
		a[root].tag = 0;
		a[root].Max = 0;
		if (l == r) return;
		int mid = (l + r) / 2;
		build(a[root].lc, l, mid);
		build(a[root].rc, mid + 1, r);
	}
	void init(int x) {
		n = x, root = size = 0;
		build(root, 1, n);
	}
	void update(int root) {
		a[root].Max = max(a[a[root].lc].Max, a[a[root].rc].Max);
	}
	void pushdown(int root) {
		if (a[root].tag) {
			a[a[root].lc].tag += a[root].tag;
			a[a[root].lc].Max += a[root].tag;
			a[a[root].rc].tag += a[root].tag;
			a[a[root].rc].Max += a[root].tag;
			a[root].tag = 0;
		}
	}
	void modify(int root, int l, int r, int ql, int qr, int d) {
		if (l == ql && r == qr) {
			a[root].tag += d;
			a[root].Max += d;
			return;
		}
		int mid = (l + r) / 2;
		pushdown(root);
		if (mid >= ql) modify(a[root].lc, l, mid, ql, min(mid, qr), d);
		if (mid + 1 <= qr) modify(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, d);
		update(root);
	}
	void modify(int l, int r, int d) {
		modify(root, 1, n, l, r, d);
	}
	int query(int root, int l, int r, int ql, int qr) {
		if (l == ql && r == qr) return a[root].Max;
		int mid = (l + r) / 2; pushdown(root);
		if (mid >= qr) return query(a[root].lc, l, mid, ql, qr);
		else if (mid + 1 <= ql) return query(a[root].rc, mid + 1, r, ql, qr);
		else return max(query(a[root].lc, l, mid, ql, mid), query(a[root].rc, mid + 1, r, mid + 1, qr));
	}
	int query(int l, int r) {
		if (l > r) return 0;
		else return query(root, 1, n, l, r);
	}
} ST[2];
int n, a[MAXN], value[MAXN], dp[MAXN][2], suf[MAXN];
bool check(int pos, int cntx, int cnty, int Max, int May) {
	int x = cntx - cnty + suf[pos + 1];
	if (x >= 0 && ST[x & 1].query(May + 1, n) >= x) return true;
	x = cnty - cntx + suf[pos + 1];
	if (x >= 0 && ST[x & 1].query(Max + 1, n) >= x) return true;
	return false;
}
int main() {
	read(n);
	for (int i = 1, Max = 0; i <= n; i++) {
		read(a[i]), chkmax(Max, a[i]);
		if (Max == a[i]) value[i] = 2;
		else value[i] = 1;
	}
	for (int i = n; i >= 1; i--)
		suf[i] = suf[i + 1] + value[i] - 1;
	ST[0].init(n), ST[1].init(n);
	for (int i = n; i >= 1; i--) {
		for (int j = 0; j <= 1; j++) {
			int cur = value[i] + ST[j].query(a[i], n);
			chkmax(dp[i][cur & 1], cur);
		}
		ST[0].modify(a[i], a[i], dp[i][0]);
		ST[1].modify(a[i], a[i], dp[i][1]);
	}
	string ans;
	int cntx = 0, cnty = 0, Max = 0, May = 0;
	if (!check(0, cntx, cnty, Max, May)) {
		puts("-1");
		return 0;
	}
	for (int i = 1; i <= n; i++) {
		ST[0].modify(a[i], a[i], -dp[i][0]);
		ST[1].modify(a[i], a[i], -dp[i][1]);
		if (check(i, cntx + (a[i] >= Max), cnty, max(a[i], Max), May)) {
			cntx += a[i] >= Max;
			chkmax(Max, a[i]);
			ans += '0';
		} else {
			cnty += a[i] >= May;
			chkmax(May, a[i]);
			ans += '1';
		}
	}
	cout << ans << endl;
	return 0;
}