#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
namespace Dinic {
const int MAXN = 310, MAXM = 2e6 + 10, inf = 1e9 + 10;
int head[MAXN], cur[MAXN], cnt;
int depth[MAXN];
int maxvex;
struct Edge {
  int nxt, to, flow;
} edges[MAXM << 1];
void init(int n) {
  maxvex = n, cnt = -1;
  for (int i = 0; i <= n; ++i) head[i] = -1;
}
void add(int u, int v, int flow) {
  edges[++cnt] = {head[u], v, flow};
  head[u] = cnt;
  edges[++cnt] = {head[v], u, 0};
  head[v] = cnt;
}
bool bfs(int s, int t) {
  for (int i = 0; i <= maxvex; ++i) cur[i] = head[i], depth[i] = inf;
  queue<int> q;
  q.push(s);
  depth[s] = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = head[u]; i != -1; i = edges[i].nxt) {
      int v = edges[i].to, flow = edges[i].flow;
      if (depth[v] == inf && flow) {
        depth[v] = depth[u] + 1;
        q.push(v);
      }
    }
  }
  return depth[t] < inf;
}
int dfs(int u, int t, int curflow) {
  if (curflow == 0 || u == t) return curflow;
  int flow = 0, f;
  for (int i = cur[u]; i != -1; i = edges[i].nxt) {
    cur[u] = i;
    int v = edges[i].to, eflow = edges[i].flow;
    if (depth[v] == depth[u] + 1 && (f = dfs(v, t, min(curflow, eflow)))) {
      flow += f;
      curflow -= f;
      edges[i].flow -= f;
      edges[i ^ 1].flow += f;
      if (curflow == 0) break;
    }
  }
  return flow;
}
int maxflow(int s, int t) {
  int cnt = 0;
  int flow = 0, f;
  while (bfs(s, t))
    while ((f = dfs(s, t, inf)) > 0) flow += f;
  return flow;
}
};  // namespace Dinic
int n, m;
vector<int> allx, ally;
struct Opt {
  int x1, x2, y1, y2;
} opt[60];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    int x1, x2, y1, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    x1--, y1--;
    opt[i] = {x1, x2, y1, y2};
    allx.push_back(x1), allx.push_back(x2);
    ally.push_back(y1), ally.push_back(y2);
  }
  sort(allx.begin(), allx.end());
  sort(ally.begin(), ally.end());
  allx.resize(unique(allx.begin(), allx.end()) - allx.begin());
  ally.resize(unique(ally.begin(), ally.end()) - ally.begin());
  Dinic::init(300);
  int s = 200, t = 201;
  for (int i = 1; i < allx.size(); ++i) Dinic::add(s, i, allx[i] - allx[i - 1]);
  for (int i = 1; i < ally.size(); ++i)
    Dinic::add(i + 100, t, ally[i] - ally[i - 1]);
  for (int i = 1; i <= m; ++i) {
    int x1 =
        lower_bound(allx.begin(), allx.end(), opt[i].x1) - allx.begin() + 1;
    int x2 =
        lower_bound(allx.begin(), allx.end(), opt[i].x2) - allx.begin() + 1;
    int y1 =
        lower_bound(ally.begin(), ally.end(), opt[i].y1) - ally.begin() + 1;
    int y2 =
        lower_bound(ally.begin(), ally.end(), opt[i].y2) - ally.begin() + 1;
    for (int j = x1; j < x2; ++j)
      for (int k = y1; k < y2; ++k) Dinic::add(j, k + 100, 1e9 + 10);
  }
  int ans = Dinic::maxflow(s, t);
  printf("%d\n", ans);
  return 0;
}
