const nmax=350;
inf=1000*12000+1;
type ref=^nod;
nod=record
vf,c:integer;
urm:ref;
end;
coada=^dub;
dub=record
x:integer;
urm:coada;
end;
var c,f:array[1..nmax,1..nmax] of integer;
t:Array[1..nmax] of integer;
g:Array[1..nmax] of ref;
d:array[1..nmax] of longint;
n,m,sursa,dest,nrh:integer;
incoada:array[1..nmax] of boolean;
buf:array[1..300000] of char;
function dijkstra:byte;
var i:integer;
q,u,aux:coada;
k:ref;
begin
for i:=1 to n do
d[i]:=inf;
d[sursa]:=0;
fillchar(incoada,sizeof(incoada),false);
new(q);q^.x:=sursa; incoada[sursa]:=true;
u:=q;
while (q<>nil) do
begin
k:=g[q^.x];
while k<>nil do
begin
if (d[k^.vf]>d[q^.x]+k^.c) and (c[q^.x,k^.vf]>f[q^.x,k^.vf]) then
begin
d[k^.vf]:=d[q^.x]+k^.c;
t[k^.vf]:=q^.x;
if not incoada[k^.vf] then
begin
incoada[k^.vf]:=true;
new(aux);
aux^.x:=k^.vf;
u^.urm:=aux;
u:=aux;
end;
end;
k:=k^.urm;
end;
{ aux:=q^.urm;
incoada[q^.x]:=false;
dispose(q);
q:=aux;}
incoada[q^.x]:=false;
q:=q^.urm;
end;
if d[dest]=inf then dijkstra:=0 else dijkstra:=1;
end;
procedure flux;
var min,k:longint;
r:int64;
begin
r:=0;
while dijkstra<>0 do
begin
k:=dest;min:=maxlongint;
while t[k]<>0 do
begin
if c[t[k],k]-f[t[k],k]<min then min:=c[t[k],k]-f[t[k],k];
k:=t[k];
end;
k:=dest;
while t[k]<>0 do
begin
inc(f[t[k],k],min);
dec(f[k,t[k]],min);
k:=t[k];
end;
inc(r,min*d[dest]);
end;
assign(output,'fmcm.out');rewrite(output);
writeln(r);close(output);
end;
procedure adaugare(x,y,c:integer);
var p:ref;
begin
new(p);
p^.vf:=y;
p^.c:=c;
p^.urm:=g[x];
g[x]:=p;
end;
procedure citire;
var i:longword;
x,y,c1,c2:integer;
begin
assign(input,'fmcm.in');settextbuf(input,buf);reset(input);
readln(n,m,sursa,dest);
for i:=1 to m do
begin
readln(x,y,c1,c2);
c[x,y]:=c1;
adaugare(x,y,c2);
adaugare(y,x,-c2);
end;
close(input);
end;
begin
citire;
flux;
end.