#include <bits/stdc++.h>
using namespace std;
const int N = 205;
const int M = 5e4 + 5;
int n, m, g, s, trace[N], w[N][N], cnt, B;
vector<int> adj[N];
struct T {
  int u, v, g, s;
};
T edge[M];
bool lf(T a, T b) { return a.g < b.g; }
void del(int u, int v) {
  for (int i = 0; i < adj[u].size(); i++) {
    if (adj[u][i] == v) {
      swap(adj[u][i], adj[u].back());
      adj[u].pop_back();
      break;
    }
  }
}
void add(int u, int v, int c) {
  adj[u].push_back(v);
  w[u][v] = c;
}
void dfs(int u) {
  cnt++;
  for (auto& v : adj[u]) {
    if (trace[v] == -1) {
      trace[v] = u;
      dfs(v);
      B = max(B, w[u][v]);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> m >> g >> s;
  for (int i = 1; i <= m; i++)
    cin >> edge[i].u >> edge[i].v >> edge[i].g >> edge[i].s;
  sort(edge + 1, edge + m + 1, lf);
  long long res = -1;
  for (int i = 1; i <= m; i++) {
    int u = edge[i].u;
    int v = edge[i].v;
    if (u == v) continue;
    memset(trace, -1, sizeof trace);
    trace[u] = 0;
    dfs(u);
    if (trace[v] == -1) {
      add(u, v, edge[i].s);
      add(v, u, edge[i].s);
    } else {
      int mx = -1;
      while (v != u) {
        if (mx == -1 || w[trace[v]][v] > w[trace[mx]][mx]) mx = v;
        v = trace[v];
      }
      if (edge[i].s < w[trace[mx]][mx]) {
        del(trace[mx], mx);
        del(mx, trace[mx]);
        add(edge[i].u, edge[i].v, edge[i].s);
        add(edge[i].v, edge[i].u, edge[i].s);
      }
    }
    int A = edge[i].g;
    B = 0;
    cnt = 0;
    memset(trace, -1, sizeof trace);
    trace[1] = 0;
    dfs(1);
    if (cnt == n) {
      if (res == -1 || res > 1ll * A * g + 1ll * B * s)
        res = 1ll * A * g + 1ll * B * s;
    }
  }
  cout << res;
}
