#include <bits/stdc++.h>
using namespace std;
/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
/*find_by_order()and order_of_key(). */
#define ll int
//#define test
#define mp make_pair
#define f first
#define s second
#define all(a) a.begin(),a.end()
#define pb push_back
#define vi vector<int>
#define pi pair<int,int>
#define pll pair<ll,ll>
#define vll vector<ll>
const ll maxn = 1e6+7;
const ll mod = 1e9+7;
const ll MOD = 1e9+7;
#define inf LLONG_MAX
#define debug(a) for(ll i=0;i<a.size();i++) cout<<a[i]<<" "; cout<<endl;
//functions
template <typename T1,typename T2>
T1 pow_(const T1 &a,const T2 &b)
{
if(!b) return 1;
T1 p = pow_(a,b/2);
p*=p;
return (b%2)?(p*a):p;
}
template <typename T1,typename T2>
T1 prod(const T1 &a,const T1 &b,const T2 &mod)
{
return ((a%mod)*(b%mod))%mod;
}
template <typename T1,typename T2,typename T3>
T1 modpow(const T1 &a,const T2 &b,const T3 &mod)
{
if(!b) return 1;
T1 p = modpow(a,b/2,mod);
p = prod(p,p,mod);
return (b%2)?(prod(p,a,mod)):p;
}
template <typename T1,typename T2>
T1 inv(T1 &x,T2 &MOD) {return modpow(x,MOD-2,MOD);}
struct Job
{
int start, finish, profit;
};
// A utility function that is used for sorting events
// according to finish time
bool myfunction(Job s1, Job s2)
{
return (s1.finish < s2.finish);
}
// A Binary Search based function to find the latest job
// (before current job) that doesn't conflict with current
// job. "index" is index of the current job. This function
// returns -1 if all jobs before index conflict with it.
// The array jobs[] is sorted in increasing order of finish
// time.
int binarySearch(Job jobs[], int index)
{
// Initialize 'lo' and 'hi' for Binary Search
int lo = 0, hi = index - 1;
// Perform binary Search iteratively
while (lo <= hi)
{
int mid = (lo + hi) / 2;
if (jobs[mid].finish <= jobs[index].start)
{
if (jobs[mid + 1].finish <= jobs[index].start)
lo = mid + 1;
else
return mid;
}
else
hi = mid - 1;
}
return -1;
}
// The main function that returns the maximum possible
// profit from given array of jobs
int findMaxProfit(Job arr[], int n)
{
// Sort jobs according to finish time
sort(arr, arr+n, myfunction);
// Create an array to store solutions of subproblems. table[i]
// stores the profit for jobs till arr[i] (including arr[i])
int *table = new int[n];
table[0] = arr[0].profit;
// Fill entries in table[] using recursive property
for (int i=1; i<n; i++)
{
// Find profit including the current job
int inclProf = arr[i].profit;
int l = binarySearch(arr, i);
if (l != -1)
inclProf += table[l];
// Store maximum of including and excluding
table[i] = max(inclProf, table[i-1]);
}
// Store result and free dynamic memory allocated for table[]
int result = table[n-1];
delete[] table;
return result;
}
void main_()
{
ll n,m;
cin>>n>>m;
Job arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i].start>>arr[i].finish;
if(arr[i].start==arr[i].finish)
{
arr[i].start--;
arr[i].finish++;
arr[i].profit=1;
}
else arr[i].profit = arr[i].finish - arr[i].start;
//if(arr[i].profit==0) arr[i].profit=1;
}
ll ans = m-findMaxProfit(arr,n);
if(ans>0) cout<<ans<<endl;
else cout<<0<<endl;
}
int main()
{
#ifdef test
ll t;
cin>>t;
while(t--)
#endif
{
main_();
}
return 0;
}