#include <bits/stdc++.h>
using namespace std;
template <typename _T>
inline void read(_T &dig) {
  long long flg;
  char c;
  flg = dig = 0;
  while (c = getchar(), !isdigit(c))
    if (c == '-') flg = 1;
  while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
  if (flg) dig = -dig;
}
template <typename _T, typename... Args>
inline void read(_T &x, Args &...args) {
  read(x);
  read(args...);
}
const long long M = 5e6 + 5, in_t = 1, out_t = 2, N = 1e6 + 5;
long long n, m, tot = 1, head[N], ver[M], nxt[M], ed[M], cnt, ls[N], rs[N],
                in_n[N], out_n[N], dis[N], vis[N];
void add(long long u, long long v, long long val) {
  nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, ed[tot] = val;
}
void build(long long x, long long y, long long l, long long r) {
  if (l == r) {
    add(x, y, 0);
    in_n[l] = x, out_n[l] = y;
    return;
  }
  ls[x] = ++cnt, rs[x] = ++cnt;
  ls[y] = ++cnt, rs[y] = ++cnt;
  add(x, ls[x], 0), add(x, rs[x], 0);
  add(ls[y], y, 0), add(rs[y], y, 0);
  build(ls[x], ls[y], l, (l + r) >> 1);
  build(rs[x], rs[y], (l + r) / 2 + 1, r);
}
void new_edge_x(long long x, long long p, long long l, long long r,
                long long ql, long long qr) {
  if (ql <= l && r <= qr) {
    add(p, x, 0);
    return;
  }
  long long mid = (l + r) >> 1;
  if (ql <= mid) new_edge_x(ls[x], p, l, mid, ql, qr);
  if (qr > mid) new_edge_x(rs[x], p, mid + 1, r, ql, qr);
}
void new_edge_y(long long y, long long p, long long l, long long r,
                long long ql, long long qr, long long v) {
  if (ql <= l && r <= qr) {
    add(y, p, v);
    return;
  }
  long long mid = (l + r) >> 1;
  if (ql <= mid) new_edge_y(ls[y], p, l, mid, ql, qr, v);
  if (qr > mid) new_edge_y(rs[y], p, mid + 1, r, ql, qr, v);
}
struct nd {
  long long id, v;
  friend bool operator<(nd a, nd b) { return a.v > b.v; }
};
priority_queue<nd> q;
signed main() {
  long long s;
  read(n, m, s);
  cnt = 2;
  build(in_t, out_t, 1, n);
  long long opt, u, v, val, l;
  while (m--) {
    read(opt);
    if (opt == 1) {
      read(u, v, val);
      add(out_n[u], in_n[v], val);
    } else if (opt == 2) {
      read(l, u, v, val);
      ++cnt;
      add(out_n[l], cnt, val);
      new_edge_x(in_t, cnt, 1, n, u, v);
    } else {
      read(l, u, v, val);
      ++cnt;
      add(cnt, in_n[l], 0);
      new_edge_y(out_t, cnt, 1, n, u, v, val);
    }
  }
  memset(dis, 0x3f, sizeof(dis));
  dis[in_n[s]] = 0, q.push((nd){in_n[s], 0});
  while (q.size()) {
    long long x = q.top().id;
    q.pop();
    if (vis[x]) continue;
    vis[x] = 1;
    for (long long i = head[x], y = ver[i]; i; i = nxt[i], y = ver[i])
      if (dis[x] + ed[i] < dis[y])
        dis[y] = dis[x] + ed[i], q.push((nd){y, dis[y]});
  }
  for (long long i = (1); i <= (n); ++i)
    printf("%lld ", vis[in_n[i]] ? dis[in_n[i]] : -1);
  return 0;
}
