#include <bits/stdc++.h>
using namespace std;
int n, m, a, b;
int x[205], y[205], c[205], siz[75], ans[75];
int info[75], Prev[205 << 1], to[205 << 1], cst[205 << 1], cnt_e;
void Node(int u, int v, int ct) {
  Prev[++cnt_e] = info[u], info[u] = cnt_e, to[cnt_e] = v, cst[cnt_e] = ct;
}
int F[75], bl[75], cnt;
int Find(int now) {
  return (!F[now] || F[now] == now) ? now : F[now] = Find(F[now]);
}
int dp[1 << 18][75];
int main() {
  scanf("%d%d%d%d", &n, &m, &a, &b);
  for (int i = 1; i <= n; i++) siz[i] = 1;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &x[i], &y[i], &c[i]);
    if (c[i] == a)
      if (Find(x[i]) != Find(y[i])) {
        siz[Find(y[i])] += siz[Find(x[i])];
        F[Find(x[i])] = Find(y[i]);
      }
    Node(x[i], y[i], c[i]), Node(y[i], x[i], c[i]);
  }
  for (int i = 1; i <= n; i++)
    if (siz[i] > 3 && Find(i) == i)
      bl[i] = cnt++;
    else if (Find(i) == i)
      bl[i] = -1;
  for (int i = 1; i <= n; i++)
    if (Find(i) != i) bl[i] = bl[Find(i)];
  memset(dp, 0x3f, sizeof dp);
  memset(ans, 0x3f, sizeof ans);
  dp[bl[1] >= 0 ? 1 << bl[1] : 0][1] = 0;
  queue<int> q;
  for (int i = 0; i < (1 << cnt); i++) {
    for (int j = 1; j <= n; j++)
      if (dp[i][j] < 0x3f3f3f3f) q.push(j);
    for (int now; !q.empty();) {
      now = q.front(), q.pop();
      for (int j = info[now]; j; j = Prev[j])
        if (cst[j] == a ||
            (cst[j] == b && bl[to[j]] == -1 && Find(now) != Find(to[j]))) {
          if (dp[i][to[j]] > dp[i][now] + cst[j]) {
            dp[i][to[j]] = dp[i][now] + cst[j];
            q.push(to[j]);
          }
        } else if (Find(now) != Find(to[j]) && !(i >> bl[to[j]] & 1))
          dp[i | (1 << bl[to[j]])][to[j]] =
              min(dp[i | (1 << bl[to[j]])][to[j]], dp[i][now] + cst[j]);
    }
    for (int j = 1; j <= n; j++)
      if (dp[i][j] < 0x3f3f3f3f) ans[j] = min(ans[j], dp[i][j]);
  }
  for (int i = 1; i <= n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
