#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;
int v[NMAX],a[NMAX*3+200],n,len[NMAX];
pair <int , int >p[NMAX];
FILE *fin = fopen("in.in","r");
FILE *fout= fopen("out.out","w");
void update(int nod,int st,int dr,int poz,int val)
{
if(st == dr)
a[nod] = val;
else
{
int d = (st + dr)/2;
if(poz <= d)
update(nod*2, st, d, poz, val);
else
update(nod*2+1, d+1, dr, poz, val);
a[nod] = max(a[nod*2],a[nod*2+1]);
}
}
void query(int nod,int st,int dr,int x,int y ,int &rez)
{
if( st >= x && dr <= y)
rez = max(rez,a[nod]);
else
{
int d = (st+dr)/2;
if(d >=x )
query(nod*2, st, d, x, y, rez);
if(d < y )
query(nod*2+1, d+1, dr, x, y, rez);
}
}
bool comp(pair <int ,int > p1 , pair <int , int > p2)
{
if(p1.first == p2.first)
return p1.second > p2.second; // strict crecator/ca sa nu se repete nr => p.second mai mare trb sa fie in fata
return p1.first < p2.first;
}
void citire()
{
fscanf(fin,"%d",&n);
for(int i=1;i<=n;++i) // ordonez vectorul dupa valoare si index ** vezi comp();
{
fscanf(fin,"%d",&v[i]);
p[i].first = v[i];
p[i].second = i;
}
sort(p+1,p+n+1,comp);
for(int i=1;i<=n;++i)
{
int maxx = 0;
query(1,1,n,1,p[i].second,maxx); // cate nr mai mici decat nr la indexul p[i].second
update(1,1,n,p[i].second,maxx+1); //update la poz p[i].second cu maxx de sus + 1; un fel de lmax[i] = 1 + Lmax
maxx = 0;
query(1, 1, n, 1, p[i].second, maxx); //cat de lunga e cea mai lunga subsecv crescatoare de la 1 la p[i].second
len[p[i].second] = maxx;
}
}
void sol()
{
list <int> solutie;
int Lmax = a[1],fost_i,i=n;
fprintf(fout,"%d\n",Lmax);
while(i && len[i] != Lmax)i--;
solutie.push_front(v[i]);
Lmax--;
fost_i = i;
while(i && Lmax)
{
if(len[i] == Lmax && v[i] < v[fost_i])
{
Lmax--;
fost_i = i;
solutie.push_front(v[i]);
}
i--;
}
for(int i : solutie)fprintf(fout,"%d ",i);
}
int main()
{
citire();
sol();
}