#include <stdio.h>
#include <algorithm>
#include <queue>

using namespace std;

const int NN = 210000;
struct tree {
	int l , r , now;
	tree *ll , *rr;
} poolt[NN*2] , *t;
struct node {
	int v , f;
	node *next , *rev;
} pool[NN*50] , *g[NN*3];
int top , topt;
int n , m;
int le[NN] , ri[NN];
int S , T;
int level[NN*3];
void add ( int u , int v , int f ) {
	node *tmp1 = &pool[++top] , *tmp2 = &pool[++top];
	tmp1 -> v = v; tmp1 -> f = f; tmp1 -> next = g[u]; g[u] = tmp1; tmp1 -> rev = tmp2;
	tmp2 -> v = u; tmp2 -> f = 0; tmp2 -> next = g[v]; g[v] = tmp2; tmp2 -> rev = tmp1;
}
void buildtree ( tree *id , int l , int r ) {
	id -> l = l; id -> r = r;
	if ( l == r ) return ;
	int mid = (l+r)/2;
	id -> ll = &poolt[++topt]; id -> ll -> now = topt;
	id -> rr = &poolt[++topt]; id -> rr -> now = topt;
	add ( id -> now , id -> ll -> now , 9999999 );
	add ( id -> now , id -> rr -> now , 9999999 );
	buildtree ( id -> ll , l , mid ); buildtree ( id -> rr , mid + 1 , r );
}
void change ( tree *id , int l , int r , int pos ) {
	if ( id -> l == l && id -> r == r ) {
		add ( pos , id -> now , 9999999 );
		return ;
	}
	int mid = (id->l+id->r)/2;
	if ( r <= mid ) change ( id -> ll , l , r , pos );
	else {
		if ( l > mid ) change ( id -> rr , l , r , pos );
		else {
			change ( id -> ll , l , mid , pos );
			change ( id -> rr , mid + 1 , r , pos );
		}
	}
}
void travel ( tree *id ) {
	if ( id -> ll ) travel ( id -> ll );
	if ( id -> rr ) travel ( id -> rr );
	if ( !id -> ll && !id -> rr ) {
		add ( id -> now , topt + n + 1 , 1 );
	}
}
bool makelevel () {
	int i , k;
	queue < int > q;
	for ( i = S ; i <= T ; i++ ) {
		level[i] = -1;
	}
	level[S] = 1; q.push ( S );
	while ( q.size () ) {
		k = q.front (); q.pop ();
		for ( node *j = g[k] ; j ; j = j -> next )
			if ( j -> f && level[j->v] == -1 ) {
				level[j->v] = level[k] + 1;
				q.push ( j -> v );
				if ( j -> v == T ) return true;
			}
	}
	return false;
}
int find ( int k , int key ) {
	if ( k == T ) return key;
	int i , s = 0;
	for ( node *j = g[k] ; j ; j = j -> next )
		if ( j -> f && level[j->v] == level[k] + 1 && s < key ) {
			i = find ( j -> v , min ( key - s , j -> f ) );
			j -> f -= i;
			j -> rev -> f += i;
			s += i;
		}
	if ( s == 0 ) level[k] = -1;
	return s;
}
void dinic () {
	int ret = 0;
	while ( makelevel () == true ) ret += find ( S , 9999999 );
	printf ( "%d\n" , n - ret );
}
void work () {
	int i;
	scanf ( "%d%d" , &n , &m );
	topt = 2;
	t = &poolt[++topt]; t -> now = 2;
	buildtree ( t , 1 , m );
	for ( i = 1 ; i <= n ; i++ ) {
		scanf ( "%d%d" , &le[i] , &ri[i] );
		if ( le[i] != 0 ) change ( t , 1 , le[i] , topt + i );
		if ( ri[i] != m + 1 ) change ( t , ri[i] , m , topt + i );
		add ( 1 , topt + i , 1 );
	}
	travel ( t );
	S = 1; T = topt + n + 1;
	dinic ();
}
int main () {
	work ();
	return 0;
}