#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1, ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') {
      f = -1;
    }
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
namespace max_flow {
const int N = 100005;
const int M = 5000005;
struct edge {
  int u, v, f, next;
  edge() {}
  edge(int u, int v, int f, int next) : u(u), v(v), f(f), next(next) {}
};
edge G[M << 1];
int head[N], inum = 1;
inline void add(int u, int v, int f, int p) {
  G[p].u = u;
  G[p].v = v;
  G[p].f = f;
  G[p].next = head[u];
  head[u] = p;
}
inline void link(int u, int v, int f) {
  add(u, v, f, ++inum), add(v, u, 0, ++inum);
}
int S, T;
int Q[N], l, r, dis[N];
inline bool bfs() {
  for (int i = 1; i <= T; i++) dis[i] = -1;
  l = r = -1;
  Q[++r] = S;
  dis[S] = 0;
  while (l < r) {
    int u = Q[++l];
    for (int p = head[u]; p; p = G[p].next)
      if (dis[G[p].v] == -1 && G[p].f) {
        dis[G[p].v] = dis[u] + 1;
        Q[++r] = G[p].v;
        if (G[p].v == T) return 1;
      }
  }
  return 0;
}
int cur[N];
inline int dfs(int u, int flow) {
  if (u == T) return flow;
  int used = 0;
  for (int p = cur[u]; p; p = G[p].next) {
    cur[u] = p;
    if (G[p].f && dis[G[p].v] == dis[u] + 1) {
      int d = dfs(G[p].v, min(G[p].f, flow - used));
      G[p].f -= d;
      G[p ^ 1].f += d;
      used += d;
      if (used == flow) break;
    }
  }
  if (!used) dis[u] = -1;
  return used;
}
inline int Dinic() {
  int ans = 0;
  while (bfs()) {
    memcpy(cur, head, sizeof(int) * (T + 5));
    ans += dfs(S, 1 << 30);
  }
  return ans;
}
}  // namespace max_flow
using namespace max_flow;
int ncnt;
int lrt, rrt, ls[N << 3], rs[N << 3], pos[2][N];
inline void Build(int &x, int l, int r, int lf) {
  x = ++ncnt;
  if (l == r) return void(pos[lf][l] = x);
  int mid = (l + r) >> 1;
  Build(ls[x], l, mid, lf);
  Build(rs[x], mid + 1, r, lf);
  if (lf)
    link(ls[x], x, 1 << 30), link(rs[x], x, 1 << 30);
  else
    link(x, ls[x], 1 << 30), link(x, rs[x], 1 << 30);
}
int lft[N], rgt[N];
inline void Query(int x, int l, int r, int ql, int qr, int *lst) {
  if (ql <= l && r <= qr) {
    lst[++*lst] = x;
    return;
  }
  int mid = (l + r) >> 1;
  if (ql <= mid) Query(ls[x], l, mid, ql, qr, lst);
  if (qr > mid) Query(rs[x], mid + 1, r, ql, qr, lst);
}
int n, m;
int rcnt;
inline void addr(int x1, int x2, int y1, int y2) {
  if (x1 > x2 || y1 > y2) return;
  rcnt++;
  *lft = 0, *rgt = 0;
  Query(lrt, 1, n, x1, x2, lft);
  Query(rrt, 1, n, y1, y2, rgt);
  for (int i = 1; i <= *lft; i++)
    for (int j = 1; j <= *rgt; j++) link(lft[i], rgt[j], 1 << 30);
}
struct event {
  int f, x, y1, y2;
  event(int f = 0, int x = 0, int y1 = 0, int y2 = 0)
      : f(f), x(x), y1(y1), y2(y2) {}
  bool operator<(const event &B) const { return x == B.x ? f < B.f : x < B.x; }
} eve[N << 1];
int tot;
set<pair<pair<int, int>, int> > Set;
int main() {
  n = read();
  Build(lrt, 1, n, 1);
  Build(rrt, 1, n, 0);
  S = ncnt + 1, T = ncnt + 2;
  for (int i = 1; i <= n; i++) link(S, pos[1][i], 1), link(pos[0][i], T, 1);
  m = read();
  for (int i = 1; i <= m; i++) {
    int x1 = read(), y1 = read(), x2 = read(), y2 = read();
    eve[++tot] = event(1, y1, x1, x2);
    eve[++tot] = event(0, y2 + 1, x1, x2);
  }
  sort(eve + 1, eve + tot + 1);
  Set.insert(make_pair(pair<int, int>(1, n), 1));
  for (int i = 1; i <= tot; i++) {
    if (i == 7267) i = 7267;
    if (eve[i].f == 1) {
      set<pair<pair<int, int>, int> >::iterator it =
          Set.upper_bound(make_pair(pair<int, int>(eve[i].y1, 1 << 30), 0));
      it--;
      pair<int, int> t = it->first;
      addr(it->second, eve[i].x - 1, t.first, t.second);
      Set.erase(it);
      if (t.first <= eve[i].y1 - 1)
        Set.insert(make_pair(pair<int, int>(t.first, eve[i].y1 - 1), eve[i].x));
      if (eve[i].y2 + 1 <= t.second)
        Set.insert(
            make_pair(pair<int, int>(eve[i].y2 + 1, t.second), eve[i].x));
    } else if (eve[i].f == 0) {
      set<pair<pair<int, int>, int> >::iterator
          r = Set.upper_bound(make_pair(pair<int, int>(eve[i].y1, 1 << 30), 0)),
          l;
      l = r;
      if (r != Set.begin()) l--;
      int lp = eve[i].y1, rp = eve[i].y2;
      if (r != Set.begin() && l->first.second == lp - 1) {
        lp = l->first.first;
        addr(l->second, eve[i].x - 1, l->first.first, l->first.second);
        Set.erase(l);
      }
      if (r != Set.end() && rp + 1 == r->first.first) {
        rp = r->first.second;
        addr(r->second, eve[i].x - 1, r->first.first, r->first.second);
        Set.erase(r);
      }
      Set.insert(make_pair(pair<int, int>(lp, rp), eve[i].x));
    }
  }
  set<pair<pair<int, int>, int> >::iterator it;
  for (it = Set.begin(); it != Set.end(); it++) {
    pair<pair<int, int>, int> x = *it;
    addr(x.second, n, x.first.first, x.first.second);
  }
  printf("%d\n", Dinic());
  return 0;
}
