#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005, maxt = 1005, INF = 2147483647;
int n, m, A, B, C, T, val[maxn], f[maxn][maxt];
bool vis[maxn][maxt];
struct Route { int x, p, q; };
vector<Route> vec[maxn];
namespace Solve1 {
inline void solve() {
for (register int i = 0; i <= T; i++) f[1][i] = val[i];
for (register int i = 2; i <= n; i++)
for(register int j = 0; j <= T; j++) f[i][j] = INF;
vector<Route>::iterator it;
for (register int i = 2; i <= n; i++) {
for (it = vec[i].begin(); it != vec[i].end(); it++) {
register int x = it->x, p = it->p, q = it->q;
if (f[x][p] == INF) continue;
if (i < n) {
for (register int j = q; j <= T; j++) f[i][j] = min(f[i][j], f[x][p] + val[j - q]);
} else {
for (register int j = q; j <= T; j++) f[i][j] = min(f[i][j], f[x][p]);
}
}
}
int ans = INF;
for (register int i = 0; i <= T; i++)
if (f[n][i] != INF) ans = min(ans, f[n][i] + i);
printf("%d\n", ans);
}
}
int head[maxn], tot = 1;
struct Edge { int to, st, ed, next; } edge[maxn << 1];
inline void addedge(int u, int v, int p, int q) {
edge[tot] = (Edge) {v, p, q, head[u]};
head[u] = tot++;
}
struct Node { int f, x, p; };
inline bool operator < (const Node &a, const Node &b) { return a.f > b.f; }
priority_queue<Node> pq;
inline void dijkstra() {
f[1][0] = 0, pq.push((Node) {0, 1, 0});
while (!pq.empty()) {
int u = pq.top().x, p = pq.top().p;
pq.pop();
if (vis[u][p]) continue;
vis[u][p] = 1;
for (register int i = head[u]; i; i = edge[i].next)
if (edge[i].st >= p) {
int v = edge[i].to, st = edge[i].st, ed = edge[i].ed;
if (f[v][ed] > f[u][p] + val[st - p]) {
f[v][ed] = f[u][p] + val[st - p];
pq.push((Node) {f[v][ed], v, ed});
}
}
}
}
int main() {
scanf("%d%d%d%d%d", &n, &m, &A, &B, &C);
bool fla = true;
for (register int i = 1; i <= m; i++) {
int x, y, p, q;
scanf("%d%d%d%d", &x, &y, &p, &q);
vec[y].push_back((Route) {x, p, q});
addedge(x, y, p, q), T = max(T, q);
if (x > y) fla = false;
}
for (register int i = 0; i <= T; i++) val[i] = A * i * i + B * i + C;
if (fla) return Solve1::solve(), 0;
for (register int i = 1; i <= n; i++)
for (register int j = 0; j <= T; j++) f[i][j] = INF;
dijkstra();
int ans = INF;
for (register int i = 0; i <= T; i++)
if (f[n][i] != INF) ans = min(ans, f[n][i] + i);
printf("%d\n", ans);
return 0;
}