#include <bits/stdc++.h>
struct MinCostFlow {
  const long long INF1 = 1000000000LL;
  const long long INF2 = 100000000LL;
  struct edge {
    long long u, v;
    long long cap, cost;
    edge* rev;
    edge(const long long& uu, const long long& vv, const long long& _cap,
         const long long& _cost, edge* _rev = nullptr)
        : u(uu), v(vv), cap(_cap), cost(_cost), rev(_rev) {}
  };
  struct node {
    long long id, d;
    node(const long long& _id, const long long& _d) : id(_id), d(_d) {}
    bool operator<(const node& o) const { return d < o.d; }
    bool operator>(const node& o) const { return d > o.d; }
  };
  std::vector<std::vector<edge*>> adj;
  long long s, t, mS, mT;
  std::vector<edge*> prev;
  std::vector<long long> w, pi;
  MinCostFlow(long long n) {
    s = n++;
    t = n++;
    mS = n++;
    mT = n++;
    adj.assign(n, std::vector<edge*>());
  }
  ~MinCostFlow(void) {
    for (auto& row : adj)
      for (auto& e : row) delete e;
  }
  edge* add_edge(const long long& a, const long long& b, const long long& cap,
                 const long long& cost) {
    edge* e1 = new edge(a, b, cap, cost);
    edge* e2 = new edge(b, a, 0, -cost);
    e1->rev = e2;
    e2->rev = e1;
    adj[a].push_back(e1);
    adj[b].push_back(e2);
    return e1;
  }
  std::pair<long long, long long> min_cost_max_flow(void) {
    long long flow = 0;
    long long cost = 0;
    get_potential();
    while (find_path()) {
      flow += w[t];
      cost += update();
    }
    return {flow, cost};
  }
  void get_potential(void) {
    pi.assign(adj.size(), INF1);
    pi[s] = 0;
    for (long long i = 0; i + 1 < adj.size(); ++i) {
      bool upd = false;
      for (long long j = 0; j < adj.size(); ++j) {
        for (edge* e : adj[j]) {
          if (e->cap > 0 && pi[e->v] > pi[e->u] + e->cost) {
            pi[e->v] = pi[e->u] + e->cost;
            upd = true;
          }
        }
      }
      if (!upd) break;
    }
  }
  bool find_path(void) {
    std::vector<long long> d(adj.size(), INF1);
    d[s] = 0;
    prev.assign(adj.size(), nullptr);
    w.assign(adj.size(), INF1);
    std::priority_queue<node, std::vector<node>, std::greater<node>> pq;
    pq.push({s, 0});
    while (!pq.empty()) {
      node best = pq.top();
      pq.pop();
      if (best.d != d[best.id]) continue;
      for (edge* e : adj[best.id]) {
        long long nd = d[best.id] + e->cost + pi[e->u] - pi[e->v];
        if (e->cap > 0 && d[e->v] > nd) {
          d[e->v] = nd;
          prev[e->v] = e;
          w[e->v] = std::min(w[best.id], e->cap);
          pq.push({e->v, nd});
        }
      }
    }
    for (long long i = 0; i < pi.size(); ++i) pi[i] += d[i];
    return d[t] < INF1;
  }
  long long update(void) {
    long long v = t;
    long long curr = 0;
    while (prev[v] != nullptr) {
      prev[v]->cap -= w[t];
      prev[v]->rev->cap += w[t];
      curr += w[t] * prev[v]->cost;
      v = prev[v]->u;
    }
    return curr;
  }
};
int main(void) {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  long long n, q;
  std::cin >> n >> q;
  std::vector<std::vector<char>> adj_mat(n, std::vector<char>(n, true));
  for (long long type, l, r, v; q > 0; --q) {
    std::cin >> type >> l >> r >> v;
    --l;
    --r;
    --v;
    if (type == 1) {
      for (long long i = 0; i < v; ++i) {
        for (long long j = l; j <= r; ++j) adj_mat[i][j] = false;
      }
    } else {
      for (long long i = v + 1; i < n; ++i) {
        for (long long j = l; j <= r; ++j) adj_mat[i][j] = false;
      }
    }
  }
  MinCostFlow graph(n + n);
  for (long long num = 0; num < n; ++num) {
    for (long long quant = 1, last = 0; quant <= n;
         last = quant * quant, quant++) {
      graph.add_edge(graph.s, num, 1, quant * quant - last);
    }
  }
  for (long long spot = n; spot < 2 * n; ++spot)
    graph.add_edge(spot, graph.t, 1, 0);
  for (long long i = 0; i < n; ++i) {
    for (long long j = 0; j < n; ++j) {
      if (adj_mat[i][j]) graph.add_edge(i, n + j, 1, 0);
    }
  }
  const std::pair<long long, long long> ret = graph.min_cost_max_flow();
  if (ret.first != n) {
    std::cout << "-1\n";
  } else {
    std::cout << ret.second << "\n";
  }
  return 0;
}
