#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int a[maxn];
int g[maxn];
int d[maxn];
int n;
struct SegTree {
  int maxv[maxn * 3];
  int ql, qr;
  int query(int o, int L, int R) {
    if (ql > qr) return 0;
    int M = L + (R - L) / 2, ans = 0;
    if (ql <= L && R <= qr) return maxv[o];
    if (ql <= M) ans = max(ans, query(o * 2, L, M));
    if (M < qr) ans = max(ans, query(o * 2 + 1, M + 1, R));
    return ans;
  }
  int p, v;
  void update(int o, int L, int R) {
    int M = L + (R - L) / 2;
    if (L == R)
      maxv[o] = v;
    else {
      if (p <= M)
        update(o * 2, L, M);
      else
        update(o * 2 + 1, M + 1, R);
      maxv[o] = max(maxv[o * 2], maxv[o * 2 + 1]);
    }
  }
} tree;
struct FT {
  int C[maxn];
  inline int lowbit(int x) { return x & -x; }
  int mmax(int x) {
    int ret = 0;
    while (x > 0) {
      ret = max(ret, C[x]);
      x -= lowbit(x);
    }
    return ret;
  }
  void add(int x, int d) {
    while (x <= n) {
      C[x] = max(C[x], d);
      x += lowbit(x);
    }
  }
  void init() { memset(C, 0, sizeof(C)); }
} ft;
int main(int argc, char *argv[]) {
  cin >> n;
  for (int i = 1; i <= n; i++) cin >> a[i];
  ft.init();
  for (int i = 1; i <= n; i++) {
    d[i] = ft.mmax(a[i] - 1) + 1;
    ft.add(a[i], d[i]);
  }
  int ans = 1;
  for (int i = 1; i <= n; i++) ans = max(ans, d[i]);
  cout << ans << endl;
  return 0;
}
