#include <bits/stdc++.h>
using namespace std;
int n, m, A, B, scc[75], tot[75], fa[75], ans[75], f[75][1 << 16];
int c, To[405], nxt[405], cst[405], Head[75];
bool vis[75][1 << 16];
inline int Read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < 48 || ch > 57) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch > 47 && ch < 58) {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
inline void Write(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) Write(x / 10);
  putchar(48 + x % 10);
}
void ad_ed(int u, int v, int ct) {
  nxt[++c] = Head[u];
  To[c] = v;
  cst[c] = ct;
  Head[u] = c;
}
int Find(int x) {
  if (fa[x] != x) fa[x] = Find(fa[x]);
  return fa[x];
}
void Merge(int x, int y) {
  int rx = Find(x), ry = Find(y);
  if (rx != ry) fa[ry] = rx, tot[rx] += tot[ry];
}
struct info {
  int id, dis, st;
  friend bool operator<(info a, info b) { return a.dis > b.dis; }
};
priority_queue<info> q;
int main() {
  n = Read();
  m = Read();
  A = Read();
  B = Read();
  if (A > B) swap(A, B);
  for (int i = 1; i <= n; i++) fa[i] = i, tot[i] = 1, ans[i] = 0x3f3f3f3f;
  memset(f, 0x3f, sizeof(f));
  for (int i = 1; i <= m; i++) {
    int u = Read(), v = Read(), ct = Read();
    ad_ed(u, v, ct);
    ad_ed(v, u, ct);
    if (ct == A) Merge(u, v);
  }
  int idx = 0;
  for (int i = 1; i <= n; i++)
    if (!scc[i] && tot[Find(i)] > 3) {
      idx++;
      for (int j = 1; j <= n; j++)
        if (Find(j) == Find(i)) scc[j] = idx;
    }
  int beg_st = (!scc[1] ? 0 : 1 << scc[1]);
  f[1][beg_st] = 0;
  q.push(info{1, 0, beg_st});
  while (!q.empty()) {
    info x = q.top();
    q.pop();
    if (vis[x.id][x.st]) continue;
    vis[x.id][x.st] = 1;
    ans[x.id] = min(ans[x.id], x.dis);
    for (int i = Head[x.id]; i; i = nxt[i]) {
      int v = To[i], ct = cst[i];
      if (ct == A) {
        if (f[x.id][x.st] + ct < f[v][x.st]) {
          f[v][x.st] = f[x.id][x.st] + ct;
          q.push(info{v, f[v][x.st], x.st});
        }
      } else if (ct == B) {
        if (Find(x.id) == Find(v)) continue;
        if (scc[v] && ((x.st >> scc[v]) & 1)) continue;
        int net = x.st | (1 << scc[v]);
        if (f[x.id][x.st] + ct < f[v][net]) {
          f[v][net] = f[x.id][x.st] + ct;
          q.push(info{v, f[v][net], net});
        }
      }
    }
  }
  for (int i = 1; i <= n; i++) Write(ans[i]), putchar(' ');
  return 0;
}
