#include <bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
void yes() {
  cout << "Yes"
       << "\n";
}
void no() {
  cout << "No"
       << "\n";
}
struct Sync_stdio {
  Sync_stdio() {
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
  }
} _sync_stdio;
struct FAIL {
  FAIL() {
    cout << "CHANGE!!!"
         << "\n";
  }
};
struct Edge {
  int from;
  int to;
  long long cost;
  long long cap;
  long long flow;
  Edge(int from_, int to_, long long cost_ = 1, long long cap_ = 1)
      : from(from_), to(to_), cost(cost_), cap(cap_), flow(0) {}
};
template <class Edge>
class SPFA {
 public:
  SPFA(int vertices_count_, vector<Edge> &edges_)
      : vertices_count(vertices_count_),
        edges(edges_),
        dist(vertices_count, SPFA<Edge>::INF),
        g(vertices_count),
        pre(vertices_count, -1) {
    for (int i = 0; i < edges.size(); ++i) {
      g[edges[i].from].push_back(i);
    }
  }
  void calculate(int source_) {
    source = source_;
    dist[source] = 0;
    queue<int> q;
    q.push(source);
    vector<int> used(vertices_count);
    while (q.size()) {
      int u = q.front();
      q.pop();
      used[u] = 0;
      for (int index : g[u]) {
        const auto &edge = edges[index];
        if (edge.cap - edge.flow == 0) {
          continue;
        }
        if (dist[u] + edge.cost < dist[edge.to]) {
          dist[edge.to] = dist[u] + edge.cost;
          pre[edge.to] = index;
          if (!used[edge.to]) {
            used[edge.to] = 1;
            q.push(edge.to);
          }
        }
      }
    }
  }
  vector<int> restore_path(int target) {
    vector<int> path;
    while (target != source) {
      int index = pre[target];
      const auto &edge = edges[index];
      target = edge.from;
      path.push_back(index);
    }
    reverse(path.begin(), path.end());
    return path;
  }
  void reset() { dist.assign(vertices_count, INF); }
  Edge &get_edge(int index) { return edges[index]; }
  const Edge &get_edge(int index) const { return edges[index]; }
  const vector<long long> &get_distances() const { return dist; }
  const long long no_path() const { return INF; }

 private:
  const long long INF = 1e18;
  int vertices_count;
  vector<Edge> &edges;
  vector<long long> dist;
  vector<vector<int>> g;
  vector<int> pre;
  int source;
};
class MinCostMaxFlow {
 public:
  MinCostMaxFlow(int vertices_count_) : vertices_count(vertices_count_){};
  long long calculate() {
    SPFA<Edge> spfa(vertices_count, edges);
    long long flow = 0;
    while (1) {
      spfa.reset();
      spfa.calculate(source);
      if (spfa.get_distances()[sink] == spfa.no_path()) {
        break;
      }
      vector<int> path = spfa.restore_path(sink);
      long long add = path_flow(path);
      flow += add;
      for (auto index : path) {
        edges[index].flow += add;
        edges[index ^ 1].flow -= add;
      }
    }
    return flow;
  }
  long long get_cost() {
    long long res = 0;
    for (auto &edge : edges) {
      if (edge.cap > 0 && edge.flow > 0) {
        res += edge.cost;
      }
    }
    return res;
  }
  void set_sink(int sink_) { sink = sink_; }
  void set_source(int source_) { source = source_; }
  vector<Edge> &get_edges() { return edges; }
  const vector<Edge> &get_edges() const { return edges; }
  void add_edge(int from, int to, long long cap, long long cost) {
    edges.push_back({from, to, cost, cap});
    edges.push_back({to, from, -cost, 0});
  }
  void print_edges() {
    for (int i = 0; i < edges.size(); i += 2) {
      cout << edges[i].from << "->" << edges[i].to << " "
           << "CAP: " << edges[i].cap << " "
           << "COST: " << edges[i].cost << "\n";
    }
  }

 private:
  long long path_flow(const vector<int> &path_indices) {
    long long flow = LLONG_MAX;
    for (int index : path_indices) {
      flow = min(flow, edges[index].cap - edges[index].flow);
    }
    return flow;
  }
  int vertices_count;
  vector<Edge> edges;
  int source = -1;
  int sink = -1;
};
int main() {
  int n, q;
  cin >> n >> q;
  vector<int> minc(n, 0);
  vector<int> maxc(n, n - 1);
  for (int i = (0); i < (q); ++i) {
    int t, l, r, x;
    cin >> t >> l >> r >> x;
    --l, --r;
    if (t == 1) {
      for (int j = (l); j < (r + 1); ++j) {
        minc[j] = max(minc[j], x - 1);
        ;
      }
    } else {
      for (int j = (l); j < (r + 1); ++j) {
        maxc[j] = min(maxc[j], x - 1);
        ;
      }
    }
  }
  for (int i = (0); i < (n); ++i) {
    if (minc[i] > maxc[i]) {
      cout << -1;
      return 0;
    }
  }
  vector<pair<int, int>> a(n);
  for (int i = (0); i < (n); ++i) {
    a[i] = {minc[i], maxc[i]};
  }
  MinCostMaxFlow mcmf(2 * n + 2);
  int source = 2 * n;
  int sink = 2 * n + 1;
  mcmf.set_source(source);
  mcmf.set_sink(sink);
  for (int i = (0); i < (n); ++i) {
    mcmf.add_edge(source, i, 1, 0);
  }
  for (int i = (0); i < (n); ++i) {
    for (int j = (minc[i]); j < (maxc[i] + 1); ++j) {
      mcmf.add_edge(i, n + j, 1, 0);
    }
  }
  for (int i = (0); i < (n); ++i) {
    for (int j = (0); j < (n); ++j) {
      mcmf.add_edge(n + i, sink, 1, (j + 1) * (j + 1) - j * j);
    }
  }
  mcmf.calculate();
  cout << mcmf.get_cost();
  return 0;
}
