类似最短路
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include <queue>
#define REP(i, n) for(int i=0; i<n; i++)
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define CLR(a, b) memset(a, b, sizeof(a))
#define PB push_back
using namespace std;
const int maxn = 100010;
const int INF = 100000007;
int n, m, s, t;
struct Node{
int to, next;
int at, bt, tt;
};
Node adj[50050];
int head[310];
int tot;
void init()
{
tot = 0;
CLR(head, -1);
}
void add_edge(int x, int y, int at, int bt, int tt)
{
adj[tot].to = y;
adj[tot].at = at;
adj[tot].bt = bt;
adj[tot].tt = tt;
adj[tot].next = head[x];
head[x] = tot++;
}
int dp[310];
int inq[310];
void spfa()
{
REP(i, n + 1) dp[i] = INF;
dp[s] = 0;
CLR(inq, 0);
inq[s] = 1;
queue<int>q;
while (!q.empty()) q.pop();
q.push(s);
while (!q.empty())
{
int u = q.front(); q.pop();
inq[u] = 0;
for (int r = head[u]; r != -1; r = adj[r].next)
{
if (adj[r].at < adj[r].tt) continue;
int v = adj[r].to;
int y = dp[u] % (adj[r].at + adj[r].bt);
int x = adj[r].at - y;
if (x >= adj[r].tt)
{
int nextv = dp[u] + adj[r].tt;
if (dp[v] > nextv)
{
dp[v] = nextv;
if (!inq[v]) inq[v] = 1, q.push(v);
}
}
else
{
int nextv = dp[u] + adj[r].tt + (adj[r].at + adj[r].bt - y);
if (dp[v] > nextv)
{
dp[v] = nextv;
if (!inq[v]) inq[v] = 1, q.push(v);
}
}
}
}
}
int main()
{
int nc = 1;
int at, bt, tt;
int x, y;
while (~scanf("%d%d%d%d", &n, &m, &s, &t))
{
init();
while (m--)
{
scanf("%d%d%d%d%d", &x, &y, &at, &bt, &tt);
add_edge(x, y, at, bt, tt);
}
spfa();
printf("Case %d: %d\n", nc++, dp[t]);
}
}