#include <bits/stdc++.h>
using namespace std;
template <typename V>
bool tomin(V& x, V y) {
  if (y < x) {
    x = y;
    return true;
  }
  return false;
}
template <typename V>
bool tomax(V& x, V y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}
const int M = 105;
int n, m, S, T, X1[M], Y1[M], X2[M], Y2[M], X[M], Y[M];
bool A[M][M];
namespace Dinic {
int level[M * M], ptr[M * M];
vector<int> E[M * M];
queue<int> Q;
struct FlowEdge {
  int v, u;
  long long cap, flow;
  FlowEdge(int v, int u, long long cap, long long flow = 0)
      : v(v), u(u), cap(cap), flow(flow) {}
};
vector<FlowEdge> Edge;
void Addedge(int v, int u, long long cap) {
  static int tot = 0;
  Edge.emplace_back((FlowEdge){v, u, cap});
  Edge.emplace_back((FlowEdge){u, v, 0});
  E[v].emplace_back(tot);
  E[u].emplace_back(tot + 1);
  tot += 2;
}
bool bfs() {
  level[S] = 0;
  Q.push(S);
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (int id : E[v]) {
      if (Edge[id].cap - Edge[id].flow < 1) continue;
      if (level[Edge[id].u] != -1) continue;
      level[Edge[id].u] = level[v] + 1;
      Q.push(Edge[id].u);
    }
  }
  return level[T] != -1;
}
long long dfs(int v, long long pushed) {
  if (pushed == 0) return 0;
  if (v == T) return pushed;
  for (int& cid = ptr[v]; cid < E[v].size(); cid++) {
    int id = E[v][cid], u = Edge[id].u;
    if (level[v] + 1 != level[u] || Edge[id].cap - Edge[id].flow < 1) continue;
    long long tr = dfs(u, min(pushed, Edge[id].cap - Edge[id].flow));
    if (tr == 0) continue;
    Edge[id].flow += tr;
    Edge[id ^ 1].flow -= tr;
    return tr;
  }
  return 0;
}
long long flow() {
  long long f = 0;
  while (true) {
    for (int i = S; i <= T; i++) level[i] = -1;
    if (!bfs()) break;
    for (int i = S; i <= T; i++) ptr[i] = 0;
    while (long long t = dfs(S, LLONG_MAX)) f += t;
  }
  return f;
}
}  // namespace Dinic
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    cin >> X1[i] >> Y1[i] >> X2[i] >> Y2[i];
    ++X2[i];
    ++Y2[i];
    X[i + i - 1] = X1[i];
    Y[i + i - 1] = Y1[i];
    X[i + i] = X2[i];
    Y[i + i] = Y2[i];
  }
  sort(X + 1, X + 1 + m + m);
  sort(Y + 1, Y + 1 + m + m);
  int xtot = unique(X + 1, X + 1 + m + m) - X - 1,
      ytot = unique(Y + 1, Y + 1 + m + m) - Y - 1;
  for (int i = 1; i <= m; i++) {
    X1[i] = lower_bound(X + 1, X + 1 + xtot, X1[i]) - X;
    X2[i] = lower_bound(X + 1, X + 1 + xtot, X2[i]) - X;
    Y1[i] = lower_bound(Y + 1, Y + 1 + ytot, Y1[i]) - Y;
    Y2[i] = lower_bound(Y + 1, Y + 1 + ytot, Y2[i]) - Y;
  }
  for (int k = 1; k <= m; k++) {
    for (int i = X1[k]; i < X2[k]; i++)
      for (int j = Y1[k]; j < Y2[k]; j++) A[i][j] = true;
  }
  S = 0;
  T = xtot + ytot + 1;
  for (int i = 1; i < xtot; i++) Dinic::Addedge(S, i, X[i + 1] - X[i]);
  for (int i = 1; i < ytot; i++)
    Dinic::Addedge(i + xtot - 1, T, Y[i + 1] - Y[i]);
  for (int i = 1; i < xtot; i++) {
    for (int j = 1; j < ytot; j++)
      if (A[i][j]) Dinic::Addedge(i, j + xtot - 1, n);
  }
  cout << Dinic::flow() << endl;
  return 0;
}
