#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
const int NMAX = 100001;
int n, aint[4 * NMAX], v[NMAX], d[NMAX], ma;
vector<int> b;
void build(int nod, int l, int r) {
if (l == r) {
aint[nod] = v[l];
return;
}
int mj = (l + r) / 2;
build(nod * 2, l, mj);
build(nod * 2 + 1, mj + 1, r);
aint[nod] = max(aint[nod * 2], aint[nod * 2 + 1]);
}
void update(int nod, int l, int r, int poz, int val) {
if (l == r) {
aint[nod] = val;
return;
}
int mj = (l + r) / 2;
if (poz > mj)
update(nod * 2 + 1, mj + 1, r, poz, val);
else
update(nod * 2, l, mj, poz, val);
aint[nod] = max(aint[nod * 2], aint[nod * 2 + 1]);
}
int query(int nod, int l, int r, int x, int y) {
if (l >= x && r <= y) {
return aint[nod];
}
int mj = (l + r) / 2;
int s1 = 0, s2 = 0;
if (x <= mj)
s1 = query(nod * 2, l, mj, x, y);
if (y > mj)
s2 = query(nod * 2 + 1, mj + 1, r, x, y);
return max(s1, s2);///max(aint[nod], max(s1, s2));
}
int main() {
fin >> n;
for (int i = 1; i <= n; ++i) {
fin >> v[i];
b.push_back(v[i]);
}
build(1, 1, n);
sort(b.begin(), b.end());
b.erase(unique(b.begin(), b.end()), b.end());
for (int i = 1; i <= n; ++i)
v[i] = lower_bound(b.begin(), b.end(), v[i]) - b.begin() + 1;
d[1] = 1;
update(1, 1, n, v[1], d[1]);
for (int i = 2; i <= n; ++i) {
if (v[i] - 1 >= 1)
ma = query(1, 1, n, 1, v[i] - 1);
d[i] = ma + 1;
update(1, 1, n, v[i], d[i]);
}
int ma = 0;
for (int i = 1; i <= n; ++i)
ma = max(ma, d[i]);
fout << ma;
}