#include <bits/stdc++.h>
using namespace std;
const int N = 500, INF = 1 << 30;
int n, m;
struct Rectangle {
  int x1, y1, x2, y2;
  void read() { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); }
} rect[N];
int xx[N], yy[N];
int cntx, cnty;
int cap[N][N];
bool vis[N];
int SRC, TRGT;
int ans = 0, min_flow = INF;
int dfs(int x, int flow) {
  vis[x] = true;
  if (x == TRGT) return flow;
  for (int y = SRC; y <= TRGT; ++y) {
    if (vis[y]) continue;
    if (cap[x][y] < min_flow) continue;
    int cur_flow = dfs(y, min(flow, cap[x][y]));
    if (cur_flow > 0) {
      cap[x][y] -= cur_flow;
      cap[y][x] += cur_flow;
      return cur_flow;
    }
  }
  return 0;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    rect[i].read();
    xx[i * 2 - 1] = rect[i].x1;
    xx[i * 2] = rect[i].x2 + 1;
    yy[i * 2 - 1] = rect[i].y1;
    yy[i * 2] = rect[i].y2 + 1;
  }
  sort(xx + 1, xx + 2 * m + 1);
  sort(yy + 1, yy + 2 * m + 1);
  cntx = unique(xx + 1, xx + 2 * m + 1) - xx - 1;
  cnty = unique(yy + 1, yy + 2 * m + 1) - yy - 1;
  SRC = 0;
  TRGT = cntx + cnty + 1;
  for (int i = 1; i <= m; ++i) {
    int q = lower_bound(xx + 1, xx + cntx + 1, rect[i].x2 + 1) - xx;
    for (int x = lower_bound(xx + 1, xx + cntx + 1, rect[i].x1) - xx; x < q;
         ++x) {
      int p = lower_bound(yy + 1, yy + cnty + 1, rect[i].y2 + 1) - yy;
      for (int y = lower_bound(yy + 1, yy + cnty + 1, rect[i].y1) - yy; y < p;
           ++y) {
        cap[x][cntx + y] = INF;
      }
    }
  }
  for (int i = 1; i < cntx; ++i) {
    cap[SRC][i] = xx[i + 1] - xx[i];
  }
  for (int i = 1; i < cnty; ++i) {
    cap[cntx + i][TRGT] = yy[i + 1] - yy[i];
  }
  while (min_flow) {
    memset(vis, false, sizeof(vis));
    int cur_flow = dfs(SRC, INF);
    if (cur_flow > 0)
      ans += cur_flow;
    else
      min_flow >>= 1;
  }
  printf("%d", ans);
  return 0;
}
