#include <stdio.h>
#include <algorithm>
using namespace std;
#define nmax 100005
#define lmax 11*nmax
int arb[4*nmax], SOL[nmax], poz[nmax], V[nmax], ord[nmax], pz[nmax];
int N, pozitie, maxim;
char sir[lmax];
void citire ()
{
int i = 0, ind = 0, h, x;
scanf("%d", &N);
//parasare
fgets(sir,lmax,stdin);//sir vid
fgets(sir,lmax,stdin);
back:
x = 0;
for( ;sir[ind] >= '0' && sir[ind] <= '9'; ind++)
x=x*10+(sir[ind]-'0');
V[++i] = x; ord[i] = x; ind++;
if(i != N) goto back;
sort(ord+1, ord+N+1);
h = 1;
for (i = 2; i <= N; ++i)
if (ord[i] != ord[h])
ord[++h] = ord[i];
for (i = 1; i <= N; ++i)
pz[i] = lower_bound(ord+1, ord+h+1, V[i])-ord;
}
void afisare (int x)
{
if ( x ) afisare(poz[x]);
else return;
printf("%d ", V[x]);
}
void update(int ind, int st, int dr, int indx, int x)
{
if (st == dr) { arb[ind] = x; return; }
int mij = (st+dr) / 2;
if (indx <= mij) update(2*ind, st, mij, indx, x);
else update(2*ind+1, mij+1, dr, indx, x);
if (SOL[arb[2*ind]] > SOL[arb[2*ind+1]]) arb[ind] = arb[2*ind];
else arb[ind] = arb[2*ind+1];
}
void query(int ind, int st, int dr, int a, int b)
{
if (a <= st && dr <= b)
{
if (SOL[arb[ind]] > maxim) { maxim = SOL[arb[ind]]; pozitie = arb[ind]; }
return ;
}
int mij = (st+dr) / 2;
if (a <= mij) query(2*ind, st, mij, a, b);
if (mij < b) query(2*ind+1, mij+1, dr, a, b);
}
void solve ()
{
int i, ind, rez = 0;
SOL[1] = 1;
update(1, 1, N, pz[1], 1);
for (i = 2; i <= N; ++i)
{
maxim = 0; pozitie = 0;
if (pz[i] == 1) { maxim = 0; pozitie = 0; }
else query(1, 1, N, 1, pz[i]-1);
SOL[i] = maxim + 1; poz[i] = pozitie;
if (SOL[i] > rez) { rez = SOL[i]; ind = i; }
update(1, 1, N, pz[i], i);
}
printf("%d\n", SOL[ind]);
afisare (ind);
}
int main ()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
citire ();
solve ();
return 0;
}