#include <bits/stdc++.h>
using namespace std;
const int maxn = 200 + 10;
int e[maxn][maxn];
int lnk[maxn][maxn];
struct node {
  int g, s, u, v;
} p[50010];
int g[maxn];
int que[maxn];
int dist[maxn];
int S, G, cnt, n, m;
bool cmp(const node &a, const node &b) { return a.g < b.g; }
void renew(int id) {
  for (int i = 1; i <= n; i++) e[i][0] = 0;
  for (int i = 0; i < cnt; i++) {
    int u = p[g[i]].u, v = p[g[i]].v;
    e[u][++e[u][0]] = g[i];
    e[v][++e[v][0]] = g[i];
    lnk[u][e[u][0]] = v;
    lnk[v][e[v][0]] = u;
  }
  int S = p[id].u, T = p[id].v;
  if (S == T) return;
  for (int i = 1; i <= n; i++) dist[i] = -1;
  dist[S] = -2;
  que[0] = S;
  for (int l = 0, r = 0; l <= r; l++)
    for (int i = 1; i <= e[que[l]][0]; i++) {
      int v = lnk[que[l]][i];
      if (dist[v] < 0 && v != S) {
        dist[v] = dist[que[l]];
        que[++r] = v;
        if (dist[v] == -2 || p[e[que[l]][i]].s > p[dist[v]].s)
          dist[v] = e[que[l]][i];
      }
    }
  if (dist[T] < 0) {
    g[cnt++] = id;
    return;
  }
  if (p[dist[T]].s <= p[id].s) return;
  for (int i = 0; i < cnt; i++)
    if (g[i] == dist[T]) {
      g[i] = id;
      break;
    }
}
int main() {
  scanf("%d%d%d%d", &n, &m, &G, &S);
  for (int i = 0; i < m; i++)
    scanf("%d%d%d%d", &p[i].u, &p[i].v, &p[i].g, &p[i].s);
  sort(p, p + m, cmp);
  long long res = 3000000000000000000LL;
  for (int i = 0, j; i < m; i = j) {
    for (j = i; p[j].g == p[i].g; j++)
      ;
    for (int k = i; k < j; k++) renew(k);
    if (cnt == n - 1) {
      int aa = 0, bb = 0;
      for (int k = 0; k < cnt; k++) {
        aa = max(aa, p[g[k]].g), bb = max(bb, p[g[k]].s);
      }
      res = min(res, (long long)p[i].g * G + (long long)bb * S);
    }
  }
  if (res == 3000000000000000000LL) res = -1;
  cout << res << endl;
}
