#include <bits/stdc++.h>
using namespace std;
template <typename T>
bool chmax(T& a, const T& b) {
  return a < b ? (a = b, true) : false;
}
template <typename T>
bool chmin(T& a, const T& b) {
  return b < a ? (a = b, true) : false;
}
template <typename T>
struct Dinic {
  struct edge {
    int to, rev;
    T cap;
  };
  vector<vector<edge> > G;
  vector<int> level, iter;
  void init(int n) {
    G.assign(n, vector<edge>());
    level.assign(n, 0);
    iter.assign(n, 0);
  }
  void add_edge(int from, int to, T cap) {
    G[from].push_back(edge{to, int(G[to].size()), cap});
    G[to].push_back(edge{from, int(G[from].size()) - 1, 0});
  }
  void bfs(int s) {
    fill(level.begin(), level.end(), -1);
    queue<int> q;
    level[s] = 0;
    q.push(s);
    while (q.empty() == false) {
      int curr = q.front();
      q.pop();
      for (int i = 0; i < int(G[curr].size()); i++) {
        edge& e = G[curr][i];
        if (e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[curr] + 1;
          q.push(e.to);
        }
      }
    }
  }
  T dfs(int curr, int t, T f) {
    if (curr == t) return f;
    for (int& i = iter[curr]; i < int(G[curr].size()); i++) {
      edge& e = G[curr][i];
      if (e.cap > 0 && level[e.to] > level[curr]) {
        T d = dfs(e.to, t, min<T>(f, e.cap));
        if (d == 0) continue;
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
    return 0;
  }
  T max_flow(int s, int t) {
    T flow = 0, d;
    while (true) {
      bfs(s);
      if (level[t] < 0) break;
      fill(iter.begin(), iter.end(), 0);
      while ((d = dfs(s, t, numeric_limits<T>::max())) > 0) flow += d;
    }
    return flow;
  }
};
int N, M;
vector<int> L, R;
Dinic<int> din;
const int INF = 1e9;
int main() {
  scanf("%d%d", &N, &M);
  L.assign(N, 0);
  R.assign(N, 0);
  for (int i = int(0); i < int(N); i++) {
    scanf("%d%d", &L[i], &R[i]);
    L[i]--;
    R[i]--;
  }
  int s = N + M * 3, t = N + M * 3 + 1;
  din.init(N + M * 3 + 2);
  for (int i = int(0); i < int(N); i++) {
    din.add_edge(s, i, 1);
    if (L[i] >= 0 && L[i] < M) din.add_edge(i, L[i] + N, 1);
    if (R[i] >= 0 && R[i] < M) din.add_edge(i, R[i] + N + M, 1);
  }
  for (int i = int(0); i < int(M); i++) {
    if (i > 0) {
      din.add_edge(i + N, (i - 1) + N, INF);
    }
    if (i + 1 < M) {
      din.add_edge(i + N + M, (i + 1) + N + M, INF);
    }
    din.add_edge(i + N, i + N + M * 2, 1);
    din.add_edge(i + N + M, i + N + M * 2, 1);
    din.add_edge(i + N + M * 2, t, 1);
  }
  int ans = N - din.max_flow(s, t);
  printf("%d\n", ans);
  return 0;
}
