#include<fstream>
#include<algorithm>
#include<iostream>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
const int NMAX = 100000;
struct numar{
int vl;
int pz;
int k;
};
numar v[NMAX + 5],sortat[NMAX + 5];
int n,maxim,dp[NMAX + 5],pozitie,pr[NMAX + 5],prim,el[NMAX + 5];
struct arbore{
int lgmax;
int valoare;
};
arbore arb[3*NMAX + 5];
void read()
{
in>>n;
for(int i = 1 ; i <= n ; i++)
{
in>>sortat[i].vl;
sortat[i].pz = i;
}
}
bool cmp(numar a,numar b)
{
return a.vl < b.vl;
}
void normalizare()
{
sort(sortat+1,sortat+n+1,cmp);
int h = 0;
for(int i = 1 ; i <= n ; i++)
{
if(sortat[i].vl != sortat[i-1].vl){
++h;
el[h] = sortat[i].vl;
}
v[sortat[i].pz].k = h;
v[sortat[i].pz].vl = sortat[i].vl;
}
}
void update(int nod,int left,int right,int poz,int val)
{
if(left == right){
arb[nod].valoare = poz;
arb[nod].lgmax = val;
return;
}
int mid = (left + right)/2;
if(poz <= mid)
update(2*nod,left,mid,poz,val);
else
update(2*nod+1,mid + 1,right,poz,val);
if(arb[2*nod+1].lgmax > arb[2*nod].lgmax){
arb[nod].lgmax = arb[2*nod + 1].lgmax;
arb[nod].valoare = arb[2*nod + 1].valoare;
}
else{
arb[nod].lgmax = arb[2*nod].lgmax;
arb[nod].valoare = arb[2*nod].valoare;
}
}
void query(int nod,int left,int right,int st,int fn)
{
if(st <= left && right <= fn){
if(maxim < arb[nod].lgmax){
maxim = arb[nod].lgmax;
pozitie = arb[nod].valoare;
}
return;
}
int mid = (left + right)>>1;
if(st <= mid)
query(2*nod,left,mid,st,fn);
if(fn > mid)
query(2*nod+1,mid + 1,right,st,fn);
}
int main()
{
int solmax = 1;
pr[n] = -1;
read();
normalizare();
prim = v[n].k;
dp[n] = 1;
update(1,1,n,v[n].k,1);
for(int i = n-1 ; i >= 1 ; i--){
maxim = 0;
pozitie = -1;
query(1,1,n,v[i].k+1,n+1);
dp[i] = maxim + 1;
pr[v[i].k] = pozitie;
update(1,1,n,v[i].k,dp[i]);
if(solmax < maxim + 1){
solmax = maxim + 1;
prim = v[i].k;
}
}
out<<solmax<<"\n";
while(prim != -1){
out<<el[prim]<<" ";
prim = pr[prim];
}
return 0;
}