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
#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define db double
#define pint pair<int,int>
#define mk(x,y) make_pair(x,y)
#define fir first
#define sec second
#define Rep(x,y,z) for(int x=y;x<=z;x++)
#define Red(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
const int MAXN=2e5+5;
char buf[1<<12],*pp1=buf,*pp2=buf,nc;int ny;
inline char gc() {return pp1==pp2&&(pp2=(pp1=buf)+fread(buf,1,1<<12,stdin),pp1==pp2)?EOF:*pp1++;}
//inline char gc(){return getchar();}
inline int read(){
	int x=0;for(ny=1;nc=gc(),(nc<48||nc>57)&&nc!=EOF;)if(nc==45)ny=-1;if(nc<0)return nc;
	for(x=nc-48;nc=gc(),47<nc&&nc<58&&nc!=EOF;x=(x<<3)+(x<<1)+(nc^48));return x*ny;
}int n,a[MAXN],val[MAXN],cnt[MAXN],Mx;char s[MAXN];
struct SegTree{
	#define ls x<<1
	#define rs x<<1|1
	int Mx[MAXN<<2];
	inline void pushup(int x){Mx[x]=max(Mx[ls],Mx[rs]);}
	void Change(int x,int l,int r,int p,int v){
		if(l==r){Mx[x]=v;return;}int mid=l+r>>1;
		if(p<=mid)Change(ls,l,mid,p,v);else Change(rs,mid+1,r,p,v);
		pushup(x);
	}int Ask(int x,int l,int r,int ql,int qr){
		if(ql<=l&&r<=qr)return Mx[x];int mid=l+r>>1;
		if(qr<=mid)return Ask(ls,l,mid,ql,qr);else if(ql>mid)return Ask(rs,mid+1,r,ql,qr);
		else return max(Ask(ls,l,mid,ql,mid),Ask(rs,mid+1,r,mid+1,qr));
	}void Build(int x,int l,int r){
		Mx[x]=1-1e9;if(l==r)return;int mid=l+r>>1;
		Build(ls,l,mid),Build(rs,mid+1,r);
	}
}Odd,Even;
inline bool chk(int mx,int Q){if(Q<0)return 0;return Q&1?Odd.Ask(1,1,n,mx,n)>=Q:Even.Ask(1,1,n,mx,n)>=Q;}
int main(){
	n=read();
	Rep(i,1,n)a[i]=read(),a[i]>Mx?Mx=a[i],val[i]=2:val[i]=1;
	Odd.Build(1,1,n);
	Red(i,n,1){
		int Mx1=Odd.Ask(1,1,n,a[i],n),Mx0=Even.Ask(1,1,n,a[i],n);
		if(val[i]==1)Odd.Change(1,1,n,a[i],Mx0+1),Even.Change(1,1,n,a[i],Mx1+1);
		else Odd.Change(1,1,n,a[i],Mx1+2),Even.Change(1,1,n,a[i],Mx0+2);
	}Red(i,n,1)cnt[i]=cnt[i+1]+val[i]-1;
	int cntX=0,cntY=0,mxX=0,mxY=0;
	Rep(i,1,n){
		Odd.Change(1,1,n,a[i],1-1e9),Even.Change(1,1,n,a[i],0);
		if(chk(mxY,cntX+cnt[i+1]-cntY+(a[i]>mxX)))s[i]='0',cntX+=a[i]>mxX,mxX=max(mxX,a[i]);
		else if(chk(max(mxX,a[i]),cntY+cnt[i+1]-cntX-(a[i]>mxX)))s[i]='0',cntX+=a[i]>mxX,mxX=max(mxX,a[i]);
		else s[i]='1',cntY+=a[i]>mxY,mxY=max(mxY,a[i]);
	}if(cntX==cntY)cout<<s+1<<'\n';else puts("-1");
	return 0;
}


