#include <bits/stdc++.h>
using namespace std;
const int maxn = 50010;
const long long inf = 0x3f3f3f3f3f3f3f3fll;
struct edge {
  int u, v, g, s;
  bool operator<(const edge& x) const {
    if (g != x.g) {
      return g < x.g;
    } else {
      return s < x.s;
    }
  }
} e[maxn << 1], g[maxn << 1];
int father[maxn];
int n, m, G, S;
void init() {
  for (int i = 1; i <= n; i++) {
    father[i] = i;
  }
}
bool cmp(edge x, edge y) { return x.s < y.s; }
int find(int x) {
  while (x != father[x]) x = father[x];
  return x;
}
int main() {
  init();
  scanf("%d%d%d%d", &n, &m, &G, &S);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].g, &e[i].s);
    if (find(e[i].u) != find(e[i].v)) father[find(e[i].v)] = find(e[i].u);
  }
  for (int i = 1; i < n; i++) {
    if (find(i) != find(i + 1)) {
      printf("-1");
      return 0;
    }
  }
  sort(e + 1, e + m + 1);
  long long ans = inf;
  int top = 0;
  for (int i = 1; i <= m; i++) {
    init();
    g[++top] = e[i];
    for (int j = top; j >= 2; j--) {
      if (g[j].s < g[j - 1].s) swap(g[j], g[j - 1]);
    }
    int cnt = 0;
    for (int j = 1; j <= top; j++) {
      int fx = find(g[j].u);
      int fy = find(g[j].v);
      if (fx != fy) {
        g[++cnt] = g[j];
        father[fx] = fy;
        if (cnt == n - 1) break;
      }
    }
    if (cnt == n - 1) {
      ans = min(ans, (long long)e[i].g * (long long)G +
                         (long long)g[cnt].s * (long long)S);
    }
    top = cnt;
  }
  if (ans != inf)
    printf("%I64d\n", ans);
  else
    printf("-1");
  return 0;
}
