#include <bits/stdc++.h>
using namespace std;
const int MX = 1e5 + 9;
const long long inf = 1e16;
int tot, n, m, st, order, l, r, v, u, vis[MX << 3];
long long w, dis[MX << 3];
int pa[MX], pb[MX];
struct node {
  int l, r;
  int num;
} ta[MX << 2], tb[MX << 2];
struct node1 {
  long long w;
  int v;
  node1(long long _w, int v) : w(_w), v(v) {}
};
priority_queue<pair<long long, int>, vector<pair<long long, int> >,
               greater<pair<long long, int> > >
    que;
vector<node1> ve[MX << 3];
void builda(int k, int l, int r) {
  ta[k].l = l, ta[k].r = r, ta[k].num = ++tot;
  if (l == r) {
    pa[l] = ta[k].num;
    return;
  }
  int mid = (ta[k].l + ta[k].r) >> 1;
  builda(k << 1, l, mid);
  builda(k << 1 | 1, mid + 1, r);
  ve[ta[k << 1].num].push_back(node1(0, ta[k].num));
  ve[ta[k << 1 | 1].num].push_back(node1(0, ta[k].num));
}
void buildb(int k, int l, int r) {
  tb[k].l = l, tb[k].r = r, tb[k].num = ++tot;
  if (l == r) {
    pb[l] = tb[k].num;
    ve[tb[k].num].push_back(node1(0, pa[l]));
    return;
  }
  int mid = (tb[k].l + tb[k].r) >> 1;
  buildb(k << 1, l, mid);
  buildb(k << 1 | 1, mid + 1, r);
  ve[tb[k].num].push_back(node1(0, tb[k << 1].num));
  ve[tb[k].num].push_back(node1(0, tb[k << 1 | 1].num));
}
void updateb(int k, int L, int R, int num, long long w) {
  if (L <= tb[k].l && tb[k].r <= R) {
    ve[num].push_back(node1(w, tb[k].num));
    return;
  }
  int mid = (tb[k].l + tb[k].r) >> 1;
  if (L <= mid) updateb(k << 1, L, R, num, w);
  if (mid < R) updateb(k << 1 | 1, L, R, num, w);
}
void updatea(int k, int L, int R, int num, long long w) {
  if (L <= ta[k].l && ta[k].r <= R) {
    ve[ta[k].num].push_back(node1(w, num));
    return;
  }
  int mid = (ta[k].l + ta[k].r) >> 1;
  if (L <= mid) updatea(k << 1, L, R, num, w);
  if (mid < R) updatea(k << 1 | 1, L, R, num, w);
}
void dij(int st) {
  for (int i = 1; i < MX << 3; i++) {
    dis[i] = inf;
    vis[i] = 0;
  }
  dis[st] = 0;
  que.push(pair<long long, int>(0, st));
  while (!que.empty()) {
    pair<long long, int> temp = que.top();
    que.pop();
    long long w = temp.first;
    int u = temp.second;
    if (w > dis[u]) continue;
    vis[u] = 1;
    for (int i = 0; i < ve[u].size(); i++) {
      int v = ve[u][i].v;
      if (!vis[v]) {
        if (dis[v] > dis[u] + ve[u][i].w) {
          dis[v] = dis[u] + ve[u][i].w;
          que.push(pair<long long, int>(dis[v], v));
        }
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (dis[pa[i]] == inf) dis[pa[i]] = -1;
    printf("%lld ", dis[pa[i]]);
  }
  return;
}
int main() {
  while (~scanf("%d %d %d", &n, &m, &st)) {
    tot = 0;
    builda(1, 1, n);
    buildb(1, 1, n);
    while (m--) {
      scanf("%d ", &order);
      if (order == 1) {
        scanf("%d %d %lld", &v, &u, &w);
        ve[pa[v]].push_back(node1(w, pb[u]));
      } else if (order == 2) {
        scanf("%d %d %d %lld", &v, &l, &r, &w);
        updateb(1, l, r, pa[v], w);
      } else if (order == 3) {
        scanf("%d %d %d %lld", &v, &l, &r, &w);
        updatea(1, l, r, pb[v], w);
      }
    }
    dij(pa[st]);
  }
  return 0;
}
