#include <bits/stdc++.h>
using namespace std;
const int MAXM = 50010;
const int MAXN = 210;
struct edge {
  int a, b, g, s;
  friend bool operator<(const edge &a, const edge &b) {
    if (a.g == b.g) return a.s < b.s;
    return a.g < b.g;
  }
} e[MAXM];
int N, M, G, S;
int father[MAXN];
edge use[MAXN];
bool cmp(const edge &a, const edge &b) {
  if (a.s == b.s) return a.g < b.g;
  return a.s < b.s;
}
int getfather(int x) {
  if (father[x] == x) return x;
  father[x] = getfather(father[x]);
  return father[x];
}
int main() {
  scanf("%d%d%d%d", &N, &M, &G, &S);
  for (int i = 1; i <= M; i++)
    scanf("%d%d%d%d", &e[i].a, &e[i].b, &e[i].g, &e[i].s);
  sort(e + 1, e + M + 1);
  int cnt = 0;
  long long ans = 2100000000000000000LL;
  for (int i = 1; i <= M; i++) {
    use[++cnt] = e[i];
    for (int j = 1; j <= N; j++) father[j] = j;
    int maxg = 0, maxs = 0;
    sort(use + 1, use + cnt + 1, cmp);
    int tot = 0;
    for (int j = 1; j <= cnt; j++) {
      int x = getfather(use[j].a);
      int y = getfather(use[j].b);
      if (x != y) {
        use[++tot] = use[j];
        maxg = max(maxg, use[j].g);
        maxs = max(maxs, use[j].s);
        father[x] = y;
      }
    }
    cnt = tot;
    if (cnt == N - 1) {
      ans = min(ans, (long long)maxg * G + (long long)maxs * S);
    }
  }
  printf("%I64d\n", ans == 2100000000000000000LL ? -1 : ans);
  return 0;
}
