#include <bits/stdc++.h>
using namespace std;
int n, m, k;
const int MAXN = 1e5;
const int MAXM = 1e5;
const long long int INF = 1e15;
struct Flight {
  int day;
  int departure;
  int arrival;
  int cost;
  Flight() {}
  Flight(int day, int departure, int arrival, int cost) {
    this->day = day;
    this->departure = departure;
    this->arrival = arrival;
    this->cost = cost;
  }
} flights[MAXM];
static bool operator<(Flight f1, Flight f2) { return f1.day < f2.day; }
int cities_mins[MAXN + 1][2];
struct MSet {
  int index;
  MSet() {}
  MSet(int index) { this->index = index; }
};
static bool operator<(MSet m1, MSet m2) {
  return flights[m1.index].cost < flights[m2.index].cost;
}
struct Que {
  int index;
  multiset<MSet>::iterator it;
  Que() {}
  Que(int index, multiset<MSet>::iterator it) {
    this->index = index;
    this->it = it;
  }
};
static bool operator<(Que q1, Que q2) { return q1.index > q2.index; }
multiset<MSet> sets[MAXN + 1];
queue<Que> que;
void read() {
  cin >> n >> m >> k;
  for (int i = 0; i < m; ++i) {
    int d, f, t, c;
    cin >> d >> f >> t >> c;
    flights[i] = Flight(d, f, t, c);
  }
  sort(flights, flights + m);
}
long long int init() {
  for (int i = 0; i < m; ++i) {
    Flight f = flights[i];
    if (f.departure == 0) {
      auto it = sets[f.arrival].insert(MSet(i));
      que.push(Que(i, it));
    }
  }
  long long int res = 0;
  for (int i = 1; i <= n; ++i) {
    if (sets[i].empty()) return -1;
    cities_mins[i][1] = flights[(*sets[i].begin()).index].cost;
    res += cities_mins[i][1];
  }
  return res;
}
long long int count_answer() {
  long long int backs = init();
  if (backs == -1) return INF;
  int index = 0;
  long long int fronts = 0;
  int left = n;
  while (index < m && left) {
    Flight f = flights[index];
    if (f.arrival == 0) {
      if (que.empty()) return INF;
      while (flights[que.front().index].day <= k + f.day) {
        auto front = que.front();
        que.pop();
        int city = flights[front.index].arrival;
        sets[city].erase(front.it);
        if (sets[city].empty()) return INF;
        int new_cost = flights[sets[city].begin()->index].cost;
        backs -= cities_mins[city][1];
        backs += new_cost;
        cities_mins[city][1] = new_cost;
      }
      if (!cities_mins[f.departure][0]) {
        left--;
      }
      if (!cities_mins[f.departure][0] ||
          cities_mins[f.departure][0] > f.cost) {
        fronts -= cities_mins[f.departure][0];
        fronts += f.cost;
        cities_mins[f.departure][0] = f.cost;
      }
    }
    index++;
  }
  if (left) return INF;
  long long int res = backs + fronts;
  for (; index < m; ++index) {
    Flight f = flights[index];
    if (f.arrival != 0) continue;
    if (que.empty()) return res;
    while (flights[que.front().index].day <= k + f.day) {
      auto front = que.front();
      que.pop();
      int city = flights[front.index].arrival;
      sets[city].erase(front.it);
      if (sets[city].empty()) return res;
      int new_cost = flights[sets[city].begin()->index].cost;
      backs -= cities_mins[city][1];
      backs += new_cost;
      cities_mins[city][1] = new_cost;
    }
    if (!cities_mins[f.departure][0] || cities_mins[f.departure][0] > f.cost) {
      fronts -= cities_mins[f.departure][0];
      fronts += f.cost;
      cities_mins[f.departure][0] = f.cost;
    }
    res = min(res, backs + fronts);
  }
  return res;
}
int main() {
  ios_base::sync_with_stdio(false);
  read();
  long long int ans = count_answer();
  if (ans == INF) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
  return 0;
}
