#include <stdio.h>
#include <fstream>
#include <string.h>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#include <assert.h>
#define INF 0x3f3f3f3f
#define NMax 351
#define cmp(x,y) ( Dist[x]<Dist[y] )
#define change(x,y) {swap(H[x],H[y]);swap(Poz[H[x]],Poz[H[y]]);}
using namespace std;
typedef long long ll;
const char IN[]="fmcm.in",OUT[]="fmcm.out";
int N,M,S,D,L,Sum;
int Dist[NMax];
short C[NMax][NMax] , F[NMax][NMax] ,Cost[NMax][NMax],P[NMax],Poz[NMax],H[NMax] , Size[NMax];
bool inQue[NMax];
vector<int> ad[NMax];
void remake(int x)
{
int l=2*x,r=l+1,min=x;
if ( l <= L && cmp(H[l],H[min])) min=l;
if ( r <= L && cmp(H[r],H[min])) min=r;
if (min!=x)
{
change(min,x);
remake(min);
}
}
inline void tryup(int x){
for (int p=Poz[x];p>1 && cmp(H[p],H[p>>1]);p>>=1)
change(p,p>>1);
}
inline void push(int x)
{
if (Poz[x]) return;
Poz[x]=++L;H[Poz[x]]=x;
tryup(x);
}
inline void pop(int x)
{
if (!Poz[x]) return;
for (int p=Poz[x];p>1;p>>=1)
change(p,p>>1);
change(1,L);
Poz[x]=0;H[L--]=0;
remake(1);
}
void BellmanFord()
{
int j,i,x;
memset(Dist,0x3f,sizeof(Dist));
Dist[S]=0;
bool stop=true;
for (j=0;j<N && stop;++j)
for (x=1,stop=false;x<=N;++x)
for (i=0;i<Size[x];++i) if ( C[x][ad[x][i]]>F[x][ad[x][i]] && Dist[x]+Cost[x][ad[x][i]] < Dist[ad[x][i]] )
{
stop=true;
Dist[ad[x][i]]=Dist[x]+Cost[x][ad[x][i]];
}
Sum=Dist[D];
}
bool Dijkstra()
{
int i,j,x;
for (i=1;i<=N;++i) if (Dist[i]!=INF)
for (j=0;j<Size[i];++j)
if ( Dist[ad[i][j]]!=INF ) Cost[i][ad[i][j]]+=Dist[i]-Dist[ad[i][j]];
for (i=1;i<=N;++i)
Dist[i]=INF,P[i]=0;
/*memset(Dist,0x3f,sizeof(Dist));
memset(P,0,sizeof(P));*/
L=0;
push(S);
Dist[S]=0;
while (L>0 )
{
x=H[1];pop(H[1]);
//if (x==D) break;
for (i=0;i<Size[x];++i)
{
if ( C[x][ad[x][i]] > F[x][ad[x][i]] ) assert( Cost[x][ad[x][i]]>=0 );
if ( C[x][ad[x][i]] > F[x][ad[x][i]] && Dist[x]+Cost[x][ad[x][i]]<Dist[ad[x][i]])
{
Dist[ad[x][i]]=Dist[x]+Cost[x][ad[x][i]];
P[ad[x][i]]=x;
if (Poz[ad[x][i]])
{
tryup(ad[x][i]);
remake(Poz[ad[x][i]]);
}
else
push(ad[x][i]);
}
}
}
return Dist[D]!=INF;
}
ll flux()
{
ll ret=0;int p;
while (Dijkstra())
{
int fmin=INF;
for (p=D;p!=S;p=P[p])
fmin=min(fmin,C[P[p]][p]-F[P[p]][p]);
if (!fmin) continue;
for (p=D;p!=S;p=P[p])
{
F[P[p]][p]+=fmin;
F[p][P[p]]-=fmin;
}
Sum+=Dist[D];
ret+=fmin*Sum;
}
return ret;
}
inline void read(int &a,int &b,int &c,int &d)
{
int t[4],i,j;bool minus;
static char s[256],*r;
//scanf("%s",s);r=s;
gets(s);r=s;
for (i=0;i<4;++i)
{
t[i]=0;minus=false;
while (*r && (*r<'0' || *r>'9') && *r!='-') ++r;
if (*r=='-') minus=true,++r;
while ( '0'<=*r && *r<='9' )
t[i]= t[i]*10 + *r - '0',
++r;
if (minus) t[i]=-t[i];
}
a=t[0];b=t[1];c=t[2];d=t[3];
}
int main()
{
int x,y,cap,s;
freopen(IN,"r",stdin);
read(N,M,S,D);
while (M--)
{
read(x,y,cap,s);
ad[x].push_back(y);
ad[y].push_back(x);
C[x][y]=cap;
Cost[x][y]=s;
Cost[y][x]=-s;
}
for (int i=1;i<=N;++i) Size[i]=ad[i].size();
BellmanFord();
freopen(OUT,"w",stdout);
printf("%lld\n",flux());
fclose(stdout);
return 0;
}