#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int ai[500000],val,poz,start,stop,maxim;
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
void update(int nod,int st,int dr)
{
int div;
if(st==dr)
{
ai[nod]=val;
return;
}
div=(st+dr)/2;
if(poz<=div)
update(2*nod+1,st,div);
else
update(2*nod+2,div+1,dr);
ai[nod]=max(ai[2*nod+1],ai[2*nod+2]);
}
void query(int nod,int st,int dr)
{
int div;
if(start<=st && dr<=stop)
{
if(ai[nod]>maxim)
maxim=ai[nod];
}
else
{
div=(st+dr)/2;
if(start<=div)
query(2*nod+1,st,div);
if(stop>div)
query(2*nod+2,div+1,dr);
}
}
int main()
{
int n,v[100000],v1[100000],best[100000],i;
FILE *f=fopen("scmax.in","r");
for(i=0;i<500000;i++)
ai[0]=0;
for(i=0;i<100000;i++)
best[i]=0;
fscanf(f,"%i",&n);
for(i=0;i<n;i++)
{
fscanf(f,"%i",v+i);
v1[i]=v[i];
}
fclose(f);
//Normalizare v
sort(v1,v1+n);
for(i=0;i<n;i++)
v[i]=lower_bound(v1,v1+n,v[i])-v1;
poz=v[0];
val=1;
update(0,0,n-1);
for(i=1;i<n;i++)
{
start=0;
stop=v[i]-1;
if(stop>=start)
{
maxim=0;
query(0,0,n-1);
if(1+maxim>best[v[i]])
{
best[v[i]]=1+maxim;
val=best[v[i]];
poz=v[i];
update(0,0,n-1);
}
}
if(best[v[i]]==0)
{
poz=v[i];
val=1;
update(0,0,n-1);
best[v[i]]=1;
}
}
f=fopen("scmax.out","w");
fprintf(f,"%i\n",ai[0]);
fclose(f);
return 0;
}