#include <bits/stdc++.h>
using namespace std;
struct edge {
  long long l;
  long long r;
  long long q1;
  long long q2;
};
bool cmp(edge a, edge b) {
  return make_pair(a.q1, a.q2) < make_pair(b.q1, b.q2);
}
bool operator<(edge a, edge b) { return a.q2 < b.q2; }
vector<edge> d;
long long p[1000000 + 5];
long long nt[1000000 + 5];
long long cnt = 0;
long long find_set(long long v) {
  if (v == p[v])
    return v;
  else
    return p[v] = find_set(p[v]);
}
void unite_sets(long long a, long long b) {
  a = find_set(a);
  b = find_set(b);
  if (nt[a] > nt[b]) swap(a, b);
  if (a != b) {
    cnt--;
    p[a] = b;
    nt[b] += nt[a];
  }
}
vector<vector<pair<long long, long long> > > c;
vector<edge> w;
bool used[1000000 + 5];
bool can = false;
void dfs(long long v, long long pr) {
  if (can) return;
  used[v] = true;
  for (auto i : c[v]) {
    if (can) return;
    if (i.first == pr) continue;
    if (used[i.first]) {
      w.push_back({v, i.first, 0, i.second});
      can = true;
      return;
    }
    w.push_back({v, i.first, 0, i.second});
    dfs(i.first, v);
    if (can) return;
    w.pop_back();
  }
}
long long gr[200 + 5][200 + 5];
int32_t main() {
  long long n, m;
  cin >> n >> m;
  long long g, s;
  cin >> g >> s;
  cnt = n;
  for (long long i = 0; i < n; i++) {
    p[i] = i;
    nt[i] = 1;
  }
  for (long long i = 0; i < m; i++) {
    long long l, r, q1, q2;
    cin >> l >> r >> q1 >> q2;
    l--;
    r--;
    if (l == r) continue;
    d.push_back({l, r, q1 * g, q2 * s});
  }
  sort(d.begin(), d.end(), cmp);
  c.resize(n);
  long long ans = 4e18;
  for (long long o = 0; o < (long long)d.size(); o++) {
    c[d[o].l].push_back({d[o].r, d[o].q2});
    c[d[o].r].push_back({d[o].l, d[o].q2});
    gr[d[o].l][d[o].r]++;
    gr[d[o].r][d[o].l]++;
    if (find_set(d[o].l) == find_set(d[o].r)) {
      w.clear();
      for (long long i = 0; i < n; i++) {
        used[i] = false;
      }
      for (long long i = 0; i < n; i++) {
        for (auto j : c[i]) {
          if (gr[i][j.first] > 1) {
            w.push_back({i, j.first, 0, j.second});
          }
        }
      }
      can = false;
      dfs(d[o].l, -1);
      edge mx = {0, 0, 0, 0};
      for (auto i : w) {
        if (mx < i) mx = i;
      }
      for (long long i = 0; i < n; i++) {
        for (long long j = 0; j < (long long)c[i].size(); j++) {
          if (i == mx.r && c[i][j].first == mx.l && c[i][j].second == mx.q2) {
            gr[i][c[i][j].first]--;
            c[i].erase(c[i].begin() + j);
            break;
          }
          if (i == mx.l && c[i][j].first == mx.r && c[i][j].second == mx.q2) {
            gr[i][c[i][j].first]--;
            c[i].erase(c[i].begin() + j);
            break;
          }
        }
      }
    }
    unite_sets(d[o].l, d[o].r);
    long long cnt0 = 0;
    for (long long i = 0; i < n; i++) {
      for (auto j : c[i]) {
        cnt0 = max(cnt0, j.second);
      }
    }
    if (cnt == 1) {
      ans = min(ans, d[o].q1 + cnt0);
    }
  }
  if (ans == 4e18)
    cout << -1;
  else
    cout << ans;
}
