#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;
}
