#include <bits/stdc++.h>
using namespace std;
template <int V, class T = long long>
class max_flow {
  static const T INF = numeric_limits<T>::max();
  struct edge {
    int t, rev;
    T cap, f;
  };
  vector<edge> adj[V];
  int dist[V];
  int ptr[V];
  bool bfs(int s, int t) {
    memset(dist, -1, sizeof dist);
    dist[s] = 0;
    queue<int> q({s});
    while (!q.empty() && dist[t] == -1) {
      int n = q.front();
      q.pop();
      for (auto& e : adj[n]) {
        if (dist[e.t] == -1 && e.cap != e.f) {
          dist[e.t] = dist[n] + 1;
          q.push(e.t);
        }
      }
    }
    return dist[t] != -1;
  }
  T augment(int n, T amt, int t) {
    if (n == t) return amt;
    for (; ptr[n] < adj[n].size(); ptr[n]++) {
      edge& e = adj[n][ptr[n]];
      if (dist[e.t] == dist[n] + 1 && e.cap != e.f) {
        T flow = augment(e.t, min(amt, e.cap - e.f), t);
        if (flow != 0) {
          e.f += flow;
          adj[e.t][e.rev].f -= flow;
          return flow;
        }
      }
    }
    return 0;
  }

 public:
  void add(int u, int v, T cap = 1, T rcap = 0) {
    adj[u].push_back({v, (int)adj[v].size(), cap, 0});
    adj[v].push_back({u, (int)adj[u].size() - 1, rcap, 0});
  }
  T calc(int s, int t) {
    T flow = 0;
    while (bfs(s, t)) {
      memset(ptr, 0, sizeof(ptr));
      while (T df = augment(s, INF, t)) flow += df;
    }
    return flow;
  }
  void clear() {
    for (int n = 0; n < V; n++) adj[n].clear();
  }
};
set<int> xsw;
set<int> ysw;
bool adj[105][105];
int x1arr[50];
int x2arr[50];
int y1arr[50];
int y2arr[50];
int xswa[105];
int yswa[105];
int main() {
  int n, m;
  cin >> n >> m;
  xsw.insert(0);
  xsw.insert(n);
  ysw.insert(0);
  ysw.insert(n);
  for (int i = 0; i < m; i++) {
    cin >> x1arr[i] >> y1arr[i] >> x2arr[i] >> y2arr[i];
    xsw.insert(x1arr[i] - 1);
    xsw.insert(x2arr[i]);
    ysw.insert(y1arr[i] - 1);
    ysw.insert(y2arr[i]);
  }
  int idx = 0;
  for (auto x : xsw) {
    xswa[idx++] = x;
  }
  idx = 0;
  for (auto y : ysw) {
    yswa[idx++] = y;
  }
  for (int i = 0; i < m; i++) {
    int xmin = 0;
    for (int j = 0; j < xsw.size(); j++) {
      if (xswa[j] == x1arr[i] - 1) {
        xmin = j;
        break;
      }
    }
    int xmax = 0;
    for (int j = 0; j < xsw.size(); j++) {
      if (xswa[j] == x2arr[i]) {
        xmax = j;
        break;
      }
    }
    int ymin = 0;
    for (int j = 0; j < ysw.size(); j++) {
      if (yswa[j] == y1arr[i] - 1) {
        ymin = j;
        break;
      }
    }
    int ymax = 0;
    for (int j = 0; j < ysw.size(); j++) {
      if (yswa[j] == y2arr[i]) {
        ymax = j;
        break;
      }
    }
    for (int j = xmin; j < xmax; j++) {
      for (int k = ymin; k < ymax; k++) {
        adj[j][k] = true;
      }
    }
  }
  max_flow<500> network;
  for (int i = 0; i < xsw.size() - 1; i++) {
    network.add(0, i + 1, xswa[i + 1] - xswa[i]);
  }
  for (int i = 0; i < xsw.size() - 1; i++) {
    for (int j = 0; j < ysw.size() - 1; j++) {
      if (adj[i][j]) {
        network.add(i + 1, xsw.size() + j, n);
      }
    }
  }
  for (int j = 0; j < ysw.size() - 1; j++) {
    network.add(xsw.size() + j, xsw.size() + ysw.size(), yswa[j + 1] - yswa[j]);
  }
  cout << network.calc(0, xsw.size() + ysw.size()) << endl;
}
