#include <bits/stdc++.h>
using namespace std;
const int maxn = 200 + 10;
const long long inf = (-1ull) >> 1;
struct edge {
  int x, y, g, s;
  void input() {
    scanf("%d%d%d%d", &x, &y, &g, &s);
    --x, --y;
  }
  bool operator<(const edge& e) const { return g < e.g; }
};
edge e[50010];
int n, m, G, S;
void init() {
  scanf("%d%d", &G, &S);
  for (int i = 0; i < (m); ++i) {
    e[i].input();
  }
}
struct disjiont_set {
  int p[maxn];
  void init() {
    for (int i = 0; i < (maxn); ++i) {
      p[i] = i;
    }
  };
  int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); }
  void join(int x, int y) { p[x] = y; }
};
disjiont_set ds;
set<pair<int, int> > mst[maxn];
int g[maxn][maxn], pre[maxn];
long long getCost(int x, int y) { return (long long)G * x + (long long)S * y; }
long long getCost(int x) {
  int maxS = 0;
  for (int i = 0; i < (n); ++i) {
    for (set<pair<int, int> >::iterator it = mst[i].begin(); it != mst[i].end();
         ++it) {
      maxS = max(maxS, it->second);
    }
  }
  return getCost(x, maxS);
}
void dfs(int x) {
  for (set<pair<int, int> >::iterator it = mst[x].begin(); it != mst[x].end();
       ++it) {
    if (pre[it->first] == -1) {
      pre[it->first] = x;
      dfs(it->first);
    }
  }
}
void addedge(int x, int y, int c) {
  g[x][y] = g[y][x] = c;
  mst[x].insert(pair<int, int>(y, c));
  mst[y].insert(pair<int, int>(x, c));
}
void deledge(int x, int y, int c) {
  g[x][y] = g[y][x] = -1;
  mst[x].erase(pair<int, int>(y, c));
  mst[y].erase(pair<int, int>(x, c));
}
void solve() {
  sort(e, e + m);
  long long ans = inf;
  ds.init();
  for (int i = 0; i < (n); ++i) {
    mst[i].clear();
    for (int j = 0; j < (n); ++j) {
      g[i][j] = -1;
    }
  }
  int cnt = 1;
  for (int i = 0; i < (m); ++i) {
    if (e[i].x == e[i].y) continue;
    int px = ds.find(e[i].x), py = ds.find(e[i].y);
    if (px != py) {
      ds.join(px, py);
      addedge(e[i].x, e[i].y, e[i].s);
      if (++cnt == n) {
        ans = getCost(e[i].g);
      }
    } else {
      memset(pre, -1, sizeof(pre));
      pre[e[i].x] = n;
      dfs(e[i].x);
      int nowy = e[i].y;
      int maxC = 0;
      while (nowy != e[i].x) {
        maxC = max(maxC, g[nowy][pre[nowy]]);
        nowy = pre[nowy];
      }
      if (maxC <= e[i].s) {
        continue;
      }
      nowy = e[i].y;
      while (nowy != e[i].x) {
        if (g[nowy][pre[nowy]] == maxC) {
          deledge(nowy, pre[nowy], maxC);
          break;
        }
        nowy = pre[nowy];
      }
      addedge(e[i].x, e[i].y, e[i].s);
      if (cnt == n) {
        ans = min(ans, getCost(e[i].g));
      }
    }
  }
  if (ans == inf) {
    puts("-1");
  } else {
    printf("%I64d\n", ans);
  }
}
int main() {
  while (scanf("%d%d", &n, &m) != EOF) {
    init();
    solve();
  }
  return 0;
}
