#include <bits/stdc++.h>
using namespace std;
int n,m,hmax;
int v[100003];
int aux[100003];
struct segtree{
vector<int>t;
void init(int lg){
t.resize(3*lg);
fill(t.begin(),t.end(),0);
}
int query(int nod,int st,int dr,int x,int y){
if(dr<x || st>y)return 0;
if(x<=st && dr<=y)return t[nod];
int mid=(st+dr)/2;
int left=query(2*nod,st,mid,x,y);
int right=query(2*nod+1,mid+1,dr,x,y);
return max(left,right);
}
void update(int nod,int st,int dr,int poz,int val){
if(st==dr){
t[nod]=val;
return;
}
int mid=(st+dr)/2;
if(poz<=mid)update(2*nod,st,mid,poz,val);
if(poz>mid)update(2*nod+1,mid+1,dr,poz,val);
t[nod]=max(t[nod*2],t[nod*2+1]);
}
}sg;
int main()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&v[i]);
aux[i]=v[i];
}
vector<int>dif;
sort(aux+1,aux+n+1);
dif.push_back(aux[1]);
for(int i=2;i<=n;i++){
if(aux[i]!=aux[i-1]){
dif.push_back(aux[i]);
}
}
m=(int)dif.size();
sg.init(m);
for(int i=1;i<=n;i++){
v[i]=lower_bound(dif.begin(),dif.end(),v[i])-dif.begin()+1;
}
for(int i=1;i<=n;i++){
int nr=sg.query(1,1,m,1,v[i]-1);
sg.update(1,1,m,v[i],nr+1);
hmax=max(hmax,nr+1);
//printf("%d\n",nr+1);
}
printf("%d\n",hmax);
return 0;
}