#include <bits/stdc++.h>
using namespace std;
int a[100005], tree[100005 * 4];
inline int query(int at, int l, int r, int l1, int r1) {
  if (l == l1 && r == r1) return tree[at];
  int k, mid;
  k = at * 2 + 1;
  mid = (l + r) / 2;
  int ans, a1, a2;
  if (r1 <= mid) ans = query(k, l, mid, l1, r1);
  if (l1 > mid) ans = query(k + 1, mid + 1, r, l1, r1);
  if (l1 <= mid && r1 > mid) {
    a1 = query(k, l, mid, l1, mid);
    a2 = query(k + 1, mid + 1, r, mid + 1, r1);
    ans = max(a1, a2);
  }
  return ans;
}
inline void update(int at, int l, int r, int id, int val) {
  if (l == id && r == id) {
    tree[at] = max(tree[at], val);
    return;
  }
  int k, mid;
  k = at * 2 + 1;
  mid = (l + r) / 2;
  if (id <= mid)
    update(k, l, mid, id, val);
  else
    update(k + 1, mid + 1, r, id, val);
  tree[at] = max(tree[k], tree[k + 1]);
  return;
}
int main() {
  int ans, now, valu, i, n;
  cin >> n;
  for (i = 0; i < n; i++) cin >> a[i];
  memset(tree, 0, sizeof(tree));
  ans = 0;
  for (i = 0; i < n; i++) {
    now = a[i];
    valu = query(0, 0, n, 0, now) + 1;
    update(0, 0, n, now, valu);
    ans = max(ans, valu);
  }
  cout << ans << endl;
  return 0;
}
