#include <bits/stdc++.h>
using namespace std;
const int N = -1;
const long long INF = 1.01e9;
const int LOG = 20;
namespace flow {
const int inf = 1.01e9;
const int maxn = 3e6 + 10;
const int maxe = 2 * maxn;
int head[maxn], next[maxe], to[maxe], f[maxe], ec = 1;
int ST, EN, N = maxn;
inline void setN(int n) {
  ST = n;
  EN = n + 1;
  N = n + 2;
}
inline void _add(int x, int y, int ff) {
  ++ec;
  to[ec] = y;
  next[ec] = head[x];
  head[x] = ec;
  f[ec] = ff;
}
inline int add(int x, int y, int ff) {
  _add(x, y, ff);
  _add(y, x, 0);
  return ec - 1;
}
void clear() {
  for (int i = 0; i < (N); ++i) head[i] = 0;
  ec = 1;
}
int d[maxn];
int q[maxn], st = 0, en = 0;
int bfs() {
  for (int i = 0; i < (N); ++i) d[i] = 1e9;
  st = 0, en = 0;
  d[ST] = 0;
  q[en++] = ST;
  while (st < en) {
    int x = q[st++];
    if (x == EN) return 1;
    for (int e = head[x]; e; e = next[e]) {
      int y = to[e];
      if (d[y] == 1e9 && f[e]) {
        d[y] = d[x] + 1;
        q[en++] = y;
      }
    }
  }
  return 0;
}
int pushed;
int fst[maxn];
int dfs(int x, int flow = 1e9) {
  if (x == EN) {
    pushed = flow;
    return 1;
  }
  for (; fst[x]; fst[x] = next[fst[x]]) {
    int e = fst[x];
    int y = to[e];
    if (d[y] == d[x] + 1 && f[e] && dfs(y, min(f[e], flow))) {
      f[e] -= pushed;
      f[e ^ 1] += pushed;
      return 1;
    }
  }
  return 0;
}
long long calcFlow() {
  long long res = 0;
  while (bfs()) {
    for (int i = 0; i < (N); ++i) fst[i] = head[i];
    while (dfs(ST)) {
      res += pushed;
    }
  }
  return res;
}
}  // namespace flow
struct Event {
  int t, y;
  int l, r;
};
int cur;
struct SparseTable {
  vector<int> table[LOG];
  vector<int> deg;
  void build(vector<int> a, bool flagDown) {
    table[0] = a;
    deg.push_back(0);
    deg.push_back(0);
    for (int i = 2; i <= (int)a.size(); i++) {
      deg.push_back(deg[i / 2] + 1);
    }
    for (int j = 1; j < LOG; j++) {
      for (int i = 0; i + (1ll << (j)) <= (int)a.size(); i++) {
        table[j].push_back(cur);
        if (flagDown) {
          flow::add(cur, table[j - 1][i], INF);
          flow::add(cur, table[j - 1][i + (1ll << (j - 1))], INF);
        } else {
          flow::add(table[j - 1][i], cur, INF);
          flow::add(table[j - 1][i + (1ll << (j - 1))], cur, INF);
        }
        cur++;
      }
    }
  }
  pair<int, int> ask(int l, int r) {
    int k = deg[r - l];
    return {table[k][l], table[k][r - (1ll << (k))]};
  }
};
int main() {
  int n, Q;
  scanf("%d%d", &n, &Q);
  vector<Event> event;
  for (int i = 0; i < Q; i++) {
    int x1, y1, x2, y2;
    scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
    x1--;
    y1--;
    event.push_back({y1, y2, x1, x2});
  }
  event.push_back({n, n, 0, n});
  sort((event).begin(), (event).end(),
       [](Event A, Event B) { return A.t < B.t; });
  flow::ST = n * 2;
  flow::EN = n * 2 + 1;
  vector<int> L;
  vector<int> R;
  for (int i = 0; i < n; i++) {
    L.push_back(i);
    flow::add(flow::ST, i, 1);
  }
  for (int i = 0; i < n; i++) {
    R.push_back(i + n);
    flow::add(i + n, flow::EN, 1);
  }
  cur = n * 2 + 2;
  SparseTable tableL;
  SparseTable tableR;
  tableL.build(L, 0);
  tableR.build(R, 1);
  vector<int> h(n);
  set<pair<int, int>> q;
  q.insert({0, n});
  h[0] = 0;
  for (auto E : event) {
    auto it = q.lower_bound({E.l, n + 1});
    assert(it != q.begin());
    it--;
    vector<pair<int, int>> seg;
    for (;;) {
      if (it == q.end()) break;
      if (E.r <= it->first) break;
      seg.push_back(*it);
      auto itNext = it;
      itNext++;
      q.erase(it);
      it = itNext;
    }
    for (auto second : seg) {
      int tl = max(second.first, E.l);
      int tr = min(second.second, E.r);
      assert(tl < tr);
      int x = h[second.first];
      int y = E.t;
      if (x < y) {
        auto B1 = tableL.ask(x, y);
        auto B2 = tableR.ask(tl, tr);
        for (auto v : {B1.first, B1.second})
          for (auto u : {B2.first, B2.second}) flow::add(v, u, INF);
      }
      if (second.first < E.l) {
        q.insert({second.first, E.l});
      }
      if (E.r < second.second) {
        q.insert({E.r, second.second});
        h[E.r] = x;
      }
    }
    q.insert({E.l, E.r});
    h[E.l] = E.y;
  }
  flow::N = cur;
  cout << flow::calcFlow() << endl;
  return 0;
}
