#include <bits/stdc++.h>
using namespace std;
struct MinCostFlow {
  const int INF = 1000 * 1000 * 1000;
  const int MAX_CAP = 1000 * 1000 * 1000;
  struct edge {
    int from, v;
    int cap, flow;
    int cost, dist;
    int rev_index;
    bool residual() { return flow < cap; }
    edge(int _f, int _v, int _cap, int _cost)
        : from(_f), v(_v), cap(_cap), flow(0), cost(_cost), dist(_cost) {}
  };
  int n, s, t;
  vector<int> d;
  vector<edge *> p;
  vector<vector<edge>> g;
  vector<bool> queued;
  MinCostFlow(int n) : n(n), d(n), p(n), g(n), queued(n) {}
  void bellman() {
    for (int i = (0); i <= (n - 1); ++i) {
      d[i] = INF;
      queued[i] = 0;
    }
    queue<int> q;
    d[s] = 0;
    q.push(s);
    queued[s] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      queued[u] = 0;
      for (auto &i : g[u])
        if (i.residual() && d[i.v] > d[u] + i.dist) {
          d[i.v] = d[u] + i.dist;
          p[i.v] = &i;
          if (!queued[i.v]) {
            q.push(i.v);
            queued[i.v] = 1;
          }
        }
    }
  }
  pair<int, int> computeFlow(int s, int t) {
    this->s = s;
    this->t = t;
    int flow = 0;
    int cost = 0;
    while (true) {
      bellman();
      if (d[t] == INF) break;
      int c = 0;
      int f = MAX_CAP;
      for (int u = t; u != s; u = p[u]->from) {
        f = min(f, p[u]->cap - p[u]->flow);
      }
      for (int u = t; u != s; u = p[u]->from) {
        p[u]->flow += f;
        g[p[u]->v][p[u]->rev_index].flow -= f;
        c += p[u]->cost;
      }
      flow += f;
      cost += f * c;
    }
    return {flow, cost};
  }
  void addEdge(int a, int b, int f, int c) {
    assert(a != b);
    g[a].push_back(edge(a, b, f, c));
    g[b].push_back(edge(b, a, 0, -c));
    g[a].back().rev_index = (int)(g[b]).size() - 1;
    g[b].back().rev_index = (int)(g[a]).size() - 1;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  int n, q;
  cin >> n >> q;
  vector<int> low(n, 0);
  vector<int> high(n, n - 1);
  while (q--) {
    int type, l, r, v;
    cin >> type >> l >> r >> v;
    l--;
    r--;
    v--;
    for (int i = (l); i <= (r); ++i) {
      if (type == 1) {
        low[i] = max(low[i], v);
      } else {
        high[i] = min(high[i], v);
      }
    }
  }
  for (int i = (0); i <= (n - 1); ++i)
    if (low[i] > high[i]) {
      cout << -1;
      return 0;
    }
  int v = 2 * n + 2;
  int src = v - 2;
  int sink = v - 1;
  MinCostFlow graph(v);
  for (int i = (0); i <= (n - 1); ++i) {
    graph.addEdge(src, i, 1, 0);
  }
  for (int i = (0); i <= (n - 1); ++i)
    for (int j = (low[i]); j <= (high[i]); ++j) {
      graph.addEdge(i, n + j, 1, 0);
    }
  for (int i = (0); i <= (n - 1); ++i)
    for (int k = (0); k <= (n - 1); ++k) {
      graph.addEdge(n + i, sink, 1, 2 * k + 1);
    }
  cout << graph.computeFlow(src, sink).second;
  return 0;
}
