#include <bits/stdc++.h>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
struct Wow{int val,pos;};
int n;
int a[100001];
Wow aux[100001];
int arbore[100001<<2];
int queryMax(int,int,int,int,int);
void update(int,int,int,int,int);
bool cmp(Wow a,Wow b)
{
if(b.val==a.val)
return a.pos>b.pos;
return a.val<b.val;
}
int main()
{
fin>>n;
for(int i=1;i<=n;i+=1)
{
fin>>a[i];
aux[i]={a[i],i};
}
sort(aux+1,aux+n+1,cmp);
for(int i=1;i<=n;i+=1)
update(1,1,n,aux[i].pos,queryMax(1,1,n,1,aux[i].pos-1)+1);
fout<<arbore[1];
return 0;
}
int queryMax(int n, int low, int high, int x, int y)
{
int m=(low+high)>>1,leftNode=n<<1,rightNode=leftNode|1;
if(x<=low&&high<=y) return arbore[n];
if(x > high || y < low) return 0;
if(y<=m) return queryMax(leftNode,low,m,x,y);
else if(x>m) return queryMax(rightNode,m+1,high,x,y);
else return max(queryMax(leftNode,low,m,x,y),queryMax(rightNode,m+1,high,x,y));
}
void update(int n, int low, int high, int pos, int val)
{
int m=(low+high)>>1,leftNode=n<<1,rightNode=leftNode|1;
if(low==high)
{
arbore[n]=val;
return;
}
if(pos<=m) update(leftNode,low,m,pos,val);
else update(rightNode,m+1,high,pos,val);
arbore[n]=max(arbore[leftNode],arbore[rightNode]);
}