#include <bits/stdc++.h>
#include <stdint.h>
using namespace std;
long long MXMX=0x3f3f3f3f3f3f3f3fll;
const long long MAXN=1e5+5;
struct Edge
{
int nxt,to,quzhi,from;
};
struct node
{
long long dis;
int u;
};
struct st
{
int l,r;
} tree[MAXN<<5];
bool operator < (node n1,node n2)
{
return n1.dis>n2.dis;
}
Edge e[MAXN<<5];
int head[MAXN<<5],dd[MAXN<<5];
bool flag[MAXN<<5];
long long dis[MAXN<<5];
int n,m,cnt,s,LL,RR;
void add(int u,int v,int qz)
{
e[++cnt].nxt=head[u];
head[u]=cnt;
e[cnt].to=v;
e[cnt].quzhi=qz;
e[cnt].from=u;
}
priority_queue<node> q;
void dj(int a)
{
for(int i=1;i<=8*n;i++)
{
dis[i]=MXMX;
}
dis[a]=0;
q.push({0,a});
while(!q.empty())
{
node t=q.top();
int u=t.u;
q.pop();
if(flag[u]==true)
{
continue;
}
flag[u]=true;
for(int i=head[u];i!=0;i=e[i].nxt)
{
int v=e[i].to;
if(dis[v]>dis[u]+e[i].quzhi)
{
dis[v]=dis[u]+e[i].quzhi;
q.push({dis[v],v});
}
}
}
}
void build(int p,int l,int r,int fa)
{
if(fa!=0)
{
add(fa,p,0);
add(p+4*n,fa+4*n,0);
}
tree[p].r=r,tree[p].l=l;
if(tree[p].l==tree[p].r)
{
dd[l]=p;
add(dd[l],dd[l]+4*n,0);
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid,p);
build(p<<1|1,mid+1,r,p);
}
void upd1(int p,int l,int r,int v,int w)
{
if(LL<=tree[p].l&&RR>=tree[p].r)
{
add(dd[v]+4*n,p,w);
return;
}
int mid=(l+r)>>1;
if(LL<=mid)
{
upd1(p<<1,l,mid,v,w);
}
if(RR>mid)
{
upd1(p<<1|1,mid+1,r,v,w);
}
}
void upd2(int p,int l,int r,int v,int w)
{
if(LL<=tree[p].l&&RR>=tree[p].r)
{
add(p+4*n,dd[v],w);
return;
}
int mid=(l+r)>>1;
if(LL<=mid)
{
upd2(p<<1,l,mid,v,w);
}
if(RR>mid)
{
upd2(p<<1|1,mid+1,r,v,w);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
build(1,1,n,0);
while(m--)
{
int op,u,v,l,r,w;
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%d",&v,&u,&w);
add(dd[v],dd[u]+4*n,w);
}
else if(op==2)
{
scanf("%d%d%d%d",&v,&l,&r,&w);
LL=l;
RR=r;
upd1(1,1,n,v,w);
}
else
{
scanf("%d%d%d%d",&v,&l,&r,&w);
LL=l;
RR=r;
upd2(1,1,n,v,w);
}
}
dj(dd[s]);
for(int i=1;i<=n;i++)
{
if(dis[dd[i]]>=MXMX)
{
printf("-1 ");
}
else
{
printf("%lld ",dis[dd[i]]);
}
}
return 0;
}