#include <bits/stdc++.h>
using namespace std;
long long read() {
  long long x = 0, f = 1;
  char ch;
  while (!isdigit(ch = getchar())) (ch == '-') && (f = -f);
  for (x = ch ^ 48; isdigit(ch = getchar());
       x = (x << 3) + (x << 1) + (ch ^ 48))
    ;
  return x * f;
}
const int N = 3e5 + 5;
const int M = 1e5 + 5;
const long long inf = 1e10 + 5;
int head[N * 20], ncnt, cnt, n, m, s, rt1, rt2;
bool vis[N];
long long dis[N];
struct segtree {
  int ls, rs;
} tr[N * 20];
struct edge {
  int to, val, nxt;
} e[M * 20];
void add(int u, int v, int w) {
  cnt++;
  e[cnt].to = v;
  e[cnt].val = w;
  e[cnt].nxt = head[u];
  head[u] = cnt;
}
void build_out(int &o, int l, int r) {
  if (l == r) {
    o = l;
    return;
  }
  o = ++ncnt;
  build_out((tr[o].ls), l, ((l + r) >> 1));
  build_out((tr[o].rs), ((l + r) >> 1) + 1, r);
  add(o, (tr[o].ls), 0);
  add(o, (tr[o].rs), 0);
}
void build_in(int &o, int l, int r) {
  if (l == r) {
    o = l;
    return;
  }
  o = ++ncnt;
  build_in((tr[o].ls), l, ((l + r) >> 1));
  build_in((tr[o].rs), ((l + r) >> 1) + 1, r);
  add((tr[o].ls), o, 0);
  add((tr[o].rs), o, 0);
}
void update(int o, int l, int r, int x, int y, int f, int val, int type) {
  if (x <= l && r <= y) {
    type == 2 ? add(f, o, val) : add(o, f, val);
    return;
  }
  if (x <= ((l + r) >> 1))
    update((tr[o].ls), l, ((l + r) >> 1), x, y, f, val, type);
  if (y > ((l + r) >> 1))
    update((tr[o].rs), ((l + r) >> 1) + 1, r, x, y, f, val, type);
}
void dij(int s) {
  priority_queue<pair<long long, int>, vector<pair<long long, int> >,
                 greater<pair<long long, int> > >
      q;
  for (int i = 1; i < N; i++) dis[i] = inf;
  dis[s] = 0;
  q.push(make_pair(0, s));
  while (!q.empty()) {
    int now = q.top().second;
    q.pop();
    if (vis[now]) continue;
    vis[now] = 1;
    for (int i = head[now]; i; i = e[i].nxt) {
      int to = e[i].to;
      if (dis[to] > dis[now] + e[i].val) {
        dis[to] = dis[now] + e[i].val;
        q.push(make_pair(dis[to], to));
      }
    }
  }
}
int main() {
  n = read();
  m = read();
  s = read();
  ncnt = n;
  build_out(rt1, 1, n);
  build_in(rt2, 1, n);
  for (int i = 1, opt, f, t, val, l, r; i <= m; i++) {
    opt = read();
    if (opt == 1) {
      f = read();
      t = read();
      val = read();
      add(f, t, val);
    } else {
      f = read();
      l = read();
      r = read();
      val = read();
      update(opt == 2 ? rt1 : rt2, 1, n, l, r, f, val, opt);
    }
  }
  dij(s);
  for (int i = 1; i <= n; i++) {
    printf("%lld ", dis[i] < inf ? dis[i] : -1);
  }
  return 0;
}
