#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 rge<c>{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;
  }
};
using ll = long long;
const int nax = (int)1e6 + 5;
const ll INF = (ll)1e17;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m, k;
  cin >> n >> m >> k;
  vector<pair<int, pair<int, int>>> a, b;
  for (int i = 0; i < m; i++) {
    int day, from, to, costs;
    cin >> day >> from >> to >> costs;
    day--;
    if (from != 0) {
      a.emplace_back(day, make_pair(costs, from));
    } else
      b.emplace_back(day, make_pair(costs, to));
  }
  sort(a.begin(), a.end());
  sort(b.begin(), b.end());
  vector<long long> pref(nax);
  vector<int> best(nax, -1);
  int node = 0;
  ll sum = 0;
  int x = 0;
  debug() << " ["
          << "a"
             ": "
          << (a) << "] ";
  debug() << " ["
          << "b"
             ": "
          << (b) << "] ";
  for (int i = 0; i < nax; i++) {
    while (x < (int)a.size() && a[x].first < i) {
      int from = a[x].second.second, cs = a[x].second.first;
      if (best[from] == -1) {
        node++;
        sum += cs;
        best[from] = cs;
      } else {
        if (cs < best[from]) {
          sum -= best[from];
          sum += cs;
          best[from] = cs;
        }
      }
      x++;
    }
    if (node != n) {
      pref[i] = INF;
    } else {
      pref[i] = sum;
    }
  }
  vector<long long> suff(nax);
  best.assign(nax, -1);
  x = (int)b.size() - 1, node = 0, sum = 0;
  for (int i = nax - 1; i >= 0; i--) {
    while (x >= 0 && b[x].first > i) {
      int from = b[x].second.second, cs = b[x].second.first;
      if (best[from] == -1) {
        node++;
        sum += cs;
        best[from] = cs;
      } else {
        if (cs < best[from]) {
          sum -= best[from];
          sum += cs;
          best[from] = cs;
        }
      }
      x--;
    }
    if (node != n) {
      suff[i] = INF;
    } else {
      suff[i] = sum;
    }
  }
  ll answer = INF;
  for (int i = 0; i < nax; i++) {
    if (i + k - 1 > (int)1e6 + 1) break;
    sum = pref[i] + suff[i + k - 1];
    answer = min(answer, sum);
  }
  cout << (answer >= INF ? -1 : answer) << '\n';
  return 0;
}
