#include <fstream>
#include <algorithm>
using namespace std;
const int N=100100;
int x[N],norm[N];
ofstream h("scmax.out");
struct arbore
{
int v,el;
}arb[2*N+1],xx[N];
struct nrm
{
int v, poz;
}cpy[N];
int n,mx,maxx;
bool cmp(nrm x1, nrm x2)
{
if(x1.v<x2.v)
return true;
return false;
}
void citire()
{
ifstream f("scmax.in");
f>>n;
for(int i=1;i<=n;++i){
f>>x[i];
cpy[i].v=x[i];
cpy[i].poz=i;
}
f.close();
}
inline arbore max(arbore x1, arbore x2)
{
if(x1.v>x2.v)
return x1;
return x2;
}
void formare(int nod, int s, int d)
{
if(s==d)
arb[nod].el=-1;
else
{
int m=(s+d)>>1;
formare(2*nod,s,m);
formare(2*nod+1,m+1,d);
arb[nod].el=-1;
}
}
arbore query(int nod, int s, int d, int a, int b)
{
if(a>b)
return {0,-1};
if(a<=s&&d<=b)
{
return arb[nod];
}
else
{
int m=(s+d)/2;
arbore ss={0,-1},dd={0,-1};
if(a<=m)
ss=query(2*nod,s,m,a,b);
if(b>m)
dd=query(2*nod+1,m+1,d,a,b);
return arb[nod]=max(ss,dd);
}
}
void update(int nod, int s, int d, int v)
{
if(s==d){
arb[nod].el=v;
arb[nod].v=max(xx[v].v,arb[nod].v);}
else
{
int m=(s+d)>>1;
if(norm[v]<=m)
update(2*nod,s,m,v);
else update(2*nod+1,m+1,d,v);
arb[nod]=max(arb[2*nod],arb[2*nod+1]);
}
}
void normaliz()
{
int k=0,ant=-1;
for(int i=1;i<=n;++i)
{
if(cpy[i].v!=ant)
{
ant=cpy[i].v;
++k;
}
norm[cpy[i].poz]=k;
}
maxx=k;
}
void solve()
{
for(int i=1;i<=n;++i)
{
xx[i]=query(1,1,maxx,1,norm[i]-1);
xx[i].v++;
update(1,1,maxx,i);
if(xx[i].v>xx[mx].v)
mx=i;
}
}
void afisare()
{
h<<xx[mx].v<<'\n';
while(xx[mx].el!=-1)
{
h<<xx[mx].v<<" ";
mx=xx[mx].el;
}
}
int main()
{
citire();
sort(cpy+1,cpy+n+1,cmp);
normaliz();
formare(1,1,maxx);
solve();
afisare();
return 0;
}