#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define NMAX 351
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
const int INF = 0x3f3f3f3f, INT = sizeof(int);
int n, m, s, d, FC, CMIN, SZ;
int C[NMAX][NMAX], F[NMAX][NMAX], cost[NMAX][NMAX]; //flux max
int dist[NMAX], t[NMAX], D[NMAX], dst[NMAX];
bool viz[NMAX];
vector < int > v[NMAX]; //cost , nod;
priority_queue < pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > H;
void bellman()
{
int i, nod, vec, sz, cst;
queue <int> Q;
memset(dist, INF, SZ);
dist[s]=0;
viz[s]=true;
Q.push(s);
while(!Q.empty()){
nod = Q.front();
Q.pop();
viz[nod]=0;
sz=v[nod].size();
for(i=0;i<sz;++i){
vec = v[nod][i];
cst = cost[nod][vec];
if(dist[vec] > dist[nod] + cst && C[nod][vec] > F[nod][vec]){
dist[vec] = dist[nod] + cst;
if(!viz[vec] && vec!=d){
viz[vec] = true;
Q.push(vec);
}
}
}
}
}
bool dijkstra()
{
int i, nod, vec, cst, sz, cstVec;
memset(dst, INF, SZ);
memset(t, 0, SZ);
H.push(make_pair(0, s));
dst[s] = D[s] = 0;
t[s]=-1;
while(!H.empty()){
nod = H.top().second;
cst = H.top().first;
H.pop();
if(nod==d || cst!=dst[nod])
continue;
sz = v[nod].size();
for(i=0;i<sz;++i){
vec = v[nod][i];
cstVec = cost[nod][vec];
if(dst[vec] > cst + cstVec + dist[nod] - dist[vec] && C[nod][vec] > F[nod][vec]){
dst[vec] = cst + cstVec + dist[nod] - dist[vec];
t[vec] = nod;
D[vec] = D[nod] + cstVec;
H.push(make_pair(dst[vec], vec));
}
}
}
memcpy(dist, D, SZ);
if(t[d])return true;
return false;
}
int main()
{
int i, j, x, y, cst, cap;
f>>n>>m>>s>>d;
SZ = (n+1) * INT;
for(i=1;i<=m;++i){
f>>x>>y>>cap>>cst;
v[x].push_back(y);
v[y].push_back(x);
C[x][y] = cap;
cost[x][y]=cst;
cost[y][x]=-cst;
}
bellman();
while(dijkstra()){
FC = INF;
for(j=d;j!=s;j=t[j])
FC=min(FC, C[t[j]][j]-F[t[j]][j]);
for(j=d;j!=s;j=t[j]){
F[t[j]][j] += FC;
F[j][t[j]] -= FC;
CMIN += FC * cost[t[j]][j];
}
}
g<<CMIN;
g.close();
return 0;
}