#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#define INF 1000000000
#define MAXN 350
#define MASK 511
#define MAXM 25000
FILE *fin = fopen("fmcm.in", "r"), *fout = fopen("fmcm.out", "w");
int care[MAXN + 1];
struct myc {
int x, y, z;
myc(int _x, int _y, int _z) {
x = _x;
y = _y;
z = _z;
}
};
class fmcmDirected {
int s, d, k, ans, rez;
int f[MAXM], c[MAXM];
std::vector <myc> g[MAXN];
bool viz[MAXN];
int q[MASK + 1], dist[MAXN];
int heap[MAXN], poz[MAXN];
int from[MAXN], cine[MAXN];
int dp[MAXN], real[MAXN];
public :
inline void initialize(int n) {
s = k = ans = rez = 0;
d = n;
}
inline void add(int x, int y, int z, int t) {
muchie(x, y, z, t);
muchie(y, x, 0, -t);
}
inline void flood(){
bellman();
while (dijkstra())
go();
}
inline int flux() {
return ans;
}
inline int cost() {
return rez;
}
private :
inline void muchie(int x, int y, int z, int t) {
f[k] = 0;
c[k] = z;
g[x].push_back(myc(y, t, k));
k++;
}
inline void bellman() {
for (int i = s; i <= d; i++)
dist[i] = INF;
memset(viz, 0, sizeof(bool) * (d + 1));
int st = 0, dr = 1;
dist[s] = 0;
viz[s] = 1;
while (st < dr) {
int x = q[st & MASK];
viz[x] = 0;
st++;
for (auto &y : g[x]) {
if (c[y.z] > f[y.z] && dist[x] + y.y < dist[y.x]) {
dist[y.x] = dist[x] + y.y;
if(viz[y.x] == 0) {
viz[y.x] = 1;
q[dr & MASK] = y.x;
dr++;
}
}
}
}
}
inline bool cmp(int a, int b) {
return dp[a] < dp[b];
}
inline int tata(int p) {
return (p - 1) / 2;
}
inline int fiust(int p) {
return 2 * p + 1;
}
inline int fiudr(int p) {
return 2 * p + 2;
}
inline void mySwap(int p, int q) {
int aux = heap[p];
heap[p] = heap[q];
heap[q] = aux;
poz[heap[p]] = p;
poz[heap[q]] = q;
}
inline void urcare(int p) {
int tad;
while (p > 0 && cmp(heap[p], heap[tata(p)])) {
tad = tata(p);
mySwap(p, tad);
p = tad;
}
}
inline void coborare(int p) {
int q;
bool f = 1;
while(f && (q = fiust(p)) <= d) {
if(fiudr(p) <= d && cmp(heap[fiudr(p)], heap[q]))
q = fiudr(p);
if(cmp(heap[q], heap[p])) {
mySwap(p, q);
p = q;
}else f = 0;
}
}
inline bool dijkstra() {
for (int i = s; i <= d; i++)
heap[i] = poz[i] = i;
for (int i = s; i <= d; i++)
dp[i] = INF;
memset(viz, 0, sizeof(bool) * (d + 1));
dp[s] = 0;
while (dp[heap[0]] != INF) {
int x = heap[0];
for (auto &y : g[x]) {
if (viz[y.x] == 0 && c[y.z] > f[y.z] && dp[x] + y.y + dist[x] - dist[y.x] < dp[y.x]) {
from[y.x] = x;
cine[y.x] = y.z;
real[y.x] = real[x] + y.y;
dp[y.x] = dp[x] + y.y + dist[x] - dist[y.x];
urcare(poz[y.x]);
}
}
dp[x] = INF;
viz[x] = 1;
coborare(0);
}
for (int i = s; i <= d; i++)
dist[i] = real[i];
return viz[d];
}
inline void go() {
int x = d, r = INF;
while (x != s) {
r = std::min(r, c[cine[x]] - f[cine[x]]);
x = from[x];
}
x = d;
while (x != s) {
f[cine[x]] += r;
f[1 ^ cine[x]] -= r;
x = from[x];
}
ans += r;
rez += r * real[d];
}
}T;
int main() {
int n, m, s, d;
fscanf(fin, "%d%d%d%d", &n, &m, &s, &d);
care[s] = 0;
care[d] = n - 1;
int q = 0;
for (int i = 1; i <= n; i++)
if (i != s && i != d)
care[i] = ++q;
T.initialize(n - 1);
for (int i = 0; i < m; i++) {
int x, y, z, t;
fscanf(fin, "%d%d%d%d", &x, &y, &z, &t);
T.add(care[x], care[y], z, t);
}
T.flood();
fprintf(fout, "%d\n", T.cost());
fclose(fin);
fclose(fout);
return 0;
}