#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define inf 2000000000
#define maxn 352
struct list { int v, z; struct list *n; } *G[maxn];
int C[maxn][maxn], F[maxn][maxn], W[maxn][maxn];
int w[maxn], T[maxn], TZ[maxn], D[maxn];
int H[maxn], posInH[maxn], Hsize;
int N, source, sink;
void bellmanford();
void removeNegativeWeights();
int dijkstra();
void up(int pos);
int pop();
int main()
{
int i, a, b, c, z;
int flow, cost, minCost;
struct list *p;
FILE *in = fopen("fmcm.in", "r");
FILE *out = fopen("fmcm.out", "w");
fscanf(in, "%d %d %d %d", &N, &i, &source, &sink);
for(; i; --i)
{
fscanf(in, "%d %d %d %d", &a, &b, &c, &z);
C[a][b] = c; W[a][b] = z; W[b][a] = -z;
p = malloc(sizeof(struct list));
p->v = b; p->z = z; p->n = G[a]; G[a] = p;
p = malloc(sizeof(struct list));
p->v = a; p->z = -z; p->n = G[b]; G[b] = p;
}
bellmanford();
removeNegativeWeights();
minCost = 0;
while( dijkstra() )
{
flow = inf, cost = 0;
for(i = sink; i != source; i = T[i])
if(flow > C[T[i]][i] - F[T[i]][i])
flow = C[T[i]][i] - F[T[i]][i];
for(i = sink; i != source; i = T[i])
{
F[T[i]][i] += flow;
F[i][T[i]] -= flow;
cost += flow * TZ[i];
}
minCost += cost;
}
fprintf(out, "%d\n", minCost);
fclose(out);
fclose(in);
return 0;
}
int dijkstra()
{
int i;
struct list *p;
for(i = 1; i <= N; ++i)
T[i] = 0,
D[i] = inf,
H[i] = posInH[i] = i;
Hsize = N;
D[source] = 0;
H[1] = source;
H[source] = 1;
posInH[source] = 1;
posInH[1] = source;
while(Hsize)
{
i = pop();
if(i == inf) break;
for(p = G[i]; p; p = p->n)
if(C[i][p->v] > F[i][p->v] && D[p->v] > D[i] + W[i][p->v])
{
D[p->v] = D[i] + W[i][p->v];
T[p->v] = i;
TZ[p->v] = p->z;
up( posInH[p->v] );
}
}
return T[sink];
}
int pop()
{
int v, pos, next, aux;
v = H[1];
H[1] = H[ Hsize-- ];
posInH[ H[1] ] = 1;
for(pos = next = 1; 1; pos = next)
{
if(pos<<1 <= Hsize && D[H[next]] > D[H[pos<<1]])
next <<= 1;
if((pos<<1)+1 <= Hsize && D[H[next]] > D[H[(pos<<1)+1]])
next = (pos<<1)+1;
if(next == pos) break;
aux = H[pos]; H[pos] = H[next]; H[next] = aux;
posInH[ H[pos] ] = pos;
posInH[ H[next] ] = next;
}
return v;
}
void up(int pos)
{
int aux, next;
for(next = pos>>1; pos > 1 && D[H[pos]] < D[H[next]]; pos = next, next >>= 1)
{
aux = H[pos]; H[pos] = H[next]; H[next] = aux;
posInH[ H[pos] ] = pos;
posInH[ H[next] ] = next;
}
}
void removeNegativeWeights()
{
int i, j;
for(i = 1; i <= N; ++i)
for(j = 1; j <= N; ++j)
W[i][j] += w[i] - w[j];
}
void bellmanford()
{
int choose, i, j, ok, v;
int Q[2][maxn], inQ[maxn];
struct list *p;
memset(inQ, 0, sizeof(inQ));
Q[0][0] = 1;
Q[0][1] = source;
choose = 0;
for(i = ok = 1; i < N && ok; ++i)
{
Q[1-choose][0] = 0;
for(ok = 0, j = 1; j <= Q[choose][0]; ++j)
{
v = Q[choose][j];
for(p = G[v]; p; p = p->n)
if(w[p->v] > w[v] + p->z)
{
ok = 1;
w[p->v] = w[v] + p->z;
T[p->v] = v;
if(inQ[p->v] != i)
{
Q[1-choose][++Q[1-choose][0]] = p->v;
inQ[p->v] = i;
}
}
}
choose = 1 - choose;
}
}