#include <bits/stdc++.h>
using namespace std;
const int maxn = 210;
const int maxm = 50010;
struct Edge {
  int a, b;
  int jin, yin;
} edge[maxm];
struct Node {
  int a, b;
  int yin;
  bool operator<(const Node &q) const { return a < q.a; }
} node[maxm], use[maxm];
int used;
int n, m;
int G, S;
const long long inf = 4000000000000000000ll;
bool cmp(const Edge &a, const Edge &b) { return a.jin < b.jin; }
bool cmp2(const Node &a, const Node &b) { return a.yin < b.yin; }
int se[maxn];
int find(int x) {
  if (x == se[x]) return x;
  return se[x] = find(se[x]);
}
void uniu(int x, int y) {
  int xx = find(x);
  int yy = find(y);
  if (xx != yy) se[xx] = yy;
}
long long maxx;
void MST(int jin) {
  int cnt = 2;
  for (int i = 1; i <= used; i++) {
    node[cnt].a = use[i].a;
    node[cnt].b = use[i].b;
    node[cnt].yin = use[i].yin;
    cnt++;
  }
  sort(node + 1, node + 1 + cnt, cmp2);
  used = 0;
  for (int i = 1; i <= n; i++) se[i] = i;
  int maxl = 0;
  for (int i = 1; i <= cnt; i++) {
    int a = node[i].a, b = node[i].b, y = node[i].yin;
    if (find(a) != find(b)) {
      uniu(a, b);
      used++;
      use[used] = node[i];
      if (y > maxl) maxl = y;
      if (used == n - 1) break;
    }
  }
  if (used == n - 1) {
    long long ans = (long long)((long long)G * (long long)jin) +
                    (long long)((long long)maxl * (long long)S);
    if (ans < maxx) maxx = ans;
  }
}
int main() {
  cin >> n >> m;
  cin >> G >> S;
  maxx = inf;
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d%d", &edge[i].a, &edge[i].b, &edge[i].jin, &edge[i].yin);
  }
  sort(edge, edge + m, cmp);
  Node a;
  used = 0;
  for (int i = 0; i < m; i++) {
    node[1].a = edge[i].a;
    node[1].b = edge[i].b;
    node[1].yin = edge[i].yin;
    MST(edge[i].jin);
  }
  if (maxx == inf) {
    cout << -1 << endl;
  } else {
    cout << maxx << endl;
  }
  return 0;
}
