#include <iostream>
#include <fstream>
#define nmax 100006
#define dim 8192
using namespace std;
char ax[dim];
int pz;
inline void cit (int &x)
{
x = 0;
while (ax[pz] < '0' || ax[pz] > '9')
if (++pz == dim)
fread (ax, 1, dim, stdin), pz = 0;
while (ax[pz] >= '0' && ax[pz] <= '9')
{
x = x * 10 + ax[pz] - '0';
if (++pz == dim)
fread (ax, 1, dim, stdin), pz = 0;
}
}
const char iname[] = "scmax.in";
const char oname[] = "scmax.out";
//ifstream fin(iname);
ofstream fout(oname);
int N, i, j, k, dp[nmax], pred[nmax], rez, poz[nmax * 3], rasp[nmax * 3], maxim, max2, A[nmax], B[nmax];
int position, max3, val;
struct nod { int v, poz;};nod aux[nmax];
struct cmp
{
bool operator()(const nod &a, const nod &b)const
{
if(a.v < b.v)
return 1;
return 0;
}
};
inline void update(int nod, int left, int right, int valoare, int pozitie)
{
if(left == right)
{
rasp[nod] = dp[pozitie];
poz[nod] = pozitie;
return;
}
int middle = (left + right) >> 1;
int L = nod << 1;
int R = L | 1;
if(valoare <= middle)
update(L, left, middle, valoare, pozitie);
else
update(R, middle + 1, right, valoare, pozitie);
rasp[nod] = max(rasp[R], rasp[L]);
if(rasp[R] == rasp[nod])
poz[nod] = poz[R];
else
poz[nod] = poz[L];
}
inline void query(int nod, int left, int right, int lm, int rm)
{
if(lm <= left && right <= rm)
{
if(rasp[nod] >= max2)
{
max2 = rasp[nod];
max3 = poz[nod];
}
return;
}
int middle = (left + right) >> 1;
int L = nod << 1;
int R = L | 1;
if(lm <= middle)
query(L, left, middle, lm, rm);
if(middle < rm)
query(R, middle +1 , right, lm, rm);
}
int main()
{
freopen ("scmax.in", "r", stdin);
cit (N);
//fin >> N;
for(i = 1; i <= N; i ++)
{
cit (A[i]);
//fin >> A[i];
aux[i].v = A[i];
aux[i].poz = i;
}
dp[1] = 1;
pred[1] = 1;
j = 1;
sort(aux + 1, aux + N + 1, cmp());
B[aux[1].poz] = ++j;
for(i = 2; i <= N; i ++)
{
if(aux[i].v != aux[i - 1].v)
B[aux[i].poz] = ++j;
else
B[aux[i].poz] = j;
}
maxim = N;
update(1, 1, maxim, B[1], 1);
for(i = 2; i <= N; i ++)
{
max2 = 0;
query(1, 1, maxim, 1, B[i] - 1);
dp[i] = max(dp[i], dp[max3] + 1);
update(1, 1, maxim, B[i], i);
}
max2 = 0;
for(i = 1; i <= N; i ++)
if(dp[i] > max2)
max2 = dp[i];
fout << max2;
return 0;
}