#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#define N 1000005
#define F(i, x, y) for (int i = x; i <= y; i++)
#define D(i, x, y) for (int i = x; i >= y; i--)

using namespace std;

int a[N], c[N], f[N], d[N];
int n, m, x, y, ans = 0;

int low(int x) { return x & (-x); }

void change(int x, int v)
{
	while (x < N)
		c[x] = max(c[x], v), x += low(x);
}

int query(int x)
{
	int mx = 0;
	while (x)
		mx = max(mx, c[x]), x -= low(x);
	return mx;
}

int main()
{
	//freopen("data.in", "r", stdin);
	//freopen("data.out", "w", stdout);

	scanf("%d %d\n", &n, &m);
	F(i, 1, n) scanf("%d %d", &x, &y), a[x]++, a[y + 1]--;
	int s = 0;
	F(i, 1, m)
		s += a[i], a[i] = s + 1;
	//F(i, 1, m) printf("%d ", a[i]); printf("\n");

	memset(c, 0, sizeof(c));
	F(i, 1, m)
		f[i] = query(a[i]) + 1, change(a[i], f[i]);

	memset(c, 0, sizeof(c));
	D(i, m, 1)
		d[i] = query(a[i]) + 1, change(a[i], d[i]);

	F(i, 1, m)
		ans = max(ans, f[i] + d[i] - 1);
	printf("%d\n", ans);

	return 0;
}

#pragma GCC optimize("O2,unroll-loops")
#pragma GCC target("avx,avx2,sse,sse2,ssse3")
#include<bits/stdc++.h>
#define all(x) x.begin(), x.end()
using namespace std;
using ll = long long;
const int maxn = 1<<20, mod = 1e9 + 7;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
int n, m, a[maxn], v[maxn];
signed main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> n >> m;
	for(int l, r, i = 0; i < n; i++) {
		cin >> l >> r;
		a[l]++, a[r+1]--;
	}
	for(int i = 1; i <= m; i++) a[i] += a[i-1];
	vector<int> ans;
	for(int i = 1; i <= m; i++) {
		auto it = upper_bound(all(ans), a[i]);
		if(it == ans.end()) ans.push_back(a[i]);
		else *it = a[i];
		v[i] = upper_bound(all(ans), a[i])-ans.begin();
	}
	ans.clear();
	for(int i = m; i; i--) {
		auto it = upper_bound(all(ans), a[i]);
		if(it == ans.end()) ans.push_back(a[i]);
		else *it = a[i];
		v[i] += upper_bound(all(ans), a[i])-ans.begin();
	}
	int res = 0;
	for(int i = 1; i <= m; i++) res = max(res, v[i]-1);
	cout << res << endl;
}

#include <bits/stdc++.h>
using namespace std;

#define ERR(x) cerr<<#x" = "<<x<<endl
typedef long long llint;
const int N = 1e5 + 20;

int cnt[N], n, m;
vector<int> lis;
int t1[N], t2[N];

int main(){
    scanf("%d%d", &n, &m);
    for (int l, r, i = 1; i <= n; i++){
        scanf("%d%d", &l, &r);
        cnt[l]++;
        cnt[r+1]--;
    }
    int cur = 0;
    for (int i = 1; i <= m; i++){
        cur += cnt[i];
        cnt[i] = cur;
    }

    int p, i;
    lis.push_back(cnt[1]);
    t1[1] = 1;
    for (i = 2; i <= m; i++){
        p = upper_bound(lis.begin(), lis.end(), cnt[i]) - lis.begin();
        t1[i] = p + 1;
        if (p == (int)lis.size())
            lis.push_back(cnt[i]);
        else
            lis[p] = min(lis[p], cnt[i]);
    }

    lis.clear();
    lis.push_back(cnt[m]);
    t2[m] = 1;
    for (i = m-1; i > 0; i--){
        p = upper_bound(lis.begin(), lis.end(), cnt[i]) - lis.begin();
        t2[i] = p + 1;
        if (p == (int)lis.size())
            lis.push_back(cnt[i]);
        else
            lis[p] = min(lis[p], cnt[i]);
    }

    int ans = -1;
    for (int i = 1; i <= m; i++)
        ans = max(ans, t1[i] + t2[i] - 1);
    cout << ans << endl;

    return 0;
}

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
int read(){
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c=='-')t=-1;
    do{s=s*10+c-'0';}while(isdigit(c=getchar()));
    return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>0?x:-x;}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=100010;

int n,m,a[maxn],f[maxn],g[maxn],c[maxn];

void modify(int k,int x){for(int i=k;i<=m;i+=lowbit(i))c[i]=max(c[i],x);}//0
int query(int k){int ans=0;for(int i=k;i>=1;i-=lowbit(i))ans=max(ans,c[i]);return ans;}
int main(){
    m=read();n=read();
    for(int i=1;i<=m;i++){
    	int u=read(),v=read();
    	a[u]++;a[v+1]--;
    }
    for(int i=1;i<=n;i++)a[i]+=a[i-1];
    for(int i=1;i<=n;i++)a[i]++;
    for(int i=1;i<=n;i++){
    	f[i]=query(a[i])+1;
    	modify(a[i],f[i]);
    }
    memset(c,0,sizeof(c));
    for(int i=n;i>=1;i--){
    	g[i]=query(a[i])+1;
    	modify(a[i],g[i]);
    }
    int ans=0;
	for(int i=0;i<=n;i++){
		//printf("%d %d %d %d\n",a[i],f[i],g[i],f[i]+g[i]);
		ans=max(ans,f[i]+g[i+1]);
	}
	printf("%d",ans);
    return 0;
}

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100010;

#define lson l,mid,rt<<1
#define rson mid+1,r, rt<<1|1

int t[maxn*4];
int tdp[2][maxn];
int dp[maxn];
void change(int L, int R, int l, int r, int rt) {
    if(L == l && R == r) {
        t[rt]++;
        return ;
    }
    int mid = (l + r) / 2;
    if(R <= mid) change(L, R, lson);
    else if(L > mid) change(L, R, rson);
    else {
        change(L, mid, lson);
        change(mid + 1, R, rson);
    }
}
int query(int L, int R, int l, int r, int rt) {
    int sum = t[rt];
    int mid = (l + r) / 2;
    if(L == l && R == r);
    else if(R <= mid) sum += query(L, R, lson);
    else if(L > mid) sum += query(L, R, rson);
    else {
        sum += query(L, mid, lson);
        sum += query(mid + 1, R, rson);
    }
    return sum;
}
int a[maxn];

int bsearch(int len,int x)
{
    int l=0,r=len-1;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(x>=dp[mid-1]&&x<dp[mid])return mid;
        else if(x<dp[mid-1])r=mid-1;
        else l=mid+1;
    }
    return l;
}

void LIS(int n) {
    memset(dp, 0, sizeof(dp));
    dp[0]=a[0];
    tdp[0][0] = 1;
    int len=1;
    int j;
    for(int i = 1; i < n; i++)
    {
        if(a[i]<dp[0])j=0;
        else if(a[i]>=dp[len-1])j=len++;
        else j=bsearch(len,a[i]);
        dp[j]=a[i];
        tdp[0][i] = len;
    }
    memset(dp, 0, sizeof(dp));
    len = 1;
    dp[0] = a[n - 1];
    tdp[1][0] = 1;
    for(int i = n - 2; i >= 0; i--)
    {
        if(a[i]<dp[0])j=0;
        else if(a[i]>=dp[len-1])j=len++;
        else j=bsearch(len,a[i]);
        dp[j]=a[i];
        tdp[1][i] = len;
    }
}

void solve() {
   int n, m;
   cin >> n >> m;
   memset(t, 0, sizeof(t));
   for(int i = 1, l, r;i <= n;i++) {
        scanf("%d%d", &l, &r);
        change(l, r, 1, maxn, 1);
   }
   for(int i = 1;i <= m;i++) {
        a[i - 1] = query(i, i, 1, maxn, 1);
   }
   memset(tdp, 0, sizeof(tdp));
   memset(dp, 0, sizeof(dp));
   LIS(m);
   int ans = 0;
   for(int i = 0;i < m;i++) {
        ans = max(ans, tdp[0][i] + tdp[1][i] - 1);
   }
   cout << ans << endl;
}

int main() {
    solve();
    int MARKEOF;
    if(scanf("%d", &MARKEOF)) ;
    return 0;
}

#include <bits/stdc++.h>

#define rust(a, b, c, d) sqrt(sqr(a - c) + sqr(b - d))
#define sqr(a) (a)*(a)
#define m_p make_pair
#define fi first
#define se second
#define fast_io ios_base::sync_with_stdio(0);cin.tie(0);
#define endl "\n"
#define pll pair <ll,ll>
#define next stopplz
#define y1 STOPPLZ

typedef long long ll;

const int MAXINT=2147483640;
const ll MAXLL=9223372036854775800LL;
const ll MAXN = 2e6;
const double eps = 1e-9;
const ll mod = 1e9 + 7;

using namespace std;

ll f[MAXN], a[MAXN], mx;

int main() {
    srand(time(0));
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    fast_io;
    ll n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i){
        ll x, y;
        cin >> x >> y;
        f[x]++;
        f[y + 1]--;
    }
    ll now = 0;
    for (int i = 1; i <= m; ++i){
        now += f[i];
        a[i] = now;
    }

    vector <ll> v;
    ll mx = 0;
    v.push_back(-1e18);
    for (int i = 1; i <= m; ++i) v.push_back(1e18);
    v.push_back(1e18);
    for (int i = 1; i <= m; ++i){
        ll now = upper_bound(v.begin(), v.end(), a[i]) - v.begin();
        if (v[now - 1] <= a[i]) v[now] = a[i];
        f[i] = lower_bound(v.begin(), v.end(), 1e18) - v.begin() - 1;
        mx = max(f[i], mx);
    }

    v.clear();
    v.push_back(-1e18);
    for (int i = 1; i <= m; ++i) v.push_back(1e18); v.push_back(1e18);

    reverse(a + 1, a + m + 1);

    for (int i = 1; i <= m; ++i){
        ll now = upper_bound(v.begin(), v.end(), a[i]) - v.begin();
        if (v[now - 1] <= a[i]) v[now] = a[i];
        ll cur = lower_bound(v.begin(), v.end(), 1e18) - v.begin() - 1;
        mx = max(f[m - i + 1] + cur - 1, mx);
    }
    cout << mx << endl;

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
const int INF = 0x3f3f3f3f;
const LL mod = 1e9+7;
typedef pair<int,int> pll;
const int N = 100010;
int a[N], dp[N], cnt[N], pre[N], suf[N];
int main(){
    int n, m, l, r;
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++){
        scanf("%d%d",&l,&r);
        cnt[l]++;
        cnt[r+1]--;
    }
    for(int i = 1; i <= m; i++)
        a[i] = a[i-1]+cnt[i];
    memset(dp, INF, sizeof(dp));
	for(int i = 1; i <= m; i++){
        *upper_bound(dp, dp+m, a[i]) = a[i];
        pre[i] = lower_bound(dp, dp+m, INF) - dp;
	}
	memset(dp, INF, sizeof(dp));
	for(int i = m; i >= 1; --i){
        *upper_bound(dp, dp+m, a[i]) = a[i];
        suf[i] = lower_bound(dp, dp+m, INF) - dp;
	}
	int ans = 0;
	for(int i = 1; i <= m; i++) ans = max(ans, pre[i]+suf[i+1]);
	printf("%d",ans);
	return 0;
}

#include <bits/stdc++.h>
#define LL long long
#define Accel ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define Re(a,b) memset(a,b,sizeof a)
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define ALL(X) (X).begin(), (X).end()
#define FOR(I, A, B) for (int I = (A); I <= (B); I++)
#define REP(I, N) for (int I = 0; I < (N); I++)
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define SZ(a) ((int)a.size())
//#pragma GCC optimize(2)
using namespace std;
const int N=1e5+5;
const int M=1e9+7;
const double eps=1e-6;
typedef complex<double>C;
const double PI(acos(-1.0));
//size() use int
//__gcd, atan2(y,x)=y/x , __int128
//c(n,k)=c(n-1,k-1)+c(n-1,k)
//c(i,r),i for r to n =c(n+1,r+1)
//void add(int x){while(x<N)BIT[x]++,x+=x&-x;}
//int sum(int x){return x?BIT[x]+sum(x-(x&-x)):0;}
//int find(int x){return x==p[x]?x:p[x]=find(p[x]);}
//LL pw(LL a, LL b,LL M) { return b ? b & 1 ? a*pw(a, b - 1,M) % M : pw(a*a%M, b>>1,M) : 1; }
//log() = ln() , log(x)/log(y)=log(y)-base-x
//watch out LL
//INT_MAX 127,INT_MIN 128
int n,m;
int a[N];
int ls[N],ld[N];
int d[N];
int main(){
	cin>>n>>m;
	REP(i,n){
		int l,r;
		cin>>l>>r;
		a[l]++;a[r+1]--;
	}
	FOR(i,1,m)a[i]+=a[i-1],d[i]=1e9;
	d[0]=-1e9;
	FOR(i,1,m){
		int pos=upper_bound(d,d+m,a[i])-d;
		ls[i]=pos;
		d[pos]=min(d[pos],a[i]);
	}
	d[0]=-1e9;
	FOR(i,1,m)d[i]=1e9;
	for(int i=m;i;i--){
		int pos=upper_bound(d,d+m,a[i])-d;
		ld[i]=pos;
		d[pos]=min(d[pos],a[i]);
	}
	int ans=0;
	FOR(i,1,m)
		ans=max(ans,ls[i]+ld[i]-1);
	cout<<ans<<endl;
}

#include<bits/stdc++.h>
#include<unordered_map>
//#include "mtsf.h"
using namespace std;
typedef double D;
typedef long long ll;
const ll mod=1e9+7;
const int inf=(1<<30);
const int MX=1e5+9;
int n,m,p[MX],seg[MX*5],seg1[MX*5],l[MX],r[MX];
void up(int node,int l,int r,int ind,int val){
    if(l>ind||r<ind)return;
    if(l==r){
        seg[node]=val;
        return;
    }
    int mid=(l+r)/2;
    up(node*2,l,mid,ind,val);
    up(node*2+1,mid+1,r,ind,val);
    seg[node]=max(seg[node*2],seg[node*2+1]);
}
int q(int node,int l,int r,int s,int e){
    if(l>e||r<s)return 0;
    if(l>=s&&r<=e)return seg[node];
    int mid=(l+r)/2;
    return max(q(node*2,l,mid,s,e),q(node*2+1,mid+1,r,s,e));
}
int x,y;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d%d",&x,&y);
        p[x]++;
        p[y+1]--;
    }
    int ans=0;
    for(int i=1;i<=m;i++)p[i]+=p[i-1];
    for(int i=1;i<=m;i++){
        l[i]=q(1,0,n,0,p[i])+1;
        up(1,0,n,p[i],l[i]);
        ans=max(ans,l[i]);
    }
    memset(seg,0,sizeof(seg));
    for(int i=m;i>=1;i--){
        r[i]=q(1,0,n,0,p[i])+1;
        up(1,0,n,p[i],r[i]);
        ans=max(ans,r[i]);
    }
    for(int i=1;i<=m;i++)ans=max(ans,l[i]+r[i]-1);
    cout<<ans<<endl;
}

#include <bits/stdc++.h>
using namespace std;
int arr[100005];
int n, m;
vector<pair<int, int> > vec;
int le[100005];
int tree[400005];
int sz;
void update(int idx, int val) {
	idx += sz;
	tree[idx] = val;
	idx /= 2;
	while (idx) {
		tree[idx] = max(tree[idx * 2], tree[idx * 2 + 1]);
		idx /= 2;
	}
}
int query(int le, int ri) {
	int ret = 0;
	le += sz;
	ri += sz;
	while (le <= ri) {
		if (le & 1)ret = max(ret, tree[le++]);
		if (!(ri & 1))ret = max(ret, tree[ri--]);
		le /= 2;
		ri /= 2;
	}
	return ret;
}
int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		int l, r;
		scanf("%d%d", &l, &r);
		vec.push_back(make_pair(l, 0));
		vec.push_back(make_pair(r, 1));
	}
	sort(vec.begin(), vec.end());
	int idx = 0;
	int cnt = 0;
	for (int i = 1; i <= m; i++) {
		while (idx < vec.size() && vec[idx]==make_pair(i,0)) {
			cnt++;
			idx++;
		}
		arr[i] = cnt;
		while (idx < vec.size() && vec[idx] == make_pair(i, 1)) {
			cnt--;
			idx++;
		}
	}
	sz = 1;
	while (sz <= n)sz *= 2;
	for (int i = 1; i <= m; i++) {
		int lis = query(0, arr[i]);
		le[i] = lis + 1;
		update(arr[i], lis + 1);
	}
	memset(tree, 0, sizeof(tree));
	int ans = 0;
	for (int i = m; i >= 1; i--) {
		int lis = query(0, arr[i]);
		ans = max(ans, le[i] + lis);
		update(arr[i], lis + 1);
	}
	printf("%d\n", ans);
	return 0;
}

#include<bits/stdc++.h>
#define rg register
#define fp( i , x , y ) for( rg int i=(x); i<=(y); ++i )
#define fq( i , x , y ) for( rg int i=(y); i>=(x); --i )
using namespace std ;
const int N = 1e5+10  ;
int t[N] , a[N] , len , f[N] , b[N] , n , m ;
int Ins( int x ) {
   int i = b[len] <= x ? ++len : upper_bound( b+1 , b+1+len , x ) - b ;
   b[i] = x ; return i ;
}
signed main( ) {
  int x , y ;
  scanf( "%d %d" , &m , &n ) ;
  fp( i , 1 , m ) {
    scanf( "%d %d" , &x , &y ) ;
    t[x] ++ ; t[y+1] -- ; }
  int now = 0 , ans = 0 ;
  fp( i , 1 , n )
    now += t[i] , a[i] = now ;
 // fp( i , 1 , n ) printf( "%d " , a[i] ) ;
   len = 0 ; b[1] = -1 ;
   fp( i , 1 , n ) f[i] = Ins( a[i] ) ;
   len = 0 ; b[1] = -1 ;
   fq( i , 1 , n ) ans = max( ans , f[i] + Ins(a[i]) - 1 ) ;
   printf( "%d\n" , ans ) ;
  return 0 ;
}

/*
chirag11032000
Chirag Thakur
*/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

using ll = long long;
using db = double;
using pii = pair < int, int >;
using pll = pair < ll, ll >;

template < typename T > using OrderedSet = tree < T, null_type, less < T >, rb_tree_tag, tree_order_statistics_node_update >;
template < typename T > using MinPriorityQueue = priority_queue < T, vector < T >, greater < T > >;

#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template < typename Arg1 >
void __f(const char* name, Arg1&& arg1) {
	cerr << name << " : " << arg1 << std :: endl;
}
template < typename Arg1, typename... Args >
void __f(const char* names, Arg1&& arg1, Args&&... args) {
	const char* comma = strchr(names + 1, ',');
	cerr.write(names, comma - names) << " : " << arg1 << " | ";
	__f(comma + 1, args...);
}
#else
#define trace(...)
#endif

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fastIo() ios_base :: sync_with_stdio(0); cin.tie(0); cout.tie(0)

const db PI = acos(-1);
const ll LINF = LLONG_MAX;
const int MOD = 1e9 + 7, INF = INT_MAX, N = 1e5 + 10;

int bit[N];

void testCase();
int getMax(int ind);
void update(int ind, int val);

int main() {
	fastIo();
	testCase();
	cerr << "Time taken: " << int((clock() * 1000.) / CLOCKS_PER_SEC) << "ms\n";
	return 0;
}

void testCase() {
	int n, m;
	cin >> n >> m;
	vector < int > diff(m + 1);
	for (int i = 0; i < n; ++i) {
		int l, r;
		cin >> l >> r;
		++diff[l - 1], --diff[r];
	}
	vector < int > freq(m + 1);
	for (int i = 0; i < m; ++i) {
		freq[i + 1] = freq[i] + diff[i];
	}
	vector < int > lis(m + 1), lisRev(m + 1);
	for (int i = 1; i <= m; ++i) {
		lis[i] = getMax(freq[i]) + 1;
		update(freq[i], lis[i]);
	}
	reverse(freq.begin() + 1, freq.end());
	memset(bit, 0, sizeof(bit));
	for (int i = 1; i <= m; ++i) {
		lisRev[i] = getMax(freq[i]) + 1;
		update(freq[i], lisRev[i]);
	}
	reverse(lisRev.begin() + 1, lisRev.end());
	int res = 0;
	for (int i = 1; i <= m; ++i) {
		res = max(res, lis[i] + lisRev[i] - 1);
	}
	cout << res << "\n";
}

int getMax(int ind) {
	int res = -INF;
	for (int i = ind; i >= 0; i = (i & (i + 1)) - 1) {
		res = max(res, bit[i]);
	}
	return res;
}

void update(int ind, int val) {
	for (int i = ind; i < N; i |= i + 1) {
		bit[i] = max(bit[i], val);
	}
}

//stl deque,priority_queue<int,vector<int>,greater<int> >先出小，不加默认先出大
//std::ios::sync_with_stdio(false);
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	char c = getchar();
	int x = 0, f = 1;
	while (c < '0' || c > '9')
	{
		if (c == '-')
			f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x * f;
}
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef pair<int, int> P;
const int MOD = 998244353;
const db eps = 1e-5;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x7f7f7f7f;
#define pb push_back
#define Shazam ios_base::sync_with_stdio(false);  cin.tie(NULL); cout.tie(NULL);
int gcd(int a,int b){return (a%b==0)?b:gcd(b,a%b);}
ll lowbit(ll x){return x&-x;}
ll kuai(ll b,ll p,ll k)       	//	b^p % k
{
	ll now=b,ans=0;
	while(p)
	{
		if(p%2==0)
			now=now*now%k;
		else
		{
			if(ans==0)
				ans=1;
			ans=ans*now%k;
			now=now*now%k;
		}
		p/=2;
	}
	return ans;
}
const int N1 = 1005;
const int N = 1e5 + 5;

int ans[N],ansl[N],ansr[N];
int leftt[N],rightt[N];
int main()
{
	Shazam
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;++i)
	{
		int l,r;
		cin>>l>>r;
		ans[l]++;
		ans[r+1]--;
	}
	for(int i=1;i<=m;++i)
		ans[i]=ans[i-1]+ans[i];

	int cnt=1;
	leftt[0]=ans[1];
	for(int i=2;i<=m;++i)
	{
		ansl[i]=upper_bound(leftt,leftt+cnt,ans[i])-leftt;
		cnt=max(cnt,ansl[i]+1);
		leftt[ansl[i]]=ans[i];
	}
	cnt=1;
	rightt[0]=ans[m];
	for(int i=m-1;i>=1;--i)
	{
		ansr[i]=upper_bound(rightt,rightt+cnt,ans[i])-rightt;
		cnt=max(cnt,ansr[i]+1);
		rightt[ansr[i]]=ans[i];
	}
	int maxtot=0,maxl=0;
	for(int i=1;i<=m;++i)
	{
		maxtot=max(maxtot,maxl+ansr[i]+1);
		maxl=max(maxl,ansl[i]+1);
		//cout<<maxtot<<" "<<maxl<<endl;
	}
	cout<<maxtot<<endl;

	return 0;
}
/*
*/
/*
 * ┌───┐   ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
 * │Esc│   │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│  ┌┐    ┌┐    ┌┐
 * └───┘   └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘  └┘    └┘    └┘
 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
 * │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
 * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │   │
 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
 * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter  │               │ 4 │ 5 │ 6 │   │
 * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤     ┌───┐     ├───┼───┼───┼───┤
 * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│  Shift   │     │ ↑ │     │ 1 │ 2 │ 3 │   │
 * ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
 * │ Ctrl│ Win│ Alt│         Space         │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │   0   │ . │←─┘│
 * └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 */

/*
 *  Author: sleepify
 */
#include <bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
	#include "prettyprint.h"
	#define LOG(x) cerr << "*** " << x << " ***" << endl;
	#define wi(x) what_is(x, '\n')
	#define wisp(x) what_is(x, ", ")
	#define what_is(x, terminator) cerr << #x << " = " << x << terminator;
#else
	#define LOG(x)
	#define wi(x)
	#define wisp(x)
	#define what_is(x, terminator)
#endif

#define F first
#define S second
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define pb push_back
#define ALL(x) x.begin(), x.end()
#define REV_ALL(x) x.rbegin(), x.rend()
#define SZ(x) (int)x.size()
#define CONTAINS(cont, val) (cont.find(val) != cont.end())
#define endl '\n'
#define IO_SPEED_UP ios::sync_with_stdio(false);cin.tie(NULL)
#define FOR(i, s, e) for(ll i = s; i < e; i++)
#define leftmost_set(x) __builtin_clzll(x)
#define TWO_POWER(n) (1LL << (n))

// When root of a binary tree is 1
#define PARENT(n) ((n) >> 1LL)
#define LCHILD(n) ((n) << 1LL)
#define RCHILD(n) (((n) << 1LL) + 1LL)

typedef long long ll;typedef pair<ll, ll> ii;
typedef vector<ll> vi;typedef vector<bool> vb;
typedef vector<ii> vii;typedef vector<vi> vvi;

const int INF32 = 1E9;
const long long INF64 = 4E18;
const ll M = 1E9 + 7;
const double EPS = 1E-9;
const double PI = 2 * acos(0);

/*
 * L(i) represents the smallest ending value of all length-i LISs found so far.
 */
int LIS(vi &a, vi& res) {
	if(SZ(a) == 0) return 0;
	vi L; L.pb(a[0]);
	ll lis = 1; // lis = length of longest non decreasing subsequence till now
	 	 	 	// lis is not length of lis ending at current position
	res[0] = 1;
	for(int i = 1; i < SZ(a); i++) {
//		auto ind = lower_bound(ALL(L), a[i]); // for strictly increasing
		auto ind = upper_bound(ALL(L), a[i]); // for non decreasing
		if(ind == L.end()) {
			L.pb(a[i]);
		} else {
			*ind = min(a[i], *ind);
		}
//		lis = max(lis, pos);
		lis = SZ(L);
		res[i] = lis;
	}
	return SZ(L);
}

int main() {
	IO_SPEED_UP; // Turn Off for Interactive Problems
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, m; cin >> n >> m;
	vi a(m + 2, 0);
	for (int i = 0; i < n; ++i) {
		int l, r; cin >> l >> r;
		a[l]++;
		a[r + 1]--;
	}
	for (int i = 1; i <= m; ++i) {
		a[i] += a[i - 1];
	}

	vi aa(m), bb; // 0 indexed a
	for (int i = 1; i <= m; ++i) {
		aa[i - 1] = a[i];
	}
	bb = aa;
	reverse(ALL(bb));

	vi lis(m), lds(m);
	LIS(aa, lis);

	LIS(bb, lds);
	reverse(ALL(lds));

	vi unimodal(m);
	for (int i = 0; i < m; ++i) {
		unimodal[i] = lis[i] + lds[i] - 1;
	}

	ll ans = max(lis[m - 1], lds[0]);
	ans = max(ans, *max_element(ALL(unimodal)));

	cout << ans << endl;
	return 0;
}

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
using namespace std;
typedef long long LL;
int seg[400000],delt[100000],cnt[100000],acc[100000],up[100000],down[100000];
int m;
LL _get(int t){
    int l,r,p,mid;
    for(l=0,r=m-1,p=0;l!=r;){
        mid=(l+r)/2;
        if(t<=mid) r=mid,p=2*p+1;
        else l=mid+1,p=2*p+2;
    }
    return seg[p];
}
void addseg(int l,int r,int lb,int rb,int p){
    if(lb==l&&rb==r){
        seg[p]++;
        return;
    }
    int mid=(lb+rb)/2;
    seg[2*p+1]+=seg[p];
    seg[2*p+2]+=seg[p];
    seg[p]=0;
    if(r<=mid){
        addseg(l,r,lb,mid,2*p+1);
    }else if(l>mid){
        addseg(l,r,mid+1,rb,2*p+2);
    }else{
        addseg(l,mid,lb,mid,2*p+1);
        addseg(mid+1,r,mid+1,rb,2*p+2);
    }
}
void add(int l,int r){
    addseg(l,r,0,m-1,0);
}
int search(int x[],int l,int r,int w,int s){
    int mid,bl;
    for(;l!=r;){
        mid=(l+r+s)/2;
        if(s==0) bl=w>=x[mid];
        else bl=w<x[mid];
        if(bl) l=mid+1-s;
        else r=mid-s;
    }
    return l;
}
int main(){
    int n,i,u,v;
    scanf("%d%d",&n,&m);
    for(i=0;i<4*m;i++) seg[i]=0;
    for(i=0;i<n;i++){
        scanf("%d%d",&u,&v);
        add(u-1,v-1);
    }
    for(i=0;i<4*m;i++){
        if(2*i+1<4*m) seg[2*i+1]+=seg[i];
        if(2*i+2<4*m) seg[2*i+2]+=seg[i];
    }
    for(i=0;i<m;i++){
        cnt[i]=_get(i);
    }
    for(i=0;i<m;i++) up[i]=down[i]=n+1;
    for(i=0;i<m;i++) acc[i]=-1;
    int p;
    for(i=0;i<m;i++){
        p=search(up,0,i,cnt[i],0);
        acc[i]+=p+1;
        if(cnt[i]<up[p]) up[p]=cnt[i];
    }
    for(i=m-1;i>=0;i--){
        p=search(down,i,m-1,cnt[i],1);
        acc[i]+=m-p;
        if(cnt[i]<down[p]) down[p]=cnt[i];
    }
    int mx=0;
    for(i=0;i<m;i++){
        if(acc[i]>mx) mx=acc[i];
    }
    printf("%d\n",mx);
    return 0;
}
/*
 4 10
 1 1
 10 10
 4 7
 4 7
*/

#include<bits/stdc++.h>
using namespace std;
#ifndef d
#define d(...)
#endif
#define st first
#define nd second
#define pb push_back
#define siz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
typedef long long LL;

int n,m;
int tab[100005];
int prop[100005];
int naj[100005][2];

vector<int>pom;

int znajdz(int a)
{
	if(pom.empty())
	{
		pom.pb(0);
		return 0;
	}
	int p=0,k=siz(pom)-1;
	while(p!=k)
	{
		int s=(p+k)/2;
		if(pom[s]<=a)
			p=s+1;
		else
			k=s;
	}
	if(p==siz(pom)-1 && pom[p]<=a){
		pom.pb(0);
		p++;
	}
	return p;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	cin>>n>>m;
	for(int i=0;i<n;i++){
		int a,b;
		cin>>a>>b;
		prop[a]++;
		prop[b+1]--;
	}
	int curr=0;
	for(int i=1;i<=m;i++){
		curr+=prop[i];
		tab[i]=curr;
		d(cerr<<tab[i]<<endl;)
	}
	for(int i=1;i<=m;i++)
	{
		int j=znajdz(tab[i]);
		d(cerr<<i<<": "<<j<<endl;)
		naj[i][0]=j+1;
		pom[j]=tab[i];
	}
	int res=0;
	//int res=siz(pom);
	pom.clear();
	for(int i=m;i>0;i--)
	{
		int j=znajdz(tab[i]);
		naj[i][1]=j;
		pom[j]=tab[i];
		res=max(res,naj[i][0]+naj[i][1]);
	}

	//res=max(res,siz(pom));
	cout<<res<<"\n";

	return 0;
}

#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair

using namespace std;

void LIS(vector<int> a, vector<int>& dp){
	int n=a.size();
	vector<int> d(n+1,1e9);

	for(int i=0;i<n;i++){
		auto it=upper_bound(d.begin(),d.end(),a[i]);
		*it=a[i];
		dp[i]=it-d.begin()+1;
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n,m; cin >> m >> n;

	vector<int> a(n+1,0);
	while(m--){
		int l,r; cin >> l >> r; l--,r--;
		a[l]++;a[r+1]--;
	}
	for(int i=1;i<=n;i++){
		a[i]+=a[i-1];
	}
	a.pop_back();

	vector<int> ia(n),da(n);
	LIS(a, ia);
	reverse(a.begin(),a.end());

	LIS(a,da);

	reverse(da.begin(),da.end());

	int ans=0;
	for(int i=0;i<n;i++){
		ans=max(ans,ia[i]+da[i]-1);
	}

	cout << ans << endl;
	return 0;
}

#include <bits/stdc++.h>
#define F first
#define S second
#define I insert
#define LL long long
#define PB push_back
#define MP make_pair
const LL N=100005, mod=1000000007;
using namespace std;
LL n, m, i, j, k, l, r, t, a[N], ans, b[N], ll[N];
stack<LL>s;
int main(){
    cin>>n>>m;
    for(i=0;i<n;i++){
        scanf("%lld %lld",&l,&r);
        a[l]++;
        a[r+1]--;
    }
    for(i=1;i<=m;i++)a[i]+=a[i-1];
    for(i=1;i<=m;i++)b[i]=N;
    for(i=1;i<=m;i++){
        t=0;
        for(j=17;j>=0;j--){
            if(t+(1<<j)>m)continue;
            if(b[t+(1<<j)]<=a[i])t+=(1<<j);
        }
        b[t+1]=a[i];
        ll[i]=t+1;
        //cout<<ll[i]<<" ";
    }  // cout<<endl;
    reverse(a+1,a+m+1);
    for(i=1;i<=m;i++)b[i]=N;
    for(i=1;i<=m;i++){
        t=0;
        for(j=17;j>=0;j--){
            if(t+(1<<j)>m)continue;
            if(b[t+(1<<j)]<=a[i])t+=(1<<j);
        }
        b[t+1]=a[i];
        ans=max(ans,t+ll[m-i+1]);
    }
    cout<<ans<<endl;
    return 0;
}
//      IIIIIIIII      OOOOO             A          NN        N    EEEEEEEEEE
//          I         O     O           A A         N N       N    E
//          I        O       O         A   A        N  N      N    E
//          I        O       O        A     A       N   N     N    E
//          I        O       O       AAAAAAAAA      N    N    N    EEEEEEEE
//          I        O       O      A         A     N     N   N    E
//          I        O       O     A           A    N      N  N    E
//          I         O     O     A             A   N       N N    E
//      IIIIIIIII      OOOOO     A               A  N        NN    EEEEEEEEEE ___ KAPANADZE

#include<bits/stdc++.h>
using namespace std;
#define MAX         100000
int L[MAX+10], dp1[MAX+10], dp2[MAX+10];
int lis(int *seq, int *ls, int N)
{
    int len = 0;
    for (int i = 1; i <= N; ++i) {
        int lo = 1, hi = len;
        while (lo <= hi) {
            int m = (lo + hi) / 2;
            if (L[m] <= seq[i]) lo = m + 1;
            else hi = m - 1;
        }
        L[lo] = seq[i], ls[i] = lo;
        if (len < lo) len = lo;
    }
    return len;
}
int A[MAX+10], Rev[MAX+10];
int solve(int n)
{
    lis(A, dp1, n);
    lis(Rev, dp2, n);
    int ans = 0;
    for(int i = 1, j = n; i<=n; i++, j--)
    {
        ans = max(ans, dp1[i] + dp2[j] - 1);
//        ans = max(ans, (min(dp1[i],dp2[j])*2 - 1));;
    }
    return ans;
}
int go(vector<int>&arr, int n)
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    for(int i = 1, j = n; i<=n; i++,j--)
        A[i] = arr[i-1], Rev[j] = A[i];
    return solve(n);
}
vector<int>V;
int arr[MAX+5];
int main()
{
//    freopen("in.txt", "r", stdin);

    int n, m, i, l, r, ans = 0;

    scanf("%d %d", &n, &m);
    for(i = 1; i <= n; i++){
        scanf("%d %d", &l, &r);
        arr[l]++;
        arr[r + 1]--;
    }

    for(i = 1; i <= m; i++)
        arr[i] += arr[i - 1];

    for(int i = 1; i<=m; i++)
    {
//        if(arr[i])
            V.push_back(arr[i]);
    }
//    cerr<< V.size() << endl;
    cout << go (V, V.size()) << endl;
}

#define _CRT_SECURE_NO_WARNINGS
#define TASK "circuit"
#pragma comment(linker, "/STACK:210886422")
#include <cstdio>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <assert.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <functional>
#include <bitset>
#include <unordered_set>
#include <unordered_map>
#include <random>
#include <complex>
using namespace std;

const int MOD = 998244353;
const int INF = 1000000000;
const long double EPS = 1e-3;
const int HASH_POW = 29;
const long double PI = acos(-1.0);
mt19937_64 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());

long long nextLong(long long l, long long r) {
	uniform_int_distribution <long long> foo(l, r);
	return foo(rnd);
}

double nextDouble(double l, double r) {
	uniform_real_distribution <double> foo(l, r);
	return foo(rnd);
}

double workTime() {
	return double(clock()) / CLOCKS_PER_SEC;
}

void myReturn(int code = 0) {
#ifdef MYDEBUG
	cout << "\nTime = " << fixed << setprecision(3) << workTime() << endl;
#endif
	exit(code);
}

int n, m, x[100010], y[100010], cnt[100010];

int dpL[100010], dpR[100010], t[400010];

void build(int v, int tl, int tr) {
	memset(t, 0, sizeof t);
}

void update(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {
		t[v] = max(t[v], val);
	}
	else {
		int mid = (tl + tr) / 2;
		if (pos <= mid) {
			update(2 * v, tl, mid, pos, val);
		}
		else {
			update(2 * v + 1, mid + 1, tr, pos, val);
		}
		t[v] = max(t[2 * v], t[2 * v + 1]);
	}
}

int query(int v, int tl, int tr, int l, int r) {
	if (l > r) {
		return 0;
	}
	if (tl == l && tr == r) {
		return t[v];
	}
	int mid = (tl + tr) / 2;
	if (r <= mid) {
		return query(2 * v, tl, mid, l, r);
	}
	else if (l > mid) {
		return query(2 * v + 1, mid + 1, tr, l, r);
	}
	else {
		return max(query(2 * v, tl, mid, l, mid), query(2 * v + 1, mid + 1, tr, mid + 1, r));
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
#ifdef MYDEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	/*freopen(TASK".in", "r", stdin);
	freopen(TASK".out", "w", stdout);*/
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
#endif

	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d %d", &x[i], &y[i]);
		++cnt[x[i]];
		--cnt[y[i] + 1];
	}
	for (int i = 1; i <= m; ++i) {
		cnt[i] += cnt[i - 1];
	}

	build(1, 0, n);
	for (int i = 1; i <= m; ++i) {
		dpL[i] = query(1, 0, n, 0, cnt[i]) + 1;
		update(1, 0, n, cnt[i], dpL[i]);
	}
	build(1, 0, n);
	for (int i = m; i >= 1; --i) {
		dpR[i] = query(1, 0, n, 0, cnt[i]) + 1;
		update(1, 0, n, cnt[i], dpR[i]);
	}
	int ans = 0;
	for (int i = 1; i <= m; ++i) {
		ans = max(ans, dpL[i] + dpR[i] - 1);
	}
	printf("%d\n", ans);

	myReturn();
}

#include <bits/stdc++.h>

// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")

#define fr(i, a, b) for(int i = (a); i <= (b); ++i)
#define rf(i, a, b) for(int i = (a); i >= (b); --i)
#define fe(x, y) for(auto& x : y)

#define fi first
#define se second
#define pb push_back
#define ve vector
#define y1 stanislavpolyn

#define sz(x) (ll)(x).size()
#define pw(x) (1ll << (x))
#define all(x) (x).begin(), (x).end()

using namespace std;

using ll = long long;
using ld = long double;

#include <ext/rope>
using namespace __gnu_cxx;

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define fbo find_by_order
#define ook order_of_key

mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());

template<typename T>
bool umn(T& a, T b) { return (a > b ? (a = b, 1) : 0); }
template<typename T>
bool umx(T& a, T b) { return (a < b ? (a = b, 1) : 0); }

const ll maxn = 1e5 + 5;
const ll oo = 1e18;
const ll mod = 1e9 + 7;

#define right shue
#define left ppsh

struct Fenwick {
    ve<ll> F;
    int n;
    void init(int _n) {
        n = _n;
        F.resize(n);
    }
    Fenwick(int _n) {
        init(_n);
    }
    Fenwick() {

    }
    void update(int pos, ll val) {
        while(pos < n) {
            F[pos] += val;
            pos = pos | (pos + 1);
        }
    }
    ll get(int pos) {
        ll res = 0;
        while(pos >= 0) {
            res += F[pos];
            pos = (pos & (pos + 1)) - 1;
        }
        return res;
    }
};

ll n, m;
Fenwick F;
ve<ll> v;
ve<ll> dp;
ll left[maxn], right[maxn];

int main() {
//     freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    F.init(m + 1);
    fr(i, 0, n - 1) {
        ll l, r;
        cin >> l >> r;
        F.update(l, 1);
        F.update(r + 1, -1);
    }
    fr(i, 1, m) {
        v.pb(F.get(i));
    }
    dp.resize(sz(v) + 1, oo);
    dp[0] = -oo;
    fr(i, 0, sz(v) - 1) {
        ll x = v[i];
        int pos = upper_bound(all(dp), x) - dp.begin();
        left[i] = pos;
        if(dp[pos] > x && dp[pos - 1] <= x) {
            dp[pos] = x;
        }
    }
    reverse(all(v));
    dp.clear();
    dp.resize(sz(v) + 1, oo);
    dp[0] = -oo;
    fr(i, 0, sz(v) - 1) {
        ll x = v[i];
        int pos = upper_bound(all(dp), x) - dp.begin();
        right[sz(v) - i - 1] = pos;
        if(dp[pos] > x && dp[pos - 1] <= x) {
            dp[pos] = x;
        }
    }
    ll mx = -oo;
    fr(i, 0, sz(v) - 1) {
        umx(mx, left[i] + right[i] - 1);
    }
    cout << mx << "\n";
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int a[maxn],d[maxn],pre[maxn],suf[maxn];
int main()
{
	int n,m,l,r;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&l,&r);
		a[l]++;
		a[r+1]--;
	}
	int tol=0,j,mx=0,sum=0,ans=0,sum1=0;
	for(int i=1;i<=m;i++)
	{
		a[i]+=a[i-1];
	}
	memset(d,0x3f,sizeof(d));
	for(int i=1;i<=m;i++)
	{
		int pos=upper_bound(d+1,d+1+m,a[i])-d;
		if(d[pos]==a[i])pos++;
		d[pos]=a[i];
		pre[i]=pos;
	}
	memset(d,0x3f,sizeof(d));
	for(int i=m;i>=1;i--)
	{
		int pos=upper_bound(d+1,d+1+m,a[i])-d;
		if(d[pos]==a[i])pos++;
		d[pos]=a[i];
		suf[i]=pos;
	}
	for(int i=1;i<=m;i++)
	{
		 ans=max(ans,pre[i]+suf[i]-1);
	}
	printf("%d\n",ans);
	return 0;
}

/*input
4 6
1 3
2 3
4 6
4 6
*/
#include <bits/stdc++.h>
using namespace std;
int freq[100005],n,enter[100005],m;
template <typename T>
class SegmentTree{
	vector<T> segtree;
	public:
	SegmentTree(int size){
		segtree.resize(4*size,0);
	}
	void update(int u, int a, int b, int i, int j, T x){
		if(j<a || i>b || a>b) return;
		if(j>=b && i<=a){
			segtree[u]=x;
			return;
		}
		update(u*2,a,(a+b)/2,i,j,x); update(u*2+1,(a+b)/2+1,b,i,j,x);
		segtree[u]=max(segtree[u*2],segtree[u*2+1]);
	}
	void update(int i, T x){
		update(1, 0, segtree.size()/4-1, i, i, x);
	}
	void update(int i, int j, T x){
		update(1, 0, segtree.size()/4-1, i, j, x);
	}
	T query(int u, int a, int b, int i, int j){
		if(j<a || i>b || a>b) return 0;
		if(j>=b && i<=a) return segtree[u];
		return max(query(u*2,a,(a+b)/2,i,j),query(u*2+1,1+(a+b)/2,b,i,j));
	}
	T query(int i, int j){
		return query(1,0,segtree.size()/4-1,i,j);
	}
};
int dpi[100005],dpd[100005];
int solve(int n){
	fill_n(dpi,n,0);
	fill_n(dpd,n,0);
	SegmentTree<int> inc(100005), dec(100005);

	for(int i=0;i<n;++i){
		inc.update(freq[i],inc.query(0,freq[i])+1);
		dpi[i] = inc.query(0,100004);
	}
	reverse(freq,freq+n);
	for(int i=0;i<n;++i){
		dec.update(freq[i],dec.query(0,freq[i])+1);
		dpd[i] = dec.query(0,100004);
	}
	reverse(dpd,dpd+n);
	int ans = 0;
	for(int i=0;i<n;++i){
		ans=max(ans,dpi[i]+dpd[i]-1);
	}
	return ans;
}

int main(){
	ios_base::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=n,x,y;i--;++enter[x],--enter[y+1])
		cin>>x>>y;
	for(int i=1,run=0;i<=m;++i)
		freq[i-1] = (run+=enter[i]);
	cout<<solve(m);
}

#define _CRT_SECURE_NO_DEPRECATE
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#ifndef __GNUC__
#include <intrin.h>
#endif // !__GNUC__
#include <random>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <numeric>
#include <cstring>
#include <complex>
#include <cassert>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <functional>

int bsf(int x) {
#ifdef __GNUC__
    return __builtin_ctz(x);
#else
    unsigned long i;
    _BitScanForward(&i, x);
    return i;
#endif
}
int bsr(int x) {
#ifdef __GNUC__
    return 31 - __builtin_clz(x);
#else
    unsigned long i;
    _BitScanReverse(&i, x);
    return i;
#endif
}

using namespace std;
typedef long long int64;
const double pi = 3.14159265358979323846;
const int inf = (int)2e+9 + 2;
const int mod = (int)1e+9 + 7;
const double eps = 1e-8;
const int N = 100000;

int n, m, k;
int a[N];
int dl[N];
int dr[N];
int b[N];

void solve()
{
    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        --x;
        ++a[x];
        --a[y];
    }
    for (int i = 1; i < m; ++i)
        a[i] += a[i - 1];
    int p = 1;
    *b = *a;
    *dl = 1;
    for (int i = 1; i < m; ++i) {
        int p1 = upper_bound(b, b + p, a[i]) - b;
        p = max(p, p1 + 1);
        b[p1] = a[i];
        dl[i] = p;
    }
    memset(b, 0, sizeof(int) * p);
    p = 1;
    *b = a[m - 1];
    dr[m - 1] = 1;
    for (int i = 1; i < m; ++i) {
        int p1 = upper_bound(b, b + p, a[m - i - 1]) - b;
        p = max(p, p1 + 1);
        b[p1] = a[m - i - 1];
        dr[m - i - 1] = p;
    }
    int ans = 0;
    for (int i = 0; i < m; ++i)
        ans = max(ans, dl[i] + dr[i] - 1);
    cout << ans;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int test = 1;
    //cin >> test;
    for (; test; --test)
        solve();
    return 0;
}

#include <iostream>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <bitset>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <random>
#include <cassert>

using namespace std;

const int N = 1e5 + 1;
const int SZ_T = 1 << 20;

int d[SZ_T];
int t[SZ_T];

void push(int pos, int l, int r) {
	if (d[pos]) {
		if (r - l != 1) {
			d[2 * pos + 1] += d[pos];
			d[2 * pos + 2] += d[pos];
		}
		t[pos] += d[pos];
		d[pos] = 0;
	}
}

void upd(int pos, int l, int r, int ul, int ur, int x) {
	push(pos, l, r);
	if (r <= ul || ur <= l) {
		return;
	}
	else if (ul <= l && r <= ur) {
		d[pos] = x;
		push(pos, l, r);
	}
	else {
		upd(2 * pos + 1, l, l + r >> 1, ul, ur, x);
		upd(2 * pos + 2, l + r >> 1, r, ul, ur, x);
	}
}

int a[N];

void build_a(int pos, int l, int r) {
	push(pos, l, r);
	if (r - l == 1) {
		a[l] = t[pos];
	}
	else {
		build_a(2 * pos + 1, l, l + r >> 1);
		build_a(2 * pos + 2, l + r >> 1, r);
	}
}

int n, m;

int dp[N];
int f[N][2];

signed main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	cin >> n >> m;
	for (int i = 0; i < n; ++i) {
		int l, r;
		cin >> l >> r;
		upd(0, 0, m, --l, r, 1);
	}
	build_a(0, 0, m);
	fill(dp + 1, dp + N, N);
	for (int i = 0; i < m; ++i) {
		int l = -1, r = i + 1;
		while (r - l > 1) {
			int mid = l + r >> 1;
			(dp[mid] <= a[i] ? l : r) = mid;
		}
		dp[l + 1] = min(dp[l + 1], a[i]);
		f[i][0] = l + 1;
	}
	reverse(a, a + m);
	fill(dp + 1, dp + N, N);
	for (int i = 0; i < m; ++i) {
		int l = -1, r = i + 1;
		while (r - l > 1) {
			int mid = l + r >> 1;
			(dp[mid] <= a[i] ? l : r) = mid;
		}
		dp[l + 1] = min(dp[l + 1], a[i]);
		f[i][1] = l + 1;
	}
	int ans = 0;
	for (int i = 0; i < m; ++i) {
		ans = max(ans, f[i][0] + f[m - 1 - i][1] - 1);
	}
	cout << ans << '\n';
	//system("pause");
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int maxn = 100005;
int cnt[maxn];

struct segtree {
  int t[2 * maxn];
  void upd(int x, int v) {
    for (x += maxn; x; x /= 2) t[x] = max(t[x], v);
  }
  int get(int l, int r) {
    int ret = 0;
    for (l += maxn, r += maxn + 1; l < r; l /= 2, r /= 2) {
      if (l & 1) ret = max(ret, t[l++]);
      if (r & 1) ret = max(ret, t[--r]);
    }
    return ret;
  }
} seg[2];

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  int n, m; cin >> n >> m;
  for (int i = 0; i < n; ++i) {
    int l, r; cin >> l >> r;
    cnt[l]++, cnt[r + 1]--;
  }
  for (int i = 1; i <= m; ++i) {
    cnt[i] += cnt[i - 1];
    seg[1].upd(cnt[i], max(seg[1].get(cnt[i], n), seg[0].get(0, n)) + 1);
    seg[0].upd(cnt[i],     seg[0].get(0, cnt[i]) + 1);
  }
  cout << seg[1].get(0, n) << '\n';
}

#include<iostream>
#include<set>
#include<map>
#include<functional>
#include<queue>
#include<string.h>
#include <sstream>
#include<stdio.h>
#include<iomanip>
#include<stdlib.h>
#include<math.h>
#include<cstdlib>
#include<vector>
#include<random>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<bitset>
#include<assert.h>
#include<fstream>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
#define rep(i,a,b) for (int i = a; i < b; i++)
#define all(x) x.begin(), x.end()
#define sz(a) (int)a.size()
#define sqr(x) ((x) * (x))
#define pi pair<ll, ll>
#define mk(a, b) make_pair(a, b)
#define nextI nextInt()
#define nextD nextDouble()
#define nextL nextLong()
#define nextC nextChar()
#define line newLine()
#define Left(x) (2 * x + 1)
#define Right(x) (2 * x + 2)
int nextInt(){ int x; scanf("%d", &x); return x; }
double nextDouble(){ double x; scanf("%lf", &x); return x; }
ll nextLong(){ ll x; scanf("%I64d", &x); return x; }
char nextChar(){ char x; scanf("%c", &x); return x; }
void newLine(){ printf("\n"); }
ll powM(ll a, ll b, ll MOD){ ll x = 1, y = a; while (b > 0){ if (b % 2 == 1){ x = (x*y); if (x>MOD) x %= MOD; }y = (y*y); if (y>MOD) y %= MOD; b /= 2; }return x; }
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b){ return (a*b) / gcd(a, b); }
int countBitSet(ll n){ int ans = 0;  while (n != 0){ n -= (n & -n); ++ans; } return ans; }
ll mod = ll(1e9 + 7);
ll mod2 = ll(1e9 + 9);
const int N = 200100;
const int M = 111;
const int LOG = 21;
const int INF = 1e9;
const LD EPS = 1e-6;
const LD PI = 2 * acos(0);
using namespace std;
int  tree[4 * N];
int point[N];
int n, m;
int l[N], r[N];
void build(int lo = 0, int hi = N - 1, int id = 0){
	if (lo == hi) {
		tree[id] = 0;
		return;
	}
	int mid = (lo + hi) / 2;
	build(lo, mid, Left(id));
	build(mid + 1, hi, Right(id));
	tree[id] = max(tree[Left(id)], tree[Right(id)]);
}
int getMax(int a, int b, int lo = 0, int hi = N - 1, int id = 0){
	if (a > hi || b < lo) return -1;
	if (a <= lo && b >= hi) return tree[id];
	int mid = (lo + hi) / 2;
	return max(getMax(a, b, lo, mid, Left(id)), getMax(a, b, mid + 1, hi, Right(id)));
}
void update(int a, int b, int val, int lo = 0, int hi = N - 1, int id = 0){
	if (a > hi || b < lo) return;
	if (a <= lo && b >= hi){
		if (tree[id] < val) tree[id] = val;
		return;
	}
	int mid = (lo + hi) / 2;
	update(a, b, val, lo, mid, Left(id));
	update(a, b, val, mid+1, hi, Right(id));

	tree[id] = max(tree[Left(id)], tree[Right(id)]);
}
vector<int> Start[N], End[N];
multiset<pair<int, int> > ms;
int main(){
#ifdef HOME
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	n = nextI;
	m = nextI;
	for (int i = 0; i < n; i++){
		int x = nextI - 1;
		int y = nextI - 1;
		Start[y].push_back(x);
		End[x].push_back(y);
	}
	for (int i = 0; i < m; i++){
		for (int j = 0; j < End[i].size(); j++){
			ms.insert(mk(i, End[i][j]));
		}
		point[i] = ms.size();
		for (int j = 0; j < Start[i].size(); j++){
			ms.erase(mk(Start[i][j], i));
		}
	}
	build();
	for (int i = m - 1; i >= 0; i--){
		r[i] = getMax(0, point[i]) +1;
		update(point[i], point[i], r[i]);
	}
	build();
	for (int i = 0; i < m; i++){
		l[i] = getMax(0, point[i]) + 1;
		update(point[i], point[i], l[i]);
	}
	int mx = -1,  pos;
	for (int i = 0; i < m; i++){
		if (l[i] + r[i] - 1 > mx){ mx = l[i] + r[i] - 1; pos = i; }
	}
	cout << mx << endl;

	return 0;
}

#include<iostream>
#include<set>
#include<map>
#include<functional>
#include<queue>
#include<string.h>
#include <sstream>
#include<stdio.h>
#include<iomanip>
#include<stdlib.h>
#include<math.h>
#include<cstdlib>
#include<vector>
#include<random>
#include<algorithm>
#include<string>
#include<stack>
#include<queue>
#include<bitset>
#include<assert.h>
#include<fstream>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
#define rep(i,a,b) for (int i = a; i < b; i++)
#define all(x) x.begin(), x.end()
#define sz(a) (int)a.size()
#define sqr(x) ((x) * (x))
#define pi pair<ll, ll>
#define mk(a, b) make_pair(a, b)
#define nextI nextInt()
#define nextD nextDouble()
#define nextL nextLong()
#define nextC nextChar()
#define line newLine()
#define Left(x) (2 * x + 1)
#define Right(x) (2 * x + 2)
int nextInt(){ int x; scanf("%d", &x); return x; }
double nextDouble(){ double x; scanf("%lf", &x); return x; }
ll nextLong(){ ll x; scanf("%I64d", &x); return x; }
char nextChar(){ char x; scanf("%c", &x); return x; }
void newLine(){ printf("\n"); }
ll powM(ll a, ll b, ll MOD){ ll x = 1, y = a; while (b > 0){ if (b % 2 == 1){ x = (x*y); if (x>MOD) x %= MOD; }y = (y*y); if (y>MOD) y %= MOD; b /= 2; }return x; }
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b){ return (a*b) / gcd(a, b); }
int countBitSet(ll n){ int ans = 0;  while (n != 0){ n -= (n & -n); ++ans; } return ans; }
ll mod = ll(1e9 + 7);
ll mod2 = ll(1e9 + 9);
const int N = 200100;
const int M = 111;
const int LOG = 21;
const int INF = 1e9;
const LD EPS = 1e-6;
const LD PI = 2 * acos(0);
using namespace std;
pair<int, int>  tree[4 * N];
int point[N];
int n, m;
int l[N], lSol[N], r[N], rSol[N];
void build(int lo = 0, int hi = N - 1, int id = 0){
	if (lo == hi) {
		tree[id] = mk(0, lo);
		return;
	}
	int mid = (lo + hi) / 2;
	build(lo, mid, Left(id));
	build(mid + 1, hi, Right(id));
	tree[id] = max(tree[Left(id)], tree[Right(id)]);
}
pair<int, int> getMax(int a, int b, int lo = 0, int hi = N - 1, int id = 0){
	if (a > hi || b < lo) return mk(-1, -1);
	if (a <= lo && b >= hi) return tree[id];
	int mid = (lo + hi) / 2;
	return max(getMax(a, b, lo, mid, Left(id)), getMax(a, b, mid + 1, hi, Right(id)));
}
void update(int a, int b, int val, int lo = 0, int hi = N - 1, int id = 0){
	if (a > hi || b < lo) return;
	if (a <= lo && b >= hi){
		if (tree[id].first < val) tree[id] = mk(val, tree[id].second);
		return;
	}
	int mid = (lo + hi) / 2;
	update(a, b, val, lo, mid, Left(id));
	update(a, b, val, mid+1, hi, Right(id));

	tree[id] = max(tree[Left(id)], tree[Right(id)]);
}
vector<int> Start[N], End[N];
multiset<pair<int, int> > ms;
int main(){
#ifdef HOME
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	n = nextI;
	m = nextI;
	for (int i = 0; i < n; i++){
		int x = nextI - 1;
		int y = nextI - 1;
		Start[y].push_back(x);
		End[x].push_back(y);
	}
	for (int i = 0; i < m; i++){
		for (int j = 0; j < End[i].size(); j++){
			ms.insert(mk(i, End[i][j]));
		}
		point[i] = ms.size();
		for (int j = 0; j < Start[i].size(); j++){
			ms.erase(mk(Start[i][j], i));
		}
	}
	build();
	for (int i = m - 1; i >= 0; i--){
		pair<int, int> p = getMax(0, point[i]);
		r[i] = p.first + 1;
		if (p.first == 0) rSol[i] = INF;
		else rSol[i] = p.second;
		update(point[i], point[i], r[i]);
	}
	build();
	for (int i = 0; i < m; i++){
		pair<int, int> p = getMax(0, point[i]);
		l[i] = p.first + 1;
		if (p.first == 0) lSol[i] = INF;
		else lSol[i] = p.second;
		update(point[i], point[i], l[i]);
	}
	int mx = -1,  pos;
	for (int i = 0; i < m; i++){
		if (l[i] + r[i] - 1 > mx){ mx = l[i] + r[i] - 1; pos = i; }
	}
	cout << mx << endl;

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define lowbit(x) ((x) & (-x))

const int maxn = (int)(1e5) + 5;
const int MAX = (int)(1e5) + 1;
int a[maxn];
int C[maxn];
int L[maxn], R[maxn];
int n, m;

inline int sum(int x) {
	int ret = 0;
	for (; x; x -= lowbit(x)) ret = max(ret, C[x]);
	return ret;
}

inline void add(int x, int v) {
	for (; x <= MAX; x += lowbit(x)) C[x] = max(C[x], v);
}

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		int l, r;
		scanf("%d%d", &l, &r);
		++a[l]; --a[r + 1];
	}
	for (int i = 1; i <= m; ++i) a[i] += a[i - 1];
	for (int i = 1; i <= m; ++i) ++a[i];
	memset(C, 0, sizeof(C));
	for (int i = 1; i <= m; ++i) {
		L[i] = sum(a[i]) + 1; add(a[i], L[i]);
	}
	memset(C, 0, sizeof(C));
	int ret = 0;
	for (int i = m; i >= 1; --i) {
		R[i] = sum(a[i]) + 1; add(a[i], R[i]);
		ret = max(ret, L[i] + R[i] - 1);
	}
	return printf("%d\n", ret), 0;
}

#include<bits/stdc++.h>
#include <ext/numeric>
using namespace std;
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scs(a) scanf("%s", a)
#define pri(x) printf("%d\n", x)
#define prie(x) printf("%d ", x)
#define pris() printf("\n")
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define BUFF ios::sync_with_stdio(false)
#define db(x) cerr << #x << " == " << x << endl
#define power(a,x) __gnu_cxx::power(a, x)
#define eps 1e-5
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<vector<int> > vvi;
typedef vector<ii> vii;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fll;
const ld pi = acos(-1);
const int MOD = 1e9 + 7;

int v[100100];
int aux[100100];
multiset<ii> s;
int dp[100100];
int main()
{
    int n,m;
    sc2(n,m);
    for(int i=0;i<n;i++)
    {
        int l,r;
        sc2(l,r);
        aux[l]++;
        aux[r+1]--;
    }
    int curr=0;
    for(int i=1;i<=m+1;i++)
    {
        curr+=aux[i];
        v[i]=curr;
    }
    multiset<ii>::iterator it;
    for(int i=1;i<=m;i++)
    {
        s.insert(mp(v[i],i));
        it=s.find((mp(v[i],i)));
        it++;
        if(it!=s.end())s.erase(it);
        dp[i]=s.size();
    }
    s.clear();
    int mx=dp[m];
    for(int i=m;i>=1;i--)
    {
        s.insert(mp(v[i],-i));
        it=s.find((mp(v[i],-i)));
        it++;
        if(it!=s.end())s.erase(it);
        mx=max(mx,((int)s.size()+dp[i-1]));

    }
    pri(mx);
    return 0;
}

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 100010;
int Pre[maxn], Suf[maxn];//Pre[i]表示[0,i]的最长非严格递增子序列的长度
int N[maxn];
int Stk[maxn], top;
const int INF = 0x3f3f3f3f;
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	memset(N, 0, sizeof(N));
	for (int i = 1; i <= n; i++)
	{
		int l, r;
		scanf("%d%d", &l, &r);
		N[l]++, N[r + 1]--;
	}
	for (int i = 2; i <= m; i++) N[i] += N[i - 1];//得到所有端点被覆盖的线段数
	top = -1;
	for (int i = 1; i <= m; i++)
	{
		if (top == -1)
		{
			Stk[++top] = N[i];
			Pre[i] = top + 1;
		}
		else
		{
			if (Stk[top] <= N[i])
			{
				Stk[++top] = N[i];
				Pre[i] = top + 1;
			}
			else
			{
				int index = upper_bound(Stk, Stk + top + 1, N[i]) - Stk;
				Stk[index] = N[i];
				Pre[i] = top + 1;
			}
		}
	}
	top = -1;
	for (int i = m; i >= 1; i--)
	{
		if (top == -1)
		{
			Stk[++top] = N[i];
			Suf[i] = top + 1;
		}
		else
		{
			if (Stk[top] <= N[i])
			{
				Stk[++top] = N[i];
				Suf[i] = top + 1;
			}
			else
			{
				int index = upper_bound(Stk, Stk + top + 1, N[i]) - Stk;
				Stk[index] = N[i];
				Suf[i] = top + 1;
			}
		}
	}
	int ans = 0;
	for (int i = 1; i <= m; i++) ans = max(ans, Pre[i] + Suf[i + 1]);
	printf("%d\n", ans);
	return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,ans;
int sum[100010],l,r;
int tr[100010],f[100010],dp[100010];
void add(int x,int v){for (;x<=m;x+=(x&-x)) tr[x]=max(tr[x],v);}
int query(int x){int ans=0;for (;x;x-=(x&-x)) ans=max(ans,tr[x]);return ans;}
int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d%d",&l,&r),sum[l]++,sum[r+1]--;
	for (int i=1;i<=m;i++) sum[i]+=sum[i-1];
	for (int i=1;i<=m;i++) sum[i]++;
	for (int i=1;i<=m;i++)
	{
		f[i]=query(sum[i])+1;
		add(sum[i],f[i]);
	//	cout<<f[i]<<endl;
	}
	memset(tr,0,sizeof(tr));
	for (int i=m;i>=1;i--)
	{
		dp[i]=query(sum[i])+1;
		add(sum[i],dp[i]);
	//	cout<<dp[i]<<endl;
	}
	for (int i=1;i<m;i++) ans=max(ans,f[i]+dp[i+1]);
	printf("%d",ans);
}

#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define ll long long
#define ld long double
#define endl '\n'

using namespace std;

const int M = 1e9 + 7;
const int N = 2e5 + 7;

int n, m, cnt[N], l[N], r[N], ansl[N], ansr[N], ans;
vector<int> dp(N, 1e9);

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef LOCAL
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif
    cin >> n >> m;
    for (int i = 0; i < n; i++){
        cin >> l[i] >> r[i];
        cnt[l[i]]++;
        cnt[r[i] + 1]--;
    }
    for (int i = 1; i <= m; i++)
        cnt[i] += cnt[i - 1];
    dp[0] = -1e9;
    for (int i = 1; i <= m; i++) {
        int j = int(upper_bound(dp.begin(), dp.end(), cnt[i]) - dp.begin());
        if (dp[j - 1] <= cnt[i] && cnt[i] < dp[j]){
            dp[j] = cnt[i];
            ansl[i] = max(ansl[i - 1], j);
        }
    }
    dp.assign(N, 1e9);
    dp[0] = -1e9;
    for (int i = m; i >= 1; i--) {
        int j = int(upper_bound(dp.begin(), dp.end(), cnt[i]) - dp.begin());
        if (dp[j - 1] <= cnt[i] && cnt[i] < dp[j]){
            dp[j] = cnt[i];
            ansr[i] = max(ansr[i + 1], j);
        }
    }
    for (int i = 1; i <= m + 1; i++)
        ans = max(ans, ansl[i - 1] + ansr[i]);
    cout << ans;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int len = 1e5+5;
int cnt[len], pref[len], suf[len], tree[4*len];

void update(int p, int l, int r, int i, int v){
    if (l == r)
        tree[p] = max(tree[p], v);

    else{
        int mid = (l+r)/2;
        if (i <= mid) update(2*p, l, mid, i, v);
        else update(2*p+1, mid+1, r, i, v);
        tree[p] = max(tree[2*p], tree[2*p+1]);
    }
}

int query(int p, int l, int r, int i, int j){
    if (i <= l && r <= j)
        return tree[p];
    if (r < i || j < l)
        return 0;

    int mid = (l+r)/2;
    return max(query(2*p, l, mid, i, j), query(2*p+1, mid+1, r, i, j));
}

int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++){
        int a, b;
        scanf("%d %d", &a, &b);
        cnt[a]++;
        cnt[b+1]--;
    }

    for (int i = 1; i <= m; i++)
        cnt[i] += cnt[i-1];

    for (int i = 0; i <= 4*n; i++)
        tree[i] = 0;
    for (int i = 1; i <= m; i++){
        pref[i] = query(1, 0, n, 0, cnt[i])+1;
        update(1, 0, n, cnt[i], pref[i]);
    }

    for (int i = 0; i <= 4*n; i++)
        tree[i] = 0;
    for (int i = m; i >= 1; i--){
        suf[i] = query(1, 0, n, 0, cnt[i])+1;
        update(1, 0, n, cnt[i], suf[i]);
    }

    int ans = 0;
    for (int i = 1; i <= m; i++)
        ans = max(ans, pref[i]+suf[i]-1);

    printf("%d\n", ans);
    return 0;
}

/*10 20
1 5
2 6
3 14
1 6
15 18
13 13
20 20
5 15
2 8
9 14
*/

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <bitset>
#include <sstream>
#include <cstdlib>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <climits>
#include <cstdio>
#include <ctype.h>
#include <time.h>
using namespace std;

#define PI acos(-1.0)
#define EPS 1e-8
#define MOD 1000000007
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define fi first
#define se second
#define go(i, a, b) for(int i = a; i <= b; ++i)
#define gorev(i, a, b) for(int i = a; i >= b; --i)

typedef long double ld;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;

template <class L, class R> ostream &operator <<(ostream &os, pair<L, R> P){
    return os << "(" << P.fi << "," << P.se << ")";
}
template <class T> ostream &operator <<(ostream &os, vector<T> V){
    os << "["; for (auto vv: V) os << vv << ","; return os << "]";
}

struct Matrix {
    vvi data;
    int r, c;
    Matrix(int row, int col, bool identity = false) : r(row), c(col) {
        data.assign(row, vector<int>(col, 0));
        if (identity) {
            for (int i = 0; i < r; ++i) {
                data[i][i] = 1;
            }
        }
    }
    Matrix operator * (Matrix& other) {
        int m = r, n = c, p = other.c;
        Matrix res(m, p);
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < p; ++j) {
                for (int k = 0; k < n; ++k) {
                    res.data[i][j] += data[i][k] * other.data[k][j];
                }
            }
        }
        return res;
    }
};

// 扩展欧几里得算法 res[1] * a + res[2] * b = res[0] = gcd(a, b)
vector<int> extendGcd(int a, int b) {
    if (b == 0) {
        return {a, 1, 0};
    } else {
        vector<int> tmp = extendGcd(b, a % b);
        return {tmp[0], tmp[2], tmp[1] - (a / b) * tmp[2]};
    }
}

// 矩阵快速幂
Matrix matrix_power(Matrix base, ll exp) {
    int n = base.r;
    Matrix res(n, n, true);
    while (exp) {
        if (exp & 1) {
            res = res * base;
        }
        base = base * base;
        exp >>= 1;
    }
    return res;
}

/******************************** template ********************************/
#define N 100010
int n, m;
int cnt[N];
//key:xi value:positions of corresponding points
unordered_map<int, vi> mm;
//amount of smaller element in the left/right
int l[N], r[N];
vi cur;
int dp[N];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef ZYC_LOCAL
    freopen("input.txt", "rt", stdin);
#endif
    cin >> n >> m;
    int L, R;
    go(i, 1, n) {
        cin >> L >> R;
        cnt[L]++;
        cnt[R + 1]--;
    }
    go(i, 1, m) {
        cnt[i] += cnt[i - 1];
        mm[cnt[i]].pb(i);
    }

    go(i, 1, m) {
        auto it = upper_bound(all(cur), cnt[i]);
        l[i] = it - cur.begin();
        if (it == cur.end()) cur.insert(it, cnt[i]);
        else *it = cnt[i];
    }

    cur.clear();

    gorev(i, m, 1) {
        auto it = upper_bound(all(cur), cnt[i]);
        r[i] = it - cur.begin();
        if (it == cur.end()) cur.insert(it, cnt[i]);
        else *it = cnt[i];
    }

    go(i, 0, n) {
        dp[i] = INT_MIN;
    }

    int res = 0;
    go(i, 1, m) {
        dp[cnt[i]] = max(dp[cnt[i]], l[i] - (int)(lower_bound(all(mm[cnt[i]]), i) - mm[cnt[i]].begin()));
        res = max(res, dp[cnt[i]] + r[i] + (int)(lower_bound(all(mm[cnt[i]]), i) - mm[cnt[i]].begin()) + 1);
    }
    cout << res;

#ifdef ZYC_LOCAL
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
    return 0;
}

//hoho! xtwakioi! xtwddYnoi(双重含义)!
#include <bits/stdc++.h>
#define ri register
#define int long long
#define E (100001)
#define mk make_pair
using namespace std; const int N=200010;
inline int read()
{
    int s=0, w=1; ri char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
    return s*w;
}
int n,m,a[N],F[N],G[N],C[N],res;
signed main()
{
    n=read(), m=read();
    for(ri int i=1;i<=n;i++)
    {
        int l,r;
        l=read(), r=read();
        l--, r--;
        a[l]++, a[r+1]--;
    }
    for(ri int i=1;i<=m;i++) a[i]+=a[i-1];
    memset(C,0x3f,sizeof(C)), C[0]=0;
    for(ri int i=0;i<m;i++)
    {
        int pos=upper_bound(C,C+m,a[i])-C-1;
        pos++;
        C[pos]=min(C[pos],a[i]);
        F[i]=pos;
    }
    memset(C,0x3f,sizeof(C)), C[0]=0;
    for(ri int i=m-1;~i;i--)
    {
        int pos=upper_bound(C,C+m,a[i])-C-1;
        pos++;
        C[pos]=min(C[pos],a[i]);
        G[i]=pos;
    }
    for(ri int i=0;i<m;i++) res=max(res,F[i]+G[i]-1);
    printf("%lld\n",res);
    return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
const int INF = 100001;

void rise(const vector<int>&a, vector<int>&d, int m)
{

	vector<int> dop(m + 1, INF);
	for (int i = 0; i < m; ++i)
	{
		int j = (int)(upper_bound(dop.begin(), dop.end(),a[i]) - dop.begin());
		d[i] = j;
		dop[j] = a[i];
	}
}

int main()
{
	int n, m;
	cin >> n >> m;
	vector<int>open(m + 1,0),close(m+1,0);
	int l, r;
	for (int i = 0; i < 2 * n; i += 2)
	{
		cin >> l >> r;
		open[l]++;
		close[r]++;
	}
	vector<int> cnt(m,0);
	int bal = 0;
	for (int i = 0; i < m; ++i)
	{
		bal += open[i+1];
		cnt[i] = bal;
		bal -= close[i+1];
	}
	vector<int> dp_up(m,0), dp_down(m,0);
	rise(cnt, dp_up, m);
	reverse(cnt.begin(), cnt.end());
	rise(cnt, dp_down, m);
	reverse(dp_down.begin(), dp_down.end());
	int maxx = -INF;
	for (int i = 0; i < m; ++i)
		maxx = max(maxx, dp_up[i] + dp_down[i] + 1);
	cout << maxx;

	return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

//#define int long long
#define ll long long
#define vi vector <int>
#define vii vector <pair<int,int> >
#define rep(i,a,b) for (int i=a;i<b;i++)
#define repD(i,a,b) for (int i=a;i>b;i--)
#define pb push_back
#define pii pair <int,int>
#define ff first
#define ss second
#define all(a) a.begin(),a.end()
#define MOD 1000000007
#define PI 3.14159265359

typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
///*X.find_by_order("index")
///X.order_of_key("key")

#define deb(x) {x}
#ifndef local
	#define deb(x) ;
#endif

///----------------------------------------------------------------------------------

int n,m,arr[100005],P[100005],pref[100005],suf[100005],segtree[400005];

void update(int node,int si,int ei,int idx,int val)
{
    if (si==ei)
    {
        segtree[node]=val;
        return;
    }

    int mid=(si+ei)/2;

    if (idx<=mid)
        update(2*node,si,mid,idx,val);
    else
        update(2*node+1,mid+1,ei,idx,val);

    segtree[node]=max(segtree[2*node],segtree[2*node+1]);
}

int query(int node,int si,int ei,int l,int r)
{
    if (si>r || ei<l)
        return 0;

    if (si>=l && ei<=r)
        return segtree[node];

    int mid=(si+ei)/2;
    return max(query(2*node,si,mid,l,r),query(2*node+1,mid+1,ei,l,r));
}

void solve()
{
	int l,r;
	cin >> n >> m;
	rep(i,0,n)
	{
		cin >> l >> r;
		P[l]++;
		P[r+1]--;
	}

	int v = 0;
	rep(i,0,m+1)
	{
		v += P[i];
		arr[i] = v;
	}
	memset(segtree,0,sizeof segtree);
	rep(i,1,m+1)
	{
		pref[i] = query(1,0,100001,0,arr[i]) + 1;
		update(1,0,100001,arr[i],pref[i]);
	}
	memset(segtree,0,sizeof segtree);
	repD(i,m,0)
	{
		suf[i] = query(1,0,100001,0,arr[i]) + 1;
		update(1,0,100001,arr[i],suf[i]);
	}
	/*
	rep(i,0,10)cout<<arr[i]<<" ";cout<<"\n";
	rep(i,0,10)cout<<pref[i]<<" ";cout<<"\n";
	rep(i,0,10)cout<<suf[i]<<" ";cout<<"\n";
	*/
	int ans = 0;
	rep(i,1,m+1)ans = max(ans, pref[i] + suf[i] - 1);
	cout<<ans<<"\n";
}

signed main()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);

 	#ifdef local
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	clock_t qwertyuiop = clock();
	#endif

	int t=1;
	//cin>>t;

	rep(a,0,t)
	{
		///cout<<"Case #"<<a+1<<": ";
		solve();
	}

	#ifdef local
	{qwertyuiop = clock() - qwertyuiop;double time_taken = ((double)qwertyuiop)/CLOCKS_PER_SEC;cerr<<fixed<<setprecision(5)<<"\n\nTime Taken : "<<time_taken<<" seconds\n";}
	#endif
}

/*
ID: varunra2
LANG: C++
TASK: c
*/

#include<bits/stdc++.h>
using namespace std;

#ifdef DEBUG
#include "lib/debug.h"
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#pragma GCC diagnostic ignored "-Wsign-compare"
//#pragma GCC diagnostic ignored "-Wunused-parameter"
//#pragma GCC diagnostic ignored "-Wunused-variable"
#else
#define debug(...) 42
#endif

#define EPS 1e-9
#define IN(A, B, C) assert(B <= A && A <= C)
#define INF (int)1e9
#define MEM(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define MP make_pair
#define PB push_back
#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.end(), cont.begin()
#define x first
#define y second

const double PI = acos(-1.0);
typedef long long ll;
typedef long double ld;
typedef pair<int, int> PII;
typedef map<int, int> MPII;
typedef multiset<int> MSETI;
typedef set<int> SETI;
typedef set<string> SETS;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<string> VS;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define sz(x) (int)(x).size()
typedef pair<int, int> pii;
typedef vector<int> vi;
#pragma GCC diagnostic ignored "-Wsign-compare"
// util functions

void LIS(vector<int> nums, VI& dp) {
    vector<int> res;
    for(int i=0; i<nums.size(); i++) {
        auto it = upper_bound(res.begin(), res.end(), nums[i]);
        if(it==res.end()) res.push_back(nums[i]);
        else *it = nums[i];
        dp[i] = res.size();
    }
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("c.in", "r", stdin);
  freopen("c.out", "w", stdout);
#endif
  cin.sync_with_stdio(0); cin.tie(0);

  int n, m;
  cin >> n >> m;

  VII vals(n);

  for(int i = 0; i < n; i++) {
    cin >> vals[i].x >> vals[i].y;
  }

  VI pref(m + 1, 0);

  for(int i = 0; i < n; i++) {
    pref[vals[i].x - 1]--;
    pref[vals[i].y]++;
  }

  for(int i = m - 1; i >= 0; i--) {
    pref[i] += pref[i + 1];
  }

  VI dpa(m + 1, 0), dpb(m + 1, 0);

  LIS(pref, dpa);

  reverse(all(pref));

  LIS(pref, dpb);

  int ret = 0;

  for(int i = 0; i <= m; i++) {
    ret = max(ret, dpa[i] - 1 + dpb[m - i] - 1);
  }
  cout << ret << endl;

  debug(dpa);
  debug(dpb);

  return 0;
}

#include <bits/stdc++.h>
                                        #include<iostream>
                                        #include<cstdio>
                                        #include<vector>
                                        #include<queue>
                                        #include<map>
                                        #include<cstring>
                                        #include<string>
                                        #include <math.h>
                                        #include<algorithm>
                                    //    #include <boost/multiprecision/cpp_int.hpp>
                                        #include<functional>
                               #define int long long
                                        #define inf  1000000007
                                        #define pa pair<int,int>
                                        #define ll long long
                                        #define pal pair<double,double>
                                        #define ppap pair<pa,int>

                                        #define ssa pair<string,int>
                                        #define  mp make_pair
                                        #define  pb push_back
                                        #define EPS (1e-8)
                                        #define equals(a,b) (fabs((a)-(b))<EPS)
int dx[4]={0,-1,0,1};
int dy[4]={1,0,-1,0};
                                        using namespace std;
                               			class pa3{
                                        	public:
                                        	int x,y,z;
                                        	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                        	bool operator < (const pa3 &p) const{
                                        		if(x!=p.x) return x<p.x;
                                        		if(y!=p.y) return y<p.y;
                                        		 return z<p.z;
                                        		//return x != p.x ? x<p.x: y<p.y;
                                        	}
                               				bool operator > (const pa3 &p) const{
                                        		if(x!=p.x) return x>p.x;
                                        		if(y!=p.y) return y>p.y;
                                        		 return z>p.z;
                                        		//return x != p.x ? x<p.x: y<p.y;
                                        	}
                                        	bool operator == (const pa3 &p) const{
                                        		return x==p.x && y==p.y && z==p.z;
                                        	}
                                        		bool operator != (const pa3 &p) const{
                                        			return !( x==p.x && y==p.y && z==p.z);
                                        	}

                                        };

                                        class pa4{
                                        	public:
                                        	double x;
                                        	int y,z,w;
                                        	pa4(double x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                        	bool operator < (const pa4 &p) const{
                                        		if(x!=p.x) return x<p.x;
                                        		if(y!=p.y) return y<p.y;
                                        		if(z!=p.z)return z<p.z;
                                        		return w<p.w;
                                        		//return x != p.x ? x<p.x: y<p.y;
                                        	}
                                        	bool operator > (const pa4 &p) const{
                                        		if(x!=p.x) return x>p.x;
                                        		if(y!=p.y) return y>p.y;
                                        		if(z!=p.z)return z>p.z;
                                        		return w>p.w;
                                        		//return x != p.x ? x<p.x: y<p.y;
                                        	}
                                        	bool operator == (const pa4 &p) const{
                                        		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                        	}

                                        };
                                        class pa2{
                                        	public:
                                        	int x,y;
                                        	pa2(int x=0,int y=0):x(x),y(y) {}
                                        	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                        	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                        	pa2 operator * (int a) {return pa2(x*a,y*a);}
                                        	bool operator < (const pa2 &p) const{
                                        		return x != p.x ? x<p.x: y<p.y;
                                        	}
                                        	bool operator > (const pa2 &p) const{
                                        		return x != p.x ? x>p.x: y>p.y;
                                        	}
                                        	bool operator == (const pa2 &p) const{
                                        		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                        	}
                                        	bool operator != (const pa2 &p) const{
                                        		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                        	}

                                        };

                                               #define ppa pair<int,pas>
                                        class Point{
                                        	public:
                                        	double x,y;
                                        	Point(double x=0,double y=0):x(x),y(y) {}
                                        	Point operator + (Point p) {return Point(x+p.x,y+p.y);}
                                        	Point operator - (Point p) {return Point(x-p.x,y-p.y);}
                                        	Point operator * (double a) {return Point(x*a,y*a);}
                                        	Point operator / (double a) {return Point(x/a,y/a);}
                                        	double absv() {return sqrt(norm());}
                                        	double norm() {return x*x+y*y;}
                                        	bool operator < (const Point &p) const{
                                        		return x != p.x ? x<p.x: y<p.y;
                                        	}
                                        	bool operator == (const Point &p) const{
                                        		return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
                                        	}
                                        };
                                        typedef Point Vector;
                                 #define pl pair<int,pas>
                                        struct Segment{
                                        Point p1,p2;
                                        };
                                         double dot(Vector a,Vector b){
                                        	return a.x*b.x+a.y*b.y;
                                        }
                                        double cross(Vector a,Vector b){
                                        	return a.x*b.y-a.y*b.x;
                                        }

            bool parareru(Point a,Point b,Point c,Point d){
            //	if(abs(cross(a-b,d-c))<EPS)cout<<"dd "<<cross(a-b,d-c)<<endl;
            	return abs(cross(a-b,d-c))<EPS;
            }
            double distance_ls_p(Point a, Point b, Point c) {
              if ( dot(b-a, c-a) < EPS ) return (c-a).absv();
              if ( dot(a-b, c-b) < EPS ) return (c-b).absv();
              return abs(cross(b-a, c-a)) / (b-a).absv();
            }
            bool is_intersected_ls(Segment a,Segment b) {
            	if(a.p1==b.p1||a.p2==b.p1||a.p1==b.p2||a.p2==b.p2) return false;
            	if(parareru((a.p2),(a.p1),(a.p1),(b.p2))&&parareru((a.p2),(a.p1),(a.p1),(b.p1))){
            //		cout<<"sss"<<endl;
            		if(dot(a.p1-b.p1,a.p1-b.p2)<EPS) return true;
            		if(dot(a.p2-b.p1,a.p2-b.p2)<EPS) return true;
            		if(dot(a.p1-b.p1,a.p2-b.p1)<EPS) return true;
            		if(dot(a.p1-b.p2,a.p2-b.p2)<EPS) return true;
            		return false;
            	}
              else return ( cross(a.p2-a.p1, b.p1-a.p1) * cross(a.p2-a.p1, b.p2-a.p1) < EPS ) && ( cross(b.p2-b.p1, a.p1-b.p1) * cross(b.p2-b.p1, a.p2-b.p1) < EPS );
            }

            double segment_dis(Segment a,Segment b){
            	if(is_intersected_ls(a,b))return 0;
            	double r=distance_ls_p(a.p1, a.p2, b.p1);
            	r=min(r,distance_ls_p(a.p1, a.p2, b.p2));
            	r=min(r,distance_ls_p(b.p1, b.p2, a.p2));
            	r=min(r,distance_ls_p(b.p1, b.p2, a.p1));
            	return r;
            }
            Point intersection_ls(Segment a, Segment b) {
              Point ba = b.p2-b.p1;
              double d1 = abs(cross(ba, a.p1-b.p1));
              double d2 = abs(cross(ba, a.p2-b.p1));
              double t = d1 / (d1 + d2);

              return a.p1 + (a.p2-a.p1) * t;
            }

                            string itos( int i ) {
                            ostringstream s ;
                            s << i ;
                            return s.str() ;
                            }

                            int gcd(int v,int b){
                            	if(v>b) return gcd(b,v);
                            	if(v==b) return b;
                            	if(b%v==0) return v;
                            	return gcd(v,b%v);
                            }

                            double distans(double x1,double y1,double x2,double y2){
                            	double rr=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
                            	return sqrt(rr);

                            }
             /*
            int pr[1000010];
            int inv[1000010];

            int beki(int wa,int rr,int warukazu){
            	if(rr==0) return 1%warukazu;
            	if(rr==1) return wa%warukazu;
            	if(rr%2==1) return (beki(wa,rr-1,warukazu)*wa)%warukazu;
            	int zx=beki(wa,rr/2,warukazu);
            	return (zx*zx)%warukazu;
            }
double bekid(double w,int r){
	if(r==0) return 1.0;
	if(r==1) return w;
	if(r%2) return bekid(w,r-1)*w;
	double f=bekid(w,r/2);
	return f*f;
}

			int comb(int nn,int rr){
				int r=pr[nn]*inv[rr];
				r%=inf;
				r*=inv[nn-rr];
				r%=inf;
				return r;
			}

            void gya(int ert){
            	pr[0]=1;
            	for(int i=1;i<=ert;i++){
            		pr[i]=(pr[i-1]*i)%inf;
            	}
           	for(int i=0;i<=ert;i++) inv[i]=beki(pr[i],inf-2,inf);

            }
            */
			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;
             //sort(ve.begin(),ve.end(),greater<int>());
                                     //----------------kokomade tenpure------------
            //vector<double> ans(100000000),ans2(100000000)

struct Segmax{
	//       1
	//   2        3
	// 4   5   6    7

	private:
	public:

	// (1<<15)=32768
	// 1<<16 = 65536
	// 1<<17 = 131072
	// 1<<18 = 262144

	int cor=(1<<17);

	vector<pa> vec;

	void shoki1(){

		vec.resize(2*cor+3, mp(0,0));
		for(int i=cor;i<2*cor;i++)vec[i].second=i-cor;
	}
		void shoki2(){
			for(int i=cor-1;i>0;i--) {
				if(vec[2*i].first>=vec[2*i+1].first) vec[i]=vec[2*i];
				else vec[i]=vec[2*i+1];
			}
		}

	void updadd(int x,int w){
		//x ���ڂ� w���Z
		x+=cor;
		vec[x].first+=w;
		while(1){
			x/=2;
			if(x==0) break;
			if(vec[2*x].first>=vec[2*x+1].first) vec[x]=vec[2*x];
			else vec[x]=vec[2*x+1];
		}

	}

	void updchan(int x,int w){
		//x���ڂ�w�ɕύX
		x+=cor;
		vec[x].first=w;
		while(1){
			x/=2;
			if(x==0) break;
			if(vec[2*x].first>=vec[2*x+1].first) vec[x]=vec[2*x];
			else vec[x]=vec[2*x+1];
		}

	}
	// [a,b)
	// k-th node
	// k no kukanha [l,r)
	pa segmax(int a,int b,int k=1,int l=0,int r=-10){
		if(r<0)r=cor;

	//	cout<<a<<" "<<b<<" "<<k<<" "<<l<<" "<<r<<endl;

		if(a<=l && r<=b){
			return vec[k];
		}
		if(r<=a || b<=l){
			return mp(-(1ll<<31),-1);
		}

		pa v1=segmax(a,b,k*2,l,(l+r)/2),v2=segmax(a,b,k*2+1,(l+r)/2,r);

		if(v1.first>=v2.first)return v1;
		else return v2;
	}

};
int imo[100010];
int hi[100010],mi[100010];
Segmax sm,sm2;
signed main(){
//ios::sync_with_stdio(false);
int n,m;
	sm.shoki1();
	sm.shoki2();
	sm2.shoki1();
	sm2.shoki2();
	cin>>n>>m;
	for(int i=0;i<n;i++){
	int y,yy;
		cin>>y>>yy;
		yy++;
		imo[y]++;
		imo[yy]--;

	}
	for(int i=1;i<=100002;i++)imo[i]+=imo[i-1];

	for(int i=1;i<=m;i++){
		pa z=sm.segmax(0,imo[i]+1);
		hi[i]=1+z.first;
		sm.updchan(imo[i],hi[i]);
	//	cout<<hi[i]<<endl;
	}

	for(int i=m;i>0;i--){
		pa z=sm2.segmax(0,imo[i]+1);
		mi[i]=1+z.first;
		sm2.updchan(imo[i],mi[i]);
	//	cout<<mi[i]<<endl;
	}
	int ans=0;
	for(int i=1;i<=m;i++)ans=max(ans,hi[i]+mi[i]-1);
	cout<<ans<<endl;
	return 0;
        }

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <cstdio>
#include <stdlib.h>
#include <stack>
#include <numeric>
#include <bitset>
#include <cctype>
#include <list>
#include <assert.h>
#include <random>
#include <unordered_map>
#include <ctime>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD 1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
#define MAX 100005
bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et() {
    puts("-1"); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) {
    ll z = y;
    while(x%y!=0) {
        z = x%y; x = y; y = z;
    }
    return z;
}

int a[MAX];
int L[MAX],R[MAX],N=100005;
const int MN=270000;
struct mb {
    int M,T[MN];
    void init(int sz, int val) {
        for(M=1;sz+2>M;M<<=1);
        REP(i,MN) T[i]=val;
    }
    void uptSingleMax(int l, int val) {
        l+=M; T[l]=max(T[l], val);
        while(l>1) {
            T[l>>1] = max(T[l],T[l^1]); l>>=1;
        }
    }
    int qyRangeMax(int l, int r) {
        int ans = 0;
        for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){
            if(~l&1) ans = max(ans, T[l^1]);
            if(r&1) ans = max(ans, T[r^1]);
        }
        return ans;
    }
}T;
void fmain(int ID) {
    scanf("%d%d", &n,&m);
    REQ(i,n) {
        int l,r; scanf("%d%d", &l,&r);
        a[l]++; a[r+1]--;
    }
    REQ(i,m) a[i]+=a[i-1];
    REQ(i,m) a[i]++;
    T.init(N, 0);
    REQ(i,m) {
        L[i] = T.qyRangeMax(1, a[i]) + 1;
        T.uptSingleMax(a[i], L[i]);
    }

    T.init(N, 0);
    for(int i=m;i;i--) {
        R[i] = T.qyRangeMax(1, a[i]) + 1;
        T.uptSingleMax(a[i], R[i]);
    }
    int ans=0;
    REQ(i,m) L[i]=max(L[i],L[i-1]);
    for(int i=m;i;i--) R[i]=max(R[i],R[i+1]);
    for(int i=2;i<=m;i++) {
        ans=max(ans, L[i-1]+R[i]);
    }
    printf("%d\n", ans);
}
int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define INF 0x3f3f3f3f3f3f3f3fLL

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<typename T> inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<typename T> inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<typename T> inline void println(T x) {print(x), putchar('\n');}

template<typename T> inline void printsp(T x) {print(x), putchar(' ');}

template<class T, class T1> inline void print(T x, T1 y) {printsp(x), println(y);}

template<class T, class T1, class T2> inline void print(T x, T1 y, T2 z) {printsp(x), printsp(y), println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#define NN 100100

int val[NN];

int arr[NN];

int dp[2][NN];

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int n, m;

	gn(n, m);

	for(int i=0; i<n; i++){

		int L, R;

		gn(L, R);

		val[L]++;

		val[R+1]--;

	}

	for(int i=1; i<=m; i++) val[i]+=val[i-1];

	for(int i=0; i<=m; i++) arr[i]=inf;

	for(int i=1; i<=m; i++){

		int j=upper_bound(arr, arr+m+1, val[i])-arr;

		arr[j]=val[i];

		dp[0][i]=j+1;

	}

	for(int i=0; i<=m; i++) arr[i]=inf;

	for(int i=m; i>=1; i--){

		int j=upper_bound(arr, arr+m+1, val[i])-arr;

		arr[j]=val[i];

		dp[1][i]=j+1;

	}

	int ans=0;

	for(int i=1; i<=m; i++) smax(ans, dp[0][i]+dp[1][i]-1);

	println(ans);

	return 0;

}

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+5;

int n,m,ans,ms[N],dpL[N],dpR[N],mx[N];

void upd(int v, int key){
    for(; v < N; v |= v+1)
        mx[v] = max(mx[v],key);
}

int get_mx(int v){
    int ans = 0;
    for(; v >= 0; v = (v&(v+1))-1)
        ans = max(ans,mx[v]);
    return ans;
}

void make_dp(auto &dp){
    fill(mx,mx+N,0);
    for(int i = 1; i <= m; ++i){
        dp[i] = get_mx(ms[i])+1;
        upd(ms[i],dp[i]);
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i){
        int l,r;
        scanf("%d%d",&l,&r);
        ++ms[l];
        --ms[r+1];
    }
    int now = 0;
    for(int i = 1; i <= m; ++i){
        now += ms[i];
        ms[i] = now;
    }
    make_dp(dpL);
    reverse(ms+1,ms+m+1);
    make_dp(dpR);
    for(int i = 0; i <= m; ++i)
        ans = max(ans,dpL[i]+dpR[m-i]);
    printf("%d",ans);
    return 0;
}

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>//memset(a, 0, sizeof(a));

#define maxlongint 2147483647
#define ll long long
#define fo(i, x, y) for (int i = x; i <= y; i++)
#define fd(i, x, y) for (int i = x; i >= y; i--)
#define N 500005
using namespace std;
int n,m,x,xx,y;
int sum[N];
int a[N],b[N],c[N],d[N],len1,len2;
int cc[N],dd[N],ans;
void read(int &x) {
	x=0;
	int k=1;char c=getchar();
	while ((c!='-')&&(c<'0'||c>'9')) c=getchar();
	if (c=='-') k=-1,c=getchar();
	while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
	x=x*k;
}
void write(int x) {
	if (x<0) putchar('-'),x=-x;
	if (x>9) write(x/10);
	putchar(x%10+'0');
}
void init() {
	freopen("f.in","r",stdin);
	//freopen("f.out","w",stdout);
}
void er1(int l,int r,int t) {
	while (l<=r) {
		int mid=(l+r)/2;
		if (c[mid]>t) {
			x=min(x,mid);
			r=mid-1;
		} else l=mid+1;
	}
}
void er2(int l,int r,int t) {
	while (l<=r) {
		int mid=(l+r)/2;
		if (d[mid]>t) {
			xx=min(xx,mid);
			r=mid-1;
		} else l=mid+1;
	}
}
int main() {
	//init();
	read(n),read(m);
	fo(i,1,n) {
		read(x),read(y);
		sum[x]++,sum[y+1]--;
	}
	fo(i,1,m) a[i]=a[i-1]+sum[i];
	fo(i,1,m) b[i]=a[m-i+1];
	fo(i,1,m) {
		x=len1+1;
		er1(1,len1,a[i]);
		c[x]=a[i];
		cc[i]=x;
		len1=max(len1,x);
		xx=len2+1;
		er2(1,len2,b[i]);
		d[xx]=b[i];
		dd[i]=xx;
		len2=max(len2,xx);
	}
	fo(i,1,m) {
		ans=max(ans,cc[i]+dd[m-i]);
	}
	write(ans);
	return 0;
}

#include <bits/stdc++.h>
#define ll long long

using namespace std;

const int INF = 1e9 + 7;
const int MAXN = 1e6 + 7;
const double EPS = 1e-8;

struct Tree {
    int n;
    vector <int> t;
    Tree(int n) : n(n), t(2 * n, 0) {}
    void change(int v, int x) {
        v += n;
        t[v] = x;
        v /= 2;
        while (v) {
            t[v] = max(t[2 * v], t[2 * v + 1]);
            v /= 2;
        }
    }
    int get_max(int l, int r) {
        int res = 0;
        for (l += n, r += n; l <= r; l /= 2, r /= 2) {
            if (l % 2 == 1) res = max(res, t[l++]);
            if (r % 2 == 0) res = max(res, t[r--]);
        }
        return res;
    }
};

int main() {
    #ifdef MY
        freopen("input.txt", "r", stdin);
    #else
        ios_base::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
    #endif // MY
    int n, m;
    cin >> n >> m;
    vector <int> cnt(m, 0);
    vector <pair <int, int> > a;
    for (int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        l--, r--;
        a.push_back({l, 1});
        a.push_back({r + 1, 0});
    }
    sort(a.begin(), a.end());
    int pr = 0;
    int now = 0;
    for (int i = 0; i < a.size(); i++) {
        while (a[i].first > pr) {
            cnt[pr] = now;
            pr++;
        }
        if (a[i].second) {
            now++;
        } else {
            now--;
        }
    }
    while (m > pr) {
        cnt[pr] = now;
        pr++;
    }
    vector <int> down(m, 0), up(m, 0);
    Tree t(n + 1);
    for (int i = m - 1; i >= 0; i--) {
        int val = t.get_max(0, cnt[i]) + 1;
        down[i] = val;
        t.change(cnt[i], val);
    }
    t = Tree(n + 1);
    for (int i = 0; i < m; i++) {
        int val = t.get_max(0, cnt[i]) + 1;
        //cout << val << " ";
        up[i] = val;
        t.change(cnt[i], val);
    }
    //cout << "\n";
    int res = 0;
    for (int i = 0; i < m; i++) {
        res = max(res, up[i] + down[i] - 1);
    }
    cout << res;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+5;

int n,m,ans,ms[N],dpL[N],dpR[N],mx[N];

void upd(int v, int key){
    for(; v < N; v |= v+1)
        mx[v] = max(mx[v],key);
}

int get_mx(int v){
    int ans = 0;
    for(; v >= 0; v = (v&(v+1))-1)
        ans = max(ans,mx[v]);
    return ans;
}

void make_dp(auto &dp){
    fill(mx,mx+N,0);
    for(int i = 1; i <= m; ++i){
        dp[i] = get_mx(ms[i])+1;
        upd(ms[i],dp[i]);
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i){
        int l,r;
        scanf("%d%d",&l,&r);
        ++ms[l];
        --ms[r+1];
    }
    int now = 0;
    for(int i = 1; i <= m; ++i){
        now += ms[i];
        ms[i] = now;
    }
    make_dp(dpL);
    reverse(ms+1,ms+m+1);
    make_dp(dpR);
    for(int i = 1; i <= m; ++i)
        ans = max(ans,dpL[i]+dpR[m-i]);
    printf("%d",ans);
    return 0;
}

#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=int(l);i<int(r);i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define pb push_back
#define pp pop_back
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,inf=1e9+10;

int n,m,A[maxn],pref[maxn],suff[maxn],lis[maxn];

int32_t main(){
    scanf("%d%d",&n,&m);
    rep(i,0,n){
	int l,r;
	scanf("%d%d",&l,&r);
	l--;
	A[l]++;
	A[r]--;
    }
    rep(i,1,m){
	A[i]+=A[i-1];
    }
    fill(lis,lis+maxn,inf);
    for(int i=0;i<m;i++){
	int pos=upper_bound(lis,lis+maxn,A[i])-lis;
	pref[i]=pos;
	lis[pos]=A[i];
    }
    fill(lis,lis+maxn,inf);
    for(int i=m-1;i>=0;i--){
	int pos=upper_bound(lis,lis+maxn,A[i])-lis;
	suff[i]=pos;
	lis[pos]=A[i];
    }
    int ans=0;
    rep(i,0,m){
	ans=max(ans,pref[i]+suff[i]+1);
    }
    printf("%d\n",ans);
}

/// by ztx
/// blog.csdn.net/hzoi_ztx
#include <bits/stdc++.h>
#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define rep(i,l,r) for(i=(l);i< (r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
#define rev(i,r,l) for(i=(r);i> (l);i--)
#define _Rep(i,l,r) for(int i=(l);i<=(r);i++)
#define _rep(i,l,r) for(int i=(l);i< (r);i++)
#define _Rev(i,r,l) for(int i=(r);i>=(l);i--)
#define _rev(i,r,l) for(int i=(r);i> (l);i--)
#define Each(i,v)  for(i=v.begin();i!=v.end();i++)
#define r(x) read(x)
typedef long long ll;
typedef double lf;
typedef unsigned uint;
int CH, NEG;
template <typename TP>inline void read(TP& ret) {
    ret = NEG = 0; while (CH=getchar(), CH<'!');
    if (CH == '-') NEG = true, CH = getchar();
    while (ret = ret*10+CH-'0', CH=getchar(), CH>'!');
    if (NEG) ret = -ret;
}

#define  kN  100010LL

using namespace std;

struct node {
    int l, r;
    bool operator < (const node&B) const {
        return r > B.r;
    }
}s[kN];

priority_queue<node> h;

int n, m;
int a[kN];
int ansl[kN], ansr[kN];

inline bool cmp(const node&a,const node&b){
    return a.l < b.l;
}

#define lb (p&(-p))
int c[kN];
inline void insert(int p,int x) {
    for(;p<=n+1;p+=lb) if(c[p] < x) c[p] = x; else break;
}
inline int query(int p) {
    int ret=0;for(;p>0;p-=lb) if(c[p]>ret)ret=c[p];return ret;
}

void LIS(int f[kN]) {
    // f[i] 以i结尾最长上升子序列
    memset(c,0,sizeof c);
    for(int i = 1; i <= m; i ++ ) {
        f[i] = query(a[i])+1;
        insert(a[i],f[i]);
    }
}

int main() {
    r(n), r(m);
    _Rep(i,1,n) {
        r(s[i].l);r(s[i].r);
    }
    sort(s+1,s+n+1,cmp);
    int p = 1;
    _Rep(i,1,m) {
        while (p <= n && s[p].l <= i) h.push(s[p]), p ++ ;
        while (!h.empty() && h.top().r<i) h.pop();
        a[i] = h.size()+1;
    }
    LIS(ansl);
    for(int i = m/2;i>0;i--) swap(a[i],a[m-i+1]);
    LIS(ansr);
    for(int i = m/2;i>0;i--) swap(ansr[i],ansr[m-i+1]),swap(a[i],a[m-i+1]);
    int ans = 0;
    _Rep(i,1,m) {
        // printf("a:%d ansl %d ansr %d\n",a[i],ansl[i],ansr[i]);
        ans = std::max(ans,ansl[i]+ansr[i]-1);
    }
    printf("%d\n",ans);
    END: getchar(), getchar();
    return 0;
}

/*************************************************************************
    > File Name: F.cpp
    > Author: wennitao
    > Mail: wennitao@126.com
    > Created Time: 一  3/ 5 20:21:19 2018
 ************************************************************************/

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10 ;
int c1[maxn],c2[maxn],a[maxn],f1[maxn],f2[maxn] ;
int n,m ;
int lowbit(int x){
	return x & (-x) ;
}
void add1(int x,int val){
	while(x <= n){
		c1[x] = max(c1[x],val) ;
		x += lowbit(x) ;
	}
}
void add2(int x,int val){
	while(x <= n){
		c2[x] = max(c2[x],val) ;
		x += lowbit(x) ;
	}
}
int query1(int x){
	int res = 0 ;
	while(x){
		res = max(res,c1[x]) ;
		x -= lowbit(x) ;
	}
	return res ;
}
int query2(int x){
	int res = 0 ;
	while(x){
		res = max(res,c2[x]) ;
		x -= lowbit(x) ;
	}
	return res ;
}
int main()
{
	cin >> n >> m ;
	for(int i = 0; i < n; i++){
		int l,r ;
		scanf("%d%d",&l,&r) ;
		a[l] ++; a[r + 1] -- ;
	}
	int sum = 0 ;
	for(int i = 1; i <= m; i++){
		sum += a[i] ;
		a[i] = sum + 1 ;
	}
	for(int i = 1; i <= m; i++){
		f1[i] = query1(a[i]) + 1 ;
		add1(a[i],f1[i]) ;
	}
	for(int i = m; i >= 1; i--){
		f2[i] = query2(a[i]) + 1 ;
		add2(a[i],f2[i]) ;
	}
	int ans = 0 ;
	for(int i = 1; i <= m; i++){
		ans = max(ans,f1[i] + f2[i] - 1) ;
	}
	cout << ans << endl ;
    return 0 ;
}

#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <vector>
#include <string>
#include <iomanip>

using namespace std;

typedef long long ll;

#define sz(a) ((int)(a).size())
#define all(a) (a).begin(), a.end()

#define int long long

const int N = 100000 + 123;

int t[4*N];

int get(int v, int tl, int tr, int l, int r)
{
	if (l >= tr || r <= tl)
	{
		return 0;
	}
	if (tl >= l && tr <= r)
	{
		return t[v];
	}
	int c = (tl + tr) / 2;
	return max(get(2 * v, tl, c, l, r), get(2 * v + 1, c, tr, l, r));
}

void upd(int v, int tl, int tr, int pos, int x)
{
	if (tl + 1 == tr)
	{
		t[v] = max(t[v], x);
		return;
	}
	int c = (tl + tr) / 2;
	if (pos < c)
	{
		upd(2 * v, tl, c, pos, x);
	}
	else
	{
		upd(2 * v + 1, c, tr, pos, x);
	}
	t[v] = max(t[2 * v], t[2 * v + 1]);
}

int n, m;
pair<int, int> segs[N];
int help_prec[N];
int prec[N];
int dp[N];
int ans;

inline int get(int l, int r)
{
	return get(1, 0, N, l, r);
}

inline void upd(int pos, int x)
{
	upd(1, 0, N, pos, x);
}

inline void clear()
{
	for (int i = 0; i < 4*N; i++)
	{
		t[i] = 0;
	}
}

void recalc1()
{
	clear();
	for (int i = 1; i <= m; i++)
	{
		int kek = 1 + get(1, prec[i] + 2);
		if (kek > ans)
		{
			ans = kek;
		}
		dp[i] = kek;
		upd(prec[i] + 1, kek);
	}

	clear();
	for (int i = m; i >= 1; i--)
	{
		int kek = 1 + get(1, prec[i] + 2);
		if (dp[i] + kek - 1 > ans)
		{
			ans = dp[i] + kek - 1;
		}
		upd(prec[i] + 1, kek);
	}
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	//cout << fixed << setprecision(20);

	cin >> n >> m;
	for (int  i = 0; i < n; i++)
	{
		cin >> segs[i].first >> segs[i].second;
		help_prec[segs[i].second + 1]--;
		help_prec[segs[i].first]++;
	}

	int cur = 0;
	for (int i = 1; i <= m; i++)
	{
		cur += help_prec[i];
		prec[i] = cur;
	}

	recalc1();

	for (int i = 1; i <= m; i++)
	{
		prec[i] = n - prec[i] - 1;
	}

	//recalc1();

	cout << ans;
}

#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<pair<int,int> > vp;
#define pb push_back
#define mp make_pair
#define ll long long
#define rep(i,n) for(int i=0;i<n;i++)
#define MOD 1000000007
#define N 100010
#define INF 2*1e6
int start[N], val[N], endi[N], tree[4*N], dp1[N], dp2[N];
vector<pair<int,int> > pts;
void update(int low,int high,int ind,int val, int node){
	if(low == high){
		tree[node] = max(val,tree[node]);
		return;
	}
	int mid = (low + high)/2;
	if(ind <= mid)
		update(low,mid,ind,val,2*node);
	else
		update(mid+1,high,ind,val,2*node+1);
	tree[node] = max(tree[2*node], tree[2*node+1]);
}
int query(int low,int high,int begin,int end,int node){
	if(low > end || high < begin || begin > end)
		return -1*INF;
	if(low >= begin && high <= end)
		return tree[node];
	int mid = (low + high)/2;
	return max(query(low,mid,begin,end,2*node),query(mid+1,high,begin,end,2*node+1));
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		int x,y;
		cin>>x>>y;
		start[x]++;
		endi[y]++;
	}
	int cur = 0;
	for(int i=1;i<=m;i++){
		cur += start[i];
		val[i] = cur;
		cur -= endi[i];
	}
	int maxi = 0;
	for(int i=1;i<=m;i++){
		dp1[i] = max(query(0,n,0,val[i],1),0) + 1;
		update(0,n,val[i],dp1[i],1);
	}
	memset(tree,0,sizeof(tree));
	for(int i=m;i>=1;i--){
		dp2[i] = max(query(0,n,0,val[i],1),0) + 1;
		update(0,n,val[i],dp2[i],1);
	}
	for(int i=1;i<=m;i++){
		maxi = max(maxi,dp1[i] + dp2[i] - 1);

	}
	cout<<maxi<<'\n';
}

#include <bits/stdc++.h>

using namespace std;

#define NN 100010
int B[NN];

void update(int u, int x){
    while(u < NN){
        B[u] = max(B[u], x);
        u += u & (-u);
    }
}

int calc(int u){
    int s = 0;
    while(u > 0){
        s = max(s, B[u]);
        u -= u & (-u);
    }
    return s;
}

int L[NN], R[NN];
int sL[NN], sR[NN];
int a[NN];

int main() {
#ifndef ONLINE_JUDGE
        freopen("in.in", "r", stdin);
        freopen("out.out", "w", stdout);
#endif
    ios_base :: sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int n, m;
    cin >> n >> m;
    for(int i=1; i<=n; i++){
        int Lv, Rv;
        cin >> Lv >> Rv;
        a[Lv]++;
        a[Rv+1]--;
    }

    for(int i=1; i<=m; i++) a[i] += a[i-1];
    for(int i=1; i<=m; i++) a[i]++;
    for(int i=1; i<=m; i++){
        int x = a[i];
        int t = calc(x) + 1;
        L[i] = t;
        sL[i] = max(sL[i-1], L[i]);
        update(x, t);
    }

    memset(B, 0, sizeof B);
    for(int i=m; i>=1; i--){
        int x = a[i];
        int t = calc(x) + 1;
        update(x, t);
        R[i] = t;
        sR[i] = max(sR[i+1], R[i]);
    }

    int ans = 0;
    for(int i=1; i<=m; i++){
        ans = max(ans, L[i] + R[i] - 1);
        ans = max(ans, sL[i-1] + sR[i+1]);
    }
    cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i < b; ++i)

int debug = 0;

const int N = 1<<18;
int ans, op[N], cl[N], t[N << 1], pr[N], sf[N];

void update(int v, int dd) {
    v += N - 1;
    t[v] = dd;
    while (v) {
        v = (v - 1) / 2;
        t[v] = max(t[v * 2 + 1] , t[v * 2 + 2]);
    }

}

int get(int l, int r) {
    if (l > r) { return 0; }
    l += N - 1, r += N - 1;
    int res = 0;
    while (l < r) {
        if (l % 2 == 0) res = max(res, t[l]);
        if (r % 2 == 1) res = max(res, t[r]);
        l = l / 2;
        r = (r - 2) / 2;
    }
    if (l == r) res = max(res, t[l]);
    return res;
}

main() {
    int n, m;
    cin >> n >> m;
    rep(i,0,n) {
        int l, r;
        scanf("%d%d", &l, &r);
        op[l]++;
        cl[r]++;
    }
    int bal = 0;
    vector <int> p(m + 2, 0);
    vector <vector<int>>ord(n+2);
    rep(i, 1, m + 1) {
        bal += op[i];
        p[i] = bal;
        ord[p[i]].push_back(i);
        bal -= cl[i];
    }
    //sort(ord.begin(), ord.end());
    rep(i, 0, n + 1) {
        sort(ord[i].begin(), ord[i].end());
        for (int j : ord[i]) {
            pr[j] = get(0,j-1) + 1;
            update(j,pr[j]);
        }
    }
    fill(t, t + N + N, 0);
    rep(i, 0, n + 1) {
        reverse(ord[i].begin(), ord[i].end());
        for (int j : ord[i]) {
            sf[j] = get(j + 1, m) + 1;
            update(j, sf[j]);
        }
    }
    ans = 0;
    rep(i, 0, m + 1) {
        ans = max(ans, pr[i] + sf[i + 1]);
        if (debug) { cerr << " i= " << i << ' ' << pr[i] << ' ' << sf[i + 1] << endl; }
    }
    cout << ans << endl;
    return 0;
}

#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
#define ALL(x) (x.begin(), x.end())
#define mset(a,i) memset(a,i,sizeof(a))
#define rep(i,n) for(int i = 0;i < n;i ++)

const int N = 1e5 + 5;
const LL inf = 1LL << 60;
LL a[N], dp[N];
int l[N], r[N];
int main() {
    ios :: sync_with_stdio(false);
    cout << fixed << setprecision(16);
    int n, m, x, y;
    scanf("%d%d", &n, &m);
    rep(i, n) {
        scanf("%d%d", &x, &y);
        a[x] ++;
        a[y + 1] --;
    }
    for (int i = 1; i <= m; i ++) {
        a[i] += a[i-1];
    }
    rep(i, N) dp[i] = inf;
    for (int i = 1; i <= m; i ++) {
        int k = upper_bound(dp, dp + m, a[i]) - dp;
        l[i] = k;
        dp[k] = a[i];
    }
    rep(i, N) dp[i] = inf;
    reverse(a + 1, a + 1 + m);
    for (int i = 1; i <= m; i ++) {
        int k = upper_bound(dp, dp + m, a[i]) - dp;
        r[m - i + 1] = k;
        dp[k] = a[i];
    }
    int answer = 1;
    for (int i = 1; i <= m; i ++) {
        answer = max(answer, l[i] + r[i] + 1);
    }
    printf("%d\n", answer);
    return 0;
}

#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define pii         pair<int,int>
#define vi          vector<int>
#define vii         vector<pii>
#define mi          map<int,int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define x           first
#define y           second
#define sz(x)       (int)x.size()
#define endl        '\n'
#define hell        1000000007
#define rep(i,a,b)  for(int i=a;i<b;i++)
using namespace std;
int n,m,p[100005],ans,N=100000;
int t[200005],lis[100005],lds[100005];
void modify(int P,int val){
    for(t[P+=N]=val;P>1;P>>=1) t[P>>1]=max(t[P],t[P^1]);
}
int query(int l,int r){
    int res=0;
    for(l+=N,r+=N+1;l<r;l>>=1,r>>=1){
        if(l&1) res=max(res,t[l++]);
        if(r&1) res=max(res,t[--r]);
    }
    return res;
}
void solve(){
    cin>>n>>m;
    rep(i,0,n){
        int L,R;
        cin>>L>>R;
        p[L]++;
        p[R+1]--;
    }
    rep(i,1,m+1){
        p[i]+=p[i-1];
    }
    for(int i=1;i<=m;i++){
        lis[i]=query(0,p[i])+1;
        modify(p[i],lis[i]);
    }
    memset(t,0,sizeof t);
    for(int i=m;i>=1;--i){
        lds[i]=query(0,p[i])+1;
        modify(p[i],lds[i]);
    }
    rep(i,1,m+1){
        ans=max(ans,lis[i]+lds[i]-1);
    }
    cout<<ans<<endl;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

// Made By Haireden Aibyn
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>

using namespace std;

#define fname ""
#define INF 2147483647
#define MOD 1000000007
#define mp make_pair
#define F first
#define S second
#define sc scanf
#define all(x) x.begin(), x.end()
#define size(x) int(x.size())
#define pr printf
#define deb(x) cerr << "[ " << #x << " = " << x << " ]"
#define pb push_back
#define ex exit(0)
#define y1 y4

typedef long long ll;
typedef unsigned long long ull;

const int N = 100500;

int t[N * 3], a[N], add[N], d[N], dr[N];
int sz;

int getmax(int l, int r) {
    l += sz;
    r += sz;
    int res = 0;
    while (l <= r) {
          if (l % 2 == 1) res = max(res, t[l]);
          if (r % 2 == 0) res = max(res, t[r]);
          l = (l + 1) >> 1;
          r = (r - 1) >> 1;
    }
    return res;
}

void upd(int p) {
     while (p) {
           p /= 2;
           t[p] = max(t[p + p], t[p + p + 1]);
     }
}

int main() {
    srand(time(NULL));
    #ifndef ONLINE_JUDGE
    freopen(fname".in", "r", stdin);
    freopen(fname".out", "w", stdout);
    #endif
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        int l, r;
        cin >> l >> r; add[l]++, add[r + 1]--;
    }
    int now = 0;
    for (int i = 1; i <= m; i++)
        now += add[i], a[i] = now;
    n++;
    sz = 1;
    while(sz < n) {
        sz*=2;
    }
    for (int i = 1; i <= m; i++) {
        d[i] = getmax(0, a[i]) + 1;
        t[sz + a[i]] = max(t[sz + a[i]], d[i]);
        upd(sz + a[i]);
    }
    reverse(a + 1, a + 1 + m);
    int ans = 0;
    for (int i = 1; i <= sz + sz; i++) t[i] = 0;
    for (int i = 1; i <= m; i++) {
        dr[i] = getmax(0, a[i]) + 1;
         t[sz + a[i]] = max(t[sz + a[i]], dr[i]);
         upd(sz + a[i]);
         ans = max(ans, d[m - i + 1] + dr[i] - 1);
    }
    cout << ans;
    #ifndef ONLINE_JUDGE
       cerr << clock() << " ms";
    #endif
    return 0;
}

/////////////////////////   _LeMur_
#include <iostream>
#include <algorithm>
#include <time.h>
#include <stack>
#include <string>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>

using namespace std;

const int N = 100005;
const int inf = 1000 * 1000 * 1000;
const int mod = 1000 * 1000 * 1000 + 7;

int n , m;
int a[N] , b[N] , c[N];
multiset <int> q;
multiset <int>::iterator it;
int pref[N] , suf[N];

int t[4 * N];

void build(int v,int s,int e){
    t[v] = 0;
    if(s == e)return ;
    int m = (s + e) / 2;
    build(2*v , s , m);
    build(2*v+1 , m+1 , e);
}

void update(int v,int s,int e,int pos,int val){
    if(s == e){
        t[v] = max(t[v] , val);
        return ;
    }
    int m = (s + e) / 2;
    if(pos <= m)
        update(2*v , s , m , pos , val);
    else
        update(2*v+1 , m+1 , e , pos , val);
    t[v] = max(t[2*v] , t[2*v+1]);
}

int get(int v,int s,int e,int l,int r){
    if(l > r)return 0;
    if(s == l && e == r)return t[v];
    int m = (s + e) / 2;
    return max( get(2*v , s , m , l , min(r , m)) , get(2*v+1 , m+1 , e , max(m+1 , l) , r) );
}

int main(){
    scanf("%d%d",&n,&m);
    int sz = 0;
    for(int i=1;i<=n;i++){
        int l , r;
        scanf("%d%d",&l,&r);
        b[l]++;
        c[r + 1]--;
    }
    int sum = 0;
    for(int i=1;i<=m;i++){
        sum += b[i] + c[i];
        a[i] = sum;
    }
    for(int i=1;i<=m;i++){
        pref[i] = get(1 , 0 , n - 1 , 0 , a[i]) + 1;
        update(1 , 0 , n - 1 , a[i] , pref[i]);
    }
    build(1 , 0 , n - 1);
    for(int i=m;i>=1;i--){
        suf[i] = get(1 , 0 , n - 1 , 0 , a[i]) + 1;
        update(1 , 0 , n - 1 , a[i] , suf[i]);
    }
    int answ = 0;
    for(int i=1;i<=m;i++){
        answ = max(answ , pref[i] + suf[i] - 1);
    }
    cout<<answ<<endl;
    return 0;
}

/*
5 5
1 3
2 3
3 3
4 5
4 4
*/

#include <bits/stdc++.h>
using namespace std;

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
	return os<<vc<t>(all(a));
}

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

template<class t>
void print(t x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<"\n";
	#else
	cout<<"Yes"<<"\n";
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<"\n";
	#else
	cout<<"No"<<"\n";
	#endif
	if(ex)exit(0);
}
void possible(bool ex=true){
	#ifdef CAPITAL
	cout<<"POSSIBLE"<<"\n";
	#else
	cout<<"Possible"<<"\n";
	#endif
	if(ex)exit(0);
}
void impossible(bool ex=true){
	#ifdef CAPITAL
	cout<<"IMPOSSIBLE"<<"\n";
	#else
	cout<<"Impossible"<<"\n";
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class t>
int lwb(const vc<t>&v,const t&a){
	return lower_bound(all(v),a)-v.bg;
}

//VERIFY: yosupo
//CF Global3 H
//ARC073 F
//point update
template<class T,class F>
struct SegTree{
	vc<T> buf;
	int s;
	const F f;
	const T g;
	SegTree(F ff,T gg):f(ff),g(gg){}
	void init(const vc<T>& d){
		int n=d.size();
		s=1;
		while(s<n)s*=2;
		buf.resize(s*2,g);
		rep(i,n)
			buf[i+s]=d[i];
		gnr(i,1,s)
			u(i);
	}
	SegTree(const vc<T>& d,F ff,T gg):f(ff),g(gg){
		init(d);
	}
	void u(int i){
		buf[i]=f(buf[i*2],buf[i*2+1]);
	}
	void set(int i,T t){
		i+=s;
		buf[i]=t;
		while(i>>=1)u(i);
	}
	void upd(int i,T t){
		i+=s;
		buf[i]=f(buf[i],t);
		while(i>>=1)u(i);
	}
	T get(int b,int e,int l,int r,int i){
		if(e<=l||r<=b)return g;
		if(b<=l&&r<=e)return buf[i];
		int m=(l+r)/2;
		return f(get(b,e,l,m,i*2),get(b,e,m,r,i*2+1));
	}
	T get(int b,int e){
		return get(b,e,0,s,1);
	}
};
template<class T,class F>
SegTree<T,F> segtree(const vc<T>& d,F f,T g){
	return SegTree<T,F>(d,f,g);
}

vi waf(vi a){
	int vmax=*max_element(all(a))+1;
	auto seg=segtree(vi(vmax),[](int x,int y){return max(x,y);},int(0));
	int n=si(a);
	vi res(n);
	rep(i,n){
		res[i]=seg.get(0,a[i]+1)+1;
		seg.upd(a[i],res[i]);
	}
	return res;
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);

	int n,m;cin>>n>>m;
	vi vs(m);
	rep(i,n){
		int l=read()-1,r=read();
		vs[l]++;
		if(r<m)vs[r]--;
	}
	rep(i,m-1)vs[i+1]+=vs[i];

	vi x=waf(vs);
	reverse(all(vs));
	vi y=waf(vs);
	reverse(all(y));
	int ans=0;
	rep(i,m)chmax(ans,x[i]+y[i]-1);
	print(ans);
}

#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/stack:16777216")
#include <string>
#include <vector>
#include <map>
#include <list>
#include <iterator>
#include <set>
#include <queue>
#include <iostream>
#include <sstream>
#include <stack>
#include <deque>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <utility>
#include <time.h>
using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define REP(i, N) FOR(i, 0, N)
#define RREP(i, N) RFOR(i, N, 0)
#define FILL(A,value) memset(A,value,sizeof(A))

#define ALL(V) V.begin(), V.end()
#define SZ(V) (int)V.size()
#define PB push_back
#define MP make_pair
#define Pi 3.14159265358979

typedef long long Int;
typedef unsigned long long UINT;
typedef vector <int> VI;
typedef pair <int, int> PII;

const int INF = 1000000000;
const int MAX = 200000;
const int MAX2 = 7000;
const int BASE = 1000000000;

struct Fenwick
{
	int n;
	int T[MAX];
	Fenwick(){}
	Fenwick(int len)
	{
		n = len;
		FOR (i,0,n)
			T[i] = 0;
	}

	int getmax (int r)
	{
		int result = 0;
		for (; r >= 0; r = (r & (r+1)) - 1)
			result = max (result, T[r]);
		return result;
	}

	void update (int i, int new_val)
	{
		for (; i < n; i = (i | (i+1)))
			T[i] = max (T[i], new_val);
	}
};

int n, m;
int A[MAX];
Fenwick FL;
Fenwick FR;
int L[MAX];
int R[MAX];

int main()
{
	//freopen("in.txt", "r", stdin);

	cin >> m >> n;
	FOR (i,0,m)
	{
		int l, r;
		scanf("%d %d", &l, &r);
		-- l;
		-- r;
		++ A[l];
		-- A[r+1];
	}

	FOR (i,1,n)
		A[i] = A[i-1] + A[i];

	FL = Fenwick(max(n, m));
	FR = Fenwick(max(n, m));

	FOR (i,0,n)
	{
		L[i] = FL.getmax(A[i]) + 1;
		FL.update(A[i], L[i]);
	}

	RFOR (i,n,0)
	{
		R[i] = FR.getmax(A[i]) + 1;
		FR.update(A[i], R[i]);
	}

	int res = 0;

	FOR (i,0,n)
	{
		res = max(res, L[i]+R[i]-1);
	}
	cout << res << endl;

    return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<ctime>
#include<string>
#include<cmath>
#include<algorithm>
#include<complex>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define LL long long
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
void getint(int &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
int n,m,x,y,tag[500010],ts,ans,bit1[500010],bit2[500010],a[500010],f[500010],g[500010],tmp[500010];
int lowbit(int x){
	return x&-x;
}
void add1(int x,int y){
	for (;x<=ts;x+=lowbit(x)) bit1[x]=max(bit1[x],y);
}
void add2(int x,int y){
	for (;x<=ts;x+=lowbit(x)) bit2[x]=max(bit2[x],y);
}
int que1(int x){
	int t=0;
	for (;x;x-=lowbit(x)) t=max(t,bit1[x]);
	return t;
}
int que2(int x){
	int t=0;
	for (;x;x-=lowbit(x)) t=max(t,bit2[x]);
	return t;
}
int main(){
	scanf("%d%d",&m,&n);
	FOR(i,1,m){
		getint(x),getint(y);
		++tag[x],--tag[y+1];
	}
	FOR(i,1,n) a[i]=a[i-1]+tag[i];
	FOR(i,0,m) tmp[++ts]=i;
	FOR(i,0,n) a[i]=lower_bound(tmp+1,tmp+ts+1,a[i])-tmp;
	add1(a[0],f[0]);
	add2(a[0],g[0]);
	FOR(i,1,n){
		f[i]=que1(a[i])+1;
		g[i]=que2(ts-a[i]+1)+1;
		add1(a[i],f[i]);
		add2(ts-a[i]+1,max(f[i],g[i]));
		ans=max(ans,f[i]);
		ans=max(ans,g[i]);
	}
	cout<<ans<<endl;
	return 0;
}

#pragma GCC optimize("O3", "unroll-loops")

#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <algorithm>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <sstream>
#include <cmath>
#include <tuple>
#include <random>
#include <bitset>

using namespace std;

#define FIXED cout << fixed << setprecision(15)
#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define RANDOM srand(85453532)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define popb pop_back
#define pf push_front
#define popf pop_front
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define eps 1e-9
#define mod 1000000007
#define inf 1000000000000000007ll
#define f first
#define s second
#define shuffle(a) \
    for (int i = 0; i < sz(a); ++i) \
        swap(a[i], a[rand() % sz(a)])

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmin(T &x, U y) {
    if (y < x) return x = y, true;
    return false;
}
template<class T, class U> inline bool ifmax(T &x, U y) {
    if (y > x) return x = y, true;
    return false;
}
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T> inline istream& operator>>(istream &stream, vector<T> &a) {
    for (auto &i : a) stream >> i;
    return stream;
}

const int N = 1e5 + 100;

struct Fenv {
    int fenv[N];
    void add(int r, int x) {
        for (; r < N; r |= r + 1) fenv[r] += x;
    }
    int get(int r) {
        int ans = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) ans += fenv[r];
        return ans;
    }
};

struct LIS {
    int val[N];
    LIS() {
        for (int i = 0; i < N; ++i) val[i] = mod;
    }
    int add(int x) {
        int l = -1, r = N - 1;
        while (r - l > 1) {
            int m = r + l >> 1;
            if (val[m] > x) r = m;
            else l = m;
        }
        val[r] = x;
        return r;
    }
};

signed main() {
    FAST; FIXED; RANDOM;
    int n, m;
    cin >> m >> n;
    if (n == 1) {
        cout << 0;
        return 0;
    }
    Fenv fenv;
    for (int i = 0; i < m; ++i) {
        int l, r;
        cin >> l >> r;
        --l, --r;
        fenv.add(l, 1);
        fenv.add(r + 1, -1);
    }
    vector<int> arr(n);
    for (int i = 0; i < n; ++i) arr[i] = fenv.get(i);
    vector<int> inc(n), dec(n);
    LIS pref, suff;
    for (int i = 0; i < n; ++i)
        inc[i] = pref.add(arr[i]);
    for (int i = n - 1; i >= 0; --i)
        dec[i] = suff.add(arr[i]);
    int ans = 0;
    for (int i = 0; i < n; ++i) checkmax(ans, inc[i] + dec[i] + 1);
    cout << ans;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;

int N, M;

struct Fenwick {
    vector<int> tree;
    void init() {
        tree = vector<int>(M + 1, 0);
    }
    void upd(int idx, int val) {
        for(int i = idx + 1; i <= M; i += (i & -i)) tree[i] += val;
    }
    int quer(int a) {
        int ret = 0;
        for(int i = a + 1; i >= 1; i -= (i & -i)) ret += tree[i];
        return ret;
    }
} fwt;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * N, 0);
    }
    void upd(int idx, int val, int l, int r, int n) {
        if(idx < l || r < idx) return;
        if(l == r) {
            tree[n] = max(tree[n], val);
            return;
        }
        int m = (l + r)>>1;
        upd(idx, val, l, m, 2*n);
        upd(idx, val, m + 1, r, 2*n + 1);
        tree[n] = max(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 0;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return max(L, R);
    }
} bit;

int A[100010], dp1[100010], dp2[100010], mx1[100010], mx2[100010];

int main() {
    scanf("%d %d", &N, &M);

    fwt.init();
    for(int i = 0; i < N; i++) {
        int l, r; scanf("%d %d", &l, &r);
        l--; r--;

        fwt.upd(l, 1);
        fwt.upd(r + 1, -1);
    }

    for(int i = 0; i < M; i++) A[i] = fwt.quer(i);

    bit.init();
    for(int i = 0; i < M; i++) {
        dp1[i] = 1 + bit.quer(0, A[i], 0, N - 1, 1);
        bit.upd(A[i], dp1[i], 0, N - 1, 1);

        mx1[i] = dp1[i];
        if(i) mx1[i] = max(mx1[i], mx1[i - 1]);
    }
    bit.init();
    for(int i = M - 1; i >= 0; i--) {
        dp2[i] = 1 + bit.quer(0, A[i], 0, N - 1, 1);
        bit.upd(A[i], dp2[i], 0, N - 1, 1);

        mx2[i] = dp2[i];
        if(i != M - 1) mx2[i] = max(mx2[i], mx2[i + 1]);
    }

    int ans = 0;
    for(int i = 0; i < M; i++) {
        ans = max(ans, mx1[i] + mx2[i] - 1);
    }

    printf("%d", ans);
}

/**************************************************
    WhatTheFua
    Anan Schuett
    arnan_s@msn.com
**************************************************/

#define BK back()
#define BL for(int K = 1; K <= T; K++)
#define F first
#define INF 2147483647LL
#define LNF 8000000000000000000LL
#define P107 1000000007LL
#define P109 1000000009LL
#define PB push_back
#define PF push_front
#define I insert
#define E erase
#define S second
#define SZ size()
#define IT iterator
#define db double
#define ll long long int
#define mp make_pair

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int inp[100010];
int inp2[100010];

int dp[100010];
int dpn;

int lis[100010];
int lis2[100010];

int main()
{
	int n, k, i, a, b, s, m, e, res = 0;

	scanf("%d%d", &n, &k);

	for(i = 0; i < n; i++)
	{
		scanf("%d%d", &a, &b);

		inp[a]++;
		inp[b + 1]--;
	}

	for(i = 2; i <= k; i++)
	{
		inp[i] += inp[i - 1];
	}

	dp[1] = inp[1];
	lis[1] = 1;
	dpn = 1;

	for(i = 2; i <= k; i++)
	{
		if(inp[i] >= dp[dpn])
		{
			dpn++;
			dp[dpn] = inp[i];
			lis[i] = dpn;
		} else if(inp[i] < dp[1]) {
			dp[1] = inp[i];
			lis[i] = 1;
		} else {
			s = 1;
			e = dpn;

			while(e - s > 1)
			{
				m = (s + e) / 2;

				if(dp[m] > inp[i])
				{
					e = m;
				} else {
					s = m;
				}
			}

			s++;

			dp[s] = inp[i];
			lis[i] = s;
		}
	}

	for(i = 1; i <= k; i++)
	{
		inp2[i] = inp[k - i + 1];
		// printf("%d ", lis[i]);
	}

	dp[1] = inp2[1];
	lis2[1] = 1;
	dpn = 1;

	for(i = 2; i <= k; i++)
	{
		if(inp2[i] >= dp[dpn])
		{
			dpn++;
			dp[dpn] = inp2[i];
			lis2[i] = dpn;
		} else if(inp2[i] < dp[1]) {
			dp[1] = inp2[i];
			lis2[i] = 1;
		} else {
			s = 1;
			e = dpn;

			while(e - s > 1)
			{
				m = (s + e) / 2;

				if(dp[m] > inp2[i])
				{
					e = m;
				} else {
					s = m;
				}
			}

			s++;

			dp[s] = inp2[i];
			lis2[i] = s;
		}
	}

	// printf("\n");

	for(i = 2; i <= k; i++)
	{
		lis[i] = max(lis[i], lis[i - 1]);
	}

	for(i = 1; i <= k; i++)
	{
		res = max(res, lis[i] + lis2[k - i + 1] - 1);
		// printf("%d ", lis2[k - i + 1]);
	}

	printf("%d", res);
}
/*
===
2 4
1 2
3 4
---
4
===
4 6
1 3
2 3
4 6
5 6
---
5
===
*/

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
int static const N = 200010;

int a[N*10], vel;

void init(int q)
{
	int w = 1;
	while(w < q)
		w *= 2;
	vel = w;
}

void ubaci(int poz, int vr)
{
	int t = vel+poz;
	a[t] = vr;
	t /= 2;
	while(t)
	{
		a[t] = max(a[t*2], a[t*2+1]);
		t /= 2;
	}
}

int rmq(int cvor, int ll, int dd, int l, int d)
{
	if(dd < l || ll > d)
		return 0;
	if(ll >= l && dd <= d)
		return a[cvor];
	return max(rmq(cvor*2, ll, (ll+dd)/2, l, d), rmq(cvor*2+1, (ll+dd)/2+1, dd, l, d));
}

int rmq(int l, int d)
{
	return rmq(1, 0, vel-1, l, d);
}

int n, m, br[N], levo[N], desno[N];
pi niz[N];

int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		int x, y;
		scanf("%i%i",&x,&y);
		niz[2*i] = pi(x,-1);	// sa minusom su poceci, da bih mogao prvo njih da obradim
		niz[2*i+1] = pi(y,1);
	}

	sort(niz, niz+2*n);
	//for(int i=0;i<n;i++)
	//	printf("%i %i\n",niz[i])

	int q = 0, tr = 0;
	for(int i=1;i<=m;i++)
	{
		while(niz[q].first == i-1)
		{
			q++;
			tr--;
		}
		while(niz[q].first == i && niz[q].second == -1)
		{
			q++;
			tr++;
		}
		br[i] = tr;
	//	printf("%i\n",br[i]);
	}

	//printf("\n\n\n");
	init(m+5);
	for(int i=1;i<=m;i++)
	{
		levo[i] = rmq(0, br[i]) + 1;
		if(levo[i] > rmq(br[i], br[i]))
			ubaci(br[i], levo[i]);
	//	printf("%i\n",levo[i]);
	}

	for(int i=0;i<=vel*2;i++)
		a[i] = 0;

	//printf("\n");
	for(int i=m;i>=0;i--)
	{
		desno[i] = rmq(0, br[i]) + 1;
	//	printf("aa %i %i\n",br[i], rmq(0,br[i]));
		if(desno[i] > rmq(br[i], br[i]))
			ubaci(br[i], desno[i]);
	//	printf("%i\n",desno[i]);
	}
	int maxx = 0;
	for(int i=0;i<=m;i++)
		maxx = max(maxx, levo[i] + desno[i] -1);
	printf("%i\n",maxx);

	return 0;
}

#include<cstring>
#include<cstdio>
#include<algorithm>
#define fo(i,a,b)for(int i=a,E=b;i<=E;i++)
#define fd(i,a,b)for(int i=b,E=a;i>=E;i--)
#define min(a,b)(a<b?a:b)
#define max(a,b)(a>b?a:b)
#define ll long long
using namespace std;
const int N=1e5+5;
int n,m,x,y,d[N],t[N*4],t2[N*4];
int fi(int v,int l,int r,int x){
	if(r<=x)return t[v];
	int m=l+r>>1;
	if(x<=m)return fi(v<<1,l,m,x);
	int b=fi(v<<1|1,m+1,r,x);
	return max(b,t[v<<1]);
}
int fi2(int v,int l,int r,int x){
	if(x<=l)return max(t2[v],t[v]);
	int m=l+r>>1;
	if(x>m)return fi2(v<<1|1,m+1,r,x);
	int b=fi2(v<<1,l,m,x);
	b=max(b,t2[v<<1|1]);
	return max(t[v<<1|1],b);
}
void ch(int v,int l,int r,int x,int y){
	t[v]=max(t[v],y);
	if(l==r)return;
	int m=l+r>>1;
	if(x<=m)ch(v<<1,l,m,x,y);else ch(v<<1|1,m+1,r,x,y);
}
void ch2(int v,int l,int r,int x,int y){
	t2[v]=max(t2[v],y);
	if(l==r)return;
	int m=l+r>>1;
	if(x<=m)ch2(v<<1,l,m,x,y);else ch2(v<<1|1,m+1,r,x,y);
}
int main(){
//	freopen("a.in","r",stdin);
	scanf("%d%d",&n,&m);
	fo(i,1,n)scanf("%d%d",&x,&y),d[x]++,d[y+1]--;
	fo(i,1,m)d[i]+=d[i-1];
	fo(i,1,m){
		ch2(1,0,n,d[i],fi2(1,0,n,d[i])+1);
		ch(1,0,n,d[i],fi(1,0,n,d[i])+1);
	}
	printf("%d",max(t[1],t2[1]));
}

#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<cassert>
#include<map>
#include<string>
#include<iostream>
#include<ext/pb_ds/priority_queue.hpp>
#include<queue>
#include<stack>
#include<bitset>
#include<tr1/unordered_map>
#include<tr1/unordered_set>
#define pb push_back
#define all(a) a.begin(),a.end()
#define pointtype double
#define pointtype_INT 0
using namespace std;
using namespace tr1;
typedef long long LL;
typedef pair<int,int>pii;
typedef unsigned uint;
typedef unsigned long long uLL;
const double pi=acos(-1);
template<class T>
void Read(T &x){
	char c;
	bool f(0);
	while(c=getchar(),c!=EOF){
		if(c=='-')
			f=1;
		else if(c>='0'&&c<='9'){
			x=c-'0';
			while(c=getchar(),c>='0'&&c<='9')
				x=x*10+c-'0';
			ungetc(c,stdin);
			if(f)
				x=-x;
			return;
		}
	}
}
struct point{
	pointtype x,y;
	inline point(){
	}
	inline point(pointtype x,pointtype y=0):x(x),y(y){
	}
	inline point operator+(const point &a)const{
		return point(x+a.x,y+a.y);
	}
	inline point operator+=(const point &a){
		return *this=*this+a;
	}
	inline point operator-(const point &a)const{
		return point(x-a.x,y-a.y);
	}
	inline point operator-=(const point &a){
		return *this=*this-a;
	}
	inline bool operator<(const point &b)const{
		if(x==b.x)
			return y<b.y;
		return x<b.x;
	}
	inline bool operator==(const point &b)const{
		return x==b.x&&y==b.y;
	}
	#if pointtype_INT==1
		inline point operator*(const point &a)const{
			return point(1ll*x*a.x-1ll*y*a.y,1ll*x*a.y+1ll*y*a.x);
		}
		inline friend LL cross(const point &a,const point &b){
			return 1ll*a.x*b.y-1ll*a.y*b.x;
		}
		inline friend LL dot(const point &a,const point &b){
			return 1ll*a.x*b.x+1ll*a.y*b.y;
		}
	#else
		inline point operator*(const point &a)const{
			return point(x*a.x-y*a.y,x*a.y+y*a.x);
		}
		inline friend pointtype cross(const point &a,const point &b){
			return a.x*b.y-a.y*b.x;
		}
		inline friend pointtype dot(const point &a,const point &b){
			return a.x*b.x+a.y*b.y;
		}
	#endif
};
template<class T,class T2>
struct hashnode{
	T val;
	T2 v;
	hashnode *next;
};
template<class T,class T2>
inline int& addhash(int u,const T &val,T2 *&ecnt,T2 **adj){
	T2 *p=++ecnt;
	p->val=val;
	p->v=0;
	p->next=adj[u];
	adj[u]=p;
	return p->v;
}
template<class T,class T2,int MOD,int ss>
class hash_table{
	hashnode<T,T2>*adj[MOD],edge[ss+10],*ecnt;
	int sz;
	public:
	inline int Get_val(int x){
		return x%MOD;
	}
	#if pointtype_INT==1
		inline int Get_val(point x){
			return (x.x*998244353ll+x.y)%MOD;
		}
	#endif
	inline hash_table():ecnt(edge),sz(0){
		for(int i=0;i<MOD;i++)
			adj[i]=0;
	}
	inline int size(){
		return sz;
	}
	inline hashnode<T,T2>* hash(const T &x){
		int t=Get_val(x);
		for(hashnode<T,T2> *p=adj[t];p;p=p->next)
			if(p->val==x)
				return p;
		return 0;
	}
	inline int &operator[](const T &x){
		hashnode<T,T2> *p=hash(x);
		if(p)
			return p->v;
		return ++sz,addhash(Get_val(x)%MOD,x,ecnt,adj);
	}
	inline bool count(const T &x){
		return hash(x);
	}
	inline void clear(){
		ecnt=edge;
		int t=MOD>>2<<2,i;
		for(i=0;i<t;i+=4){
			adj[i]=0;
			adj[i+1]=0;
			adj[i+2]=0;
			adj[i+3]=0;
		}
		for(;i<MOD;i++)
			adj[i]=0;
		sz=0;
	}
};
template<int sz,int MOD>
struct Matrix{
	int a[sz][sz];
	inline Matrix(){
		memset(a,0,sizeof a);
	}
	inline Matrix(int){
		memset(a,0,sizeof a);
		for(int i=0;i<sz;i++)
			a[i][i]=1;
	}
	inline void clear(){
		memset(a,0,sizeof a);
	}
	inline Matrix operator *(const Matrix &b)const{
		static Matrix c;
		c.clear();
		int i,j,k;
		for(i=0;i<sz;i++)
			for(j=0;j<sz;j++)
				if(a[i][j])
					for(k=0;k<sz;k++)
						c.a[i][k]=(c.a[i][k]+1ll*a[i][j]*b.a[j][k])%MOD;
		return c;
	}
	inline Matrix &operator *=(const Matrix &b){
		return *this=*this*b;
	}
	friend Matrix quick_pow(Matrix a,int b){
		Matrix ret(1);
		while(b){
			if(b&1)
				ret*=a;
			a*=a;
			b>>=1;
		}
		return ret;
	}
};
struct cpx{
	double r,i;
	inline cpx(){
	}
	inline cpx(double r,double i=0):r(r),i(i){
	}
	inline cpx operator+(const cpx &a)const{
		return cpx(r+a.r,i+a.i);
	}
	inline cpx operator-(const cpx &a)const{
		return cpx(r-a.r,i-a.i);
	}
	inline cpx operator*(const cpx &a)const{
		return cpx(r*a.r-i*a.i,r*a.i+i*a.r);
	}
	inline cpx operator/(const double &a)const{
		return cpx(r/a,i/a);
	}
	inline cpx operator/(const cpx&a)const{
		return *this*cpx(a.r,-a.i)/(a.r*a.r+a.i*a.i);
	}
	inline cpx operator+=(const cpx &a){
		return *this=*this+a;
	}
	inline cpx operator-=(const cpx &a){
		return *this=*this-a;
	}
	inline cpx operator*=(const cpx &a){
		return *this=*this*a;
	}
	inline cpx operator/=(const cpx &a){
		return *this=*this/a;
	}
	inline cpx conj(){
		return cpx(r,-i);
	}
};
template<class T,int len>
struct polynomial{
	T a[len];
	inline void clear(){
		int t=len>>2<<2,i;
		for(i=0;i<t;i+=4){
			a[i]=0;
			a[i+1]=0;
			a[i+2]=0;
			a[i+3]=0;
		}
		for(;i<len;i++)
			a[i]=0;
	}
	inline polynomial operator+(const polynomial &b)const{
		static polynomial c;
		int t=len>>2<<2,i;
		for(i=0;i<t;i+=4){
			c.a[i]=a[i]+b.a[i];
			c.a[i+1]=a[i+1]+b.a[i+1];
			c.a[i+2]=a[i+2]+b.a[i+2];
			c.a[i+3]=a[i+3]+b.a[i+3];
		}
		for(;i<len;i++)
			c.a[i]=a[i]+b.a[i];
		return c;
	}
	inline polynomial operator+=(const polynomial &b){
		return *this=*this+b;
	}
	inline polynomial operator-(const polynomial &b)const{
		static polynomial c;
		int t=len>>2<<2,i;
		for(i=0;i<t;i+=4){
			c.a[i]=a[i]-b.a[i];
			c.a[i+1]=a[i+1]-b.a[i+1];
			c.a[i+2]=a[i+2]-b.a[i+2];
			c.a[i+3]=a[i+3]-b.a[i+3];
		}
		for(;i<len;i++)
			c.a[i]=a[i]-b.a[i];
		return c;
	}
	inline polynomial operator-=(const polynomial &b){
		return *this=*this-b;
	}
	inline polynomial operator*(const polynomial &b){
		static polynomial ret;
		ret.clear();
		for(int i=0;i<len;i++)
			for(int j=0;j<=i;j++)
				ret.a[i]+=a[j]*b.a[i-j];
		return ret;
	}
	inline void Antiderivative(int c){
		int i;
		for(i=len-1;i;i--)
			a[i]=a[i-1]/i;
		a[0]=c;
	}
	inline T Get_val(T c){
		T ret(a[0]);
		for(int i=1;i<len;i++){
			ret+=c*a[i];
			c*=c;
		}
		return ret;
	}
};
void fft(cpx *a,int N,int f){
	int i,j=0,k,t;
	for(i=1;i<N-1;i++){
		for(t=N;j^=t>>=1,~j&t;);
		if(i<j)
			swap(a[i],a[j]);
	}
	for(i=1;i<N;i<<=1){
		cpx wn(cos(pi/i),f*sin(pi/i));
		t=i<<1;
		for(j=0;j<N;j+=t){
			cpx w(1,0);
			for(k=0;k<i;k++,w*=wn){
				cpx x(a[j+k]),y(w*a[j+k+i]);
				a[j+k]=x+y,a[j+k+i]=x-y;
			}
		}
	}
	if(f==-1)
		for(i=0;i<N;i++)
			a[i].r/=N;
}
void mul(cpx *a,cpx *b,cpx *c,cpx *t,int N){
	int i,j;
	for(i=0;i<N;i++)
		t[i]=cpx(a[i].r,b[i].r);
	fft(t,N,1);
	for(i=0;i<N;i++){
		j=(N-i)&(N-1);
		c[i]=(t[i]*t[i]-(t[j]*t[j]).conj())*cpx(0,-0.25);
	}
	fft(c,N,-1);
	// c refer t
	//a[i]=(c[i]+c[k-i])/2
	//b[i]=-i(c[i]-c[k-i])/2
	//a[i]*b[i]=(c[i]*c[i]-c[k-i]*c[k-i])*((-i)/4)
}
namespace mypq{
	template<class T,class Container=std::vector<T>,class cmp=std::less<typename Container::value_type> >
	struct priority_queue{
		std::priority_queue<T,Container,cmp>ins,del;
		inline void push(T a){
			ins.push(a);
		}
		inline void erase(T a){
			del.push(a);
		}
		inline void pop(){
			while(!del.empty()&&ins.top()==del.top())
				ins.pop(),del.pop();
			ins.pop();
		}
		inline T top(){
			while(!del.empty()&&ins.top()==del.top())
				ins.pop(),del.pop();
			return ins.top();
		}
		inline T second_top(){
			T tmp=top(),ret;
			pop();
			ret=top();
			push(tmp);
			return ret;
		}
		inline void clear(){
			while(!ins.empty())
				ins.pop();
			while(!del.empty())
				del.pop();
		}
		inline int size(){
			return ins.size()-del.size();
		}
		inline bool empty(){
			return !size();
		}
	};
}
void exgcd(long long a,long long b,long long &d,long long &x,long long &y){
    if(!b){
        d=a;
        x=1;
        y=0;
        return;
    }
    exgcd(b,a%b,d,y,x);
    y-=a/b*x;
}
//template
#define MAXN 100000
int mx[2][MAXN*4+10],f[2][MAXN+10],ans;
int n,m,a[MAXN+10];
inline void update(int *mx,int i){
	mx[i]=max(mx[i<<1],mx[(i<<1)|1]);
}
inline void insert(int *mx,int i,int l,int r,int p,int val){
	if(l==r){
		mx[i]=max(mx[i],val);
		return;
	}
	int mid((l+r)>>1);
	if(p<=mid)
		insert(mx,i<<1,l,mid,p,val);
	else
		insert(mx,(i<<1)|1,mid+1,r,p,val);
	update(mx,i);
}
inline int get_mx(int *mx,int i,int l,int r,int ll,int rr){
	if(ll<=l&&r<=rr)
		return mx[i];
	if(ll>r||rr<l)
		return 0;
	int mid((l+r)>>1);
	return max(get_mx(mx,i<<1,l,mid,ll,rr),get_mx(mx,(i<<1)|1,mid+1,r,ll,rr));
}
int main()
{
	Read(n),Read(m);
	int l,r,i;
	for(i=1;i<=n;i++){
		Read(l),Read(r);
		a[l]++,a[r+1]--;
	}
	for(i=1;i<m;i++)
		a[i+1]+=a[i];
	for(i=1;i<=m;i++){
		f[0][i]=get_mx(mx[0],1,0,n,0,a[i])+1;
		f[1][i]=get_mx(mx[1],1,0,n,a[i],n)+1;
		insert(mx[0],1,0,n,a[i],f[0][i]);
		insert(mx[1],1,0,n,a[i],max(f[0][i],f[1][i]));
		ans=max(f[0][i],f[1][i]);
	}
	printf("%d\n",ans);
}

#include<bits/stdc++.h>
#define N 100005
int n,m,a[N],sum[N],ans;
class BIT
{
	int t[N];
public:
	int lowbit(int x){return x&(-x);}
	void add(int x,int y){for(int i=x;i<=n;i+=lowbit(i)) t[i]=std::max(t[i],y);}
	int ask(int x){int res=0;for(int i=x;i;i-=lowbit(i)) res=std::max(res,t[i]);return res;}
}T1,T2;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1,l,r;i<=n;i++) scanf("%d%d",&l,&r),a[l]++,a[r+1]--;
	for(int i=1;i<=m;i++) a[i]+=a[i-1];
	for(int i=1;i<=m;i++) a[i]++;
	for(int i=1;i<=m;i++) sum[i]+=T1.ask(a[i]),T1.add(a[i],sum[i]+1);
	for(int i=m,tmp;i;i--) tmp=T2.ask(a[i]),T2.add(a[i],tmp+1),sum[i]+=tmp;
	for(int i=1;i<=m;i++) ans=std::max(ans,sum[i]+1);
	printf("%d\n",ans);
}

// I make this just for fun because i'm done
// Aimi Haraguni >> Konomi Suzuki >> Yui >>  Ikimono Gakari >> Garnidelia >> Kalafina >> Eir Aoi.   .. dude?
// problems that involves any kind of persistent data structures are the best of the best, are not them?

// #pragma GCC optimize ("Ofast,unroll-loops")
// #pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define ff  first
#define ss second
#define tm1 first
#define tm2 second.first
#define tm3 second.second
#define sz(x) ll(x.size())
// #define fill(x, v) memset(x, v, sizeof(x))
#define all(v) (v).begin(), (v).end()
#define FER(i,a,b) for(int i=int(a); i< int(b); ++i)
#define IFR(i,a,b) for(int i=int(a); i>=int(b); --i )
#define fastio ios_base::sync_with_stdio(0); cin.tie(0)

#define N 2005
// #define M 19

// #define mod 998244353
#define mod1 1000000007
#define mod2 1000000009
#define bas 987625403
#define sqr(x) (x)*(x)
#define INF 1e9

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> ii;
typedef pair<ll, ii > tri;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> S_t;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

#define trace(...) fff(#__VA_ARGS__, __VA_ARGS__)
template<typename t> void fff(const char* x, t&& val1) { cout<<x<< " : "<<val1<<"\n";}
template<typename t1, typename... t2> void fff(const char* x, t1&& val1, t2&&... val2){
    const char* xd=strchr(x+1, ',');
    cout.write(x, xd-x)<<" : "<<val1<<" | ";
    fff(xd+1, val2...);
}

inline ll add(ll a, ll b, ll mod) { return a+b < mod? a+b : a+b-mod;}
inline ll rem(ll a, ll b, ll mod) { return a >= b? a - b: a- b + mod;}
inline ll mul(ll a, ll b, ll mod) { return (long long) a*b%mod;}
inline void Mul(ll &a, ll b, ll mod) { a = (long long) a*b%mod;}
inline ll bp(ll a, ll p, ll mod){
    ll ret;
    for(ret = 1; p; p>>=1, Mul(a, a, mod)) (p & 1) && (Mul(ret, a, mod), 1);
    return ret;
}

static inline void read(ll &result) {
    bool minus = false;
    char ch;
    ch = getchar();
    while (true) {
        if (ch == '-') break;
        if (ch >= '0' and ch <= '9') break;
        ch = getchar();
    }
    (ch == '-')? minus = true: result = ch-'0';
    while (true) {
        ch = getchar();
        if (ch < '0' or ch > '9') break;

        result = (result<<3)+ (result<<1) + (ch - '0');
    }
    if(minus) result = -result;
}

vi pos[1<<20];
struct ST{
    ll n, t[1<<20];
    inline ll Op(ll a, ll b) { return max(a, b);}
    inline void build() { IFR(i, n - 1, 1) t[i] = Op(t[i<<1], t[i<<1|1]);}
    inline void modify(ll p, ll val) { for(t[p += n] = val; p>>=1; ) t[p] = Op(t[p<<1], t[p<<1|1]);}
    inline ll que(ll l, ll r){
        ll ans = -INF;
        for(l += n, r += n; l < r; l>>=1, r>>=1){
            if(l&1) ans = Op(ans, t[l++]);
            if(r&1) ans = Op(t[--r], ans);
        }
        return ans;
    }
};

int main(){
    ll n, m; read(n), read(m);
    vi ar(m + 2, 0), cnt(m + 1, 0);
    FER(i, 0, n){
        ll l, r; read(l), read(r);
        ar[l]++, ar[r + 1]--;
    }
    ll acum = 0, top = 0;
    // vi frec(m + 1, 0);
    FER(i, 0, m + 1){
        acum += ar[i];
        cnt[i] = acum;
        // frec[cnt[i]]++;
    }
    // cnt es la secuencia
    auto build = [&](vi &vec){
        ST st;
        st.n = 1e5 + 1;
        FER(i, 0, st.n) st.t[i + st.n] = 0;
        st.build();
        ll n = sz(vec);
        vi dp(n, 0);
        FER(i, 0, n){
            ll val = vec[i];
            // auto cur = st.que(val, val + 1);
            auto ret = st.que(0, val + 1) + 1;
            st.modify(val, ret);
            dp[i] = st.que(0, st.n);
        }
        return dp;
    };
    vi ket, ret;
    FER(i, 1, m + 1) ket.pb(cnt[i]), ret.pb(cnt[i]);
    reverse(all(ret));
    auto dp1 = build(ket);
    auto dp2 = build(ret);
    ll jael = dp2[m - 1];
    FER(i, 0, m){
    	ll add;
    	if(m - i - 2 < 0) add = 0;
    	else add = dp2[m - i - 2];
    	// trace(dp1[i], add);
        jael = max(dp1[i] + add, jael);
    }
    cout<<jael<<"\n";
    return 0;
}

#include <bits/stdc++.h>

#define F first
#define S second
#define pb push_back
#define ll long long
#define ld long double
#define pii pair <int, int>
#define endl '\n'
//#define int long long

using namespace std;

const int mod = 1e9 + 7;
const int N = 1e5 + 5;

int cnt[N], reversecnt[N], pref[N], suff[N], ispref[N], issuff[N], anspref[N], anssuff[N];
int dp[N];
int cursz = 0;

int bin(int x) {
    int l = 0, r = cursz - 1;
    int res = -1;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (dp[mid] > x) {
            res = mid;
            r = mid - 1;
        } else l = mid + 1;
    }
    return res;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif // LOCAL
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        cnt[l]++;
        cnt[r + 1]--;
        if (l > 1) reversecnt[l - 1]--;
        reversecnt[r]++;
    }
    int cur = 0;
    for (int i = 1; i <= m; i++) cur += cnt[i], pref[i - 1] = cur;
    cur = 0;
    for (int i = m; i >= 1; i--) cur += reversecnt[i], suff[i - 1] += cur;
    reverse(suff, suff + m);
    for (int i = 0; i < m; i++) dp[i] = 1e9;
    dp[0] = pref[0], anspref[0] = 1, ispref[0] = 1;
    cursz = 1;
    for (int i = 1; i < m; i++) {
        if (pref[i] >= dp[cursz - 1]) {
            dp[cursz] = pref[i];
            anspref[i] = ++cursz;
            ispref[i] = 1;
            continue;
        }
        {
            int pos = bin(pref[i]);
            dp[pos] = pref[i];
            anspref[i] = cursz;
        }
    }
    for (int i = 0; i < m; i++) dp[i] = 1e9;
    dp[0] = suff[0], anssuff[0] = 1, issuff[0] = 1;
    cursz = 1;
    for (int i = 1; i < m; i++) {
        if (suff[i] >= dp[cursz - 1]) {
            dp[cursz] = suff[i];
            anssuff[i] = ++cursz;
            issuff[i] = 1;
            continue;
        }
        {
            int pos = bin(suff[i]);
            dp[pos] = suff[i];
            anssuff[i] = cursz;
        }
    }
    int res = 0;
    for (int i = 0; i < m; i++) {
        int cur = anspref[i] + anssuff[m - i - 1];
      //  cout << anspref[i] << " " << anssuff[m - i - 1] << " " << ispref[i]  << " " << issuff[m - i - 1] << endl;
        if (ispref[i] && issuff[m - i - 1]) cur--;
        res = max(res, cur);
    }
    cout << res << endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair <int,int> pii;

#define fi first
#define sc second
#define mp make_pair
#define pb push_back

const int MAXN=100005,INF=0x3f3f3f3f;

int n,d[MAXN],a[MAXN],C[MAXN],l[MAXN],r[MAXN];

void add(int x,int d)
{
	for (;x;x-=x&-x)
		C[x]=max(C[x],d);
}

int query(int x)
{
	int ret=0;
	for (;x<=n;x+=x&-x)
		ret=max(ret,C[x]);
	return ret;
}

void add2(int x,int d)
{
	for (;x<=n;x+=x&-x)
		C[x]=max(C[x],d);
}

int query2(int x)
{
	int ret=0;
	for (;x;x-=x&-x)
		ret=max(ret,C[x]);
	return ret;
}

int main()
{
	int m;
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		d[l]++;
		d[r+1]--;
	}
	for (int i=1;i<=m;i++)
		a[i]=a[i-1]+d[i];
	for (int i=1;i<=m;i++)
		a[i]++;
	for (int i=1;i<=m;i++)
	{
		l[i]=query2(a[i])+1;
		add2(a[i],l[i]);
	}
	memset(C,0,sizeof(C));
	for (int i=m;i>=1;i--)
	{
		r[i]=query2(a[i])+1;
		add2(a[i],r[i]);
	}
	int ans=0;
	for (int i=1;i<=m;i++)
		ans=max(ans,l[i]+r[i]-1);
	printf("%d",ans);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef	long long	ll;
typedef unsigned long long	ull;

#define		debug(x)    cout << #x << " = " << x << endl
#define     pb          push_back
#define 	mp			make_pair
#define     sz(x)       ((long long)(x.size()))
#define 	F			first
#define 	S			second

const int N = 1000 * 100 + 10;
const int MAX_X = 1000 + 20;
const int MAX_N = 100 + 20;
const int MOD = 1000 * 1000 * 1000 + 7;
const int INF = 1000 * 1000 * 1000 + 1;

int poww(int x, int y) {
    return (!y ?1: (y & 1 ?x * poww(x * x , y / 2): poww(x * x, y / 2)));
}

ll t[N * 4];
ll tdp[2][N];
ll dp[N];

void change(ll L, ll R, ll l, ll r, ll rt) {
    if (L == l && R == r) {
        t[rt]++;
        return ;
    }
    int mid = (l + r) / 2;
    if (R <= mid)
		change(L, R, l, mid, rt << 1);
    else if(L > mid)
		change(L, R, mid + 1, r, rt << 1 | 1);
    else {
        change(L, mid, l, mid, rt << 1);
        change(mid + 1, R, mid + 1, r, rt << 1 | 1);
    }
}

ll query(ll L, ll R, ll l, ll r, ll rt) {
    ll sum = t[rt];
    ll mid = (l + r) / 2;
    if (L == l && R == r);
    else if (R <= mid)
		sum += query(L, R, l, mid, rt << 1);
    else if (L > mid) sum += query(L, R, mid + 1, r, rt << 1 | 1);
    else {
        sum += query(L, mid, l, mid, rt << 1);
        sum += query(mid + 1, R, mid + 1, r, rt << 1 | 1);
    }
    return sum;
}

int a[N];

int bs(int len,int x) {
    int l = 0, r = len - 1;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (x >= dp[mid - 1] && x < dp[mid])
			return mid;
        else if(x < dp[mid - 1])
			r = mid - 1;
        else
			l = mid + 1;
    }
    return l;
}

void LIS(int n) {
    memset(dp, 0, sizeof(dp));
    dp[0] = a[0];
    tdp[0][0] = 1;
    int len = 1;
    int j;
    for (int i = 1; i < n; i++) {
        if (a[i] < dp[0])
			j = 0;
        else if (a[i] >= dp[len - 1])
			j = len++;
        else
			j = bs(len, a[i]);
        dp[j] = a[i];
        tdp[0][i] = len;
    }
    memset(dp, 0, sizeof(dp));
    len = 1;
    dp[0] = a[n - 1];
    tdp[1][0] = 1;
    for (int i = n - 2; i >= 0; i--) {
        if (a[i] < dp[0])
			j = 0;
        else if (a[i] >= dp[len - 1])
			j = len++;
        else
			j = bs(len, a[i]);
        dp[j] = a[i];
        tdp[1][i] = len;
    }
}

ll n, m;

void input() {
   cin >> n >> m;
   memset(t, 0, sizeof(t));
   for (int i = 1; i <= n; i++) {
        ll l, r;
        cin >> l >> r;
        change(l, r, 1, N, 1);
   }
   for (int i = 1; i <= m; i++)
        a[i - 1] = query(i, i, 1, N, 1);
}

void solve() {
   memset(tdp, 0, sizeof(tdp));
   memset(dp, 0, sizeof(dp));
   LIS(m);
   ll ans = 0;
   for(int i = 0; i < m; i++)
        ans = max(ans, tdp[0][i] + tdp[1][i] - 1);
   cout << ans << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cout.tie(0); cout.tie(0);
	input();
	solve();
	return 0;
}

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<bits/stdc++.h>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<bitset>
#include<unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include "boost/algorithm/string.hpp"
#define fio ios_base::sync_with_stdio(false)
#define mod 1000000007
#define mod1 mod
#define mod2 100000009
#define li long long int
#define ll int
#define readi(x) scanf("%d",&x)
#define  reads(x)  scanf("%s", x)
#define readl(x) scanf("%I64d",&x)
#define rep(i,n) for(i=0;i<n;i++)
#define revp(i,n) for(i=(n-1);i>=0;i--)
#define myrep1(i,a,b) for(i=a;i<=b;i++)
#define myrep2(i,a,b) for(i=b;i>=a;i--)
#define pb push_back
#define mp make_pair
#define fi first
#define sec second
#define si short int
#define MAXN 1000000000000000000
#define MINN -1000000000000000000
// #define INTMAX 1000001000
#define pii pair<ll,ll>
#define pdd pair<double,double>
#define pic pair<int,char>
#define N 300010
#define lgn 20
#define ddouble long double
#define minus minu
#define PI 3.1415926535
#define lgn 20

// #define INTMAX 200000000
// using namespace boost;
// #define si short int

using namespace std;
using namespace __gnu_pbds;
typedef priority_queue<pii, vector<pii> ,greater < pii > > min_pq;
// typedef priority_queue<pii, vector<pii> , greater<pii >  > min_pq;
ll toint(const string &s) {stringstream ss; ss << s; ll x; ss >> x; return x;}
string tostring ( ll number ){stringstream ss; ss<< number; return ss.str();}

// using namespace __gnu_pbds;
// typedef priority_queue<pair<ll,char> , vector<pair<ll , char> > > max_pq;
// typedef priority_queue<pii , vector<pii > ,greater<pii > > min_pq;
typedef tree<pii , null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update> OST;
// typedef priority_queue<pair < ll , pair < pii , ll > >  , vector<pair < ll , pair < pii , ll > >  > ,greater<pair < ll , pair < pii , ll > >  > > min_pq;
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cout << name << " : " << arg1 << std::endl;
        //use cerr if u want to display at the bottom
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif
#define nn 2000005
#define INTMAX 1000000000
#define eps 1e-9
ll lis[ N ],lds[ N ];
ll val[ N ];
ll b[ N ];
ll n,m;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    cin >> n >> m;
    for ( ll i = 1; i <= n; i ++)
    {
        ll l,r;
        cin >> l >> r;
        val[l]++;
        val[r+1]--;
    }
    ll pre  = 0,answer = 0;
    ll ma = 0;
    for ( ll i = 1; i <= m; i++)
    {
        pre += val[i];
        val[i] = pre;
    }
    for ( ll i = 1; i <= m; i++)
    {
        // trace(val[i]);
        lis[i] = upper_bound(b+1,b+answer+1,val[i])-b;
        answer = max(answer,lis[i]);
        b[lis[i]] = val[i];
        lis[i] = answer;
    }
    // trace(answer);
    memset(b,0,sizeof b);
    answer = 0;
    for ( ll i = (m); i >=1; i-- )
    {
        // trace(val[i]);
        lds[i] = upper_bound(b+1,b+answer+1,val[i])-b;
        answer = max(answer,lds[i]);
        b[lds[i]] = val[i];
        lds[i] = answer;
    }
    ll ans = 0;
    for (ll i = 0; i <= m+1; i ++)
    {
        // trace(i,lis[i],lds[i]);
        // ans = max(ans,lis[i]+lds[i]-1);
        if ( i )
        {
            ans = max(ans,lis[i]+lds[i]-1);
            ans = max(ans,lis[i-1]+lds[i+1]);
        }
        else
            ans = max(ans,lds[1]);
    }
    cout << ans;

}

#include<bits/stdc++.h>
#define pi acos(-1)
#define ll long long
#define pii pair<ll,ll>
#define debug(a) cout<<a<<'\n'
#define maxn 100009 /// I wanna be the wind
#define MOD 1000000007
#define F first
#define S second
#define rep(i, a, b) for(ll i = a; i < (b); ++i)
#define per(i, b, a) for(ll i = b-1; i>=a ; i--)
#define trav(a, x) for(auto& a : x)
#define allin(a , x) for(auto a : x)
#define all(x) begin(x), end(x)
#define sz(x) (ll)(x).size()
using namespace std;
const ll INF = 1e17 + 9;
ll n,m;
vector<int> num;
ll dp[maxn][2];
void solve(int tp){
    multiset < int > s;
    multiset < int > :: iterator it;
    if(tp==0){
        rep(i,1,m+1){
            s.insert(num[i]);
            it = s.upper_bound(num[i]);
            if(it != s.end())
                s.erase(it);
            dp[i][tp] = sz(s);
            }
        }
    else{
        per(i,m+1,1){
            s.insert(num[i]);
            it = s.upper_bound(num[i]);
            if(it != s.end())
                s.erase(it);
            dp[i][tp] = sz(s);
            }
        }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    ll acum[maxn];
    memset(acum,0,sizeof acum);
    rep(i,0,n){
        ll a,b;
        cin>>a>>b;
        acum[a]++;
        acum[b+1]--;
    }
    rep(i,1,m+2){
        acum[i] += acum[i-1];
    }
    rep(i,0,m+1){
        num.push_back(acum[i]);
    }
    solve(0);
    // cout<<"oi"<<endl;
    solve(1);
    ll ans=0;
    rep(i,1,m+1){
        ans = max({dp[i][0]+dp[i][1]-1,ans});
    }
    cout<<ans<<"\n";
    return 0;
}

// Believe in yourself...
#include<bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define PF push_front
#define POB pop_back
#define POF pop_front
#define F first
#define S second
#define sz(c) (c).size()
#define REP(i,n)  for(ll i=0;i<n;i++)
#define REPD(i,n) for(ll i=n-1;i>=0;i--)
#define FOR(i,a,b) for(ll i=a;i<=b;i++)
#define FORD(i,a,b) for(ll i=a;i>=b;i--)

#define bit(num,i) ((num>>i)&1)

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pll;

const ll inf=4e18;
const ll mod=1e9+7;
const ll maxn=1e5+10;

#pragma GCC Optimize("Ofast")

ll s[maxn],lst[maxn],a[maxn],ans,lis[maxn][2],mx;

int main(){
	ll n,m;cin>>n>>m;
	REP(i,n){
		ll a,b;cin>>a>>b;
		s[b]++;
		s[a-1]--;
	}
	ll sm=0;
	FORD(i,m,1){
		sm+=s[i];
		a[i]=sm;
	}

	fill(lst+1,lst+maxn,inf);
	mx=0;
	FOR(i,1,m){
		ll up=upper_bound(lst,lst+maxn,a[i])-lst;
		lst[up]=a[i];
		mx=max(mx,up);
		lis[i][0]=mx;
	}
	fill(lst+1,lst+maxn,inf);
	mx=0;
	FORD(i,m,1){
		ll up=upper_bound(lst,lst+maxn,a[i])-lst;
		lst[up]=a[i];
		mx=max(mx,up);
		lis[i][1]=mx;
	}

	ans=max(lis[m][0],lis[1][1]);
	FOR(i,1,m-1)
		ans=max(ans,lis[i][0]+lis[i+1][1]);

	cout<<ans;
}

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll, ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define ppi pair<pii,int>
#define pip pair<int,pii>
#define pdd pair<double, double>
#define f first
#define s second
#define MOD 1000000007
#define mkp make_pair
#define M_PI 3.14159265358979323846
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define LOR(i,l,r) for (ll i=l;i<=r;i++)
#define FORD(i,r,l) for (int i=r;i>=l;i--)
#define LORD(i,r,l) for (ll i=r;i>=l;i--)
#define INF 1000000000
#define CL(x) memset(x,0,sizeof(x))
#define DEB(x) cout << #x << " : " << x << '\n'
#define ALL(x) x.begin(), x.end()
#define SZ(x) x.size()
typedef long long ll;

#define MXN 100005
int N,M;
int A[MXN];
int Ad[MXN];
int L[MXN][2];
int Ans;

struct segtree
{
    segtree(){}
    void init(int N)
    {
        this->N=N;
        build(1,N,1);
    }
    void build(int l, int r, int id=1)
    {
        if(l==r)st[id]=0;
        else
        {
            int mid = (l+r)/2;
            build(l,mid,id<<1);
            build(mid+1,r,(id<<1)|1);
            up(id);
        }
    }
    void up(int id)
    {
        st[id]=max(st[id<<1], st[(id<<1)|1]);
    }
    int Max(int L, int R, int l, int r, int id=1)
    {
        if(r<L||R<l)return 0;
        if(L<=l&&r<=R)return st[id];
        int mid = (l+r)/2;
        return max(Max(L,R,l,mid,(id<<1)), Max(L,R,mid+1,r,(id<<1)|1));
    }
    void mod(int pos, int d, int l, int r, int id=1)
    {
        if(l==r&&l==pos)
        {
            st[id]=d;
            return;
        }
        int mid = (l+r)/2;
        if(pos>mid)mod(pos,d,mid+1,r,(id<<1)|1);
        else mod(pos,d,l,mid,(id<<1));
        up(id);
    }
    //helper functions
    int Max(int L, int R)
    {
        return Max(L,R,1,N);
    }
    void mod(int pos, int d)
    {
        mod(pos,d,1,N);
    }
    int N;
    static const int ST_MAXN = 100005;
    int st[ST_MAXN*4];
}segt;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin>>M>>N;
    int a,b;
    FOR(i,0,M-1)
    {
        cin>>a>>b;
        Ad[a]++;
        Ad[b+1]--;
    }
    int cur = 0;
    FOR(i,1,N)
    {
        cur+=Ad[i];
        A[i]=cur;
    }

    segt.init(M+1);
    FOR(i,1,N)
    {
        int Mx = segt.Max(1,A[i]+1);
        L[i][0]=Mx+1;
        segt.mod(A[i]+1,Mx+1);
    }
    segt.init(M+1);
    FORD(i,N,1)
    {
        int Mx = segt.Max(1,A[i]+1);
        L[i][1]=Mx+1;
        segt.mod(A[i]+1,Mx+1);
    }

    FOR(i,1,N)Ans=max( Ans, L[i][0]+L[i][1]-1 );
    cout<<Ans<<'\n';

    return 0;
}

#include <iostream>
#include <cstdio>
#include <sstream>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iterator>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define x0 abc
#define y0 ABC
#define x1 abcd
#define y1 ABCD
#define xn abcde
#define yn ABCDE

#define l_b lower_bound
#define u_b upper_bound

#define in insert
#define er erase

#define fi first
#define se second
#define m_p make_pair

#define p_b push_back
#define po_b pop_back

#define uns unsigned

#define ld long double
#define ll long long

#define cont continue
#define re return

#define MAXLL 9000000000000000000LL
#define MAXINT 2000000000

#define MINLL -9000000000000000000LL
#define MININT -2000000000

#define pi acos(-1.)

#define endl '\n'

#define OUT cout << "-------" << endl;

using namespace std;

using namespace __gnu_pbds;

typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

ll p[120001], f[120001], pref[120001], suff[120001], l, r, n, m, i, ans;

    ll get(ll n)
    {
        ll ans = 0;

        while (n >= 0) {
            ans = max(ans, f[n]);

            n &= n + 1;

            n--;
        }

        re ans;
    }

    void update(ll nom, ll val)
    {
        while (nom <= n) {
            f[nom] = max(f[nom], val);

            nom |= nom + 1;
        }
    }

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> m;

    for (i = 1; i <= n; i++) {
        cin >> l >> r;

        p[l]++;

        p[r + 1]--;
    }

    for (i = 1; i <= m; i++) p[i] += p[i - 1];

    for (i = 1; i <= m; i++) {
        pref[i] = get(p[i]) + 1;

        update(p[i], pref[i]);
    }

    for (i = 0; i <= n; i++) f[i] = 0;

    for (i = m; i >= 1; i--) {
        suff[i] = get(p[i]) + 1;

        update(p[i], suff[i]);
    }

    for (i = 0; i <= m; i++) ans = max(ans, pref[i] + suff[i + 1]);

    cout << ans << endl;

    re 0;
}

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <string>
#include <iomanip>
#include <cassert>

#define endl "\n"
#define mp make_pair
#define pii pair<int, int>

typedef long long LL;

const int N = (int)1e5 + 7;
const int INF = (int)1e9;

using namespace std;

template <typename T>
T sqr(T x) {
	return x * x;
}

int n, m, p[N][2];
int cnt[N] = {};
vector <pii> seg;

void calc_cnt() {
	sort(seg.begin(), seg.end());
	int val = 0, ind = 0;
	for (int i = 1; i <= m; i++) {
		while (ind < 2 * n && seg[ind].first == i && seg[ind].second == 0)
			val++, ind++;
		cnt[i] = val;
		while (ind < 2 * n && seg[ind].first == i && seg[ind].second == 1)
			val--, ind++;
	}
}

int up() {
	vector <int> dp(m + 1, INF), r1(m + 1), r2(m + 1);
	dp[0] = -1;
	for (int i = 1; i <= m; i++) {
		int l = 0, r = m + 1;
		while (r - l > 1) {
			int m = (r + l) / 2;
			if (dp[m] > cnt[i])
				r = m;
			else
				l = m;
		}
		r1[i] = l + 1;
		if (dp[l + 1] > cnt[i])
			dp[l + 1] = cnt[i];
	}
	fill(dp.begin(), dp.end(), INF);
	reverse(cnt + 1, cnt + m + 1);
	dp[0] = -INF;
	for (int i = 1; i <= m; i++) {
		int l = 0, r = m + 1;
		while (r - l > 1) {
			int m = (r + l) / 2;
			if (dp[m] > cnt[i])
				r = m;
			else
				l = m;
		}
		r2[i] = l + 1;
		if (dp[l + 1] > cnt[i])
			dp[l + 1] = cnt[i];
	}
	reverse(r2.begin() + 1, r2.end());
	reverse(cnt + 1, cnt + m + 1);
	int res = 0;
	for (int i = 1; i <= m; i++) {
		res = max(res, r1[i] + r2[i] - 1);
	}
	return res;
}

int down() {
	vector <int> dp(m + 1, INF), r1(m + 1), r2(m + 1);
	dp[0] = -1;
	for (int i = m; i > 0; i--) {
		int l = 0, r = m + 1;
		while (r - l > 1) {
			int m = (r + l) / 2;
			if (dp[m] > cnt[i])
				r = m;
			else
				l = m;
		}
		r1[i] = l + 1;
		if (dp[l + 1] > cnt[i])
			dp[l + 1] = cnt[i];
	}
	fill(dp.begin(), dp.end(), INF);
	dp[0] = -INF;
	reverse(cnt + 1, cnt + m + 1);
	for (int i = m; i > 0; i--) {
		int l = 0, r = m + 1;
		while (r - l > 1) {
			int m = (r + l) / 2;
			if (dp[m] > cnt[i])
				r = m;
			else
				l = m;
		}
		r2[i] = l + 1;
		if (dp[l + 1] > cnt[i])
			dp[l + 1] = cnt[i];
	}
	reverse(r2.begin() + 1, r2.end());
	reverse(cnt + 1, cnt + m + 1);
	int res = 0;
	for (int i = 1; i <= m; i++) {
		res = max(res, r1[i] + r2[i] - 1);
	}
	return res;
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
#endif
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> p[i][0] >> p[i][1];
		seg.push_back(mp(p[i][0], 0));
		seg.push_back(mp(p[i][1], 1));
	}
	calc_cnt();
	int a1 = up(), a2 = down();
	cout << max(a1, a2);
}

#include <bits/stdc++.h>

#define fore(i, l, r) for(int i = int(l); i < int(r); ++i)
#define forn(i, n) fore(i, 0, n)
#define nfor(i, n) for(int i = int(n) - 1; i >= 0; --i)
#define for1(i, n) for(int i = 1; i < int(n); ++i)

#define mp make_pair
#define pb push_back
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define x first
#define y second
#define correct(x, y, xmax, ymax) ((x) >= 0 && (x) < (xmax) && (y) >= 0 && (y) < (ymax))

using namespace std;

template<typename T> inline T abs(T a){ return ((a < 0) ? -a : a); }
template<typename T> inline T sqr(T a){ return a * a; }
template<class T> T gcd(T a, T b) { return a ? gcd (b % a, a) : b; }
template<class T> T lcm(T a, T b) { return a / gcd (a, b) * b; }
template<class T> T sign(T a) { return a > 0 ? 1 : (a < 0 ? -1 : 0); }

template<class A, class B> ostream& operator <<(ostream &out, const pair<A, B> &p) {
    return out << "(" << p.x << ", " << p.y << ")";
};

template<class A> ostream& operator <<(ostream &out, const vector<A> &v) {
    out << "[";
    forn(i, sz(v)) {
        if(i)
            out << ", ";
        out << v[i];
    }
    return out << "]";
}

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;
typedef vector <int> vi;

const int dx[] = {-1, 0, 1,  0};
const int dy[] = { 0, 1, 0, -1};
const int dxK[] = {-1, -1, 0, 1, 1,  1,  0, -1};
const int dyK[] = { 0,  1, 1, 1, 0, -1, -1, -1};
const int dxKn[] = {-2, -1, 1, 2,  2,  1, -1, -2};
const int dyKn[] = { 1,  2, 2, 1, -1, -2, -2, -1};

const int INF = int(1e9) + 100;
const li INF64 = li(1e18) + 100;
const ld EPS = 1e-9;
const ld PI = acosl(-1.0);
const int N = 200 * 1000 + 9;

vector <int> lis(vector <int> v, bool strictly){
	vector <int> mn(sz(v), INF);
	mn[0] = -INF;
	vector <int> res(sz(v));
	forn(i, sz(v)){
		int pos = upper_bound(all(mn), v[i] - strictly) - mn.begin() - 1;
		res[i] = pos + 1;
		mn[pos + 1] = min(mn[pos + 1], v[i]);
	}

	return res;
}

int n, m;
pt p[N];
int d[N];
int a[N];

inline bool read() {
    if(!(cin >> n >> m))
    	return false;
    forn(i, n)
    	cin >> p[i].x >> p[i].y;
    return true;
}

inline void solve() {
	forn(i, n){
		++d[p[i].x - 1];
		--d[p[i].y];
	}
	int cur = 0;
	forn(i, m + 1){
		cur += d[i];
		a[i] = cur;
	}

	vector <int> va(a, a + m);
	vector <int> v1 = lis(va, false);
	reverse(all(va));
	vector <int> v2 = lis(va, false);
	reverse(all(v2));

	int res = -1;
	forn(i, m)
		res = max(res, v1[i] + v2[i] - 1);
	cout << res << endl;
}

int main() {
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    int tt = clock();
#endif
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(15);

    if(read()) {
        solve();

#ifdef _DEBUG
        cerr << "TIME = " << clock() - tt << endl;
        tt = clock();
#endif
    }

    return 0;
}

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>

using namespace std;
const int MAXN = 200010;
const int mod = 1e9+7;
#define INF 0x3f3f3f3f
#define LL long long

int cnt;
int mx = -INF, mn = INF;
int TT, T, n, m;

int bit[MAXN + 10];
	int la[100010];
	int ra[100010];
int mark[100010];
	int a[MAXN], g[MAXN];
int lowbit(int x)
{
    return x&(-x);
}

void add(int i,int x)
{
    while(i<=n)
    {
        bit[i]+=x;
        i+=lowbit(i);
    }
}

int sum(int i)
{
    int s=0;
    while(i>0)
    {
        s+=bit[i];
        i-=lowbit(i);
    }
    return s;
}

int binary_search(int key, int *g, int low, int high)
{
    while (low < high)
    {
        int mid = (low + high) >> 1;
        if (key >= g[mid])
            low = mid + 1;
        else
            high = mid;
    }
    return low;
}
int main()
{
    int ans, fla;
    int i, j, k, kk, l, r;

	cnt = 1;
	scanf("%d %d", &m, &n);

	for(i = 1; i <= m; i++)
	{
		scanf("%d %d", &l, &r);
		add(l, 1);
		add(r + 1, -1);
	}

	int len;
	g[1] = sum(1), len = 1;
	la[1] = 0;
	mark[1]++;
	for (i = 2; i <= n; i++)
	{
		la[i] = len;
		int a = sum(i);
        if (g[len] <= a)
		{
			j = ++len;
			mark[i]++;
		}
		else
            j = binary_search(a, g, 1, len + 1);
		g[j] = a;
    }
	g[1] = sum(n), len = 1;
	ra[1] = 0;
	mark[n]++;
	for (i = 2; i <= n; i++)
	{
		ra[i] = len;
		int a = sum(n - i + 1);
        if (g[len] <= a)
		{
			j = ++len;
			mark[n - i + 1]++;
		}
		else
            j = binary_search(a, g, 1, len + 1);
		g[j] = a;
    }

	int mxn = 0;

	for(i = 1; i <= n; i++)
	{
			if(mark[i])
				la[i]++;
		mxn = max(mxn, la[i] + ra[n - i + 1]);
//		cout << la[i] << ' ' <<ra[n - i + 1] << endl;
	}

	if(n != 1)
	{
		cout << mxn << endl;
	}
	else
	{
		cout << 0 << endl;
	}

	return 0;

}

#include <bits/stdc++.h>

using namespace std;
#define SZ(X) ((int)X.size())
#define mp make_pair
#define pb push_back
#define RALL(X) X.rbegin(),X.rend()
#define ALL(X) X.begin(),X.end()

using ll = long long ;
using ld = long double ;

const int N = 1E5 + 7;
const int INF = 0x3f3f3f3f;

int a[N];
int dp1[N];
int dp2[N];
int f1[N];
int f2[N];
int n, q;

int main()
{
    scanf("%d %d", &q, &n);
    for(int i = 1;i <= q;i ++) {
        int l, r;
        scanf("%d %d",&l, &r);
        a[l] ++;
        a[r+1] --;
    }
    for(int i = 1;i <= n;i ++) a[i] += a[i-1];
    int len = 1;
    dp1[1] = a[1];
    f1[1] = 1;
    for(int i = 2;i <= n;i ++) {
        if(a[i] >= dp1[len]) {
            dp1[++len] = a[i];
        } else {
            int pos = upper_bound(dp1 + 1, dp1 + 1 + len, a[i]) - dp1;
            dp1[pos] = a[i];
        }
        f1[i] = len;
    }
    len = 1;
    dp2[1] = a[n];
    for(int i = n - 1;i >= 1;i --) {
        if(a[i] >= dp2[len]) {
            dp2[++len] = a[i];
        } else {
            int pos = upper_bound(dp2 + 1, dp2 + 1 + len, a[i]) - dp2;
            dp2[pos] = a[i];
        }
        f2[i] = len;
    }
    int res = 0;
    for(int i = 1;i <= n;i ++) res = max(res, f1[i]+f2[i]-1);
    printf("%d\n", res);
    return 0;
}

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#define N 1000005
#define F(i, x, y) for (int i = x; i <= y; i++)
#define D(i, x, y) for (int i = x; i >= y; i--)

using namespace std;

int a[N], c[N], f[N], d[N];
int n, m, x, y, ans = 0;

int low(int x) { return x & (-x); }

void change(int x, int v)
{
	while (x < N)
		c[x] = max(c[x], v), x += low(x);
}

int query(int x)
{
	int mx = 0;
	while (x)
		mx = max(mx, c[x]), x -= low(x);
	return mx;
}

int main()
{
	//freopen("data.in", "r", stdin);
	//freopen("data.out", "w", stdout);

	scanf("%d %d\n", &n, &m);
	F(i, 1, n) scanf("%d %d", &x, &y), a[x]++, a[y + 1]--;
	int s = 0;
	F(i, 1, m)
		s += a[i], a[i] = s + 1;
	//F(i, 1, m) printf("%d ", a[i]); printf("\n");

	memset(c, 0, sizeof(c));
	F(i, 1, m)
		f[i] = query(a[i]) + 1, change(a[i], f[i]);

	memset(c, 0, sizeof(c));
	D(i, m, 1)
		d[i] = query(a[i]) + 1, change(a[i], d[i]);

	F(i, 1, m)
		ans = max(ans, f[i] + d[i] - 1);
	printf("%d\n", ans);

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define FILE_IN freopen("kotlin.in", "r", stdin);
#define FILE_OUT freopen("kotlin.out", "w", stdout);

#define fr(i,n) for(int i=0;i<n;i++)
#define frr(i,a,b) for(int i =a;i<=b;i++)
// for(auto it : g[i].nb)

typedef long long ll;
typedef long double ld;

#define pb push_back

#define all(a) a.begin(),a.end()

#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef tuple<ll,ll,ll> t3ll;

#define mt make_tuple
#define get(a,id) get<id>(a)

const long double PI = acos(-1.0l);
const ll MOD = 1e9+7;

//LONG_LONG_MAX
//-DBL_MAX

bool debug = 0;
#define printa(a) cout << #a << " = " << (a) << endl
#define prin(a) if(debug) cout << #a << " = " << (a) << endl
#define soprin(a) if(debug) cout << (a)
#define ppal(a)  if(debug) cout << #a << endl
#define prinsep if(debug) cout << "------" << endl
#define cendl if(debug) cout << endl
#define prinpar(p) if(debug) cout << #p << ".fi=" << (p).fi << " " << #p << ".se=" << (p).se << endl
#define print(tup) if(debug) cout << #tup << " = {" << get(tup,0) << ", " << get(tup,1) << ", " << get(tup,2) << "}\n"
#define prinv(v) if(debug){ cout << #v << ":" << endl; for(auto it = (v).begin(); it!=(v).end();it++){ cout << *it << " ";} cout << endl;}

const int N = 1e5+10;

int pre[N];

vector<int> tot;

int main(){
	//FILE_IN FILE_OUT
	int n, m;
	cin >> n >> m;

	fr(i,n){
		int l, r;
		scanf("%d%d", &l, &r);
		pre[l]++;
		pre[r+1]--;
	}

	int cur = 0;
	frr(i,1,m){
		cur+=pre[i];
		tot.pb(cur);
	}

	/*
	tot.clear();
	tot = {1,1,2,2,1};
	m = 5;
	*/

	map<int,int> mi,mid;

	int ans = 0;

	fr(i,m){
		{
			if(mi.size() and (--mi.end())->fi>=tot[i]){
				auto it = mid.lower_bound(tot[i]);
				int cur  = 0;
				if(it!=mid.end()) cur = it->se;

				mid[tot[i]] = max(cur+1,(--mi.end())->se+1);
				cur = mid[tot[i]];

				for(auto it = mid.find(tot[i]);it!=mid.end();){
					if(it==mid.begin()) break;
					it--;
					if(it->se>cur) break;
					it = mid.erase(it);
				}
			}
		}
		{
			int cur = 0;
			auto it = mi.lower_bound(tot[i]);
			if(it!=mi.begin()){
				it--;
				cur = it->se;
			}

			mi[tot[i]] = max(mi[tot[i]]+1,cur+1);
			cur = mi[tot[i]];

			for(auto it = ++mi.find(tot[i]);it!=mi.end();){
				if(it->se>mi[tot[i]]) break;
				it = mi.erase(it);
			}
		}
	}

	prin(mid.begin()->se);
	prin((--mi.end())->se);
	ans = max({ans,mid.begin()->se,(--mi.end())->se});

	reverse(all(tot));
	mi.clear();
	mid.clear();

	fr(i,m){
		{
			if(mi.size() and (--mi.end())->fi>=tot[i]){
				auto it = mid.lower_bound(tot[i]);
				int cur  = 0;
				if(it!=mid.end()) cur = it->se;

				mid[tot[i]] = max(cur+1,(--mi.end())->se+1);
				cur = mid[tot[i]];

				for(auto it = mid.find(tot[i]);it!=mid.end();){
					if(it==mid.begin()) break;
					it--;
					if(it->se>cur) break;
					it = mid.erase(it);
				}
			}
		}
		{
			int cur = 0;
			auto it = mi.lower_bound(tot[i]);
			if(it!=mi.begin()){
				it--;
				cur = it->se;
			}

			mi[tot[i]] = max(mi[tot[i]]+1,cur+1);
			cur = mi[tot[i]];

			for(auto it = ++mi.find(tot[i]);it!=mi.end();){
				if(it->se>mi[tot[i]]) break;
				it = mi.erase(it);
			}
		}
	}

	prin(mid.begin()->se);
	prin((--mi.end())->se);
	ans = max({ans,mid.begin()->se,(--mi.end())->se});

	cout << ans << endl;

	return 0;
}

#include <bits/stdc++.h>

#define F first
#define S second
#define pb push_back
#define ll long long
#define ld long double
#define endl '\n'
#define pii pair <int, int>
#define pll pair <ll, ll>
#define pld pair <ld, ld>
#define ull unsigned long long

using namespace std;

const int N = 5e5 + 7;
const int M = 5e4 + 5;
const int INF = 2e9 + 5;
const int rx[8] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int ry[8] = { 0, -1, 0, 1, 1, -1, 1, -1};

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    int n, m;
    cin >> n >> m;
    vector <int> f(m, 0);
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        f[x - 1]++;
        if (y < m) f[y]--;
    }
    for (int i = 0; i < m; i++) {
        if (i) f[i] += f[i - 1];
    }
    vector <int> l(m + 1, 1e9 + 7), r(m + 1, 1e9 + 7);
    vector <int> res1(m, 0), res2(m, 0);
    vector <int> kek1(m, 0), kek2(m, 0);
    l[0] = -1e9 - 7;
    r[0] = -1e9 - 7;
    for (int i = 0; i < m; i++) {
        int j = upper_bound(l.begin(), l.end(), f[i]) - l.begin();
        if (l[j - 1] <= f[i] && f[i] < l[j]) {
            l[j] = f[i];
            res1[i] = j;
            kek1[i] = 1;
        }
        j = upper_bound(r.begin(), r.end(), f[m - i - 1]) - r.begin();
        if (r[j - 1] <= f[m - i - 1] && f[m - i - 1] < r[j]) {
            r[j] = f[m - i - 1];
            res2[m - i - 1] = j;
            kek2[i] = 1;
        }
        if (i) {
            res1[i] = max(res1[i], res1[i - 1]);
            res2[m - i - 1] = max(res2[m - i - 1], res2[m - i]);
        }
    }
    int res = 0;
    for (int i = 0; i < m; i++) {
        int f = bool(kek1[i] && kek2[i]);
        //cout << i << ' ' << res1[i] << ' ' << res2[i] << ' ' << f << endl;
        res = max(res, res1[i] + res2[i] - f);
    }
    cout << res;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e5 + 1;

struct FENWICK_TREE{
	int ft[MAXN + 2];
	int N;

	void init(int n){
		N = n;
		for(int i = 1; i <= N; i++){
			ft[i] = 0;
		}
	}
	int bit(int x){
		return x & (-x);
	}
	int query(int i){
		int ret = 0;
		while(i > 0){
			ret = max(ret, ft[i]);
			i -= bit(i);
		}
		return ret;
	}
	void update(int i, int v){
		while(i <= N){
			ft[i] = max(ft[i], v);
			i += bit(i);
		}
	}
};

int incrementos[MAXN + 2];

int a[MAXN + 2];
int dp_crec[MAXN + 2];
int dp_decrec[MAXN + 2];

void calcula(int dp[], int n){ //
	FENWICK_TREE bit;
	bit.init(MAXN);
	for(int i = 1; i <= n; i++){
		dp[i] = bit.query(a[i]) + 1;
		bit.update(a[i], dp[i]);
	}
}

int max_subset(int n){
	calcula(dp_crec, n);
	reverse(a + 1, a + n + 1);
	calcula(dp_decrec, n);

	int mayor = 0, aux;
	for(int i = 1, j = n; i <= n; i++, j--){
		aux = dp_crec[i];
		aux += dp_decrec[j];
		aux--;
		mayor = max(mayor, aux);
	}
	return mayor;
}

void prepara(int m){
	int acc = 0;
	for(int i = 1; i <= m; i++){
		acc += incrementos[i];
		a[i] = acc;
		a[i]++;
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i++){
		int l, r;
		cin >> l >> r;
		incrementos[l]++;
		incrementos[r + 1]--;
	}
	prepara(m);

	cout << max_subset(m) << "\n";

	return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define F(i, n) for(int i = 0; i < n; ++ i)

int32_t main() {
    ios_base::sync_with_stdio(false);
    int n, m; cin >> n >> m;
    vector<int> v(m + 1);
    F(i, n) {
        int a, b; cin >> a >> b;
        ++ v[a - 1];
        -- v[b];
    }
    int tec = 0;
    F(i, m) {
        tec += v[i];
        v[i] = tec;
    }
    vector<int> A(m + 1, INT_MAX), B(m + 1, INT_MAX);
    A[0] = -1;
    B[0] = -1;
    vector<int> d(m + 1);
    F(i, m) {
        int t = upper_bound(A.begin(), A.end(), v[i]) - A.begin() - 1;
        d[i] = t + 1;
        A[t + 1] = min(A[t + 1], v[i]);
    }
    for(int i = m - 1; i >= 0; -- i) {
        int t = upper_bound(B.begin(), B.end(), v[i]) - B.begin() - 1;
        d[i] += t;
        B[t + 1] = min(B[t + 1], v[i]);
    }
    int ans = 0;
    F(i, m) {
        //cout << d[i] << ' ';
        if(d[i] > ans) ans = d[i];
    }
    //cout << endl;
    //F(i, m) cout << d1[i] << ' ';
    cout << ans;
}
//hello

#include <bits/stdc++.h>

using namespace std;

#define sqr(x) ((x) * (x))
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define fin(name) freopen(name, "r", stdin)
#define fout(name) freopen(name, "w", stdout)
#define I(x, a) for(auto x : a)
#define F(i, l, r) for(auto i = l; i < r; ++i)
#define E(i, l, r) for(auto i = l; i <= r; ++i)
#define DF(i, l, r) for(auto i = l; i >= r; --i)
#define clean(a) memset((a),0,sizeof (a))
#define sync ios_base::sync_with_stdio(0);cin.tie(0)
#define all(x) (x).begin(),(x).end()
#define ret return
#define cont continue
#define brk break
#define ins insert
#define sz(a) ((int)(a).size())

typedef long long ll;
typedef unsigned long long ull;
typedef long double dbl;
typedef pair <int, int> pii;

const int inf = (int)1e9;
const ll linf = (ll)1e18;
const int mod = (int)1e9 + 7;
const dbl eps = (dbl)1e-8;
const int maxn = (int)1e5 + 5;
const dbl pi = acos(-1);

int t[4 * maxn];
int n, m, s[maxn], ans[maxn];
pair <int, int> a[maxn];
int pos[maxn], mxpos[maxn], mnpos[maxn];

int getmx(int v, int l, int r, int tl, int tr) {
	if (tl > tr || l > r)
		return 0;
	if (l == tl && r == tr)
		return t[v];
	int m = (l + r) / 2;
	return max(getmx(2 * v, l, m, tl, min(m, tr)), getmx(2 * v + 1, m + 1, r, max(tl, m + 1), tr));
}

void upd(int v, int l, int r, int pos, int x) {
	if (pos < l || pos > r || l > r)
		return;
	t[v] = max(t[v], x);
	if (l == r)
		return;
	int m = (l + r) / 2;
	upd(2 * v, l, m, pos, x);
	upd(2 * v + 1, m + 1, r, pos, x);
}

int main() {
//    fin("t.in");
    sync;
    cin >> n >> m;
    F(i, 0, n) {
    	int l, r;
    	cin >> l >> r;
    	++s[l];
    	--s[r + 1];
    }
    E(i, 2, m) {
    	s[i] = s[i - 1] + s[i];
    }
    E(i, 1, m) {
    	a[i] = {s[i], i};
    }
    sort(a + 1, a + m + 1);
    clean(mxpos);
    E(i, 0, m)
    	mnpos[i] = m;
    E(i, 1, m) {
    	mxpos[a[i].X] = max(mxpos[a[i].X], i);
    	mnpos[a[i].X] = min(mnpos[a[i].X], i);
    	pos[a[i].Y] = i;
    }
    clean(t);
    clean(ans);
    E(i, 1, m) {
    	int x = 1 + getmx(1, 1, m, 1, mxpos[s[i]]);
//    	cout << i << " " << x << " " << pos[i] << " " << mxpos[s[i]] << endl;
    	upd(1, 1, m, pos[i], x);
    	ans[i] += x;
    }
    clean(t);
    int o = 0;
    DF(i, m, 1) {
    	int x = 1 + getmx(1, 1, m, 1, mxpos[s[i]]);
    	upd(1, 1, m, pos[i], x);
    	ans[i] += x;
//    	if (i <= 10)
//    		cout << i << " " << ans[i] << endl;
    	o = max(ans[i] - 1, o);
    }
    cout << o << endl;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
int x, n, m, ovl[100001], sl[100002], p, cum[100002], pum[100002], mv, maksic[1000002];
vector<pair<int, int> > vec;
pair<int, int> seks = {696969, -69};

int bs(int k) {
	int l = 0;
	int r = vec.size() - 1;
	int mid = (l + r)/2;
	while(l != r) {
		if(vec[mid].first <= k) l = mid;
		else if(vec[mid].first > k) r = mid;
		if(l == r - 1) {
			if(vec[l].first <= k) l = r;
			else r = l;
		}
		mid = (l + r)/2;
	}
	return mid;
}

int main() {
	cin >> n >> m;
	for(int i = 0; i < n; i++) {
		int a, b;
		cin >> a >> b;
		a--;
		sl[a]++;
		sl[b]--;
	}
	for(int i = 0; i < m; i++) {
		x += sl[i];
		ovl[i] = x;
	}
	for(int z = 0; z < 2; z++) {
		vec.push_back(make_pair(ovl[0], 0));
		vec.push_back(seks);
		for(int i = 1; i < m; i++) {
			p = bs(ovl[i]);
			if(p == vec.size() - 1) {
				vec.push_back(seks);
			} else {
				if(z%2) cum[vec[p].second] = p + 1;
				else pum[vec[p].second] = p + 1;
			}
			vec[p] = make_pair(ovl[i], i);
			for(int j = 0; j < vec.size(); j++) {
	//			cout << vec[j].first << " " <<  vec[j].second << '\n';
			}
		//	cout << '\n';
		}
		for(int i = vec.size() - 1; i >= 0; i--) {
			if(z%2) cum[vec[i].second] = i + 1;
			else pum[vec[i].second] = i + 1;
		}
		vec.clear();
		reverse(ovl, ovl + m);
	}
	maksic[0] = cum[0];
 	for(int i = 1; i < m; i++) {
 		maksic[i] = max(maksic[i - 1], cum[i]);
	}
	for(int i = 0; i < m; i++) {
		mv = max(mv, pum[i] + maksic[m - 1 - i]);
	}
	cout << mv - 1;
}

#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef unsigned int ui32;
const long long INFLL = 1e18;

using namespace std;

const int MAXN = 100000;

int tree[4 * MAXN + 1], m, dp[MAXN + 1];

void upd(int pos, int delta, int tv = 1, int tl = 0, int tr = MAXN) {
    if (tl == tr) {
        tree[tv] = delta;
    } else {
        int tm = (tl + tr) / 2;
        if (pos <= tm) {
            upd(pos, delta, tv * 2, tl, tm);
        } else {
            upd(pos, delta, tv * 2 + 1, tm + 1, tr);
        }
        tree[tv] = max(tree[tv * 2], tree[tv * 2 + 1]);
    }
}

int get(int l, int r, int tv = 1, int tl = 0, int tr = MAXN) {
    if (l > r) {
        return 0;
    } else if (l == tl && r == tr) {
        return tree[tv];
    } else {
        int tm = (tl + tr) / 2;
        return max(get(l, min(tm, r), tv * 2, tl, tm), get(max(tm + 1, l), r, tv * 2 + 1, tm + 1, tr));
    }
}

int c[MAXN + 10];

int main() {
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        ++c[l];
        --c[r + 1];
    }
    for (int i = 1; i <= m; i++) {
        c[i] += c[i - 1];
    }
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        int val = get(0, c[i]) + 1;
        upd(c[i], val);
        dp[i] = val;
    }
    for (int i = 1; i <= m; i++) {
        upd(c[i], 0);
    }
    reverse(c + 1, c + 1 + m);
    for (int i = 1; i <= m; i++) {
        int val = get(0, c[i]) + 1;
        upd(c[i], val);
        ans = max(ans, dp[m - i + 1] + val - 1);
    }
    cout << ans << "\n";
    return 0;
}

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#include<vector>
#include<set>
#define il inline
#define re register
using namespace std;
typedef long long ll;
const int N=1000001;
int Q,n,a[N],b[N],s[N],t[N],f[N],g[N],top,ans;
il void solve(int *a,int *s,int *f){
	s[top=0]=0;
	for(int i=1;i<=n;i++){
		int l=0,r=top,mid;
		while(l<r){
			mid=(l+r+1)/2;
			if(s[mid]<=a[i]) l=mid;
			else r=mid-1;
		}
		f[i]=l+1;
		if(l==top) s[++top]=a[i];
		else s[l+1]=min(s[l+1],a[i]);
	}
}
int main(){
	scanf("%d%d",&Q,&n);
	for(int i=1,x,y;i<=Q;i++){
		scanf("%d%d",&x,&y);
		a[x]+=1;a[y+1]-=1;
	}
	for(int i=1;i<=n;i++) a[i]+=a[i-1];
	for(int i=1;i<=n;i++) b[i]=a[n-i+1];
	solve(a,s,f);
	solve(b,t,g);
	for(int i=1;i<=n;i++) ans=max(ans,f[i]+g[n-i+1]-1);
	cout<<ans;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;

template <typename T> ostream& operator<<(ostream& out, const vector<T>& xs) { out << "[ " ; for (auto&& x : xs) out << x << ' '; return out << ']'; }
#define DBG(x) clog << #x ": " << (x) << endl

vector<int> incseqs(const vector<int>& tab) {

	auto rs = vector<int>(tab.size()+1, -1);
	rs[0] = 0;

	auto dyn = vector<int>();
	for (int i=0; i<static_cast<int>(tab.size()); ++i) {
		auto ept = lower_bound(dyn.begin(), dyn.end(), tab[i]+1);
		if (ept == dyn.end())
			dyn.push_back(tab[i]);
		else
			*ept = tab[i];
		rs[i+1] = (int)dyn.size();
	}

	return rs;

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n, m;
	cin >>n  >> m;
	vector<int> tab(m, 0);
	for (int i=0; i<n; ++i) {
		int l, r;
		cin >> l >> r;
		++tab[l-1];
		if (r < m)
			--tab[r];
	}
	vector<int> tab2(m, 0);
	tab2[0] = tab[0];
	for (int i=1; i<m; ++i)
		tab2[i] = tab2[i-1] + tab[i];

//DBG(tab2);

	auto dforw =  incseqs(tab2);
	reverse(tab2.begin(), tab2.end());
	auto dback = incseqs(tab2);
	reverse(tab2.begin(), tab2.end());
//	DBG(dforw);
//	DBG(dback);

	auto ans = 0;
	for (int i=0; i<m+1; ++i) {
		ans = max(ans, dforw[i] + dback[m-i]);
	}

	cout << ans << '\n';

}

#include <bits/stdc++.h>
using namespace std;

#define F(i, n) for(int i = 0; i < n; ++ i)

int32_t main() {
    ios_base::sync_with_stdio(false);
    int n, m; cin >> n >> m;
    vector<int> v(m + 1);
    F(i, n) {
        int a, b; cin >> a >> b;
        ++ v[a - 1];
        -- v[b];
    }
    int tec = 0;
    F(i, m) {
        tec += v[i];
        v[i] = tec;
    }
    vector<int> A(m + 1, INT_MAX), B(m + 1, INT_MAX);
    A[0] = -1;
    B[0] = -1;
    vector<int> d(m + 1);
    F(i, m) {
        int t = upper_bound(A.begin(), A.end(), v[i]) - A.begin() - 1;
        d[i] = t + 1;
        A[t + 1] = min(A[t + 1], v[i]);
    }
    for(int i = m - 1; i >= 0; -- i) {
        int t = upper_bound(B.begin(), B.end(), v[i]) - B.begin() - 1;
        d[i] += t;
        B[t + 1] = min(B[t + 1], v[i]);
    }
    int ans = 0;
    F(i, m) {
        //cout << d[i] << ' ';
        if(d[i] > ans) ans = d[i];
    }
    //cout << endl;
    //F(i, m) cout << d1[i] << ' ';
    cout << ans;
}

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <vector>
#include <set>
#include <utility>
#include <algorithm>

using namespace std;
int con[200005];
int how[200005]={0};
int ll[200005]={0};
int rr[200005]={0};
vector < int > all;
int main()
{
    int N,M,now=0,big=0,l=2e9,r=-2e9,ans=0,i,t;
    scanf("%d %d",&N,&M);
    for(i=1;i<=N;i++)
    {
        scanf("%d %d",&l,&r);
        how[l]++;
        how[r+1]--;
    }
    l=2e9;
    r=-2e9;
    for(i=1;i<=M;i++)
    {
        now+=how[i];
        big=max(big,now);
        con[i]=now;
    }

    all.clear();
    t=0;
    for(i=1;i<=M;i++)
    {
        if(upper_bound(all.begin(),all.end(),con[i])==all.end())
        {
            all.push_back(con[i]);
            t++;
        }
        else all[upper_bound(all.begin(),all.end(),con[i])-all.begin()]=con[i];
        ll[i]=t;
    }
    t=0;
    all.clear();
    for(i=M;i>=0;i--)
    {
        if(upper_bound(all.begin(),all.end(),con[i])==all.end())
        {
            t++;
            all.push_back(con[i]);
        }
        else all[upper_bound(all.begin(),all.end(),con[i])-all.begin()]=con[i];
        rr[i]=t;
    }
    for(i=0;i<=N;i++)
    {
        ans=max(ans,ll[i]+rr[i+1]);
    }
    printf("%d\n",ans);
    return 0;
}
/*
17 7
1 1
1 1
2 2
2 2
3 3
3 3
3
3
4 4
4 4
4 4
4 4
5 5
5 5 5
5
6 6
7 7
7 7
*/

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <unordered_map>
#include <cmath>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef pair<ll,ll> ii;
typedef vector<ii> vii;
#define rep(i,a,b) for(int i = a; i < b; i++)
#define per(i,a,b) for(int i = a; i >= b; i--)
#define inf 1000000000000000000
#define all(x) x.begin(),x.end()
#define sz(x) (ll)(x).size()
#define trav(a,x) for(auto& a : x)

vi lis,lds;

int CeilIndex(vi &v, ll l, ll r, ll key) {
    while (r-l > 1) {
      ll m = l + (r-l)/2;
      if (v[m] >= key) r = m;
      else l = m;
    }
    return r;
}

int LIS(vi &v) {
    if (v.size() == 0) return 0;

    std::vector<ll> tail(v.size(), 0);
    int length = 1;

    tail[0] = v[0];
    for (size_t i = 1; i < v.size(); i++) {
        if (v[i] < tail[0]) tail[0] = v[i];
        else if (v[i] > tail[length-1]) tail[length++] = v[i];
        else tail[CeilIndex(tail, -1, length-1, v[i])] = v[i];
        lds[i] = length;
    }
    return length;
}

int main(){
  ll n,m,cur = 0; cin >> m >> n;
  vi s,e,cnt; s.assign(m,0); e.assign(m,0); cnt.assign(n,0);
  rep(i,0,m){
    cin >> s[i] >> e[i];
  }
  sort(s.begin(),s.end());
  sort(e.begin(), e.end());
  /*
  rep(i,0,sz(s)) cout << s[i] << " ";
  cout << endl;
  rep(i,0,sz(e)) cout << e[i] <<" ";
  cout << endl;
  */
  ll cs = 0,ce = 0;
  rep(i,1,n+1){
    while (s[cs] == i){
      cur++; cs++;
    }
    while (e[ce] == i-1){
      cur--; ce++;
    }
    cnt[i-1] = cur;
  }
  /*
  rep(i,0,n) cout << cnt[i] << " ";
  cout << endl;
  */
  lis.assign(n,0);
  lds.assign(n,0);

  vi cnt2; ll add = 0;
  cnt2.push_back(cnt[0]);
  rep(i,1,n){
    if (cnt[i] == cnt[i-1]) {
      add++;
      cnt2.push_back(cnt[i]+add);
    } else {
      cnt2.push_back(cnt[i]+add);
    }
  }

  LIS(cnt2);
  rep(i,0,n) lis[i] = lds[i];
  reverse(cnt2.begin(),cnt2.end());
  LIS(cnt2);
  reverse(lds.begin(),lds.end());
  /*
  rep(i,0,n) cout << lis[i] << " ";
  cout << endl;
  rep(i,0,n) cout << lds[i] << " ";
  cout << endl;
  */
  ll ans = 0;
  rep(i,0,n) ans = max(ans,lis[i]+lds[i]);
  cout << ans << endl;

}

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int maxn=1e5+10;

int n,m,a[maxn],ma[maxn*4],ans,ma1[maxn*4];

void change(int pos,int x,bool b,int id=1,int s=0,int e=maxn)
{
    if(s+1==e)
    {
        if(b==1)
        ma[id]=x;
        else ma[id]--;
        return ;
    }
    int mid=(s+e)/2;
    if(pos<mid)
        change(pos,x,b,id<<1,s,mid);
    else change(pos,x,b,id<<1|1,mid,e);
    ma[id]=max(ma[id<<1],ma[id<<1|1]);
}

int get(int l,int r,int id=1,int s=0,int e=maxn)
{
    if(e<=l || r<=s)
        return 0;
    if(l<=s && e<=r)
        return ma[id];
    int mid=(s+e)/2;
    return max(get(l,r,id<<1,s,mid),get(l,r,id<<1|1,mid,e));
}

void change1(int pos,int x,bool b,int id=1,int s=0,int e=maxn)
{
    if(s+1==e)
    {
        if(b==1)
        ma1[id]=x;
        else ma1[id]--;
        return ;
    }
    int mid=(s+e)/2;
    if(pos<mid)
        change1(pos,x,b,id<<1,s,mid);
    else change1(pos,x,b,id<<1|1,mid,e);
    ma1[id]=max(ma1[id<<1],ma1[id<<1|1]);
}

int get1(int l,int r,int id=1,int s=0,int e=maxn)
{
    if(e<=l || r<=s)
        return 0;
    if(l<=s && e<=r)
        return ma1[id];
    int mid=(s+e)/2;
    return max(get1(l,r,id<<1,s,mid),get1(l,r,id<<1|1,mid,e));
}

int32_t main()
{
    ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
       // if(cin.peek()!='\n')
 //   ifstream cin("input.txt");
 //   ofstream cout("output.txt");
    cin>>n>>m;
    //if(n==1)
    for(int l,r,i=0;i<n;i++)
    {
        cin>>l>>r;
        a[l-1]++;
        a[r]--;
    }
    for(int i=1;i<m;i++)
    {
        a[i]=a[i]+a[i-1];
    }
  //  for(int i=0;i<m;i++)
//        cin>>a[i];
   // for(int i=1;i<=m;i++)
    //    cout<<a[i]<<' ';
  //  cout<<endl;
    for(int i=0;i<m-1;i++)
    {
        change(a[i],get(0,a[i]+1)+1,1);
    }
    for(int i=m-1;i>=0;i--)
    {
        ans=max(ans,get(0,a[i]+1)+get1(0,a[i]+1)+1);
        change1(a[i],get1(0,a[i]+1)+1,1);
        change(a[i],1,0);
    }
    cout<<ans;
}

#include <bits/stdc++.h>
#define ill int long long
#define fi first
#define se second
#define pb push_back
#define ld long double
using namespace std;
int n,q,i,t[400005],p[400005],k,v[100005],ans,dl[100005],dr[100005],z;
void push(int x,int l,int r)
{
    if (p[x]!=0)
    {
        t[x]+=p[x];
        if (l!=r)
        {
            int m=(l+r)/2;
            p[x*2]+=m-l+1;
            p[x*2+1]+=r-m;
        }
        p[x]=0;
    }
}
void update(int x, int l,int r,int tl,int tr)
{
    if (tl>tr)return ;
    push(x,l,r);
    if (l==tl && tr==r)
    {
        p[x]+=(r-l+1);
        push(x,l,r);
        return ;
    }
    int m=(l+r)/2;
    update(x*2,l,m,tl,min(m,tr));
    update(x*2+1,m+1,tr,max(tl,m+1),tr);
    t[x]=t[x*2]+t[x*2+1];
}
void build(int x,int l,int r)
{
    push(x,l,r);
    if (l==r)
    {
        k++;
        v[k]=t[x];
        return ;
    }
    int m=(l+r)/2;
    build(x*2,l,m);
    build(x*2+1,m+1,r);
}
int main()
{
    //freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
    ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
    cin>>q>>n;
    for (i=1;i<=q;i++)
    {
        int l,r;
        cin>>l>>r;
        update(1,1,n,l,r);
    }
    build(1,1,n);
    for (i=1;i<=n;i++)
    {
        dl[i]=dl[i-1];
        if (v[i]>=v[i-1])dl[i]++;
    }
    for (i=n;i>0;i--)
    {
        z=0;
        dr[i]=dr[i+1];
        if (v[i]>=v[i+1])dr[i]++;
        if (v[i]>=v[i-1] || v[i]>=v[i+1])z=1;
        ans=max(ans,dl[i-1]+dr[i+1]+z);
    }
    cout<<ans;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i < b; ++i)

const int N = 2e5;
int op[N], cl[N];

main() {
    int n, m;
    cin >> n >> m;
    rep(i,0,n) {
        int l, r;
        scanf("%d%d", &l, &r);
        op[l]++;
        cl[r]++;
    }
    int mx = 0, bal = 0;
    rep(i, 1, m + 1) {
        bal += op[i];
        mx = max(mx, bal);
        bal -= cl[i];
    }
    bal = 0;
    int cnt = 0;
    rep(i, 1, m + 1) {
        bal += op[i];
        if (bal==mx)cnt++;
        bal -= cl[i];
    }
    if (cnt < m) cnt++;
    cout << cnt << endl;
    return 0;
}

#include <bits/stdc++.h>

#define int         long long
#define uint        unsigned int
#define ld          long double
#define showoff     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb          push_back
#define pii         pair<int,int>
#define FOR(i,a,b)  for(int i=a;i<b;++i)
#define RFOR(i,a,b) for(int i=a;i>b;--i)
#define f           first
#define se          second
#define maxn        5000005
#define all(v)      v.begin(),v.end()
#define sz(x)       (int)x.size()
#define mod         998244353
#define pqueue      priority_queue<pii>
#define pdqueue     priority_queue< int,vector<int> ,greater< int >>

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int power(int a,int n)
{
    a %= mod;
    if(n == 1)return a;
    if(n == 0)return 1;
    if(n%2)return (a*(power((a*a)%mod,n/2)%mod))%mod;
    return power((a*a)%mod,n/2)%mod;
}

const int inf = (int) 1e18;

int inverse(int x){
    return power(x,mod-2)%mod;//little fermat....
}
void solve(){
    int n,m;
    cin >> n >> m;
    vector<int>p(m+5);
    FOR(i,1,n+1){
        int l,r;
        cin >> l >> r;
        p[r+1]--;
        p[l]++;
    }
    FOR(i,1,m+1)p[i] += p[i-1];
    set<int>s;
    FOR(i,1,m+1){
        s.insert(p[i]);
        if(p[i] == 0){cout << "0\n";return ;}
    }
    if(sz(s) == 1)cout << m << "\n";
    else cout << m-1 << "\n";
}

signed main()
{
    showoff;
    int T = 1;
    //cin >> T;
    FOR(t,1,T+1){
        solve();
        //cout << "\n";
    }
    return 0;
}
//*->for large size of matrix take int not long long if possible......
//*->always take maximum as inf for safer side ...

#include<bits/stdc++.h>
using namespace std;
#define dbg(x) cerr << #x << " = " << x << '\n';
#ifndef LOCAL
    #define cerr if(0) cerr
#endif
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mkt make_tuple
#define forn(i, n) for(int i = 0; i < int(n); i++)
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vll = vector<ll>;

const ld eps = 1e-8;
const ld Pi = acosl(-1);
const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const ll INFL = 9e18;

void solve();
int main()
{
    cout.sync_with_stdio(0);
    cout.tie(0);
    cout.precision(0);
    cout << fixed;
    int t = 1;
    #ifdef LOCAL
    assert(freopen("in", "r", stdin));
		freopen("out", "w", stdout);
		freopen("err", "w", stderr);
		cin >> t;
    #endif
    while(t--)
        solve();
}

vi starr(vi a)
{
	int n = a.size();
	vi d(1e5 + 2, INF);
	d[0] = 0;
	vi ans;
	int mx = 0;
	forn(i, n)
	{
		int j = upper_bound(all(d), a[i]) - d.begin();
		if(a[i] >= d[j - 1] && a[i] < d[j])
		{
			d[j] = a[i];
			mx = max(mx, j);
		}
		ans.pb(mx);
	}

	return ans;
}

void solve()
{
	int n, m;
	cin >> n >> m;
	vi del(m + 1, 0);
	forn(i, n)
	{
		int l, r;
		cin >> l >> r; l--; r--;
		del[l]++; del[r + 1]--;
	}
	vi a(m);
	int cur = 0;
	forn(i, m)
	{
		cur += del[i];
		a[i] = cur;
	}
	vi starrf = starr(a);
	reverse(all(a));
	vi starrb = starr(a);
	reverse(all(a));
	reverse(all(starrb));
	forn(i, m)
		cerr << a[i] << ' ';
	cerr << '\n';
	forn(i, m)
		cerr << starrf[i] << ' ';
	cerr << '\n';
	forn(i, m)
		cerr << starrb[i] << ' ';
	cerr << '\n';
	int mx = max(*max_element(all(starrf)), *max_element(all(starrb)));
	for(int i = 0; i < m; i++)
	{
		mx = max(mx, (i - 1 >= 0 ? starrf[i - 1] : 0) + (i + 1 < m ? starrb[i + 1] : 0));
	}
	cout << mx;
}

#include <algorithm>
#include <iostream>
#include <cstring>
#include <iomanip>
#include <vector>
using namespace std;

const int MAX_N = 1e5 + 15, MAX_C = 30;
int n, m, ans;
int psum[MAX_N];
int Arr[MAX_N];

int main() {
	ios::sync_with_stdio(false), cin.tie(0);
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		int l, r;
		cin >> l >> r;
		l--;
		psum[l]++;
		psum[r]--;
	}

	for (int i = 1; i < m; i++)
		psum[i] += psum[i - 1];

	memset(Arr, 127, sizeof Arr);
	Arr[0] = 0;
	for (int i = 0; i < m; i++) {
		int ind = upper_bound(Arr, Arr + MAX_N, psum[i]) - Arr;
		Arr[ind] = psum[i];
		ans = max(ans, ind);
	}

	for (int i = 0; i < m; i++)
		psum[i] *= -1;

	memset(Arr, 127, sizeof Arr);
	Arr[0] = 0;
	for (int i = 0; i < m; i++) {
		int ind = upper_bound(Arr, Arr + MAX_N, psum[i]) - Arr;
		Arr[ind] = psum[i];
		ans = max(ans, ind);
	}

	cout << ans << "\n";
	return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int tmp[100005];
int left[100005];
int right[100005];
int ceva[100005];
int N;
int M;
void u(int pos,int val){
    for(;pos <= M;pos += (-pos) & pos){
        ceva[pos] = max(ceva[pos],val);
    }
}
int q(int pos){
    int rez = 0;
    for(;pos;pos -= (-pos) & pos){
        rez = max(rez,ceva[pos]);
    }
    return rez;
}
int main()
{
    scanf("%d %d",&N,&M);
    for(int i = 1;i <= N;i++){
        int S,D;
        scanf("%d %d",&S,&D);
        tmp[S]++;
        tmp[D + 1]--;
    }
    for(int i = 1;i <= M;i++){
        tmp[i] += tmp[i - 1];
    }
    memset(ceva,0,sizeof(ceva));
    for(int i = 1;i <= M;i++){
        if(!tmp[i])continue;
        left[i] = q(tmp[i]) + 1;
        u(tmp[i],left[i]);
    }
    memset(ceva,0,sizeof(ceva));
    for(int i = M;i;i--){
        if(!tmp[i])continue;
        right[i] = q(tmp[i]) + 1;
        u(tmp[i],right[i]);
    }
    int rez = 0;
    for(int i = 1;i <= M;i++){
        if(tmp[i] == 0){
            continue;
        }
        rez = max(rez,max(left[i],right[i]));
    }
    printf("%d",rez);
    return 0;
}

// I make this just for fun because i'm done
// Aimi Haraguni >> Konomi Suzuki >> Yui >>  Ikimono Gakari >> Garnidelia >> Kalafina >> Eir Aoi.   .. dude?
// problems that involves any kind of persistent data structures are the best of the best, are not them?

// #pragma GCC optimize ("Ofast,unroll-loops")
// #pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>

#define pb push_back
#define ff  first
#define ss second
#define tm1 first
#define tm2 second.first
#define tm3 second.second
#define sz(x) ll(x.size())
// #define fill(x, v) memset(x, v, sizeof(x))
#define all(v) (v).begin(), (v).end()
#define FER(i,a,b) for(int i=int(a); i< int(b); ++i)
#define IFR(i,a,b) for(int i=int(a); i>=int(b); --i )
#define fastio ios_base::sync_with_stdio(0); cin.tie(0)

#define N 2005
// #define M 19

// #define mod 998244353
#define mod1 1000000007
#define mod2 1000000009
#define bas 987625403
#define sqr(x) (x)*(x)
#define INF 1e9

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef pair<ll, ll> ii;
typedef pair<ll, ii > tri;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> S_t;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

#define trace(...) fff(#__VA_ARGS__, __VA_ARGS__)
template<typename t> void fff(const char* x, t&& val1) { cout<<x<< " : "<<val1<<"\n";}
template<typename t1, typename... t2> void fff(const char* x, t1&& val1, t2&&... val2){
    const char* xd=strchr(x+1, ',');
    cout.write(x, xd-x)<<" : "<<val1<<" | ";
    fff(xd+1, val2...);
}

inline ll add(ll a, ll b, ll mod) { return a+b < mod? a+b : a+b-mod;}
inline ll rem(ll a, ll b, ll mod) { return a >= b? a - b: a- b + mod;}
inline ll mul(ll a, ll b, ll mod) { return (long long) a*b%mod;}
inline void Mul(ll &a, ll b, ll mod) { a = (long long) a*b%mod;}
inline ll bp(ll a, ll p, ll mod){
    ll ret;
    for(ret = 1; p; p>>=1, Mul(a, a, mod)) (p & 1) && (Mul(ret, a, mod), 1);
    return ret;
}

static inline void read(ll &result) {
    bool minus = false;
    char ch;
    ch = getchar();
    while (true) {
        if (ch == '-') break;
        if (ch >= '0' and ch <= '9') break;
        ch = getchar();
    }
    (ch == '-')? minus = true: result = ch-'0';
    while (true) {
        ch = getchar();
        if (ch < '0' or ch > '9') break;

        result = (result<<3)+ (result<<1) + (ch - '0');
    }
    if(minus) result = -result;
}

vi pos[1<<20];
struct ST{
    ll n, t[1<<20];
    inline ll Op(ll a, ll b) { return max(a, b);}
    inline void build() { IFR(i, n - 1, 1) t[i] = Op(t[i<<1], t[i<<1|1]);}
    inline ll que(ll l, ll r){
        ll ans = -INF;
        for(l += n, r += n; l < r; l>>=1, r>>=1){
            if(l&1) ans = Op(ans, t[l++]);
            if(r&1) ans = Op(t[--r], ans);
        }
        return ans;
    }
}st;

int main(){
    ll n, m; read(n), read(m);
    vi ar(m + 2, 0), cnt(m + 1, 0);
    FER(i, 0, n){
        ll l, r; read(l), read(r);
        ar[l]++, ar[r + 1]--;
    }
    ll acum = 0, top = 0;
    FER(i, 0, m + 1){
        acum += ar[i];
        cnt[i] = acum;
        top = max(top, cnt[i]);
    }
    vi dp(m + 1, 0);
    vi froz;
    FER(i, 1, m + 1){
        dp[i] = dp[i - 1];
        dp[i] += cnt[i] == top;
        if(cnt[i] == top) froz.pb(i);
    }
    // primer term = l - 1 - dp[l - 1]
    // segundo term = (m - r) - (dp[m] - dp[r]);
    // medio dp[r] - dp[l - 1];
    // l - 1 - 2*dp[l - 1];
    // -r + 2*dp[r];
    // m - dp[m];
    // itero por r
    st.n = m +  1;
    FER(i, 0, st.n) st.t[i + st.n] = -i + 2*dp[i];
    st.build();
    ll ans = 0;
    for(auto xd: froz){
        auto l = xd;
        auto base = l - 1 - 2*dp[l - 1];
        auto right = st.que(l + 1, st.n);
        auto everule = m - dp[m] + right + base;
        ans = max(ans, everule);
    }
    cout<<ans<<"\n";
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;

int N, M;

struct Fenwick {
    vector<int> tree;
    void init() {
        tree = vector<int>(M + 1, 0);
    }
    void upd(int idx, int val) {
        for(int i = idx + 1; i <= M; i += (i & -i)) tree[i] += val;
    }
    int quer(int a) {
        int ret = 0;
        for(int i = a + 1; i >= 1; i -= (i & -i)) ret += tree[i];
        return ret;
    }
} fwt;

struct BIT {
    vector<int> tree;
    void init() {
        tree = vector<int>(4 * N, 0);
    }
    void upd(int idx, int val, int l, int r, int n) {
        if(idx < l || r < idx) return;
        if(l == r) {
            tree[n] = max(tree[n], val);
            return;
        }
        int m = (l + r)>>1;
        upd(idx, val, l, m, 2*n);
        upd(idx, val, m + 1, r, 2*n + 1);
        tree[n] = max(tree[2*n], tree[2*n + 1]);
    }
    int quer(int a, int b, int l, int r, int n) {
        if(b < l || r < a) return 0;
        if(a <= l && r <= b) return tree[n];
        int m = (l + r)>>1;
        int L = quer(a, b, l, m, 2*n);
        int R = quer(a, b, m + 1, r, 2*n + 1);
        return max(L, R);
    }
} bit;

int A[100010], dp1[100010], dp2[100010], mx1[100010], mx2[100010];

int main() {
    scanf("%d %d", &N, &M);

    fwt.init();
    for(int i = 0; i < N; i++) {
        int l, r; scanf("%d %d", &l, &r);
        l--; r--;

        fwt.upd(l, 1);
        fwt.upd(r + 1, -1);
    }

    for(int i = 0; i < M; i++) A[i] = fwt.quer(i);

    int p = 0;
    for(int i = 1; i < M; i++) {
        if(A[i - 1] <= A[i]) p = i;
        else break;
    }
    int q = M - 1;
    for(int i = M - 2; i >= 0; i--) {
        if(A[i + 1] <= A[i]) q = i;
        else break;
    }

    if(p == M - 1 || q == 0) {
        printf("%d", M);
        return 0;
    }

    bit.init();
    for(int i = 0; i < M; i++) {
        dp1[i] = 1 + bit.quer(0, A[i], 0, N - 1, 1);
        bit.upd(A[i], dp1[i], 0, N - 1, 1);

        mx1[i] = dp1[i];
        if(i) mx1[i] = max(mx1[i], mx1[i - 1]);
    }
    bit.init();
    for(int i = M - 1; i >= 0; i--) {
        dp2[i] = 1 + bit.quer(0, A[i], 0, N - 1, 1);
        bit.upd(A[i], dp2[i], 0, N - 1, 1);

        mx2[i] = dp2[i];
        if(i != M - 1) mx2[i] = max(mx2[i], mx2[i + 1]);
    }

    int ans = 0;
    for(int i = 0; i < M; i++) {
        ans = max(ans, (i == 0? 0 : mx1[i - 1]) + (i == M - 1? 0 : mx2[i + 1]));
    }

    printf("%d", ans);
}

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include <memory.h>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <queue>
#include <complex>
#include <cstring>

using namespace std;

#define FILE_PREFIX "../../../../../../../../CompetitiveProgramming/CF/CF/"
#define FOR(i, a, b) for (int (i) = (a); (i) < (b); ++(i))
#define REP(i, n) FOR((i), 0, (n))
#define ll unsigned int
#define pb push_back

const int N = 1e5 * 5;
int n, m;
int L[N], R[N];
int s[N];
int fenv[N];
int f[N], p[N];

int find(int x) {
    int ret = 0;
    while (x >= 0) {
        ret = max(ret, fenv[x]);
        x = x & (x + 1);x--;
    }
    return ret;
}

void update(int x, int val) {
    while (x <= N-2) {
        fenv[x] = max(fenv[x], val);
        x |= (x + 1);
    }
}

int main() {
//    freopen(FILE_PREFIX"input.txt", "r", stdin);
    ios :: sync_with_stdio(false);

    cin >> n >> m;
    REP(i, n) {
        cin >> L[i] >> R[i];
        L[i]--; R[i]--;
        s[L[i]]++;
        s[R[i]+1]--;
    }

    int cur = 0;
    REP(i, m) {
        cur += s[i];
        s[i] = cur;
    }
    REP(i, m) {
        int r = find(s[i]);
        f[i] = max(f[i], r + 1);
        update(s[i], f[i]);
    }

    memset(fenv,0,sizeof(fenv));

    for (int i = m-1; i >= 0; --i) {
        int r = find(n-s[i]);
        p[i] = max(p[i], r + 1);
        update(n-s[i], p[i]);
    }

    int ans = 0;
    REP(i, m) {
        int res = f[i] + p[i] - 1;
        ans = max(ans, res);
    }

    cout << ans << endl;

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define st first
#define nd second
#define db(x) cerr << #x << " == " << x << endl
#define _ << ", " <<
const int N = 1e5 + 5;
int lr[N], rl[N];
int dp[N], lis[N], lis2[N];

int main(){
  int n, m;
  cin >> n >> m;
  for(int i = 0, l, r; i < n; i++)
    cin >> l >> r, lr[l]++, lr[r + 1]--, rl[r]++, rl[l - 1]--;

  for(int i = 1; i <= m; i++)
    lr[i] += lr[i - 1];
  for(int i = m - 1; i > 0; i--)
    rl[i] += rl[i + 1];

  for(int i = 1; i < m/2; i++)
    swap(rl[i], rl[m - i + 1]);

  memset(dp, 63, sizeof dp);
  for (int i=1; i<m; ++i) {
    int j = upper_bound(dp, dp+lis[i - 1], lr[i]) - dp;
    dp[j] = min(dp[j], lr[i]);
    lis[i] = max(lis[i - 1], j+1);
  }

  memset(dp, 63, sizeof dp);
  for (int i=1; i<m; ++i) {
    int j = upper_bound(dp, dp+lis2[i - 1], rl[i]) - dp;
    dp[j] = min(dp[j], rl[i]);
    lis2[i] = max(lis2[i - 1], j+1);
  }

  int ans = 0;
  for(int i = 1; i <= m; i++)
    ans = max(ans, lis[i] + lis2[m - i + 1] - 1);

  cout << ans << endl;
}

#include <bits/stdc++.h>
#define pb push_back
#define m_p make_pair
#define X first
#define Y second
using namespace std;
typedef long long ll;
const int maxn=1e5+50,M=1e9+7;
int seg[maxn*4],arr[maxn],n,m;
void upd(int pos,int val,int id=1,int s=0,int e=n+1){
	if(e-s<2){
		seg[id]=val;
		return;
	}
	int mid = (s+e)>>1;
	if(pos<mid)upd(pos,val,id<<1,s,mid);
	else upd(pos,val,id<<1|1,mid,e);
	seg[id]=max(seg[id<<1],seg[id<<1|1]);
}
int get(int l,int r,int id=1,int s=0,int e=n+1){
	if(s>=r || e<=l)return 0;
	if (l<=s && r>=e)return seg[id];
	int mid = (s+e)>>1;
	return max(get(l,r,id<<1,s,mid),get(l,r,id<<1|1,mid,e));
}
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		int x,y;
		cin>>x>>y;
		arr[x]++;
		arr[y+1]--;
	}
	for(int i=1;i<=m;i++){
		arr[i]+=arr[i-1];
	}
	for(int i=1;i<=m;i++){
		int val=get(0,arr[i]+1);
		upd(arr[i],val+1);
	}
	cout<<get(0,n+1);
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

int n, m, x, y, z, p, q, r;
int bittree[200000];

int axis[200000];

int fromshuru[200000];

void update(int pos, int val)
{
    int idx = pos;
    while(idx <= m + 2){
        bittree[idx] = max(bittree[idx], val);
        idx += (idx & -idx);
    }
}
int get(int pos)
{

    int idx = pos, re = 0;
    while(idx > 0){
        re = max(re, bittree[idx]);
        idx -= (idx & -idx);
    }
    return re;
}

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        scanf("%d %d",&x,&y);
        axis[y + 1]--;
        axis[x]++;
    }
    for(int i = 1; i <= m; i++){
        axis[i] += axis[i - 1];

        if(axis[i] == 0) continue;

        int xx = get(axis[i]);
        fromshuru[i] = xx + 1;
        update(axis[i], fromshuru[i]);
//        cout << i << ' ' << fromshuru[i] << endl;

    }

    memset(bittree, 0, sizeof(bittree));
    int ans = 0;

    for(int i = m; i >= 1; i--){
        if(axis[i] == 0) continue;
        int xx = get(axis[i]);
        xx = get(xx);
        ans = max(ans, fromshuru[i]+ xx);
    }
    cout << ans << endl;

    return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <string.h>

#define INF 2000000009
#define MAX_N 100005
#define f first
#define s second

using namespace std;

int cnt[MAX_N], DP1[MAX_N], DP2[MAX_N];
int N, M;

class SegTree {
    private:
        int tree[(1 << 19)];

    public:
        SegTree(int N) {

        }

        int get_val(int l, int r, int a, int b, int ind) {
            if (a <= l && r <= b) { return (tree[ind]); }
            if (a > r || b < l) { return (0); }

            int leftS = get_val(l, (l + r) / 2, a, b, 2 * ind);
            int rightS = get_val((l + r) / 2 + 1, r, a, b, 2 * ind + 1);

            return (leftS + rightS);
        }

        int query(int a, int b)
        { return (get_val(0, MAX_N, a, b, 1)); }

        void change_val(int l, int r, int newVal, int ind, int tmp) {
            if (tmp > r || tmp < l) { return; }
            if (l == r) {
                tree[ind] += newVal;
                return;
            }

            change_val(l, (r + l) / 2, newVal, 2 * ind, tmp);
            change_val((r + l) / 2 + 1, r, newVal, 2 * ind + 1, tmp);

            tree[ind] = tree[2 * ind] + tree[2 * ind + 1];
        }

        void update(int ind, int val)
        { change_val(0, MAX_N, val, 1, ind); }
};

class SegMax {
    private:
        int tree[(1 << 19)];

    public:
        SegMax(int N) {

        }

        int get_val(int l, int r, int a, int b, int ind) {
            if (a <= l && r <= b) { return (tree[ind]); }
            if (a > r || b < l) { return (0); }

            int leftS = get_val(l, (l + r) / 2, a, b, 2 * ind);
            int rightS = get_val((l + r) / 2 + 1, r, a, b, 2 * ind + 1);

            return (max(leftS, rightS));
        }

        int query(int a, int b)
        { return (get_val(0, MAX_N, a, b, 1)); }

        void change_val(int l, int r, int newVal, int ind, int tmp) {
            if (tmp > r || tmp < l) { return; }
            if (l == r) {
                tree[ind] = newVal;
                return;
            }

            change_val(l, (r + l) / 2, newVal, 2 * ind, tmp);
            change_val((r + l) / 2 + 1, r, newVal, 2 * ind + 1, tmp);

            tree[ind] = max(tree[2 * ind], tree[2 * ind + 1]);
        }

        void update(int ind, int val)
        { change_val(0, MAX_N, val, 1, ind); }
};

int main() {
    cin >> N >> M;

    SegTree seg(MAX_N);

    int a, b;
    for (int i = 0; i < N; i ++) {
        cin >> a >> b;
        seg.update(a - 1, 1);
        seg.update(b, -1);
    }

    int big = 0;

    for (int i = 0; i < M; i ++) {
        cnt[i] = seg.query(0, i);
        big = max(big, cnt[i]);
    }

    SegMax forward(MAX_N);
    SegMax backward(MAX_N);

    DP1[0] = 1;
    forward.update(cnt[0], 1);
    for (int i = 1; i < M; i ++) {
        DP1[i] = forward.query(0, cnt[i]) + 1;
        forward.update(cnt[i], DP1[i]);
    }

    DP2[M - 1] = 1;
    backward.update(cnt[M - 1], 1);
    for (int i = M - 2; i >= 0; i --) {
        DP2[i] = backward.query(0, cnt[i]) + 1;
        backward.update(cnt[i], DP2[i]);
    }

    int l1 = -1;
    int l2 = -1;
    int ans = 0;

    for (int i = 0; i < M; i ++) {
        if (cnt[i] == big) {
            ans = max(ans, DP1[i] + DP2[i] - 1);
            ans = max(ans, DP1[i] + DP2[i + 1]);
        }
    }

    for (int i = 0; i < M; i ++) {
        if (cnt[i] == big && l1 == -1)
            l1 = i;
        else if (cnt[i] == big && l1 != -1 && l2 == -1) {
            l2 = i;

            ans = max(ans, DP1[l1] + DP2[l2]);

            l1 = l2;
            l2 = -1;
        }
    }

    cout << ans << endl;
    return (0);
}

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,sse4,abm,popcnt,tune=native")
#pragma GCC optimize("unroll-loops,no-stack-protector")

#include <bits/stdc++.h>

//#define KOSTYL

using namespace std;

#define int long long
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define sz(v) (int)v.size()
#define pb push_back
#define mp make_pair

typedef long long ll;
typedef long double ld;

void run();

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    #ifdef KOSTYL
        freopen("input.txt", "r", stdin);
    #endif // KOSTYL
    run();
}

const int MAXN = 1e5 + 123;
int tree[4 * MAXN];

void clr(int tl = 0, int tr = MAXN, int v = 1) {
    if (tl == tr - 1) {
        tree[v] = 0;
        return;
    }
    int m = (tl + tr) / 2;
    clr(tl, m, v * 2);
    clr(m, tr, v * 2 + 1);
    tree[v] = max(tree[v * 2], tree[v * 2 + 1]);
}

int get(int l, int r, int tl = 0, int tr = MAXN, int v = 1) {
    if (l >= tr || tl >= r)
        return 0;
    if (l <= tl && tr <= r)
        return tree[v];
    int m = (tl + tr) / 2;
    return max(get(l, r, tl, m, v * 2), get(l, r, m, tr, v * 2 + 1));
}

void update(int pos, int x, int tl = 0, int tr = MAXN, int v = 1) {
    if (tl == tr - 1) {
        tree[v] = max(tree[v], x);
        return;
    }
    int m = (tl + tr) / 2;
    if (pos < m)
        update(pos, x, tl, m, v * 2);
    else
        update(pos, x, m, tr, v * 2 + 1);
    tree[v] = max(tree[v * 2], tree[v * 2 + 1]);
}

const int N = 1e5 + 124;

int cnt[N];
int mas[N];
int dp[N];

void run() {

    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        y++;
        cnt[x]++;
        cnt[y]--;
    }

    int cur = 0;
    for (int i = 1; i <= m; i++) {
        cur += cnt[i];
        mas[i] = cur;
    }

    int ans = 0;
    clr();
	for (int i = 1; i <= m; i++) {
        int left = get(0, mas[i] + 1);
        left++;
        ans = max(ans, left);
		dp[i] = left;
		update(mas[i], left);
	}

	clr();
	for (int i = m; i; i--) {
		int left = get(0, mas[i] + 1);
        ans = max(ans, dp[i] + left);
        update(mas[i], left + 1);
	}

	for (int i = 1; i <= m; i++) {
		mas[i] = n - mas[i] - 1;
	}

	clr();
	for (int i = 1; i <= m; i++) {
		int left = get(0, mas[i] + 1);
        left++;
        ans = max(ans, left);
		dp[i] = left;
		update(mas[i], left);
	}

	clr();
	for (int i = m; i; i--) {
		int left = get(0, mas[i] + 1);
        ans = max(ans, dp[i] + left);
        update(mas[i], left + 1);
	}

	cout << ans;

}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define forr(i,a,b) for(int i=(a); i <(b); i++)
#define forn(i,n) forr(i,0,n)
#define dforn(i,n) for(int i = n-1; i >= 0; i--)
#define zero(v) memset(v, 0, sizeof(v));
#define forall(it,v) for(auto it = v.begin(); it != v.end(); it++)
#define pb push_back
#define mp make_pair
#define sz(v) (int)(v).size()
#define debug(v) cerr << #v << ": " << (v) << endl;
#define debugc(c) forn(i, sz(c)) cerr << #c << "[" << i << "] = " << (c)[i] << endl;

// Para non-increasing, cambiar comparaciones y revisar busq binaria
// Given an array, paint it in the least number of colors so that each color turns to a non-increasing subsequence.
// Solution: Min number of colors = Length of the longest increasing subsequence
const int MAXN = 1e5 + 5;
const int INF = 1e9 + 5;
typedef pair<int,int> ii;
ii d[MAXN+1]; // d[i] = ultimo valor de la subsecuencia de tam i
int padres[MAXN];  // padres
vector<int> RES;// respuesta

int lis(vector<int> &a, vector<int> &dp){ // O(n logn)
    int N = sz(a);
    d[0] = ii(-INF, -1); forn(i, N) d[i+1]=ii(INF, -1);
    forr(i, 0, N){
        int j = upper_bound(d, d+N+1, ii(a[i], INF))-d;
        if (d[j-1].first <= a[i] && a[i] <= d[j].first){
            // padres[i]=d[j-1].second;
            d[j] = ii(a[i], i);
            dp[j] = i;
        }
    }

    // dforn(i, N+1) {
        // dp[i] = (d[i].first != INF ? i : 0);
    // }

    dforn(i, N+1) if(d[i].first!=INF){
        // rec(d[i].second);// reconstruir rta en RES
        // reverse(RES.begin(), RES.end());
        return i;//longitud
    }
    return 0;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    int n, m; cin >> n >> m;

        vector<int> diffarray(m+1, 0);
    forn(i, n) {
        int a, b; cin >> a >> b;
        diffarray[a-1]++;
        diffarray[b]--;
    }

    vector<int> cant(m, 0);
    forn(i, m) {
        cant[i] = (i != 0 ? cant[i-1] : 0) + diffarray[i];
    }

    // forr(i, 0, m) {
    //     cout << cant[i] << " ";
    // }
    // cout << "\n";

    vector<int> creciente(m+1);
    vector<int> decreciente(m+1);

    int lisc = lis(cant, creciente);
    reverse(cant.begin(), cant.end());

    int lisd = lis(cant, decreciente);
    // reverse(decreciente.begin(), decreciente.end());

    // debugc(creciente)
    // debugc(decreciente)

    int maxUnimodal = max(lisc, lisd);
    forn(i, m) {
        // debug(creciente[i] + decreciente[i])
        maxUnimodal = max(maxUnimodal, creciente[i] + decreciente[i+1] - 1);
    }

    cout << maxUnimodal << "\n";

}

#include <bits/stdc++.h>

using namespace std;

vector <int> gis_calc(const vector <int> &a)
{
    vector <int> dp(a.size() + 1, 1e9);
    dp[0] = -1e9;
    vector <int> ans;
    for (int x : a)
    {
        int pos(upper_bound(begin(dp), end(dp), x) - begin(dp));
        ans.push_back(pos);
        dp[pos] = x;
    }
    return ans;
}

int solve_up(vector <int> a)
{
    vector <int> gis(gis_calc(a));
    //reverse(begin(a), end(a));
    for (int &x : a) x *= -1;
    vector <int> gds(gis_calc(a));
    //reverse(begin(gds), end(gds));
    int ans(0);
    for (int i(0); i < a.size(); ++i)
        ans = max(ans, gis[i] + gds[i] - 1);
    return ans;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector <int> cnt(m + 1, 0);
    for (int a, b; n; --n)
    {
        cin >> a >> b;
        ++cnt[--a];
        --cnt[b];
    }
    cnt.pop_back();
    for (int i(1); i < m; ++i) cnt[i] += cnt[i - 1];
    int ans(solve_up(cnt));
    for (int &x : cnt) x *= -1;
    ans = max(ans, solve_up(cnt));
    cout << ans;
}

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <string>
#include <set>
#include <bitset>
#include <stdlib.h>
#include <ctime>
#define Clear(x,y) memset (x,y,sizeof(x))
#define Close() ios::sync_with_stdio(0)
#define Open() freopen ("more.in", "r", stdin)
#define get_min(a,b) a = min (a, b)
#define get_max(a,b) a = max (a, b);
#define y0 yzz
#define y1 yzzz
#define fi first
#define se second
#define pii pair<int, int>
#define pil pair<int, long long>
#define pli pair<long long, int>
#define pll pair<long long, long long>
#define pdi pair<double, int>
#define pdd pair<double, double>
#define vei vector<int>
#define vel vector<long long>
#define pb push_back
#define lson l,mid,pl
#define rson mid+1,r,pr
#define ALL(x) x.begin(),x.end()
namespace fastIO {
    #define BUF_SIZE 100000
    //fread -> read
    bool IOerror = 0;
    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if(p1 == pend) {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1) {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }
    inline bool blank(char ch) {
        return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
    }
    inline void read(int &x) {
        char ch;
        while(blank(ch = nc()));
        if(IOerror)
            return;
        for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
    }
    #undef BUF_SIZE
};
typedef unsigned long long ull;
template <class T> inline T lowbit (T x) {return x&(-x);}
template <class T> inline T sqr (T x) {return x*x;}
template <class T>
inline bool scan (T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return 0; //EOF
    while (c != '-' && (c < '0' || c > '9') ) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
const double pi = 3.14159265358979323846264338327950288L;
using namespace std;
const long long mod = 1000000007;
#define maxn 100005
#define maxm 200005
#define maxq 400005
const long long INF = 1e18;
#define eps 1e-6
//-----------------morejarphone--------------------//

int c[maxn] = {0}, n, m, cnt[maxn];

void add (int x, int num) {
	for (int i = x; i < maxn; i += lowbit (i)) c[i] += num;
}

int query (int x) {
	int ans = 0;
	for (int i = x; i >= 1; i -= lowbit (i)) {
		get_max (ans, c[i]);
	}
	return ans;
}

void update (int x, int num) {
	for (int i = x; i < maxn; i += lowbit (i)) {
		get_max (c[i], num);
	}
}

int get_lcs () {
	int ans = 0;
	Clear (c, 0);
	for (int i = 1; i <= m; i++) {
		int tmp = query (cnt[i]);
		get_max (ans, tmp+1);
		update (cnt[i], tmp+1);
	}
	return ans;
}

int main () {
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		int x, y;
		scanf ("%d%d", &x, &y);
		add (x, 1); add (y+1, -1);
	}
	for (int i = 1; i <= m; i++) {
		int tot = 0;
		for (int x = i; x >= 1; x -= lowbit (x)) tot += c[x];
		cnt[i] = tot+1;
		//cout << cnt[i] << " ";
	} //cout << endl;
	int ans1 = get_lcs ();
	reverse (cnt+1, cnt+1+m);
	int ans2 = get_lcs ();
	cout << max (ans1, ans2) << endl;
	return 0;
}

#include<bits/stdc++.h>

using namespace std;

int c[100020],a,b,n,m,i,res,now,ans;
int tr[262144];
int d[100020];

int get_max(int t,int l,int r,int x) {
    if (r <= x) return tr[t];
    if (x < l) return 0;
    return max(get_max(2*t,l,(l+r)/2,x),get_max(2*t+1,(l+r)/2+1,r,x));
}

void upd(int t,int l,int r,int x,int y) {
    if (r < x || x < l) return;
    if (l == r) {
        tr[t]=max(tr[t],y);
        return;
    }
    upd(2*t,l,(l+r)/2,x,y);
    upd(2*t+1,(l+r)/2+1,r,x,y);
    tr[t]=max(tr[2*t],tr[2*t+1]);
}

void build(int t,int l,int r) {
    tr[t]=0;
    if (l == r) return;
    build(2*t,l,(l+r)/2);
    build(2*t+1,(l+r)/2+1,r);
}

int main() {
    cin>>n>>m;
    for (i=1;i<=n;i++) {
        scanf("%d%d",&a,&b);
        c[a]++;
        c[b+1]--;
    }
    for (i=1;i<=m;i++)
        c[i]+=c[i-1];
    for (i=1;i<=m;i++) {
        now=get_max(1,0,m-1,c[i])+1;
        upd(1,0,m-1,c[i],now);
        d[i]=max(d[i-1],now);
    }
    build(1,0,m-1);
    for (i=m;i>=1;i--) {
        now=get_max(1,0,m-1,c[i])+1;
        upd(1,0,m-1,c[i],now);
        ans=max(ans,now);
        if (i>=2) ans=max(ans,now+d[i-2]);
    }
    cout<<ans<<endl;
}

#include<bits/stdc++.h>

#define For(i,x,y) for (int i=x;i<y;i++)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lf else if

#define dprintf(...) fprintf(stderr,__VA_ARGS__)
using namespace std;

typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef vector<int> Vi;

int IN(){
	int c,f,x;
	while (!isdigit(c=getchar())&&c!='-');c=='-'?(f=1,x=0):(f=0,x=c-'0');
	while (isdigit(c=getchar())) x=(x<<1)+(x<<3)+c-'0';return !f?x:-x;
}

const int oo=(1<<30)-1;
const int N=1e5+19;

int A[N];
int n,m,x,y,mx,wei;

int main(){
	n=IN(),m=IN();
	For(i,1,n+1){
		x=IN(),y=IN();
		A[x]++,A[y+1]--;
	}
	For(i,1,m+1) A[i]+=A[i-1];
	x=oo,y=-oo;
	For(i,1,m+1) mx=max(mx,A[i]);
	For(i,1,m+1){
		if (A[i]==mx){
			x=min(x,i);
			y=max(y,i);
		}
	}
	For(i,x,y+1) if (A[i]<mx) wei=1;
	For(i,1,x) if (A[i]>A[i+1]) wei=1;
	For(i,y,m+1) if (A[i]<A[i+1]) wei=1;
	if (wei) printf("%d\n",m-1);else printf("%d\n",m);
}

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1e5;

int N, M;
int cc[MAXN + 10];

struct SGTree {
   int mx[4*MAXN + 10];
   void upd(int cn, int b, int e, int i, int v) {
      if(i < b || i > e) return;
      if(b == e) {
         mx[cn] = max(mx[cn], v);
         return;
      }
      int m = (b + e) / 2;
      if(i <= m) upd(2*cn, b, m, i, v);
      else upd(2*cn+1, m+1, e, i, v);
      mx[cn] = max(mx[2*cn], mx[2*cn+1]);
   }
   int get(int cn, int b, int e, int l, int r) {
      if(l <= b && e <= r) return mx[cn];
      if(r < b || l > e) return 0;
      int m = (b + e) / 2;
      return max(get(2*cn, b, m, l, r), get(2*cn+1, m+1, e, l, r));
   }
   void upd(int i, int v) {
      upd(1, 1, N, i, v);
   }
   int get(int l, int r) {
      return get(1, 1, N, l, r);
   }
} inc, decr;

int calc() {
   for(int i = M; i >= 1; i--) {
      inc.upd(cc[i], inc.get(cc[i], N) + 1);
      decr.upd(cc[i], decr.get(1, cc[i]) + 1);
      inc.upd(cc[i], decr.get(cc[i], cc[i]));
   }
   return inc.get(1, N);
}

bool bad() {
   int mx = 0;
   for(int i = 1; i+1 <= M; i++) {
      if(cc[i] < mx && cc[i+1] > cc[i]) return false;
      mx = max(mx, cc[i]);
   }
   return true;
}

int main() {
   scanf("%d%d", &N, &M);
   for(int i = 1; i <= N; i++) {
      int l, r; scanf("%d%d", &l, &r);
      cc[l]++; cc[r+1]--;
   }
   for(int i = 1; i <= M; i++) cc[i] += cc[i-1];
   if(false) printf("%d\n", M);
   else printf("%d\n", calc());
}

#include <iostream>
#include <bits/stdc++.h>
#include <string>
using namespace std;

#define pb push_back
#define ull unsigned long long
#define ll long long
#define F first
#define S second
#define PI acos(-1)
#define EPS 1e-9
#define BASE 31ll
#define BASE2 53ll
#define ld double
#define MAX 1000000000
#define NIL 0
#define INF 1e15
#define infi 1000000000
#define rd(a) scanf("%d",&a)
#define rd2(a,b) scanf("%d %d",&a,&b)
#define rd3(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define rdll(a) scanf("%I64d",&a)
#define sz(a) (int) a.size()
#define lp(i,a,n) for(int i=(a); i<=(n) ; ++i)
#define lpd(i,n,a) for(int i=(n); i>=(a) ; --i)
#define pi acos(-1)
#define lc (x << 1)
#define rc (x << 1 | 1)
#define cp(a,b)                 ( (conj(a)*(b)).imag() )	// a*b sin(T), if zero -> parllel
#define dp(a,b)                 ( (conj(a)*(b)).real() )	// a*b cos(T), if zero -> prep
#define angle(a)                (atan2((a).imag(), (a).real()))
#define X real()
#define Y imag()
#define vec(a,b)                ((b)-(a))
#define vvi vector<vector<int>>
#define f first
#define s second

typedef complex<double>point;
typedef complex<double>CX;
typedef pair<int,int>ii;
typedef pair<ii,int>tri;
typedef pair<vector<int>,int>vii;
typedef pair<int, int> pii;
typedef pair<ii,ii> line;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

const int N=100005;

ll mod=(1e9+7);
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
ll lcm(ll a, ll b) { return a * (b / gcd(a, b)); }
bool is_vowel(char c){if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')return 1;return 0;}
ld getDistance(ld x1,ld y1,ld x2,ld y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
ll extended_euclidean(ll a,ll b,ll &x,ll &y){if(b==0){x=1;y=0;return a;}ll g = extended_euclidean(b,a%b,y,x);y -= (a/b)*x;return g;}
ll power(ll base,ll p){if(p==1)return base;if(!p)return 1ll;ll ret=power(base,p/2);ret*=ret;ret%=mod;if(p&1)ret*=base;return ret%mod;}

int acc[N],tree[N*4],dp[N],dp2[N];
int get(int p,int s,int e,int from,int to){
  if(e<from||to<s)return 0;
  if(from<=s&&e<=to)return tree[p];
  return max(get(p*2,s,(s+e)/2,from,to),get(p*2+1,(s+e)/2+1,e,from,to));
}
void update(int p,int s,int e,int idx,int val){
   if(idx<s||e<idx)return;
   if(s==e){
    tree[p]=val;
    return;
   }
   update(p*2,s,(s+e)/2,idx,val);
   update(p*2+1,(s+e)/2+1,e,idx,val);
   tree[p]=max(tree[p*2],tree[p*2+1]);
}
int main(){
 //   freopen("test.in","r",stdin);
    int n,m;
    rd2(n,m);
    lp(i,1,n){
       int a,b;
       rd2(a,b);
       acc[a]++;
       acc[b+1]--;
    }
    lp(i,2,m)acc[i]+=acc[i-1];
    int mx=0;
    lp(i,1,m){
        if(acc[i]==0)continue;
        int cur=get(1,0,m,0,acc[i]);
        update(1,0,m,acc[i],cur+1);
        dp[i]=cur+1;
    }
    memset(tree,0,sizeof(tree));
    lpd(i,m,1){
        if(acc[i]==0)continue;
        int cur=get(1,0,m,0,acc[i]);
        update(1,0,m,acc[i],cur+1);
        dp2[i]=cur+1;
    }
    lp(i,1,m)mx=max(dp2[i]+dp[i]-1,mx);
    cout<<mx;
    return 0;
}

#include <bits/stdc++.h>

//#define int long long

using namespace std;

int INF = int(2e9);

signed main()
{
    int n, m, l, r, k = 0, maxk = 0;
    cin >> n >> m;
    vector < pair < int, int > > lr(m + 1, {0, 0});
    for(int i = 0; i < n; i++)
    {
        cin >> l >> r;
        lr[l - 1].first++;
        lr[r].second++;
    }
    vector < int > a(m, 0);
    for(int i = 0; i < m; i++)
    {
        k += lr[i].first - lr[i].second;
        a[i] = k;
    }
    vector < int > d(m + 1, INF);
    d[0] = -INF;
    for(int i = 0; i < m; i++)
    {
        int j = upper_bound(d.begin(), d.end(), a[i]) - d.begin();
        d[j] = a[i];
    }
    for(int i = m; i >= 0; i--)
    {
        if(d[i] != INF)
        {
            maxk = i;
            break;
        }
    }
    reverse(a.begin(), a.end());
    d.assign(m + 1, INF);
    d[0] = -INF;
    for(int i = 0; i < m; i++)
    {
        int j = upper_bound(d.begin(), d.end(), a[i]) - d.begin();
        d[j] = a[i];
    }
    for(int i = m; i >= 0; i--)
    {
        if(d[i] != INF)
        {
            maxk = max(maxk, i);
            break;
        }
    }
    cout << maxk;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define lc (o<<1)
#define rc ((o<<1)|1)
#define mid ((l+r)>>1)
int a[maxn],n,m;
struct Seg
{
	int v[maxn<<2];
	void up(int o)
	{
		v[o]=max(v[lc],v[rc]);
	}
	void update(int o,int l,int r,int p,int x)
	{
		if(l==r)
		{
			v[o]=x;
			return;
		}
		if(p<=mid) update(lc,l,mid,p,x);
		else update(rc,mid+1,r,p,x);
		up(o);
	}
	int query(int o,int l,int r,int y1,int y2)
	{
		if(y1<=l&&y2>=r) return v[o];
		int ans=0;
		if(y1<=mid) ans=max(ans,query(lc,l,mid,y1,y2));
		if(y2>mid) ans=max(ans,query(rc,mid+1,r,y1,y2));
		return ans;
	}
}seg[2];
int dp[maxn][2];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		++a[l];--a[r+1];
	}
	for(int i=1;i<=m;++i) a[i]+=a[i-1];
	int ans=0;
	for(int i=1;i<=m;++i)
	{
		if(!a[i]) continue;
		//dp[i][0]
		dp[i][0]=seg[0].query(1,1,m,1,a[i])+1;
		//dp[i][1]
		dp[i][1]=max(seg[0].query(1,1,m,a[i],m),seg[1].query(1,1,m,a[i],m))+1;
		seg[0].update(1,1,m,a[i],dp[i][0]);
		seg[1].update(1,1,m,a[i],dp[i][1]);
		ans=max(ans,dp[i][0]);
		ans=max(ans,dp[i][1]);
	}
	printf("%d\n",ans);
	return 0;
}

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m,l,r;
const int maxn = 100007;
int a[maxn],addmark[maxn],dp[maxn],lis[2][maxn],slis[maxn];
int cnt = 0;
int main(){
    cin>>n>>m;
    for (int i=0; i<n; i++){
        scanf("%d%d", &l, &r);
        addmark[l]++;
        addmark[r+1]--;
    }
    int sum = 0;
    for (int i=1; i<=m; i++){
        sum+=addmark[i];
        a[i] = sum;
    }

    memset(dp, 0x3f, sizeof(dp));
    for (int i=1; i<=m; i++){
        int pos = upper_bound(dp, dp+i, a[i]) - dp;
        dp[pos] = a[i];
        lis[0][i] = pos + 1;
    }
    memset(dp, 0x3f, sizeof(dp));
    for (int i=m; i>=1; i--){
        int pos = upper_bound(dp, dp+i, a[i]) - dp;
        dp[pos] = a[i];
        lis[1][i] = pos + 1;
        slis[i] = max(slis[i+1], pos + 1);
    }
    int ans = 0;
    for (int i=1; i<=m; i++){
        ans = max(ans, lis[0][i] + slis[i+1]);
    }
    cout<<ans<<endl;
/*
    for(int i = 0;i < n;++i){
        scanf("%d%d",&l,&r);
        addmark[l]++;
        addmark[r+1]--;
    }
    int sum = 0;
    for(int i = 1;i <= m;++i){
        sum += addmark[i];
        a[i] = sum;
    }
    memset(dp,0x3f,sizeof(dp));
    for(int i = 1;i <= m;++i){
        int pos = upper_bound(dp,dp+m,a[i])-dp;
        dp[pos] = a[i];
        lis[0][i] = pos+1;
    }
    memset(dp,0x3f,sizeof(dp));
    for(int i = m;i >= 1;i--){
        int pos = upper_bound(dp,dp+m,a[i])-dp;
        dp[pos] = a[i];
        lis[1][i] = pos+1;
        slis[i] = max(slis[i+1],lis[1][i]);
    }
    int ans = 0;
    for(int i = 1;i <= m;++i){
        //printf("i:%d %d %d\n",i,lis[0][i],lis[1][i]);
        ans = max(ans,lis[0][i] + slis[i+1]);
    }
    cout<<ans<<endl;

    return 0;
*/
}

#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast")
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <string>
#include <cmath>
#include <stack>
#include <iomanip>
#include <set>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <random>

using namespace std;

#define ff first
#define ss second

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int maxn = 1e5 + 7;
const int inf = 2e9 + 7;
const ll infl = 1e18 + 7;
const long double eps = 1e-9;
const ll mod = 998244353;

vector<string> v[26];

ld p[26];

int main() {
#ifdef _DEBUG
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif // _DEBUG
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	srand(time(0));

	int n, m;
	cin >> n >> m;
	vector<int> cnt(m + 1, 0);
	vector<pair<int, int>> e;
	for (int i = 0; i < n; i++) {
		int l, r;
		cin >> l >> r;
		e.push_back({ l, 1 });
		e.push_back({ r, -1 });
	}
	sort(e.begin(), e.end());
	int j = 0, b = 0;
	for (int i = 1; i <= m; i++) {
		while (j < e.size() && i >= e[j].ff) {
			b += e[j].ss;
			j++;
		}
		cnt[i] = b;
	}

	vector<int> pref(m + 1), suff(m + 1);
	vector<int> dp(m + 1, inf);
	dp[0] = -1;
	for (int i = 1; i <= m; i++) {
		int ind = upper_bound(dp.begin(), dp.end(), cnt[i]) - dp.begin();
		pref[i] = ind;
		dp[ind] = cnt[i];
	}

	dp.assign(m + 1, inf);
	dp[0] = -1;
	for (int i = m; i >= 0; i--) {
		int ind = upper_bound(dp.begin(), dp.end(), cnt[i]) - dp.begin();
		suff[i] = ind;
		dp[ind] = cnt[i];
	}
	int ans = 0;
	for (int i = 1; i <= m; i++) {
		ans = max(ans, pref[i] + suff[i]);
	}
	cout << ans;
	return 0;
}

#include <bits/stdc++.h>
#define mid (l+r)/2
#define pb push_back
#define for(i,l,r) for (int i=l;i<r;i++)
using namespace std;
struct arr {int val,pos;};
arr a[100001];
bool cmp1(arr& a,arr& b) {if (a.val==b.val) return a.pos<b.pos; else return a.val<b.val;}
bool cmp2(arr& a,arr& b) {if (a.val==b.val) return a.pos>b.pos; else return a.val<b.val;}
int n,m,l[100001],r[100001],cnt[100001],t[400001],lazy[400001],dp[100001],dp2[100001],fin1[100001],fin2[100001];
void update(int l,int r,int s,int e,int node) {
	if (lazy[node]) {
		t[node]+=lazy[node];
		lazy[node*2]+=lazy[node];
		lazy[node*2+1]+=lazy[node];
		lazy[node]=0;
	}
	if (l>r||r<s||l>e) return;
	if (s<=l&&r<=e) {lazy[node]++; return;}
	update(l,mid,s,e,node*2); update(mid+1,r,s,e,node*2+1);
}
int get(int l,int r,int pos,int node) {
	if (lazy[node]) {
		t[node]+=lazy[node];
		lazy[node*2]+=lazy[node];
		lazy[node*2+1]+=lazy[node];
		lazy[node]=0;
	}
	if (l==r) return t[node];
	if (pos<=mid) return get(l,mid,pos,node*2);
	else return get(mid+1,r,pos,node*2+1);
}
void update2(int l,int r,int pos,int val,int node) {
	if (l==r) {t[node]=val; return;}
	if (pos<=mid) update2(l,mid,pos,val,node*2);
	else update2(mid+1,r,pos,val,node*2+1);
	t[node]=max(t[node*2],t[node*2+1]);
}
int get_max(int l,int r,int s,int e,int node) {
	if (s>e) return -1;
	if (l>r||l>e||r<s) return -1;
	if (s<=l&&r<=e) return t[node];
	return max(get_max(l,mid,s,e,node*2),get_max(mid+1,r,s,e,node*2+1));
}
signed main() {
	//freopen("930C.inp","r",stdin);
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin>>n>>m; for (i,0,n) {cin>>l[i]>>r[i]; l[i]--; r[i]--;}
	memset(t,0,sizeof(t)); memset(lazy,0,sizeof(lazy));
	for (i,0,n) update(0,m-1,l[i],r[i],1);
	for (i,0,m) {cnt[i]=get(0,m-1,i,1); a[i].pos=i; a[i].val=cnt[i];}
	sort(a,a+m,cmp1);
	memset(t,-1,sizeof(t)); memset(lazy,0,sizeof(lazy));
	//for (i,0,m) cout<<a[i].pos<<" "<<a[i].val<<"\n";
	for (i,0,m) {
		dp[i]=max(1,get_max(0,m-1,0,a[i].pos-1,1)+1);
		update2(0,m-1,a[i].pos,dp[i],1);
		fin1[a[i].pos]=dp[i];
	}
	sort(a,a+m,cmp2);
	memset(t,-1,sizeof(t)); memset(lazy,0,sizeof(lazy));
	for (i,0,m) {
		dp2[i]=max(1,get_max(0,m-1,a[i].pos+1,m-1,1)+1);
		update2(0,m-1,a[i].pos,dp2[i],1);
		fin2[a[i].pos]=dp2[i];
	}
	//for (i,0,m) cout<<cnt[i]<<" "; cout<<"\n";
	//for (i,0,m) cout<<fin1[i]<<" "; cout<<"\n";
	//for (i,0,m) cout<<fin2[i]<<" "; cout<<"\n";
	int ans=max(fin2[0],fin1[m-1]);
	for (i,0,m-1) {
		ans=max(ans,fin1[i]+fin2[i]-1);
		//cout<<"currans="<<ans<<"\n";
	}
	//Why the algorithm is wrong? fin1 and fin2 all considers subsequences strictly ending at i.
	//So, the correct answer lies on fin1[i] + fin2[i] - 1 (Get rid of the point i since it's calculated
	//twice)
	cout<<ans;
}

#include <iostream>
#include <algorithm>
#include <utility>
#include <set>
#include <vector>

int main(int argc, const char * argv[])
{
    std::ios_base::sync_with_stdio(false);

    int n, m;
    std::cin >> n >> m;

    std::vector<int> v(m + 2);
    for (int i = 0; i < n; i ++)
    {
        int l, r;
        std::cin >> l >> r;

        v[l + 0] ++;
        v[r + 1] --;
    }

    for (int i = 1; i <= m; i ++)
        v[i] += v[i - 1];

    std::vector<int> last0(m + 1);
    for (int i = 0; i <= m; i ++)
        last0[i] = -1;

    std::vector<int> dp0(m + 1);
    for (int i = 1; i <= m; i ++)
    {
        for (int j = v[i]; j >= 0; j --)
        {
            if (last0[v[j]] != -1)
            {
                dp0[i] = std::max(dp0[i], dp0[last0[j]] + 1);
                break;
            }
            else dp0[i] = std::max(dp0[i], 1);
        }
        last0[v[i]] = i;
    }

    std::vector<int> last1(m + 1);
    for (int i = 0; i <= m; i ++)
        last1[i] = -1;

    std::vector<int> dp1(m + 1);
    for (int i = m; i >= 1; i --)
    {
        for (int j = v[i]; j >= 0; j --)
        {
            if (last1[j] != -1)
            {
                dp1[i] = std::max(dp1[i], dp1[last1[j]] + 1);
                break;
            }
            else dp1[i] = std::max(dp1[i], 1);
        }
        last1[v[i]] = i;
    }

    int result = 0;
    for (int i = 1; i <= m; i ++)
        result = std::max(result, dp0[i] + dp1[i] - 1);

    std::cout << result << std::endl;

    return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;

#define int long long
#define ll long long
#define vi vector <int>
#define vii vector <pair<int,int> >
#define rep(i,a,b) for (int i=a;i<b;i++)
#define repD(i,a,b) for (int i=a;i>b;i--)
#define pb push_back
#define pii pair <int,int>
#define ff first
#define ss second
#define all(a) a.begin(),a.end()
#define MOD 1000000007
#define PI 3.14159265359

typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
///*X.find_by_order("index")
///X.order_of_key("key")

#define deb(x) {x}
#ifndef local
	#define deb(x) ;
#endif

///----------------------------------------------------------------------------------

int n,m,arr[100005],P[100005],pref[100005],suf[100005],segtree[400005];

void update(int node,int si,int ei,int idx,int val)
{
    if (si==ei)
    {
        segtree[node]=val;
        return;
    }

    int mid=(si+ei)/2;

    if (idx<=mid)
        update(2*node,si,mid,idx,val);
    else
        update(2*node+1,mid+1,ei,idx,val);

    segtree[node]=max(segtree[2*node],segtree[2*node+1]);
}

int query(int node,int si,int ei,int l,int r)
{
    if (si>r || ei<l)
        return 0;

    if (si>=l && ei<=r)
        return segtree[node];

    int mid=(si+ei)/2;
    return max(query(2*node,si,mid,l,r),query(2*node+1,mid+1,ei,l,r));
}

void solve()
{
	int l,r;
	cin >> n >> m;
	rep(i,0,n)
	{
		cin >> l >> r;
		P[l]++;
		P[r+1]--;
	}

	int v = 0;
	rep(i,0,m+1)
	{
		v += P[i];
		arr[i] = v;
	}
	memset(segtree,0,sizeof segtree);
	rep(i,0,m+1)
	{
		pref[i] = query(1,0,100001,0,arr[i]) + 1;
		update(1,0,100001,arr[i],pref[i]);
	}
	memset(segtree,0,sizeof segtree);
	repD(i,m,-1)
	{
		suf[i] = query(1,0,100001,0,arr[i]) + 1;
		update(1,0,100001,arr[i],suf[i]);
	}
	int ans = 0;
	rep(i,0,m)ans = max(ans, pref[i] + suf[i] - 1);
	cout<<ans<<"\n";
}

signed main()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);

 	#ifdef local
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	clock_t qwertyuiop = clock();
	#endif

	int t=1;
	//cin>>t;

	rep(a,0,t)
	{
		///cout<<"Case #"<<a+1<<": ";
		solve();
	}

	#ifdef local
	{qwertyuiop = clock() - qwertyuiop;double time_taken = ((double)qwertyuiop)/CLOCKS_PER_SEC;cerr<<fixed<<setprecision(5)<<"\n\nTime Taken : "<<time_taken<<" seconds\n";}
	#endif
}

#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mp make_pair
#define sz(A) ((int)(A).size())

typedef long long LL;

const int N = int(1e5 + 5);

int n, m, res[N], ans;
vector<pair<int, int>> p;

int main() {
  ios::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    int l, r;
    cin >> l >> r;
    p.pb(mp(l, -1));
    p.pb(mp(r, 1));
  }
  sort(p.begin(), p.end());
  int cur = 0, cnt = 0, mx = 0;
  for (int i = 1; i <= m; i++) {
    while (cur < sz(p) && p[cur].first == i && p[cur].second == -1) {
      cnt++;
      cur++;
    }
    res[i] = cnt;
    mx = max(mx, res[i]);
    //cerr << res[i] << " ";
    while (cur < sz(p) && p[cur].first == i && p[cur].second == 1) {
      cnt--;
      cur++;
    }
  }
  int ans = m;
  bool ok = 0;
  for (int i = 2; i <= m; i++) {
    if (res[i] < res[i - 1]) {
      ok = 1;
    }
    if (ok && res[i] > res[i - 1]) {
      ans = m - 1;
    }
  }

  cout << ans << endl;

  return 0;
}

#pragma comment(linker, "/STACK:66777216")
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <queue>

using namespace std;

const int N = 2e5 + 7;

int d[N], dd[N], cnt[N];

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	//freopen("flow.in", "r", stdin);
	//freopen("flow.out", "w", stdout);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		int x, y;
		cin >> x >> y;
		d[x]++;
		dd[y]--;
	}
	int sum = 0, mx = 0;
	for (int i = 1; i <= m; i++) {
		sum += d[i];
		cnt[i] = sum;
		sum += dd[i];
		mx = max(mx, cnt[i]);
	}
	int ans = 0;
	vector <int> t(m + 6);
	t[0] = -1000000;
	for (int i = 1; i <= m + 5; i++)
		t[i] = 1000000;
	for (int i = 1; i <= m; i++) {
		int j = int(upper_bound(t.begin(), t.end(), cnt[i]) - t.begin());
		if (t[j - 1] <= cnt[i] && cnt[i] <= t[j])
			t[j] = cnt[i];
	}
	for (int i = 1; i <= m; i++) {
		if (t[i] != 1000000) {
			ans++;
		}
	}
	int anss = 0;
	vector <int> tt(m + 6);
	tt[0] = -1000000;
	for (int i = 1; i <= m + 5; i++)
		tt[i] = 1000000;
	for (int i = 1; i <= m; i++) {
		int j = int(upper_bound(tt.begin(), tt.end(), cnt[m - i + 1]) - tt.begin());
		if (tt[j - 1] <= cnt[m - i + 1] && cnt[m - i + 1] <= tt[j])
			tt[j] = cnt[m - i + 1];
	}
	for (int i = 1; i <= m; i++) {
		if (tt[i] != 1000000) {
			anss++;
		}
	}
	cout << max(ans, anss);
	cin >> n;
	return 0;
}
/*
*/

#include <bits/stdc++.h>
#define  ms(a,b) memset(a,b,sizeof(a))
#define SZ(x) ((int)(x).size())
#define li i<<1
#define ri (i<<1)|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF=1e18L;
const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
const int Mod=1e9+7;
int n,m;
int cnt[maxn],b[maxn*2];
int dp[maxn][2];
int Search(int x,int l,int r) //从l,r找到第一个比x大的
{
    int ans=r;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(b[mid]>x)
        {
            ans = mid;
            r=mid-1;
        }
        else l=mid+1;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        int l,r;
        cin>>l>>r;
        cnt[l]++;
        cnt[r+1]--;
    }
    for(int i=1;i<=m;i++)
        cnt[i]+=cnt[i-1];

    int len,pos;
    b[1] = cnt[1];
    len=1;
    dp[1][0]=len;
    for(int i=2;i<=m;i++)
    {
        if(cnt[i]>=b[len])
        {
            dp[i][0]=++len;
            b[len]=cnt[i];
        }
        else
        {
            pos = Search(1,len,cnt[i]);
            dp[i][0] = pos;
            b[pos] = cnt[i];
        }
    }

    b[1] = cnt[m];
    len=1;
    dp[m][1]=len;
    for(int i=m-1;i>=1;i--)
    {
        if(cnt[i]>=b[len])
        {
            dp[i][1]=++len;
            b[len]=cnt[i];
        }
        else
        {
            pos = Search(1,len,cnt[i]);
            dp[i][1]=pos;
            b[pos]=cnt[i];
        }
    }
    int ans=0;
    for(int i=1;i<=m;i++)
    {
        ans=max(ans,dp[i][0]+dp[i][1]-1);
    }
    cout<<ans<<endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int maxn = 100005;
int cnt[maxn];

struct segtree {
  int t[2 * maxn];
  void upd(int x, int v) {
    for (x += maxn; x; x /= 2) t[x] = max(t[x], v);
  }
  int get(int l, int r) {
    int ret = 0;
    for (l += maxn, r += maxn + 1; l < r; l /= 2, r /= 2) {
      if (l & 1) ret = max(ret, t[l++]);
      if (r & 1) ret = max(ret, t[--r]);
    }
    return ret;
  }
} seg[2];

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  int n, m; cin >> n >> m;
  for (int i = 0; i < n; ++i) {
    int l, r; cin >> l >> r;
    cnt[l]++, cnt[r + 1]--;
  }
  for (int i = 1; i <= m; ++i) {
    cnt[i] += cnt[i - 1];
    seg[1].upd(cnt[i], max(seg[1].get(cnt[i], n), seg[0].get(0, n)) + 1);
    seg[0].upd(cnt[i],     seg[0].get(0, cnt[i]) + 1);
  }
  cout << seg[1].get(1, n) << '\n';
}

#include <bits/stdc++.h>

#define dbg(x) cerr<<#x": "<<x<<"\n"
#define dbg_p(x) cerr<<#x": "<<x.first<<","<<x.second<<"\n"
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok cerr<<"OK!\n"

#define st first
#define nd second

#define DMAX 100100
#define NMAX
#define MMAX

using namespace std;

int n, k, m, f[DMAX], a, b, ans, cresc[DMAX], desc[DMAX], h[DMAX], mc[DMAX], md[DMAX];
double l, v1, v2;
string s;

template<class T>
ostream& operator<<(ostream& out, vector<T> v)
{
	out << v.size() << '\n';
	for(auto e : v) out << e << ' ';
	return out;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin >> n >> m;
	for(int i = 1; i <= n; i++ ){
		cin >> a >> b;
		f[a]++;
		f[b + 1]--;
	}
	for(int i = 2; i <= m; i++)
		f[i] += f[i - 1];

	int lgmax = 1;
	for(int i = 0; i <= m; ++i) h[i] = 1000000000;
	h[0] = 0;

	for(int i = 1; i <= m; i++) {
		int lg = upper_bound(h + 1, h + lgmax + 1, f[i]) - h;
		cresc[i] = lg;
		lgmax = max(lgmax, cresc[i]);
		h[lg] = min(f[i], h[lg]);
	}
	dbg_v(cresc, m + 2);

	lgmax = 1;
	for(int i = 0; i <= m; ++i) h[i] = 1000000000;
	h[0] = -1000000000;
	for(int i = m; i >= 1; i--) {
		int lg = upper_bound(h + 1, h + lgmax + 1, -f[i]) - h;
		// dbg(lg);
		// dbg(i);
		// dbg_v(h, m + 1);
		desc[i] = lg;
		lgmax = max(lgmax, cresc[i]);
		h[lg] = min(-f[i], h[lg]);
	}
	dbg_v(desc, m + 2);

	mc[1] = cresc[1];
	for(int i = 2; i <= m; i++)
		mc[i] = max(mc[i - 1], cresc[i]);

	md[m] = desc[m];
	for(int i = m - 1; i >= 1; i--)
		md[i] = max(md[i + 1], desc[i]);

	for(int i = 1; i <= m; i++)
		ans = max(mc[i] + md[i] - 1, ans);
	cout << ans << '\n';
}

// FLYING
// RAIJIN
// JYUTSU

#include <bits/stdc++.h>
using namespace std;

#define f first
#define s second
#define pb push_back
#define all(c) c.begin(),c.end()

#define gi(x) scanf("%d", &x)
#define pi(x) printf("%d", x)
#define gl(x) scanf("%lld", &x)
#define pl(x) printf("%lld", x)
#define sp printf(" ")
#define nl printf("\n")

typedef long long int lld;
typedef long double ldb;

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << std::endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif

#define MAXN 100010

vector <int> val[MAXN];

int x[MAXN];

int td[MAXN*4], ti[MAXN*4];

int queryd(int node, int lo, int hi, int l, int r){
	if(l > hi or r < lo) return 0;
	if(lo >= l and hi <= r) return td[node];
	int md = (lo + hi) >> 1;
	int p1 = queryd(node << 1, lo, md, l, r);
	int p2 = queryd(node << 1 | 1, md + 1, hi, l, r);
	return max(p1, p2);
}

void updated(int node, int lo, int hi, int idx, int val){
	if(lo == hi){
		td[node] = max(td[node], val);
		return;
	}
	int md = (lo + hi) >> 1;
	if(idx <= md) updated(node << 1, lo, md, idx, val);
	else updated(node << 1 | 1, md + 1, hi, idx, val);
	td[node] = max(td[node << 1], td[node << 1 | 1]);
}

int queryi(int node, int lo, int hi, int l, int r){
	if(l > hi or r < lo) return 0;
	if(lo >= l and hi <= r) return ti[node];
	int md = (lo + hi) >> 1;
	int p1 = queryi(node << 1, lo, md, l, r);
	int p2 = queryi(node << 1 | 1, md + 1, hi, l, r);
	return max(p1, p2);
}

void updatei(int node, int lo, int hi, int idx, int val){
	if(lo == hi){
		ti[node] = max(ti[node], val);
		return;
	}
	int md = (lo + hi) >> 1;
	if(idx <= md) updatei(node << 1, lo, md, idx, val);
	else updatei(node << 1 | 1, md + 1, hi, idx, val);
	ti[node] = max(ti[node << 1], ti[node << 1 | 1]);
}

int ai[MAXN], ad[MAXN];

main(){
    int n, m;
    cin >> n >> m;
    for(int i = 0, l, r; i < n; ++i){
        cin >> l >> r;
        x[l]++;
        x[r+1]--;
    }
    for(int i = 1; i <= m; ++i){
        x[i] += x[i-1];
    }
    for(int i = 1; i <= m; ++i){
        auto xz = queryi(1, 0, m, 0, x[i]);
        ai[i] = xz+1;
        updatei(1, 0, m, x[i], xz+1);
    }
    for(int i = m; i > 0; --i){
        auto xz = queryd(1, 0, m, x[i], m);
        ad[i] = xz+1;
        updated(1, 0, m, x[i], xz+1);
    }
    int ans = 0;
    for(int i = 0; i <= m; ++i){
        ans = max(ans, ai[i] + ad[i] - 1);
        // trace(i,ad[i],ai[i]);
    }
    cout << ans << endl;
}

#pragma gcc optimize("OFast")
#pragma gcc target("sse,sse2,sse3,sse4,tune=native")
//#pragma gcc optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
const int maxn = 1e5, INF = 1e9;
const ll llINF = 1e18;

struct segTree {
    int n; vector<int> t;
    segTree(int n) : n(n), t(2 * n, 0) {}
    void upd(int l, int r) {
        for(l += n, r += n; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1) {
            if(l & 1) t[l]++;
            if(!(r & 1)) t[r]++;
        }
    }
    int get(int pos) {
        int ret = 0;
        for(pos += n; pos; pos >>= 1) ret += t[pos];
        return ret;
    }
};

struct segTree1 {
    int n; vector<int> t;
    segTree1(int n) : n(n), t(2 * n, 0) {}
    void upd(int v, int x) {
        t[v += n] = x;
        for(v >>= 1; v; v >>= 1) t[v] = max(t[v * 2], t[v * 2 + 1]);
    }
    int get(int l, int r) {
        int ret = 0;
        for(l += n, r += n; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1) {
            if(l & 1) ret = max(ret, t[l]);
            if(!(r & 1)) ret = max(ret, t[r]);
        }
        return ret;
    }
};

int n, m;

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    //freopen("in.txt", "r", stdin);
    cin >> n >> m;
    segTree t(m);
    for(int i = 0; i < n; i++) {
        int l, r; cin >> l >> r; l--; r--;
        t.upd(l, r);
    }
    vector<int> a(m);
    for(int i = 0; i < m; i++) a[i] = t.get(i);
    segTree1 t1(n);
    int ans = 0;
    for(int i = 0; i < m; i++) {
        int x = 1 + t1.get(0, a[i]);
        t1.upd(a[i], x);
        ans = max(ans, x);
    }
    cout << ans;
}

#include<bits/stdc++.h>

using namespace std;

vector <pair <int, int> > mem;
int n, m, p, a, b, maxi = 0;
int l[100100], mak[2][100100];

int bino (int l, int r, int x) {
	int mid = l+(r-l)/2;
	if (l == r || mem[mid].first == x) return mid;
	if (mem[mid].first > x) return bino(mid+1, r, x);
	if (mem[mid].first < x) return bino(l, mid, x);
}
int main () {
	cin >>m >>n;
	for (int i=0; i<m; i++) {
		cin >>a >>b;
		l[a-1]++;
		l[b]--;
	}
	for (int i=0; i<n; i++) {
		p+=l[i];
		l[i] = p;
	}
	for (int j=0; j<2; j++) {
		mak[j][1] = 1;
		for (int i=0; i<n; i++) {
			if (i > 0) {
				int x = bino(0, mem.size()-1, l[i]);
				//cout <<mem[x].first <<" " <<mem[x].second <<"\n";
				if (mem[x].first > l[i]) {
					mem.push_back(make_pair(l[i], 0));
					x++;
				}
				mem[x].first = l[i];
				mem[x].second++;
				mak[j][i+1] = max(mem[x].second, mak[j][i]);
				if (x != 0 && mem[x-1].second == mem[x].second) {
					mem.erase(mem.begin()+x-1, mem.begin()+x);
					//cout <<"YAAY";
				}
			}
			else mem.push_back(make_pair(l[i], 1));
		}
		//return 0;
		reverse(l, l+n);
		mem.clear();
	}
	for (int i=0; i<n+1; i++) {
		//cout <<mak[0][i] <<" ";
		maxi = max(maxi, mak[0][i]+mak[1][n-i]);
	}
	cout <<maxi;
	return 0;
}

#include <bits/stdc++.h>

#define ld long double
#define sf scanf
#define pf printf
#define pb push_back
#define mp make_pair
#define PI ( acos(-1.0) )
#define IN freopen("input.txt","r",stdin)
#define OUT freopen("output.txt","w",stdout)
#define FOR(i,a,b) for(int i=a ; i<=b ; i++)
#define FORD(i,a,b) for(int i=a ; i>=b ; i--)
#define INF 1000000000
#define ll long long int
#define eps (1e-8)
#define sq(x) ( (x)*(x) )
#define all(x) x.begin(),x.end()
#define flog2(n) 64 - __builtin_clzll(n) - 1

using namespace std;

typedef pair < int, int > pii;
typedef pair < ll, ll > pll;
const int N=100005;
struct node {
    int val;
    int lazy;
}st[4*N];
vector<int> V;
void build (int id, int l, int r){
    if (l==r){
        st[id].val=0;
        V.pb(id);
        return;
    }
    int mid=(l+r)/2;
    build (id*2,l,mid);
    build (id*2+1,mid+1,r);
    st[id].val=min(st[id*2].val,st[id*2+1].val);
}
void down(int id, int l, int r) {

    int t = st[id].lazy;
    st[id*2].lazy += t;
    st[id*2].val += t;

    st[id*2+1].lazy += t;
    st[id*2+1].val += t;

    st[id].lazy = 0;
}
void update(int id, int l, int r, int u, int v, int val) {
    if (v < l || r < u) {
        return ;
    }
    if (u <= l && r <= v) {
        st[id].val += val;
        st[id].lazy += val;
        return ;
    }
    int mid = (l + r) / 2;

    down(id,l,r);
    update(id*2, l, mid, u, v, val);
    update(id*2+1, mid+1, r, u, v, val);

    st[id].val = min(st[id*2].val, st[id*2+1].val);
}

int get(int id, int l, int r, int u, int v){
    if (v < l || r < u) {
        return INF;
    }
    if (u <= l && r <= v) {
        return st[id].val;
    }
    int mid = (l + r) / 2;

    down(id,l,r);
    return min(get(id*2, l, mid, u, v),get(id*2+1, mid+1, r, u, v));
}

vector<int> s,L,R;
int d[100005],e[100005],f[N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(NULL);
    ll n,m;
    cin>>n>>m;
    build(1,1,m);
    FOR (i,1,n){
        int x,y;
        cin>>x>>y;
        update(1,1,m,x,y,1);
        //FOR (i,x,y) gt[i]++;
    }
    FOR (i,1,m){
        update(1,1,m,i,i,0);
    }
    int M=INF;
    s.pb(0);
    for (auto i:V) s.pb(st[i].val);
    //FOR (i,1,m) cout<<s[i]<<" "; cout<<endl;
    FOR (i,1,m) {
        if (i==1) {L.pb(s[i]);}

        else if(L[L.size()-1]<=s[i]) {L.pb(s[i]);}
        else{
            auto it=lower_bound(all(L),s[i]);
            *it=s[i];
        }
        d[i]=L.size();
    }
    //FOR (i,1,m) cout<<d[i]<<" ";
    FOR (i,1,m) f[i]=s[m+1-i];
    L.clear();
    FOR (i,1,m) {
        if (i==1) {L.pb(f[i]);}

        else if(L[L.size()-1]<=f[i]) {L.pb(f[i]);}
        else{
            auto it=lower_bound(all(L),f[i]);
            *it=f[i];
        }
        e[i]=L.size();
    }
    int res=0;
    FOR (i,1,m){
        res=max(res,d[i]+e[m+1-i]-1);
    }

    cout<<res<<endl;
         return 0;
}

#include <stdio.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <utility>
using namespace std;
typedef pair<int,int> pi;
#define F first
#define S second
#define MP make_pair
#define PB push_back
const int N=1e5+10;
int main(){
    int n,m,ans,a[N],b[N],now=0;
    pi q[N];
    vector<int> lis;
    priority_queue<int,vector<int>,greater<int>>pq;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)scanf("%d%d",&q[i].F,&q[i].S);
    sort(q,q+n);
    q[n]=MP(1e9,1e9);
    for(int i=1;i<=m;i++){
        while(q[now].F<=i)pq.push(q[now++].S);
        while(!pq.empty()){
            if(pq.top()<i)pq.pop();
            else break;
        }
        a[i]=static_cast<int>(pq.size());
    }
    lis.clear();
    lis.PB(a[1]);
    b[1]=1;
    b[0]=0;
    for(int i=2;i<=m;i++){
        if(a[i]>=lis.back())lis.PB(a[i]);
        else *upper_bound(lis.begin(),lis.end(),a[i])=a[i];
        b[i]=static_cast<int>(lis.size());
    }
    lis.clear();
    lis.PB(a[m]);
    ans=max(b[m-2]+1,b[m]);
    for(int i=m-1;i>1;i--){
        if(a[i]>=lis.back())lis.PB(a[i]);
        else *upper_bound(lis.begin(),lis.end(),a[i])=a[i];
        ans=max(ans,max(static_cast<int>(lis.size()),static_cast<int>(lis.size()+b[i-2])));
    }
    if(a[1]>=lis.back())lis.PB(a[1]);
    ans=max(ans,static_cast<int>(lis.size()));
    printf("%d\n",ans);
}

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int a[maxn],cnt[maxn],dp[maxn];
int main()
{
	int n,m,l,r;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&l,&r);
		cnt[l]++;
		cnt[r+1]--;
	}
	int tol=0,j,mx=0,sum=0,ans=0,sum1=0;
	for(int i=1;i<=m;i++)
	{
		tol+=cnt[i];
		a[i]=tol;
		mx=max(mx,tol);
	}
	for(int i=1;i<=m;i++)
	{
		if(a[i]==mx)
		{
			a[i]=1;
		}
		else
		{
			a[i]=0;
		}
	}
	tol=0;
	for(int i=1;i<=m;i++)
	{
		for(j=i;j<=m;j++)
		{
			if(a[j]!=a[i])
			{
				break;
			}
		}
		cnt[++tol]=j-i;
		a[tol]=a[i];
		if(a[tol]==0)sum1+=cnt[tol];
		i=j-1;
	}

	dp[0]=0;
	for(int i=1;i<=tol;i++)
	{
		if(a[i]==0)
		{
			sum+=cnt[i];
			dp[i]=dp[i-1];
		}
		else
		{
			dp[i]=max(dp[i-1]+cnt[i],sum+cnt[i]);
			ans=max(ans,dp[i]+sum1-sum);
		}
	}
	printf("%d\n",ans);
	return 0;
}

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#include <vector>
#include <iostream>
#include <iomanip>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <time.h>
using namespace std;

typedef double LD;
typedef long long LL;
typedef pair<int, int> PII;
#define MP make_pair
#define PB push_back
#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define RFOR(i,b,a) for(int i = (b) - 1; i >= (a); --i)
#define REP(i, t) FOR(i,0,t)
#define ALL(a) a.begin(), a.end()
#define SZ(a) (int)((a).size())

const LL MOD = 1000000007;
const int INF = 1000000007;
const LL LINF = 1LL * INF * INF;
const int MAXN = 100007;
const LD EPS = 1e-6;

int C[MAXN], A[MAXN];
PII D1[MAXN], D2[MAXN];

int main()
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	//freopen("In.txt", "r", stdin);
	int n, m, ans = 0;
	cin >> n >> m;
	REP(i, n)
	{
		int l, r;
		cin >> l >> r;
		++C[l];
		--C[r + 1];
	}
	FOR(i, 1, m + 1)
		C[i] += C[i - 1];
	D1[0] = D2[0] = MP(-INF, 0);
	FOR(i, 1, m + 1)
		D1[i] = D2[i] = MP(INF, 0);
	FOR(i, 1, m + 1)
	{
		int j = upper_bound(D1, D1 + m + 1, MP(C[i], i)) - D1;
		if (D1[j - 1] < MP(C[i], i) && MP(C[i], i) < D1[j])
			D1[j] = MP(C[i], i);
	}
	RFOR(i, m + 1, 1)
	{
		int j = upper_bound(D2, D2 + m + 1, MP(C[i], -i)) - D2;
		if (D2[j - 1] < MP(C[i], -i) && MP(C[i], -i) < D2[j])
			D2[j] = MP(C[i], -i);
	}
	REP(i, m + 1)
		A[i] = D1[i].second;
	FOR(i, 1, m + 1)
	{
		if (D2[i].first == INF)
			break;
		int j = lower_bound(A, A + m + 1, -D2[i].second - 1) - A;
		if (A[j] >= -D2[j].second)
			--j;
		ans = max(ans, i + j);
	}
	cout << ans;
	//cout << endl; system("pause");
	return 0;
}

#pragma gcc optimize("OFast")
#pragma gcc target("sse,sse2,sse3,sse4,tune=native")
//#pragma gcc optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
const int maxn = 1e5, INF = 1e9;
const ll llINF = 1e18;

struct segTree {
    int n; vector<int> t;
    segTree(int n) : n(n), t(2 * n, 0) {}
    void upd(int l, int r) {
        for(l += n, r += n; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1) {
            if(l & 1) t[l]++;
            if(!(r & 1)) t[r]++;
        }
    }
    int get(int pos) {
        int ret = 0;
        for(pos += n; pos; pos >>= 1) ret += t[pos];
        return ret;
    }
};

struct segTree1 {
    int n; vector<int> t;
    segTree1(int n) : n(n), t(2 * n, 0) {}
    void upd(int v, int x) {
        t[v += n] = x;
        for(v >>= 1; v; v >>= 1) t[v] = max(t[v * 2], t[v * 2 + 1]);
    }
    int get(int l, int r) {
        int ret = 0;
        for(l += n, r += n; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1) {
            if(l & 1) ret = max(ret, t[l]);
            if(!(r & 1)) ret = max(ret, t[r]);
        }
        return ret;
    }
};

int n, m;

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    //freopen("in.txt", "r", stdin);
    cin >> n >> m;
    segTree t(m);
    for(int i = 0; i < n; i++) {
        int l, r; cin >> l >> r; l--; r--;
        t.upd(l, r);
    }
    vector<int> a(m);
    for(int i = 0; i < m; i++) a[i] = t.get(i);
    segTree1 t1(n + 1);
    int ans = 0;
    for(int i = 0; i < m; i++) {
        if(a[i] == 0) continue;
        int x = 1 + t1.get(0, a[i]);
        t1.upd(a[i], x);
        ans = max(ans, x);
    }
    reverse(all(a));
    segTree1 t2(n + 1);
    for(int i = 0; i < m; i++) {
        if(a[i] == 0) continue;
        int x = 1 + t2.get(0, a[i]);
        t2.upd(a[i], x);
        ans = max(ans, x);
    }
    cout << ans;
}

#define make_pair mp
#define push_back pb
#include <iostream>
#include <cstdio>
#include <stack>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#include <bitset>
#include <cstdlib>
#include <random>
#include <ctime>
#include <map>
using namespace std;
const int N = 1e5 + 5, D = (1<<18) + 5, pods = (1<<17) - 1;
int n, m, cnt[N], d[D], best_pref[N], best_suf[N];
int ilp[N], ilk[N];
void add(int x, int val) {
	x += pods;
	d[x] = val;
	while(x != 1) {
		x /= 2;
		d[x] = max(d[2*x], d[2*x+1]);
	}
}
int maks(int x, int y) {
	x += pods;
	y += pods;
	int ans = max(d[x], d[y]);
	while(x / 2 != y / 2) {
		if(x % 2 == 0) ans = max(ans, d[x+1]);
		if(y % 2 == 1) ans = max(ans, d[y-1]);
		x /= 2;
		y /= 2;
	}
	return ans;
}
int main()
{
	scanf("%d%d", &n, &m);
	int l, r;
	for(int i=1;i<=n;i++) {
		scanf("%d%d", &l, &r);
		ilp[l]++;
		ilk[r]++;
	}
	int c = 0;
	for(int i=1;i<=m;i++) {
		c += ilp[i];
		cnt[i] = c;
		c -= ilk[i];
	}
	for(int i=1;i<=m;i++) {
		best_pref[i] = 1 + maks(1, cnt[i] + 1);
		add(cnt[i] + 1, best_pref[i]);
	}
	for(int i=0;i<D;i++) d[i] = 0;
	for(int i=m;i>0;i--) {
		best_suf[i] = 1 + maks(1, cnt[i] + 1);
		add(cnt[i] + 1, best_suf[i]);
	}
	int ans = 0;
	for(int i=1;i<=n;i++) ans = max(ans, best_pref[i] + best_suf[i] - 1);
	printf("%d", ans);
	return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#include <algorithm>
#include <cstdio>
#include <ctime>
#include <map>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <cassert>
#include <iostream>
#include <cmath>
#include <sstream>
#include <complex>
#include <memory.h>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;

#define y1 _dsfkjdsfksdj
#define y0 _sfsdkfdop

typedef unsigned uint;
typedef vector<int64> vi64;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef pair<int,string> pis;
typedef pair<int64,int64> pii64;
typedef pair<int, pii> piii;
typedef pair<pii,pii> piiii;
typedef pair<int64,pii> qelem;
typedef vector<pii> vpii;
typedef vector<vpii> vvpii;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;

int n, m;
vector<pii> ev;
vector<int> a;
vector<int> la;
vector<int> ra;
vector<int> lk;

inline void init() {
    scanf("%d%d", &n, &m);
    ev.clear();
    int l, r;
    for (int i = 0; i < n; ++i) {
        scanf("%d%d", &l, &r);
        --l, --r;
        ev.push_back(pii(l, 0));
        ev.push_back(pii(r, 1));
    }
    sort(ev.begin(), ev.end());
    a.assign(m, 0);
    int k = static_cast<int>(ev.size());
    int cur = 0;
    int cnt = 0;
    for (int i = 0; i < m; ++i) {
        while (cur < k && ev[cur].first == i && !ev[cur].second) {
            ++cnt;
            ++cur;
        }
        a[i] = cnt;
        while (cur < k && ev[cur].first == i) {
            --cnt;
            ++cur;
        }
    }
}

int main() {
#ifdef _PKHAU_DEBUG
    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif

    init();

    la.resize(m);
    vector<int> b(1, 0);
    for (int i = 0; i < m; ++i) {
        int l = 1, r = static_cast<int>(b.size()) - 1;
        int ind = 0;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (b[mid] > a[i]) {
                r = mid - 1;
            } else {
                ind = mid;
                l = mid + 1;
            }
        }
        if (ind + 1 == static_cast<int>(b.size())) {
            la[i] = static_cast<int>(b.size());
            b.push_back(a[i]);
        } else {
            la[i] = ind + 1;
            b[ind + 1] = min(b[ind + 1], a[i]);
        }
    }

    ra.resize(m);
    vector<int> c(1, 0);
    for (int i = m - 1; i >= 0; --i) {
        int l = 1, r = static_cast<int>(c.size()) - 1;
        int ind = 0;
        while (l <= r) {
            int mid = (l + r) >> 1;
            if (c[mid] > a[i]) {
                r = mid - 1;
            } else {
                ind = mid;
                l = mid + 1;
            }
        }
        if (ind + 1 == static_cast<int>(c.size())) {
            ra[i] = static_cast<int>(c.size());
            c.push_back(a[i]);
        } else {
            ra[i] = ind + 1;
            c[ind + 1] = min(c[ind + 1], a[i]);
        }
    }

    int res = 0;
    lk.assign(m, m);
    for (int i = m - 1; i >= 0; --i) {
        int ind = i + 1;
        while (ind < m) {
            if (a[ind] < a[i]) break;
            ind = lk[ind];
        }
        lk[i] = ind;
        res = max(res, la[i]);
        res = max(res, ra[i]);
        if (ind == m) continue;
        res = max(res, la[i] + ra[ind]);
    }

    printf("%d\n", res);

    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 1e5 + 5;

int N, M;
int A[MAX_N], P[MAX_N], fwd[MAX_N], bck[MAX_N];
int fenwick[MAX_N];

void upd(int i, int x) {
    for ( ; i <= M; i += i & -i) fenwick[i] += x;
}

int qry(int i) {
    int r = 0;
    for ( ; i > 0; i -= i & -i) r += fenwick[i];
    return r;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL);

    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        int l, r; cin >> l >> r;
        upd(l, 1); upd(r + 1, -1);
    }

    int j = 0;
    for (int i = 0; i < M; i++) { A[j] = qry(i + 1); if (A[j]) j++; }
    M = j;

    int L = 0;
    for (int i = 0; i < M; i++) {
        int lo = 1, hi = L;
        while (lo <= hi) {
            int mid = (lo + hi + 1) >> 1;
            if (A[P[mid]] <= A[i])
                lo = mid + 1;
            else
                hi = mid - 1;
        }
        int nL = lo;
        P[nL] = i;
        L = max(L, nL);
        fwd[i] = L;
    }

    L = 0;
    for (int i = M - 1; i >= 0; i--) {
        int lo = 1, hi = L;
        while (lo <= hi) {
            int mid = (lo + hi + 1) >> 1;
            if (A[P[mid]] <= A[i])
                lo = mid + 1;
            else
                hi = mid - 1;
        }
        int nL = lo;
        P[nL] = i;
        L = max(L, nL);
        bck[i] = L;
    }

    int ans = 0;
    for (int i = 0; i < M - 1; i++)
        ans = max(ans, fwd[i] + bck[i + 1]);
    cout << ans << "\n";

    return 0;
}

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define F first
#define S second
#define ll long long
#define ull  unsigned long long
#define pb push_back
#define double long double

using namespace std;
using namespace __gnu_pbds;
typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int N = 505000;
int t[N], a[N], s[N], dp1[N], dp2[N];
int query(int v, int tl, int tr, int l, int r){
    if (l > r) return 0;
    if (tl == l && tr == r) return t[v];
    int mid = (tl + tr) / 2;
    return max(query(v + v, tl, mid, l, min(mid, r)), query(v + v + 1, mid + 1, tr, max(mid + 1, l), r));
}
void update (int v, int tl, int tr, int pos, int val){
    if (tl == tr){
        t[v] = max(t[v], val);
        return;
    }
    int mid = (tl + tr) / 2;
    if (pos <= mid)update(v + v, tl, mid, pos, val); else
    update(v + v + 1, mid + 1, tr, pos, val);
    t[v] = max(t[v + v], t[v + v + 1]);
}
main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++){
        int l, r;
        cin >> l >> r;
        s[l]++;
        s[r + 1]--;
    }
    int x = 0;
    for (int i = 1; i <= m; i++){
        x += s[i];
        a[i] = x;
    }
    for (int i = 1; i <= m; i++){
        dp1[i] = max(dp1[i - 1], 1 + query(1, 0, n, 0, a[i]));
        update(1, 0, n, a[i], dp1[i]);
    }
    memset(t, 0, sizeof(t));
    for (int i = m; i >= 1; i--){
        dp2[i] = max(dp2[i + 1], 1 + query(1, 0, n, 0, a[i]));
        update(1, 0, n, a[i], dp2[i]);
    }
    int ans = 0;
    for (int i = 1; i <= m; i++){
        ans = max(ans, dp1[i] + dp2[i] - 1);
    }
    cout << ans;
}

#include<bits/stdc++.h>
using namespace std;
#define s(n) scanf("%lld",&n)
#define p(n) printf("%lld\n",n)
#define sf scanf
#define pf printf
#define ll int
#define vll vector<ll>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define hell 1000000007
#define endl "\n"
#define inc(i,a,b) for(i=a;i<b;i++)
#define dec(i,a,b) for(i=a;i>b;i--)
#define all(c) c.begin(), c.end()
#define tr(c,i) for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define sz(a) (ll)((a).size())
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element) (find(all(container),element) != container.end())
#define trace(x)                 cerr << #x << ": " << x << endl;
#define trace1(x)                cerr << #x << ": " << x << endl;
#define trace2(x, y)             cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)          cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)       cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << endl;
#define trace5(a, b, c, d, e)    cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;

ll A[100001],tree[400001],lazy[400001];

void updateRange(int node, int start, int end, int l, int r, int val)
{
	if(lazy[node] != 0)
	{
		// This node needs to be updated
		tree[node] += (end - start + 1) * lazy[node];    // Update it
		if(start != end)
		{
			lazy[node*2] += lazy[node];                  // Mark child as lazy
			lazy[node*2+1] += lazy[node];                // Mark child as lazy
		}
		lazy[node] = 0;                                  // Reset it
	}
	if(start > end or start > r or end < l)              // Current segment is not within range [l, r]
		return;
	if(start >= l and end <= r)
	{
		// Segment is fully within range
		tree[node] += (end - start + 1) * val;
		if(start != end)
		{
			// Not leaf node
			lazy[node*2] += val;
			lazy[node*2+1] += val;
		}
		return;
	}
	int mid = (start + end) / 2;
	updateRange(node*2, start, mid, l, r, val);        // Updating left child
	updateRange(node*2 + 1, mid + 1, end, l, r, val);   // Updating right child
	tree[node] = tree[node*2] + tree[node*2+1];        // Updating root with max value
}

int queryRange(int node, int start, int end, int l, int r)
{
	if(start > end or start > r or end < l)
		return 0;         // Out of range
	if(lazy[node] != 0)
	{
		// This node needs to be updated
		tree[node] += (end - start + 1) * lazy[node];            // Update it
		if(start != end)
		{
			lazy[node*2] += lazy[node];         // Mark child as lazy
			lazy[node*2+1] += lazy[node];    // Mark child as lazy
		}
		lazy[node] = 0;                 // Reset it
	}
	if(start >= l and end <= r)             // Current segment is totally within range [l, r]
		return tree[node];
	int mid = (start + end) / 2;
	int p1 = queryRange(node*2, start, mid, l, r);         // Query left child
	int p2 = queryRange(node*2 + 1, mid + 1, end, l, r); // Query right child
	return (p1 + p2);
}

vll v;

signed main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	ll t=1,n,m,i,j,k,sum=0,ans=0;
	string s;
	cin>>n>>m;
	for(i=0;i<n;i++){
		cin>>j>>k;
		updateRange(1,1,m,j,k,1);
	}
	for(i=1;i<=m;i++){
		A[i]=queryRange(1,1,m,i,i);
	}
	v.pb(A[1]);
	for(i=2;i<=m;i++){
		n=v.size();
		if(A[i]>=v[n-1]){
			v.pb(A[i]);
		}
		else{
			ll low=0,high=n-1,mid;
			while(low<=high){
				mid=(low+high)/2;
				if(A[i]>v[mid]){
					ans=mid;
					high=mid-1;
				}
				else{
					low=mid+1;
				}
			}
			v[ans]=A[i];
		}
	}
	cout<<v.size();
	return 0;
}

#include <iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for(int i=m;i<(int)(n);i++)
typedef long long ll;
typedef pair<ll,ll> pint;
const int inf   = 510101010;
const int mod=1e9+7;
const ll longinf=1LL<<60;

int main() {
  int n,m;
  cin>>n>>m;
  int a[m+1];
  rep(i,m+1)a[i]=0;
  rep(i,n){
    int l,r;
    cin>>l>>r;
    a[l-1]++;
    a[r]--;
    }
  rep(i,m)a[i+1]+=a[i];
  int num1[m+1],num2[m+1];
  num1[0]=0;num2[m]=0;
  int dp1[m+1],dp2[m+1];
  rep(i,m+1)dp1[i]=dp2[i]=inf;
  rep(i,m){
    *upper_bound(dp1,dp1+m,a[i])=a[i];
    num1[i+1]=lower_bound(dp1,dp1+m,inf)-dp1;
    }
  reverse(a,a+m);
  rep(i,m){
    *upper_bound(dp2,dp2+m,a[i])=a[i];
    num2[m-1-i]=lower_bound(dp2,dp2+m,inf)-dp2;
    }
  int ans=0;
  rep(i,m+1)ans=max(ans,num1[i]+num2[i+1]);
  cout<<ans<<endl;
  return 0;
  }

// writer: w33z8kqrqk8zzzx33
#include <bits/stdc++.h>
using namespace std;

#define iter(i, a, b) for(int i=(a); i<(b); i++)
#define rep(i, a) iter(i, 0, a)
#define rep1(i, a) iter(i, 1, (a)+1)
#define fi first
#define se second
#define pb push_back

#define ll long long
#define pii pair<int, int>
//#define int ll
const int MOD = 1000000007;

void upd(int idx, int l, int r, int i, int v, vector<int>& dt) {
    if(!(l <= i && i < r)) return;
    assert(r-l);
    if(r-l == 1) {
        assert(l == i);
        dt[idx] = max(dt[idx], v);
        return;
    }
    upd(idx*2, l, (l+r)/2, i, v, dt);
    upd(idx*2+1, (l+r)/2, r, i, v, dt);
    dt[idx] = max(dt[idx*2], dt[idx*2+1]);
}
int qry(int idx, int l, int r, int L, int R, vector<int>& dt) {
    if(L <= l && r <= R) return dt[idx];
    if(R <= l || r <= L) return 0;
    assert(r-l);
    return max(qry(idx*2, l, (l+r)/2, L, R, dt),
               qry(idx*2+1, (l+r)/2, r, L, R, dt));
}

int cf[100005];
int dp[100005][2];
signed main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    int n, m; cin >> n >> m;
    rep(i, n) {
        int u, v; cin >> u >> v;
        cf[u]++; cf[v+1]--;
    }
    rep1(i, m) cf[i] += cf[i-1];
    vector<int> Seg1(1<<20), Seg2(1<<20);
    int qj = 0;
    rep1(i, m) {
        dp[i][0] = qry(1, 1, n+1, 1, cf[i]+1, Seg1) + 1;
        dp[i][1] = max(dp[i][0], qry(1, 1, n+1, cf[i], n+1, Seg2) + 1);
        upd(1, 1, n+1, cf[i], dp[i][0], Seg1);
        upd(1, 1, n+1, cf[i], dp[i][1], Seg2);
        qj = max(qj, dp[i][1]);
    }
    cout << qj;
}

#include <bits/stdc++.h>

using namespace std;

#define sqr(x) ((x) * (x))
#define pb push_back
#define mp make_pair
#define X first
#define Y second
#define fin(name) freopen(name, "r", stdin)
#define fout(name) freopen(name, "w", stdout)
#define I(x, a) for(auto x : a)
#define F(i, l, r) for(auto i = l; i < r; ++i)
#define E(i, l, r) for(auto i = l; i <= r; ++i)
#define DF(i, l, r) for(auto i = l; i >= r; --i)
#define clean(a) memset((a),0,sizeof (a))
#define sync ios_base::sync_with_stdio(0);cin.tie(0)
#define all(x) (x).begin(),(x).end()
#define ret return
#define cont continue
#define brk break
#define ins insert
#define sz(a) ((int)(a).size())

typedef long long ll;
typedef unsigned long long ull;
typedef long double dbl;
typedef pair <int, int> pii;

const int inf = (int)1e9;
const ll linf = (ll)1e18;
const int mod = (int)1e9 + 7;
const dbl eps = (dbl)1e-8;
const int maxn = (int)1e5 + 5;
const dbl pi = acos(-1);

int t[4 * maxn];
int n, m, s[maxn], ans[maxn];
pair <int, int> a[maxn];
int pos[maxn], mxpos[maxn], mnpos[maxn];

int getmx(int v, int l, int r, int tl, int tr) {
	if (tl > tr || l > r)
		return 0;
	if (l == tl && r == tr)
		return t[v];
	int m = (l + r) / 2;
	return max(getmx(2 * v, l, m, tl, min(m, tr)), getmx(2 * v + 1, m + 1, r, max(tl, m + 1), tr));
}

void upd(int v, int l, int r, int pos, int x) {
	if (pos < l || pos > r || l > r)
		return;
	t[v] = max(t[v], x);
	if (l == r)
		return;
	int m = (l + r) / 2;
	upd(2 * v, l, m, pos, x);
	upd(2 * v + 1, m + 1, r, pos, x);
}

int main() {
//    fin("t.in");
    sync;
    cin >> n >> m;
    F(i, 0, n) {
    	int l, r;
    	cin >> l >> r;
    	++s[l];
    	--s[r + 1];
    }
    E(i, 2, m) {
    	s[i] = s[i - 1] + s[i];
    }
    E(i, 1, m) {
    	a[i] = {s[i], i};
    }
    sort(a + 1, a + m + 1);
    clean(mxpos);
    E(i, 0, m)
    	mnpos[i] = m;
    E(i, 1, m) {
    	mxpos[a[i].X] = max(mxpos[a[i].X], i);
    	mnpos[a[i].X] = min(mnpos[a[i].X], i);
    	pos[a[i].Y] = i;
    }
    clean(t);
    clean(ans);
    E(i, 1, m) {
    	int x = 1 + getmx(1, 1, m, 1, mxpos[s[i]]);
    	upd(1, 1, m, pos[i], x);
    	ans[i] += x;
    }
    clean(t);
    int o = 0;
    DF(i, m, 1) {
    	int x = 1 + getmx(1, 1, m, mnpos[s[i]], m);
    	upd(1, 1, m, pos[i], x);
    	ans[i] += x;
    	o = max(ans[i] - 1, o);
    }
    cout << o << endl;
    return 0;
}

#include "bits/stdc++.h"
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")
using namespace std;
template< typename T > class fenwick_tree{
private:
	static const int default_size = 100100;
	int my_size;
	vector<T> fenwick;
public:
	fenwick_tree(){
		my_size = default_size;
		clear();
	}
	fenwick_tree(int size){
		my_size = size;
		clear();
	}
	void clear(){
		fenwick.assign(my_size, T());
	}
	void add(int pos, T v){
		for(pos++;pos < my_size; pos += pos & - pos)
			fenwick[pos] = fenwick[pos] + v;
	}
	T sum(int pos){
		T ans = T();
		for(pos++;pos; pos -= pos & - pos)
			ans = ans + fenwick[pos];
		return ans;
	}
};
const int maxn = 100100;
int p[maxn], ls[maxn], dp[maxn];
int bit[maxn];
vector<int> where[maxn];
void add(int x, int v){
	for(x++; x < maxn; x += x & x)
		bit[x] = max(bit[x], v);
}
int sum(int x){
	int ans = 0;
	for(x++; x ; x -= x & - x)
		ans = max(ans, bit[x]);
	return ans;
}
int m;
int app(vector<int> pt){
	memset(bit, 0, sizeof(bit));
	int len = pt.size();
	for(int e = 1; e <= len; e++){
		int now = sum(pt[e-1]);
		add(pt[e-1], now + 1);
		dp[e] = now + 1;
	}
	for(int e = 0; e < maxn; e++) where[e].clear();
	for(int e = 1; e <= len; e++) where[pt[e-1]].push_back(e);
	memset(bit, 0, sizeof(bit));
	fenwick_tree<int> save;
	int best = 0;
	int tot = 0;
	for(int e = 1; e < maxn; e++){
		if(where[e].empty()) continue;
		for(int f = 0; f < where[e].size(); f++){
			int l = where[e][f];
			int toback = sum(l - 1);
			int bads = save.sum(len) - save.sum(l);
			int help = (where[e].size() - f);
			if(where[e][f] != len){
				// cout << where[e][f] << " " << toback << " " << help << " " << bads << endl;
				best = max(best,  toback + help);
			}
			add(where[e][f], dp[where[e][f]]);
			save.add(where[e][f], 1);
		}
	}
	return best;
}
int main(){
	int n;
	scanf("%d %d", &n, &m);
	for(int e = 0; e < n; e++){
		int l, r;
		scanf("%d %d", &l, &r);
		p[l]++;
		p[r+1]--;
	}
	for(int e = 1; e <= m; e++) p[e] += p[e-1];
	vector<int> pts;
	for(int e = 1; e <= m; e++) pts.push_back(p[e]);
	int tot = 0;
	tot = max(tot, app(pts));
	reverse(pts.begin(), pts.end());
	tot = max(tot, app(pts));
	cout << tot << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define int long long
#define pb push_back
#define sz size()

const int inf = 1e9;
const int M = 1e6 +1;
const int mod = 1e9 +7;
const int N = 2*1e5 +1;

int n, m, l, r, a[N], tree[4*N], _sz, cur;

int get(int v, int lv, int rv, int r)
{
    if(lv > r) return 0;
    if(r >= rv) return tree[v];

    int mid = (lv+rv)/2;

    return max(get(v+v, lv, mid, r), get(v+v+1, mid+1, rv, r));
}

inline void upd(int pos, int val)
{
    pos += _sz-1;

    while(pos)
    {
        tree[pos] = max(tree[pos], val);

        pos /= 2;
    }
}

main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cout << setprecision(10) << fixed;

    cin >> n >> m;

    for(int i = 1; i <= n; i++)
    {
        cin >> l >> r;

        a[l]++;
        a[r+1]--;
    }

    for(int i = 1; i <= m; i++)
    {
        a[i] += a[i-1];
    }

    for(_sz = 1; _sz < n; _sz += _sz){}

    for(int i = 1; i <= m; i++)
    {
        upd(a[i], get(1, 1, _sz, a[i]) +1);
    }

    cur = get(1, 1, _sz, _sz);

    memset(tree, 0, sizeof(tree));

    for(int i = m; i; i--)
    {
        upd(a[i], get(1, 1, _sz, a[i]) +1);
    }

    cur = max(cur, get(1, 1, _sz, _sz));

    cout << cur;
}

#include <bits/stdc++.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
long long mod=1e9+7;
long long INF=1e7;
double EPS = 1e-12;
typedef long long int lld;
double tick(){static clock_t oldt;clock_t newt=clock();double diff=1.0*(newt-oldt)/CLOCKS_PER_SEC;oldt = newt;return diff;}
#define rep(i,a,n) for(long long int i = (a); i <= (n); ++i)
#define repI(i,a,n) for(int i = (a); i <= (n); ++i)
#define repD(i,a,n) for(long long int i = (a); i >= (n); --i)
#define repDI(i,a,n) for(int i = (a); i >= (n); --i)
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sc(a) scanf("%lld",&a)
#define sc2(a,b) scanf("%lld%lld",&a,&b)
#define sc3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define scd(a) scanf("%d",&a)
#define scd2(a,b) scanf("%d%d",&a,&b)
#define scd3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scf(a) scanf("%lf",&a)
#define scf2(a,b) scanf("%lf%lf",&a,&b)
#define scf3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define prL(a) printf("%lld\n",a)
#define prS(a) printf("%lld ",a)
#define prdL(a) printf("%d\n",a)
#define prdS(a) printf("%d ",a)
#define all(c) c.begin(), c.end()
#define sz(a) ((int)a.size())
#define Error(x) cout<< #x << " = " << (x) <<endl;
#define Error2(a,b) cout<<"( "<<#a<<" , "<<#b<<" ) = ( "<<(a)<<" , "<<(b)<<" )\n";
#define Error3(a,b,c) cout<<"("<<#a<<" , "<<#b<<" , "<<#c<<" ) = ( "<<(a)<<" , "<<(b)<<" , "<<(c)<<")\n";
#define Error4(a,b,c,d) cout<<"("<<#a<<" , "<<#b<<" , "<<#c<<" , "<<#d<<" ) = ( "<<(a)<<" , "<<(b)<<" , "<<(c)<<" , "<<(d)<<")\n";
#define errop(a) cout<<#a<<" = ( "<<((a).x)<<" , "<<((a).y)<<" )\n";
#define mset(a, v) memset(a, v, sizeof(a))
#define popcount __builtin_popcountll

typedef pair<lld,lld> PA;

lld powP(lld a,lld b){
    if(b==0) return 1%mod;
    lld k;
    k=powP(a,b/2);
    k=k*k%mod;
    if(b%2==0) return k;
    else return a*k%mod;
}

bool bitSet(lld n,lld i){
    if((n&(1LL<<i))!=0) return true;
    else return false;
}

lld findGcd(lld a,lld b){
    if(a==0) return b;
    else return findGcd(b%a,a);
}

#define lim 100010
#define lim2 203
lld C[lim],A[lim],B[lim],D[lim],Forward[lim],Backward[lim];

// char S[lim];
// map<lld,lld> M;
// map<lld,lld>::iterator it;
// map<string,lld> M,Mn;
// string S[lim];

lld bina(lld k,lld n){
    lld low=0,high=n-1,mid;
    while(high-low>1){
        mid=low+(high-low)/2;
        if(A[mid]<=k) low=mid;
        else high=mid-1;
    }
    if(A[high]<=k) return high;
    else return low;
}
lld binaBack(lld k,lld n){
    lld low=0,high=n-1,mid;
    while(high-low>1){
        // Error2(low,high);
        mid=low+(high-low)/2;
        if(B[mid]<=k) low=mid;
        else high=mid-1;
    }
    if(B[high]<=k) return high;
    else return low;
}

int main(){
    lld i,j,k,l,r,s,a,b,c,d,x,y,z,m,n,t,p,q,T,curr,sum,ans,pos,val,countA;
    sc2(n,m);
    for(i=1;i<=n;i++) {
        sc2(l,r);
        D[l]++;
        D[r + 1]--;
    }
    curr = 0;
    for(i=1;i<=m;i++) {
        curr += D[i];
        // B[i] = curr;
        // Error2(i,B[i]);
        // C[curr]++;
        C[i] = curr;
    }
    A[0]=1;
    a=1;
    for(i=1;i<=m;i++){
        // sc(j);
        j = C[i];
        if(j == 0) {
            Forward[i] = 0;
            continue;
        }
        t=bina(j,a);
        A[t+1]=j;
        Forward[i] = t + 1;
        if(t==a-1) a++;
    }
    B[0]=1;
    a=1;
    for(i=m;i>=1;i--){
        // sc(j);
        j = C[i];
        if(j == 0) {
            Backward[i] = 0;
            continue;
        }
        t=binaBack(j,a);
        B[t+1]=j;
        Backward[i] = t + 1;
        if(t==a-1) a++;
    }
    // prL(a-1);
    ans = 0;
    for(i=1;i<=m;i++) {
        ans = max(ans, Forward[i] + Backward[i] - 1);
        // Error4(i,C[i],Forward[i],Backward[i]);
    }
    prL(ans);
    return 0;
}

#define  _CRT_SECURE_NO_WARNINGS
#include "bits/stdc++.h"
using namespace std;
#define Ma_PI 3.141592653589793
#define eps 0.00000001
#define LONG_INF 3000000000000000000
#define GOLD 1.61803398874989484820458
#define MAX_MOD 1000000007
#define REP(i,n) for(long long i = 0;i < n;++i)
#define seg_size 524288
long long imossing[200000] = {};
long long griding[200000] = {};
vector<long long> dp[2];
int gee[200000] = {};
int main(){
#define int long long
	int n, m;
	cin >> n >> m;
	REP(i, n) {
		int a, b;
		cin >> a >> b;
		imossing[a]++;
		imossing[b + 1]--;
	}
	for (int i = 1; i <= m; ++i) {
		griding[i] = griding[i - 1] + imossing[i];
	}
	for (int neko = 0; neko < 2; ++neko) {
		dp[neko].push_back(griding[1]);
		for (int q = 2; q <= m; ++q) {
			int top = dp[neko].size() - 1;
			int bot = 0;
			while (top - bot > 1) {
				int mid = (top + bot) / 2;
				if (dp[neko][mid] > griding[q]) {
					top = mid;
				}
				else bot = mid;
			}
			if (dp[neko][bot] > griding[q]) {
				dp[neko][bot] = griding[q];
			}
			else if (dp[neko][top] > griding[q]) {
				dp[neko][top] = griding[q];
			}
			else {
				dp[neko].push_back(griding[q]);
			}
		}
		for (int q = 1; q <= m; ++q) {
			gee[m + 1 - q] = griding[q];
		}
		for (int q = 1; q <= m; ++q) {
			griding[q] = gee[q];
		}
	}
	cout << max(dp[0].size(), dp[1].size()) << endl;
	return 0;
}

/*input
4 6
1 3
2 3
4 6
4 6
*/
#include <bits/stdc++.h>
using namespace std;
int freq[100005],n,enter[100005],m;
int solve(int n){
	int inc[n]={freq[0]}, tail1[n]={0},dec[n],tail2[n]={0},in=1;
	for(int i=1;i<n;++i)
		if(freq[i]<inc[0])
			inc[tail1[i]=0] = freq[i];
		else if(freq[i]>=inc[in-1])
			inc[tail1[i]=in++]=freq[i];
		else
			inc[tail1[i]=upper_bound(inc,inc+in,freq[i])-inc-1] = freq[i];

	in = 1;
	reverse(freq,freq+n);
	dec[0] = freq[0];

	for(int i=1;i<n;++i)
		if(freq[i]<dec[0])
			dec[tail2[i]=0] = freq[i];
		else if(freq[i]>=dec[in-1])
			dec[tail2[i]=in++]=freq[i];
		else
			dec[tail2[i]=upper_bound(dec,dec+in,freq[i])-dec-1] = freq[i];

	reverse(freq,freq+n);
	reverse(tail2,tail2+n);
	int ans = 0;
	for(int i=0;i<n;++i)
		ans = max(ans,tail1[i]+tail2[i]+1);
	return ans;
}

int main(){
	ios_base::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=n,x,y;i--;++enter[x],--enter[y+1])
		cin>>x>>y;
	for(int i=0,run=0;i<=m;++i)
		freq[i] = (run+=enter[i]);
	cout<<solve(m);
}

#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast")
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <string>
#include <cmath>
#include <stack>
#include <iomanip>
#include <set>
#include <queue>
#include <cassert>
#include <unordered_map>
#include <random>

using namespace std;

#define ff first
#define ss second

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int maxn = 1e5 + 7;
const int inf = 2e9 + 7;
const ll infl = 1e18 + 7;
const long double eps = 1e-9;
const ll mod = 998244353;

vector<string> v[26];

ld p[26];

int main() {
#ifdef _DEBUG
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif // _DEBUG
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	srand(time(0));

	int n, m;
	cin >> n >> m;
	vector<int> cnt(m + 1, 0);
	vector<pair<int, int>> e;
	for (int i = 0; i < n; i++) {
		int l, r;
		cin >> l >> r;
		e.push_back({ l, 1 });
		e.push_back({ r, -1 });
	}
	sort(e.begin(), e.end());
	int j = 0, b = 0;
	for (int i = 1; i <= m; i++) {
		while (j < e.size() && i >= e[j].ff) {
			b += e[j].ss;
			j++;
		}
		cnt[i] = b;
	}

	vector<int> pref(m + 1), suff(m + 1);
	vector<int> dp(m + 1, inf);
	dp[0] = -1;
	for (int i = 1; i <= m; i++) {
		int ind = upper_bound(dp.begin(), dp.end(), cnt[i]) - dp.begin();
		pref[i] = ind;
		dp[ind] = cnt[i];
	}

	dp.assign(m + 1, inf);
	dp[0] = -1;
	for (int i = m; i >= 0; i--) {
		int ind = upper_bound(dp.begin(), dp.end(), cnt[i]) - dp.begin();
		suff[i] = ind;
		dp[ind] = cnt[i];
	}
	int ans = 0;
	for (int i = 1; i <= m; i++) {
		ans = max(ans, pref[i] + suff[i]);
	}
	cout << ans;
	return 0;
}

#include <bits/stdc++.h>
#define mid (l+r)/2
#define pb push_back
#define for(i,l,r) for (int i=l;i<r;i++)
using namespace std;
int n,m,l[100001],r[100001],cnt[100001],t[400001],lazy[400001];
void update(int l,int r,int s,int e,int node) {
	if (lazy[node]) {
		t[node]+=lazy[node];
		lazy[node*2]+=lazy[node];
		lazy[node*2+1]+=lazy[node];
		lazy[node]=0;
	}
	if (l>r||r<s||l>e) return;
	if (s<=l&&r<=e) {lazy[node]++; return;}
	update(l,mid,s,e,node*2); update(mid+1,r,s,e,node*2+1);
}
int get(int l,int r,int pos,int node) {
	if (lazy[node]) {
		t[node]+=lazy[node];
		lazy[node*2]+=lazy[node];
		lazy[node*2+1]+=lazy[node];
		lazy[node]=0;
	}
	if (l==r) return t[node];
	if (pos<=mid) return get(l,mid,pos,node*2);
	else return get(mid+1,r,pos,node*2+1);
}
int lis(int a[],int sizey) {
	vector<int> temp;
	for (i,0,sizey) {
		if (!temp.size()||a[i]>=temp[temp.size()-1]) temp.pb(a[i]);
		else {
			int pos=upper_bound(temp.begin(),temp.end(),a[i])-temp.begin();
			temp[pos]=a[i];
		}
	}
	return temp.size();
}
signed main() {
	//freopen("930C.inp","r",stdin);
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin>>n>>m; for (i,0,n) {cin>>l[i]>>r[i]; l[i]--; r[i]--;}
	/*
	To know if any segments end before our point x, check if there exist a point i that satisfy:
	cnt[x] < cnt[i] (At least 1 segment ended at point i)
	To know if any segments begin after our point x, check if there exist a point j that satisfy:
	cnt[x] < cnt[j] (At least 1 segment began at point j)
	So overall, to be sure that Teodor isn't lying, we proceed to find a position i:
	- cnt[j] > cnt[i] < cnt[k] (j <= i <= k)
	So overall, our set of questions must NOT contain any 3 positions that satisfy the above condition.
	So, we have 2 ways:
	- Find the longest non - decreasing subsequence (based on cnt). Then, cnt[j] > cnt[i] won't ever get
	applied and we can be sure our sequence is valid.
	- Find the longest non - increasing subsequence (based on cnt). Then, cnt[i] < cnt[k] won't ever
	get applied.
	Pick the longer length from these 2 and print it out.
	Total complexity: O(MlogM). Calculating cnt: O(NlogM) (Using a segment tree and lazy updates)
	*/
	memset(t,0,sizeof(t)); memset(lazy,0,sizeof(lazy));
	for (i,0,n) update(0,m-1,l[i],r[i],1);
	for (i,0,m) cnt[i]=get(0,m-1,i,1);
	int ans=-1;
	ans=max(ans,lis(cnt,m));
	reverse(cnt,cnt+m); ans=max(ans,lis(cnt,m));
	cout<<ans;
}

#include <bits/stdc++.h>

//#pragma GCC optimize("O3")
//#pragma GCC optimize("Ofast", "no-stack-protector")
//#pragma GCC target("sse", "sse2", "sse3", "ssse3", "sse4", "tune=native", "abm")

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define _ inline
#define f first
#define sec second
#define pb push_back
#define ins insert
#define ers erase
#define mk make_pair
#define rsz resize
//#define int ll
#define forn(i, n) for (int i(1); i <= n; i++)
#define fore(i, n) for (int i(0); i < n; i++)

#define next nextt
#define prev prevv
#define left leftt
#define right rightt

const int INF = 1e9 + 10;
const int MOD = 1e9 + 7;
const int P = 239017;
const ll BINF = 1e18 + 10;
const ld EPS = 1e-6;

mt19937 Random(int(time(0)));

const int N = 1e5 + 10;
int pref[N], arr[N], next_mn[N], next_mx[N], dp1[N], dp2[N], t1[8 * N], t2[8 * N];

void relax1(int v) {
    t1[v] = max(t1[2 * v], t1[2 * v + 1]);
}

void relax2(int v) {
    t2[v] = max(t2[2 * v], t2[2 * v + 1]);
}

void upd1(int v, int l, int r, int need, int val) {
    if (l == r) {
        t1[v] = max(t1[v], val);
        return;
    }
    int mid = (l + r) / 2;
    if (need <= mid) {
        upd1(2 * v, l, mid, need, val);
    }
    else {
        upd1(2 * v + 1, mid + 1, r, need, val);
    }
    relax1(v);
}

void upd2(int v, int l, int r, int need, int val) {
    if (l == r) {
        t2[v] = max(t2[v], val);
        return;
    }
    int mid = (l + r) / 2;
    if (need <= mid) {
        upd2(2 * v, l, mid, need, val);
    }
    else {
        upd2(2 * v + 1, mid + 1, r, need, val);
    }
    relax2(v);
}

int get_max1(int v, int l, int r, int a, int b) {
    if (l > b || r < a) {
        return 0;
    }
    if (l >= a && r <= b) {
        return t1[v];
    }
    int mid = (l + r) / 2;
    return max(get_max1(2 * v, l, mid, a, b), get_max1(2 * v + 1, mid + 1, r, a, b));
}

int get_max2(int v, int l, int r, int a, int b) {
    if (l > b || r < a) {
        return 0;
    }
    if (l >= a && r <= b) {
        return t2[v];
    }
    int mid = (l + r) / 2;
    return max(get_max2(2 * v, l, mid, a, b), get_max2(2 * v + 1, mid + 1, r, a, b));
}

_ void source() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        int l, r;
        cin >> l >> r;
        pref[l]++;
        pref[r + 1]--;
    }
    int sum = 0;
    for (int i = 1; i <= m; i++) {
        sum += pref[i];
        arr[i] = sum;
    }
    /*vector<pair<int, int> > st, st2;
    for (int i = m; i >= 1; i--) {
        while(!st.empty() && st.back().f <= arr[i]) {
            st.pop_back();
        }
        if (!st.empty()) {
            next_mx[i] = st.back().sec;
        }
        st.pb({arr[i], i});

        while(!st2.empty() && st2.back().f >= arr[i]) {
            st2.pop_back();
        }
        if (!st2.empty()) {
            next_mn[i] = st2.back().sec;
        }
        st2.pb({arr[i], i});
    }*/
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        dp1[i] = get_max1(1, 1, m, 1, arr[i]) + 1;
        upd1(1, 1, m, arr[i], dp1[i]);
        dp2[i] = get_max2(1, 1, m, arr[i], m) + 1;
        upd2(1, 1, m, arr[i], dp2[i]);
        ans = max(ans, dp1[i]);
        ans = max(ans, dp2[i]);
    }
    cout << ans;
}

signed main() {
#ifdef EXTRATERRESTRIAL_
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    source();
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T,class U> using P = pair<T,U>;
template<class T> using vec = vector<T>;
template<class T> using vvec = vector<vec<T>>;

template<typename Monoid,typename F>
class SegmentTree{
private:
    int sz;
    vector<Monoid> seg;
    const F op;//演算
    const Monoid e;//単位元
public:
    SegmentTree(int n,const F op,const Monoid &e):op(op),e(e){
        sz = 1;
        while(sz<=n) sz <<= 1;
        seg.assign(2*sz,e);
    }
    void set(int k, const Monoid &x){
        seg[k+sz] = x;
    }
    void build(){
        for(int i=sz-1;i>0;i--){
            seg[i] = op(seg[2*i],seg[2*i+1]);
        }
    }
    void update(int k,const Monoid &x){
        k += sz;
        seg[k] = x;
        while(k>>=1){
            seg[k] = op(seg[2*k],seg[2*k+1]);
        }
    }
    Monoid query(int l,int r){
        Monoid L = e,R = e;
        for(l+=sz,r+=sz;l<r;l>>=1,r>>=1){
            if(l&1) L = op(L,seg[l++]);
            if(r&1) R = op(seg[--r],R);
        }
        return op(L,R);
    }
    Monoid operator[](const int &k)const{
        return seg[k+sz];
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,M;
    cin >> N >> M;
    vec<int> L(N),R(N);
    vec<int> S(M+1,0);
    for(int i=0;i<N;i++){
        cin >> L[i] >> R[i];
        L[i]--; R[i]--;
        S[L[i]]++;
        S[R[i]+1]--;
    }
    for(int i=1;i<=M;i++) S[i] += S[i-1];
    auto mymax = [](int a,int b){return max(a,b);};
    SegmentTree<int,decltype(mymax)> seg(N+1,mymax,0);
    vec<int> dpL(M+1,0);
    for(int i=0;i<M;i++){
        int ma = seg.query(1,S[i]+1);
        dpL[i] = ma+1;
        seg.update(S[i],dpL[i]);
    }
    for(int i=0;i<=N;i++) seg.set(i,0);
    seg.build();
    vec<int> dpR(M+1,0);
    for(int i=M-1;i>=0;i--){
        int ma = seg.query(1,S[i]+1);
        dpR[i] = ma+1;
        seg.update(S[i],dpR[i]);
    }
    int ans = 0;
    for(int i=0;i<M;i++) ans = max(ans,dpL[i]+dpR[i+1]);
    cout << ans << endl;
}

#include <bits/stdc++.h>
using namespace std;

int main() {

  ios::sync_with_stdio(false);
  cout.tie(nullptr);
  cin.tie(nullptr);

  int n, m, mx = 0, mn = m, val = 0, cnt = 0;
  cin >> n >> m;

  vector<int> a(m + 2, 0);
  for (int i = 0; i < n; ++i) {
    int l, r;
    cin >> l >> r;

    a[l]++;
    a[r + 1]--;
  }

  for (int i = 0; i <= m; ++i) {
    if (i) a[i] += a[i-1];
    if (val < a[i]) {
      val = a[i];
      mn = mx = i;
      cnt = 1;
    } else if (val == a[i]) {
      mx = i;
      cnt++;
    }
  }

  for (int i = mn - 1; i >= 1; --i) {
    if (a[i] > a[i + 1]) {
      cout << 1 << '\n';
      return 0;
    }
  }

  for (int i = mx + 1; i <= m; ++i) {
    if (a[i] > a[i - 1]) {
      cout << 1 << '\n';
      return 0;
    }
  }
  cout << mn - 1 + m - mx + cnt << '\n';
}

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author parsa bahrami
 */

#pragma GCC optimize("O2")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pld;
typedef pair<string, string> pss;

template<class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define sz(x)                       (ll) x.size()
#define jjoin(x)                    for (auto i : x) cout << i << endl;
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second
#define Mp                          make_pair
#define sep                         ' '
#define error(x)                    cerr << #x << " = " << x << endl
#define fast_io                     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define set_random                  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define kill(x)                     return cout << x << endl , 0;
#define endl                        '\n'

ll poww(ll a, ll b, ll md) {
    return (!b ? 1 : (b & 1 ? a * poww(a * a % md, b / 2, md) % md : poww(a * a % md, b / 2, md) % md));
}

const ll MAXN = 2e5 + 10;
const ll MAXA = 101;
const ll INF = 8e18;
const ll MOD = 998244353; //1e9 + 7
const ld PI = 4 * atan((ld) 1);

template<ll SZ>
struct BITree {
    ll fen[SZ];

    BITree() {
        fill(fen, fen + SZ, 0);
    }

    void update(ll ind, ll val) {
        for (; ind < SZ; ind += (ind & (-ind))) fen[ind] ^= val;
    }

    ll get(ll x) {
        ll sum = 0;
        for (; x; x -= (x & (-x))) sum ^= fen[x];
        return sum;
    }
};

BITree<MAXN> fen;
vector<ll> LIS;
ll SZ[MAXN], SZrev[MAXN];

int main() {
    fast_io;
    set_random;
    ll n, m;
    cin >> n >> m;
    for (ll i = 1; i <= n; i++) {
        ll l, r;
        cin >> l >> r;
        fen.update(l, 1);
        fen.update(r + 1, -1);
    }
    //LIS.push_back(0);
    for (ll i = 1; i <= m; i++) {
        ll t = fen.get(i);
        auto it = upper_bound(all(LIS), t);
        if (it == LIS.end()) {
            LIS.push_back(t);
            SZ[i] = sz(LIS);
        } else {
            ll idx = it - LIS.begin();
            LIS[idx] = t;
            SZ[i] = idx;
        }
    }
    ll ans = -INF;
    LIS.clear();
    //LIS.push_back(0);
    for (ll i = m; i; i--) {
        ll t = fen.get(i);
        auto it = upper_bound(all(LIS), t);
        if (it == LIS.end()) {
            LIS.push_back(t);
            SZrev[i] = sz(LIS) ;
            //ans = max(ans , SZrev[i] + SZ[i]);
        } else {
            ll idx = it - LIS.begin();
            LIS[idx] = t;
            SZrev[i] = idx;
            ans = max(ans , SZrev[i] + SZ[i]);
        }
    }
    //ll ans = -INF;
    for (ll i = 1; i <= m; i++) {
        ans = max(ans, SZ[i] + SZrev[i] - 1);
    }
    cout << ans << endl;
    return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
#include <deque>
#include <cassert>
#include <ctime>
using namespace std;
#define INF 2001001001
#define MOD 1000000007
#define endl '\n'
typedef long long ll;
typedef long double ld;

int N,M;
int dp[100001][2];
int cnt[100001];
int L[100001],R[100001];
int tree[2][200101];

void update(int mode, int pos, int val){
  pos+=M+2;
  tree[mode][pos]=max(tree[mode][pos],val);
  for (pos/=2;pos>=1;pos/=2){
    tree[mode][pos]=max(tree[mode][pos*2],tree[mode][pos*2+1]);
  }
}

int query(int mode, int l, int r){
  l+=M+2;
  r+=M+2;
  int s=0;
  while (l<=r){
    if (l%2==1)//right node
      s=max(s,tree[mode][l++]);
    if (r%2==0)//left node
      s=max(s,tree[mode][r--]);
    l/=2;
    r/=2;
  }
  return s;
}

int main()
{
  //ios_base::sync_with_stdio(0);cin.tie(0);
  cin>>N>>M;
  for (int i=0;i<N;i++){
    cin>>L[i]>>R[i];
    cnt[L[i]]++;
    cnt[R[i]+1]--;
  }
  for (int i=1;i<=M;i++)
    cnt[i]+=cnt[i-1];
  for (int i=1;i<=M;i++){
    if (cnt[i]!=0){
      dp[i][0]=1;
      dp[i][1]=1;
    }
  }
  int ans=0;
  for (int i=1;i<=M;i++){
    if (cnt[i]!=0){
      dp[i][0]=max(dp[i][0],query(0,1,cnt[i])+1);
      dp[i][1]=max(dp[i][1],query(1,cnt[i],M)+1);
      dp[i][1]=max(dp[i][1],query(0,cnt[i],M)+1);
      update(0,cnt[i],dp[i][0]);
      update(1,cnt[i],dp[i][1]);
      update(1,cnt[i],dp[i][0]);
      ans=max(ans,max(dp[i][0],dp[i][1]));
    }
  }
  cout<<ans<<endl;
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
#ifndef d
#define d(...)
#endif
#define st first
#define nd second
#define pb push_back
#define siz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
typedef long long LL;

int n,m;
int tab[100005];
int prop[100005];
int naj[100005][2];

vector<int>pom;

int znajdz(int a)
{
	if(pom.empty())
	{
		pom.pb(0);
		return 0;
	}
	int p=0,k=siz(pom)-1;
	while(p!=k)
	{
		int s=(p+k)/2;
		if(pom[s]<=a)
			p=s+1;
		else
			k=s;
	}
	if(p==siz(pom)-1 && pom[p]<=a){
		pom.pb(0);
		p++;
	}
	return p;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	cin>>n>>m;
	for(int i=0;i<n;i++){
		int a,b;
		cin>>a>>b;
		prop[a]++;
		prop[b+1]--;
	}
	int curr=0;
	for(int i=1;i<=m;i++){
		curr+=prop[i];
		tab[i]=curr;
		d(cerr<<tab[i]<<endl;)
	}
	for(int i=1;i<=m;i++)
	{
		int j=znajdz(tab[i]);
		d(cerr<<i<<": "<<j<<endl;)
		naj[i][0]=j;
		pom[j]=tab[i];
	}
	int res=siz(pom);
	pom.clear();
	for(int i=m;i>0;i--)
	{
		int j=znajdz(tab[i]);
		naj[i][1]=j;
		pom[j]=tab[i];
	}

	res=max(res,siz(pom));
	cout<<res<<"\n";

	return 0;
}

#include <stdio.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <utility>
using namespace std;
typedef pair<int,int> pi;
#define F first
#define S second
#define MP make_pair
#define PB push_back
const int N=1e5+10;
int main(){
    int n,m,ans,a[N],b[N],now=0;
    pi q[N];
    vector<int> lis;
    priority_queue<int,vector<int>,greater<int>>pq;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)scanf("%d%d",&q[i].F,&q[i].S);
    sort(q,q+n);
    q[n]=MP(1e9,1e9);
    for(int i=1;i<=m;i++){
        while(q[now].F<=i)pq.push(q[now++].S);
        while(!pq.empty()){
            if(pq.top()<i)pq.pop();
            else break;
        }
        a[i]=static_cast<int>(pq.size());
    }
    lis.clear();
    lis.PB(a[1]);
    b[1]=1;
    b[0]=0;
    for(int i=2;i<=m;i++){
        if(a[i]>=lis.back())lis.PB(a[i]);
        else *upper_bound(lis.begin(),lis.end(),a[i])=a[i];
        b[i]=static_cast<int>(lis.size());
    }
    lis.clear();
    lis.PB(a[m]);
    ans=max(b[m-2]+1,b[m]);
    for(int i=m-1;i>1;i--){
        if(a[i]>=lis.back())lis.PB(a[i]);
        else *upper_bound(lis.begin(),lis.end(),a[i])=a[i];
        ans=max(ans,max(static_cast<int>(lis.size()),static_cast<int>(lis.size()+b[i-2])));
    }
    if(a[1]>=lis.back())lis.PB(a[1]);
    ans=max(ans,static_cast<int>(lis.size()));
    printf("%d\n",ans);
}

#include <bits/stdc++.h>

using namespace std;

#define f first
#define s second
#define mp make_pair
#define pb push_back
#define sz(x) ((int)((x).size()))
#define all(x) (x).begin(),(x).end()
#define deb(x) cerr << "(" << #x << " = " << x << ")\n";
#define bp(x) __builtin_popcount(x)

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;

#define ROOT 1,1,n
#define LS v+v,l,mid
#define RS v+v+1,mid+1,r

int n, m;
int a[100100];
int dl[100100], dr[100100];

int t[100100 * 4];

int get(int v, int l, int r, int L, int R) {
	if(r < L || R < l) return 0;
	if(L <= l && r <= R) return t[v];
	int mid = (l + r) >> 1;
	return max(get(LS, L, R), get(RS, L, R));
}

void update(int v, int l, int r, int pos, int val) {
	if(l == r) {
		t[v] = val;
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid)
		update(LS, pos, val);
	else
		update(RS, pos, val);
	t[v] = max(t[v+v], t[v+v+1]);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> m;
    for(int i = 0; i < n; ++i) {
    	int l, r;
    	cin >> l >> r;
    	a[l]++;
    	a[r+1]--;
    }
    for(int i = 1; i <= m; ++i) {
    	a[i] += a[i-1];
    }
    for(int i = 1; i <= m; ++i) {
    	dl[i] = get(ROOT, 1, a[i]) + 1;
    	update(ROOT, a[i], dl[i]);
    }
    memset(t, 0, sizeof t);
    for(int i = m; i >= 1; --i) {
    	dr[i] = get(ROOT, 1, a[i]) + 1;
    	update(ROOT, a[i], dr[i]);
    }
    int ans = 0;
    for(int i = 0; i <= m; ++i) {
    	ans = max(ans, dl[i] + dr[i+1]);
    }
    cout << ans << endl;

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lf double
#define maxn 65536*2
int n,m;
int tree[maxn*2+50];
int has[maxn];int num[maxn];
void update(int x,int y)
{
	x=x+maxn-1;
	while(x) tree[x]=max(tree[x],y),x=x/2;
}
int query(int a,int b,int l,int r,int id)
{
	if(l>=a and r<=b) return tree[id];
	if(a>r or b<l) return 0;
	return max(query(a,b,l,(l+r)/2,id*2),query(a,b,(l+r)/2+1,r,id*2+1) );
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		has[l]++,has[r+1]--;
	}
	for(int i=1;i<maxn;i++) has[i]+=has[i-1],num[has[i]]++;
	int ans=0;
//	for(int i=1;i<maxn;i++) ans=max(ans,num[i]);
	for(int i=1;i<=m;i++)
	{
		if(!has[i]) continue;
		int res=query(1,has[i],1,maxn,1);
		res++;ans=max(ans,res);
		update(has[i],res);
	}
	memset(tree,0,sizeof(tree));
	for(int i=1;i<=m;i++) has[i]=maxn-has[i];
	for(int i=1;i<=m;i++)
	{
		if(!has[i]) continue;
		int res=query(1,has[i],1,maxn,1);
		res++;ans=max(ans,res);
		update(has[i],res);
	}cout<<ans;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+1;
int n, m, a[N], dp1[N], dp2[N];
int seg[N+5],lis[4*N];
void upd(int i, int val, int l=0, int r=n-1, int idx=1)
{
    if(l == r)
    {
        lis[idx] = val;
        return ;
    }
    int mid = (l+r) >> 1;
    if(i <= mid)
    upd(i, val, l, mid, idx*2);
    else
    upd(i, val, mid+1, r, idx*2+1);
    lis[idx] = max(lis[idx*2], lis[idx*2+1]);
}
int query(int x, int y, int l=0, int r=n-1, int idx=1)
{
    if(l > y || r < x)
    return 0;
    if(l >= x && r <= y)
    return lis[idx];
    int mid = (l+r) >> 1;
    return max(query(x, y, l, mid, idx*2), query(x, y, mid+1, r, idx*2+1));
}
int main()
{
    scanf("%d %d", &m, &n);
    for(int i=0; i<m; i++)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        seg[l-1]++, seg[r]--;
    }
    int cur = 0;
    for(int i=0; i<n; i++)
    {
        cur += seg[i];
        a[i] = cur;
    }
    for(int i=0; i<n; i++)
    {
        dp1[i] = query(0, a[i])+1;
        upd(a[i], dp1[i]);
    }
    memset(lis, 0, sizeof lis);
    for(int i=n-1; i>=0; i--)
    {
        dp2[i] = query(a[i], N)+1;
        upd(a[i], dp2[i]);
    }
    int ans = 0;
    for(int i=0; i<n; i++)
    ans = max(ans, dp1[i]+dp2[i]-1);
    cout << ans << endl;
}

#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mk make_pair
#define fi first
#define se second

typedef long long ll;
typedef pair<int, int> ii;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);

const int N = 1e5 + 5;
int n, m, a[N], v[N];
int l[N], r[N], ct[N];

int seg[4*N + 1];
int A, B;

void update (int r, int i, int j) {
	if (j < A or i > A)	return;

	if (i == A and j == A) {
		seg[r]++;
	} else {
		int mid = (i + j)>>1;

		update (2*r, i, mid);
		update (2*r + 1, mid + 1, j);

		seg[r] = seg[2*r] + seg[2*r+1];
	}
}

int queryL (int r, int i, int j) {
	if (i > B)	return 0;

	if (j <= B) {
		if (i == j) {
			if (seg[r])
				return 0;
			else
				return i;
		}

		int mid = (i + j)>>1;

		if (!seg[2*r + 1])
			return queryL(2*r, i, mid);
		else
			return queryL(2*r + 1, mid + 1, j);
	} else {
		int mid = (i + j)>>1;

		int L = queryL (2*r, i, mid);
		int R = queryL (2*r + 1, mid + 1, j);

		return max (L, R);
	}
}

int queryR (int r, int i, int j) {
	if (j < A)	return INF;

	if (i >= A) {
		if (i == j) {
			if (seg[r])
				return INF;
			else
				return i;
		}

		int mid = (i + j)>>1;

		if (!seg[2*r])
			return queryR(2*r + 1, mid + 1, j);
		else
			return queryR(2*r, i, mid);
	} else {
		int mid = (i + j)>>1;

		int L = queryR (2*r, i, mid);
		int R = queryR (2*r + 1, mid + 1, j);

		return min (L, R);
	}
}

vector <int> occ[N];

int main (void) {
	ios_base::sync_with_stdio(false);

	cin >> n >> m;

	for (int i = 0; i < n; i++) {
		int l, r;	cin >> l >> r;

		a[l]++;
		a[r+1]--;
	}

	int at = 0;
	for (int i = 1; i <= m; i++) {
		at += a[i];
		v[i] = at;
	}

	for (int i = 1; i <= m; i++) {
		occ[v[i]].pb(i);

		if (!ct[v[i]])
			l[v[i]] = i;

		ct[v[i]]++;
		r[v[i]] = i;
	}

	int ans = 0;
	for (int i = N - 1; i >= 0; i--) {
		if (!ct[i])
			continue;

		int res = ct[i];

		B = l[i] - 1;
		int left = queryL (1, 0, m + 1);

		A = r[i] + 1;
		int right = queryR (1, 0, m + 1);

		right = min (right, r[i] + 1);

/*		cout << i << " " << left << " " << right << endl;
		cout << l[i] << " " << r[i] << " " << ct[i] << endl;
		cout << endl;
*/
		res += l[i] - (left + 1);
		res += right - (r[i] + 1);

		for (auto it : occ[i]) {
			A = it;
			update (1, 0, m + 1);
		}

		ans = max (ans, res);
	}

	cout << ans << endl;

	return 0;
}

//#define ONLINE_JUDGE

#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <memory>
#include <cmath>
#include <climits>
#include <numeric>
#include <tuple>
#include <memory.h>
#include <stdint.h>

#if !defined(__GNUC__)
#else // !defined(__GNUC__)
#define _CrtDbgBreak() __builtin_trap()
#endif // !defined(__GNUC__)

#if defined(ONLINE_JUDGE)
#define LOCAL_TEST 0
#else
#define LOCAL_TEST 1
#endif

#if LOCAL_TEST
struct AssertsCounter
{
	AssertsCounter(): counter(0) {}
	~AssertsCounter() { std::cerr << std::endl << "DIAG: " << (counter == 0 ? "OK" : "FAIL!!!") << " Asserts count: " << counter << std::endl; }
	void Increment() { counter++; }
	uint32_t counter;
};
AssertsCounter g_assertsCounter;
#define LOCAL_ASSERT(expr) { if (!(expr)) {std::cerr << "ASSERT FAILED (" << __LINE__ << "): '" << #expr << "'" << std::endl; g_assertsCounter.Increment(); _CrtDbgBreak(); } }
#define LOCAL_ASSERT_EQ(expr1, expr2) { if ((expr1) != (expr2)) {std::cerr << "ASSERT FAILED (" << __LINE__ << "): '" << #expr1 << "' == '" << #expr2 << "' (" << (expr1) << " vs " << (expr2) << "')" << std::endl; g_assertsCounter.Increment(); _CrtDbgBreak(); } }
#else
volatile bool isLocalTestEnabled = 0;
#define LOCAL_ASSERT(expr)
#define LOCAL_ASSERT_EQ(expr1, expr2)
#endif

bool g_isLocalPrintEnabled = (bool)(LOCAL_TEST);
#define LOCAL_PRINT() if (!g_isLocalPrintEnabled) { } else std::cerr // << .. << ..

typedef std::string string8_t;
typedef long double ld_t;

typedef std::vector<size_t> vector_size_t;
typedef std::vector<uint8_t> vector_uint8_t;
typedef std::vector<int32_t> vector_int32_t;
typedef std::vector<uint32_t> vector_uint32_t;
typedef std::vector<int64_t> vector_int64_t;
typedef std::vector<uint64_t> vector_uint64_t;
typedef std::vector<string8_t> vector_string8_t;

typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<vector_int32_t> vector_2d_int32_t;
typedef std::vector<vector_uint32_t> vector_2d_uint32_t;
typedef std::vector<vector_int64_t> vector_2d_int64_t;
typedef std::vector<vector_uint64_t> vector_2d_uint64_t;

typedef std::set<size_t> set_size_t;
typedef std::set<int32_t> set_int32_t;
typedef std::set<uint32_t> set_uint32_t;
typedef std::set<int64_t> set_int64_t;
typedef std::set<uint64_t> set_uint64_t;
typedef std::set<string8_t> set_string8_t;

typedef std::multiset<size_t> multiset_size_t;
typedef std::multiset<string8_t> multiset_string8_t;

// Auxiliary functions definition
//
template<typename T> void UpdateMin(T& a, const T b) {a = std::min(a, b);}
template<typename T> void UpdateMax(T& a, const T b) {a = std::max(a, b);}

const ld_t Pi = std::atan(1.0L) * 4.0L;
static const ld_t Eps = 1.0e-09;
template<typename T> bool IsEqual(const T a, const T b) { return std::abs(a - b) < Eps; }
template<typename T> bool IsGreater(const T a, const T b) { return a > b + Eps; }
template<typename T> bool IsLess(const T a, const T b) { return a + Eps < b; }
template<typename T> bool IsGreaterEqual(const T a, const T b) { return !IsLess(a, b); }
template<typename T> bool IsLessEqual(const T a, const T b) { return !IsGreater(a, b); }

template<typename T> string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }
template<typename T> T FromStr(const string8_t& str) {T val = {}; std::istringstream istr(str); istr >> val; return val; }

uint64_t SafeAdd(uint64_t a, uint64_t b) { uint64_t M = std::numeric_limits<uint64_t>::max(); return a <= M - b ? a + b : M; }
uint64_t SafeMul(uint64_t a, uint64_t b) { uint64_t M = std::numeric_limits<uint64_t>::max(); return a <= M / b ? a * b : M; }

template<typename T> std::istream& operator>>(std::istream& ist, std::vector<T>& data)
{
	LOCAL_ASSERT(!!ist);
	for (size_t i = 0; i < data.size(); i++) { ist >> data[i]; }
	return ist;
}

template<typename T> T Read(std::istream& ist)
{
	LOCAL_ASSERT(!!ist);
	T val; ist >> val; return val;
}

template<typename T> std::ostream& operator<<(std::ostream& ost, const std::vector<T>& data)
{
	for (size_t i = 0; i < data.size(); i++) { if (i != 0) { ost << ' '; } ost << data[i]; }
	return ost;
}

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#else
#include <library/lib_stopwatch.h>
#include <library/lib_random.h>
library::random::Rand g_rnd;
#endif

vector_size_t LongestNonDecreasingSequence(const vector_uint32_t& a)
{
	const size_t n = a.size();

	const uint32_t Inf = std::numeric_limits<uint32_t>::max();
	vector_uint32_t minFinish(n + 1, Inf);
	minFinish[0] = 0;
	vector_size_t lnds(n + 1);

	size_t best = 0;
	for (size_t i = 0; i < n; i++)
	{
		const uint32_t ai = a[i];
		const size_t pos = std::distance(minFinish.begin(), std::upper_bound(minFinish.begin(), minFinish.end(), ai));
		if (minFinish[pos] == Inf)
		{
			best = pos;
		}
		UpdateMin(minFinish[pos], ai);
		lnds[i + 1] = best;
	}

	return lnds;
}

struct Edge
{
	uint32_t l;
	uint32_t r;
};

typedef std::vector<Edge> VectorEdge;

size_t GetAns(const VectorEdge& edges)
{
	uint32_t xMax = 0;
	uint32_t xMin = std::numeric_limits<uint32_t>::max();
	for (const Edge& e: edges)
	{
		UpdateMin(xMin, e.l);
		UpdateMax(xMax, e.r);
	}

	vector_int32_t delta(xMax - xMin + 1);
	for (const Edge& e: edges)
	{
		delta[e.l - xMin] += 1;
		delta[e.r - xMin] -= 1;
	}

	vector_uint32_t raw(delta.size() - 1);
	for (uint32_t i = 0; i < raw.size(); i++)
	{
		raw[i] = delta[i];
		if (i > 0)
		{
			raw[i] += raw[i - 1];
		}
	}

	const vector_uint32_t reversed(raw.rbegin(), raw.rend());
	const vector_size_t fLnds = LongestNonDecreasingSequence(raw);
	const vector_size_t rLnds = LongestNonDecreasingSequence(reversed);

	size_t maxAns = fLnds[raw.size()];
	for (size_t i = 0; i < raw.size(); i++)
	{
		size_t lPart = fLnds[i + 1];
		size_t rPart = rLnds[raw.size() - i];
		UpdateMax(maxAns, lPart + rPart - 1);
	}

	return maxAns;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
	StopWatch<1> sw; (void)sw;

	//
	size_t n;
	ist >> n;
	uint32_t m;
	ist >> m;

	if (multipleTestMode && !ist)
		return false;

	//
	LOCAL_PRINT() << std::endl << "Next test" << std::endl;
	VectorEdge edges(n);
	for (Edge& e: edges)
	{
		ist >> e.l >> e.r;
		--e.l;
	}

	const size_t ans = GetAns(edges);
	ost << ans << std::endl;

	return multipleTestMode;
}

#if LOCAL_TEST
void Test()
{
	using namespace library::random;
	//const auto genVector = GenFactory::CreateGenVector(GenRange<size_t>(2, 10), GenRange<int32_t>(-100, +200));

	for (size_t t = 0; t < 10; t++)
	{
		//const vector_int32_t data = genVector();
		//size_t ans = GetAns(data);
		//size_t ref = GetAnsRef(data);
		//LOCAL_ASSERT_EQ(ref, ans);
	}
}
#endif

void RunSolve(std::istream& ist, std::ostream& ost)
{
#if !defined(ONLINE_JUDGE)
	while(Solve(ist, ost, true)) {};
#else
    Solve(ist, ost, false);
#endif
}

int main(int argc, const char *argv[])
{
#if !defined(ONLINE_JUDGE)
	Test();
#endif

    std::ios_base::sync_with_stdio(false);
	if (argc > 1)
	{
		std::ifstream ifs(argv[1]);
		if (!ifs)
		{
			std::cout << "File not found: " << argv[1] << std::endl;
			return 1;
		}
		RunSolve(ifs, std::cout);
		return 0;
	}

	RunSolve(std::cin, std::cout);
}

#include <bits/stdc++.h>
using namespace std;
#define mid ((l+r)>>1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mp make_pair
#define pb push_back
#define pii pair<ll,ll>
#define PI 3.14159265358
#define e 2.718281828459
typedef long long ll;
const ll N = 1e5+5;
const int inf = 0x3f3f3f3f;
int a[N];
int num[N];
int dp1[N],dp2[N];
int vec[N],vec2[N];
int f1[N],f2[N];
int main(){
    int n,m;
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin >> n >> m;
    for(int i = 1;i <= n;i ++){
        int l,r;
        cin >> l >> r;
        a[l]++;
        a[r+1]--;
    }
    fill(vec,vec+n+1,inf);
    fill(vec2,vec2+n+1,-inf);
    for(int i = 1;i <= m;i ++) a[i] += a[i-1];
        int len = 1;
        vec[1] = a[1];
        f1[1] = 1;
        for(int i = 2;i <= m;i ++){
            if(a[i] >= vec[len])
                vec[++len] = a[i];
            else{
                int pos = lower_bound(vec+1,vec+len+1,a[i])-vec;
                vec[pos] = a[i];
            }
            f1[i] = len;
        }
        len = 1;
        vec2[1] = a[m];
        f2[m] = 1;
        for(int i = m-1;i >= 0;i --){
            if(a[i] >= vec2[len])
                vec2[++len] = a[i];
            else{
                int pos = lower_bound(vec2+1,vec2+len+1,a[i])-vec;
                vec2[pos] = a[i];
            }
            f2[i] = len;
        }
        int ans = -1;
        for(int i = 1;i <= m;i ++) ans = max(ans,f1[i]+f2[i]-1);
        cout << ans << endl;
    return 0;
}

#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) begin(x),end(x)
#define F(i,n) for (int i = 0; i < n; ++i)
#define F1(i,n) for (int i = 1; i <= n; ++i)
#define dbg(x) cerr << #x << " = " << x << endl
#define dbgg(x) cerr << #x << " = " << x << ' '
#define T(x) x[pool]
#define mineq(x,y) { if ((x) > (y)) (x) = (y); }
#define maxeq(x,y) { if ((x) < (y)) (x) = (y); }
#define MEOW cout << "meowwwww" << '\n'; system("pause");
#define int long long
using namespace std;
typedef vector<int> vi;
typedef pair<int, int> pii;

template<typename T>
ostream& operator <<(ostream &s, const vector<T> &c)
{
	s << "[ "; for (auto it : c) s << it << " "; s << "\b]\n";
	return s;
}

template<typename T>
ostream& operator <<(ostream &s, const pair<int, T> &c)
{
	s << "[ "; cout << c.fi << " , " << c.se << " ] ";
	return s;
}

const int maxn = 1234567;
int n, m, a[maxn], bit[maxn], l[maxn], r[maxn];

void input()
{
	ios::sync_with_stdio(false); cin.tie(0);
	cin >> n >> m;
	F1 (i, n)
	{
		int l, r; cin >> l >> r;
		--a[r + 1]; ++a[l];
	}
}

#define lowbit(x) ((x) & -(x))

int query(int pos)
{
	int res = 0;
	if (pos == 0) return 0;
	while (pos)
	{
		res = max(res, bit[pos]);
		pos -= lowbit(pos);
	}
	return res;
}

void add(int pos, int val)
{
	if (pos == 0) return;
	while (pos < maxn)
	{
		bit[pos] = max(bit[pos], val);
		pos += lowbit(pos);
	}
}

void solve()
{
	F1 (i, m) a[i] += a[i - 1];

	//F1 (i, m) dbgg(a[i]);

	for (int i = 1; i <= m; ++i)
	{
		l[i] = query(a[i]);
		add(a[i], l[i] + 1);
	}

	//F1 (i, m) dbg(l[i]);

	F (i, maxn) bit[i] = 0;
	for (int i = m; i >= 1; --i)
	{
		r[i] = query(maxn - a[i]);
		add(maxn - a[i], r[i] + 1);
	}

	//F1 (i, m) dbg(r[i]);

	int ans = 0;
	F1 (i, m) ans = max(ans, l[i] + r[i]);
	cout << ans + 1 << '\n';
}

main()
{
	input();
	solve();
}

#include <bits/stdc++.h>
using namespace std;
using namespace std::chrono;
#define ll long long int
#define v vector<ll>
#define vv vector<v>
#define p pair<ll,ll>
#define arrayinput int n; int m; cin>>n>>m; v arr (n+1,-1); for (int i=0; i<n; i++){int temp; cin>>temp;arr[i]=temp;}
#define vp vector<pair<int,p> >
int LIM=2e5;
v tree(2*LIM);
int n,m;
void update(int index,int val)
{
    index=index+n-1;
    tree[index]=val;
    while (1)
    {
        index/=2;
        if (index>=1)
            tree[index]=max(tree[2*index],tree[2*index+1]);
        else
            break;
    }
}
int query(int l,int r)
{
    ll  ans=-1;
    l+=n-1;
    r+=n-1;
    while (l<=r)
    {
        if (l%2==1)
        {
            ans=max(ans,tree[l]);
            l++;
        }
        if (r%2==0)
        {
            ans=max(ans,tree[r]);
            r--;
        }
        l/=2;
        r/=2;
    }
    return ans;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>n>>m;
    v coun(m+2,0);
    for (int i=1; i<=n;i++)
    {
        int a,b;
        cin>>a>>b;
        coun[a]++;
        coun[b+1]--;
    }
    for (int i=2; i<=m; i++)
        coun[i]=coun[i-1]+coun[i];
    v dp(m+1,0);
    ll max_increasing=-1;
    //cout<<query(1,1)<<endl;
    for (int i=1; i<=m; i++)
    {
        int maxi=query(1,coun[i]);
        dp[i]=1+maxi;
        update(coun[i],dp[i]);
        max_increasing=max(max_increasing,dp[i]);
    }
    v temp(m+1,-1);
    for (int i=1; i<=m; i++)
        temp[i]=coun[m-i+1];
    coun=temp;
    for (int i=1; i<=2*n; i++)
        tree[i]=0;
    v dp2(m+1,-1);
    for (int i=1; i<=m; i++)
    {
        int maxi=query(1,coun[i]);
        dp2[i]=1+maxi;
        update(coun[i],dp[i]);
        max_increasing=max(max_increasing,dp[i]);
    }
    cout<<max_increasing<<endl;
    return 0;
}

#pragma GCC optimize("O3")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 10;

int n, m, s[MAXN], mxs[MAXN], mxp[MAXN];

int main() {
	#ifdef Fekete
		freopen("input.txt", "r", stdin);
		//freopen("output.txt", "w", stdout);
        //freopen("debuger.txt", "w", stderr);
    #else

    #endif // Fekete

    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        s[l]++;
        s[r + 1]--;
    }
    for(int i = 1; i <= m; i++){
        s[i] += s[i - 1];
    }
//    for(int i = 1; i <= m; i++) {
//        cout << s[i] << " ";
//    }
//    cout << "\n";
    mxp[1] = s[1];
    for(int i = 2; i <= m; i++) {
        mxp[i] = max(s[i], mxp[i - 1]);
    }
    mxs[m] = s[m];
    for(int i = m - 1; i > 0; i--) {
        mxs[i] = max(mxs[i + 1], s[i]);
    }
    int cnt = 0;
    for(int i = 2; i < m; i++) {
        if(mxp[i - 1] > s[i] && mxs[i + 1] > s[i]) cnt++;
    }
    cout << m - cnt;

}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct DE{
	vector<int> delta;
	DE(int n) : delta(n+1, 0){}

	void add(int l, int r, int v){
		delta[l] += v;
		delta[r+1] -= v;
	}

	vector<int> getArray(){
		vector<int> ret(delta.size()-1);
		int sum = 0;
		for(int i=0; i<ret.size(); i++){
			sum += delta[i];
			ret[i] = sum;
		}

		return ret;
	}
};

vector<int> fastLIS(vector<int> &vals){
	vector<int> ret(vals.size());
	map<int, int> t;
	t.insert(pair<int, int>(0,0));

	for(int i=0; i<vals.size(); i++){
		auto closest = t.lower_bound(vals[i]);
		if(closest == t.end() || closest->first != vals[i]) closest--;
		ret[i] = closest->second+1;
		t[vals[i]] = closest->second+1;

		while(true){
			auto next = t.upper_bound(vals[i]);
			if(next == t.end()) break;
			if((*next).second > closest->second+1) break;
			t.erase(next);
		}
	}

	return ret;
}

int main()
{
	int n, m; cin >> n >> m;
	DE delta(m);

	for(int i=0; i<n; i++){
		int l, r; cin >> l >> r;
		delta.add(l-1, r-1, 1);
	}

	vector<int> count = delta.getArray();
	vector<int> down = fastLIS(count);
	reverse(count.begin(), count.end());
	vector<int> up = fastLIS(count);

	int best = 0;
	for(int i=0; i<m; i++)
		best = max(best, up[i]+down[m-i-1]);

	cout << best-1 << "\n";
	return 0;
}

#include <cstdio>
#define MAXN 100100
#define INF (1<<30)
int a[MAXN];
int diff[MAXN];
int solve(int m) {
	int ans = 0;
	for(int i = 1; i <= m; i++)
		if((a[i - 1] > a[i] && a[i] < a[i + 1]) || a[i] == 0) ans++;
	return m - ans;
}
void add(int l, int r) {
	diff[l]++;
	diff[r + 1]--;
}
void process(int m) {
	for(int i = 1; i <= m; i++) diff[i] += diff[i - 1];
	for(int i = 1; i <= m; i++) a[i] = diff[i];
	a[0] = a[m + 1] = INF;
}
int main(void) {
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) {
		int l, r;
		scanf("%d%d", &l, &r);
		add(l, r);
	}
	process(m);
	printf("%d\n", solve(m));
	return 0;
}

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <vector>
#include <set>
#include <utility>
#include <algorithm>

using namespace std;
int con[200005];
int how[200005]={0};
int ll[200005]={0};
int rr[200005]={0};
vector < int > all;
int main()
{
    int N,M,now=0,big=0,l=2e9,r=-2e9,ans=0,i,t;
    scanf("%d %d",&N,&M);
    for(i=1;i<=N;i++)
    {
        scanf("%d %d",&l,&r);
        how[l]++;
        how[r+1]--;
    }
    l=2e9;
    r=-2e9;
    for(i=1;i<=M;i++)
    {
        now+=how[i];
        big=max(big,now);
        con[i]=now;
    }

    all.clear();
    t=0;
    for(i=1;i<=M;i++)
    {
        if(upper_bound(all.begin(),all.end(),con[i])==all.end())
        {
            all.push_back(con[i]);
            t++;
        }
        else all[upper_bound(all.begin(),all.end(),con[i])-all.begin()]=con[i];
        ll[i]=t;
    }
    t=0;
    all.clear();
    for(i=M;i>=1;i--)
    {
        if(upper_bound(all.begin(),all.end(),con[i])==all.end())
        {
            t++;
            all.push_back(con[i]);
        }
        else all[upper_bound(all.begin(),all.end(),con[i])-all.begin()]=con[i];
        rr[i]=t;
    }
    for(i=0;i<=N;i++)
    {
        ans=max(ans,ll[i]+rr[i+1]);
    }
    printf("%d\n",ans);
    return 0;
}
/*
17 7
1 1
1 1
2 2
2 2
3 3
3 3
3
3
4 4
4 4
4 4
4 4
5 5
5 5 5
5
6 6
7 7
7 7
*/

#include <bits/stdc++.h>

#define dbg(x) cerr<<#x": "<<x<<"\n"
#define dbg_p(x) cerr<<#x": "<<x.first<<","<<x.second<<"\n"
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok cerr<<"OK!\n"

#define st first
#define nd second

#define DMAX 100100
#define NMAX
#define MMAX

using namespace std;

int n, k, m, f[DMAX], a, b, ans, cresc[DMAX], desc[DMAX], h[DMAX], mc[DMAX], md[DMAX];
double l, v1, v2;
string s;

template<class T>
ostream& operator<<(ostream& out, vector<T> v)
{
	out << v.size() << '\n';
	for(auto e : v) out << e << ' ';
	return out;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin >> n >> m;
	for(int i = 1; i <= n; i++ ){
		cin >> a >> b;
		f[a]++;
		f[b + 1]--;
	}
	for(int i = 2; i <= m; i++)
		f[i] += f[i - 1];

	int lgmax = 1;
	for(int i = 0; i <= m; ++i) h[i] = 1000000000;
	h[0] = 0;

	for(int i = 1; i <= m; i++) {
		int lg = upper_bound(h + 1, h + lgmax + 1, f[i]) - h;
		cresc[i] = lg;
		lgmax = max(lgmax, cresc[i]);
		h[lg] = min(f[i], h[lg]);
	}
	// dbg_v(f, m + 2);
	// dbg_v(cresc, m + 2);

	lgmax = 1;
	for(int i = 0; i <= m; ++i) h[i] = 1000000000;
	h[0] = 1000000000;
	for(int i = m; i >= 1; i--) {
		int lg = upper_bound(h + 1, h + lgmax + 1, f[i]) - h;
		// dbg_v(h, m + 1);
		// dbg(lg);
		// dbg(i);
		desc[i] = lg;
		lgmax = max(lgmax, cresc[i]);
		h[lg] = min(f[i], h[lg]);
	}
	dbg_v(desc, m + 2);

	mc[1] = cresc[1];
	for(int i = 2; i <= m; i++)
		mc[i] = max(mc[i - 1], cresc[i]);

	md[m] = desc[m];
	for(int i = m - 1; i >= 1; i--)
		md[i] = max(md[i + 1], desc[i]);

	dbg_v(mc, m + 1);
	dbg_v(md, m + 1);

	for(int i = 0; i <= m; i++)
		ans = max(mc[i] + md[i + 1], ans);
	cout << ans << '\n';
}

// ADITYA JAIN

#include <bits/stdc++.h>
using namespace std;

#define f first
#define s second
#define pb push_back
#define all(c) c.begin(),c.end()

#define gi(x) scanf("%d", &x)
#define pi(x) printf("%d", x)
#define gl(x) scanf("%lld", &x)
#define pl(x) printf("%lld", x)
#define sp printf(" ")
#define nl printf("\n")

typedef long long int lld;
typedef long double ldb;

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
    template <typename Arg1>
    void __f(const char* name, Arg1&& arg1){
        cerr << name << " : " << arg1 << std::endl;
    }
    template <typename Arg1, typename... Args>
    void __f(const char* names, Arg1&& arg1, Args&&... args){
        const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
    }
#else
#define trace(...)
#endif

#define MAXN 100010

vector <int> val[MAXN];

int x[MAXN];

int td[MAXN*4], ti[MAXN*4];

int queryd(int node, int lo, int hi, int l, int r){
	if(l > hi or r < lo) return 0;
	if(lo >= l and hi <= r) return td[node];
	int md = (lo + hi) >> 1;
	int p1 = queryd(node << 1, lo, md, l, r);
	int p2 = queryd(node << 1 | 1, md + 1, hi, l, r);
	return max(p1, p2);
}

void updated(int node, int lo, int hi, int idx, int val){
	if(lo == hi){
		td[node] = max(td[node], val);
        return;
	}
	int md = (lo + hi) >> 1;
	if(idx <= md) updated(node << 1, lo, md, idx, val);
	else updated(node << 1 | 1, md + 1, hi, idx, val);
	td[node] = max(td[node << 1], td[node << 1 | 1]);
}

int queryi(int node, int lo, int hi, int l, int r){
	if(l > hi or r < lo) return 0;
	if(lo >= l and hi <= r) return ti[node];
	int md = (lo + hi) >> 1;
	int p1 = queryi(node << 1, lo, md, l, r);
	int p2 = queryi(node << 1 | 1, md + 1, hi, l, r);
	return max(p1, p2);
}

void updatei(int node, int lo, int hi, int idx, int val){
	if(lo == hi){
		ti[node] = max(ti[node], val);
		return;
	}
	int md = (lo + hi) >> 1;
	if(idx <= md) updatei(node << 1, lo, md, idx, val);
	else updatei(node << 1 | 1, md + 1, hi, idx, val);
	ti[node] = max(ti[node << 1], ti[node << 1 | 1]);
}

int ai[MAXN], ad[MAXN], md[MAXN];

main(){
    int n, m;
    cin >> n >> m;
    for(int i = 0, l, r; i < n; ++i){
        cin >> l >> r;
        x[l]++;
        x[r+1]--;
    }
    for(int i = 1; i <= m; ++i){
        x[i] += x[i-1];
    }
    for(int i = 1; i <= m; ++i){
        auto xz = queryi(1, 0, n, 1, x[i]);
        ai[i] = xz+1;
        updatei(1, 0, n, x[i], xz+1);
    }
    for(int i = m; i > 0; --i){
        auto xz = queryd(1, 0, n, 1, x[i]);
        // trace(i, x[i], xz);
        ad[i] = xz+1;
        updated(1, 0, n, x[i], xz+1);
    }
    md[m] = ad[m];
    int ans = 0;
    for(int i = m-1; i > 0; --i){
        // trace(i, ad[i]);
        md[i] = max(ad[i], md[i+1]);
    }
    for(int i = 1; i < m; ++i){
        ans = max(ans, ai[i] + md[i+1]);
        // trace(i,md[i+1],ai[i]);
    }
    ans = max(ans, max(md[1], ai[m]));
    cout << ans << endl;
}

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")

// Use g++ compiler for this include to work.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

// Constants
#define INF 1e18
#define EPS 1e-9
#define MOD 1000000007

// // for using in pairs
#define F first
#define S second

// Macros
#define all(x) begin(x), end(x)
#define allr(x) rbegin(x), rend(x)

// aliases
using ll = long long;
using ull = unsigned long long;
using ui = unsigned int;
using ld = long double;

template<typename T>
using oset = tree<T, null_type, less <T>, rb_tree_tag, tree_order_statistics_node_update>;

// Temporary macro.
#define int long long

// Operator overloads.

/**
 * Both types in the pair should have overload for << operator with ostream.
 */
template<typename T1, typename T2>
ostream& operator<<(ostream &ostream, pair<T1, T2>& p)
{
	ostream << p.first << " " << p.second;
	return ostream;
}

/**
 * The type of element in the vector should have overload for << operator with ostream.
 */
template<typename T>
ostream& operator<<(ostream &stream, vector<T>& v)
{
	for (const auto &it : v)
		stream << it << " ";
	return stream;
}

template<typename T1, typename T2>
istream& operator>>(istream &istream, pair<T1, T2>& p)
{
	istream >> p.first >> p.second;
	return istream;
}

template<typename T>
istream& operator>>(istream &istream, vector<T>& a)
{
	for (auto &it : a)
		istream >> it;
	return istream;
}

// Utility functions.

template<typename T>
T MIN(T first) { return first; }

template<typename T, typename... Args>
T MIN(T first, Args... args) { return min(first, MIN(args...)); }

template<typename T>
T MAX(T first) { return first; }

template<typename T, typename... Args>
T MAX(T first, Args... args) { return max(first, MAX(args...)); }

template <typename T>
void DEBUG(T&& t) {cout << t << "\n";}

template <typename T, typename... Args>
void DEBUG(T&& t, Args&&... args)
{
    cout << t << " ";
    DEBUG(forward<Args>(args)...);
}

template<typename T>
int32_t size_i(T& container) { return static_cast<int32_t>(container.size()); }

// Mathematical functions.

int GCD(int a, int b)
{
	if (!b)
		return a;
	return GCD(b, a % b);
}

int LCM(int a, int b)
{
	return (a * b) / GCD(a, b);
}

int modpow(int x, int n, int m = MOD)
{
	if (n == 0) return 1 % m;
	long long u = modpow(x, n / 2, m);
	u = (u * u) % m;
	if (n % 2 == 1)
		u = (u * x) % m;
	return u;
}

/**
 * m should be prime
 */
int modinv(int x, int m = MOD)
{
	return modpow(x, m - 2, m);
}

//////////////////// START CODE HERE ///////////////////////////

void preSolve()
{
}

// Binary Search
int ceilIndex(int arr[], int l, int r, int x)
{
    if (l > r)
        return -1;

    int mid = l + (r - l) / 2;
    if (arr[mid] == x)
        return mid;

    if (x < arr[mid])
        return ceilIndex(arr, l, mid - 1, x);

    return ceilIndex(arr, mid + 1, r, x);

}

// function to reverse an array
void revereseArr(int arr[], int n)
{
    int i = 0;
    int j = n - 1;
    while (i < j)
       swap(arr[i++], arr[j--]);
}

// Returns length of longest Bitonic
// subsequence in O(n Log n) time.
int getLBSLengthLogn(int arr[], int n)
{
    // Base Case:
    if (n == 0)
        return 0;

    // Aux array storing the input array
    // in same order to calculate LIS:
    int increasing[n];
    int tail1[n];  // To store lengths of IS

    // Aux array storing the input array
    // in reverse order to calculate LIS:
    // This will calculate Longest Decreasing
    // Subsequence which is required for
    // Longest Bitonic Subsequence
    int decreasing[n];
    int tail2[n]; // To store lengths of DS

    // initializing first index same as
    // original array:
    increasing[0] = arr[0];

    // index in initialized as 1 from where
    // the remaining computations will be done
    int in = 1;

    // tail1 stores Longest Increasing subsequence
    // length values till index in
    tail1[0] = 0;

    // remaining computations to get the
    // LIS length for increasing
    for (int i = 1; i < n; i++)
    {
        if (arr[i] < increasing[0])
        {
            increasing[0] = arr[i];
            tail1[i] = 0;
        }
        else if (arr[i] > increasing[in - 1])
        {
            increasing[in++] = arr[i];
            tail1[i] = in - 1;
        }
        else
        {
            increasing[ceilIndex(increasing, -1,
                        in - 1, arr[i])] = arr[i];
            tail1[i] = ceilIndex(increasing, -1,
                                   in - 1, arr[i]);
        }
    }

    // reiitializing the index to 1
    in = 1;

    // reversing the array to get the Longest
    // Decreasing Subsequence Length:
    revereseArr(arr, n);
    decreasing[0] = arr[0];
    tail2[0] = 0;

    for (int i = 1; i < n; i++)
    {
        if (arr[i] < decreasing[0])
        {
            decreasing[0] = arr[i];
            tail2[i] = 0;
        }
        else if (arr[i] > decreasing[in - 1])
        {
            decreasing[in++] = arr[i];
            tail2[i] = in - 1;
        }
        else
        {
            decreasing[ceilIndex(decreasing, -1,
                      in - 1, arr[i])] = arr[i];
            tail2[i] = ceilIndex(decreasing, -1,
                                 in - 1, arr[i]);
        }
    }

    revereseArr(arr, n);
    revereseArr(tail2, n);

    // Longest Bitonic Subsequence length is
    // maximum of tail1[i] + tail2[i] + 1:
    int ans = 0;
    for (int i = 0; i < n; i++)
        if (ans < (tail1[i] + tail2[i] + 1))
            ans = (tail1[i] + tail2[i] + 1);

    return ans;
}

void solve(int tc)
{
	int n, m;
	cin >> n >> m;
	int a[m + 1], da[m + 2];
	for (int i = 0; i < n; i++)
	{
		int l, r;
		cin >> l >> r;
		da[l]++;
		da[r + 1]--;
	}
	for (int i = 1; i <= m; i++)
		a[i] = da[i] + a[i - 1];

	a[0] = INF;
	int ans = getLBSLengthLogn(a, m + 1);
	cout << ans + 1;
}

int32_t main()
{
	#ifdef LOCAL_PROJECT
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
	#else
		// freopen("input.txt", "r", stdin);
		// freopen("output.txt", "w", stdout);
	#endif

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	preSolve();

	int t = 1;
	// cin >> t;
	for (int i = 1; i <= t; i++)
	{
		solve(i);
	}

	return 0;
}

#include "bits/stdc++.h"
#define int long long
#define double long double
#pragma GCC optimize("O3")

using namespace std;

const int MAXN = 1e5 + 100;

vector<int> t(MAXN * 8);

void add(int x, int dx, int v = 0, int l = 0, int r = MAXN) {
    if (l >= x || r < x)
        return;
    if (r - l == 1) {
        t[v] = dx;
        return;
    }
    int c = (l + r) / 2;
    add(x, dx, v * 2 + 1, l, c);
    add(x, dx, v * 2 + 2, c, r);
    t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
}

int query(int lq, int rq, int v = 0, int l = 0, int r = MAXN) {
    if (r <= lq || l >= rq)
        return 0;
    if (l >= lq && r <= rq) {
        return t[v];
    }
    int c = (l + r) / 2;
    return max(query(lq, rq, v * 2 + 1, l, c), query(lq, rq, v * 2 + 2, c, r));
}

signed main() {
    int n, m;

    cin >> n >> m;

    vector<int> b(m), e(m), cnt(m);

    for (int i = 0; i < n; ++i) {
        int l, r;
        cin >> l >> r;
        b[l - 1]++;
        e[r - 1]++;
    }

    int cur = 0;

    for(int i = 0; i < m; ++i) {
        cur += b[i];
        cnt[i] = cur;
        cur -= e[i];
    }

    vector<int> ldp(m), rdp(m + 1);

   // for (auto i : cnt)
   //     cout << i << ' ';

    int best = 0;
    for (int i = 0; i < m; ++i) {
        ldp[i] = query(0, cnt[i]) + 1;
        add(cnt[i], ldp[i]);
        if (i)
           ldp[i] = max(ldp[i - 1], ldp[i]);
    }

    reverse(cnt.begin(), cnt.end());
    t.assign(MAXN * 8, false);
    for (int i = 0; i < m; ++i) {
        rdp[m - i - 1] = query(0, cnt[i]) + 1;
        add(cnt[i], rdp[m - 1 - i]);
        if (i)
          rdp[m - i - 1] = max(rdp[m - i - 1], rdp[m - i]);
    }

    best = max(ldp[m - 1], rdp[0]);

    for (int i = 0; i < m; ++i) {
       // cout << ldp[i] << ' ' << rdp[i + 1] << '\n';
        best = max(best, (ldp[i] + rdp[i + 1]));
    }

    cout << best;

    return 0;
}

#include<bits/stdc++.h>

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using dd = double;
using ldd = long double;
using si = short int;

#define all(x) (x).begin(), (x).end()
#define ff first
#define ss second

//debug defines
#define debug(x) cout << #x << " " << x << endl;
#define debug_v(x) for (auto j : (x)){ cout << j << " ";} cout << endl;
#define PO cout << "Pomelo" << endl;
#define OL cout << "Oliva" << endl;
//end of debug defines

vector<int> tree;

void create(int m)
{
    tree.clear();
    tree.resize(m, 0);
}

void upd(int x, int del)
{
    for (int i = x; i < tree.size(); i |= i + 1)
        tree[i] = max(tree[i], del);
}

ll ans(int x)
{
    int ma = 0;
    for (int i = x; i >= 0; i &= i + 1, --i)
        ma = max(ma, tree[i]);
    return ma;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int n, m;
    cin >> n >> m;
    ++m;
    vector<int> pl(m), cnt(m);
    for (int i = 0; i < n; ++i)
    {
        int a, b;
        cin >> a >> b;
        pl[a - 1]++;
        pl[b]--;
    }
    cnt[0] = pl[0];
    for (int i = 1; i < m; ++i)
    {
        cnt[i] = cnt[i - 1] + pl[i];
    }
    create(m);
 //   debug_v(cnt);
    vector<int> pref(m), suf(m);
    for (int i = 0; i < m; ++i)
    {
        pref[i] = ans(cnt[i]) + 1;
        upd(cnt[i], pref[i]);
    //    cout << pref[i] << " ";
    }
  //  debug_v(pref);
    reverse(all(cnt));
    create(m);
    for (int i = 0; i < m; ++i)
    {
        suf[i] = ans(cnt[i]) + 1;
        upd(cnt[i], suf[i]);
    }
  //  debug_v(suf);
    reverse(all(suf));
    int ans = suf[0];
    for (int i = 0; i < m - 1; ++i)
    {
        ans = max(ans, suf[i + 1] + pref[i]);
    }
    cout << ans - 1;
}

#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define ld long double
const ll N = 5 * 1e7 + 9;

int main() {
    ios_base::sync_with_stdio(false);
    //freopen("elect.in", "r", stdin);
    //freopen("elect.out", "w", stdout);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> a(m + 1, 0);
    for (int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        a[l - 1]++;
        a[r]--;
    }
    vector<int> op(m + 1, 0);
    op[0] = a[0];
    for (int i = 1; i <= m; i++) {
        op[i] = op[i - 1] + a[i];
    }
    vector<int> d(m + 1, 1e9);
    d[0] = -1e9;

    for (int i = 0; i < m; i++) {
        int j = (int) (upper_bound(d.begin(), d.end(), op[i]) - d.begin());

        if (d[j - 1] <= op[i] && op[i] < d[j])
            d[j] = op[i];
    }
    int ans1 = 0;
    for (int i = m; i > 0; i--) {
        if (d[i] < 1e9) {
            ans1 = i;
            break;
        }
    };
    d.clear();
    d.resize(m + 1, 1e9);
    d[0] = -1e9;
    for (int i = m - 1; i >= 0; i--) {
        int j = (int) (upper_bound(d.begin(), d.end(), op[i]) - d.begin());

        if (d[j - 1] <= op[i] && op[i] < d[j])
            d[j] = op[i];
    }
    int ans2 = 0;
    for (int i = 0; i < m; i++) {
        if (d[i] < 1e9) {
            ans2 = i;
            break;
        }
    };
    cout << max(ans1, ans2);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define int long long

const int N=1e5+5;

int pre[N];
int tree[2*N];
int frwd[N];
int bkwd[N];

void update(int node,int l,int r,int in,int val){
	if(l==r){
		tree[node]=val;
	}
	else {
		int mid=(l+r)/2;
		if(in<=mid && l<=mid){
			update(2*node+1,l,mid,in,val);
		}
		else {
			update(2*node+2,mid+1,r,in,val);
		}
		tree[node]=max(tree[2*node+2],tree[2*node+1]);
	}
}

int query(int node,int st,int end,int l,int r){
	if(r<st||end<l){
		return -1e6;
	}
	if(l<=st&&end<=r){
		return tree[node];
	}
	int mid=(st+end)/2;
	int p1=query(2*node+1,st,mid,l,r);
	int p2=query(2*node+2,mid+1,end,l,r);
	return max(p1,p2);
}

int32_t main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		int l,r;
		cin>>l>>r;
		pre[l]++;
		pre[r+1]--;
	}
	for(int i=1;i<=m;i++)
		pre[i]+=pre[i-1];
	for(int i=1;i<=m;i++)
	{
		int x=query(0,0,m,0,pre[i]);
		update(0,0,m,pre[i],x+1);
		frwd[i]=x;
	}
	memset(tree,0,sizeof(tree));
	for(int i=m;i>0;i--)
	{
		int x=query(0,0,m,0,pre[i]);
		update(0,0,m,pre[i],x+1);
		bkwd[i]=x;
	}
	int ans=0;
	for(int i=1;i<=m;i++)
		ans=max(ans,frwd[i]+bkwd[i]+1);
	cout<<ans;

   return 0;
}

#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vecpll vector<pll>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define endl "\n"
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),(x)))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),(x)))
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
string stin() {string s;cin>>s;return s;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
vec iota(int n){vec a(n);iota(all(a),0);return a;}
void print(){putchar(' ');}
void print(bool a){cout<<a;}
void print(int a){cout<<a;}
void print(long long a){cout<<a;}
void print(char a){cout<<a;}
void print(string &a){cout<<a;}
void print(double a){cout<<a;}
template<class T> void print(const vector<T>&);
template<class T, size_t size> void print(const array<T, size>&);
template<class T, class L> void print(const pair<T, L>& p);
template<class T, size_t size> void print(const T (&)[size]);
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } cout<<endl;}
template<class T> void print(const deque<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, size_t size> void print(const array<T, size>& a){ print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout<<" "; print(*i); } }
template<class T, class L> void print(const pair<T, L>& p){ cout<<'(';print(p.first); cout<<","; print(p.second);cout<<')'; }
template<class T, size_t size> void print(const T (&a)[size]){ print(a[0]); for(auto i = a; ++i != end(a); ){ cout<<" "; print(*i); } }
template<class T> void print(const T& a){ cout << a; }
int out(){ putchar('\n'); return 0; }
template<class T> int out(const T& t){ print(t); putchar('\n'); return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); return 0; }
ll gcd(ll a, ll b){ while(b){ ll c = b; b = a % b; a = c; } return a; }
ll lcm(ll a, ll b){ if(!a || !b) return 0; return a * b / gcd(a, b); }
#define _GLIBCXX_DEBU
#ifdef _MY_DEBUG
    #undef endl
    #define debug(x) cout<<#x<<": "<<x<<endl
    void err(){}
    template<class T> void err(const T& t){ print(t);  cout<<" ";}
    template<class Head, class... Tail> void err(const Head& head, const Tail&... tail){ print(head); putchar(' '); out(tail...); }
#else
    #define debug(x)
    template<class... T> void err(const T&...){}
#endif
#pragma endregion

template< typename T >
vec longest_increasing_subsequence(const vector< T > &a, bool strict) {
  vector< T > lis;
  vec res;
  for(auto &p : a) {
    typename vector< T >::iterator it;
    if(strict) it = lower_bound(begin(lis), end(lis), p);
    else it = upper_bound(begin(lis), end(lis), p);
    if(end(lis) == it) lis.emplace_back(p);
    else *it = p;
    res.pb(ub(lis,p));
  }
  return res;
}

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int n=in(),m=in();
    vec r(m+1);
    rep(i,n){
        int x=in(),y=in();
        r[x-1]++;r[y]--;
    }
    rep(i,m)r[i+1]+=r[i];
    r.pop_back();
    vec pre = longest_increasing_subsequence(r,0);
    reverse(all(r));
    vec suf = longest_increasing_subsequence(r,0);
    reverse(all(suf));
    print(suf);
    int ma=0;
    rep(i,m){
        chmax(ma,pre[i]+suf[i]-1);
    }
    cout<<ma<<endl;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <iomanip>
#include <cmath>

#define elif else if

using namespace std;
typedef long long ll;
typedef long double ld;

const ll inf = 1e18 + 3, mod = 1e9 + 7;

istream& operator>>(istream& is, vector<ll> &a) {
	for (int i = 0; i < a.size(); ++i) cin >> a[i];
	return is;
}

ostream& operator<<(ostream& os, vector<ll> &a) {
	for (int i = 0; i < a.size(); ++i) cout << a[i] << ' ';
	return os;
}

void sort(vector<ll> &a) {
	sort(a.begin(), a.end());
}

ll step(ll a, ll n) {
	if (n == 1) return a % mod;
	if (n & 1) return (step(a, n - 1) * a) % mod;
	ll k = step(a, n / 2);
	return (k * k) % mod;
}

ll gcd(ll a, ll b) {
	return a > 0 ? gcd(b % a, a) : b;
}

ll lcm(ll a, ll b) {
	return a * b / gcd(a, b);
}

int main() {
	int n, m;
	cin >> n >> m;
	vector<ll> from(n), to(n);
	for (int i = 0; i < n; ++i) cin >> from[i] >> to[i], --from[i], --to[i];
	sort(from);
	sort(to);
	vector<ll> a(m);
	int pf = 0, pt = 0, curr = 0;
	for (int i = 0; i < m; ++i) {
		while (pf < n && from[pf] == i) ++pf, ++curr;
		a[i] = curr;
		while (pt < n && to[pt] == i) ++pt, --curr;
	}
	int check = a[0];
	bool cr = true;
	for (int i = 0; i < m; ++i)
		cr = cr && a[i] == check;
	if (cr) {
		cout << m;
		return 0;
	}
	ll prev = 0, maxx;
	for (int i = 1; i < m; ++i) {
		if (a[i] < a[i - 1]) prev += a[i - 1] - a[i];
		maxx = max(maxx, a[i] + prev);
	}
	cr = true;
	for (int i = 0; i < n; ++i)
		cr = cr && maxx > a[i];
	if (cr) cout << m - 1;
	else cout << m;
	//system("pause");
	return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <stdio.h>
#include <time.h>
using namespace std;
#define sqr(z) (z) * (z)
#define ch_NO(x) cout << "NO\n"; x = 1 - x;
#define b_NO cout << "NO\n"; break;
#define r_NO cout << "NO\n"; return 0;
#define c_NO cout << "NO\n"; continue;
#define ch_YES(x) cout << "YES\n"; x = 1 - x;
#define b_YES cout << "YES\n"; break;
#define r_YES cout << "YES\n"; return 0;
#define c_YES cout << "YES\n"; continue;
#define sz size()
#define pb push_back
#define int_ "%d",
#define fi first
#define se second
#define mm(k) memset((k), -1, sizeof(k));
#define all(k) (k).begin(), (k).end()
#define forn(i, n) for (int (i) = 0; (i) != (n); i++)
#define nfor(i, n) for (int (i) = (n) - 1; (i) != -1; i--)
#define do_nothing cout << " Work_Error ";
#define erace erase
#define incert insert
#define reverce reverse
#define re return
#define pre pre1234
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef long long ll;
typedef double ld;
typedef pair<ll, ll> lpii;
const int INF = 1e9;
const ll INFLL = 1e18 + 1;
const int MAX = 200001;
const ll MOD = 1000000007;
ll inq(ll k, ll q)
{
    if (q == 0)
        return 1;
    ll l = inq(k, q / 2);
    if (q % 2 == 0)
        return l * l % MOD;
    else
        return (l * l) % MOD * k % MOD;
}
ll gcd(ll a, ll b)
{
    if (a < b)
        swap(a, b);
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
ll cubr(ll a)
{
    ll l = -1, r = 1e6 + 2;
    while (l < r - 1)
    {
        ll mid = (l + r) / 2;
        if (mid * mid * mid > a)
            r = mid;
        else
            l = mid;
    }
    return l;
}
ll max(ll a, ll b)
{
    if (a > b)
        return a;
    return b;
}
ll possible(ll q)
{
    if (q == INF)
        return -1;
    return q;
}
bool correct(int x, int xx)
{
    if (x < 0)
        return 0;
    if (x >= xx)
        return 0;
    return 1;
}
ll dsumm(ll x, ll k)
{
    ll y = 1;
    ll z = 0;
    for (int i = 0; y < 1e18; i++)
    {
        z += x / y % k;
        y *= k;
    }
    return z;
}
ll dcount(ll x)
{
    ll y = 1;
    ll z = 0;
    int c[100];
    for (int i = 0; i < 10; i++)
    c[i] = 0;
    for (int i = 0; x > 0; i++)
    {
        if (c[x / y % 10] == 0)
        z++;
        c[x / y % 10] = 1;
        x /= 10;
    }
    return z;
}
ll lg10(ll x)
{
    if (x == 0)
        return 0;
    return lg10(x / 10) + 1;
}

#define bitcount __builtin_popcount
#define bitcountl __builtin_popcountll

#define RA(n, arr) cin >> n; forn(i, n) cin >> (arr)[i];
#define WA(n, arr) cout << n << "\n"; forn(i, n) cout << (arr)[i] << " ";
#define WWA(n, arr) forn(i, n) cout << (arr)[i] << " ";
#define RSA(n, arr) cin >> n; forn(i, n) cin >> (arr)[i]; sort(arr, arr + n);
#define WSA(n, arr) cout << n << "\n"; sort(arr, arr + n); forn(i, n) cout << (arr)[i] << " ";
#define WWSA(n, arr) sort(arr, arr + n); forn(i, n) cout << (arr)[i] << " ";
#define WSV(vec) cout << vec.size() << "\n"; sort(all(vec)); forn(i, vec.sz) cout << (vec)[i] << " ";
#define WWSV(vec) sort(all(vec)); forn(i, vec.sz) cout << (vec)[i] << " ";

#define cnks(l) for (int i = 0; i < l; i++) cnk[i][0] = 1; for (int i = 0; i < l; i++) cnk[0][i] = 1; for (int i = 0; i < l; i++) for (int j = 1; j < i; j++) cnk[i][j] = cnk[i - 1][j] + cnk[i - 1][j - 1];
#define facts(l) fact[0] = 1; for (int i = 1; i < l; i++) fact[i] = fact[i - 1] * i;
#define stirling_2s(l) stirling_2[0][0] = 1; for (int i = 1; i < l; i++) stirling_2[i][0] = 0; for (int i = 0; i < l; i++) for (int j = 1; j <= i; j++) stirling_2[i][j] = stirling_2[i - 1][j - 1] + j * stirling_2[i - 1][j];

//string months[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
//int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//vi cx, cy;
//______________________
ll n, m;
ll a[500000];
ll d[500000];
ll dp1[500000];
ll rd1[500000];
ll dp2[500000];
ll rd2[500000];
ll f1[500000];
ll f2[500000];

int main()
{
    //freopen("in.in", "r", stdin);
    //freopen("out.out", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n >> m;
    forn(i, MAX) rd1[i] = -1;
    forn(i, MAX) rd2[i] = -1;
    for (int i = 0; i < n; i++)
    {
        int l, r;
        cin >> l >> r;
        l--;
        d[l]++;
        d[r]--;
    }
    int c = 0;
    for (int i = 0; i <= m; i++)
    {
        a[i] = c;
        c += d[i];
    }
    for (int i = 1; i <= m; i++)
    {
        int l = 0, r = i + 1;
        while (l + 1 < r)
        {
            int mid = (l + r) / 2;
            if (rd1[mid] <= a[i] && rd1[mid] != -1)
            {
                l = mid;
            }
            else
            {
                r = mid;
            }
        }
        dp1[i] = l + 1;
        if (rd1[l + 1] == -1)
            rd1[l + 1] = a[i];
        rd1[l + 1] = min(rd1[l + 1], a[i]);
    }
    for (int i = m; i >= 1; i--)
    {
        int l = 0, r = i + 1;
        while (l + 1 < r)
        {
            int mid = (l + r) / 2;
            if (rd2[mid] <= a[i] && rd2[mid] != -1)
            {
                l = mid;
            }
            else
            {
                r = mid;
            }
        }
        dp2[i] = l + 1;
        if (rd2[l + 1] == -1)
            rd2[l + 1] = a[i];
        rd2[l + 1] = min(rd2[l + 1], a[i]);
    }
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ans = max(ans, dp1[i] + dp2[i] - 1);
    }
    cout << ans;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5+10;
int n,m;
int s[N],loc[N];
int t[2][4*N];
int f[N][2],ans;
pair<int,int> px[N];

void query(int sig,int x,int l,int r,int tl,int tr,int &ret) {
	if (r<tl || l>tr) return;
	if (tl<=l && r<=tr) {
		ret=max(ret,t[sig][x]);
		return;
	}
	query(sig,x*2  ,l,l+r>>1,tl,tr,ret);
	query(sig,x*2+1,(l+r>>1)+1,r,tl,tr,ret);
}

void change(int sig,int x,int l,int r,int tg,int v) {
	if (l==r) {
		t[sig][x] = max(t[sig][x],v);
		return;
	}
	int mid=l+r>>1;
	if (tg<=mid)
		change(sig,x*2,l,l+r>>1,tg,v);
	else
		change(sig,x*2+1,(l+r>>1)+1,r,tg,v);
	t[0][x]=max(t[0][x*2],t[0][x*2+1]);
	t[1][x]=max(t[1][x*2],t[1][x*2+1]);
}

int main() {
	//freopen("c.in","r",stdin);
	cin>>n>>m; for (int i=1; i<=n; i++) {
		int l,r; scanf("%d %d",&l,&r);
		s[l]++,s[r+1]--;
	}
	for (int i=1; i<=m; i++) s[i]+=s[i-1];
	for (int i=1; i<=m; i++) {
		px[i] = make_pair(s[i],i);
	}
	sort(px+1,px+1+m); int cnt=0;
	for (int i=1; i<=m; i++) {
		if (px[i].first != px[i-1].first) cnt++;
		loc[px[i].second] = cnt;
	}
	for (int i=1; i<=m; i++) {
		query(0,1,1,cnt,1,loc[i],f[i][0]);
		f[i][0]++;

		query(1,1,1,cnt,loc[i],cnt,f[i][1]);
		f[i][1]++;

		change(0,1,1,cnt,loc[i],f[i][0]);
		change(1,1,1,cnt,loc[i],max(f[i][1],f[i][0]));
		ans=max(f[i][0],f[i][1]);
	}
	cout<<ans<<endl;
}

#include<bits/stdc++.h>
using namespace std;
inline int R()
{
	char c;int sign=1,res=0;
	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1;res+=c-'0';
	while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
	return res*sign;
}
const int Maxn=1e5+5;
int a[Maxn],s[Maxn],t[Maxn],n,m,ans1[Maxn],ans2[Maxn];
int main()
{
	n=R();m=R();

	int z,y;
	for(int i=1;i<=n;i++)
	{
		z=R();y=R();
		s[z]++;
		s[y+1]--;
	}
	for(int i=1;i<=m;i++)
		a[i]=a[i-1]+s[i];
	memset(t,63,sizeof t);
	for(int i=1;i<=m;i++)
	{
		int p=upper_bound(t+1,t+1+m,a[i])-t;
		ans1[i]=p;
		t[p]=a[i];
	}
	memset(t,63,sizeof t);
	for(int i=m;i>=1;i--)
	{
		int p=upper_bound(t+1,t+1+m,a[i])-t;
		ans2[i]=p;
		t[p]=a[i];
	}
	int M=0;
	for(int i=1;i<=n;i++)
		M=max(M,ans1[i]+ans2[i]-1);
	printf("%d\n",M);
}

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <vector>
#include <set>
#include <utility>
#include <algorithm>

using namespace std;
int con[200005];
int how[200005];
vector < int > tt;
vector < int > all;
int main()
{
    int N,M,now=0,big=0,l=2e9,r=-2e9,ans=0,i;
    scanf("%d %d",&N,&M);
    for(i=1;i<=N;i++)
    {
        scanf("%d %d",&l,&r);
        how[l]++;
        how[r+1]--;
    }
    for(i=1;i<=M;i++)
    {
        now+=how[i];
        big=max(big,now);
        con[i]=now;
        //printf("%d\n",con[i]);
    }
    for(i=1;i<=M;i++)
    {
        if(con[i]==big)
        {
            ans++;
            l=min(l,i);
            r=max(i,r);
        }
    }

    all.clear();
    for(i=1;i<l;i++)
    {

        if(upper_bound(all.begin(),all.end(),con[i])==all.end()) all.push_back(con[i]);
        else all[upper_bound(all.begin(),all.end(),con[i])-all.begin()]=con[i];
    }
    ans+=all.size();

    all.clear();
    for(i=M;i>r;i--)
    {
        if(upper_bound(all.begin(),all.end(),con[i])==all.end()) all.push_back(con[i]);
        else all[upper_bound(all.begin(),all.end(),con[i])-all.begin()]=con[i];
    }
    ans+=all.size();
    printf("%d\n",ans);
    return 0;
}

#include <ext/rope>
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define ull unsigned long long
typedef vector<vector<ll>> mat;

const int N = 1e5 + 5;
int inc[N] , de[N] , a[N] , b[N] , n , m , x  , y , val[N] , cur , incDp[N] , deDp[N] , out;
vector<int> v;

int main()
{
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);

    cin >> n >> m;
    for(int i = 0 ; i < n ; i++)
        cin >> x >> y , val[x]++ , val[y + 1]--;

    for(int i = 1 ; i <= m ; i++)
        cur += val[i] , inc[i] = cur + i , de[i] = -cur;

    for(int i = 1 ; i <= m ; i++)
    {
        auto it = lower_bound(v.begin() , v.end() , inc[i]);
        if(it != v.end()) *it = inc[i];
        else v.push_back(inc[i]);
        incDp[i] = v.size();
    }
    v.clear();
    for(int i = 1 ; i <= m ; i++)
    {
        auto it = lower_bound(v.begin() , v.end() , de[i]);
        if(it != v.end()) *it = de[i];
        else v.push_back(de[i]);
        deDp[i] = v.size();
    }

    for(int i = 1 ; i < m ; i++)
        out = max(out , incDp[i] + deDp[i + 1]);
    out = max(incDp[m] , deDp[1]);
    cout << out;

    return 0;
}

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#define N 200002
#define M 200002
using namespace std;
int n,m;
int l[N],r[N];
int val[M];
int f[M],g[M];
int val1[M],val2[M];
int main(){
	int ans = 0;
	scanf("%d%d",&n,&m);
	for(int i=0;i<=m + 1;i++)val[i] = 0;
	for(int i=1;i<=n;i++) scanf("%d%d",&l[i],&r[i]);
	for(int i=1;i<=n;i++)val[l[i]]++,val[r[i] + 1]--;
	for(int i=1;i<=m;i++)val[i] += val[i - 1];
	f[0] = 0;
	for(int i=0;i<=m;i++)val1[i] = -1;
	val1[0] = 0;
	for(int i=1;i<=m;i++){
		int l = 0,r = m;
		while(l < r){
			int mid = (l + r + 1) >> 1;
			if(val1[mid] >= val[i])l = mid;
			else r = mid - 1;
		}
		f[i] = r + 1,val1[f[i]] = max(val1[f[i]],val[i]);
	}
	g[m + 1] = 0;
	for(int i=0;i<=m;i++)val2[i] = -1;
	val2[0] = 0;
	for(int i=m;i>=1;i--){
		int l = 0,r = m;
		while(l < r){
			int mid = (l + r + 1) >> 1;
			if(val2[mid] >= val[i])l = mid;
			else r = mid - 1;
		}
		g[i] = r + 1,val2[g[i]] = max(val2[g[i]],val[i]);
	}
	for(int i=1;i<=m;i++)ans = max(ans,f[i]);
	for(int i=1;i<=m;i++)ans = max(ans,g[i]);
	for(int i=1;i<=m;i++)ans = max(ans,f[i] + g[i] - 1);
	printf("%d\n",ans);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+15;

int tree[N*4];

void update(int pos,int l,int r,int ql,int qr){
    if(r<ql || qr<l)return;

    if(ql<=l && r<=qr){

        ++tree[pos];
        return;
    }
    int mid = (l+r)/2;
    update(pos*2,l,mid,ql,qr);
    update(pos*2+1,mid+1,r,ql,qr);
}

int get(int pos,int l,int r,int ind){
    if(l==r && l==ind){
        return tree[pos];
    }
    int ret= tree[pos],mid = (l+r)/2;

    if(ind<=mid)
        ret+=get(pos*2,l,mid,ind);
    else
        ret+=get(pos*2+1,mid+1,r,ind);
    return ret;
}

int cnt[N];

int pen[N];

int get(int ind){
    int ret= 0;
    while(ind)
        ret = max(ret,pen[ind]),ind = ind&(ind-1);
    return ret;
}

void update(int ind,int upd){
    while(ind<N){
        pen[ind] = max(pen[ind],upd);
        ind += ind&(-ind);
    }
}
int Left[N];
int main(){
    //freopen("input.txt","r",stdin);
    int n,m,i,l,r;

    cin>>n>>m;

    for(i=0;i<n;++i){
        scanf("%d%d",&l,&r);
        update(1,1,m,l,r);
    }
    for(i=1;i<=m;++i){
        cnt[i]= get(1,1,m,i)+1;
    }
    int temp,ret=0;
    for(i=1;i<=m;++i){
        temp = get(cnt[i])+1;
        update(cnt[i],temp);
        Left[i]= temp;
    }
    memset(pen,0,sizeof(pen));
    for(i=1;i<=m;++i){
        cnt[i]= m+2-cnt[i];
    }
    for(i=m;i>=1;--i){
        temp = get(cnt[i])+1;
        update(cnt[i],temp);
        ret= max(ret, Left[i] + temp-1);
    }
    cout<<ret<<endl;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef long double ld;

#define sz(x) (int)(x.size())
#define pii pair <int, int>
#define X first
#define Y second
#define pb push_back
struct node {
    int s = 0, val= 0;
};
vector <int> ans;
vector <node> tree;

void relax(int i, int l, int r) {
    if (l != r)
        tree[i].val = tree[2 * i].val + tree[2 * i + 1].val;
}

void push(int i, int l, int r) {
    tree[i].val += (r - l + 1) * tree[i].s;
    if (l != r) {
        tree[2 * i].s += tree[i].s;
        tree[2 * i + 1].s += tree[i].s;
    }
    tree[i].s = 0;
}

void update(int i, int l, int r, int nl, int nr) {
    push(i, l, r);
    //cout << i << " " << l <<" "<< r << " "<< nl << " " << nr << endl;
    if (l > nr || r < nl)
        return;
    if (l >= nl && r <= nr) {
        tree[i].s++;
        push(i, l, r);
        return;
    }
    int m = (l + r) / 2;
    update(2 * i, l, m, nl, nr);
    update(2 * i + 1, m + 1, r, nl, nr);
    relax(i, l, r);
}

void find_ans(int i, int l, int r) {
    push(i, l, r);
    if (l == r) {
        ans.pb(tree[i].val);
        return;
    }
    int mid = (l + r) / 2;
    find_ans(2 * i, l ,mid);
    find_ans(2 * i + 1, mid + 1, r);
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    tree.resize(4 * m);
    for (int i = 0; i < n; ++i) {
        int l ,r;
        cin >> l >> r;
        update(1, 1, m, l, r);
    }
    find_ans(1, 1, m);
    //sort(ans.begin(), ans.end());
    int res = 0;
    vector <int> dp(n), dp2(n);
    vector <int> seq(n, 1e9);
    seq[0] = -1;
    int mx = 0;
    for (int i = 0; i < n; ++i) {
        int l = 0, r = n - 1;
        while (r - l > 1) {
            int mid = (r + l) / 2;
            if (seq[mid] > ans[i])
                r = mid;
            else
                l = mid;
        }
        seq[l + 1] = ans[i];
        mx = max(mx, l + 1);
        dp[i] = mx;
    }
    //reverse(ans.begin(), ans.end());
    mx = 0;
    seq.resize(0);
    seq.resize(n, 1e9);
    seq[0] = -1;
    for (int i = n - 1; i > -1; --i) {
        int l = 0, r = n - 1;
        while (r - l > 1) {
            int mid = (r + l) / 2;
            if (seq[mid] > ans[i])
                r = mid;
            else
                l = mid;
        }
        seq[l + 1] = ans[i];
        mx = max(mx, l + 1);
        dp2[i] = mx;
    }
    for (int i = 0; i < n; ++i) {
        res = max(res, dp[i] + dp2[i]);
    }
    cout << res;
    return 0;
}

#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef unsigned int ui32;
const long long INFLL = 1e18;

using namespace std;

const int MAXN = 100000;

int c[MAXN + 10];

int main() {
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        ++c[l];
        --c[r + 1];
    }
    for (int i = 1; i <= m; i++) {
        c[i] += c[i - 1];
    }
    int mx = *max_element(c + 1, c + 1 + m);
    bool now = false;
    int cnt = 0;
    int l = 1e9;
    int r = -1e9;
    int sz = 0;
    for (int i = 1; i <= m; i++) {
        if (c[i] == mx) {
            l = min(l, i);
            r = max(r, i);
            ++sz;
            cnt += !now;
            now = true;
        } else {
            now = false;
        }
    }
    if (cnt == 1) {
        cout << m << "\n";
    } else {
        cout << l - 1 + m - r + max(sz, r - l + 1 - sz + 1) << "\n";
    }
    return 0;
}