#include <bits/stdc++.h>   using namespace std;   const long long INF = 1LL * 1001 * 1001 * 1001 * 1001 * 1001 * 1001;   const int N = 10000;   struct edge {     long long a, b, cap, flow;     edge(long long a, long long b, long long cap)         : a(a), b(b), cap(cap), flow(0) {}     long long cap_to(long long u) { return u == b ? cap - flow : flow; }     long long another(long long u) { return u == b ? a : b; }     void add_flow(long long u, long long first) {       flow += (u == b ? first : -first);     }   };   struct dinic_graph {     vector<edge> e;     vector<long long> g[N];     long long pos[N], d[N], p[N];     void add_edge(long long a, long long b, long long c) {       g[a].push_back((int)e.size());       g[b].push_back((int)e.size());       e.push_back(edge(a, b, c));     }     bool bfs(long long S, long long T) {       d[S] = 1;       queue<long long> q;       q.push(S);       while (q.size()) {         long long u = q.front();         q.pop();         if (u == T) return 1;         for (int i = 0; i < g[u].size(); i++) {           long long to = e[g[u][i]].another(u);           if (!d[to] && e[g[u][i]].cap_to(to)) {             d[to] = d[u] + 1;             q.push(to);           }         }       }       return 0;     }     bool dfs(long long u, long long t) {       if (u == t) return 1;       for (; pos[u] < g[u].size(); pos[u]++) {         long long to = e[g[u][pos[u]]].another(u);         if (d[to] == d[u] + 1 && e[g[u][pos[u]]].cap_to(to)) {           p[to] = g[u][pos[u]];           if (dfs(to, t)) return 1;         }       }       return 0;     }     long long dinic(long long S, long long T) {       long long max_flow = 0;       while (1) {         memset(d, 0, sizeof(d));         if (!bfs(S, T)) return max_flow;         memset(pos, 0, sizeof(pos));         while (dfs(S, T)) {           long long cur_f = INF;           for (long long u = T; u != S; u = e[p[u]].another(u))             cur_f = min(cur_f, e[p[u]].cap_to(u));           for (long long u = T; u != S; u = e[p[u]].another(u))             e[p[u]].add_flow(u, cur_f);           max_flow += cur_f;         }       }     }   };   int n, m;   int x1[55], mezhdy[55], x2[55], nami[55];   vector<int> x, y;   dinic_graph g;   bool in(double x, double y, int pos) {     return x >= min(x1[pos], x2[pos]) && x <= max(x1[pos], x2[pos]) &&            y >= min(mezhdy[pos], nami[pos]) && y <= max(mezhdy[pos], nami[pos]);   }   int main() {     ios_base::sync_with_stdio(0);     cin >> n >> m;     for (int i = 0; i < m; i++) {       cin >> x1[i] >> mezhdy[i] >> x2[i] >> nami[i];       x2[i]++;       nami[i]++;       x.push_back(x1[i]);       x.push_back(x2[i]);       y.push_back(mezhdy[i]);       y.push_back(nami[i]);     }     sort(x.begin(), x.end());     sort(y.begin(), y.end());     x.erase(unique(x.begin(), x.end()), x.end());     y.erase(unique(y.begin(), y.end()), y.end());     int S = 0;     int T = (int)x.size() + (int)y.size() + 1;     for (int i = 1; i < x.size(); i++) g.add_edge(S, i, x[i] - x[i - 1]);     for (int i = 1; i < y.size(); i++)       g.add_edge(i + x.size(), T, y[i] - y[i - 1]);     for (int i = 1; i < x.size(); i++)       for (int j = 1; j < y.size(); j++) {         double xx = 1.0 * (x[i] + x[i - 1]) / 2;         double yy = 1.0 * (y[j] + y[j - 1]) / 2;         bool ok = 0;         for (int p = 0; p < m; p++)           if (in(xx, yy, p)) ok = 1;         if (ok) g.add_edge(i, j + x.size(), INF);       }     cout << g.dinic(S, T);   }