#include <bits/stdc++.h>
using namespace std;
struct plan {
  bool used;
  int type;
  int single;
  int start;
  int end;
  long long cost;
};
void getInput(vector<plan> &plans, vector<vector<int> > &outs,
              vector<forward_list<int> > &segtree);
void addPlan(vector<forward_list<int> > &segtree, int st_ind, int cs, int ce,
             int ds, int de, int pi);
void getMinCosts(vector<long long> &min_costs, int source,
                 vector<vector<int> > &outs,
                 vector<forward_list<int> > &segtree, vector<plan> &plans);
void processNode(int n, vector<bool> &visited, set<int> &unvisited,
                 priority_queue<pair<long long, int> > &to_visit,
                 vector<vector<int> > &outs,
                 vector<forward_list<int> > &segtree, vector<plan> &plans,
                 long long cur_cost, vector<long long> &min_costs);
int main() {
  int num_planets, num_plans, source;
  cin >> num_planets >> num_plans >> source;
  source--;
  vector<long long> min_costs(num_planets, LLONG_MAX);
  min_costs[source] = 0;
  vector<vector<int> > outs(num_planets);
  vector<forward_list<int> > segtree(2 *
                                     pow(2, ceil(log(num_planets) / log(2))));
  vector<plan> plans(num_plans);
  getInput(plans, outs, segtree);
  getMinCosts(min_costs, source, outs, segtree, plans);
  for (int i = 0; i < min_costs.size(); i++)
    cout << ((min_costs[i] < LLONG_MAX) ? min_costs[i] : -1) << ' ';
  cout << '\n';
  return 0;
}
void getInput(vector<plan> &plans, vector<vector<int> > &outs,
              vector<forward_list<int> > &segtree) {
  for (int pi = 0; pi < plans.size(); pi++) {
    plans[pi].used = false;
    cin >> plans[pi].type >> plans[pi].single >> plans[pi].start;
    plans[pi].type -= 2;
    if (plans[pi].type >= 0)
      cin >> plans[pi].end;
    else {
      plans[pi].end = plans[pi].start;
      plans[pi].type = 0;
    }
    plans[pi].single--;
    plans[pi].start--;
    plans[pi].end--;
    cin >> plans[pi].cost;
    if (plans[pi].type == 0)
      outs[plans[pi].single].push_back(pi);
    else
      addPlan(segtree, 1, 0, segtree.size() / 2 - 1, plans[pi].start,
              plans[pi].end, pi);
  }
}
void addPlan(vector<forward_list<int> > &segtree, int st_ind, int cs, int ce,
             int ds, int de, int pi) {
  if (cs > de || ce < ds)
    return;
  else if (cs >= ds && ce <= de)
    segtree[st_ind].push_front(pi);
  else {
    int cm = (cs + ce) / 2;
    addPlan(segtree, 2 * st_ind, cs, cm, ds, de, pi);
    addPlan(segtree, 2 * st_ind + 1, cm + 1, ce, ds, de, pi);
  }
}
void getMinCosts(vector<long long> &min_costs, int source,
                 vector<vector<int> > &outs,
                 vector<forward_list<int> > &segtree, vector<plan> &plans) {
  vector<bool> visited(min_costs.size(), false);
  set<int> unvisited;
  for (int i = 0; i < min_costs.size(); i++) unvisited.insert(i);
  priority_queue<pair<long long, int> > to_visit;
  processNode(source, visited, unvisited, to_visit, outs, segtree, plans, 0,
              min_costs);
  while (to_visit.size() > 0) {
    int cur_pi = to_visit.top().second;
    long long cur_cost = -to_visit.top().first;
    to_visit.pop();
    if (plans[cur_pi].type == 0) {
      set<int>::iterator s_it = unvisited.lower_bound(plans[cur_pi].start);
      set<int>::iterator e_it = unvisited.upper_bound(plans[cur_pi].end);
      for (set<int>::iterator it = s_it; it != e_it;) {
        int n = *it;
        it++;
        processNode(n, visited, unvisited, to_visit, outs, segtree, plans,
                    cur_cost, min_costs);
      }
    } else {
      if (!visited[plans[cur_pi].single])
        processNode(plans[cur_pi].single, visited, unvisited, to_visit, outs,
                    segtree, plans, cur_cost, min_costs);
    }
  }
}
void processNode(int n, vector<bool> &visited, set<int> &unvisited,
                 priority_queue<pair<long long, int> > &to_visit,
                 vector<vector<int> > &outs,
                 vector<forward_list<int> > &segtree, vector<plan> &plans,
                 long long cur_cost, vector<long long> &min_costs) {
  if (visited[n]) return;
  min_costs[n] = cur_cost;
  visited[n] = true;
  unvisited.erase(n);
  for (auto &out : outs[n])
    to_visit.push(make_pair(-(cur_cost + plans[out].cost), out));
  for (int st_ind = segtree.size() / 2 + n; st_ind > 0; st_ind /= 2) {
    for (auto &pi : segtree[st_ind])
      if (!plans[pi].used) {
        plans[pi].used = true;
        to_visit.push(make_pair(-(cur_cost + plans[pi].cost), pi));
      }
    segtree[st_ind].clear();
  }
}
