#include <iostream>
#include <fstream>
using namespace std;
typedef struct
{
long L;
long V;
}
ArbInt;
ArbInt AI[200005];
long N, V[100005], Best[100005], VBest[100005];
void Read ()
{
ifstream fin ("scmax.in");
long i;
fin >> N;
for (i=1; i<=N; i++)
{
fin >> V[i];
}
fin.close ();
}
void Type ()
{
long i, LMax, VMax=2000000002, Subsir[100005], NSubsir=0;
ofstream fout ("scmax.out");
LMax=AI[1].L;
fout << LMax << "\n";
for (i=N; i>0; i--)
{
if (LMax==0)
{
break;
}
if ((Best[i]==LMax)&&(VBest[i]<VMax))
{
VMax=VBest[i];
LMax--;
Subsir[NSubsir++]=VMax;
}
}
for (i=NSubsir-1; i>=0; i--)
{
fout << Subsir[i] << " ";
}
fout.close ();
}
long Max (long a, long b)
{
if (a>b)
{
return a;
}
return b;
}
void Update (long Left, long Right, long X, long LX, long K, long VX)
{
long Middle;
Middle=(Left+Right)/2;
if (Left==Right)
{
AI[K].L=LX;
AI[K].V=VX;
Best[Middle]=LX;
VBest[Middle]=VX;
return;
}
if (X<=Middle)
{
Update (Left, Middle, X, LX, 2*K, VX);
}
else
{
Update (Middle+1, Right, X, LX, 2*K+1, VX);
}
if (AI[2*K].L>AI[2*K+1].L)
{
AI[K]=AI[2*K];
}
else
{
AI[K]=AI[2*K+1];
}
}
long Query (long Left, long Right, long XLeft, long XRight, long K, long VX)
{
long Middle;
Middle=(Left+Right)/2;
if ((Left==Right)&&(AI[K].V>=VX))
{
return 0;
}
if ((Left==XLeft)&&(Right==XRight))
{
if (AI[K].V<VX)
{
return AI[K].L;
}
else
{
return Max (Query (Left, Middle, XLeft, Middle, 2*K, VX), Query (Middle+1, Right, Middle+1, XRight, 2*K+1, VX));
}
}
if (XRight<=Middle)
{
return Query (Left, Middle, XLeft, XRight, 2*K, VX);
}
if (XLeft>Middle)
{
return Query (Middle+1, Right, XLeft, XRight, 2*K+1, VX);
}
return Max (Query (Left, Middle, XLeft, Middle, 2*K, VX), Query (Middle+1, Right, Middle+1, XRight, 2*K+1, VX));
}
int main()
{
long i, L;
Read ();
for (i=1; i<=N; i++)
{
L=Query (1, N, 1, i, 1, V[i]);
Update (1, N, i, L+1, 1, V[i]);
}
Type ();
return 0;
}