#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const long long int INF = 1e18;
const int mod = 1e9 + 7;
const int maxn = 6e5 + 5;
const int maxm = 3e6 + 5;
struct node {
  int to, next;
  long long int w;
  bool operator<(const node &_) const { return w < _.w; }
} e[maxm];
int n, q, s, idx;
int head[maxn], cnt;
struct Tree {
  int tl, tr, val;
} tree[2][maxn];
void init() {
  memset(head, -1, sizeof(head));
  cnt = 0;
  memset(tree, 0, sizeof(tree));
  idx = n;
}
void add(int u, int v, int w) {
  e[cnt] = node{v, head[u], w};
  head[u] = cnt++;
}
void build(int id, int l, int r, int f) {
  tree[f][id].val = ++idx;
  tree[f][id].tl = l, tree[f][id].tr = r;
  if (l == r) {
    if (!f)
      add(idx, l, 0);
    else
      add(l, idx, 0);
    return;
  }
  int mid = (l + r) >> 1;
  build(id << 1, l, mid, f);
  build(id << 1 | 1, mid + 1, r, f);
  if (!f) {
    add(tree[f][id].val, tree[f][id << 1].val, 0);
    add(tree[f][id].val, tree[f][id << 1 | 1].val, 0);
  } else {
    add(tree[f][id << 1].val, tree[f][id].val, 0);
    add(tree[f][id << 1 | 1].val, tree[f][id].val, 0);
  }
}
vector<int> vs;
void query(int id, int ql, int qr, int f) {
  int l = tree[f][id].tl, r = tree[f][id].tr;
  if (ql <= l && r <= qr) {
    vs.push_back(tree[f][id].val);
    return;
  }
  int mid = (l + r) >> 1;
  if (qr <= mid)
    query(id << 1, ql, qr, f);
  else if (ql > mid)
    query(id << 1 | 1, ql, qr, f);
  else {
    query(id << 1, ql, mid, f);
    query(id << 1 | 1, mid + 1, qr, f);
  }
}
long long int dis[maxn];
bool vis[maxn];
void dij(int st, int ed) {
  priority_queue<node> q;
  for (int i = 1; i <= maxn - 5; i++) {
    dis[i] = INF;
    vis[i] = 0;
  }
  dis[st] = 0;
  q.push(node{st, 0, 0});
  while (!q.empty()) {
    node u = q.top();
    q.pop();
    if (vis[u.to]) continue;
    vis[u.to] = 1;
    for (int i = head[u.to]; ~i; i = e[i].next) {
      int to = e[i].to;
      if (dis[to] > dis[u.to] + e[i].w) {
        dis[to] = dis[u.to] + e[i].w;
        q.push(node{to, 0, -dis[to]});
      }
    }
  }
}
void solve() {
  while (~scanf("%d%d%d", &n, &q, &s)) {
    init();
    build(1, 1, n, 0);
    build(1, 1, n, 1);
    while (q--) {
      int op, u, v, l, r, w;
      scanf("%d%d", &op, &u);
      if (op == 1) {
        scanf("%d%d", &v, &w);
        add(u, v, w);
      } else if (op == 2) {
        scanf("%d%d%d", &l, &r, &w);
        vs.clear();
        query(1, l, r, 0);
        for (int i = 0; i < (int)(vs).size(); i++) {
          add(u, vs[i], w);
        }
      } else {
        scanf("%d%d%d", &l, &r, &w);
        vs.clear();
        query(1, l, r, 1);
        for (int i = 0; i < (int)(vs).size(); i++) {
          add(vs[i], u, w);
        }
      }
    }
    dij(s, n);
    for (int i = 1; i <= n; i++) {
      printf("%lld%c", dis[i] == INF ? -1ll : dis[i], i == n ? '\n' : ' ');
    }
  }
}
int main() {
  int t = 1, cas = 1;
  while (t--) {
    solve();
  }
}
