#include<bits/stdc++.h>
using namespace std;
int n,m,d;
const int MAXN=155;
struct Edge{int to,len,next,v;}edge[MAXN*MAXN];
int head[MAXN];
double dis[MAXN][505];
int tot;
int maxv=-1;
void add(int f,int t,int l,int v){
tot++;
edge[tot].to=t;
edge[tot].next=head[f];
edge[tot].len=l;
edge[tot].v=v;
head[f]=tot;
}
struct Node{
double dis;
int data,v;
bool operator <(const Node&a) const {return dis>a.dis;}
};
bool vis[MAXN][505];
priority_queue<Node>q;
int fron[MAXN];
int jl[MAXN],top;
double mip[MAXN];
void print(){
double minn=1e9*1.0;
for(int i=1;i<=maxv;i++)minn=min(minn,dis[2][i]);
cout<<minn;
cout<<endl<<mip[2];
int i=d;
while(i!=0){
jl[++top]=fron[i];
i=fron[i];
}
for(int i=top;i>=1;i--)cout<<jl[i]<<' ';
}
void Dijkstra(){
memset(dis,0x7f,sizeof(dis));
memset(mip,0x7f,sizeof(mip));
dis[0][70]=0;
q.push((Node){0,0,70});
while(!q.empty()){
int t=q.top().data, nowv=q.top().v;q.pop();
if(vis[t][nowv])continue;
vis[t][nowv]=1;
for(int i=head[t];i;i=edge[i].next){
int tto=edge[i].to,nv;
if(edge[i].v==0)nv=nowv;else nv=edge[i].v;
if(dis[tto][nv]>dis[t][nowv]+double(edge[i].len)/double(nv)&&!vis[tto][nv]){
dis[tto][nv]=dis[t][nowv]+double(edge[i].len)/double(nv);
q.push((Node){dis[tto][nv],tto,nv});
if(dis[tto][nv]<mip[tto]){
mip[tto]=dis[tto][nv];
fron[tto]=t;
}
}
}
}
print();
}
void Read(){
cin>>n>>m>>d;
for(int i=1;i<=m;i++){
int u,v,vv,l;cin>>u>>v>>vv>>l;
add(u,v,l,vv);
maxv=max(maxv,vv);
}
}
int main(){
Read();
Dijkstra();
return 0;
}