#include<stdio.h>
#include<stdlib.h>
#define NMAX 100000
#define MMAX 265000
long n,a[NMAX+1],b[NMAX+1],m;
int l[NMAX+1],maxim;
int best[MMAX];
int fcmp(const void*xx,const void*yy){
if ((*(long*)xx)>(*(long*)yy)) return 1;
else if ((*(long*)xx)<(*(long*)yy)) return -1;
else return 0;
}
int cauta(long x){
int i=1,j=m,mij;
while(i<=j){
mij=(i+j)/2;
if(b[mij]==x) return mij;
else if(x<b[mij]) j=mij-1;
else i=mij+1;
}
return 0;
}
void upd(int nod){
int i=1,j=m,k=1,mij,st,dr;
while(i<=j){
if(i==j){
best[k]=nod;
k/=2;
while(k){
st=best[2*k];dr=best[2*k+1];
if(l[st]>l[dr]) best[k]=st;
else best[k]=dr;
k/=2;
}
return;
}
else{
mij=(i+j)/2;
if(nod<=mij) {k=2*k;j=mij;}
else {k=2*k+1;i=mij+1;}
}
}
}
void qry(int nod,int st,int dr,int li,int &mx){
int mij,mxst,mxdr;
mx=0;
if(li<=st&&dr<=m){
if(mx<best[nod]) mx=best[nod];
}
else{
mij=(st+dr)/2;
if(li<=mij) {qry(nod*2,st,mij,li,mxst);
if(l[mx]<l[mxst]) mx=mxst; }
if(dr<=m) {qry(nod*2+1,mij+1,dr,li,mxdr);
if(l[mx]<l[mxdr]) mx=mxdr;}
}
}
int main(){
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
int i,poz,lmax,first,next[NMAX+1]={0};
char sir[NMAX*11],*p;
scanf("%ld\n",&n);
fgets(sir,NMAX*11,stdin);p=sir;
for(i=1;i<=n;i++){
a[i]=(long)atoi(p);
while(*p!=32) p++;p++;
b[i]=a[i];
}
qsort(b,n+1,sizeof(b[0]),fcmp);
m=0;
for(i=1;i<=n;i++)
if(b[i]!=b[i-1]) {m++;b[m]=b[i];}
for(i=n;i>0;i--){
poz=cauta(a[i]);
if(b[poz]<best[1])
maxim=best[1];
else {maxim=0;
qry(1,1,m,poz+1,maxim);
}
l[poz]=l[maxim]+1;
next[poz]=maxim;
upd(poz);
}
lmax=0;first=0;
for(i=1;i<=m;i++)
if(l[i]>lmax) {lmax=l[i];first=i;}
printf("%d\n",lmax);
i=first;
while(next[i]!=0){
printf("%ld ",b[i]);
i=next[i];
}
printf("%ld",b[i]);
return 0;
}