#include <bits/stdc++.h>
using namespace std;
const long long M = 550, INF = 0x7fffffff;
struct noder {
  long long x, y;
};
struct edger {
  long long to, nxt, w;
} edge[M * M];
long long n, m, rangex, rangey, cntx, cnty, tmpx[M], tmpy[M];
long long s, t, cntedge = 1, head[M], tmphead[M];
pair<noder, noder> sqr[M];
void add(long long u, long long v, long long w) {
  edge[++cntedge].to = v;
  edge[cntedge].nxt = head[u];
  edge[cntedge].w = w;
  head[u] = cntedge;
}
void discreate() {
  for (long long i = 1; i <= m; i++) {
    tmpx[++cntx] = sqr[i].first.x, tmpy[++cnty] = sqr[i].first.y;
    tmpx[++cntx] = sqr[i].second.x, tmpy[++cnty] = sqr[i].second.y;
  }
  sort(tmpx + 1, tmpx + 1 + cntx);
  sort(tmpy + 1, tmpy + 1 + cnty);
  rangex = unique(tmpx + 1, tmpx + 1 + cntx) - tmpx - 1;
  rangey = unique(tmpy + 1, tmpy + 1 + cnty) - tmpy - 1;
  for (long long i = 1; i <= m; i++) {
    sqr[i].first.x =
        lower_bound(tmpx + 1, tmpx + 1 + rangex, sqr[i].first.x) - tmpx;
    sqr[i].first.y =
        lower_bound(tmpy + 1, tmpy + 1 + rangey, sqr[i].first.y) - tmpy;
    sqr[i].second.x =
        lower_bound(tmpx + 1, tmpx + 1 + rangex, sqr[i].second.x) - tmpx;
    sqr[i].second.y =
        lower_bound(tmpy + 1, tmpy + 1 + rangey, sqr[i].second.y) - tmpy;
  }
}
void build() {
  s = 0, t = rangex + rangey + 1;
  for (long long i = 1; i < rangex; i++)
    add(s, i, tmpx[i + 1] - tmpx[i]), add(i, s, 0);
  for (long long i = 1; i < rangey; i++)
    add(i + rangex, t, tmpy[i + 1] - tmpy[i]), add(t, i + rangex, 0);
  for (long long i = 1; i <= m; i++)
    for (long long x = sqr[i].first.x; x < sqr[i].second.x; x++)
      for (long long y = sqr[i].first.y; y < sqr[i].second.y; y++)
        add(x, y + rangex, INF), add(y + rangex, x, 0);
}
namespace dinic {
long long depth[M];
bool bfs() {
  memset(depth, 0, sizeof(depth));
  queue<long long> q;
  q.push(s);
  depth[s] = 1;
  while (!q.empty()) {
    long long u = q.front();
    q.pop();
    for (long long i = head[u]; i; i = edge[i].nxt) {
      long long v = edge[i].to, w = edge[i].w;
      if (w && !depth[v]) depth[v] = depth[u] + 1, q.push(v);
    }
  }
  return depth[t];
}
long long dfs(long long u, long long flow) {
  if (u == t || !flow) return flow;
  long long res = 0;
  for (long long &i = tmphead[u]; i; i = edge[i].nxt) {
    long long v = edge[i].to, &w = edge[i].w, &fw = edge[i ^ 1].w;
    if (!w || depth[v] != depth[u] + 1) continue;
    long long inc = dfs(v, min(w, flow));
    w -= inc, fw += inc;
    res += inc, flow -= inc;
    if (!flow) break;
  }
  if (!res) depth[u] = -1;
  return res;
}
void solve() {
  long long ans = 0, inc = 0;
  while (bfs()) {
    memcpy(tmphead, head, sizeof(head));
    while (inc = dfs(s, INF)) ans += inc;
  }
  printf("%lld\n", ans);
}
}  // namespace dinic
signed main() {
  scanf("%lld%lld", &n, &m);
  for (long long i = 1; i <= m; i++) {
    scanf("%lld%lld", &sqr[i].first.x, &sqr[i].first.y);
    scanf("%lld%lld", &sqr[i].second.x, &sqr[i].second.y);
    sqr[i].second.x++, sqr[i].second.y++;
  }
  discreate();
  build();
  dinic::solve();
  return 0;
}
