#include <bits/stdc++.h>   using namespace std;   struct box {     long long int x1, x2, y1, y2;     box() : x1(0), x2(0), y1(0), y2(0) {}     box(int x1, int x2, int y1, int y2) : x1(x1), x2(x2), y1(y1), y2(y2) {}   };   struct edge {     long long int to, c, f;     edge() : to(0), c(0), f(0) {}     edge(int to, long long int c, int f) : to(to), c(c), f(f) {}   };   bool ins(box a, box b) {     if (a.x1 >= b.x1 && a.x2 <= b.x2 && a.y1 >= b.y1 && a.y2 <= b.y2) {       return 1;     }     return 0;   }   const int M = 5000000;   edge edges[M];   vector<int> g[M];   int cnt = 0;   int nxt[M];   int d[M];   int oy[40000];   int ox[40000];   int lasty[10000];   vector<int> how;   int n1;   void addedge(int v, int u, long long int c) {     edges[cnt] = edge(u, c, 0);     g[v].push_back(cnt++);     edges[cnt] = edge(v, 0, 0);     g[u].push_back(cnt++);   }   void buildy(int v, int l, int r) {     if (l == r) {       addedge(100000, v, 1);       return;     }     int m = (l + r) / 2;     buildy(2 * v, l, m);     buildy(2 * v + 1, m + 1, r);     addedge(2 * v, v, 1000000);     addedge(2 * v + 1, v, 1000000);     return;   }   void buildx(int v, int l, int r) {     if (l == r) {       addedge(v + 40000, 100001, 1);       return;     }     int m = (l + r) / 2;     buildx(2 * v, l, m);     buildx(2 * v + 1, m + 1, r);     addedge(v + 40000, 2 * v + 40000, 1000000);     addedge(v + 40000, 2 * v + 1 + 40000, 1000000);     return;   }   void gety(int v, int l, int r, int l1, int r1) {     if (l >= l1 && r <= r1) {       how.push_back(v);       return;     }     if (l > r1 || l1 > r) return;     int m = (l + r) / 2;     gety(2 * v, l, m, l1, r1);     gety(2 * v + 1, m + 1, r, l1, r1);   }   void getx(int v, int l, int r, int l1, int r1) {     if (l >= l1 && r <= r1) {       for (auto c : how) {         addedge(c, 40000 + v, 1000000000);       }       return;     }     if (l > r1 || l1 > r) return;     int m = (l + r) / 2;     getx(2 * v, l, m, l1, r1);     getx(2 * v + 1, m + 1, r, l1, r1);   }   void makepr(int x1, int x2, int y1, int y2) {     how.clear();     gety(1, 0, n1 - 1, x1, x2);     getx(1, 0, n1 - 1, y1, y2);   }   bool bfs(int s, int t, int n) {     for (int i = 0; i < n; i++) d[i] = 1000000;     d[s] = 0;     queue<int> q;     q.push(s);     while (q.size()) {       int v = q.front();       q.pop();       for (auto c : g[v]) {         int to = edges[c].to;         if (d[to] <= d[v] + 1 || edges[c].c == edges[c].f) continue;         d[to] = d[v] + 1;         q.push(to);       }     }     if (d[t] == 1000000) return 0;     return 1;   }   long long int dfs(int v, int t, long long int f) {     if (v == t) return f;     if (f == 0) return 0;     long long int sum = 0;     for (; nxt[v] < g[v].size(); nxt[v]++) {       int id = g[v][nxt[v]];       int to = edges[id].to;       if (d[to] != d[v] + 1 || edges[id].c == edges[id].f) continue;       long long int del = dfs(to, t, min(edges[id].c - edges[id].f, f - sum));       sum += del;       edges[id].f += del;       edges[id ^ 1].f -= del;       if (sum == f) break;     }     return sum;   }   long long int dinic(int s, int t, int n) {     long long int mf = 0;     while (bfs(s, t, n)) {       for (int i = 0; i < n; i++) nxt[i] = 0;       mf += dfs(s, t, 1e9);     }     return mf;   }   bool cmp(box a, box b) { return (a.y1 < b.y1); }   void solve() {     cin >> n1;     int m;     cin >> m;     vector<box> all(m);     for (int i = 0; i < m; i++) {       cin >> all[i].x1 >> all[i].y1 >> all[i].x2 >> all[i].y2;       all[i].x1--;       all[i].x2--;       all[i].y1--;       all[i].y2--;     }     sort(begin(all), end(all), cmp);     buildy(1, 0, n1 - 1);     buildx(1, 0, n1 - 1);     for (auto c : all) {       int x1, x2, y1, y2;       y1 = c.x1;       y2 = c.x2;       x1 = c.y1;       x2 = c.y2;       int cur = 0;       for (int i = 0; i < n1; i++) {         if (lasty[cur] != lasty[i]) {           if (cur >= y1 && i - 1 <= y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, cur, i - 1);             for (int y = cur; y <= i - 1; y++) lasty[y] = x2 + 1;           }           if (cur < y1 && i - 1 > y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, y1, y2);             for (int y = y1; y <= y2; y++) lasty[y] = x2 + 1;             cur = i;           }           if (cur < y1 && i - 1 <= y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, y1, i - 1);             for (int y = y1; y <= i - 1; y++) lasty[y] = x2 + 1;           }           if (cur >= y1 && i - 1 > y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, cur, y2);             for (int y = cur; y <= y2; y++) lasty[y] = x2 + 1;           }           cur = i;         }         if (i == n1 - 1) {           i++;           if (cur >= y1 && i - 1 <= y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, cur, i - 1);             for (int y = cur; y <= i - 1; y++) lasty[y] = x2 + 1;           }           if (cur < y1 && i - 1 > y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, y1, y2);             for (int y = y1; y <= y2; y++) lasty[y] = x2 + 1;           }           if (cur < y1 && i - 1 <= y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, y1, i - 1);             for (int y = y1; y <= i - 1; y++) lasty[y] = x2 + 1;           }           if (cur >= y1 && i - 1 > y2) {             if (lasty[cur] != x1) makepr(lasty[cur], x1 - 1, cur, y2);             for (int y = cur; y <= y2; y++) lasty[y] = x2 + 1;           }         }       }     }     int cur = 0;     for (int i = 0; i < n1; i++) {       if (lasty[cur] != lasty[i]) {         if (lasty[cur] <= n1 - 1) makepr(lasty[cur], n1 - 1, cur, i - 1);         cur = i;       }       if (i == n1 - 1) {         i++;         if (lasty[cur] <= n1 - 1) makepr(lasty[cur], n1 - 1, cur, i - 1);         cur = i;       }     }     cout << dinic(100000, 100001, 100002);   }   int main() {     ios_base::sync_with_stdio(0);     cout.tie(0);     cin.tie(0);     int t;     t = 1;     while (t) {       t--;       solve();     }   }