#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 202;
int cnt[MAXN][MAXN];
struct bitset_ {
  long long val1, val2, val3, val4;
  inline void reset() { val1 = val2 = val3 = val4 = 0ll; }
  bitset_() { reset(); }
  inline bitset_ operator|(bitset_& that) {
    bitset_ ret;
    ret.val1 = val1 | that.val1;
    ret.val2 = val2 | that.val2;
    ret.val3 = val3 | that.val3;
    ret.val4 = val4 | that.val4;
    return ret;
  }
  inline bitset_ operator&(bitset_& that) {
    bitset_ ret;
    ret.val1 = val1 & that.val1;
    ret.val2 = val2 & that.val2;
    ret.val3 = val3 & that.val3;
    ret.val4 = val4 & that.val4;
    return ret;
  }
  inline bitset_ operator^(bitset_& that) {
    bitset_ ret;
    ret.val1 = val1 ^ that.val1;
    ret.val2 = val2 ^ that.val2;
    ret.val3 = val3 ^ that.val3;
    ret.val4 = val4 ^ that.val4;
    return ret;
  }
  inline int count() {
    int ret = 0;
    long long val = val1;
    while (val) {
      ret++;
      val &= (val - 1);
    }
    val = val2;
    while (val) {
      ret++;
      val &= (val - 1);
    }
    val = val3;
    while (val) {
      ret++;
      val &= (val - 1);
    }
    val = val4;
    while (val) {
      ret++;
      val &= (val - 1);
    }
    return ret;
  }
  inline int lg2(long long x) {
    int l = 0, r = 50;
    while (l < r - 1) {
      int mid = (l + r) >> 1;
      if ((1ll << mid) < x) {
        l = mid;
      } else {
        if ((1ll << mid) == x) {
          return mid;
        }
        r = mid;
      }
    }
    return l;
  }
  inline int low_bit() {
    if (val1) {
      int ret = lg2(val1 ^ (val1 & (val1 - 1))) + 1;
      val1 &= (val1 - 1);
      return ret;
    }
    if (val2) {
      int ret = lg2(val2 ^ (val2 & (val2 - 1))) + 50 + 1;
      val2 &= (val2 - 1);
      return ret;
    }
    if (val3) {
      int ret = lg2(val3 ^ (val3 & (val3 - 1))) + 100 + 1;
      val3 &= (val3 - 1);
      return ret;
    }
    if (val4) {
      int ret = lg2(val4 ^ (val4 & (val4 - 1))) + 150 + 1;
      val4 &= (val4 - 1);
      return ret;
    }
    return 0;
  }
  inline void set(int x) {
    x--;
    if (x < 50) {
      val1 |= 1ll << x;
    } else {
      if (x < 100) {
        x -= 50;
        val2 |= 1ll << x;
      } else {
        if (x < 150) {
          x -= 100;
          val3 |= 1ll << x;
        } else {
          x -= 150;
          val4 |= 1ll << x;
        }
      }
    }
  }
  inline void unset(int x) {
    x--;
    if (x < 50) {
      val1 ^= (1ll << x);
    } else {
      if (x < 100) {
        x -= 50;
        val2 ^= (1ll << x);
      } else {
        if (x < 150) {
          x -= 100;
          val3 ^= (1ll << x);
        } else {
          x -= 150;
          val4 ^= (1ll << x);
        }
      }
    }
  }
};
bitset_ g_[MAXN];
int n, m;
bool check() {
  bitset_ unv;
  for (int i = 2; i <= n; ++i) {
    unv.set(i);
  }
  queue<int> q;
  q.push(1);
  int Cnt = 0;
  while (!q.empty()) {
    Cnt++;
    int now = q.front();
    q.pop();
    bitset_ nex = unv & g_[now];
    unv = unv ^ nex;
    while (true) {
      int nx = nex.low_bit();
      if (!nx) break;
      q.push(nx);
    }
  }
  return Cnt == n;
}
unsigned long long rest = (unsigned long long)2000000000000000011;
vector<pair<pair<int, int>, pair<int, int>>> e1, e2;
bool cmp(pair<pair<int, int>, pair<int, int>> A,
         pair<pair<int, int>, pair<int, int>> B) {
  return A.second.first < B.second.first;
}
bool cmp2(pair<pair<int, int>, pair<int, int>> A,
          pair<pair<int, int>, pair<int, int>> B) {
  return A.second.second < B.second.second;
}
bool try_erase(int x, int go) {
  int u, v;
  u = e2[x].first.first;
  v = e2[x].first.second;
  if (e2[x].second.first > go) {
    return true;
  }
  cnt[u][v]--;
  cnt[v][u]--;
  if (cnt[u][v] == 0) {
    g_[u].unset(v);
    g_[v].unset(u);
  }
  if (check()) return true;
  cnt[u][v]++;
  cnt[v][u]++;
  g_[u].set(v);
  g_[v].set(u);
  return false;
}
void add(int u, int v) {
  cnt[u][v]++;
  cnt[v][u]++;
  g_[u].set(v);
  g_[v].set(u);
}
int main() {
  scanf("%d%d", &n, &m);
  int g, s;
  scanf("%d%d", &g, &s);
  for (int i = 1; i <= m; ++i) {
    int u, v, gi, si;
    scanf("%d%d%d%d", &u, &v, &gi, &si);
    if (u == v) {
      i--;
      m--;
      continue;
    }
    e1.push_back(make_pair(make_pair(u, v), make_pair(gi, si)));
    e2.push_back(make_pair(make_pair(u, v), make_pair(gi, si)));
  }
  sort(e1.begin(), e1.end(), cmp);
  sort(e2.begin(), e2.end(), cmp2);
  int t = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      q;
  for (auto it : e2) {
    int u, v;
    u = it.first.first;
    v = it.first.second;
    q.push(make_pair(it.second.first, t++));
  }
  t--;
  for (auto it : e1) {
    while (!q.empty()) {
      pair<int, int> now = q.top();
      q.pop();
      if (now.second <= t) {
        if (now.first <= it.second.first)
          add(e2[now.second].first.first, e2[now.second].first.second);
        else {
          q.push(now);
          break;
        }
      }
    }
    if (check()) {
      while (t >= 0 && try_erase(t, it.second.first)) {
        t--;
      }
      rest = min(rest, (unsigned long long)1 * it.second.first * g +
                           (unsigned long long)1 * e2[t].second.second * s);
    }
  }
  if (rest == (unsigned long long)2000000000000000011) {
    cout << -1 << endl;
    return 0;
  }
  cout << rest << endl;
  return 0;
}
