#include <fstream>
//sol 1 aint
#include <algorithm>
using namespace std;
ifstream f("scmax.in");
ofstream g("scmax.out");
int n,k,m;
const int N=1e5+5;
int best[N];
int last[N];
struct pct
{
int x,y;
} v[N],a[4*N];
bool cmp(pct X,pct Y)
{
if(X.x==Y.x)
return X.y>Y.y;
return X.x<Y.x;
}
void update_aint(int nod,int st,int dr,int poz, int val,int p1)
{
if(st==dr)
{
a[nod].x=val;
a[nod].y=p1;
return;
}
int mj=(st+dr)/2;
if(mj>=poz)
update_aint(nod*2,st,mj,poz,val,p1);
else
update_aint(nod*2+1,mj+1,dr,poz,val,p1);
a[nod].x=max(a[nod*2].x,a[nod*2+1].x);
if(a[nod*2].x>=a[nod*2+1].x)
a[nod].y=a[nod*2].y;
else
a[nod].y=a[nod*2+1].y;
}
void max_self(pct &X,pct Y)
{
if(X.x>Y.x)
return;
else
if(X.x==Y.x&&X.y>Y.x)
X=Y;
else
if(X.x<Y.x)
X=Y;
}
pct query_aint (int nod,int st, int dr,int qst,int qdr)
{
if(qst<=st&&dr<=qdr)
{
return a[nod];
}
if(st>dr)
return {0,0};
int mj=(st+dr)/2;
pct mx= {0,0};
if(mj>=qst)
max_self(mx,query_aint(nod*2,st,mj,qst,qdr));
if(mj+1<=qdr)
max_self(mx,query_aint(nod*2+1,mj+1,dr,qst,qdr));
return mx;
}
void afisare(int poz)
{
if(poz==0) return;
afisare(last[poz]);
g<<v[poz].x<<" ";
}
int main()
{
f>>n;
for(int i=1; i<=n; i++)
f>>v[i].x,v[i].y=i;
sort(v+1,v+n+1,cmp);
int i=1;
for(int i=1; i<=n; i++)
{
pct T=query_aint (1,1,n,1,v[i].y);
best[i]=T.x+1;
last[i]=T.y;
update_aint(1,1,n,v[i].y,best[i],i);
}
int mx=0,poz;
for(int i=1; i<=n; i++)
if(best[i]>mx)
mx=best[i],poz=i;
g<<mx<<'\n';
afisare(poz);
return 0;
}