#include<iostream>
#include<fstream>
#include<string.h>
#include<vector>
#include<queue>
#include<bitset>
#include<set>
using namespace std;
#define NMAX 355
#define INF 0X3f3f3f3f
int fluxMax[NMAX][NMAX], fluxSol[NMAX][NMAX], bmf[NMAX], T[NMAX], realC[NMAX];
void bellmanFord(int n, int S, vector< pair<int, int> > *adj){ //specificat in enunt ca nu sunt cicluri !!!
int y, cost, q[n+3];
bitset<NMAX> inQueue(false);
vector< pair<int,int> > :: iterator it;
memset(bmf, INF, sizeof(bmf));
q[0] = 1; q[1] = S;
inQueue[S]=true; bmf[S]=0;
for( int i=1; i<=q[0]; i++){
int x = q[i];
inQueue[x] = false;
for(it = adj[x].begin(); it != adj[x].end(); it++ ){
y = it->first; cost = it->second;
if( !fluxMax[x][y] ) continue;
if( bmf[y] > bmf[x] + cost ){
bmf[y] = bmf[x] + cost;
if( !inQueue[y] ){
q[++q[0]] = y;
inQueue[y] = true;
}
}
}
}
}
bool dijkstra( int n, int S, int D, vector< pair<int, int> > *adj ){
int cAux[n+2], costUntil, x, y, cost;
vector< pair<int, int> > :: iterator it;
for(int i=1; i<=n; i++){
T[i] = -1;
cAux[i] = INF;
}
set< pair<int,int> > q;
q.insert( make_pair(0,S) ); cAux[S] = 0;
while(!q.empty()){
x = q.begin()->second;
costUntil = q.begin()->first;
q.erase(q.begin());
if( x == D || cAux[x] != costUntil ) continue;
for( it = adj[x].begin(); it != adj[x].end(); it++){
y = it->first; cost = it->second;
if( fluxMax[x][y] - fluxSol[x][y] <= 0 ) continue;
if( costUntil + cost + bmf[x] - bmf[y] < cAux[y] ){
cAux[y] = costUntil + cost + bmf[x] - bmf[y];
q.insert( make_pair(cAux[y],y) );
T[y] = x;
realC[y] = realC[x] + cost;
}
}
}
memcpy(bmf,realC,sizeof(realC));
return !(cAux[D] == INF );
}
int main(){
int nod, n, m, S, D, x, y, f, c, fMin, minC=0;
FILE *in = fopen("fmcm.in","r");
//citire
fscanf(in,"%i %i %i %i", &n, &m, &S, &D);
vector< pair<int,int> > adj[n+2]; // <destinatie arc, cost>
while(m--){
fscanf(in,"%i %i %i %i",&x, &y, &f, &c);
adj[x].push_back( make_pair(y,c) );
adj[y].push_back( make_pair(x,-c) );
fluxMax[x][y] = f;
}
fclose(in);
bellmanFord(n, S, adj);
while ( dijkstra(n, S, D, adj) ){
fMin = INF;
for(nod = D; nod != S; nod = T[nod])
fMin = min( fMin, fluxMax[ T[nod] ][ nod ] - fluxSol[ T[nod] ][ nod ]);
for(nod = D; nod != S; nod = T[nod]){
fluxSol[ T[nod] ][ nod ] += fMin;
fluxSol[ nod ][ T[nod] ] -= fMin;
}
minC += fMin * realC[D];
}
FILE *out = fopen("fmcm.out","w");
fprintf(out,"%i",minC);
fclose(out);
return 0;
}