#include <bits/stdc++.h>
using namespace std;
const int INF = 1000 * 1000 * 1000 + 7;
struct edge {
  int from, to;
  int capacity, flow;
  int cost;
  int revEdge;
  edge() {}
  edge(int _from, int _to, int _capacity, int _flow, int _cost, int _revEdge) {
    from = _from;
    to = _to;
    capacity = _capacity;
    flow = _flow;
    cost = _cost;
    revEdge = _revEdge;
  }
};
const int MAXN = 105;
vector<edge> g[MAXN];
void addEdge(int from, int to, int cap, int cost) {
  edge e(from, to, cap, 0, cost, (int)g[to].size());
  edge re(to, from, 0, 0, -cost, (int)g[from].size());
  g[from].push_back(e);
  g[to].push_back(re);
}
int dist[MAXN];
int parent[MAXN], lastEdge[MAXN];
pair<int, int> goFlow(int source, int sink, int n) {
  for (int i = 1; i <= n; i++) {
    dist[i] = INF;
    parent[i] = -1;
    lastEdge[i] = -1;
  }
  dist[source] = 0;
  for (int it = 1; it <= n; it++) {
    for (int u = 1; u <= n; u++) {
      for (int j = 0; j < (int)g[u].size(); j++) {
        edge cur = g[u][j];
        if (cur.flow < cur.capacity &&
            dist[cur.to] > dist[cur.from] + cur.cost) {
          dist[cur.to] = dist[cur.from] + cur.cost;
          parent[cur.to] = cur.from;
          lastEdge[cur.to] = j;
        }
      }
    }
  }
  if (dist[sink] == INF) return make_pair(0, 0);
  int v = sink;
  int flowVal = (int)1e9;
  while (v != source) {
    edge last = g[parent[v]][lastEdge[v]];
    flowVal = min(flowVal, last.capacity - last.flow);
    v = parent[v];
  }
  v = sink;
  int ans = 0;
  while (v != source) {
    edge& last = g[parent[v]][lastEdge[v]];
    edge& rlast = g[v][last.revEdge];
    ans += 1LL * last.cost * flowVal;
    last.flow += flowVal;
    rlast.flow -= flowVal;
    v = parent[v];
  }
  return make_pair(flowVal, ans);
}
int lv[MAXN], rv[MAXN];
int main() {
  int n, q;
  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    lv[i] = 1;
    rv[i] = n;
  }
  for (int i = 0; i < q; i++) {
    int t, l, r, v;
    cin >> t >> l >> r >> v;
    for (int j = l; j <= r; j++) {
      if (t == 1) {
        lv[j] = max(lv[j], v);
      } else {
        rv[j] = min(rv[j], v);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    addEdge(n + n + 2, i, 1, 0);
  }
  for (int i = 1; i <= n; i++) {
    for (int j = lv[i]; j <= rv[i]; j++) {
      addEdge(i, n + j, 1, 0);
    }
  }
  for (int i = n + 1; i <= n + n; i++) {
    for (int j = 1; j <= n; j++) {
      addEdge(i, n + n + 1, 1, 2 * j - 1);
    }
  }
  int flow = 0, cost = 0;
  pair<int, int> tmp = goFlow(n + n + 2, n + n + 1, n + n + 2);
  while (tmp.first != 0) {
    flow += tmp.first;
    cost += tmp.second;
    tmp = goFlow(n + n + 2, n + n + 1, n + n + 2);
  }
  if (flow != n) {
    puts("-1");
  } else {
    printf("%d\n", cost);
  }
  return 0;
}
