#include <bits/stdc++.h>
#define int long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
using LL = long long;
using ULL = unsigned long long;
constexpr int N = 1e5 + 10;
int n, q, s, tot, spt;
int h[N << 3], e[N << 3], ne[N << 3], val[N << 3], idx;
int dis[N << 3], ans[N];
bool vis[N << 3];
vector<int> from, to;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;
struct Node {
int ls, rs, l, r;
} tr[N << 4];
void add_edge(int u, int v, int w) {
e[idx] = v, val[idx] = w, ne[idx] = h[u], h[u] = idx ++;
}
void build(int l, int r, int flag) { // flag = 0 : 出树, flag = 1 : 入树
int u = ++ tot;
tr[u].l = l, tr[u].r = r;
if(l == r) return ;
int mid = l + r >> 1;
tr[u].ls = tot + 1, build(l, mid, flag);
tr[u].rs = tot + 1, build(mid + 1, r, flag);
if(flag) add_edge(u, tr[u].ls, 0), add_edge(u, tr[u].rs, 0);
else add_edge(tr[u].ls, u, 0), add_edge(tr[u].rs, u, 0);
}
void find(int u, int l, int r, int flag) {
if(tr[u].l >= l && tr[u].r <= r) {
if(flag) to.emplace_back(u);
else from.emplace_back(u);
return ;
}
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) find(tr[u].ls, l, r, flag);
if(r > mid) find(tr[u].rs, l, r, flag);
}
signed main() {
ios_base :: sync_with_stdio(false);
*cin.tie(nullptr) << fixed << setprecision(20);
memset(h, -1, sizeof h);
cin >> n >> q >> s;
build(1, n, 0), spt = tot + 1, build(1, n, 1);
for(int i = 1, opt, u, v, l, r, w; i <= q; i ++) {
cin >> opt;
from.clear(), to.clear();
if(opt == 1) {
cin >> u >> v >> w;
find(1, u, u, 0), find(spt, v, v, 1);
add_edge(from[0], to[0], w);
}
else if(opt == 2) {
cin >> u >> l >> r >> w;
find(1, u, u, 0), find(spt, l, r, 1);
for(int t : to) add_edge(from[0], t, w);
}
else {
cin >> u >> l >> r >> w;
find(1, l, r, 0), find(spt, u, u, 1);
for(int f : from) add_edge(f, to[0], w);
}
}
for(int i = 1; i <= n; i ++) {
from.clear(), to.clear();
find(1, i, i, 0), find(spt, i, i, 1);
add_edge(from[0], to[0], 0), add_edge(to[0], from[0], 0);
}
from.clear();
find(1, s, s, 0);
que.push({0, from[0]});
memset(dis, 0x3f, sizeof dis), memset(ans, 0x3f, sizeof ans);
dis[from[0]] = 0;
while(que.size()) {
auto [d, u] = que.top(); que.pop();
if(vis[u]) continue;
vis[u] = true;
for(int i = h[u]; ~i; i = ne[i]) {
int v = e[i], w = val[i];
if(dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
que.push({dis[v], v});
}
}
}
for(int i = 1; i <= n; i ++) {
to.clear();
find(spt, i, i, 1);
ans[tr[to[0]].l] = min(ans[tr[to[0]].l], dis[to[0]]);
}
for(int i = 1; i <= n; i ++)
cout << (ans[i] == 0x3f3f3f3f3f3f3f3f ? -1 : ans[i]) << " \n"[i == n];
return 0;
}