#include <bits/stdc++.h>
using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f;
long long pre[2000005];
long long suf[2000005];
bool vis[2000005];
long long now[2000005];
struct edge {
  int id;
  long long c;
};
vector<edge> G1[2000005];
vector<edge> G2[2000005];
int main() {
  int n, m, k;
  scanf("%d%d%d", &n, &m, &k);
  int maxx = 0;
  while (m--) {
    int d, f, t, c;
    scanf("%d%d%d%d", &d, &f, &t, &c);
    edge e;
    e.c = c;
    if (f != 0) {
      e.id = f;
      G1[d].push_back(e);
    } else {
      e.id = t;
      G2[d].push_back(e);
    }
    maxx = max(maxx, d);
  }
  memset(suf, 0x3f, sizeof(suf));
  memset(pre, 0x3f, sizeof(pre));
  memset(now, 0x3f, sizeof(now));
  memset(vis, false, sizeof(vis));
  int cnt = 0;
  long long ans = 0;
  for (int i = 1; i <= maxx; i++) {
    for (int j = 0; j < G1[i].size(); j++) {
      int v = G1[i][j].id;
      if (!vis[v]) {
        vis[v] = true;
        ++cnt;
        ans += G1[i][j].c;
        now[v] = G1[i][j].c;
      } else if (G1[i][j].c < now[v]) {
        ans -= now[v];
        now[v] = G1[i][j].c;
        ans += now[v];
      }
    }
    if (cnt == n) {
      pre[i] = ans;
    } else {
      pre[i] = inf;
    }
  }
  memset(vis, false, sizeof(vis));
  memset(now, 0x3f, sizeof(now));
  ans = 0;
  cnt = 0;
  for (int i = maxx; i >= 1; i--) {
    for (int j = 0; j < G2[i].size(); j++) {
      int v = G2[i][j].id;
      if (!vis[v]) {
        vis[v] = true;
        ++cnt;
        now[v] = G2[i][j].c;
        ans += G2[i][j].c;
      } else if (G2[i][j].c < now[v]) {
        ans -= now[v];
        now[v] = G2[i][j].c;
        ans += now[v];
      }
    }
    if (cnt == n) {
      suf[i] = ans;
    } else {
      suf[i] = inf;
    }
  }
  long long Ans = inf;
  for (int i = 1; i + k + 1 <= maxx; i++) {
    Ans = min(Ans, pre[i] + suf[i + k + 1]);
  }
  if (Ans == inf)
    printf("-1\n");
  else
    printf("%I64d\n", Ans);
  return 0;
}
