#include <bits/stdc++.h>
const int INF = 0x3f3f3f3f;
const int kN = 70;
int n, m, A, B;
std::vector<std::pair<int, int>> edges[kN];
int dsu[kN], cnt[kN];
int idx[kN];
int dis[kN][1 << 18];
int find(int x) { return x == dsu[x] ? x : dsu[x] = find(dsu[x]); }
int main() {
  scanf("%d%d%d%d", &n, &m, &A, &B);
  std::iota(dsu, dsu + n, 0);
  std::fill(cnt, cnt + n, 1);
  for (int i = 0; i < m; ++i) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    --a;
    --b;
    edges[a].emplace_back(b, c);
    edges[b].emplace_back(a, c);
    if (c == A) {
      int aa = find(a);
      int bb = find(b);
      if (aa != bb) {
        cnt[aa] += cnt[bb];
        dsu[bb] = aa;
      }
    }
  }
  std::fill(idx, idx + n, -1);
  int tot = 0;
  for (int i = 0; i < n; ++i)
    if (find(i) == i) {
      if (cnt[i] >= 4) idx[i] = tot++;
    }
  memset(dis, INF, sizeof(dis));
  using Node = std::tuple<int, int, int>;
  std::priority_queue<Node> pq;
  if (idx[find(0)] == -1) {
    dis[0][0] = 0;
    pq.emplace(0, 0, 0);
  } else {
    int mask = 1 << idx[find(0)];
    dis[0][mask] = 0;
    pq.emplace(0, 0, mask);
  }
  while (!pq.empty()) {
    int tmp, u, mask;
    std::tie(tmp, u, mask) = pq.top();
    pq.pop();
    if (-tmp != dis[u][mask]) continue;
    for (auto t : edges[u]) {
      int v, c;
      std::tie(v, c) = t;
      int vmask = mask;
      int vid = idx[find(v)];
      if (c == B && find(u) == find(v)) continue;
      if (vid != -1) {
        if ((mask >> vid & 1) && c == B) continue;
        vmask |= 1 << vid;
      }
      if (dis[v][vmask] > dis[u][mask] + c) {
        dis[v][vmask] = dis[u][mask] + c;
        pq.emplace(-dis[v][vmask], v, vmask);
      }
    }
  }
  for (int u = 0; u < n; ++u) {
    int result = INF;
    for (int mask = 0; mask < 1 << tot; ++mask) {
      result = std::min(result, dis[u][mask]);
    }
    printf("%d ", result);
  }
}
