#include <bits/stdc++.h>
using namespace std;
const int inf = 999999999;
int n;
template <typename T>
struct SegTree_t {
  int n;
  vector<int> tree, A;
  SegTree_t(int _n) : n(_n), tree(4 * n, 0), A(4 * n, 0) {}
  T operation(const T &a, const T &b) { return max(a, b); }
  T query(int node, int l, int r, int a, int b) {
    if (a > r || b < l) return 0;
    if (l >= a && r <= b) return tree[node];
    return operation(query(node << 1, l, (l + r) / 2, a, b),
                     query((node << 1) + 1, (l + r) / 2 + 1, r, a, b));
  }
  T query(int a, int b) { return query(1, 0, n - 1, a, b); }
  void update(int node, int l, int r, int idx, int val) {
    if (l == r) {
      A[idx] = val;
      tree[node] = val;
    } else {
      int mid = (l + r) / 2;
      if (l <= idx and idx <= mid)
        update(node << 1, l, mid, idx, val);
      else
        update((node << 1) + 1, mid + 1, r, idx, val);
      tree[node] = operation(tree[(node << 1)], tree[(node << 1) + 1]);
    }
  }
  void update(int idx, int val) { return update(1, 0, n - 1, idx, val); }
};
int main() {
  scanf("%d", &n);
  int ret = 0;
  SegTree_t<int> segtree(n);
  for (int i = 0; i < n; ++i) {
    int x;
    scanf("%d", &x);
    int y = segtree.query(0, x - 1);
    ret = max(ret, y + 1);
    segtree.update(x, y + 1);
  }
  printf("%d\n", ret);
  return 0;
}
