#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int dest, back;
  long long f, c;
};
const long long inf = 1e9;
struct PushRelabel {
  vector<vector<Edge>> g;
  vector<long long> ec;
  vector<Edge *> cur;
  vector<vector<int>> hs;
  vector<int> H;
  PushRelabel(int n) : g(n), ec(n), cur(n), hs(2 * n), H(n) {}
  void add_edge(int s, int t, long long cap, long long rcap = 0) {
    if (s == t) return;
    g[s].push_back({t, int(g[t].size()), 0, cap});
    g[t].push_back({s, int(g[s].size()) - 1, 0, rcap});
  }
  void add_flow(Edge &e, long long f) {
    Edge &back = g[e.dest][e.back];
    if (!ec[e.dest] && f) hs[H[e.dest]].push_back(e.dest);
    e.f += f;
    e.c -= f;
    ec[e.dest] += f;
    back.f -= f;
    back.c += f;
    ec[back.dest] -= f;
  }
  long long maxflow(int s, int t) {
    int v = int(g.size());
    H[s] = v;
    ec[t] = 1;
    vector<int> co(2 * v);
    co[0] = v - 1;
    for (int i = (0); i < (v); ++i) cur[i] = g[i].data();
    for (auto &e : g[s]) add_flow(e, e.c);
    for (int hi = 0;;) {
      while (hs[hi].empty())
        if (!hi--) return -ec[s];
      int u = hs[hi].back();
      hs[hi].pop_back();
      while (ec[u] > 0)
        if (cur[u] == g[u].data() + int(g[u].size())) {
          H[u] = 1e9;
          for (auto &e : g[u])
            if (e.c && H[u] > H[e.dest] + 1) H[u] = H[e.dest] + 1, cur[u] = &e;
          if (++co[H[u]], !--co[hi] && hi < v)
            for (int i = (0); i < (v); ++i)
              if (hi < H[i] && H[i] < v) --co[H[i]], H[i] = v + 1;
          hi = H[u];
        } else if (cur[u]->c && H[u] == H[cur[u]->dest] + 1)
          add_flow(*cur[u], min(ec[u], cur[u]->c));
        else
          ++cur[u];
    }
  }
};
int main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  int m;
  cin >> m >> m;
  if (m == 0) {
    cout << 0 << endl;
    return 0;
  }
  vector<pair<int, int>> lo(m), hi(m);
  for (int i = (0); i < (m); ++i)
    cin >> lo[i].first >> lo[i].second >> hi[i].first >> hi[i].second;
  for (auto &pa : hi) ++pa.first, ++pa.second;
  map<int, int> xren, yren;
  for (auto &pa : lo) xren[pa.first], yren[pa.second];
  for (auto &pa : hi) xren[pa.first], yren[pa.second];
  int ixx = 0, ixy = 0;
  for (auto &pa : xren) pa.second = ixx++;
  for (auto &pa : yren) pa.second = ixy++;
  --ixx, --ixy;
  vector<int> xlen(ixx), ylen(ixy);
  int prev = 0;
  for (auto &pa : xren) {
    if (prev) xlen[pa.second - 1] = pa.first - prev;
    prev = pa.first;
  }
  prev = 0;
  for (auto &pa : yren) {
    if (prev) ylen[pa.second - 1] = pa.first - prev;
    prev = pa.first;
  }
  for (auto &pa : lo) {
    pa.first = xren[pa.first];
    pa.second = yren[pa.second];
  }
  for (auto &pa : hi) {
    pa.first = xren[pa.first];
    pa.second = yren[pa.second];
  }
  vector<vector<bool>> black(ixx, vector<bool>(ixy, false));
  for (int i = (0); i < (m); ++i) {
    for (int x = (lo[i].first); x < (hi[i].first); ++x)
      for (int y = (lo[i].second); y < (hi[i].second); ++y) black[x][y] = true;
  }
  PushRelabel pr(ixx + ixy + 2);
  int s = ixx + ixy, t = s + 1;
  for (int x = (0); x < (ixx); ++x)
    for (int y = (0); y < (ixy); ++y)
      if (black[x][y]) pr.add_edge(x, y + ixx, inf);
  for (int x = (0); x < (ixx); ++x) pr.add_edge(s, x, xlen[x]);
  for (int y = (0); y < (ixy); ++y) pr.add_edge(y + ixx, t, ylen[y]);
  cout << pr.maxflow(s, t) << endl;
}
