#include <stdio.h>
#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < n; i++)
#define repa(i, l, r) for (int i = l; i < r; i++)
#define repd(i, r, l) for (int i = r; i > l; i--)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
ifstream fin ("scmax.in");
ofstream fout ("scmax.out");
const int Nmax = 100555;
int orig[Nmax]; // original numbers
int a[Nmax]; // Normalized Numbers: 0 <= a[i] <= count distinct(orig[i])
int v[Nmax]; // sorted, unique
int Arb[3*Nmax];
void update(int nod, int l, int r, int pos, int val);
int query(int nod, int l, int r, int a, int b);
int main(void) {
int N;
fin >> N;
rep(i, N) {
fin >> orig[i];
a[i] = v[i] = orig[i];
}
sort(v, v+N);
int pos = unique(v, v+N) - v;
rep(i, N) {
a[i] = lower_bound(v, v+pos, orig[i]) - v; // position of orig[i] in the new order.
}
// rep(i, N) {
// cout << a[i] << (i == N-1 ? '\n' : ' ');
// }
for(int i = 0; i < N; i++) {
int best = 0;
if (a[i] > 0) {
best = query(1, 0, N-1, 0, a[i] - 1);
}
update(1, 0, N-1, a[i], best + 1);
}
int count = query(1, 0, N-1, 0, pos);
fout << count << endl;
return 0;
}
void update(int nod, int l, int r, int pos, int val) {
if (l == r) {
Arb[nod] = val;
return;
}
int mid = l + (r - l)/2;
if (pos <= mid) {
update(2*nod, l, mid, pos, val);
} else {
update(2*nod+1, mid+1, r, pos, val);
}
Arb[nod] = max(Arb[2*nod], Arb[2*nod+1]);
}
int query(int nod, int l, int r, int a, int b) {
if (a <= l && r <= b) {
return Arb[nod];
}
int mid = l + (r - l)/2;
if (b < mid+1) {
return query(2*nod, l, mid, a, b);
} else if (a > mid) {
return query(2*nod+1, mid+1, r, a, b);
} else {
return max(
query(2*nod, l, mid, a, b),
query(2*nod+1, mid+1, r, a, b)
);
}
}