#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005, MAXM = 100005 << 1, INF = 2147483647;
int g[MAXN];
struct edges {
  int to, next, cap, flow;
} e[MAXM];
int tot = 1, head, tail, q[MAXN], dis[MAXN], vist[MAXN], s, t, maxp, temp[MAXN];
int min1(int a1, int b1) { return a1 < b1 ? a1 : b1; }
void adds(int a1, int b1, int c1) {
  tot++;
  e[tot].to = b1;
  e[tot].cap = c1;
  e[tot].next = g[a1];
  e[tot].flow = 0;
  g[a1] = tot;
  return;
}
void add_edge(int a1, int b1, int c1) {
  adds(a1, b1, c1);
  adds(b1, a1, 0);
  return;
}
bool bfs() {
  for (int i = 0; i <= maxp; i++) {
    vist[i] = false;
  }
  head = 0;
  tail = 1;
  q[tail] = s;
  vist[s] = true;
  while (head != tail) {
    head++;
    int x = q[head];
    for (int i = g[x]; i; i = e[i].next) {
      if (e[i].cap > e[i].flow && !vist[e[i].to]) {
        tail++;
        q[tail] = e[i].to;
        vist[e[i].to] = true;
        dis[e[i].to] = dis[x] + 1;
      }
    }
  }
  return vist[t];
}
int dfs(int now, int mins) {
  if (now == t || mins == 0) return mins;
  int now_flow = 0, next_flow;
  for (; temp[now]; temp[now] = e[temp[now]].next) {
    if (dis[e[temp[now]].to] == dis[now] + 1) {
      next_flow = dfs(e[temp[now]].to,
                      min1(mins, e[temp[now]].cap - e[temp[now]].flow));
      if (next_flow > 0) {
        e[temp[now]].flow += next_flow;
        e[temp[now] ^ 1].flow -= next_flow;
        now_flow += next_flow;
        mins -= next_flow;
        if (mins == 0) break;
      }
    }
  }
  return now_flow;
}
int dinic() {
  int ans = 0;
  while (bfs()) {
    for (int i = 0; i <= maxp; ++i) {
      temp[i] = g[i];
    }
    ans += dfs(s, INF);
  }
  return ans;
}
void init() {
  memset(g, 0, sizeof(g));
  tot = 1;
  return;
}
int n, m, x_1[55], y_1[55], x_2[55], y_2[55];
vector<int> x, y, X, Y;
vector<pair<int, int>> range_x, range_y;
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %d %d", &x_1[i], &y_1[i], &x_2[i], &y_2[i]);
    X.push_back(x_1[i]);
    X.push_back(x_2[i]);
    Y.push_back(y_1[i]);
    Y.push_back(y_2[i]);
  }
  sort(X.begin(), X.end());
  sort(Y.begin(), Y.end());
  for (int i = 0; i < X.size(); ++i) {
    if (i == 0 || X[i] != X[i - 1]) x.push_back(X[i]);
  }
  for (int i = 0; i < Y.size(); ++i) {
    if (i == 0 || Y[i] != Y[i - 1]) y.push_back(Y[i]);
  }
  for (int i = 0; i < x.size(); ++i) {
    if (i && x[i] - 1 != x[i - 1])
      range_x.push_back(make_pair(x[i - 1] + 1, x[i] - 1));
    range_x.push_back(make_pair(x[i], x[i]));
  }
  for (int i = 0; i < y.size(); ++i) {
    if (i && y[i] - 1 != y[i - 1])
      range_y.push_back(make_pair(y[i - 1] + 1, y[i] - 1));
    range_y.push_back(make_pair(y[i], y[i]));
  }
  s = range_x.size() + range_y.size() + m + 1;
  t = range_x.size() + range_y.size() + m + 2;
  maxp = t;
  init();
  for (int i = 0; i < range_x.size(); ++i) {
    add_edge(s, i + 1, range_x[i].second - range_x[i].first + 1);
    for (int j = 1; j <= m; ++j) {
      if (x_1[j] <= range_x[i].first && range_x[i].second <= x_2[j]) {
        add_edge(i + 1, range_x.size() + range_y.size() + j, INF);
      }
    }
  }
  for (int i = 0; i < range_y.size(); ++i) {
    add_edge(range_x.size() + i + 1, t,
             range_y[i].second - range_y[i].first + 1);
    for (int j = 1; j <= m; ++j) {
      if (y_1[j] <= range_y[i].first && range_y[i].second <= y_2[j]) {
        add_edge(range_x.size() + range_y.size() + j, range_x.size() + i + 1,
                 INF);
      }
    }
  }
  printf("%d\n", dinic());
  return 0;
}
