#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e05 + 10;
const int MAXM = (MAXN << 3) + MAXN;
struct LinkedForwardStar {
  int to;
  int w;
  int next;
};
LinkedForwardStar Link[MAXM << 2];
int Head[MAXM] = {0};
int size = 0;
void Insert(int u, int v, int w) {
  Link[++size].to = v;
  Link[size].w = w;
  Link[size].next = Head[u];
  Head[u] = size;
}
int N, Q;
struct Node {
  int left, right;
  Node() {}
};
Node Tree[2][MAXN << 2];
const int Root = 1;
int maxroot = 0;
void Build(int root, int left, int right, int type) {
  Tree[type][root].left = left, Tree[type][root].right = right;
  if (type == 0) maxroot = max(maxroot, root);
  if (left == right) {
    type == 0 ? Insert(root + N, left, 0) : Insert(left, root + N + maxroot, 0);
    return;
  }
  int mid = (left + right) >> 1;
  Build(root << 1, left, mid, type);
  Build(root << 1 | 1, mid + 1, right, type);
  if (type == 0) {
    Insert(root + N, (root << 1) + N, 0);
    Insert(root + N, (root << 1 | 1) + N, 0);
  } else {
    Insert((root << 1) + N + maxroot, root + N + maxroot, 0);
    Insert((root << 1 | 1) + N + maxroot, root + N + maxroot, 0);
  }
}
void AddEdge(int root, int u, int L, int R, int w, int type) {
  if (L <= Tree[type][root].left && Tree[type][root].right <= R) {
    type == 0 ? Insert(u, root + N, w) : Insert(root + N + maxroot, u, w);
    return;
  }
  int mid = (Tree[type][root].left + Tree[type][root].right) >> 1;
  if (L <= mid) AddEdge(root << 1, u, L, R, w, type);
  if (R > mid) AddEdge(root << 1 | 1, u, L, R, w, type);
}
struct Part {
  int u;
  long long dist;
  Part() {}
  Part(int fu, long long fdist) : u(fu), dist(fdist) {}
  bool operator<(const Part& p) const { return dist > p.dist; }
};
priority_queue<Part> Que;
long long Dist[MAXM];
bool Vis[MAXM] = {false};
void Dijkstra(int S) {
  memset(Dist, 0x3f, sizeof(Dist));
  Que.push(Part(S, 0));
  Dist[S] = 0;
  while (!Que.empty()) {
    Part top = Que.top();
    Que.pop();
    int u = top.u;
    if (Vis[u]) continue;
    Vis[u] = true;
    for (int i = Head[u]; i; i = Link[i].next) {
      int v = Link[i].to, w = Link[i].w;
      if (Vis[v]) continue;
      if (Dist[u] + w < Dist[v]) {
        Dist[v] = Dist[u] + w;
        Que.push(Part(v, Dist[v]));
      }
    }
  }
}
int getnum() {
  int num = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) num = num * 10 + ch - '0', ch = getchar();
  return num;
}
int main() {
  int S;
  scanf("%d%d%d", &N, &Q, &S);
  Build(Root, 1, N, 0);
  Build(Root, 1, N, 1);
  for (int i = 1; i <= Q; i++) {
    int opt;
    opt = getnum();
    if (opt == 1) {
      int u, v, w;
      u = getnum(), v = getnum(), w = getnum();
      Insert(u, v, w);
    } else if (opt == 2) {
      int u, L, R, w;
      u = getnum(), L = getnum(), R = getnum(), w = getnum();
      AddEdge(Root, u, L, R, w, 0);
    } else {
      int u, L, R, w;
      u = getnum(), L = getnum(), R = getnum(), w = getnum();
      AddEdge(Root, u, L, R, w, 1);
    }
  }
  Dijkstra(S);
  for (int i = 1; i <= N; i++) {
    if (i > 1) putchar(' ');
    if (Dist[i] >= 0x3f3f3f3f3f3f3f3f)
      putchar('-'), putchar('1');
    else
      printf("%I64d", Dist[i]);
  }
  puts("");
  return 0;
}
