#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, INF = 0x3f3f3f3f;
struct Edge {
int to, h, w;
Edge() {}
Edge(int to, int h, int w) : to(to), h(h), w(w) {}
};
int n, m;
int dis[N];
vector<Edge> G[N];
struct qnode {
int u, w;
qnode() {}
qnode(int u, int w) : u(u), w(w) {}
bool operator<(const qnode &other) const {
return w > other.w;
}
};
void Dijkstra(int s, int h) {
priority_queue<qnode> q;
memset(dis, INF, sizeof dis);
dis[s] = 0;
q.push(qnode(s, 0));
while (!q.empty()) {
int u = q.top().u;
q.pop();
for (int i = 0, len = G[u].size(); i < len; ++i) {
if (h > G[u][i].h) continue;
int v = G[u][i].to, w = G[u][i].w;
if (dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
q.push(qnode(v, dis[v]));
}
}
}
}
int main() {
int cas = 0;
while (scanf("%d %d", &n, &m) != EOF) {
if (n == 0 && m == 0) break;
if (cas) puts("");
cas++;
printf("Case %d:\n", cas);
for (int i = 0; i < N; ++i) G[i].clear();
int Min = INF, Max = 0;
for (int i = 1, u, v, h, w; i <= m; ++i) {
scanf("%d %d %d %d", &u, &v, &h, &w);
if (h == -1) {
h = INF;
}
Min = min(Min, h);
Max = max(Max, h);
G[u].push_back(Edge(v, h, w));
G[v].push_back(Edge(u, h, w));
}
int st, ed, limit;
scanf("%d %d %d", &st, &ed, &limit);
Max = min(Max, limit);
Dijkstra(st, 3);
int l = Min, r = Max, res = -1;
while (r - l >= 0) {
int mid = (l + r) >> 1;
Dijkstra(st, mid);
if (dis[ed] != INF) {
l = mid + 1;
res = mid;
} else {
r = mid - 1;
}
}
if (res != -1) {
Dijkstra(st, res);
printf("maximum height = %d\n", res);
printf("length of shortest route = %d\n", dis[ed]);
} else {
printf("cannot reach destination\n");
}
}
return 0;
}