#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 2;
int n, m;
vector<int> b[N];
class TTree {
  int mx[1 << 19], laz[1 << 19];
  void Propagate(int id, int sl, int sr) {
    if (laz[id] != 0) {
      mx[id] += laz[id];
      if (sl < sr) laz[(id * 2 + 1)] += laz[id], laz[(id * 2 + 2)] += laz[id];
      laz[id] = 0;
    }
  }

 public:
  void Init(int id, int sl, int sr) {
    if (sl < sr) {
      Init((id * 2 + 1), sl, (sl + sr) / 2),
          Init((id * 2 + 2), (sl + sr) / 2 + 1, sr);
      mx[id] = max(mx[(id * 2 + 1)], mx[(id * 2 + 2)]);
    } else
      mx[id] = -(m - sl + 1);
  }
  void Update(int id, int sl, int sr, int ul, int ur, int v) {
    Propagate(id, sl, sr);
    if (ur < sl || sr < ul) return;
    if (ul <= sl && sr <= ur) {
      mx[id] += v;
      if (sl < sr) laz[(id * 2 + 1)] += v, laz[(id * 2 + 2)] += v;
      return;
    }
    Update((id * 2 + 1), sl, (sl + sr) / 2, ul, ur, v);
    Update((id * 2 + 2), (sl + sr) / 2 + 1, sr, ul, ur, v);
    mx[id] = max(mx[(id * 2 + 1)], mx[(id * 2 + 2)]);
  }
  int Query(int id, int sl, int sr, int ql, int qr) {
    Propagate(id, sl, sr);
    if (qr < sl || sr < ql) return -N;
    if (ql <= sl && sr <= qr) return mx[id];
    return max(Query((id * 2 + 1), sl, (sl + sr) / 2, ql, qr),
               Query((id * 2 + 2), (sl + sr) / 2 + 1, sr, ql, qr));
  }
} tree;
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    int l, r;
    scanf("%d %d", &l, &r);
    b[l].push_back(r);
  }
  tree.Init(0, 1, m);
  int indep = max(n, m);
  for (int l = 0; l <= m; ++l) {
    for (int v : b[l]) tree.Update(0, 1, m, 1, v, 1);
    indep = max(indep, m + tree.Query(0, 1, m, l + 1, m) - l);
  }
  int match = n + m - indep;
  printf("%d", n - match);
  return 0;
}
