#include <bits/stdc++.h>
using namespace std;
using ll = long long;
inline int RI() {
  int ret = 0, flag = 1, ip = getchar();
  for (; ip < 48 || ip > 57; ip = getchar()) {
    if (ip == 45) {
      flag = -1;
      ip = getchar();
      break;
    }
  }
  for (; ip > 47 && ip < 58; ip = getchar()) ret = ret * 10 + ip - 48;
  return flag * ret;
}
const int mx = 1e5 + 10;
int n;
int tree[mx * 3], ar[mx];
void update(int node, int b, int e, int i, int val) {
  if (i > e || i < b) {
    return;
  }
  if (i >= e && i <= b) {
    tree[node] = max(tree[node], val);
    return;
  }
  int left = node << 1;
  int right = left | 1;
  int mid = (b + e) >> 1;
  update(left, b, mid, i, val);
  update(right, mid + 1, e, i, val);
  tree[node] = max(tree[left], tree[right]);
}
int query(int node, int b, int e, int i, int j) {
  if (i > e || j < b) {
    return 0;
  }
  if (b >= i && e <= j) {
    return tree[node];
  }
  int left = node << 1;
  int right = left | 1;
  int mid = (b + e) >> 1;
  int part1 = query(left, b, mid, i, j);
  int part2 = query(right, mid + 1, e, i, j);
  return max(part1, part2);
}
int main() {
  int h, ans, x;
  while (cin >> n) {
    ans = 0;
    memset(tree, 0, sizeof tree);
    for (int i = 0; i < n; i++) {
      cin >> x;
      h = query(1, 0, n, 0, x - 1) + 1;
      update(1, 0, n, x, h);
      ans = max(ans, h);
    }
    cout << ans << "\n";
  }
  return 0;
}
