#include <bits/stdc++.h>
using namespace std;
template <typename T>
T MAX(T a, T b) {
  return (a > b) ? a : b;
}
template <typename T>
T MIN(T a, T b) {
  return (a < b) ? a : b;
}
template <typename T>
void UMAX(T &a, T b) {
  a = (a > b ? a : b);
}
template <typename T>
void UMIN(T &a, T b) {
  a = (a < b ? a : b);
}
int readint() {
  char c = getchar();
  int ret = 0;
  while (!(c >= '0' && c <= '9')) c = getchar();
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return ret;
}
void putint(int v) {
  if (!v) {
    putchar('0');
    return;
  }
  if (v >= 10) putint(v / 10);
  putchar('0' + (v % 10));
}
int n, m, a, b;
namespace DSU {
int fa[75];
void init() {
  int i;
  for (i = 0; i < n; ++i) fa[i] = i;
}
int anc(int x) { return (fa[x] == x ? x : (fa[x] = anc(fa[x]))); }
void unite(int x, int y) { fa[anc(x)] = anc(y); }
}  // namespace DSU
vector<pair<int, int> > adj[75], ng[75];
vector<int> comps[75];
int cct, id_of_c[75], id_in_c[75], acct, acid[75];
int cd[75], dist[131072][75], tmp[75];
void dijk(vector<pair<int, int> > *G, int *dist, int sz) {
  int i;
  priority_queue<pair<int, int> > pq;
  for (i = 0; i < sz; ++i) {
    if (dist[i] < (int)1e9) pq.push(make_pair(-dist[i], i));
  }
  while (!pq.empty()) {
    int cv = pq.top().second;
    int cw = -pq.top().first;
    pq.pop();
    if (cw != dist[cv]) continue;
    for (i = 0; i < (int)G[cv].size(); ++i) {
      int u = G[cv][i].first, w = G[cv][i].second;
      if (cw + w < dist[u]) {
        dist[u] = cw + w;
        pq.push(make_pair(-dist[u], u));
      }
    }
  }
}
int main() {
  int i, j, k;
  scanf("%d%d%d%d", &n, &m, &a, &b);
  DSU::init();
  for (i = 0; i < m; ++i) {
    int u, v, c;
    scanf("%d%d%d", &u, &v, &c);
    --u;
    --v;
    adj[u].push_back(make_pair(v, c));
    adj[v].push_back(make_pair(u, c));
    if (c == a) DSU::unite(u, v);
  }
  for (i = 0; i < n; ++i) {
    if (DSU::fa[i] == i) {
      id_of_c[i] = cct++;
    }
  }
  for (i = 0; i < n; ++i) {
    int f = DSU::anc(i), d = id_of_c[f];
    id_in_c[i] = (int)comps[d].size();
    comps[d].push_back(i);
    id_of_c[i] = d;
  }
  for (i = 0; i < cct; ++i) {
    if (comps[i].size() >= 4) {
      cd[i] = (1 << acct);
      acid[i] = acct++;
    } else
      acid[i] = -1, cd[i] = 0;
  }
  for (i = 0; i < (1 << acct); ++i) {
    fill(dist[i], dist[i] + n, (int)1e9);
  }
  dist[cd[id_of_c[0]]][0] = 0;
  for (i = 0; i < (1 << acct); ++i) {
    for (j = 0; j < n; ++j) {
      if (dist[i][j] < (int)1e9) break;
    }
    if (j == n) continue;
    for (j = 0; j < n; ++j) {
      ng[j].clear();
      if ((i & cd[id_of_c[j]]) != cd[id_of_c[j]]) continue;
      for (k = 0; k < (int)adj[j].size(); ++k) {
        int v = adj[j][k].first, w = adj[j][k].second;
        if ((id_of_c[v] == id_of_c[j] && w == a) ||
            (id_of_c[v] != id_of_c[j] && !cd[id_of_c[v]]))
          ng[j].push_back(make_pair(v, w));
      }
    }
    dijk(ng, dist[i], n);
    for (j = 0; j < n; ++j) {
      if (dist[i][j] == (int)1e9) continue;
      for (k = 0; k < (int)adj[j].size(); ++k) {
        int v = adj[j][k].first, w = adj[j][k].second, d = cd[id_of_c[v]];
        if (!(i & d) && id_of_c[v] != id_of_c[j])
          UMIN(dist[i | d][v], dist[i][j] + w);
      }
    }
  }
  for (i = 0; i < n; ++i) {
    int res = (int)1e9;
    for (j = 0; j < (1 << acct); ++j) {
      UMIN(res, dist[j][i]);
    }
    printf("%d ", res);
  }
  printf("\n");
  return 0;
}
