//Arbori de intervale
#include<fstream>
#include<algorithm>
using namespace std;
#define MAX 100001
int lst[MAX],v[MAX],R[MAX],AI[MAX*4 +66],pos[MAX],D[MAX],N,i;
ifstream in("scmax.in");
ofstream out("scmax.out");
int query(int x,int y,int l,int r,int k)
{
if(!y)
return 0;
if(x<=l && r<=y)
return AI[k];
else
{
int mid=(l+r)/2;
int max=0,el;
if(x<=mid)
max=query(x,y,l,mid,k*2);
if(y>mid)
{
el=query(x,y,mid+1,r,k*2 +1);
if(D[el]>D[max])
max=el;
}
return max;
}
}
void update(int e,int val,int l,int r,int k)
{
if(l==e && r==e)
AI[k]=val;
else
{
int mid=(l+r)/2;
if(e<=mid)
update(e,val,l,mid,k*2);
else
update(e,val,mid+1,r,k*2+1);
AI[k]=D[AI[k*2]] > D[AI[k*2+1]] ? AI[k*2] : AI[k*2+1];
}
}
int main()
{
in>>N;
for(i=1;i<=N;i++)
in>>lst[i],R[i]=lst[i];
sort(lst+1,lst + N +1);
int l=1;
for(i=2;i<=N;i++)
if(lst[l]!=lst[i])
lst[++l]=lst[i];
for(i=1;i<=N;i++)
v[i]=lower_bound(lst + 1,lst + l + 1 ,R[i]) -lst;
for(i=1;i<=N;i++)
{
pos[i]=query(1,v[i]-1,1,N,1);
D[i]=1 + D[pos[i]];
update(v[i],i,1,N,1);
}
int mx=0;
for(i=1;i<=N;i++)
if(D[i]>D[mx])
mx=i;
int j=0;
for(i=mx;i;i=pos[i])
{
lst[++j]=R[i];
}
out<<D[mx]<<'\n';
for(i=j;i;--i)
out<<lst[i]<<" ";
return 0;
}