Young Teodor enjoys drawing. His favourite hobby is drawing segments with integer borders inside his huge [1;m] segment. One day Teodor noticed that picture he just drawn has one interesting feature: there doesn't exist an integer point, that belongs each of segments in the picture. Having discovered this fact, Teodor decided to share it with Sasha.Sasha knows that Teodor likes to show off so he never trusts him. Teodor wants to prove that he can be trusted sometimes, so he decided to convince Sasha that there is no such integer point in his picture, which belongs to each segment. However Teodor is lazy person and neither wills to tell Sasha all coordinates of segments' ends nor wills to tell him their amount, so he suggested Sasha to ask him series of questions 'Given the integer point xi, how many segments in Fedya's picture contain that point?', promising to tell correct answers for this questions.Both boys are very busy studying and don't have much time, so they ask you to find out how many questions can Sasha ask Teodor, that having only answers on his questions, Sasha can't be sure that Teodor isn't lying to him. Note that Sasha doesn't know amount of segments in Teodor's picture. Sure, Sasha is smart person and never asks about same point twice.

First line of input contains two integer numbers: n and m (1 ≤ n, m ≤ 100 000) — amount of segments of Teodor's picture and maximal coordinate of point that Sasha can ask about. ith of next n lines contains two integer numbers li and ri (1 ≤ li ≤ ri ≤ m) — left and right ends of ith segment in the picture. Note that that left and right ends of segment can be the same point. It is guaranteed that there is no integer point, that belongs to all segments.

Single line of output should contain one integer number k – size of largest set (xi, cnt(xi)) where all xi are different, 1 ≤ xi ≤ m, and cnt(xi) is amount of segments, containing point with coordinate xi, such that one can't be sure that there doesn't exist point, belonging to all of segments in initial picture, if he knows only this set(and doesn't know n).

NoteFirst example shows situation where Sasha can never be sure that Teodor isn't lying to him, because even if one knows cnt(xi) for each point in segment [1;4], he can't distinguish this case from situation Teodor has drawn whole [1;4] segment.In second example Sasha can ask about 5 points e.g. 1, 2, 3, 5, 6, still not being sure if Teodor haven't lied to him. But once he knows information about all points in [1;6] segment, Sasha can be sure that Teodor haven't lied to him.

#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;
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;
}

#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 <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;
}

/*
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);
	}
}

#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 <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 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>

#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>

#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 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<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 <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<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 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 <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 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<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<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;
}

//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   │ . │←─┘│
 * └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 */

#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;
}

/////////////////////////   _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;
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>
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<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;
#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;
}

/*
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;
}

// 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;
}

#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;

#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>
#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 ;
}

#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 <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 <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>
#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;
}

#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>
#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);
}

#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);
}

#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;
}

/// 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;
}

#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>
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 <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>
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;
}

#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;

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 <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 <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;
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<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 <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>
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 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;
}

#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<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;
}

// 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>

#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 <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;
}

#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();
}

/**************************************************
    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;

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);
}

#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;
}

#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>
#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<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;
}

#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;
}

#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;
}

/*
 *  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<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>

// #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<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;
}

#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;
}

//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;
}

/*************************************************************************
    > 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<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);
}

#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 <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;
}

// 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;
}

/*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);
}

#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 <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/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
}

#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
*/

#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<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 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>
#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 <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<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 <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;
}

#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 <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;
}