#include <bits/stdc++.h>
using namespace std;
int N, M, A, B, cnt;
int Arrive[505], Times, vis[85][131072], dp[85][131072], Used[505], nex[505],
    las[505], qz[505], fa[505], Size[505];
struct Node {
  int Now;
  int Dis;
  int S;
};
bool operator<(Node a, Node b) { return a.Dis > b.Dis; }
priority_queue<Node> bfs;
void jt(int x, int y, int z) {
  cnt++;
  nex[cnt] = las[x];
  las[x] = cnt;
  Arrive[cnt] = y;
  qz[cnt] = z;
}
int GetFather(int x) {
  if (fa[x] != x)
    return fa[x] = GetFather(fa[x]);
  else
    return x;
}
void Merge(int x, int y) {
  int fx = GetFather(x), fy = GetFather(y);
  fa[fy] = fx;
  Size[fx] += Size[fy];
}
int main() {
  scanf("%d%d%d%d", &N, &M, &A, &B);
  for (int i = 1; i <= N; i++) fa[i] = i, Size[i] = 1, Used[i] = -1;
  for (int i = 1; i <= M; i++) {
    int x, y, w;
    scanf("%d%d%d", &x, &y, &w);
    if (w == A) Merge(x, y);
    jt(x, y, w);
    jt(y, x, w);
  }
  for (int i = 1; i <= N; i++) {
    if (Used[i] == -1 && Size[GetFather(i)] > 3) {
      for (int j = 1; j <= N; j++)
        if (GetFather(i) == GetFather(j)) Used[j] = Times;
      Times++;
    }
  }
  memset(dp, 63, sizeof(dp));
  Node a;
  if (Used[1] != -1)
    a.S = 1 << Used[1];
  else
    a.S = 0;
  a.Dis = 0;
  a.Now = 1;
  dp[a.Now][a.S] = 0;
  bfs.push(a);
  while (!bfs.empty()) {
    Node qwq;
    qwq = bfs.top();
    bfs.pop();
    if (vis[qwq.Now][qwq.S]) continue;
    vis[qwq.Now][qwq.S] = true;
    for (int i = las[qwq.Now]; i; i = nex[i]) {
      if (qz[i] == A) {
        if (dp[Arrive[i]][qwq.S] > dp[qwq.Now][qwq.S] + qz[i]) {
          dp[Arrive[i]][qwq.S] = dp[qwq.Now][qwq.S] + qz[i];
          Node New;
          New.Dis = dp[Arrive[i]][qwq.S];
          New.S = qwq.S;
          New.Now = Arrive[i];
          bfs.push(New);
        }
        continue;
      }
      if (GetFather(qwq.Now) == GetFather(Arrive[i])) continue;
      if (Used[Arrive[i]] != -1 && (qwq.S & (1 << Used[Arrive[i]]))) continue;
      int Nzt;
      if (Used[Arrive[i]] != -1)
        Nzt = 1 << Used[Arrive[i]];
      else
        Nzt = 0;
      Nzt = qwq.S | Nzt;
      Node New;
      if (dp[Arrive[i]][Nzt] > dp[qwq.Now][qwq.S] + qz[i]) {
        dp[Arrive[i]][Nzt] = dp[qwq.Now][qwq.S] + qz[i];
        New.S = Nzt;
        New.Dis = dp[Arrive[i]][Nzt];
        New.Now = Arrive[i];
        bfs.push(New);
      }
    }
  }
  for (int i = 1; i <= N; i++) {
    int ans = 1 << 30;
    for (int j = 0; j < 1 << Times; j++) ans = min(ans, dp[i][j]);
    printf("%d ", ans);
  }
  return 0;
}
