#include<bits/stdc++.h>
#define N 900005
#define M 5000005
#define ll long long
using namespace std;
int head[N],idx,n,q,s;
struct edge{
int v,next,w;
}e[M];
void add(int u,int v,int w){
e[++idx],v=v;
e[idx].next=head[u];
e[idx].w=w;
head[u]=idx;
}
struct SGtree{
int l,r;
}t[N];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
add(l+8*n,p,0),add(p+4*n,l+8*n,0);
add(p,l+8*n,0),add(l+8*n,p+4*n,0);
return ;
}
int mid=(l+r)>>1;
add(p,p*2,0), add(p*2+n*4,p+n*4,0);
add(p,p*2+1,0), add(p*2+1+n*4,p+n*4,0);
build(p*2,l,mid);
build(p*2+1,mid+1,r);
}
void add_edge(int p,int x,int y,bool type,int u,int w) {
int l=t[p].l, r=t[p].r, mid=((l+r)>>1);
if(l==x&&y==r) {
if(!type) return add(u+8*n,p,w);
else return add(p+4*n,u+8*n,w);
}
if(y<=mid) add_edge(p*2,x,y,type,u,w);
else if(x>mid) add_edge(p*2+1,x,y,type,u,w);
else add_edge(p*2,x,mid,type,u,w), add_edge(p*2+1,mid+1,y,type,u,w);
}
ll dis[N];
bool vis[N];
void dijkstra(){
priority_queue<pair<ll,int> > q;
for(int i=1;i<=9*n;i++) dis[i]=1111111111111111;
memset(vis,0,sizeof(vis));
q.push(make_pair(0,s));
dis[s]=0;
while(!q.empty()){
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=e[i].next){
int y=e[i].v;
if(dis[y]>dis[x]+e[i].w){
dis[y]=dis[x]+e[i].w;
q.push(make_pair(-dis[y],y));
}
}
}
}
int main(){
scanf("%d%d%d",&n,&q,&s);
s+=8*n;
build(1,1,n);
for(int i=1;i<=q;i++){
int op,l,r,x,w;
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&l,&r,&w);
add(l+8*n,r+8*n,w);
}
if(op==2){
scanf("%d%d%d%d",&x,&l,&r,&w);
add_edge(1,l,r,0,x,w);
}
if(op==3){
scanf("%d%d%d%d",&x,&l,&r,&w);
add_edge(1,l,r,1,x,w);
}
}
dijkstra();
for(int i=1;i<=n;i++){
printf("%lld ",dis[8*n+i]);
}
return 0;
}