#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 200;
struct Edge {
  int from, to, cap, flow, cost;
};
int n, m, s, t;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn], d[maxn], p[maxn], a[maxn];
void AddEdge(int from, int to, int cap, int cost) {
  edges.push_back((Edge){from, to, cap, 0, cost});
  edges.push_back((Edge){to, from, 0, 0, -cost});
  m = edges.size();
  G[from].push_back(m - 2);
  G[to].push_back(m - 1);
}
bool SPFA(int s, int t, int &flow, int &cost) {
  for (int i = 0; i <= 180; i++) d[i] = INF;
  memset(inq, 0, sizeof(inq));
  d[s] = 0;
  inq[s] = 1;
  p[s] = 0;
  a[s] = INF;
  queue<int> Q;
  Q.push(s);
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    inq[u] = 0;
    for (int i = 0; i < G[u].size(); i++) {
      Edge &e = edges[G[u][i]];
      if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
        d[e.to] = d[u] + e.cost;
        p[e.to] = G[u][i];
        a[e.to] = min(a[u], e.cap - e.flow);
        if (!inq[e.to]) {
          Q.push(e.to);
          inq[e.to] = 1;
        }
      }
    }
  }
  if (d[t] == INF) return false;
  flow += a[t];
  cost += d[t] * a[t];
  int u = t;
  while (u != s) {
    edges[p[u]].flow += a[t];
    edges[p[u] ^ 1].flow -= a[t];
    u = edges[p[u]].from;
  }
  return true;
}
int minCost(int s, int t) {
  int flow = 0, cost = 0;
  while (SPFA(s, t, flow, cost))
    ;
  if (flow != n) return -1;
  return cost;
}
int main() {
  ios::sync_with_stdio(false);
  int q, Min[55], Max[55];
  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    Min[i] = 1;
    Max[i] = n;
  }
  for (int i = 1; i <= q; i++) {
    int o, l, r, v;
    cin >> o >> l >> r >> v;
    if (o == 1)
      for (int j = l; j <= r; j++) Min[j] = max(Min[j], v);
    else
      for (int j = l; j <= r; j++) Max[j] = min(Max[j], v);
  }
  for (int i = 1; i <= n; i++) {
    AddEdge(0, i, n, 0);
    for (int j = 1; j <= n; j++) AddEdge(i, i + n, 1, 2 * j - 1);
    AddEdge(2 * n + i, 3 * n + 1, 1, 0);
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (i >= Min[j] && i <= Max[j]) AddEdge(i + n, 2 * n + j, 1, 0);
  cout << minCost(0, 3 * n + 1) << endl;
  return 0;
}
