#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e6 + 5;
const long long inf = 0x3f3f3f3f3f3f3f3f;
int n, q, s, maxo;
long long dis[maxn];
int head[maxn];
bool vis[maxn];
int cnt;
struct edge {
  int to, next;
  long long dis;
} e[maxn];
struct node {
  int pos;
  long long dis;
  bool operator<(const node &x) const { return dis > x.dis; }
};
inline void addedge(int u, int v, long long w) {
  cnt++;
  e[cnt].to = v;
  e[cnt].dis = w;
  e[cnt].next = head[u];
  head[u] = cnt;
}
inline void build1(int o, int l, int r) {
  maxo = max(maxo, o);
  if (l == r) {
    addedge(o + n, l, 0);
    return;
  }
  int m = (l + r) >> 1;
  build1(o << 1, l, m);
  build1(o << 1 | 1, m + 1, r);
  addedge(o + n, (o << 1) + n, 0);
  addedge(o + n, (o << 1 | 1) + n, 0);
}
inline void build2(int o, int l, int r) {
  if (l == r) {
    addedge(l, o + n + maxo, 0);
    return;
  }
  int m = (l + r) >> 1;
  build2(o << 1, l, m);
  build2(o << 1 | 1, m + 1, r);
  addedge((o << 1) + maxo + n, o + maxo + n, 0);
  addedge((o << 1 | 1) + maxo + n, o + maxo + n, 0);
}
inline void update1(int o, int l, int r, int ql, int qr, long long w, int x) {
  if (ql <= l && r <= qr) {
    addedge(x, o + n, w);
    return;
  }
  int m = (l + r) >> 1;
  if (ql <= m) update1(o << 1, l, m, ql, qr, w, x);
  if (qr > m) update1(o << 1 | 1, m + 1, r, ql, qr, w, x);
}
inline void update2(int o, int l, int r, int ql, int qr, long long w, int x) {
  if (ql <= l && r <= qr) {
    addedge(o + maxo + n, x, w);
    return;
  }
  int m = (l + r) >> 1;
  if (ql <= m) update2(o << 1, l, m, ql, qr, w, x);
  if (qr > m) update2(o << 1 | 1, m + 1, r, ql, qr, w, x);
}
inline void dijkstra() {
  queue<node> q;
  for (int i = 1; i <= 1e6; i++) dis[i] = inf;
  dis[s] = 0;
  q.push({s, 0});
  vis[s] = 1;
  while (!q.empty()) {
    int x = q.front().pos;
    q.pop();
    vis[x] = 0;
    for (int i = head[x]; i; i = e[i].next) {
      if (dis[e[i].to] > dis[x] + e[i].dis) {
        dis[e[i].to] = dis[x] + e[i].dis;
        if (!vis[e[i].to]) {
          vis[e[i].to] = 1;
          q.push({e[i].to, dis[e[i].to]});
        }
      }
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &q, &s);
  build1(1, 1, n);
  build2(1, 1, n);
  while (q--) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int x, y;
      long long w;
      scanf("%d%d%lld", &x, &y, &w);
      if (x != y) addedge(x, y, w);
    }
    if (op == 2) {
      int x, l, r;
      long long w;
      scanf("%d%d%d%lld", &x, &l, &r, &w);
      update1(1, 1, n, l, r, w, x);
    }
    if (op == 3) {
      int x, l, r;
      long long w;
      scanf("%d%d%d%lld", &x, &l, &r, &w);
      update2(1, 1, n, l, r, w, x);
    }
  }
  dijkstra();
  for (int i = 1; i <= n; i++) printf("%lld ", dis[i] == inf ? -1 : dis[i]);
  puts("");
  return 0;
}
