#include <cstdio>
#include <vector>
#include <cstring>
#define maxn 600
#define inf 0x3f
using namespace std;
int n, m, s, d;
int a, b, cap, ct, i, j;
vector <int> g[maxn], cost[maxn], tru[maxn];
int f[maxn][maxn], c[maxn][maxn];
int flux[maxn], up[maxn], viz[maxn];
int dist[maxn], dmin[maxn];
int heap[2 * maxn], heap_sz, poz_heap[maxn];
bool ok;
int rez, sum;
inline void bford(int src) {
int p, u, i, nod, fiu;
int q[maxn * maxn];
dmin[src] = 0;
q[1] = src;
p = u = 1;
memset(viz, 0, sizeof(viz));
while (p <= u) {
nod = q[p];
viz[nod] = 0;
for (i = 0; i < g[nod].size(); i++) if (tru[nod][i]) {
fiu = g[nod][i];
if (dmin[nod] + cost[nod][i] < dmin[fiu]) {
dmin[fiu] = dmin[nod] + cost[nod][i];
if (viz[fiu] == 0) {
u++;
q[u] = fiu;
viz[fiu] = 1;
}
}
}
p++;
}
sum = dmin[d];
}
void init() {
memset(flux, 0, sizeof(flux));
memset(up, -1, sizeof(up));
memset(dmin, inf, sizeof(dmin));
dmin[s] = 0;
ok = 0;
}
inline void swap(int &a, int &b) {
int aux;
aux = a; a = b; b = aux;
}
inline void heap_down() {
int nod = 1;
while (2 * nod <= heap_sz) {
// fprintf(stderr, "%d\n", nod);
if (dmin[heap[nod]] > min(dmin[heap[2 * nod]], dmin[heap[2 * nod + 1]])) {
if (dmin[heap[2 * nod]] < dmin[heap[2 * nod + 1]]) {
swap(heap[nod], heap[2 * nod]);
poz_heap[heap[nod]] = nod;
poz_heap[heap[2 * nod]] = 2 * nod;
nod = 2 * nod;
}
else {
swap(heap[nod], heap[2 * nod + 1]);
poz_heap[heap[nod]] = nod;
poz_heap[heap[2 * nod + 1]] = 2 * nod + 1;
nod = 2 * nod + 1;
}
}
else
break;
}
}
inline void heap_up(int nod) {
while (nod > 1) {
// fprintf(stderr, "%d\n", nod);
if (dmin[heap[nod]] < dmin[heap[nod / 2]]) {
swap(heap[nod], heap[nod / 2]);
poz_heap[heap[nod]] = nod;
poz_heap[heap[nod / 2]] = nod / 2;
nod /= 2;
}
else
break;
}
}
inline int dijkstra() {
int i, j, fiu, nod, fmin;
dmin[s] = 0;
//mai intai ar trebui sa mesteresc la costuri
for (i = 1; i <= n; i++)
for (j = 0; j < g[i].size(); j++) {
fiu = g[i][j];
if (dmin[i] <= 1000000000 && dmin[fiu] <= 1000000000)
cost[i][j] += dmin[i] - dmin[fiu];
}
init();
//sa fac initializari pentru dijkstra
heap_sz = 0;
for (i = 1; i <= n; i++) {
heap_sz++;
heap[i] = i;
poz_heap[i] = heap_sz;
}
swap(heap[1], heap[s]);
poz_heap[1] = s; poz_heap[s] = 1;
//dijkstra propriu-zis
for (i = 1; i < n && dist[heap[1]] <= 1000000000; i++) {
nod = heap[1];
for (j = 0; j < g[nod].size(); j++) {
fiu = g[nod][j];
// fprintf(stderr, "%d\n", fiu);
if (f[nod][fiu] < c[nod][fiu] && dmin[nod] + cost[nod][j] < dmin[fiu]) {
dmin[fiu] = dmin[nod] + cost[nod][j];
// fprintf(stderr, "%d\n", poz_heap[fiu]);
heap_up(poz_heap[fiu]);
up[fiu] = nod;
}
}
heap[1] = heap[heap_sz];
poz_heap[heap[heap_sz]] = 0;
heap[heap_sz] = 0;
heap_sz--;
heap_down();
}
// fprintf(stderr, "\n");
// fprintf(stderr, "%d\n", dmin[d]);
if (dmin[d] > 1000000000)
return 0;
ok = 1;
fmin = 1000000000;
for (i = d; i != s; i = up[i])
fmin = min(fmin, c[up[i]][i] - f[up[i]][i]);
for (i = d; i != s; i = up[i]) {
f[up[i]][i] += fmin;
f[i][up[i]] -= fmin;
}
sum += dmin[d];
return (sum * fmin);
}
int main() {
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
scanf("%d%d%d%d", &n, &m, &s, &d);
for (i = 1; i <= m; i++) {
scanf("%d%d%d%d", &a, &b, &cap, &ct);
g[a].push_back(b);
tru[a].push_back(1);
g[b].push_back(a);
tru[b].push_back(0);
c[a][b] = cap;
cost[a].push_back(ct);
cost[b].push_back(-ct);
}
memset(dmin, 0x3f, sizeof(dmin));
dmin[0] = 1000000000;
bford(s);
ok = 1;
while (ok)
rez += dijkstra();
printf("%d\n", rez);
return 0;
}