#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define MAXN 2500010
using namespace std;
struct edge
{
int u,v,w,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define w(x) ed[x].w
#define n(x) ed[x].nxt
}ed[MAXN<<3];
int first[MAXN],num_e;
#define f(x) first[x]
int n,m,p;
inline void add_e(int u,int v,int w);
struct tree
{
int l,r,ls,rs;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define ls(x) tr[x].ls
#define rs(x) tr[x].rs
}tr[MAXN];
int ra,rb,pos[MAXN],tot;
void build(int &k,int ll,int rr,int opt)
{
k=++tot;
l(k)=ll,r(k)=rr;
if(ll==rr){if(opt)pos[ll]=k;return;}
int mid=(ll+rr)>>1;
build(ls(k),ll,mid,opt);
build(rs(k),mid+1,rr,opt);
if(opt)add_e(ls(k),k,0),add_e(rs(k),k,0);
else add_e(k,ls(k),0),add_e(k,rs(k),0);
}
void addleaf(int k)
{
if(l(k)==r(k)){add_e(k,pos[l(k)],0);return;}
addleaf(ls(k)),addleaf(rs(k));
}
void treeadd(int k,int ll,int rr,int to,int opt)
{
if(ll<=l(k) && rr>=r(k)){opt?add_e(k,to,0):add_e(to,k,0);return;}
int mid=(l(k)+r(k))>>1;
if(ll<=mid)treeadd(ls(k),ll,rr,to,opt);
if(rr> mid)treeadd(rs(k),ll,rr,to,opt);
}
void add(int a,int b,int c,int d)
{
int p1=++tot,p2=++tot;
treeadd(ra,a,b,p1,1);
add_e(p1,p2,1);
treeadd(rb,c,d,p2,0);
}
int dis[MAXN];bool v[MAXN];
void dist(int s)
{
memset(dis,0x7f,sizeof(dis));
priority_queue<pair<int,int> >q;
dis[s]=0;q.push(make_pair(0,s));
while(q.size())
{
int x=q.top().second;q.pop();
if(v[x])continue;v[x]=1;
for(int i=f(x);i;i=n(i))
if(!v[v(i)] && dis[v(i)]>dis[x]+w(i))
dis[v(i)]=dis[x]+w(i),
q.push(make_pair(-dis[v(i)],v(i)));
}
}
signed main()
{
// freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&m,&p);
build(ra,1,n,1),build(rb,1,n,0);addleaf(rb);
for(int i=1;i<=m;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
add(a,b,c,d),add(c,d,a,b);
}
dist(pos[p]);
for(int i=1;i<=n;i++)
printf("%d
",dis[pos[i]]);
}
inline void add_e(int u,int v,int w)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
w(num_e)=w;
n(num_e)=f(u);
f(u)=num_e;
}