#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll inf = LLONG_MAX >> 5;
const int N = 50005, M = 10000005;
namespace FlowGraph {
int head[N], v[M], nxt[M], ptr, tt;
ll w[M];
inline void padd_edge(int uu, int vv, ll ww) {
  v[ptr] = vv;
  w[ptr] = ww;
  nxt[ptr] = head[uu];
  head[uu] = ptr++;
}
int dis[N], cur[N];
bool vis[N];
bool bfs(int s, int t) {
  memset(vis, 0, sizeof(vis));
  memset(dis, -1, sizeof(dis));
  queue<int> q;
  q.push(s);
  dis[s] = 1;
  while (!q.empty()) {
    int nd = q.front();
    q.pop();
    for (int i = head[nd]; i != -1; i = nxt[i])
      if (w[i] && dis[v[i]] == -1) {
        dis[v[i]] = dis[nd] + 1;
        q.push(v[i]);
      }
  }
  return dis[t] != -1;
}
ll dfs(int pos, ll flow) {
  if (pos == tt) return flow;
  ll tmp = flow;
  for (int &i = cur[pos]; i != -1; i = nxt[i])
    if (w[i] && dis[v[i]] == dis[pos] + 1) {
      ll fl = dfs(v[i], min(flow, w[i]));
      w[i] -= fl;
      w[i ^ 1] += fl;
      flow -= fl;
      if (!flow) break;
    }
  return tmp - flow;
}
void init() {
  memset(head, -1, sizeof(head));
  memset(nxt, -1, sizeof(nxt));
}
inline void add_edge(int uu, int vv, ll ww) {
  padd_edge(uu, vv, ww);
  padd_edge(vv, uu, 0);
}
ll dinic(int s, int t) {
  tt = t;
  ll ret = 0;
  while (bfs(s, t)) memcpy(cur, head, sizeof(cur)), ret += dfs(s, inf);
  return ret;
}
};  // namespace FlowGraph
int sz, ss, tt;
inline int id(int l, int r, int tp) { return tp * sz + ((l + r) | (l != r)); }
void build(int l, int r, int tp) {
  int pos = id(l, r, tp);
  if (l == r) {
    if (!tp)
      FlowGraph::add_edge(ss, pos, 1);
    else
      FlowGraph::add_edge(pos, tt, 1);
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, tp);
  build(mid + 1, r, tp);
  if (!tp)
    FlowGraph::add_edge(id(l, mid, tp), pos, inf),
        FlowGraph::add_edge(id(mid + 1, r, tp), pos, inf);
  else
    FlowGraph::add_edge(pos, id(l, mid, tp), inf),
        FlowGraph::add_edge(pos, id(mid + 1, r, tp), inf);
}
using pii = pair<int, int>;
void modify(int l, int r, int tp, int ql, int qr, vector<pii> &s) {
  if (l == ql && r == qr) return s.push_back({id(l, r, tp), r - l + 1});
  int mid = (l + r) >> 1;
  if (qr <= mid)
    modify(l, mid, tp, ql, qr, s);
  else if (ql > mid)
    modify(mid + 1, r, tp, ql, qr, s);
  else
    modify(l, mid, tp, ql, mid, s), modify(mid + 1, r, tp, mid + 1, qr, s);
}
int n, q;
void update(int tl, int tr, int ql, int qr) {
  static vector<pii> a, b;
  a.clear();
  b.clear();
  modify(1, n, 0, tl, tr, a);
  modify(1, n, 1, ql, qr, b);
  for (auto &i : a)
    for (auto &j : b)
      FlowGraph::add_edge(i.first, j.first, i.second * j.second);
}
struct Node {
  int r1, r2, c;
  bool tp;
} mat[N];
int lf[N];
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> q;
  int idx = 0;
  for (int i = 1, r1, r2, c1, c2; i <= q; i++)
    cin >> r1 >> c1 >> r2 >> c2, mat[++idx] = {r1, r2, c1, 0},
                                 mat[++idx] = {r1, r2, c2, 1};
  mat[++idx] = {1, n, n + 1, 0};
  mat[++idx] = {1, n, n + 1, 1};
  sort(mat + 1, mat + idx + 1,
       [](Node a, Node b) { return a.c == b.c ? a.tp < b.tp : a.c < b.c; });
  sz = id(n, n, 0);
  ss = sz * 2 + 3;
  tt = ss + 1;
  FlowGraph::init();
  build(1, n, 0);
  build(1, n, 1);
  for (int i = 1; i <= idx; i++) {
    if (mat[i].tp == 1)
      for (int j = mat[i].r1; j <= mat[i].r2; j++) lf[j] = mat[i].c;
    else
      for (int j = mat[i].r1, lw = mat[i].c - 1, lh = 0; j <= mat[i].r2 + 1;
           j++)
        if (j == mat[i].r2 + 1 || lf[j] != lw) {
          if (lw + 1 < mat[i].c) update(lh, j - 1, lw + 1, mat[i].c - 1);
          lw = lf[j];
          lh = j;
        }
  }
  cout << FlowGraph::dinic(ss, tt) << endl;
  return 0;
}
