#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int to, next, v;
} edges[3000005];
int n, m, s, first[500005], te = 0, id = 0;
bool used[500005];
long long dis[500005];
struct Point {
  int num;
  long long dis;
  Point() {}
  Point(int a, long long b) { num = a, dis = b; }
  bool operator<(const Point &b) const { return dis > b.dis; }
};
priority_queue<Point> q;
struct Node {
  int st, ed, num;
  Node *l, *r;
  Node() {}
  Node(int a, int b, Node *c, Node *d) {
    st = a, ed = b, num = (st == ed) ? st : ++id, l = c, r = d;
  }
} * root1, *root2;
void addE(int a, int b, int c) {
  edges[++te].to = b;
  edges[te].next = first[a];
  first[a] = te;
  edges[te].v = c;
}
Node *build(int st, int ed) {
  if (st == ed) return new Node(st, ed, 0, 0);
  int mid = (st + ed) >> 1;
  Node *ret = new Node(st, ed, build(st, mid), build(mid + 1, ed));
  return ret;
}
void init(Node *x, bool rev) {
  if (x->st == x->ed) return;
  if (!rev) {
    addE(x->num, x->l->num, 0);
    addE(x->num, x->r->num, 0);
  } else {
    addE(x->l->num, x->num, 0);
    addE(x->r->num, x->num, 0);
  }
  init(x->l, rev);
  init(x->r, rev);
}
void addE2(Node *x, int st, int ed, int from, int v) {
  if (x->st >= st && x->ed <= ed) {
    addE(from, x->num, v);
    return;
  }
  int mid = (x->st + x->ed) >> 1;
  if (st <= mid) addE2(x->l, st, ed, from, v);
  if (ed > mid) addE2(x->r, st, ed, from, v);
}
void addE3(Node *x, int st, int ed, int from, int v) {
  if (x->st >= st && x->ed <= ed) {
    addE(x->num, from, v);
    return;
  }
  int mid = (x->st + x->ed) >> 1;
  if (st <= mid) addE3(x->l, st, ed, from, v);
  if (ed > mid) addE3(x->r, st, ed, from, v);
}
void dijkstra() {
  memset(dis, -1, sizeof(dis));
  dis[s] = 0;
  q.push(Point(s, 0));
  while (!q.empty()) {
    Point tot = q.top();
    q.pop();
    int x = tot.num;
    long long y = tot.dis;
    if (dis[x] != y) continue;
    used[x] = 1;
    for (int e = first[x]; e; e = edges[e].next) {
      int to = edges[e].to;
      if (dis[to] == -1 || dis[to] > dis[x] + edges[e].v) {
        dis[to] = edges[e].v + dis[x];
        q.push(Point(to, dis[to]));
      }
    }
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> m >> s;
  id = n;
  root1 = build(1, n);
  root2 = build(1, n);
  init(root1, 0);
  init(root2, 1);
  for (int i = 1; i <= m; ++i) {
    int tp, x, y, v, z;
    cin >> tp;
    if (tp == 1) {
      cin >> x >> y >> v;
      addE(x, y, v);
    } else if (tp == 2) {
      cin >> x >> y >> z >> v;
      addE2(root1, y, z, x, v);
    } else {
      cin >> x >> y >> z >> v;
      addE3(root2, y, z, x, v);
    }
  }
  dijkstra();
  for (int i = 1; i <= n; ++i) cout << dis[i] << " ";
  return 0;
}
