#include <bits/stdc++.h>
using namespace std;
template <class c>
struct rge {
  c b, e;
};
template <class c>
rge<c> range(c i, c j) {
  return {i, j};
}
template <class c>
auto dud(c* x) -> decltype(cerr << *x, 0);
template <class c>
char dud(...);
struct debug {
  template <class c>
  debug& operator<<(const c&) {
    return *this;
  }
};
const int N = 400;
const int inf = 1e9 + 5;
const int nax = 6405;
namespace MinCost {
struct Edge {
  int w, c, v, rev;
  Edge(int _w, int _c, int _v, int _rev) : w(_w), c(_c), v(_v), rev(_rev) {}
};
int odl[nax], pot[nax], pop[nax], pop_kraw[nax];
int q[nax], qbeg, qend;
vector<Edge> v[nax];
bool bylo[nax];
queue<int> kolej;
void init(int n) {
  for (int i = 0; i < n; i++) v[i].clear();
}
void AddEdge(int a, int b, int cap, int cost) {
  v[a].push_back(Edge(b, cap, cost, int(v[b].size()) + (a == b)));
  v[b].push_back(Edge(a, 0, -cost, int(v[a].size() - 1)));
}
pair<int, int> MinCostMaxFlow(int s, int t, int n) {
  int flow = 0, cost = 0;
  while (true) {
    for (int i = 0; i < n; i++) {
      odl[i] = inf;
      bylo[i] = false;
    }
    bylo[s] = true;
    odl[s] = 0;
    kolej.push(s);
    while (!kolej.empty()) {
      int x = kolej.front();
      kolej.pop();
      bylo[x] = false;
      int dl = v[x].size();
      for (int i = 0; i < dl; i++)
        if (v[x][i].c > 0 &&
            odl[v[x][i].w] > odl[x] + pot[x] - pot[v[x][i].w] + v[x][i].v) {
          odl[v[x][i].w] = odl[x] + pot[x] - pot[v[x][i].w] + v[x][i].v;
          if (!bylo[v[x][i].w]) {
            kolej.push(v[x][i].w);
            bylo[v[x][i].w] = true;
          }
          pop[v[x][i].w] = x;
          pop_kraw[v[x][i].w] = i;
        }
    }
    if (odl[t] == inf) break;
    int x = t;
    int cap = inf;
    while (x != s) {
      cap = min(cap, v[pop[x]][pop_kraw[x]].c);
      x = pop[x];
    }
    flow += cap;
    x = t;
    while (x != s) {
      cost += v[pop[x]][pop_kraw[x]].v * cap;
      v[pop[x]][pop_kraw[x]].c -= cap;
      v[x][v[pop[x]][pop_kraw[x]].rev].c += cap;
      x = pop[x];
    }
  }
  return make_pair(flow, cost);
}
};  // namespace MinCost
int ogr[N][2];
int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) {
    ogr[i][0] = 1;
    ogr[i][1] = n;
  }
  for (int i = 0; i < q; i++) {
    int t, l, r, v;
    scanf("%d%d%d%d", &t, &l, &r, &v);
    for (int i = l; i <= r; i++) {
      if (t == 1) ogr[i][0] = max(ogr[i][0], v);
      if (t == 2) ogr[i][1] = min(ogr[i][1], v);
    }
  }
  MinCost::init(3 * n + 3);
  for (int i = 1; i <= n; i++) {
    MinCost::AddEdge(1, 1 + i, 1, 0);
    for (int j = ogr[i][0]; j <= ogr[i][1]; j++) {
      MinCost::AddEdge(i + 1, n + 1 + j, 1, 0);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      MinCost::AddEdge(n + 1 + i, n + n + 1 + j, 1, j * j - (j - 1) * (j - 1));
    }
  }
  for (int i = 1; i <= n; i++) {
    MinCost::AddEdge(n + n + 1 + i, n + n + n + 2, 100, 0);
  }
  pair<int, int> res = MinCost::MinCostMaxFlow(1, 3 * n + 2, 3 * n + 3);
  if (res.first < n)
    printf("-1\n");
  else
    printf("%d\n", res.second);
}
