#include <bits/stdc++.h>
using namespace std;
const long long KILLED = 2e18, INF = 1e18;
const int N = 100010;
vector<pair<pair<int, int>, int> > edges[N];
long long ans[N];
struct SegmentTree {
  pair<long long, int> t[4 * N];
  long long add[4 * N];
  void build(int v, int tl, int tr) {
    add[v] = INF;
    if (tl == tr) {
      t[v] = {INF, tl};
      return;
    }
    int tm = (tl + tr) >> 1;
    build(v * 2, tl, tm);
    build(v * 2 + 1, tm + 1, tr);
    t[v] = min(t[v * 2], t[v * 2 + 1]);
  }
  void change(int v, long long val) {
    if (t[v].first == KILLED) {
      return;
    }
    if (val == KILLED) {
      t[v].first = KILLED;
      return;
    }
    add[v] = min(add[v], val);
    t[v].first = min(t[v].first, val);
  }
  void push(int v) {
    if (t[v].first == KILLED) {
      exit(-1);
    }
    change(v * 2, add[v]);
    change(v * 2 + 1, add[v]);
    add[v] = INF;
  }
  void update(int v, int tl, int tr, int l, int r, long long val) {
    if (l > r) {
      return;
    }
    if (t[v].first == KILLED) return;
    if (tl == l && tr == r) {
      change(v, val);
      return;
    }
    push(v);
    int tm = (tl + tr) >> 1;
    update(v * 2, tl, tm, l, min(r, tm), val);
    update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, val);
    t[v] = min(t[v * 2], t[v * 2 + 1]);
  }
} seg;
struct SegmentTree2 {
  vector<pair<int, int> > t[4 * N];
  void gogo(int v, int tl, int tr, int s) {
    int n = tr;
    while (1) {
      for (auto [to, w] : t[v]) {
        seg.update(1, 1, n, to, to, ans[s] + w);
      }
      t[v].clear();
      if (tl == tr) break;
      int tm = (tl + tr) >> 1;
      if (s <= tm)
        v = v * 2, tr = tm;
      else
        v = v * 2 + 1, tl = tm + 1;
    }
  }
  void update(int v, int tl, int tr, int l, int r, int to, int w) {
    if (l > r) return;
    if (tl == l && tr == r) {
      t[v].push_back({to, w});
      return;
    }
    int tm = (tl + tr) >> 1;
    update(v * 2, tl, tm, l, min(r, tm), to, w);
    update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, to, w);
  }
} segtree;
void solve() {
  int n, q, s;
  cin >> n >> q >> s;
  set<pair<long long, pair<long long, pair<long long, long long> > > > st;
  while (q--) {
    int t;
    cin >> t;
    if (t == 1) {
      int v, u, w;
      cin >> v >> u >> w;
      edges[v].push_back({{u, u}, w});
    } else {
      int v, l, r, w;
      cin >> v >> l >> r >> w;
      if (t == 2) {
        edges[v].push_back({{l, r}, w});
      } else {
        segtree.update(1, 1, n, l, r, v, w);
      }
    }
  }
  seg.build(1, 1, n);
  seg.update(1, 1, n, s, s, 0);
  fill(ans + 1, ans + 1 + n, -1);
  while (1) {
    auto res = seg.t[1];
    if (res.first == KILLED || res.first == INF) break;
    int v = res.second;
    ans[v] = res.first;
    segtree.gogo(1, 1, n, v);
    seg.update(1, 1, n, v, v, KILLED);
    for (auto e : edges[v]) {
      int l = e.first.first, r = e.first.second, w = e.second;
      seg.update(1, 1, n, l, r, ans[v] + w);
    }
    for (auto e : st) {
      int l = e.first, r = e.second.first;
      if (!(l <= v && v <= r)) {
        continue;
      }
      int u = e.second.second.first, w = e.second.second.second;
      seg.update(1, 1, n, u, u, ans[v] + w);
    }
  }
  for (int v = 1; v <= n; v++) {
    cout << ans[v] << " ";
  }
}
int main() {
  ios::sync_with_stdio(NULL), cin.tie(0), cout.tie(0);
  cout.setf(ios::fixed), cout.precision(20);
  solve();
}
