#include <stdio.h>
#include <algorithm>
#include <string.h>
#define N 1<<17
#define P 1<<18
using namespace std;
int n,v[N],nr[N],sortat[N],r;
int ant[N],sol[N],x,poz;
int arb[P],best[N],inc,sf,maxim,rez;
void read()
{
scanf("%d",&n);
int i;
for (i=1; i<=n; i++)
scanf("%d",&v[i]);
}
int cbin(int x)
{
int i,step;
for (step=1; step<=r; step<<=1);
for (i=0; step; step>>=1)
if (i+step<=r && sortat[i+step]<=x)
i+=step;
return i;
}
void renumerotare()
{
memcpy(nr,v,sizeof(v));
sort(nr+1,nr+n+1);
int i,t;
for (i=1; i<=n; i++)
if (nr[i]!=nr[i-1])
sortat[++r]=nr[i];
for (i=1; i<=n; i++)
{
t=cbin(v[i]);
v[i]=t;
}
}
inline int maximum(int a,int b)
{
if (a>b)
return a;
return b;
}
void update(int nod,int st,int dr)
{
if (st==dr)
{
arb[nod]=maximum(x,arb[nod]);
return;
}
int t=(st+dr)/2;
if (poz<=t)
update(nod*2,st,t);
else
update(nod*2+1,t+1,dr);
arb[nod]=maximum(arb[nod*2],arb[nod*2+1]);
}
void query(int nod,int st,int dr)
{
if (inc<=st && dr<=sf)
{
if (maxim<arb[nod])
maxim=arb[nod];
return;
}
int t=(st+dr)/2;
if (inc<=t)
query(nod*2,st,t);
if (t<sf)
query(nod*2+1,t+1,dr);
}
void solve()
{
int i,j;
for (i=1; i<=n; i++)
{
maxim=0;
inc=1;
sf=v[i]-1;
if (sf)
query(1,1,r);
best[i]=maxim+1;
if (best[i]>rez)
rez=best[i];
x=best[i];
poz=v[i];
update(1,1,r);
}
printf("%d\n",rez);
}
int main()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
read();
renumerotare();
solve();
return 0;
}