#include <bits/stdc++.h>
using namespace std;
const long long INF = 0x6363636363636363LL;
int n, q, s;
vector<pair<int, int> > adj[400100];
long long tree[400100];
vector<pair<int, int> > plans[400100];
int node_of[100100];
bool mark[400100];
void add(int node, int left, int right, int l, int r, int v, int t, int w) {
  if (left > r || right < l) {
    return;
  }
  if (left >= l && right <= r) {
    if (t == 2) {
      adj[node_of[v]].push_back(make_pair(node, w));
    } else {
      plans[node].push_back(make_pair(node_of[v], w));
    }
  } else {
    int mid = (left + right) / 2;
    add(2 * node, left, mid, l, r, v, t, w);
    add(2 * node + 1, mid + 1, right, l, r, v, t, w);
  }
}
int last;
void init(int node, int left, int right) {
  adj[node].clear();
  mark[node] = false;
  plans[node].clear();
  tree[node] = INF;
  if (node > last) {
    last = node;
  }
  if (left != right) {
    int mid = (left + right) / 2;
    init(2 * node, left, mid);
    init(2 * node + 1, mid + 1, right);
  } else {
    node_of[left] = node;
  }
}
bool read() {
  if (scanf("%d%d%d", &n, &q, &s) != 3) {
    return false;
  }
  last = 0;
  init(1, 1, n);
  for (int i = 0; i < q; i++) {
    int t;
    scanf("%d", &t);
    int v, l, r, u, w;
    if (t == 1) {
      scanf("%d%d%d", &v, &u, &w);
      int vv = node_of[v];
      int uu = node_of[u];
      adj[vv].push_back(make_pair(uu, w));
    } else {
      scanf("%d%d%d%d", &v, &l, &r, &w);
      add(1, 1, n, l, r, v, t, w);
    }
  }
  return true;
}
void process() {
  priority_queue<pair<long long, int> > heap;
  int ss = node_of[s];
  tree[ss] = 0;
  heap.push(make_pair(0, ss));
  while (!heap.empty()) {
    int cur;
    long long dist;
    cur = heap.top().second;
    dist = -heap.top().first;
    heap.pop();
    if (dist > tree[cur]) continue;
    int fcur = cur;
    while (fcur >= 1 && !mark[fcur]) {
      mark[fcur] = true;
      for (vector<pair<int, int> >::iterator it = plans[fcur].begin();
           it != plans[fcur].end(); it++) {
        int v = it->first;
        int w = it->second;
        if (tree[v] > dist + w) {
          tree[v] = dist + w;
          heap.push(make_pair(-tree[v], v));
        }
      }
      fcur /= 2;
    }
    if (2 * cur <= last && tree[2 * cur] > dist) {
      tree[2 * cur] = dist;
      heap.push(make_pair(-dist, 2 * cur));
    }
    if (2 * cur + 1 <= last && tree[2 * cur + 1] > dist) {
      tree[2 * cur + 1] = dist;
      heap.push(make_pair(-dist, 2 * cur + 1));
    }
    for (int i = 0; i < adj[cur].size(); i++) {
      int v = adj[cur][i].first;
      int w = adj[cur][i].second;
      if (tree[v] > dist + w) {
        tree[v] = dist + w;
        heap.push(make_pair(-tree[v], v));
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (i > 1) {
      cout << " ";
    }
    int node = node_of[i];
    if (tree[node] != INF) {
      cout << tree[node];
    } else {
      cout << "-1";
    }
  }
  cout << endl;
}
int main() {
  bool first = true;
  while (read()) {
    if (first) {
      first = false;
    } else {
      printf("\n");
    }
    process();
  }
  return 0;
}
