#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:200000000")
using namespace std;
template <typename T>
inline T Abs(T x) {
  return (x >= 0) ? x : -x;
}
template <typename T>
inline T sqr(T x) {
  return x * x;
}
template <typename T>
inline string toStr(T x) {
  stringstream st;
  st << x;
  string s;
  st >> s;
  return s;
}
template <typename T>
inline int bit(T mask, int b) {
  return (b >= 0 && (mask & (T(1) << b)) != 0) ? 1 : 0;
}
inline int nextInt() {
  int x;
  if (scanf("%d", &x) != 1) throw;
  return x;
}
inline long long nextInt64() {
  long long x;
  if (scanf("%lld", &x) != 1) throw;
  return x;
}
inline double nextDouble() {
  double x;
  if (scanf("%lf", &x) != 1) throw;
  return x;
}
const int INF = (int)1E9;
const long long INF64 = (long long)1E18;
const long double EPS = 1E-9;
const long double PI = 3.1415926535897932384626433832795;
const int MAXN = 100100;
int tree[MAXN], n;
int getMax(int x) {
  int ans = 0;
  for (; x >= 0; x = (x & (x + 1)) - 1) ans = max(ans, tree[x]);
  return ans;
}
void update(int x, int value) {
  for (; x < n; x = (x | (x + 1))) tree[x] = max(value, tree[x]);
}
int main() {
  n = nextInt();
  int ans = 0;
  for (int i = 0; i < (int)(n); i++) {
    int x = nextInt();
    int value = getMax(x - 1) + 1;
    ans = max(ans, value);
    update(x, value);
  }
  cout << ans << endl;
  return 0;
}
