#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000001;
const long double EPS = 1e-9;
const int MOD = 1000000007;
const long long LLINF = 1000000000000000001;
const int maxm = 201;
const int maxn = 1001;
int n, m;
int x1[maxm], x2[maxm], y11[maxm], y2[maxm];
struct edge {
  int to;
  int cap;
  int rev;
};
class dinic {
 public:
  int INF;
  std::vector<edge> G[100000];
  int level[100000];
  int iter[100000];

 public:
  dinic();
  void add_edge(int from, int to, int cap);
  void bfs(int s);
  int dfs(int v, int t, int f);
  int maximum_flow(int s, int t);
};
dinic::dinic() {
  INF = 0x7fffffff;
  std::fill(level, level + 100000, 0);
  std::fill(iter, iter + 100000, 0);
}
void dinic::add_edge(int from, int to, int cap) {
  G[from].push_back((edge){to, cap, (int)G[to].size()});
  G[to].push_back((edge){from, 0, (int)G[from].size() - 1});
}
void dinic::bfs(int s) {
  std::memset(level, -1, sizeof(level));
  std::queue<int> que;
  level[s] = 0;
  que.push(s);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    for (int i = 0; i < (int)G[v].size(); i++) {
      edge &e = G[v][i];
      if (e.cap > 0 && level[e.to] < 0) {
        level[e.to] = level[v] + 1;
        que.push(e.to);
      }
    }
  }
}
int dinic::dfs(int v, int t, int f) {
  if (v == t) return f;
  for (int &i = iter[v]; i < (int)G[v].size(); i++) {
    edge &e = G[v][i];
    if (e.cap > 0 && level[v] < level[e.to]) {
      int d = dfs(e.to, t, std::min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}
int dinic::maximum_flow(int s, int t) {
  int flow = 0;
  for (;;) {
    bfs(s);
    if (level[t] < 0) return flow;
    std::memset(iter, 0, sizeof(iter));
    int f;
    while ((f = dfs(s, t, INF)) > 0) flow += f;
  }
}
vector<pair<int, int> > xsegs;
vector<pair<int, int> > ysegs;
dinic din;
void dinicAddEdge(int a, int b, int c) { din.add_edge(a, b, c); }
vector<pair<int, int> > tosegs(vector<int> &a) {
  vector<pair<int, int> > r;
  sort((a).begin(), (a).end());
  auto ite = unique((a).begin(), (a).end());
  a.erase(ite, a.end());
  for (int i = 0; i <= ((int)(a).size()) - 1; i++) {
    r.push_back({a[i], a[i]});
    if (i != ((int)(a).size()) - 1 && a[i] < a[i + 1] - 1)
      r.push_back({a[i] + 1, a[i + 1] - 1});
  }
  return r;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= m; i++) cin >> x1[i] >> y11[i] >> x2[i] >> y2[i];
  vector<int> xc;
  vector<int> yc;
  for (int i = 1; i <= m; i++) {
    xc.push_back(x1[i]);
    xc.push_back(x2[i]);
    yc.push_back(y11[i]);
    yc.push_back(y2[i]);
  }
  xsegs = tosegs(xc);
  ysegs = tosegs(yc);
  for (int i = 0; i <= ((int)(xsegs).size()) - 1; i++)
    dinicAddEdge(1, 2 + i, xsegs[i].second - xsegs[i].first + 1);
  for (int i = 0; i <= ((int)(ysegs).size()) - 1; i++)
    dinicAddEdge(2 + ((int)(xsegs).size()) + i,
                 2 + ((int)(xsegs).size()) + ((int)(ysegs).size()),
                 ysegs[i].second - ysegs[i].first + 1);
  set<pair<int, int> > toAdd;
  for (int i = 1; i <= m; i++)
    for (int j = 0; j <= ((int)(xsegs).size()) - 1; j++)
      for (int k = 0; k <= ((int)(ysegs).size()) - 1; k++) {
        if (xsegs[j].first >= x1[i] && xsegs[j].second <= x2[i] &&
            ysegs[k].first >= y11[i] && ysegs[k].second <= y2[i])
          toAdd.insert({2 + j, 2 + ((int)(xsegs).size()) + k});
      }
  for (auto i : toAdd) {
    dinicAddEdge(i.first, i.second, INF);
  }
  cout << din.maximum_flow(1, 2 + ((int)(xsegs).size()) + ((int)(ysegs).size()))
       << endl;
}
