#include <bits/stdc++.h>
using namespace std;
constexpr long long inf = 1e13;
std::vector<long long> tree1;
std::vector<long long> tree2;
vector<vector<pair<long long, long long>>> graph;
long long first_shift = 0, second_shift = 0;
void build_tree_first_type(int v, int l, int r) {
  if (l + 1 == r) {
    graph[l].push_back(make_pair(v + first_shift, 0));
    return;
  } else {
    auto mid = (r + l) / 2;
    build_tree_first_type(2 * v + 1, l, mid);
    build_tree_first_type(2 * v + 2, mid, r);
    graph[2 * v + 1 + first_shift].push_back(make_pair(v + first_shift, 0));
    graph[2 * v + 2 + first_shift].push_back(make_pair(v + first_shift, 0));
  }
}
void build_tree_second_type(int v, int l, int r) {
  if (l + 1 == r) {
    graph[v + second_shift].push_back(make_pair(l, 0));
    return;
  } else {
    auto mid = (r + l) / 2;
    graph[v + second_shift].push_back(make_pair(2 * v + 1 + second_shift, 0));
    graph[v + second_shift].push_back(make_pair(2 * v + 2 + second_shift, 0));
    build_tree_second_type(2 * v + 1, l, mid);
    build_tree_second_type(2 * v + 2, mid, r);
  }
}
void get_all_vertex_first_type(int v, int l, int r, int l_find, int r_find,
                               int to, int w) {
  if (l >= l_find && r <= r_find) {
    graph[v + first_shift].push_back(make_pair(to, w));
  } else if (l >= r_find || r <= l_find) {
    return;
  } else {
    int mid = (r + l) / 2;
    get_all_vertex_first_type(2 * v + 1, l, mid, l_find, r_find, to, w);
    get_all_vertex_first_type(2 * v + 2, mid, r, l_find, r_find, to, w);
  }
}
void get_all_vertex_second_type(int v, int l, int r, int l_find, int r_find,
                                int from, int w) {
  if (l >= l_find && r <= r_find) {
    graph[from].push_back(make_pair(v + second_shift, w));
  } else if (l >= r_find || r <= l_find) {
    return;
  } else {
    int mid = (r + l) / 2;
    get_all_vertex_second_type(2 * v + 1, l, mid, l_find, r_find, from, w);
    get_all_vertex_second_type(2 * v + 2, mid, r, l_find, r_find, from, w);
  }
  return;
}
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  long long n, q, s;
  cin >> n >> q >> s;
  s--;
  long long all_vertex_count = 4 * n + 4 * n + n;
  first_shift = n;
  second_shift = 5 * n;
  graph.resize(all_vertex_count);
  build_tree_first_type(0, 0, n);
  build_tree_second_type(0, 0, n);
  for (int i = 0; i < q; ++i) {
    int type = 0;
    cin >> type;
    if (type == 1) {
      int u, v, w;
      cin >> u >> v >> w;
      graph[u - 1].push_back(make_pair(v - 1, w));
    } else if (type == 2) {
      int v, l, r, w;
      cin >> v >> l >> r >> w;
      get_all_vertex_second_type(0, 0, n, l - 1, r, v - 1, w);
    } else if (type == 3) {
      int v, l, r, w;
      cin >> v >> l >> r >> w;
      get_all_vertex_first_type(0, 0, n, l - 1, r, v - 1, w);
    }
  }
  std::vector<long long> dist(all_vertex_count, inf);
  dist[s] = 0;
  std::set<pair<long long, long long>> Set;
  Set.insert(make_pair(0, s));
  while (!Set.empty()) {
    auto now_vertex = *(Set.begin());
    Set.erase(Set.begin());
    for (size_t i = 0; i < graph[now_vertex.second].size(); i++) {
      auto to = graph[now_vertex.second][i];
      if (dist[to.first] > now_vertex.first + to.second) {
        dist[to.first] = now_vertex.first + to.second;
        Set.erase(make_pair(dist[to.first], to.first));
        Set.insert(make_pair(now_vertex.first + to.second, to.first));
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    if (dist[i] == inf) {
      dist[i] = -1;
    }
    std::cout << dist[i] << " ";
  }
  return 0;
}
