#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 1e5 + 5, inf = 0x3f3f3f3f3f3f3f3f;
struct Edge {
  int to, prev, dist;
} ed[MAXN * 20];
struct Tuple {
  long long x, y;
  inline bool operator<(const Tuple &rhs) const { return this->x > rhs.x; }
};
priority_queue<Tuple> pq;
int cnt, nc, tot, rt, rtx, qcnt, src, op, x, y, l, r, dist;
int last[MAXN << 2], inQueue[MAXN << 2], ls[MAXN << 2], rs[MAXN << 2];
long long dis[MAXN << 2];
inline int read() {
  int res = 0, fh = 1;
  char ch = getchar();
  while ((ch > '9' || ch < '0') && ch != '-') ch = getchar();
  if (ch == '-') fh = -1, ch = getchar();
  while (ch >= '0' && ch <= '9') res = res * 10 + ch - '0', ch = getchar();
  return fh * res;
}
inline void addEdge(int from, int to, int dist) {
  ed[++tot].prev = last[from];
  ed[tot].to = to;
  ed[tot].dist = dist;
  last[from] = tot;
  return;
}
inline int createDown(int l, int r) {
  if (l == r) return l;
  int mid = (l + r) >> 1, cur = ++nc;
  ls[cur] = createDown(l, mid), rs[cur] = createDown(mid + 1, r);
  addEdge(cur, ls[cur], 0), addEdge(cur, rs[cur], 0);
  return cur;
}
inline int createUp(int l, int r) {
  if (l == r) return l;
  int mid = (l + r) >> 1, cur = ++nc;
  ls[cur] = createUp(l, mid), rs[cur] = createUp(mid + 1, r);
  addEdge(ls[cur], cur, 0), addEdge(rs[cur], cur, 0);
  return cur;
}
int lx, rx;
inline void link(int l, int r, int x, int dist, int node, int type) {
  if (lx <= l && rx >= r) {
    type ? addEdge(node, x, dist) : addEdge(x, node, dist);
    return;
  }
  int mid = (l + r) >> 1;
  if (lx <= mid) link(l, mid, x, dist, ls[node], type);
  if (rx > mid) link(mid + 1, r, x, dist, rs[node], type);
  return;
}
inline void Dij(int src) {
  int top;
  dis[src] = 0, inQueue[src] = 1, pq.push((Tuple){0, src});
  while (!pq.empty()) {
    top = pq.top().y, pq.pop(), inQueue[top] = 0;
    for (int i = last[top]; i; i = ed[i].prev) {
      if (dis[ed[i].to] > dis[top] + ed[i].dist) {
        dis[ed[i].to] = dis[top] + ed[i].dist;
        if (!inQueue[ed[i].to]) {
          inQueue[ed[i].to] = 1;
          pq.push((Tuple){dis[ed[i].to], ed[i].to});
        }
      }
    }
  }
  return;
}
int main() {
  cnt = nc = read(), qcnt = read(), src = read();
  rt = nc + 1, createDown(1, cnt), rtx = nc + 1, createUp(1, cnt);
  for (int i = 0; i < qcnt; ++i) {
    op = read();
    if (op == 1) {
      x = read(), y = read(), dist = read(), addEdge(x, y, dist);
      continue;
    }
    x = read(), lx = read(), rx = read(), dist = read();
    link(1, cnt, x, dist, op ^ 3 ? rt : rtx, op - 2);
  }
  memset(dis, 0x3f, sizeof(dis)), Dij(src);
  for (int i = 1; i <= cnt; ++i) printf("%lld ", dis[i] == inf ? -1 : dis[i]);
  printf("\n");
}
