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