#include<fstream>
#include<string.h>
using namespace std;
#define INF 9999999999
#define Nmax 353
int N,M,Cost[Nmax][Nmax],C[Nmax][Nmax],F[Nmax][Nmax],T[Nmax],S,D,flux=0,drum=0,c=0,Q[500007],Dist[Nmax];
bool U[Nmax];
struct lista{int nod; lista *leg;} *G[Nmax];
void adaug(int i,int j)
{
lista *p;
p=new lista;
p->nod=j;
p->leg=G[i];
G[i]=p;
}
void citire()
{
scanf("%d %d %d %d",&N,&M,&S,&D);
int i,j,c,z;
while(M--)
{
scanf("%d %d %d %d",&i,&j,&c,&z);
adaug(i,j);
adaug(j,i);
C[i][j]=c;
Cost[i][j]=z;
Cost[j][i]=-z;
}
}
int BF(int S,int D)
{
int p,u;
lista *q;
for(int i=1;i<=N;++i) Dist[i]=INF,U[i]=0,T[i]=0;
p=u=1;
Q[p]=S; T[S]=-1; Dist[S]=0;
for(p=1;p<=u;p++)
{
int nod=Q[p];
for(q=G[nod];q;q=q->leg)
if(C[nod][q->nod]>F[nod][q->nod]&&Dist[q->nod]>Dist[nod]+Cost[nod][q->nod])
{
Dist[q->nod]=Dist[nod]+Cost[nod][q->nod];
T[q->nod]=nod;
if(!U[q->nod]) // daca nu se afla deja in coada
{
u++; Q[u]=q->nod; U[q->nod]=1;
}
}
U[nod]=0; // se scoata din coada elementul curent
}
if(T[D]) {c=Dist[D]; return 1;}
else return 0;
}
void flow(int S,int D)
{
int i,r;
for(flux=0,drum=0;BF(S,D);flux+=r,drum+=r*c)
{
r=INF;
for(i=D;i-S;i=T[i]) r=min(r,C[T[i]][i]-F[T[i]][i]);
for(i=D;i-S;i=T[i])
{
F[T[i]][i]+=r;
F[i][T[i]]-=r;
}
}
}
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
citire();
flow(S,D);
printf("%d\n",drum);
return 0;
}