#include <bits/stdc++.h>
using namespace std;
const int N = 20000005, M = 75;
int n, m, a, b, e[M][M], clr[N];
bool vis1[M], vis2[M];
int dfs1(int pos) {
  vis1[pos] = 1;
  int ret = 1;
  for (int i = 1; i <= n; i++)
    if (e[pos][i] == a && !vis1[i]) ret += dfs1(i);
  return ret;
}
void dfs2(int pos, int c) {
  vis2[pos] = 1;
  clr[pos] = c;
  for (int i = 1; i <= n; i++)
    if (e[pos][i] == a && !vis2[i]) dfs2(i, c);
}
inline int id(int x, int y) { return x * n + y - 1; }
int dis[N];
queue<int> q1, q2;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> a >> b;
  for (int i = 1; i <= m; i++) {
    int t1, t2;
    cin >> t1 >> t2;
    cin >> e[t1][t2];
    e[t2][t1] = e[t1][t2];
  }
  int cc = 0;
  for (int i = 1; i <= n; i++)
    if (!vis1[i] && dfs1(i) > 3) dfs2(i, ++cc);
  int tmp = cc;
  memset(vis1, 0, sizeof(vis1));
  for (int i = 1; i <= n; i++)
    if (!vis1[i] && dfs1(i) <= 3) dfs2(i, ++cc);
  memset(dis, 63, sizeof(dis));
  dis[id(0, 1)] = 0;
  q1.push(id(0, 1));
  q2.push(id(0, 1));
  while (!q1.empty() || !q2.empty()) {
    int nd;
    if (q1.empty())
      nd = q2.front(), q2.pop();
    else if (q2.empty())
      nd = q1.front(), q1.pop();
    else if (dis[q1.front()] < dis[q2.front()])
      nd = q1.front(), q1.pop();
    else
      nd = q2.front(), q2.pop();
    int x = nd / n, y = nd % n + 1;
    for (int i = 1; i <= n; i++) {
      if (!e[y][i] || (clr[i] <= tmp && (x & (1 << (clr[i] - 1)))) ||
          (clr[i] == clr[y] && e[y][i] == b))
        continue;
      int v;
      if (clr[y] <= tmp && clr[y] != clr[i])
        v = id(x | (1 << (clr[y] - 1)), i);
      else
        v = id(x, i);
      if (dis[v] > dis[nd] + e[y][i]) {
        dis[v] = dis[nd] + e[y][i];
        if (e[y][i] == a)
          q1.push(v);
        else
          q2.push(v);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    int ans = INT_MAX;
    for (int j = 0; j < (1 << tmp); j++) ans = min(ans, dis[id(j, i)]);
    cout << ans << ' ';
  }
  return 0;
}
