#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <utility>
#include <cstdlib>
#include <memory>
#include <queue>
#include <cassert>
#include <cmath>
#include <ctime>
#include <complex>
#include <bitset>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <numeric>

using namespace std;

#define ws ws_____________________
#define y1 y1_____________________
#define y0 y0_____________________
#define left left_________________
#define right right_______________
#define next next_________________
#define prev prev_________________
#define hash hash_________________

#define pb push_back
#define fst first
#define snd second
#define mp make_pair 
#define sz(C) ((int) (C).size())
#define forn(i, n) for (int i = 0; i < int(n); ++i)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; --i)
#define all(C) begin(C), end(C)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef long double ld;
typedef complex<double> cd;

#ifdef LOCAL
#define eprintf(args...) fprintf(stderr, args), fflush(stderr)
#else
#define eprint(...)
#endif

#define FILE_NAME "a"


int n, m;
vi L;
vi R;

bool read() {
	if  (scanf("%d%d", &n, &m) < 2) {
		return 0;
	}
	L.resize(n);
	R.resize(n);
	forn(i, n) {
		scanf("%d%d", &L[i], &R[i]);
	}
	return 1;
}

const int INF = 1e9;

struct SegmTree {
	vi mx;
	vi add;
	int sz;

	SegmTree(int n = 0) {
		sz = 1;
		while (sz < n) sz *= 2;

		mx.assign(sz * 2, 0);
		add.assign(sz * 2, 0);
	}

	void inter(int tl, int tr, int& l, int& r) {
		l = max(l, tl);
		r = min(r, tr);
	}

	void push(int v) {
		if  (!add[v]) {
			return;
		}
		const int val = add[v];
		add[v * 2] += val;
		mx[v * 2] += val;
		add[v * 2 + 1] += val;
		mx[v * 2 + 1] += val;
		add[v] = 0;
	}

	void upd(int v) {
		assert(!add[v]);
		mx[v] = max(mx[v * 2], mx[v * 2 + 1]);
	}


	void go_add(int v, int tl, int tr, int l, int r, int val) {
		inter(tl, tr, l, r);
	
		if  (l > r) {
			return;
		}

		if  (tl == l && tr == r) {
			add[v] += val;
			mx[v] += val;
			return;
		}

		push(v);

		int tm = (tl + tr) >> 1;
		go_add(v * 2, tl, tm, l, r, val);
		go_add(v * 2 + 1, tm + 1, tr, l, r, val);
	
		upd(v);
	}

	void go_add(int l, int r, int val) {
		go_add(1, 0, sz - 1, l, r, val);
	}

	int get_max(int v, int tl, int tr, int l, int r) {
		inter(tl, tr, l, r);

		if  (l > r) {
			return -INF;
		}

		if  (tl == l && tr == r) {
			return mx[v];
		}

		push(v);

		int tm = (tl + tr) >> 1;

		int res = max(get_max(v * 2, tl, tm, l, r), get_max(v * 2 + 1, tm + 1, tr, l, r));

		upd(v);

		return res;
	}

	int get_max(int l, int r) {
		return get_max(1, 0, sz - 1, l, r);
	}
};

int solve() {
	SegmTree T(m + 2);
	for (int r = 1; r <= m; ++r) {
		T.go_add(r, r, -(m - r + 1));
	} 

	vvi with_L(m + 1);
	forn(i, n) {
		with_L[L[i]].pb(i);
	}

	int ans = max(0, n - m);
	for (int l = 0; l <= m; ++l) {
		for (int i : with_L[l]) {
			T.go_add(1, R[i], +1);
		}

		// forn(j, m + 1) {
		// 	eprintf("%d ", T.get_max(j, j));
		// }
		// eprintf("\n");

		int cur = T.get_max(l + 1, m + 1);

		// eprintf("l=%d, cur=%d\n", l, cur);

		cur += -l;

		ans = max(ans, cur);
	}

	return ans;
}

int main() {
#ifdef LOCAL
	freopen(FILE_NAME ".in", "r", stdin);
	// freopen(FILE_NAME ".out", "w", stdout);
#endif

	while (read()) {
		printf("%d\n", solve());
	}

#ifdef LOCAL
	cerr.precision(5);
	cerr << "Time: " << fixed << (double) clock() / CLOCKS_PER_SEC << endl;
#endif
	return 0;
}


Measured memory_bytes: 14208