#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXV=510;
const int INF=0x3fffffff;
int N,M,S,D; //城市数,高速公路数,起点,终点
bool visit[MAXV]; //标记在迪杰斯特拉中是否遍历过
int GD[MAXV][MAXV]; //存储距离图
int GC[MAXV][MAXV]; //存储成本图
int d[MAXV]; //最短路径
int c[MAXV]; //最低成本
int pre[MAXV]; //记录前驱
void Dijkstra(int s)
{
memset(visit,false,sizeof(visit)); //初始化标记
for(int i=0 ; i<N ; ++i) //初始化前驱数组
pre[i]=i;
fill(d,d+MAXV,INF); //初始化最短距离为无穷大
d[s]=0; //起始点到起始点距离为0
fill(c,c+MAXV,INF); //初始化最低成本为无穷大
c[s]=0; //起始点到起始点成本为0
for(int i=0 ; i<N ; ++i)
{
int MIN=INF,u=-1;
for(int j=0 ; j<N ;++j)
{
if(d[j]<MIN && visit[j]==false)
{
MIN=d[j];
u=j;
}
}
if(u==-1) //说明图不连通
return;
visit[u]=true;
for(int v=0 ; v<N ; ++v)
{
if(visit[v]==false && GD[u][v]!=INF) //v未被访问,且u可以到v
{
if(d[v]>d[u]+GD[u][v]) //距离不等,以最小距离更新
{
d[v]=d[u]+GD[u][v];
c[v]=c[u]+GC[u][v];
pre[v]=u;
}
else if(d[v]==d[u]+GD[u][v]) //距离相等,按成本最低更新
{
if(c[v]>c[u]+GC[u][v])
{
c[v]=c[u]+GC[u][v];
pre[v]=u;
}
}
}
}
}
}
void DFS(int s,int v)
{
if(s==v)
{
printf("%d ",v);
return;
}
DFS(s,pre[v]);
printf("%d ",v);
}
int main()
{
fill(GD[0],GD[0]+MAXV*MAXV,INF);
fill(GC[0],GC[0]+MAXV*MAXV,INF);
scanf("%d%d%d%d",&N,&M,&S,&D);
for(int i=0 ; i<M ; ++i) //存储城市距离和收费情况
{
int u,v;
scanf("%d%d",&u,&v);
scanf("%d%d",&GD[u][v],&GC[u][v]);
GD[v][u]=GD[u][v];
GC[v][u]=GC[u][v];
}
Dijkstra(S);
DFS(S,D);
printf("%d %d
",d[D],c[D]);
return 0;
}