#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
set<int> h;
int a[N];
int n;
int main()
{
cin >> n;
for (int i = 0;i < n;i ++) cin >> a[i];
//模拟:
// 8 4 2 1
// 5 3
// 9
// 6
//每次将当前要进去的列车与平行铁轨上的列车比较,如果有比a[i]大的,则把a[i]排在它后面
//每次都暴力搜的话会超时,可以发现每次搜索时最后有用的都是每一条铁轨的最后一个,
//所以只需维护每条轨道的最后一个即可,用set维护,每次查询set里是否有比a[i]大的,
//如果有,则说明a[i]可以排在它后面,插入a[i],删去它,这时该条铁轨最后一个元素就变成了a[i]
//如果没有,则说明需要新开一条铁轨,插入a[i]
//最后set的大小就是用于调度的铁轨数
for (int i = 0;i < n;i ++)
{
auto t = h.upper_bound(a[i]);
//lower_bound(x) 返回的是第一个>= x的数,如果没有则返回 h.end();
//upper_bound(x) 返回的是第一个 > x的数,如果没有则返回 h.end();
if (t == h.end()) h.insert(a[i]);
else
{
h.erase(t);
h.insert(a[i]);
}
}
cout << h.size();
return 0;
}