#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int s = 0, t = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') t = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
  return s * t;
}
const int N = 50005;
const int M = N * 20;
const int inf = 0x3f3f3f3f;
int n, m, Num, cnt = 1, tot, rt, S, T;
int h[M], H[M], d[M], s[M], ls[M], rs[M];
struct edge {
  int to, next, v;
} e[M * 2];
struct Node {
  int y, l, r, t;
} q[N * 2];
bool cmp(Node A, Node B) { return A.y < B.y; }
void Add(int x, int y, int v) {
  if (!x || !y) return;
  e[++cnt] = (edge){y, h[x], v};
  h[x] = cnt;
  e[++cnt] = (edge){x, h[y], 0};
  h[y] = cnt;
}
bool BFS(int S, int T) {
  queue<int> q;
  for (int i = 1; i <= tot; i++) d[i] = -1;
  q.push(S), d[S] = 0;
  while (q.size()) {
    int x = q.front();
    q.pop();
    if (x == T) return true;
    for (int i = h[x]; i; i = e[i].next) {
      int y = e[i].to;
      if (e[i].v && d[y] == -1) {
        d[y] = d[x] + 1, q.push(y);
      }
    }
  }
  return false;
}
int DFS(int x, int maxn) {
  if (x == T || !maxn) return maxn;
  int res = 0;
  for (int &i = H[x]; i; i = e[i].next) {
    int y = e[i].to;
    if (d[y] == d[x] + 1 && e[i].v) {
      int dlt = DFS(y, min(maxn, e[i].v));
      e[i].v -= dlt, e[i ^ 1].v += dlt;
      res += dlt, maxn -= dlt;
      if (!dlt) d[y] = -1;
      if (!maxn) return res;
    }
  }
  return res;
}
int Dinic(int S, int T) {
  int res = 0;
  while (BFS(S, T)) {
    for (int i = 1; i <= tot; i++) H[i] = h[i];
    res += DFS(S, inf);
  }
  return res;
}
void Add(int x) {
  if (!s[ls[x]]) Add(x, ls[x], inf);
  if (!s[rs[x]]) Add(x, rs[x], inf);
}
void Build(int &x, int l, int r) {
  if (l == r) {
    Add(x = l + n, T, 1);
    return;
  }
  x = ++tot;
  int mid = (l + r) >> 1;
  Build(ls[x], l, mid), Build(rs[x], mid + 1, r), Add(x);
}
void Ins(int &y, int x, int l, int r, int ql, int qr, int t) {
  if (l == r) {
    s[x] += t;
    return;
  }
  y = ++tot, ls[y] = ls[x], rs[y] = rs[x], s[y] = s[x];
  if (ql <= l && r <= qr) {
    s[y] += t, Add(y);
    return;
  }
  int mid = (l + r) >> 1;
  if (ql <= mid) Ins(ls[y], ls[x], l, mid, ql, qr, t);
  if (qr > mid) Ins(rs[y], rs[x], mid + 1, r, ql, qr, t);
  Add(y);
}
int main() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    int x1 = read(), y1 = read();
    int x2 = read(), y2 = read();
    q[++Num] = (Node){y1, x1, x2, +1};
    q[++Num] = (Node){y2 + 1, x1, x2, -1};
  }
  sort(q + 1, q + Num + 1, cmp);
  tot = 2 * n, S = ++tot, T = ++tot, Build(rt, 1, n);
  for (int i = 1, j = 1; i <= n; i++) {
    for (; j <= Num && q[j].y == i; j++)
      Ins(rt, rt, 1, n, q[j].l, q[j].r, q[j].t);
    Add(S, i, 1);
    if (!s[rt]) Add(i, rt, 1);
  }
  printf("%d", Dinic(S, T));
  return 0;
}
