stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<iostream>

#include<queue>

#include<vector>

using namespace std;

struct node

{

    long long v,tag;

}tree[1000000*4+1];

void build(int node,int l,int r)

{

    if(l==r)

    {

        tree[node].v=l;

        return;

    }

    build(node*2,l,(l+r)/2);

    build(node*2+1,(l+r)/2+1,r);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

void pushdown(int node,int l,int r)

{

    if(tree[node].tag)

    {

        tree[node*2].v+=tree[node].tag;

        tree[node*2+1].v+=tree[node].tag;

        tree[node*2].tag+=tree[node].tag;

        tree[node*2+1].tag+=tree[node].tag;

        tree[node].tag=0;

    }

}

long long query(int node,int st,int ed,int l,int r)

{

    if(st>r||ed<l)

        return -1;

    if(st>=l&&ed<=r)

        return tree[node].v;

    pushdown(node,st,ed);

    return max(query(node*2,st,(st+ed)/2,l,r),query(node*2+1,(st+ed)/2+1,ed,l,r));

}

void update(int node,int st,int ed,int l,int r,int ind)

{

    if(st>r||ed<l)

        return;

    if(st>=l&&ed<=r)

    {

        tree[node].v+=ind;

        tree[node].tag+=ind;

        return;

    }

    pushdown(node,st,ed);

    update(node*2,st,(st+ed)/2,l,r,ind);

    update(node*2+1,(st+ed)/2+1,ed,l,r,ind);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

vector<int> p[200001];

int main()

{

    long long n,m; 

    cin>>n>>m;

    for(int i=1;i<=n;i++)

	{

		int l,r;

		scanf("%d%d",&l,&r);

		p[l].push_back(r);

    }

	long long ans=n-m;

    build(1,1,m+1);

	for(int i=0;i<=m;i++)

	{

		for(int j=0;j<p[i].size();j++)

		{

			int right=p[i][j];

			update(1,1,m+1,1,right,1);

		}

		ans=max(ans,query(1,1,m+1,i+1,m+1)-m-i-1);

	}

	printf("%lld",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.440065890954149x):
#include <iostream>

#include <algorithm>

#include <queue>

using namespace std;

int t[200005];

struct ff{

    int l,r;

    bool operator<(const ff &b)const{

        return l!=b.l?l<b.l:r>b.r;

    }

}a[200005];

priority_queue<int,vector<int>,greater<int> >q;

int main(){

    int n,m;

    cin>>n>>m;

    int i;

    for(i=1;i<=n;i++) cin>>a[i].l>>a[i].r;

    sort(a+1,a+n+1);

    int h=1,tt=m;

    for(i=1;i<=n;i++){

        q.push(a[i].r);

        if(h<=tt&&h<=a[i].l) h++;

        else{

            t[++t[0]]=q.top();

            q.pop();

        }

    }

    sort(t+1,t+t[0]+1);

    int ans=0;

    for(i=t[0];i>=1;i--){

        if(h<=tt&&t[i]<=tt)tt--;

        else ans++;

    }

    cout<<ans<<endl;

    return 0;

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<iostream>

#include<queue>

#include<vector>

using namespace std;

struct node

{

    long long v,tag;

}tree[1000000*4+1];

void build(int node,int l,int r)

{

    if(l==r)

    {

        tree[node].v=l;

        return;

    }

    build(node*2,l,(l+r)/2);

    build(node*2+1,(l+r)/2+1,r);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

void pushdown(int node,int l,int r)

{

    if(tree[node].tag)

    {

        tree[node*2].v+=tree[node].tag;

        tree[node*2+1].v+=tree[node].tag;

        tree[node*2].tag+=tree[node].tag;

        tree[node*2+1].tag+=tree[node].tag;

        tree[node].tag=0;

    }

}

long long query(int node,int st,int ed,int l,int r)

{

    if(st>r||ed<l)

        return -1;

    if(st>=l&&ed<=r)

        return tree[node].v;

    pushdown(node,st,ed);

    return max(query(node*2,st,(st+ed)/2,l,r),query(node*2+1,(st+ed)/2+1,ed,l,r));

}

void update(int node,int st,int ed,int l,int r,int ind)

{

    if(st>r||ed<l)

        return;

    if(st>=l&&ed<=r)

    {

        tree[node].v+=ind;

        tree[node].tag+=ind;

        return;

    }

    pushdown(node,st,ed);

    update(node*2,st,(st+ed)/2,l,r,ind);

    update(node*2+1,(st+ed)/2+1,ed,l,r,ind);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

vector<int> p[200001];

int main()

{

    long long n,m; 

    cin>>n>>m;

    for(int i=1;i<=n;i++)

	{

		int l,r;

		scanf("%d%d",&l,&r);

		p[l].push_back(r);

    }

	long long ans=n-m;

    build(1,1,m+1);

	for(int i=0;i<=m;i++)

	{

		for(int j=0;j<p[i].size();j++)

		{

			int right=p[i][j];

			update(1,1,m+1,1,right,1);

		}

		ans=max(ans,query(1,1,m+1,i+1,m+1)-m-i-1);

	}

	printf("%lld",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.453095048237268x):
// luogu-judger-enable-o2

#include<bits/stdc++.h>

using namespace std;

int n,m,ans=0,a[200005],ll,rr;

struct node

{

    int l,r;

    bool operator<(const node &a)const

    {return l!=a.l?l<a.l:r>a.r;}

}b[200005];

priority_queue<int,vector<int>,greater<int> > q;

int main()

{

    cin>>n>>m;

    for(int i=1;i<=n;i++)

    {

    	cin>>b[i].l>>b[i].r;

	} 

    sort(b+1,b+n+1);

    ll=1,rr=m;

    for(int i=1;i<=n;i++)

	{

        q.push(b[i].r);

        if(ll<=rr&&ll<=b[i].l)

		{

			ll=ll+1;

		}

        else

		{

            a[++a[0]]=q.top();

            q.pop();

        }

    }

    sort(a+1,a+a[0]+1);

    for(int i=a[0];i>=1;i--)

	{

        if(ll<=rr&&a[i]<=rr)

		{

			rr--;

		}

        else ans++;

    }

    cout<<ans;

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<iostream>

#include<queue>

#include<vector>

using namespace std;

struct node

{

    long long v,tag;

}tree[1000000*4+1];

void build(int node,int l,int r)

{

    if(l==r)

    {

        tree[node].v=l;

        return;

    }

    build(node*2,l,(l+r)/2);

    build(node*2+1,(l+r)/2+1,r);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

void pushdown(int node,int l,int r)

{

    if(tree[node].tag)

    {

        tree[node*2].v+=tree[node].tag;

        tree[node*2+1].v+=tree[node].tag;

        tree[node*2].tag+=tree[node].tag;

        tree[node*2+1].tag+=tree[node].tag;

        tree[node].tag=0;

    }

}

long long query(int node,int st,int ed,int l,int r)

{

    if(st>r||ed<l)

        return -1;

    if(st>=l&&ed<=r)

        return tree[node].v;

    pushdown(node,st,ed);

    return max(query(node*2,st,(st+ed)/2,l,r),query(node*2+1,(st+ed)/2+1,ed,l,r));

}

void update(int node,int st,int ed,int l,int r,int ind)

{

    if(st>r||ed<l)

        return;

    if(st>=l&&ed<=r)

    {

        tree[node].v+=ind;

        tree[node].tag+=ind;

        return;

    }

    pushdown(node,st,ed);

    update(node*2,st,(st+ed)/2,l,r,ind);

    update(node*2+1,(st+ed)/2+1,ed,l,r,ind);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

vector<int> p[200001];

int main()

{

    long long n,m; 

    cin>>n>>m;

    for(int i=1;i<=n;i++)

	{

		int l,r;

		scanf("%d%d",&l,&r);

		p[l].push_back(r);

    }

	long long ans=n-m;

    build(1,1,m+1);

	for(int i=0;i<=m;i++)

	{

		for(int j=0;j<p[i].size();j++)

		{

			int right=p[i][j];

			update(1,1,m+1,1,right,1);

		}

		ans=max(ans,query(1,1,m+1,i+1,m+1)-m-i-1);

	}

	printf("%lld",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.5276911430123405x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<queue>

#define ksjnf sfnlk

using namespace std;



int n,m,ans=0,tmp[200005];

struct Student{

    int l,r;

    bool operator<(const Student &b)const{

        return l!=b.l?l<b.l:r>b.r;

    }

}s[200005];

priority_queue<int,vector<int>,greater<int> > q;



int main(){

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

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

    for(int i=1;i<=n;i++)

        scanf("%d%d",&s[i].l,&s[i].r);

    sort(s+1,s+n+1);

    int h=1,t=m;

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

        q.push(s[i].r);

        if(h<=t&&h<=s[i].l)h++;

        else{

            tmp[++tmp[0]]=q.top();

            q.pop();

        }

    }

    sort(tmp+1,tmp+tmp[0]+1);

    for(int i=tmp[0];i>=1;i--){

        if(h<=t&&tmp[i]<=t)t--;

        else ans++;

    }

    printf("%d",ans);

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<iostream>

#include<queue>

#include<vector>

using namespace std;

struct node

{

    long long v,tag;

}tree[1000000*4+1];

void build(int node,int l,int r)

{

    if(l==r)

    {

        tree[node].v=l;

        return;

    }

    build(node*2,l,(l+r)/2);

    build(node*2+1,(l+r)/2+1,r);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

void pushdown(int node,int l,int r)

{

    if(tree[node].tag)

    {

        tree[node*2].v+=tree[node].tag;

        tree[node*2+1].v+=tree[node].tag;

        tree[node*2].tag+=tree[node].tag;

        tree[node*2+1].tag+=tree[node].tag;

        tree[node].tag=0;

    }

}

long long query(int node,int st,int ed,int l,int r)

{

    if(st>r||ed<l)

        return -1;

    if(st>=l&&ed<=r)

        return tree[node].v;

    pushdown(node,st,ed);

    return max(query(node*2,st,(st+ed)/2,l,r),query(node*2+1,(st+ed)/2+1,ed,l,r));

}

void update(int node,int st,int ed,int l,int r,int ind)

{

    if(st>r||ed<l)

        return;

    if(st>=l&&ed<=r)

    {

        tree[node].v+=ind;

        tree[node].tag+=ind;

        return;

    }

    pushdown(node,st,ed);

    update(node*2,st,(st+ed)/2,l,r,ind);

    update(node*2+1,(st+ed)/2+1,ed,l,r,ind);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

vector<int> p[200001];

int main()

{

    long long n,m; 

    cin>>n>>m;

    for(int i=1;i<=n;i++)

	{

		int l,r;

		scanf("%d%d",&l,&r);

		p[l].push_back(r);

    }

	long long ans=n-m;

    build(1,1,m+1);

	for(int i=0;i<=m;i++)

	{

		for(int j=0;j<p[i].size();j++)

		{

			int right=p[i][j];

			update(1,1,m+1,1,right,1);

		}

		ans=max(ans,query(1,1,m+1,i+1,m+1)-m-i-1);

	}

	printf("%lld",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.970670235469906x):
#include <cstdio>

#include <algorithm>

#include <queue>

using namespace std;

const int N=200005;

int n,m;

struct People{

    int l,r,id;

    friend bool operator < (People a,People b){

        return a.r>b.r;

    }

}a[N],b[N];

bool inq[N];

int cnt;

priority_queue<People> q;

bool cmpl(const People &a,const People &b){

    return a.l<b.l;

}

bool cmpr(const People &a,const People &b){

    return a.r>b.r;

}

int main(){

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

    for(int i=1;i<=n;i++)

        scanf("%d%d",&a[i].l,&a[i].r);

    sort(a+1,a+1+n,cmpl);

    int nowl=0,nowr=m+1,last;

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

        a[i].id=i;

        if(nowl+1<=a[i].l){

            nowl++;

            q.push(a[i]);

            inq[i]=true;

        }

        else if(!q.empty()){

            People best=q.top();

            if(a[i].r>best.r){

                q.pop();

                inq[best.id]=false;

                q.push(a[i]);

                inq[i]=true;

            }

        }

    }

    for(int i=1;i<=n;i++)

        if(!inq[i])

            b[++cnt]=a[i];

    sort(b+1,b+1+cnt,cmpr);

    for(int i=1;i<=cnt&&nowr-1!=nowl;i++)

        if(nowr-1>=b[i].r)

            nowr--;

    printf("%d\n",n-(nowl+(m-nowr+1)));

    return 0;

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<iostream>

#include<queue>

#include<vector>

using namespace std;

struct node

{

    long long v,tag;

}tree[1000000*4+1];

void build(int node,int l,int r)

{

    if(l==r)

    {

        tree[node].v=l;

        return;

    }

    build(node*2,l,(l+r)/2);

    build(node*2+1,(l+r)/2+1,r);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

void pushdown(int node,int l,int r)

{

    if(tree[node].tag)

    {

        tree[node*2].v+=tree[node].tag;

        tree[node*2+1].v+=tree[node].tag;

        tree[node*2].tag+=tree[node].tag;

        tree[node*2+1].tag+=tree[node].tag;

        tree[node].tag=0;

    }

}

long long query(int node,int st,int ed,int l,int r)

{

    if(st>r||ed<l)

        return -1;

    if(st>=l&&ed<=r)

        return tree[node].v;

    pushdown(node,st,ed);

    return max(query(node*2,st,(st+ed)/2,l,r),query(node*2+1,(st+ed)/2+1,ed,l,r));

}

void update(int node,int st,int ed,int l,int r,int ind)

{

    if(st>r||ed<l)

        return;

    if(st>=l&&ed<=r)

    {

        tree[node].v+=ind;

        tree[node].tag+=ind;

        return;

    }

    pushdown(node,st,ed);

    update(node*2,st,(st+ed)/2,l,r,ind);

    update(node*2+1,(st+ed)/2+1,ed,l,r,ind);

    tree[node].v=max(tree[node*2].v,tree[node*2+1].v);

}

vector<int> p[200001];

int main()

{

    long long n,m; 

    cin>>n>>m;

    for(int i=1;i<=n;i++)

	{

		int l,r;

		scanf("%d%d",&l,&r);

		p[l].push_back(r);

    }

	long long ans=n-m;

    build(1,1,m+1);

	for(int i=0;i<=m;i++)

	{

		for(int j=0;j<p[i].size();j++)

		{

			int right=p[i][j];

			update(1,1,m+1,1,right,1);

		}

		ans=max(ans,query(1,1,m+1,i+1,m+1)-m-i-1);

	}

	printf("%lld",ans);

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.5276911430123405x):
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<queue>

using namespace std;



int n,m,ans=0,tmp[200005];

struct Student{

    int l,r;

    bool operator<(const Student &b)const{

        return l!=b.l?l<b.l:r>b.r;

    }

}s[200005];

priority_queue<int,vector<int>,greater<int> > q;



int main(){

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

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

    for(int i=1;i<=n;i++)

        scanf("%d%d",&s[i].l,&s[i].r);

    sort(s+1,s+n+1);

    int h=1,t=m;

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

        q.push(s[i].r);

        if(h<=t&&h<=s[i].l)h++;

        else{

            tmp[++tmp[0]]=q.top();

            q.pop();

        }

    }

    sort(tmp+1,tmp+tmp[0]+1);

    for(int i=tmp[0];i>=1;i--){

        if(h<=t&&tmp[i]<=t)t--;

        else ans++;

    }

    printf("%d",ans);

}
// Slower C++ solution:
#include<bits/stdc++.h>



using namespace std;



typedef tuple< int, int, int > Pi;



int N, M, L[200000], R[200000];

int ans = 11451419;

Pi first[200000], second[200000];



int check(int vq)

{

  vector< Pi > que2;

  int tail = 1;

  bool used[200000] = {};

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

    int l, r, idx;

    tie(l, r, idx) = first[i];

    if(tail <= l && tail < vq) {

      tail++;

      used[idx] = true;

    }

  }

  int head = M;

  int ret = 0;

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

    int l, r, idx;

    tie(r, l, idx) = second[i];

    if(used[idx]) continue;

    r *= -1;

    if(r <= head && head >= tail) {

      head--;

    } else {

      ++ret;

    }

  }

  ans = min(ans, ret);

  return (ret);

}



int main()

{

  cin >> N >> M;

  for(int i = 0; i < N; i++) cin >> L[i] >> R[i];

  for(int i = 0; i < N; i++) first[i] = make_tuple(L[i], -R[i], i);

  for(int i = 0; i < N; i++) second[i] = make_tuple(-R[i], L[i], i);

  sort(second, second + N);

  sort(first, first + N);





  int low = 1, high = M + 1;

  while(high - low > 1) {

    int mid = (low + high) >> 1;

    (check(mid) - check(mid - 1) > 0 ? low : high) = mid;

  }

  check(0);

  check(M + 1);

  for(int i = low - 30; i <= high + 30; i++)check(i);





  cout << ans << endl;

}


// Faster C++ solution for the same problem (measured speedup: 2.041706118981155x):
#include<bits/stdc++.h>

 

using namespace std;

 

typedef tuple< int, int, int > Pi;

 

int N, M, L[200000], R[200000];

int ans = 11451419;

Pi first[200000], second[200000];

 

int check(int vq)

{

  vector< Pi > que2;

  int tail = 1;

  bool used[200000] = {};

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

    int l, r, idx;

    tie(l, r, idx) = first[i];

    if(tail <= l && tail < vq) {

      tail++;

      used[idx] = true;

    }

  }

  int head = M;

  int ret = 0;

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

    int l, r, idx;

    tie(r, l, idx) = second[i];

    if(used[idx]) continue;

    r *= -1;

    if(r <= head && head >= tail) {

      head--;

    } else {

      ++ret;

    }

  }

  ans = min(ans, ret);

  return (ret);

}

 

int main()

{

  cin >> N >> M;

  for(int i = 0; i < N; i++) cin >> L[i] >> R[i];

  for(int i = 0; i < N; i++) first[i] = make_tuple(L[i], -R[i], i);

  for(int i = 0; i < N; i++) second[i] = make_tuple(-R[i], L[i], i);

  sort(second, second + N);

  sort(first, first + N);

 

  int low = 1, high = M + 1;

  while(high - low > 1) {

    int mid = (low + high) >> 1;

    (check(mid) - check(mid - 1) > 0 ? low : high) = mid;

  }

  check(0);

  check(M + 1);

  cout << ans << endl;

}
// Slower C++ solution:
#include<bits/stdc++.h>

#define mem0(a) memset(a,0,sizeof(a))  

#define meminf(a) memset(a,0x3f,sizeof(a))  

using namespace std;  

typedef long long ll;  

typedef long double ld;  

typedef double db;  

const int maxn=200005,inf=0x3f3f3f3f;    

const ll llinf=0x3f3f3f3f3f3f3f3f;     

const ld pi=acos(-1.0L);  

vector<int> v[maxn]; 

int main() {  

    int n,m,i,j,l,r;  

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

    priority_queue<int,vector<int>,greater<int> > pq;  

    for (i=1;i<=n;i++) {  

        scanf("%d%d",&l,&r);  

        if (l==0) pq.push(r); else v[l].push_back(r);  

    }  

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

        sort(v[i].begin(),v[i].end());  

    }  

    int pos=-1;  

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

        if (v[i].size()>1) {

            for (j=0;j<v[i].size()-1;j++) pq.push(v[i][j]);  

        } else if (v[i].size()==0) {

            if (!pq.empty()) {

                if (pq.top()<=i) pq.pop(); else {  

                    pos=max(pos,i);  

                    while (!v[pos].size()&&pos<=m) pos++;  

                    if (v[pos].size()) v[pos].pop_back();  

                }    

            } else {

                pos=max(pos,i);

                while (!v[pos].size()&&pos<=m) pos++;

                if (v[pos].size()) v[pos].pop_back();

            }

        }

    }

    int ans=pq.size();

    printf("%d\n",ans); 

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.317402191196792x):
#include<bits/stdc++.h>

using namespace std;



pair<int,int> p[300001];



int main(){

	ios_base::sync_with_stdio(0);

	cin.tie(0);

	int n,m;

	cin>>n>>m;

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

		cin>>p[i].first>>p[i].second;

	sort(p,p+n);

	priority_queue<int,vector<int>,greater<int> > R,F;

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

		while(i<n&&p[i].first<M)	R.push(p[i++].second);

		while(i<n&&p[i].first==M)	F.push(p[i++].second);

		while(F.size()>M)

			R.push(F.top()),F.pop();

	}

	for(int M=F.size()+1;M<=m;M++)

		if(!R.empty()&&R.top()<=M)	R.pop();

	cout<<R.size()<<endl;

}
// Slower C++ solution:
#include<bits/stdc++.h>

#define mem0(a) memset(a,0,sizeof(a))  

#define meminf(a) memset(a,0x3f,sizeof(a))  

using namespace std;  

typedef long long ll;  

typedef long double ld;  

typedef double db;  

const int maxn=200005,inf=0x3f3f3f3f;    

const ll llinf=0x3f3f3f3f3f3f3f3f;     

const ld pi=acos(-1.0L);  

vector<int> v[maxn]; 

int main() {  

    int n,m,i,j,l,r;  

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

    priority_queue<int,vector<int>,greater<int> > pq;  

    for (i=1;i<=n;i++) {  

        scanf("%d%d",&l,&r);  

        if (l==0) pq.push(r); else v[l].push_back(r);  

    }  

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

        sort(v[i].begin(),v[i].end());  

    }  

    int pos=-1;  

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

        if (v[i].size()>1) {

            for (j=0;j<v[i].size()-1;j++) pq.push(v[i][j]);  

        } else if (v[i].size()==0) {

            if (!pq.empty()) {

                if (pq.top()<=i) pq.pop(); else {  

                    pos=max(pos,i);  

                    while (!v[pos].size()&&pos<=m) pos++;  

                    if (v[pos].size()) v[pos].pop_back();  

                }    

            } else {

                pos=max(pos,i);

                while (!v[pos].size()&&pos<=m) pos++;

                if (v[pos].size()) v[pos].pop_back();

            }

        }

    }

    int ans=pq.size();

    printf("%d\n",ans); 

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.466425140249663x):
#define _CRT_SECURE_NO_WARNINGS

#include<bits/stdc++.h>

#include<unordered_map>

typedef long long LL;

using ld = long double;

using namespace std;

#define MAXN 500005

const double eps = (1e-11);

const int logn = 21;

const double pi = acos(-1.0);

int pp = 1000000007;

#define P pair<int,int>

#define se second

#define fi first

#define MP(i,j) make_pair(i,j)

//#define int LL

const int INF = 1e9;



//假题，贪心模拟^

//正解霍尔定理？下次下次

struct peo {

	int l; int r;

};



peo p[MAXN];



//这里肯定是要从小到大，这样就可以尽量填小的了

bool cmp1(peo a, peo b) {

	if (a.l == b.l) return a.r < b.r;

	return a.l < b.l;

}



bool operator <(peo a, peo b) {

	return a.r > b.r;

}



priority_queue<peo> q;

priority_queue<int> q2;



signed main() {

	int n, m;

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

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

		scanf("%d%d", &p[i].l, &p[i].r);

	}

	sort(p + 1, p + n + 1, cmp1);

	int left = 0;

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

		q.push(p[i]);

		if (q.size() > p[i].l) {

			q2.push(q.top().r);

			q.pop();

		}

	}

	int ans = q.size();

	int r = m + 1;

	int ans2 = 0;

	while (!q2.empty()) {

		int tmp = q2.top(); q2.pop();

		r = min(tmp, r);

		r = max(tmp, ans + 1);

		if (ans2 < m - r + 1) {

			ans2++;

		}

	}

	ans += ans2; ans = n - ans;

	printf("%d", ans);

	return 0;

}
// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

long long gcd(long long a, long long b);

int main(){

    long long a,b;

    cin>>a>>b;

    long long n=gcd(a,b);

    //cout<<n<<endl;

    vector<int> prime(1000001,0);

    int ans=1;

    for(long long i=2;i*i<=n;i++){

        //cout<<i<<" "<<n<<endl;

        if(n%i==0){

            while(n%i==0){

                n/=i;

            }

            ans++;

        }

    }

    if(n!=1)ans++;

    cout<<ans<<endl;

    return 0;

}



long long gcd(long long a,long long b){

    if(b==0)return a;

    else return gcd(b,a%b);

}

// Faster C++ solution for the same problem (measured speedup: 5.116235673985205x):
#include<iostream>

using namespace std;

long long gcd(long long a, long long b);

int main(){

    long long a,b;

    cin>>a>>b;

    long long n = gcd(a,b);

    int ans=1;

    for(long long i=2;i*i<=n;i++){

        if(n%i==0){

            while(n%i==0){

                 n/=i;

            }

            ans++;

        }

    }

    if(n!=1)ans++;

    cout<<ans<<endl;

    return 0;

}

long long gcd(long long a, long long b){

    if(b==0)return a;

    else return gcd(b,a%b);

}
// Slower C++ solution:
#pragma warning(disable:4996)

#include<iostream>

#include<cstdio>

#include<cmath>

#include<string>

using namespace std;



const int maxn1 = 60;

int fac[maxn1 + 10], cnt[maxn1 + 10];

long long getFac(long long n)

{

	long long num = 0, sum = 0, m = sqrt(n + 0.5);

	for (long long k = 2; k <= m; k++)

	{

		sum = 0;

		while (n % k == 0)

		{

			n /= k;

			sum++;

		}

		if (sum != 0)

		{

			fac[num] = k;

			cnt[num++] = sum;

		}

		m = sqrt(n + 0.5);

	}

	if (n != 1)

	{

		fac[num] = n;

		cnt[num++] = 1;

	}

	return num;

}



long long gcd(long long a, long long b)

{

	return b ? gcd(b, a % b) : a;

}





int main()

{

	long long x, y;

	scanf("%lld%lld", &x, &y);

	printf("%lld\n", getFac(gcd(x, y)) + 1);

	//system("pause");

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 5.225088242118518x):
#include<cstring>

#include<algorithm>

#include<cstdio>

#define N 100005

using namespace std;

long long int a[30],b[30];

long long int x,y;

int la=0,lb=0;

int main(){

scanf("%lld%lld",&x,&y);

a[++la]=1;

b[++lb]=1;

for(long long int i=2;i*i<=x;i++){

if(x%i==0){a[++la]=i;}

while(x%i==0){x/=i;}

}

if(x>1)a[++la]=x;

for(long long int i=2;i*i<=y;i++){

if(y%i==0){b[++lb]=i;}

while(y%i==0){y/=i;}

}

if(y>1)b[++lb]=y;

int z=1;

int ans=0;

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

while(b[z]<a[i]&&z<lb)z++;

if(b[z]==a[i])ans++;

}

printf("%d",ans);



}