#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
const int dim = 100005;
struct elem {
int val;
int pos;
} v[dim];
int arb[4 * dim];
bool cmp(struct elem e1, struct elem e2) {
if (e1.val == e2.val) {
return e1.pos > e2.pos;
}
return e1.val < e2.val;
}
void query(int nod, int st, int dr, int a, int b, int &maxim) {
if (a <= st && dr <= b) {
maxim = max(maxim, arb[nod]);
return;
}
int m = (st + dr) / 2;
if (a <= m) {
query(2 * nod, st, m, a, b, maxim);
}
if (b >= m + 1) {
query(2 * nod + 1, m + 1, dr, a, b, maxim);
}
}
void update(int nod, int st, int dr, int pos, int val) {
if (st == dr) {
arb[nod] = val;
return;
}
int m = (st + dr) / 2;
if (pos <= m) {
update(2 * nod, st, m, pos, val);
} else {
update(2 * nod + 1, m + 1, dr, pos, val);
}
arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}
int main()
{
int n, i, maxim;
in >> n;
for (i = 1; i <= n; i++) {
in >> v[i].val;
v[i].pos = i;
}
sort(v + 1, v + n + 1, cmp);
for (i = 1; i <= n; i++) {
maxim = 0;
// pred[i] = -1;
query(1, 1, n, 1, v[i].pos, maxim); // determina maximul in intervalul [1, v[i].pos]
update(1, 1, n, v[i].pos, maxim + 1);
}
// for (i = 1; i <= 2 * n - 1; i++) {
// cout << arb[i] << " ";
// }
// cout << "\n";
out << arb[1] << "\n";
return 0;
}