#include <bits/stdc++.h>   using namespace std;   const int INF = 2e9;   const int MAXN = 900;   const int MAXM = 1900000;   int N, edges;   int last[MAXN], preve[MAXM], head[MAXM];   int Cap[MAXM], Flow[MAXM];   int dist[MAXN];   int nextEdge[MAXN];   queue<int> Q;   void init(int N) {     edges = 0;     memset(last, -1, sizeof last);   }   set<int> namex, namey;   vector<int> xx, yy;   void handlex(int f) {     if (namex.find(f) != namex.end()) return;     namex.insert(f);     xx.push_back(f);   }   void handley(int f) {     if (namey.find(f) != namey.end()) return;     yy.push_back(f);     namey.insert(f);   }   inline void add_edge(int u, int v, int cap, int flow = 0) {     head[edges] = v;     preve[edges] = last[u];     Cap[edges] = cap;     Flow[edges] = flow;     last[u] = edges++;     head[edges] = u;     preve[edges] = last[v];     Cap[edges] = 0;     Flow[edges] = 0;     last[v] = edges++;   }   inline bool dinicBfs(int S, int E, int N) {     int from = S, to, cap, flow;     memset(dist, 0, sizeof(int) * N);     dist[from] = 1;     while (!Q.empty()) Q.pop();     Q.push(from);     while (!Q.empty()) {       from = Q.front();       Q.pop();       for (int e = last[from]; e >= 0; e = preve[e]) {         to = head[e];         cap = Cap[e];         flow = Flow[e];         if (!dist[to] && cap > flow) {           dist[to] = dist[from] + 1;           Q.push(to);           if (to == E) return true;         }       }     }     return (dist[E] != 0);   }   inline int dfs(int from, int minEdge, int E) {     if (!minEdge) return 0;     if (from == E) return minEdge;     int to, e, cap, flow, ret;     for (; nextEdge[from] >= 0; nextEdge[from] = preve[e]) {       e = nextEdge[from];       to = head[e];       cap = Cap[e];       flow = Flow[e];       if (dist[to] != dist[from] + 1) continue;       ret = dfs(to, min(minEdge, cap - flow), E);       if (ret) {         Flow[e] += ret;         Flow[e ^ 1] -= ret;         return ret;       }     }     return 0;   }   int dinicUpdate(int S, int E) {     int flow = 0;     while (int minEdge = dfs(S, INF, E)) {       if (minEdge == 0) break;       flow += minEdge;     }     return flow;   }   int maxFlow(int S, int E, int N) {     int totFlow = 0;     while (dinicBfs(S, E, N)) {       for (int i = 0; i <= N; i++) nextEdge[i] = last[i];       totFlow += dinicUpdate(S, E);     }     return totFlow;   }   int x1[60], y11[60], x2[60], y2[60];   int main() {     int i, j, k, l, m, n;     init(32);     scanf( %d%d , &n, &m);     for (int i = 1; i <= m; i++) {       scanf( %d%d%d%d , &x1[i], &y11[i], &x2[i], &y2[i]);       x2[i]++;       y2[i]++;       handlex(x1[i]);       handlex(x2[i]);       handley(y11[i]);       handley(y2[i]);     }     sort(xx.begin(), xx.end());     sort(yy.begin(), yy.end());     int so = xx.size() + yy.size() + 1;     int sink = so + 1;     for (int i = 1; i <= m; i++) {       for (int j = 1; j < xx.size(); j++) {         if (xx[j] <= x1[i]) continue;         if (xx[j] > x2[i]) break;         for (int k = 1; k < yy.size(); k++) {           if (yy[k] <= y11[i]) continue;           if (yy[k] > y2[i]) break;           int g = xx.size() + k;           add_edge(j, g, INF);         }       }     }     for (int i = 1; i < xx.size(); i++) {       add_edge(so, i, xx[i] - xx[i - 1]);     }     for (int i = 1; i < yy.size(); i++) {       int g = xx.size() + i;       add_edge(g, sink, yy[i] - yy[i - 1]);     }     int ans = maxFlow(so, sink, sink + 2);     cout << ans << endl;   }