#include <bits/stdc++.h>
using namespace std;
template <typename T>
void out(T x) {
  cout << x << endl;
  exit(0);
}
using ll = long long;
const ll mod = 1e9 + 7;
const int maxn = 1e6 + 5;
const int inf = 1e9;
struct edge {
  int to, cost, cap, rev;
};
struct min_cost_max_flow {
  int n;
  vector<vector<edge>> g;
  min_cost_max_flow(int n) {
    this->n = n;
    g.resize(n);
  }
  void add_edge(int from, int to, int ecost, int ecap) {
    assert(from >= 0 && from < n);
    assert(to >= 0 && to < n);
    edge fwd = {to, ecost, ecap, int(g[to].size())};
    edge bak = {from, -ecost, 0, int(g[from].size())};
    g[from].push_back(fwd);
    g[to].push_back(bak);
  }
  void sp(int source, vector<int>& dist, vector<pair<int, int>>& par) {
    dist.resize(n, inf);
    par.resize(n);
    dist[source] = 0;
    vector<bool> inq(n, false);
    queue<int> qq;
    qq.push(0);
    while (!qq.empty()) {
      int at = qq.front();
      qq.pop();
      inq[at] = false;
      for (int i = 0; i < (int)g[at].size(); i++) {
        edge& ed = g[at][i];
        int to = ed.to;
        if (ed.cap > 0 && dist[to] > dist[at] + ed.cost) {
          dist[to] = dist[at] + ed.cost;
          par[to] = {at, i};
          if (!inq[to]) {
            inq[to] = true;
            qq.push(to);
          }
        }
      }
    }
  }
  pair<int, int> compute(int source, int sink, int k = inf) {
    int mincost = 0;
    int maxflow = 0;
    while (maxflow < k) {
      vector<int> dist;
      vector<pair<int, int>> par;
      sp(source, dist, par);
      if (dist[sink] == inf) {
        break;
      }
      int f = k - maxflow;
      int at = sink;
      while (at != source) {
        int to = par[at].first;
        int id = par[at].second;
        f = min(f, g[to][id].cap);
        at = to;
      }
      at = sink;
      while (at != source) {
        int to = par[at].first;
        int id = par[at].second;
        mincost += f * g[to][id].cost;
        g[to][id].cap -= f;
        int revid = g[to][id].rev;
        g[at][revid].cap += f;
        at = to;
      }
      maxflow += f;
    }
    return make_pair(mincost, maxflow);
  }
};
int n, q;
int lo[maxn], hi[maxn];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    lo[i] = 1;
    hi[i] = n;
  }
  for (int i = 1; i <= q; i++) {
    int t, l, r, x;
    cin >> t >> l >> r >> x;
    if (t == 1) {
      for (int j = l; j <= r; j++) {
        lo[j] = max(lo[j], x);
      }
    }
    if (t == 2) {
      for (int j = l; j <= r; j++) {
        hi[j] = min(hi[j], x);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (lo[i] > hi[i]) out(-1);
  }
  min_cost_max_flow Z(2 * n + 2);
  int source = 0;
  int sink = 2 * n + 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      int cost = 1 + 2 * (j - 1);
      Z.add_edge(source, i, cost, 1);
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int x = lo[i]; x <= hi[i]; x++) {
      Z.add_edge(x, n + i, 0, 1);
    }
  }
  for (int i = 1; i <= n; i++) {
    Z.add_edge(n + i, sink, 0, 1);
  }
  auto res = Z.compute(source, sink);
  int mincost = res.first;
  int maxflow = res.second;
  assert(maxflow == n);
  cout << mincost << endl;
  return 0;
}
