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 <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define lson u << 1, l, mid
#define rson u << 1 | 1, mid + 1, r
inline char nc()
{
	// return getchar();
	static char buf[100000], * l = buf, * r = buf;
	if(l == r) r = (l = buf) + fread(buf, 1, 100000, stdin);
	if(l == r) return EOF;
	return *l++;
}
template<class T> void readin(T & x)
{
	x = 0; int f = 1, ch = nc();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
	x *= f;
}
int n, p[200050], Q;
int points[200050];
struct SegmentTree
{
	int mx[800050];
	inline void pushup(int u)
	{
		mx[u] = max(mx[u << 1], mx[u << 1 | 1]);
	}
	int query(int u, int l, int r, int ql, int qr)
	{
		if(l == ql && r == qr) return mx[u];
		int mid = (l + r) >> 1;
		if(qr <= mid) return query(lson, ql, qr);
		else if(ql > mid) return query(rson, ql, qr);
		else
		{
			int L = query(lson, ql, mid);
			int R = query(rson, mid + 1, qr);
			return max(L, R);
		}
	}
	void update(int u, int l, int r, int qp, int qv)
	{
		if(l == r)
		{
			mx[u] = qv;
			return;
		}
		int mid = (l + r) >> 1;
		if(qp <= mid) update(lson, qp, qv);
		else update(rson, qp, qv);
		pushup(u);
	}
} seg[2];
inline bool judge(int x, int y)
{
	if(y < 0) return 0;
	if(x == n) return y == 0;
	// cerr << x << ' ' << y << ' ' << seg[y & 1].query(1, 1, n, x + 1, n) << endl;
	return seg[y & 1].query(1, 1, n, x + 1, n) >= y;
}
inline bool judge(int cx, int cy, int hx, int hy)
{
	// cerr << endl;
	// cerr << cx << ' ' << cy << ' ' << Q << ' ' << hx << ' ' << hy << endl;
	return judge(hx, Q - cx + cy) || judge(hy, Q + cx - cy);
}
void solve()
{
	memset(seg[1].mx, -0x3f, sizeof(seg[1].mx));
	for(int i = 1, mx = -1; i <= n; ++i)
	{
		points[i] = 1;
		if(p[i] > mx)
		{
			mx = p[i];
			points[i] = 2;
			Q++;
		}
	}
	for(int i = n; i >= 1; --i)
	{
		int f[2];
		for(int j = 0; j < 2; ++j)
		{
			f[j] = seg[j ^ (points[i] == 1)].query(1, 1, n, p[i], n) + points[i];
		}
		for(int j = 0; j < 2; ++j)
		{
			seg[j].update(1, 1, n, p[i], f[j]);
		}
	}
	if(!judge(0, Q))
	{
		puts("-1");
		return;
	}
	int cx = 0, cy = 0, hx = 0, hy = 0;
	for(int i = 1; i <= n; ++i)
	{
		if(points[i] == 2) Q--;
		seg[0].update(1, 1, n, p[i], 0);
		seg[1].update(1, 1, n, p[i], -1);
		if(judge(cx + (p[i] > hx), cy, max(hx, p[i]), hy))
		{
			putchar('0');
			if(p[i] > hx)
			{
				hx = p[i];
				++cx;
			}
		}
		else
		{
			putchar('1');
			if(p[i] > hy)
			{
				hy = p[i];
				++cy;
			}
		}
	}
	putchar('\n');
}
int main()
{
	readin(n);
	for(int i = 1; i <= n; ++i)
	{
		readin(p[i]);
	}
	solve();
	return 0;
}