#include <bits/stdc++.h>
using namespace std;
const long long UNDEF = -1;
const long long INF = 1e18;
template <typename T>
inline bool chkmax(T &aa, T bb) {
  return aa < bb ? aa = bb, true : false;
}
template <typename T>
inline bool chkmin(T &aa, T bb) {
  return aa > bb ? aa = bb, true : false;
}
const int mn = 1e5 + 4;
set<int> te[2 * mn];
int segEdgeN;
void addedge(set<int> &s, int val, bool toadd) {
  if (toadd)
    s.insert(val);
  else
    s.erase(val);
}
void segModifyEdge(int l, int r, int value, bool toadd) {
  ++r;
  for (l += segEdgeN, r += segEdgeN; l < r; l >>= 1, r >>= 1) {
    if (l & 1) addedge(te[l++], value, toadd);
    if (r & 1) addedge(te[--r], value, toadd);
  }
}
set<int> segQueryEdge(int p) {
  set<int> res;
  for (p += segEdgeN; p > 0; p >>= 1) {
    for (auto &w : te[p]) res.insert(w);
  }
  return res;
}
typedef struct edget {
  int sl, sr, tl, tr, w;
} edge;
vector<edge> ve;
long long vans[mn];
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, q, s;
  scanf("%d%d%d", &n, &q, &s);
  segEdgeN = n + 1;
  for (int i = 0; i < q; i++) {
    int t;
    scanf("%d", &t);
    int sl, sr, tl, tr, w;
    if (t == 1) {
      int v, u;
      scanf("%d%d%d", &v, &u, &w);
      sl = v, sr = v, tl = u, tr = u;
    } else {
      int v, l, r;
      scanf("%d%d%d%d", &v, &l, &r, &w);
      if (t == 2)
        sl = v, sr = v, tl = l, tr = r;
      else
        sl = l, sr = r, tl = v, tr = v;
    }
    edge e = {sl, sr, tl, tr, w};
    ve.push_back(e);
    segModifyEdge(sl, sr, ve.size() - 1, true);
  }
  memset(vans, -1, sizeof vans);
  set<long long> active;
  for (long long x = 1; x <= n; x++) active.insert(x);
  map<long long, pair<vector<int>, vector<int> > > h;
  h[0].first.push_back(s);
  active.erase(s);
  long long prev = -1;
  while (1) {
    auto jt = h.upper_bound(prev);
    if (jt == h.end()) break;
    long long dist = jt->first;
    prev = dist;
    for (auto &ei : jt->second.second) {
      edge e = ve[ei];
      auto it = active.lower_bound(e.tl);
      while (1) {
        if (it == active.end() || *it > e.tr) break;
        h[dist].first.push_back(*it);
        it = active.erase(it);
        if (it == active.end() || *it > e.tr) break;
      }
    }
    for (auto &vtx : jt->second.first) {
      vans[vtx] = dist;
      set<int> edgeIdxSet = segQueryEdge(vtx);
      for (auto &ei : edgeIdxSet) {
        edge e = ve[ei];
        h[dist + e.w].second.push_back(ei);
        segModifyEdge(e.sl, e.sr, ei, false);
      }
    }
  }
  for (long long x = 1; x <= n; x++) printf("%lld ", vans[x]);
  printf("\n");
}
