#include <bits/stdc++.h>
using namespace std;
;
const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
long long dis[maxn * 15];
int n, q, s, cnt, op, u, l, r, w, v;
int pp1[maxn], pp2[maxn], vis[maxn * 15];
struct edge {
  int v, w;
};
vector<edge> G[maxn * 15];
struct node {
  int l, r, num;
} segtree[5][maxn << 2];
void build(int rt, int l, int r, int op) {
  segtree[op][rt].l = l, segtree[op][rt].r = r;
  segtree[op][rt].num = ++cnt;
  if (l == r) {
    if (op == 1) {
      pp1[l] = cnt;
    } else {
      pp2[l] = cnt;
      G[pp2[l]].push_back({pp1[l], 0});
    }
    return;
  }
  int mid = (l + r) >> 1;
  build(rt << 1, l, mid, op);
  build(rt << 1 | 1, mid + 1, r, op);
  if (op == 1) {
    G[segtree[op][rt << 1].num].push_back({segtree[op][rt].num, 0});
    G[segtree[op][rt << 1 | 1].num].push_back({segtree[op][rt].num, 0});
  } else {
    G[segtree[op][rt].num].push_back({segtree[op][rt << 1].num, 0});
    G[segtree[op][rt].num].push_back({segtree[op][rt << 1 | 1].num, 0});
  }
}
void update(int rt, int l, int r, int u, int w, int op) {
  if (segtree[op][rt].l == l && segtree[op][rt].r == r) {
    if (op == 1) {
      G[u].push_back({segtree[2][rt].num, w});
    } else {
      G[segtree[1][rt].num].push_back({u, w});
    }
    return;
  }
  int mid = (segtree[op][rt].l + segtree[op][rt].r) >> 1;
  if (r <= mid)
    update(rt << 1, l, r, u, w, op);
  else if (l > mid)
    update(rt << 1 | 1, l, r, u, w, op);
  else {
    update(rt << 1, l, mid, u, w, op);
    update(rt << 1 | 1, mid + 1, r, u, w, op);
  }
}
void dij(int s) {
  for (int i = 1; i <= cnt; ++i) dis[i] = INF;
  dis[pp1[s]] = 0;
  priority_queue<pair<long long, int>, vector<pair<long long, int> >,
                 greater<pair<long long, int> > >
      q;
  q.push({0, pp1[s]});
  while (!q.empty()) {
    int u = q.top().second;
    q.pop();
    if (vis[u]) continue;
    vis[u] = 1;
    int v;
    for (int i = 0; i < (int)G[u].size(); ++i) {
      v = G[u][i].v;
      if (dis[v] > dis[u] + G[u][i].w) {
        dis[v] = dis[u] + G[u][i].w;
        q.push({dis[v], v});
      }
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &q, &s);
  for (int i = 1; i <= 2; ++i) build(1, 1, n, i);
  while (q--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d%d", &u, &v, &w);
      G[pp1[u]].push_back({pp2[v], w});
    } else {
      op--;
      scanf("%d%d%d%d", &u, &l, &r, &w);
      if (op == 1)
        update(1, l, r, pp1[u], w, op);
      else
        update(1, l, r, pp2[u], w, op);
    }
  }
  dij(s);
  for (int i = 1; i <= n; ++i) {
    long long tmp = min(dis[pp1[i]], dis[pp2[i]]);
    if (tmp == INF)
      printf("-1 ");
    else
      printf("%lld ", tmp);
  }
  printf("\n");
  return 0;
}
