#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:16777216")
using namespace std;
int a, b, c, d, i, j, n, m, k, g, s;
long long ans;
pair<pair<int, int>, pair<int, int> > edges[50001];
vector<int> sm[201];
int cs[201][201];
pair<int, int> cur[201];
bool found;
bool used[201];
inline void removeSm(int oa, int ob) {
  for (int _n(((int)((sm[oa]).size())) - 1), i(0); i <= _n; i++) {
    if (sm[oa][i] == ob) {
      swap(sm[oa][i], sm[oa].back());
      sm[oa].pop_back();
      return;
    }
  }
}
inline void replaceTreeEdge(int oa, int ob, int a, int b, int c) {
  removeSm(oa, ob);
  removeSm(ob, oa);
  sm[a].push_back(b);
  sm[b].push_back(a);
  cs[a][b] = cs[b][a] = c;
  cs[oa][ob] = cs[ob][oa] = cs[0][0];
  for (int _n((k)-1), i(0); i <= _n; i++) {
    if ((cur[i].first == oa && cur[i].second == ob) ||
        (cur[i].first == ob && cur[i].second == oa)) {
      cur[i] = make_pair(a, b);
      break;
    }
  }
}
void dfs(int v, int st, int en, int c, int cur = -1, int ca = -1, int cb = -1) {
  used[v] = 1;
  if (v == en) {
    found = 1;
    if (cur <= c) return;
    replaceTreeEdge(ca, cb, st, en, c);
    return;
  }
  for (int _n(((int)((sm[v]).size())) - 1), i(0); i <= _n; i++) {
    int w = sm[v][i];
    if (used[w]) continue;
    int nx = cur, na = ca, nb = cb;
    if (cs[v][w] > nx) {
      nx = cs[v][w];
      na = v;
      nb = w;
    }
    dfs(w, st, en, c, nx, na, nb);
    if (found) return;
  }
}
inline void addEdge(int a, int b, int c) {
  if (a == b) return;
  if (cs[a][b] <= 1000000000) {
    if (cs[a][b] <= c) return;
    cs[a][b] = cs[b][a] = c;
    return;
  }
  memset(used, 0, n);
  found = 0;
  dfs(a, a, b, c);
  if (!found) {
    cur[k++] = make_pair(a, b);
    cs[a][b] = cs[b][a] = c;
    sm[a].push_back(b);
    sm[b].push_back(a);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  scanf("%d%d", &g, &s);
  for (int _n((m)-1), i(0); i <= _n; i++) {
    scanf("%d%d%d%d", &a, &b, &c, &d);
    --a;
    --b;
    edges[i] = make_pair(make_pair(c, d), make_pair(a, b));
  }
  sort(edges, edges + m);
  memset(cs, 63, sizeof(cs));
  k = 0;
  ans = 2000000000000000000LL + 1;
  for (int _n((m)-1), i(0); i <= _n; i++) {
    addEdge(edges[i].second.first, edges[i].second.second,
            edges[i].first.second);
    if (k == n - 1) {
      a = 0;
      for (int _n((n - 1) - 1), j(0); j <= _n; j++)
        if (cs[cur[j].first][cur[j].second] > a)
          a = cs[cur[j].first][cur[j].second];
      if ((long long)a * s + (long long)g * edges[i].first.first < ans)
        ans = (long long)a * s + (long long)g * edges[i].first.first;
    }
  }
  if (ans > 2000000000000000000LL) ans = -1;
  cout << ans << endl;
}
