#include <bits/stdc++.h>
const int MARX = 3e5 + 10;
const long long INF = 0x3f3f3f3f3f3f3f3f;
struct edge {
  int u, v, w, ne;
} e[MARX << 4];
int n, q, start;
std::queue<int> qu;
int num, head[MARX];
int cnt, root1, root2, ls[MARX], rs[MARX];
long long dis[MARX];
inline void add(int u, int v, int w) {
  e[++num].v = v, e[num].u = u, e[num].w = w;
  e[num].ne = head[u], head[u] = num;
}
void build1(int &s, int l, int r) {
  if (l == r) {
    s = l;
    return;
  }
  s = ++cnt;
  int mid = (l + r) >> 1;
  build1(ls[s], l, mid);
  build1(rs[s], mid + 1, r);
  add(s, ls[s], 0);
  add(s, rs[s], 0);
}
void build2(int &s, int l, int r) {
  if (l == r) {
    s = l;
    return;
  }
  s = ++cnt;
  int mid = (l + r) >> 1;
  build2(ls[s], l, mid);
  build2(rs[s], mid + 1, r);
  add(ls[s], s, 0);
  add(rs[s], s, 0);
}
int L, R;
void updata(int s, int l, int r, int u, int w, int type) {
  if (L <= l && r <= R) {
    if (type == 2)
      add(u, s, w);
    else
      add(s, u, w);
    return;
  }
  int mid = (l + r) >> 1;
  if (L <= mid) updata(ls[s], l, mid, u, w, type);
  if (mid < R) updata(rs[s], mid + 1, r, u, w, type);
}
void spfa(int start) {
  memset(dis, 0x3f, sizeof(dis));
  dis[start] = 0;
  qu.push(start);
  while (!qu.empty()) {
    int u = qu.front();
    qu.pop();
    for (int i = head[u]; i; i = e[i].ne) {
      int v = e[i].v, w = e[i].w;
      if (dis[u] + w < dis[v]) {
        dis[v] = dis[u] + w;
        qu.push(v);
      }
    }
  }
}
signed main() {
  scanf("%d%d%d", &n, &q, &start);
  cnt = n;
  build1(root1, 1, n), build2(root2, 1, n);
  for (int i = 1; i <= q; i++) {
    int opt, u, v, w;
    scanf("%d", &opt);
    if (opt == 1) {
      scanf("%d%d%d", &u, &v, &w);
      add(u, v, w);
    } else {
      scanf("%d%d%d%d", &u, &L, &R, &w);
      updata((opt == 2 ? root1 : root2), 1, n, u, w, opt);
    }
  }
  spfa(start);
  for (int i = 1; i <= n; i++) printf("%lld ", dis[i] < INF ? dis[i] : -1);
}
