#include <bits/stdc++.h>
// solved by bekagg
#define int long long
#define ent '\n'
#define pb push_back
#define all(x) x.begin(),x.end()
#define PRaim_bek_abi ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;
const int N = 3e5+5;
const int MOD = 1e9+7;
struct tree{
int lv , rv , cnt;
};
int n , d , dp[N] , timer , a[N];
tree t[50 * N];
map<int , multiset<int>>st;
void update(int v , int tl , int tr , int i , int x , bool tp){
if (tl == tr){
if (tp) st[i].insert(x);
else st[i].erase(st[i].find(x));
if (st[i].size()) t[v].cnt = *st[i].rbegin();
else t[v].cnt = 0;
return;
}
int tm = (tl + tr) / 2;
if (i <= tm){
if (t[v].lv == 0) t[v].lv = ++timer;
update(t[v].lv , tl , tm , i , x , tp);
}
else {
if (t[v].rv == 0) t[v].rv = ++timer;
update(t[v].rv , tm + 1 , tr , i , x , tp);
}
t[v].cnt = max(t[t[v].lv].cnt , t[t[v].rv].cnt);
}
int get(int v , int tl , int tr , int l , int r){
if (v == 0) return 0;
if (tr < l or r < tl) return 0;
if (l <= tl and tr <= r) return t[v].cnt;
int tm = (tl + tr) / 2;
return max(get(t[v].lv , tl , tm , l , r) , get(t[v].rv , tm + 1 , tr , l , r));
}
void arkanefury228(){
cin >> n >> d;
for (int i = 1; i <= n; i++){
cin >> a[i];
}
++timer;
for (int i = 1; i <= n; i++){
dp[i] = get(1 , 0 , 1000000000 , 0 , a[i] - 1) + 1;
update(1 , 0 , 1000000000 , a[i] , dp[i] , 1);
}
cout << dp[n];
}
signed main(){
PRaim_bek_abi
int t=1;
//cin>>t;
for (int respagold = 1; respagold <= t; respagold++) arkanefury228();
}