#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
using ll = long long;
using db = double;
const int N = 2e5 + 10;
const ll INF = 0x3f3f3f3f3f3f3f3f;
struct Edge {
int v, w;
Edge() {}
Edge(int v, int w) : v(v), w(w) {}
};
vector<vector<Edge>> G;
int n, q, s, treeIn[N << 2], treeOut[N << 2];
int cnt;
ll dis[N << 2];
void build(int id, int l, int r) {
if (l == r) {
treeIn[id] = l;
treeOut[id] = l;
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
treeIn[id] = ++cnt;
treeOut[id] = ++cnt;
G[treeOut[id << 1]].push_back(Edge(treeOut[id], 0));
G[treeOut[id << 1 | 1]].push_back(Edge(treeOut[id], 0));
G[treeIn[id]].push_back(Edge(treeIn[id << 1], 0));
G[treeIn[id]].push_back(Edge(treeIn[id << 1 | 1], 0));
}
void updateIn(int id, int l, int r, int ql, int qr, int from, int cost) {
if (l >= ql && r <= qr) {
G[from].push_back(Edge(treeIn[id], cost));
return;
}
int mid = (l + r) >> 1;
if (ql <= mid) updateIn(id << 1, l, mid, ql, qr, from, cost);
if (qr > mid) updateIn(id << 1 | 1, mid + 1, r, ql, qr, from, cost);
}
void updateOut(int id, int l, int r, int ql, int qr, int to, int cost) {
if (l >= ql && r <= qr) {
G[treeOut[id]].push_back(Edge(to, cost));
return;
}
int mid = (l + r) >> 1;
if (ql <= mid) updateOut(id << 1, l, mid, ql, qr, to, cost);
if (qr > mid) updateOut(id << 1 | 1, mid + 1, r, ql, qr, to, cost);
}
struct node {
int v, w;
node() {}
node(int v, int w) : v(v), w(w) {}
bool operator<(const node &other) const {
return w > other.w;
}
};
void solve() {
memset(dis, 0x3f, sizeof dis);
dis[s] = 0;
priority_queue<node> pq;
pq.push(node(s, 0));
while (!pq.empty()) {
int u = pq.top().v;
pq.pop();
for (auto &item: G[u]) {
if (dis[item.v] > dis[u] + item.w) {
dis[item.v] = dis[u] + item.w;
pq.push(node(item.v, dis[item.v]));
}
}
}
}
void RUN() {
while (scanf("%d %d %d", &n, &q, &s) != EOF) {
G.clear();
G.resize(N << 2);
cnt = n;
build(1, 1, n);
for (int _q = 1, op, u, v, l, r, w; _q <= q; ++_q) {
scanf("%d", &op);
if (op == 1) {
scanf("%d %d %d", &u, &v, &w);
G[u].push_back(Edge(v, w));
} else if (op == 2) {
scanf("%d %d %d %d", &u, &l, &r, &w);
updateIn(1, 1, n, l, r, u, w);
} else if (op == 3) {
scanf("%d %d %d %d", &v, &l, &r, &w);
updateOut(1, 1, n, l, r, v, w);
} else {
assert(0);
}
}
solve();
for (int i = 1; i <= n; ++i) {
printf("%lld%c", dis[i] == INF ? -1 : dis[i], " \n"[i == n]);
}
}
}
int main() {
#ifdef LOCAL_JUDGE
freopen("input.txt", "r", stdin);
#endif
RUN();
#ifdef LOCAL_JUDGE
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}