#include <bits/stdc++.h>
using namespace std;
int m, n, v[50][4];
vector<int> comp(int o) {
  vector<int> x;
  for (int i = 0; i < n; ++i) {
    x.push_back(v[i][o] - 1);
    x.push_back(v[i][o]);
    x.push_back(v[i][o + 2]);
  }
  sort(x.begin(), x.end());
  x.resize(unique(x.begin(), x.end()) - x.begin());
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < 2; ++j)
      v[i][o + j * 2] =
          lower_bound(x.begin(), x.end(), v[i][o + j * 2]) - x.begin();
  }
  return x;
}
struct edge {
  int u, v, cap, next;
};
const int N = 10000;
int p[N], last[N];
vector<edge> E;
int nodes;
bool getPath(int src, int sink) {
  fill(p, p + nodes, -1);
  p[src] = -2;
  queue<int> q;
  q.push(src);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int e = last[u]; e != -1; e = E[e].next)
      if (E[e].cap > 0 && p[E[e].v] == -1) {
        p[E[e].v] = e;
        q.push(E[e].v);
      }
  }
  return p[sink] != -1;
}
void addEdge(int a, int b, int c) {
  E.push_back({a, b, c, last[a]});
  last[a] = E.size() - 1;
  E.push_back({b, a, 0, last[b]});
  last[b] = E.size() - 1;
}
int maxFlow(int src, int sink) {
  int res = 0;
  int it = 0;
  while (getPath(src, sink)) {
    ++it;
    int flow = 1 << 29;
    for (int cur = sink; cur != src; cur = E[p[cur]].u)
      flow = min(flow, E[p[cur]].cap);
    for (int cur = sink; cur != src; cur = E[p[cur]].u) {
      E[p[cur]].cap -= flow;
      E[p[cur] ^ 1].cap += flow;
    }
    res += flow;
  }
  assert(it <= 2 * (nodes - 2));
  return res;
}
int main() {
  cin >> m >> n;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < 4; ++j) cin >> v[i][j];
  vector<int> mp[2] = {comp(0), comp(1)};
  int L = mp[0].size();
  int src = L + mp[1].size();
  int sink = src + 1;
  nodes = sink + 1;
  memset(last, -1, sizeof(last));
  vector<vector<bool> > vis(L, vector<bool>(mp[1].size()));
  for (int i = 0; i < n; ++i) {
    int x1 = v[i][0];
    int y1 = v[i][1];
    int x2 = v[i][2];
    int y2 = v[i][3];
    for (int i = x1; i <= x2; ++i)
      for (int j = y1; j <= y2; ++j)
        if (!vis[i][j]) {
          vis[i][j] = true;
          addEdge(i, j + L, 1 << 29);
        }
  }
  for (int i = 1; i < L; ++i) addEdge(src, i, mp[0][i] - mp[0][i - 1]);
  for (int i = 1; i < mp[1].size(); ++i)
    addEdge(L + i, sink, mp[1][i] - mp[1][i - 1]);
  cout << maxFlow(src, sink) << endl;
  return 0;
}
