#include <bits/stdc++.h>
using namespace std;
const int N = 10050;
const int D = 600050;
const int M = 4000050;
const int INF = 20000000;
int s, t, nds;
namespace Maxflow {
int dis[D], q[M], f, r, tot = 1;
int head[D], to[M], nex[M], fl[M], now[D];
void addedge(int u, int v, int f) {
  tot++;
  to[tot] = v, nex[tot] = head[u], head[u] = tot, fl[tot] = f;
  tot++;
  to[tot] = u, nex[tot] = head[v], head[v] = tot, fl[tot] = 0;
}
bool spfa() {
  int i, j;
  q[f = r = 1] = s;
  for (i = 2; i <= nds; i++) dis[i] = INF;
  while (f <= r) {
    j = q[f++];
    for (i = head[j]; i; i = nex[i]) {
      if (fl[i] && dis[to[i]] > dis[j] + 1) {
        dis[to[i]] = dis[j] + 1;
        q[++r] = to[i];
      }
    }
  }
  return dis[t] != INF;
}
int dinic(int x, int flow) {
  if (x == t) return flow;
  for (int i = now[x]; i; now[x] = i = nex[i]) {
    if (fl[i] && dis[x] + 1 == dis[to[i]]) {
      int tmp = dinic(to[i], min(fl[i], flow));
      if (tmp != 0) {
        fl[i] -= tmp;
        fl[i ^ 1] += tmp;
        return tmp;
      }
    }
  }
  return 0;
}
int maxflow() {
  int i, j, ans = 0;
  while (spfa()) {
    for (i = 1; i <= nds; i++) now[i] = head[i];
    int tmp = 0;
    while (tmp = dinic(s, INF)) ans += tmp;
  }
  return ans;
}
}  // namespace Maxflow
using Maxflow ::addedge;
int lc[M], rc[M], root[2 * N], typ;
void build(int &p, int l, int r) {
  p = ++nds;
  if (l == r) {
    addedge(p, 2 + l, INF);
    return;
  }
  int md = l + r >> 1;
  build(lc[p], l, md);
  build(rc[p], md + 1, r);
  addedge(p, lc[p], INF);
  addedge(p, rc[p], INF);
}
void add(int &p, int las, int one, int l, int r, int x, int y) {
  p = ++nds;
  if (l == x && r == y) {
    if (typ == -1) {
      if (x == y)
        addedge(p, 2 + x, INF);
      else {
        lc[p] = lc[one];
        rc[p] = rc[one];
        addedge(p, lc[p], INF);
        addedge(p, rc[p], INF);
      }
    }
    return;
  }
  lc[p] = lc[las];
  rc[p] = rc[las];
  int md = l + r >> 1;
  if (y <= md)
    add(lc[p], lc[las], lc[one], l, md, x, y);
  else if (x > md)
    add(rc[p], rc[las], rc[one], md + 1, r, x, y);
  else {
    add(lc[p], lc[las], lc[one], l, md, x, md);
    add(rc[p], rc[las], rc[one], md + 1, r, md + 1, y);
  }
  addedge(p, lc[p], INF);
  addedge(p, rc[p], INF);
}
namespace io {
const int L = (1 << 19) + 1;
char ibuf[L], *iS, *iT, c;
int f;
inline char gc() {
  if (iS == iT) {
    iT = (iS = ibuf) + fread(ibuf, 1, L, stdin);
    return iS == iT ? EOF : *iS++;
  }
  return *iS++;
}
template <class I>
void read(I &x) {
  for (f = 1, c = gc(); c < '0' || c > '9'; c = gc())
    if (c == '-') f = -1;
  for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15);
  x *= f;
}
};  // namespace io
using io ::read;
struct line {
  int dw, up, typ, x;
  line(int xx = 0, int y1 = 0, int y2 = 0, int tp = 0) {
    x = xx;
    dw = y1;
    up = y2;
    typ = tp;
  }
  inline bool operator<(const line &b) const {
    if (x == b.x) return typ < b.typ;
    return x < b.x;
  }
} a[2 * N];
int n, m;
int main() {
  int i, j, k, p, q;
  s = 1, read(n), read(m);
  t = 2, nds = 2 + n;
  build(root[0], 1, n);
  for (i = 1; i <= m; i++) {
    read(j), read(k), read(p), read(q);
    a[2 * i - 1] = line(k, j, p, 1);
    a[2 * i] = line(q + 1, j, p, -1);
  }
  sort(a + 1, a + 2 * m + 1);
  for (i = j = 1; i <= n; i++) {
    while (j <= 2 * m && a[j].x == i)
      typ = a[j].typ,
      add(root[j], root[j - 1], root[0], 1, n, a[j].dw, a[j].up), j++;
    addedge(2 + i, t, 1), addedge(s, root[j - 1], 1);
  }
  printf("%d\n", Maxflow ::maxflow());
  return 0;
}
