#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
template <int SZ>
struct Dinic {
  typedef long long F;
  struct Edge {
    int to, rev;
    F flow, cap;
  };
  int N, second, t;
  vector<Edge> adj[SZ];
  typename vector<Edge>::iterator cur[SZ];
  void addEdge(int u, int v, F cap) {
    assert(cap >= 0);
    Edge a{v, (int)adj[v].size(), 0, cap}, b{u, (int)adj[u].size(), 0, 0};
    adj[u].push_back(a), adj[v].push_back(b);
  }
  int level[SZ];
  bool bfs() {
    for (int i = 0; i < N; i++) level[i] = -1, cur[i] = begin(adj[i]);
    queue<int> q({second});
    level[second] = 0;
    while ((int)q.size()) {
      int u = q.front();
      q.pop();
      for (Edge e : adj[u])
        if (level[e.to] < 0 && e.flow < e.cap)
          q.push(e.to), level[e.to] = level[u] + 1;
    }
    return level[t] >= 0;
  }
  F sendFlow(int v, F flow) {
    if (v == t) return flow;
    for (; cur[v] != end(adj[v]); cur[v]++) {
      Edge& e = *cur[v];
      if (level[e.to] != level[v] + 1 || e.flow == e.cap) continue;
      auto df = sendFlow(e.to, min(flow, e.cap - e.flow));
      if (df) {
        e.flow += df;
        adj[e.to][e.rev].flow -= df;
        return df;
      }
    }
    return 0;
  }
  F maxFlow(int _N, int _s, int _t) {
    N = _N, second = _s, t = _t;
    if (second == t) return -1;
    F tot = 0;
    while (bfs())
      while (auto df = sendFlow(second, numeric_limits<F>::max())) tot += df;
    return tot;
  }
};
const int MX = 55;
int n, m;
pair<pair<int, int>, pair<int, int> > rectangles[MX];
map<int, int> cx, cy;
long long rcx[MX * 2], rcy[MX * 2];
Dinic<MX * 4 + 10> dinic;
long long szx(int x) { return rcx[x + 1] - rcx[x]; }
long long szy(int y) { return rcy[y + 1] - rcy[y]; }
void addEdge(int x, int y) {
  dinic.addEdge(x, y + MX * 2, min(szx(x), szy(y)));
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> rectangles[i].first.first >> rectangles[i].second.first >>
        rectangles[i].first.second >> rectangles[i].second.second;
    rectangles[i].first.first--;
    rectangles[i].first.second--;
    rectangles[i].second.first--;
    rectangles[i].second.second--;
    cx[rectangles[i].first.first] = 0;
    cx[rectangles[i].first.second + 1] = 0;
    cy[rectangles[i].second.first] = 0;
    cy[rectangles[i].second.second + 1] = 0;
  }
  cx[0] = 0;
  cx[n] = 0;
  cy[0] = 0;
  cy[n] = 0;
  int tmp = 0;
  for (auto& k : cx) k.second = tmp++;
  tmp = 0;
  for (auto& k : cy) k.second = tmp++;
  for (auto k : cx) rcx[k.second] = k.first;
  for (auto k : cy) rcy[k.second] = k.first;
  for (int x = 0; x < cx[n]; x++) {
    for (int y = 0; y < cy[n]; y++) {
      for (int i = 0; i < m; i++) {
        if (cx[rectangles[i].first.first] <= x &&
            x < cx[rectangles[i].first.second + 1] &&
            cy[rectangles[i].second.first] <= y &&
            y < cy[rectangles[i].second.second + 1]) {
          addEdge(x, y);
          break;
        }
      }
    }
  }
  int st = 221;
  int en = 222;
  for (int i = 0; i < cx[n]; i++) {
    dinic.addEdge(st, i, szx(i));
  }
  for (int i = 0; i < cy[n]; i++) {
    dinic.addEdge(i + MX * 2, en, szy(i));
  }
  return cout << dinic.maxFlow(MX * 4 + 10, st, en) << '\n', 0;
  ;
}
