#include <bits/stdc++.h>
using namespace std;
const int maxn = 205, maxm = 5e4 + 5;
const int mod = 1e9 + 7;
const long long inf = 2e18 + 5;
struct edge_list {
  int x, y, g, s;
  edge_list(int x = 0, int y = 0, int g = 0, int s = 0)
      : x(x), y(y), g(g), s(s) {}
};
bool gcmp(const edge_list& x, const edge_list& y) { return x.g < y.g; }
bool scmp(const edge_list& x, const edge_list& y) { return x.s < y.s; }
struct DSU {
  vector<int> lab;
  int cmp;
  void Init(int n) {
    lab.resize(n + 5);
    fill(begin(lab), end(lab), -1);
    cmp = n;
  }
  int finds(int u) {
    if (lab[u] < 0) return u;
    return lab[u] = finds(lab[u]);
  }
  bool same(int u, int v) { return finds(u) == finds(v); }
  bool merges(int u, int v) {
    u = finds(u);
    v = finds(v);
    if (u == v) return false;
    if (lab[v] < lab[u]) swap(u, v);
    lab[u] += lab[v];
    lab[v] = u;
    --cmp;
    return true;
  }
} dsu;
edge_list edge[maxm];
int N, M;
int gcost, scost;
vector<edge_list> now, nxt;
long long ret = inf;
void solve(int G) {
  nxt.clear();
  sort(now.begin(), now.end(), scmp);
  dsu.Init(N);
  for (auto all : now) {
    int x = all.x, y = all.y, S = all.s;
    if (dsu.merges(x, y)) {
      nxt.push_back(all);
      if (dsu.cmp == 1) {
        ret = min(ret, 1ll * G * gcost + 1ll * S * scost);
      }
    }
  }
}
signed main(void) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  if (fopen("A.INP", "r")) {
    freopen("A.INP", "r", stdin);
    freopen("A.OUT", "w", stdout);
  }
  if (fopen(""
            ".INP",
            "r")) {
    freopen(
        ""
        ".INP",
        "r", stdin);
    freopen(
        ""
        ".OUT",
        "w", stdout);
  }
  cin >> N >> M >> gcost >> scost;
  for (int i = 1; i <= M; ++i) {
    int x, y, g, s;
    cin >> x >> y >> g >> s;
    edge[i] = edge_list(x, y, g, s);
  }
  sort(edge + 1, edge + 1 + M, gcmp);
  for (int i = 1; i <= M; ++i) {
    now.push_back(edge[i]);
    solve(edge[i].g);
    now = nxt;
  }
  if (ret == inf) ret = -1;
  cout << ret << '\n';
}
