#include<stdio.h>
#define MID int mid=(left+right)/2;
#define APOS arb[nod].pos
#define NMAX 100000
int a[NMAX+1],best[NMAX+1],poz[NMAX+1],n,pos,var;
struct arbore
{
void init(int a,int b,int c)
{
val=a;
pos=b;
max=c;
}
int val, pos, max;
}arb[4*NMAX+1];
FILE*g=fopen("scmax.out","w");
void afis()
{
int i=pos;
do
{
fprintf(g,"%d ",a[i]);
i=poz[i];
}while(i!=-1);
}
int max(int a,int b)
{
if(a>=b)return a;
return b;
}
void init(int nod,int left,int right)
{
arb[nod].init(0,left,0);
if(left==right)return;
MID
init(nod*2,left,mid);
init(nod*2+1,mid+1,right);
}
void update(int nod,int left,int right,int x,int pos)
{
if(left==right)
{
arb[nod].init(max(arb[nod].val,x),left,a[left]);
if(var==-1)arb[nod].max=0;
return;
}
MID
if(pos<=mid)update(nod*2,left,mid,x,pos);
else update(nod*2+1,mid+1,right,x,pos);
arb[nod].val=max(arb[nod*2].val,arb[nod*2+1].val);
arb[nod].max=max(arb[nod*2].max,arb[nod*2+1].max);
if(arb[nod].val==arb[nod*2].val)arb[nod].pos=arb[nod*2].pos;
else arb[nod].pos=arb[nod*2+1].pos;
}
void querry(int nod,int left,int right,int pos)
{
if( best[pos]<arb[nod].val+1 && a[pos]<a[APOS] )
{
best[pos]=arb[nod].val+1;
var=arb[nod].pos;
poz[pos]=var;
return;
}
if(left==right)return;
MID
if( best[pos]<arb[nod*2].val+1)querry(nod*2,left,mid,pos);
if( best[pos]<arb[nod*2+1].val+1 )querry(nod*2+1,mid+1,right,pos);
}
int dinamic()
{
best[n]=1;
poz[n]=-1;
update(1,1,n,best[n],n);
int i,j,max=1;
pos=n;
for(i=n-1;i>0;--i)
{
best[i]=1;
poz[i]=-1;
var=-1;
querry(1,1,n,i);
if(var!=-1)
{
//best[i]=best[var]+1;
if(max<best[i]){max=best[i];pos=i;}
}
update(1,1,n,best[i],i);
/*for(j=i+1;j<n;++j)
if(best[i]<best[j]+1&&a[i]<a[j])
{
best[i]=best[j]+1;
update(1,1,n,best[i],i);
poz[i]=j;
if(max<best[i]){max=best[i];pos=i;}
} */
}
return max;
}
int main()
{
FILE*f=fopen("scmax.in","r");
fscanf(f,"%d ",&n);
int i;
for(i=1;i<=n;++i)
fscanf(f,"%d",&a[i]);
fclose(f);
init(1,1,n);
fprintf(g,"%d\n",dinamic());
afis();
fclose(g);
}