#include <bits/stdc++.h>
using namespace std;
#pragma GCC diagnostic ignored "-Wmissing-declarations"
inline int safe_mul(const int x, const int y)
    __attribute__((warn_unused_result));
int const maxn = 1000;
int const maxm = 1000000;
int ptr[maxn];
int const inf = 1e9 + 7;
int dist[maxn];
struct TEdge {
  int from;
  int to;
  int cap;
  int flow;
  TEdge(int from, int to, int cap, int flow = 0)
      : from(from), to(to), cap(cap), flow(flow) {}
  TEdge() : from(0), to(0), cap(0), flow(0) {}
};
TEdge edges[maxm];
int cntedges = 0;
vector<int> gr[maxn];
int dfs(int v, int f, int curFlow = inf) {
  if (curFlow == 0) return 0;
  if (v == f) {
    return curFlow;
  }
  for (int& ne = ptr[v]; ne < gr[v].size(); ++ne) {
    auto& en = edges[gr[v][ne]];
    if (dist[en.to] == dist[v] + 1) {
      int nflow = dfs(en.to, f, min(curFlow, en.cap - en.flow));
      if (nflow > 0) {
        en.flow += nflow;
        edges[gr[v][ne] ^ 1].flow -= nflow;
        return nflow;
      }
    }
  }
  return 0;
}
bool bfs(int s, int f) {
  fill(begin(dist), end(dist), -1);
  dist[s] = 0;
  queue<int> qu;
  qu.push(s);
  while (!qu.empty()) {
    int v = qu.front();
    qu.pop();
    for (int ne : gr[v]) {
      const auto& ed = edges[ne];
      if (ed.cap > ed.flow && dist[ed.to] == -1) {
        dist[ed.to] = dist[v] + 1;
        qu.push(ed.to);
      }
    }
  }
  return dist[f] > 0;
}
long long get_flow(int s, int f) {
  long long ans = 0;
  while (bfs(s, f)) {
    fill(begin(ptr), end(ptr), 0);
    while (int cur = dfs(s, f)) ans += cur;
  }
  return ans;
}
inline void add_edge(const int from, const int to, const int cap) {
  edges[cntedges] = TEdge(from, to, cap);
  gr[from].push_back(cntedges++);
  edges[cntedges] = TEdge(to, from, 0);
  gr[to].push_back(cntedges++);
  assert(cntedges < maxm - 1);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  vector<int> x = {0, n};
  vector<int> y = {0, n};
  vector<tuple<int, int, int, int>> qu(m);
  for (auto& tu : qu) {
    int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    x.push_back(x1 - 1);
    x.push_back(x2);
    y.push_back(y1 - 1);
    y.push_back(y2);
    tu = make_tuple(x1, y1, x2, y2);
  }
  sort(begin(x), end(x));
  sort(begin(y), end(y));
  x.erase(unique(begin(x), end(x)), end(x));
  y.erase(unique(begin(y), end(y)), end(y));
  for (size_t i = 1; i < x.size(); ++i) add_edge(0, i + 1, x[i] - x[i - 1]);
  for (size_t i = 1; i < y.size(); ++i)
    add_edge(x.size() + i, 1, y[i] - y[i - 1]);
  for (const auto& tu : qu) {
    int x1, y1, x2, y2;
    tie(x1, y1, x2, y2) = tu;
    int lx = lower_bound(begin(x), end(x), x1) - begin(x);
    int rx = lower_bound(begin(x), end(x), x2) - begin(x);
    int ly = lower_bound(begin(y), end(y), y1) - begin(y);
    int ry = lower_bound(begin(y), end(y), y2) - begin(y);
    for (int i = lx; i <= rx; ++i)
      for (int j = ly; j <= ry; ++j) add_edge(i + 1, j + x.size(), 1000000009);
  }
  cout << get_flow(0, 1) << endl;
}
