#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  return x * f;
}
const long long N = 2e6 + 10, M = N * 2, inf = 0x7f7f7f7f7f7f7f7f;
int n, q, s, tot;
int h[N], e[M], ne[M], idx;
long long w[M];
long long d[N];
bool st[N];
void init() {
  memset(h, -1, sizeof(h));
  idx = 0;
  tot = n;
}
void add(long long a, long long b, long long c) {
  e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
struct Node {
  int l, r, in, out;
} tr[N];
void build(long long u, long long l, long long r) {
  tr[u].l = l, tr[u].r = r;
  if (l == r)
    tr[u].in = r, tr[u].out = r;
  else {
    long long mid = (l + r) >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    tr[u].in = ++tot, tr[u].out = ++tot;
    add(tr[u].in, tr[u << 1].in, 0);
    add(tr[u].in, tr[u << 1 | 1].in, 0);
    add(tr[u << 1].out, tr[u].out, 0);
    add(tr[u << 1 | 1].out, tr[u].out, 0);
  }
}
void updatein(long long u, long long l, long long r, long long from,
              long long w) {
  if (l <= tr[u].l && tr[u].r <= r) {
    add(from, tr[u].in, w);
    return;
  } else {
    long long mid = (tr[u].l + tr[u].r) >> 1;
    if (l <= mid) updatein(u << 1, l, r, from, w);
    if (r > mid) updatein(u << 1 | 1, l, r, from, w);
    return;
  }
}
void updateout(long long u, long long l, long long r, long long to,
               long long w) {
  if (l <= tr[u].l && tr[u].r <= r) {
    add(tr[u].out, to, w);
    return;
  } else {
    long long mid = (tr[u].l + tr[u].r) >> 1;
    if (l <= mid) updateout(u << 1, l, r, to, w);
    if (r > mid) updateout(u << 1 | 1, l, r, to, w);
    return;
  }
}
void f1() {
  long long v, u, w;
  v = read();
  u = read();
  w = read();
  add(v, u, w);
}
void f2() {
  long long v, l, r, w;
  v = read();
  l = read();
  r = read();
  w = read();
  updatein(1, l, r, v, w);
}
void f3() {
  long long v, l, r, w;
  v = read();
  l = read();
  r = read();
  w = read();
  updateout(1, l, r, v, w);
}
void dijkstra(long long u) {
  memset(d, inf, sizeof(d));
  memset(st, 0, sizeof(st));
  priority_queue<pair<long long, long long>,
                 vector<pair<long long, long long> >,
                 greater<pair<long long, long long> > >
      heap;
  d[u] = 0;
  heap.push({0, u});
  while (heap.size()) {
    long long t = heap.top().second;
    heap.pop();
    if (st[t]) continue;
    st[t] = 1;
    for (long long i = h[t]; ~i; i = ne[i]) {
      long long j = e[i];
      if (d[j] > d[t] + w[i]) {
        d[j] = d[t] + w[i];
        heap.push({d[j], j});
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  n = read();
  q = read();
  s = read();
  init();
  build(1, 1, n);
  while (q--) {
    long long t;
    t = read();
    if (t == 1)
      f1();
    else if (t == 2)
      f2();
    else if (t == 3)
      f3();
  }
  dijkstra(s);
  for (long long i = 1; i <= n; i++)
    if (d[i] >= inf / 2)
      cout << -1 << " ";
    else
      cout << d[i] << " ";
  return 0;
}
