#include <bits/stdc++.h>
using namespace std;
const int maxn = 300;
int s, t, head[maxn], cnt = 1, d[maxn], n, m;
struct node {
  int nxt, to, cost;
} way[maxn * maxn * 2 * 6];
int nxt() {
  int ret;
  scanf("%d", &ret);
  return ret;
}
struct rec {
  int c1, r1, c2, r2;
} A;
vector<rec> rec_list;
struct discrete {
  vector<int> data;
  int tot;
  void insert(int x) { tot++, data.emplace_back(x); }
  void pre_work() {
    sort(data.begin(), data.end());
    tot = unique(data.begin(), data.end()) - data.begin();
  }
  int get_val(int x) {
    return lower_bound(data.begin(), data.begin() + tot, x) - data.begin() + 1;
  }
} row, col;
void addedge(int from, int to, int cost) {
  way[++cnt].cost = cost;
  way[cnt].to = to;
  way[cnt].nxt = head[from];
  head[from] = cnt;
}
bool bfs() {
  queue<int> q;
  q.push(s);
  memset(d, 0, sizeof(d));
  d[s] = 1;
  while (!q.empty()) {
    int cur = q.front();
    q.pop();
    for (int i = head[cur]; i; i = way[i].nxt) {
      int to = way[i].to, cost = way[i].cost;
      if (cost && !d[to]) {
        d[to] = d[cur] + 1;
        if (t == to) return 1;
        q.push(to);
      }
    }
  }
  return 0;
}
int dfs(int cur, int flow) {
  if (cur == t) return flow;
  int rest = flow, k;
  for (int i = head[cur]; i && rest; i = way[i].nxt) {
    int to = way[i].to, cost = way[i].cost;
    if (cost && d[to] == d[cur] + 1) {
      int k = dfs(to, min(rest, cost));
      if (!k) d[to] == 0;
      way[i].cost -= k;
      way[i ^ 1].cost += k;
      rest -= k;
    }
  }
  return flow - rest;
}
void Dinic() {
  int ans = 0;
  while (bfs()) ans += dfs(s, 0x3f3f3f3f);
  cout << ans << endl;
}
signed main() {
  n = nxt(), m = nxt();
  for (int i = (1); i <= (m); ++i) {
    A.r1 = nxt(), A.c1 = nxt(), A.r2 = nxt(), A.c2 = nxt();
    A.r2++, A.c2++;
    rec_list.push_back(A);
    row.insert(A.r1), row.insert(A.r2), col.insert(A.c1), col.insert(A.c2);
  }
  row.pre_work(), col.pre_work();
  s = 0, t = row.tot + col.tot + 3;
  for (int i = (1); i < (row.tot); ++i) {
    addedge(s, i, row.data[i] - row.data[i - 1]), addedge(i, s, 0);
  }
  for (int i = (1); i < (col.tot); ++i) {
    addedge(i + row.tot, t, col.data[i] - col.data[i - 1]),
        addedge(t, i + row.tot, 0);
  }
  for (int k = (0); k < (m); ++k) {
    for (int i = (col.get_val(rec_list[k].c1));
         i < (col.get_val(rec_list[k].c2)); ++i) {
      for (int j = (row.get_val(rec_list[k].r1));
           j < (row.get_val(rec_list[k].r2)); ++j) {
        addedge(j, i + row.tot, 0x3f3f3f3f), addedge(i + row.tot, j, 0);
      }
    }
  }
  Dinic();
}
