#include <bits/stdc++.h>
const int kMaxN = 200, kMaxM = 50000;
std::vector<int> edge[kMaxN];
int x[kMaxM], y[kMaxM], g[kMaxM], s[kMaxM], order[kMaxM];
int cost[kMaxN][kMaxN];
int dist[kMaxN], max_edge[kMaxN][2];
bool used[kMaxN];
int n, m, G, S;
inline bool Cmp(int a, int b) {
  if (g[a] != g[b]) return g[a] < g[b];
  return s[a] < s[b];
}
void Floodfill(int u, int e1, int e2) {
  if (used[u]) return;
  used[u] = true;
  if (e1 != -1) {
    max_edge[u][0] = e1;
    max_edge[u][1] = e2;
    dist[u] = cost[e1][e2];
  }
  for (size_t i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (e1 == -1 || cost[u][v] > cost[e1][e2])
      Floodfill(v, u, v);
    else
      Floodfill(v, e1, e2);
  }
}
void AddEdge(int u, int v) {
  edge[u].push_back(v);
  edge[v].push_back(u);
}
void DelEdge(int u, int v) {
  for (__typeof(edge[u].begin()) itr = edge[u].begin(); itr != edge[u].end();
       ++itr)
    if (*itr == v) {
      edge[u].erase(itr);
      break;
    }
  for (__typeof(edge[v].begin()) itr = edge[v].begin(); itr != edge[v].end();
       ++itr)
    if (*itr == u) {
      edge[v].erase(itr);
      break;
    }
}
int main() {
  scanf("%d%d%d%d", &n, &m, &G, &S);
  memset(cost, -1, sizeof(cost));
  for (int i = 0; i < m; ++i) {
    scanf("%d%d%d%d", x + i, y + i, g + i, s + i);
    --x[i];
    --y[i];
    order[i] = i;
  }
  std::sort(order, order + m, Cmp);
  long long result = -1;
  int cnt = 0;
  for (int i = 0; i < m; ++i) {
    int xx = x[order[i]], yy = y[order[i]];
    if (xx == yy) continue;
    memset(dist, -1, sizeof(dist));
    memset(used, false, sizeof(used));
    Floodfill(xx, -1, -1);
    if (dist[yy] == -1) {
      AddEdge(xx, yy);
      cost[xx][yy] = cost[yy][xx] = s[order[i]];
      ++cnt;
    } else if (dist[yy] > s[order[i]]) {
      DelEdge(max_edge[yy][0], max_edge[yy][1]);
      AddEdge(xx, yy);
      cost[xx][yy] = cost[yy][xx] = s[order[i]];
    }
    if (cnt == n - 1) {
      long long t = (long long)G * g[order[i]];
      int max_s = 0;
      for (int j = 0; j < n; ++j) {
        for (size_t k = 0; k < edge[j].size(); ++k) {
          max_s = std::max(max_s, cost[j][edge[j][k]]);
        }
      }
      t += (long long)max_s * S;
      if (result == -1 || result > t) result = t;
    }
  }
  printf("%I64d\n", result);
  return 0;
}
