#include<cstdio>
#include<vector>
#define maxn 505
#define inf 1000000000
using namespace std;
struct edge {
int node, length, time;
edge() {}
edge(int n, int l, int t) : node(n), length(l), time(t) {}
};
vector<edge> g[maxn];
int N, M;
vector<int> pre[maxn];
bool visit[maxn];
int temp[maxn];
vector<int> shortest, fastest, dfs;
int len4shortest = inf, time4shortest = inf;
int time4fastest = inf, inters4fastest = inf;
void dfs_length(int s, int d, int length, int time) {
if (s == d) {
if (length < len4shortest || (length == len4shortest && time < time4shortest)) {
shortest = dfs;
len4shortest = length;
time4shortest = time;
return;
}
else return;
}
for (int i = 0; i < pre[d].size(); i++) {
int t = pre[d][i];
edge e;
for (int j = 0; j < g[t].size(); j++) {
e = g[t][j];
if (e.node == d) break;
}
dfs.push_back(t);
dfs_length(s, t, length + e.length, time + e.time);
dfs.pop_back();
}
return;
}
void dfs_time(int s, int d, int time, int inter) {
if (s == d) {
if (time < time4fastest || (time == time4fastest && inter < inters4fastest)) {
fastest = dfs;
time4fastest = time;
inters4fastest = inter;
return;
}
else return;
}
for (int i = 0; i < pre[d].size(); i++) {
int t = pre[d][i];
edge e;
for (int j = 0; j < g[t].size(); j++) {
e = g[t][j];
if (e.node == d) break;
}
dfs.push_back(t);
dfs_time(s, t, time + e.time, inter + 1);
dfs.pop_back();
}
return;
}
void dij_time(int s, int d) {
for (int i = 0; i <= N; i++) {
visit[i] = false;
temp[i] = inf;
}
temp[s] = 0;
int n = N, smallest = N;
bool flag = false;
while(n--) {
if (flag == true) break;
smallest = N; // here
for (int i = 0; i < N; i++) {
if (visit[i] == false && temp[i] < temp[smallest])
smallest = i;
}
visit[smallest] = true;
if (smallest == d) flag = true;
if (smallest == inf) printf("error\n"); // test delete
for (int i = 0; i < g[smallest].size(); i++) {
edge e = g[smallest][i];
if (visit[e.node] == false && e.time + temp[smallest] < temp[e.node]) {
temp[e.node] = e.time + temp[smallest];
pre[e.node].clear();
pre[e.node].push_back(smallest);
}
else if (visit[e.node] == false && e.time + temp[smallest] == temp[e.node]) {
pre[e.node].push_back(smallest);
}
}
}
}
void dij_length(int s, int d) {
for (int i = 0; i <= N; i++) {
visit[i] = false;
temp[i] = inf;
}
temp[s] = 0;
int n = N, smallest = N;
bool flag = false;
while(n--) {
if (flag == true) break;
smallest = N; // here
for (int i = 0; i < N; i++) {
if (visit[i] == false && temp[i] < temp[smallest])
smallest = i;
}
visit[smallest] = true;
if (smallest == d) flag = true;
if (smallest == inf) printf("error\n"); // test delete
for (int i = 0; i < g[smallest].size(); i++) {
edge e = g[smallest][i];
if (visit[e.node] == false && e.length + temp[smallest] < temp[e.node]) {
temp[e.node] = e.length + temp[smallest];
pre[e.node].clear();
pre[e.node].push_back(smallest);
}
else if (visit[e.node] == false && e.length + temp[smallest] == temp[e.node]) {
pre[e.node].push_back(smallest);
}
}
}
}
int main() {
int a, b, c, d, e;
scanf("%d%d", &N, &M);
while(M--) {
scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
g[a].push_back(edge(b, d, e));
if (c == 0) g[b].push_back(edge(a, d, e));
}
int source, dest;
scanf("%d%d", &source, &dest);
dij_length(source, dest);
dfs_length(source, dest, 0, 0);
dfs.clear();
dij_time(source, dest);
dfs_time(source, dest, 0, 1);
if (shortest == fastest) {
printf("Distance = %d; Time = %d: ", len4shortest, time4fastest);
for (int i = shortest.size() - 1; i >= 0; i--) {
printf("%d -> ", shortest[i]);
}
printf("%d\n", dest);
}
else {
printf("Distance = %d: ", len4shortest);
for (int i = shortest.size() - 1; i >= 0; i--) {
printf("%d -> ", shortest[i]);
}
printf("%d\n", dest);
printf("Time = %d: ", time4fastest);
for (int i = fastest.size() - 1; i >= 0; i--) {
printf("%d -> ", fastest[i]);
}
printf("%d\n", dest);
}
}