#include <fstream>
#include <stack>
#include <iostream>
#include <algorithm>
#include <utility>
using namespace std;
#define dim 100005
#define mp make_pair
#define ff first
#define ss second
struct Tree{int Max,pos;};
stack<int> S;
pair<int,int> v[dim];
int i,pozA[dim],last[dim],d[dim],Pos,val;
Tree Arb[dim*4];
void update(int nod,int l,int r,int P){
if(l==r){
if(val > Arb[nod].Max) Arb[nod].Max=val,Arb[nod].pos=P;
return;
}
int mid=(l+r)/2;
if(Pos<=mid) update(nod*2,l,mid,P);
if(Pos>mid) update(nod*2+1,mid+1,r,P);
if(Arb[nod*2].Max > Arb[nod*2+1].Max){ //alegem fiul cu subsirul cel mai lung
Arb[nod].Max=Arb[nod*2].Max;
Arb[nod].pos=Arb[nod*2].pos;
}
else{
Arb[nod].Max=Arb[nod*2+1].Max;
Arb[nod].pos=Arb[nod*2+1].pos;
}
}
void query(int nod,int l,int r,int a,int b){
if(l>r || a>b) return;
if(a<=l && b>=r){
if(val<Arb[nod].Max){ //daca subsirul care se termina in Arb[nod].pos este mai mare pastram datele noi
val=Arb[nod].Max;
Pos=Arb[nod].pos;
}
return;
}
int mid=(l+r)/2;
if(a<=mid) query(nod*2,l,mid,a,b);
if(b>mid) query(nod*2+1,mid+1,r,a,b);
}
int main(){
ifstream f("scmax.in");
ofstream g("scmax.out");
int x,n,N=0,Best=0,end;
f >> n;
for(i=1;i<=n;i++){
f >> d[i];
v[i]=mp(d[i],i);
}
sort(v+1,v+n+1);
for(i=1;i<=n;i++){
if(v[i].ff!=v[i-1].ff) N++;
pozA[v[i].ss]=N; //pozitia din arbore a elementului de pe pozitia v[i].ss
}
for(i=1;i<=n;i++){
Pos=val=0;
query(1,1,N,1,pozA[i]-1);
last[i]=Pos; //pozitia ultimului element din cel mai mare subsir gasit
val++;
Pos=pozA[i];
if(val>Best){
Best=val; //lungimea celui mai lung subsir si pozitia in care se termina
end=i;
}
update(1,1,N,i);
}
for(;end;end=last[end]){
S.push(d[end]);
}
g << Best <<"\n";
while(!S.empty()){
g << S.top() <<" ";
S.pop();
}
}