#include <bits/stdc++.h>
using namespace std;
int v[100004],i,n,lmax,max1,a[100004],dp[100004], aint[400004];
struct andreea
{
int valoare,pozitie;
}vv[100004];
bool cmp(andreea a, andreea b)
{
if(a.valoare<b.valoare)return 1;
return 0;
}
void update(int nod, int st, int dr, int val, int poz)
{
int mij;
if(st==dr)
{
aint[nod]=max(val,aint[nod]);
return;
}
mij=(st+dr)/2;
if(poz<=mij)update(nod*2,st,mij,val,poz);
else update(nod*2+1,mij+1,dr,val,poz);
aint[nod]=max(aint[nod*2], aint[nod*2+1]);
}
void query(int nod, int st, int dr, int x, int y)
{
int mij;
if(x<=st&&y>=dr)
{
max1=max(max1,aint[nod]);
return;
}
mij=(st+dr)/2;
if(x<=mij)query(nod*2,st,mij,x,y);
if(y>mij)query(nod*2+1,mij+1,dr,x,y);
}
int main()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&v[i]);
vv[i].valoare=v[i];
vv[i].pozitie=i;
}
sort(vv+1,vv+n+1,cmp);
for(i=1;i<=n;i++)
{
if(vv[i].valoare!=vv[i-1].valoare)a[vv[i].pozitie]=a[vv[i-1].pozitie]+1;
else a[vv[i].pozitie]=a[vv[i-1].pozitie];
}
for(i=1;i<=n;i++)
{
max1=0;
if(a[i]>1)
{
query(1,1,n,1,a[i]-1);
dp[i]=max1+1;
}
else dp[i]=1;
update(1,1,n,dp[i],a[i]);
}
for(i=1;i<=n;i++)
{
if(lmax<dp[i])lmax=dp[i];
}
printf("%d\n",lmax);
return 0;
}