#include <bits/stdc++.h>
using namespace std;
struct SSP {
  int n, source, sink;
  vector<vector<int>> adj;
  struct edge {
    int u, flow, cap, cost, origcost;
  };
  vector<edge> edges;
  SSP(int n, int source, int sink) : n(n), source(source), sink(sink), adj(n) {}
  int add_edge(int a, int b, int cap, int cost) {
    int result = edges.size();
    adj[a].push_back(edges.size());
    edges.push_back({b, 0, cap, cost, cost});
    adj[b].push_back(edges.size());
    edges.push_back({a, 0, 0, -cost, -cost});
    return result;
  }
  pair<int, int> iterate() {
    struct state_t {
      int dist, prev, maxf;
    };
    priority_queue<pair<int, int>, vector<pair<int, int>>,
                   greater<pair<int, int>>>
        pq;
    vector<state_t> states(n, {INT_MAX / 2, -1, 0});
    states[source] = {0, -2, INT_MAX};
    pq.push(make_pair(states[source].dist, source));
    while (!pq.empty()) {
      int d, v;
      tie(d, v) = pq.top();
      pq.pop();
      if (d != states[v].dist) continue;
      for (int edid : adj[v]) {
        edge& ed = edges[edid];
        if (ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost) {
          states[ed.u].dist = states[v].dist + ed.cost;
          states[ed.u].prev = edid;
          states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
          pq.push(make_pair(states[ed.u].dist, ed.u));
        }
      }
    }
    int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
    if (lastid == -1) return {0, 0};
    for (int id = lastid; id != -2; id = states[edges[id ^ 1].u].prev) {
      edges[id].flow += extraflow;
      edges[id ^ 1].flow -= extraflow;
      atcost += edges[id].origcost;
    }
    for (int id = 0; id < (int)edges.size(); ++id) {
      int v = edges[id ^ 1].u, u = edges[id].u;
      if (states[v].prev != -1 && states[u].prev != -1)
        edges[id].cost += states[v].dist - states[u].dist;
    }
    return {extraflow, atcost};
  }
  pair<int, int> mfmc() {
    int flow = 0, cost = 0;
    int extraflow, atcost;
    while (tie(extraflow, atcost) = iterate(), extraflow > 0)
      flow += extraflow, cost += extraflow * atcost;
    return {flow, cost};
  }
};
const int maxn = 55;
int mint[maxn], maxt[maxn];
int cnt = 0;
int get_vertex() {
  cnt++;
  return cnt - 1;
}
int ma[maxn][maxn], iv[maxn], iv2[maxn];
int main() {
  int n, q;
  cin >> n >> q;
  for (int e = 1; e <= n; e++) mint[e] = 1, maxt[e] = n;
  for (int e = 0; e < q; e++) {
    int t, l, r, v;
    cin >> t >> l >> r >> v;
    if (t == 1) {
      for (int f = l; f <= r; f++) mint[f] = max(mint[f], v);
    } else {
      for (int f = l; f <= r; f++) maxt[f] = min(maxt[f], v);
    }
  }
  for (int e = 1; e <= n; e++)
    if (mint[e] > maxt[e]) return !printf("-1\n");
  int sink = get_vertex();
  int source = get_vertex();
  for (int e = 1; e <= n; e++) iv[e] = get_vertex();
  for (int e = 1; e <= n; e++) iv2[e] = get_vertex();
  SSP solver(cnt, source, sink);
  for (int e = 1; e <= n; e++)
    for (int g = 1; g <= n; g++) solver.add_edge(source, iv[e], 1, 2 * g - 1);
  for (int e = 1; e <= n; e++) solver.add_edge(iv2[e], sink, 1, 0);
  for (int e = 1; e <= n; e++)
    for (int f = mint[e]; f <= maxt[e]; f++) {
      solver.add_edge(iv[f], iv2[e], 1, 0);
    }
  pair<int, int> ans = solver.mfmc();
  cout << ans.second << endl;
  return 0;
}
