#include <bits/stdc++.h>   using namespace std;   struct edge {     int v, to, cap, scap;     edge(int a, int b, int c) { v = a, to = b, cap = c, scap = c; }     edge() {}   };   struct rect {     int x1, y1, x2, y2;   };   struct tri {     int y1, y2, x;   };   bool operator<(const tri &a, const tri &b) { return a.y1 < b.y1; };   const int N = 1e6 + 7;   const int INF = 1e9 + 7;   vector<edge> e;   vector<int> g[N];   int us[N];   int usbs = 1;   int d[N];   int q[N];   int ded[N];   int ptr[N];   vector<rect> fget[N];   int after_bfs = 1;   int visb = 1;   long long ans = 0;   int qh, qt;   int s, t;   int l;   bool bfs() {     qh = qt = 0;     us[s] = usbs;     q[qt++] = s;     d[s] = 0;     while (qh < qt) {       int v = q[qh++];       for (auto c : g[v]) {         if (us[e[c].to] != usbs && e[c].cap > 0) {           d[e[c].to] = d[v] + 1;           us[e[c].to] = usbs;           q[qt++] = e[c].to;         }       }     }     return (us[t] == usbs++);   }   int dfs(int v = s, int c = 1e9) {     if (!c) {       return 0;     }     if (v == t) {       ans += c;       return c;     }     if (ded[v] != after_bfs) {       ded[v] = after_bfs;       ptr[v] = 0;     }     for (; ptr[v] < (int)g[v].size(); ptr[v]++) {       int ind = g[v][ptr[v]];       if (e[ind].cap > 0 && d[e[ind].to] == d[v] + 1) {         int x = dfs(e[ind].to, min(c, e[ind].cap));         if (x) {           e[ind].cap -= x;           e[ind ^ 1].cap += x;           return x;         }       }     }     return 0;   }   void add_edge(int u, int v, int cap) {     g[u].push_back(e.size());     e.push_back({u, v, cap});     g[v].push_back(e.size());     e.push_back({v, u, 0});   }   long long dinic(int a, int b) {     s = a, t = b;     while (bfs()) {       after_bfs++;       while (dfs()) {         continue;       }     }     return ans;   }   vector<int> inds;   int lel(int v, int l, int r, int i) {     if (r - l == 1) {       return v;     } else {       int m = (l + r) / 2;       if (i < m) {         return lel(v * 2 + 1, l, m, i);       } else {         return lel(v * 2 + 2, m, r, i);       }     }   }   void get(int v, int l, int r, int tl, int tr) {     if (tl >= r || tr <= l) {       return;     }     if (tl >= l && tr <= r) {       inds.push_back(v);     } else {       int tm = (tl + tr) / 2;       get(v * 2 + 1, l, r, tl, tm);       get(v * 2 + 2, l, r, tm, tr);     }   }   void build(int v, int l, int r, int ax, int bx, int n) {     if (r - l == 1) {       add_edge(l, ax + v, 1);       add_edge(bx + v, n + l, 1);     } else {       int m = (l + r) / 2;       build(v * 2 + 1, l, m, ax, bx, n);       build(v * 2 + 2, m, r, ax, bx, n);       add_edge(ax + v * 2 + 1, ax + v, INF);       add_edge(ax + v * 2 + 2, ax + v, INF);       add_edge(bx + v, bx + v * 2 + 1, INF);       add_edge(bx + v, bx + v * 2 + 2, INF);     }   }   int main() {     vector<rect> fre;     int n, q;     cin >> n >> q;     for (int i = 0; i < q; i++) {       int x1, y1, x2, y2;       cin >> x1 >> y1 >> x2 >> y2;       x1--, y1--, x2--, y2--;       fget[x2].push_back({x1, y1, x2, y2});     }     set<tri> s;     s.insert({0, n - 1, 0});     for (int i = 0; i < n; i++) {       for (auto c : fget[i]) {         auto it = s.lower_bound({c.y1, -1, -1});         vector<tri> gt;         if (it != s.begin()) {           it--;           gt.push_back(*it);           it++;         }         bool b = false;         while (it != s.end() && (it->y2 <= c.y2 || !b)) {           gt.push_back(*it);           it++;           if (it != s.end()) {             if (it->y2 > c.y2) {               gt.push_back(*it);               b = true;             }           }         }         for (auto d : gt) {           if (max(d.y1, c.y1) > min(d.y2, c.y2)) {             continue;           }           s.erase(d);           if (c.y1 <= d.y1 && d.y2 <= c.y2) {             int a = d.x, b = c.x1 - 1;             if (a <= b) {               fre.push_back({a, d.y1, b, d.y2});             }           } else {             if (d.y1 <= c.y1 && c.y2 <= d.y2) {               auto was = d;               was.y2 = c.y1 - 1;               if (was.y1 <= was.y2) {                 s.insert(was);               }               was = d;               was.y1 = c.y2 + 1;               if (was.y1 <= was.y2) {                 s.insert(was);               }               int a = d.x, b = c.x1 - 1;               if (a <= b) {                 fre.push_back({a, c.y1, b, c.y2});               }             } else if (d.y2 > c.y2) {               auto was = d;               was.y1 = c.y2 + 1;               s.insert(was);               int a = d.x, b = c.x1 - 1;               if (a <= b) {                 fre.push_back({a, d.y1, b, c.y2});               }             } else if (d.y1 < c.y1) {               auto was = d;               was.y2 = c.y1 - 1;               s.insert(was);               int a = d.x, b = c.x1 - 1;               if (a <= b) {                 fre.push_back({a, c.y1, b, d.y2});               }             }           }         }         if (c.x2 != n - 1) {           s.insert({c.y1, c.y2, c.x2 + 1});         }       }     }     for (auto c : s) {       fre.push_back({c.x, c.y1, n - 1, c.y2});     }     inds.clear();     get(0, n - 1, n, 0, n);     int cnt = inds[0] + 1;     for (auto c : fre) {       int x1 = c.x1, y1 = c.y1, x2 = c.x2, y2 = c.y2;       inds.clear();       get(0, x1, x2 + 1, 0, n);       vector<int> a = inds;       inds.clear();       get(0, y1, y2 + 1, 0, n);       vector<int> b = inds;       for (auto c : a) {         for (auto d : b) {           add_edge(n + n + c, n + n + cnt + d, INF);         }       }     }     build(0, 0, n, n + n, n + n + cnt, n);     int st = n + n + cnt + cnt, en = n + n + cnt + cnt + 1;     for (int i = 0; i < n; i++) {       add_edge(st, i, 1);       add_edge(i + n, en, 1);     }     cout << dinic(st, en) << endl;   }