#include <fstream>
#include <cstring>
#include <cassert>
using namespace std;
#define NUME "fmcm"
ifstream fi(NUME".in");
ofstream fo(NUME".out");
#define MAXN 351
#define INF 0x3f3f3f3f
int N, M, S, D;
struct list { int nod, cost; list *r; } *L[MAXN];
int F[MAXN][MAXN], C[MAXN][MAXN];
int Dist[MAXN], T[MAXN], tCost;
#define avail(i, j) (C[i][j] - F[i][j])
#define cmp(i, j) (Dist[i] > Dist[j])
class Heap {
private:
int *H, size;
// cmp: Dist[A] > Dist[B] (fiu, tata)
public:
Heap(int n) {
H = new int[n];
size = 0;
}
int top() {
return H[0];
}
bool empty() {
return size == 0;
}
void push(int who) {
int x;
H[size ++] = who;
for (x = size-1; x && !cmp(H[x], H[x-1 >> 1]); x = x-1 >> 1)
swap(H[x], H[x-1 >> 1]);
}
void pop() {
int x;
H[0] = H[--size];
for (x = 0; x < size && (!cmp(H[x], H[x*2+1]) || !cmp(H[x], H[x*2+2])); ) {
int fiu = cmp(H[x*2+1], H[x*2+2]) ? x*2+2 : x*2+1;
swap(H[x], H[fiu]);
x = fiu;
}
}
};
int bellman(int S, int D)
{
int stop = 0, i, j;
memset(Dist, INF, sizeof(T));
Dist[S] = 0;
for (i = 1; i <= N && !stop; ++i) {
stop = 1;
for (j = 1; j <= N; ++j)
for (list *p = L[j]; p; p = p->r)
if (avail(j, p->nod) > 0 &&
Dist[p->nod] > Dist[j] + p->cost) {
Dist[p->nod] = Dist[j] + p->cost;
stop = 0;
}
}
tCost = Dist[D];
return stop;
}
int dijkstra(int S, int D)
{
// HACK
for (int i = 1; i <= N; ++i)
for (list *j = L[i]; j; j = j->r)
if (Dist[i] != INF && Dist[j->nod] != INF)
j->cost += Dist[i] - Dist[j->nod];
// Dijkstra
memset(Dist, INF, sizeof(Dist));
Heap Q(N);
Q.push(S);
Dist[S] = 0;
while (!Q.empty()) {
int x = Q.top(); Q.pop();
for (list *p = L[x]; p; p = p->r) {
if (avail(x, p->nod) > 0 && Dist[p->nod] > Dist[x] + p->cost) {
Dist[p->nod] = Dist[x] + p->cost;
T[p->nod] = x;
Q.push(p->nod);
}
}
}
return Dist[D];
}
void push(int x, int y, int c) {
list *p = new list;
*p = (list) { y, c, L[x] };
L[x] = p;
}
void fluxul(int S, int D)
{
int f, c, r, dist, i;
for (f = c = 0; (dist = dijkstra(S, D)) != INF;
f += r, tCost += dist, c += r*tCost) {
r = INF;
for (i = D; i != S; i = T[i])
r = min(r, avail(T[i], i));
for (i = D; i != S; i = T[i])
F[ T[i] ][i] += r, F[i][ T[i] ] -= r;
}
fo << c << "\n";
}
void citirea()
{
int i;
fi >> N >> M >> S >> D;
while (M--) {
int x, y, c, cost;
fi >> x >> y >> c >> cost;
push(x, y, cost);
push(y, x, -cost);
C[x][y] = c;
}
}
int main()
{
citirea();
assert(bellman(S, D)); // anti-cicluri
fluxul(S, D);
return 0;
}