#include <bits/stdc++.h>
using namespace std;
long long d[1000006], t1[400005], t2[400005];
vector<pair<long long, long long> > g[1000006];
long long NMAX = 1e18, timer;
void build1(int v, int L, int R) {
  if (L == R) {
    t1[v] = L;
  } else {
    t1[v] = timer++;
    int M = (L + R) / 2;
    build1(v * 2, L, M);
    build1(v * 2 + 1, M + 1, R);
    g[t1[v]].push_back({t1[2 * v], 0});
    g[t1[v]].push_back({t1[2 * v + 1], 0});
  }
}
void build2(int v, int L, int R) {
  if (L == R) {
    t2[v] = L;
  } else {
    t2[v] = timer++;
    int M = (L + R) / 2;
    build2(v * 2, L, M);
    build2(v * 2 + 1, M + 1, R);
    g[t2[2 * v]].push_back({t2[v], 0});
    g[t2[2 * v + 1]].push_back({t2[v], 0});
  }
}
void update1(int v, int L, int R, int l, int r, int V, int w) {
  if (l > r) return;
  if (l == L && R == r) {
    g[V].push_back({t1[v], w});
  } else {
    int M = (L + R) / 2;
    update1(2 * v, L, M, l, min(M, r), V, w);
    update1(2 * v + 1, M + 1, R, max(M + 1, l), r, V, w);
  }
}
void update2(int v, int L, int R, int l, int r, int V, int w) {
  if (l > r) return;
  if (l == L && R == r) {
    g[t2[v]].push_back({V, w});
  } else {
    int M = (L + R) / 2;
    update2(2 * v, L, M, l, min(M, r), V, w);
    update2(2 * v + 1, M + 1, R, max(M + 1, l), r, V, w);
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  fill(d, d + 400005, NMAX);
  long long n, Q, second;
  cin >> n >> Q >> second;
  timer = n + 1;
  build1(1, 1, n);
  build2(1, 1, n);
  while (Q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int v, u, w;
      cin >> v >> u >> w;
      g[v].push_back({u, w});
    } else if (type == 2) {
      long long v, l, r, w;
      cin >> v >> l >> r >> w;
      update1(1, 1, n, l, r, v, w);
    } else {
      long long v, l, r, w;
      cin >> v >> l >> r >> w;
      update2(1, 1, n, l, r, v, w);
    }
  }
  set<pair<long long, long long> > q;
  d[second] = 0;
  q.insert({d[second], second});
  while (!q.empty()) {
    int v = (*q.begin()).second;
    q.erase({d[v], v});
    for (auto i : g[v]) {
      long long to = i.first;
      long long w = i.second;
      if (d[to] > d[v] + w) {
        q.erase({d[to], to});
        d[to] = d[v] + w;
        q.insert({d[to], to});
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    if (d[i] == NMAX)
      cout << "-1 ";
    else
      cout << d[i] << ' ';
  }
}
