#include <bits/stdc++.h>
using namespace std;
priority_queue<pair<long long, int>, vector<pair<long long, int> >,
               greater<pair<long long, int> > >
    q;
struct node {
  int left, right, num[3];
} tree[4 * 100010];
struct NODE {
  int begin, end, value, next;
} edge[50 * 100010 + 10];
int cnt, Head[2 * 4 * 100010 + 10], lcc[3], SIZE, cc[3][100010];
long long dis[2 * 4 * 100010 + 10];
int read() {
  int s = 0, fh = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') fh = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    s = s * 10 + (ch - '0');
    ch = getchar();
  }
  return s * fh;
}
void addedge(int bb, int ee, int vv) {
  edge[++cnt].begin = bb;
  edge[cnt].end = ee;
  edge[cnt].value = vv;
  edge[cnt].next = Head[bb];
  Head[bb] = cnt;
}
void addedge1(int bb, int ee, int vv) {
  addedge(bb, ee, vv);
  addedge(ee, bb, vv);
}
void Build(int k, int l, int r) {
  tree[k].left = l;
  tree[k].right = r;
  tree[k].num[1] = ++SIZE;
  tree[k].num[2] = ++SIZE;
  if (l == r) {
    addedge(tree[k].num[1], tree[k].num[2], 0);
    return;
  }
  int mid = (l + r) / 2;
  Build(k * 2, l, mid);
  Build(k * 2 + 1, mid + 1, r);
  addedge(tree[k].num[1], tree[k * 2].num[1], 0);
  addedge(tree[k].num[1], tree[k * 2 + 1].num[1], 0);
  addedge(tree[k * 2].num[2], tree[k].num[2], 0);
  addedge(tree[k * 2 + 1].num[2], tree[k].num[2], 0);
}
void Find(int k, int ql, int qr, int F) {
  if (ql <= tree[k].left && tree[k].right <= qr) {
    cc[F][++lcc[F]] = tree[k].num[F];
    return;
  }
  int mid = (tree[k].left + tree[k].right) / 2;
  if (qr <= mid)
    Find(k * 2, ql, qr, F);
  else if (ql > mid)
    Find(k * 2 + 1, ql, qr, F);
  else {
    Find(k * 2, ql, mid, F);
    Find(k * 2 + 1, mid + 1, qr, F);
  }
}
void dijkstra(int start) {
  int i, u, v;
  for (i = 1; i <= SIZE; i++) dis[i] = 1LL << 60;
  dis[start] = 0LL;
  q.push(make_pair(dis[start], start));
  while (!q.empty()) {
    u = q.top().second;
    q.pop();
    for (i = Head[u]; i != -1; i = edge[i].next) {
      v = edge[i].end;
      if (dis[v] > dis[u] + (long long)edge[i].value) {
        dis[v] = dis[u] + (long long)edge[i].value;
        q.push(make_pair(dis[v], v));
      }
    }
  }
}
int main() {
  int N, Q, S, i, zs, s1, s2, s3, s4, j;
  N = read();
  Q = read();
  S = read();
  memset(Head, -1, sizeof(Head));
  cnt = 1;
  SIZE = 0;
  Build(1, 1, N);
  for (i = 1; i <= Q; i++) {
    zs = read();
    if (zs == 1) {
      s1 = read();
      s2 = read();
      s3 = read();
      lcc[1] = lcc[2] = 0;
      Find(1, s1, s1, 2);
      Find(1, s2, s2, 1);
      addedge(cc[2][1], cc[1][1], s3);
    } else if (zs == 2) {
      s1 = read();
      s2 = read();
      s3 = read();
      s4 = read();
      lcc[1] = lcc[2] = 0;
      Find(1, s1, s1, 2);
      Find(1, s2, s3, 1);
      for (j = 1; j <= lcc[1]; j++) addedge(cc[2][1], cc[1][j], s4);
    } else {
      s1 = read();
      s2 = read();
      s3 = read();
      s4 = read();
      lcc[1] = lcc[2] = 0;
      Find(1, s2, s3, 2);
      Find(1, s1, s1, 1);
      for (j = 1; j <= lcc[2]; j++) addedge(cc[2][j], cc[1][1], s4);
    }
  }
  lcc[2] = 0;
  Find(1, S, S, 2);
  dijkstra(cc[2][1]);
  for (i = 1; i <= N; i++) {
    lcc[2] = 0;
    Find(1, i, i, 2);
    printf("%lld ", dis[cc[2][1]] == 1LL << 60 ? -1LL : dis[cc[2][1]]);
  }
  return 0;
}
