#include <bits/stdc++.h>
using namespace std;
const long long int inf = 200000000000000000;
int tl[4 * 100010], tr[4 * 100010];
int fl[100010], fr[100010];
long long int d[1000010];
int q, n, s, cnt;
struct node {
  int w;
  int to;
};
queue<int> qs;
vector<node> g[1000010];
void add_edge(int from, int to, int w) {
  node temp;
  temp.to = to;
  temp.w = w;
  g[from].push_back(temp);
}
void buildl(int root, int l, int r) {
  if (l == r) {
    tl[root] = ++cnt;
    fl[l] = tl[root];
  } else {
    tl[root] = ++cnt;
    int mid = (l + r) / 2;
    buildl(root * 2, l, mid);
    buildl(root * 2 + 1, mid + 1, r);
    add_edge(tl[2 * root], tl[root], 0);
    add_edge(tl[2 * root + 1], tl[root], 0);
  }
}
void buildr(int root, int l, int r) {
  if (l == r) {
    tr[root] = ++cnt;
    fr[l] = tr[root];
  } else {
    tr[root] = ++cnt;
    int mid = (l + r) / 2;
    buildr(root * 2, l, mid);
    buildr(root * 2 + 1, mid + 1, r);
    add_edge(tr[root], tr[root * 2], 0);
    add_edge(tr[root], tr[root * 2 + 1], 0);
  }
}
void pre(int root, int l, int r) {
  for (int i = 1; i <= n; i++) {
    add_edge(i, fl[i], 0);
    add_edge(fr[i], i, 0);
  }
}
void updatel(int root, int l, int r, int L, int R, int v, int w) {
  if (l == r) {
    add_edge(fl[l], fr[v], w);
    return;
  }
  if (l >= L && r <= R) {
    add_edge(tl[root], fr[v], w);
    return;
  }
  int mid = (l + r) / 2;
  if (mid >= L) {
    updatel(root * 2, l, mid, L, R, v, w);
  }
  if (mid + 1 <= R) {
    updatel(root * 2 + 1, mid + 1, r, L, R, v, w);
  }
}
void updater(int root, int l, int r, int L, int R, int v, int w) {
  if (l == r) {
    add_edge(fl[v], fr[l], w);
    return;
  }
  if (l >= L && r <= R) {
    add_edge(fl[v], tr[root], w);
    return;
  }
  int mid = (l + r) / 2;
  if (mid >= L) {
    updater(root * 2, l, mid, L, R, v, w);
  }
  if (mid + 1 <= R) {
    updater(root * 2 + 1, mid + 1, r, L, R, v, w);
  }
}
void spfa() {
  for (int i = 1; i <= cnt; i++) {
    d[i] = inf;
  }
  d[s] = 0;
  qs.push(s);
  while (!qs.empty()) {
    int st = qs.front();
    qs.pop();
    int Size = g[st].size();
    for (int i = 0; i < Size; i++) {
      node t = g[st][i];
      if (d[st] + t.w < d[t.to]) {
        d[t.to] = d[st] + t.w;
        qs.push(t.to);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (d[i] == inf) {
      if (i == n)
        printf("-1");
      else
        printf("-1 ");
    } else {
      if (i == n)
        printf("%I64d", d[i]);
      else
        printf("%I64d ", d[i]);
    }
  }
}
int main() {
  int i, j, k, t, u, v, l, r, w;
  scanf("%d%d%d", &n, &q, &s);
  cnt = n;
  buildl(1, 1, n);
  buildr(1, 1, n);
  pre(1, 1, n);
  for (i = 1; i <= q; i++) {
    scanf("%d", &t);
    if (t == 1) {
      scanf("%d%d%d", &u, &v, &w);
      updatel(1, 1, n, u, u, v, w);
    } else if (t == 2) {
      scanf("%d%d%d%d", &v, &l, &r, &w);
      updater(1, 1, n, l, r, v, w);
    } else {
      scanf("%d%d%d%d", &v, &l, &r, &w);
      updatel(1, 1, n, l, r, v, w);
    }
  }
  spfa();
  return 0;
}
