#include <bits/stdc++.h>
using namespace std;
const int SIZE = 351, INF = (1<<30);
int dp[SIZE], tata[SIZE], dst[SIZE], aux[SIZE];
int capacitate[SIZE][SIZE], cost[SIZE][SIZE];
bool mrk[SIZE];
vector<int> graf[SIZE];
queue<int> que;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
int n, m, s, d;
bool bellman()
{
fill(dst,dst+SIZE,INF);
dst[s] = 0;
fill(mrk, mrk+SIZE,0);
mrk[s] = 1;
que.push(s);
while(!que.empty())
{
int x = que.front();
que.pop();
mrk[x]=0;
for( int y : graf[x] )
{
if( capacitate[x][y] != 0 && dst[y] > dst[x] + cost[x][y] )
{
dst[y] = dst[x] + cost[x][y];
tata[y] = x;
if( y != d && !mrk[y])
{
mrk[y] = 1;
que.push( y );
}
}
}
}
return !(dst[d] == INF);
}
bool dijkstra()
{
fill(dp,dp + SIZE,INF);
fill(aux,aux + SIZE,INF);
dp[s] = aux[s] = 0;
heap.push(make_pair(0,s));
while(!heap.empty())
{
pair<int, int> x = heap.top();
heap.pop();
if( dp[x.second] == x.first)
{
for( int y : graf[x.second] )
{
if( capacitate[x.second][y] != 0 && \
dp[y] > dp[x.second] + dst[x.second] - dst[y] + cost[x.second][y] )
{
dp[y] = dp[x.second] + dst[x.second] - dst[y] + cost[x.second][y];
aux[y] = aux[x.second] + cost[x.second][y];
tata[y] = x.second;
if( y != d )
heap.push( make_pair( dp[y], y ) );
}
}
}
}
copy(aux,aux+SIZE,dst);
return !(dp[d]==INF);
}
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
scanf( "%d %d %d %d", &n, &m, &s, &d );
for( int i = 1; i <= m; i ++ )
{
int x, y, c, z;
scanf("%d %d %d %d", &x, &y, &c, &z);
capacitate[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
graf[x].push_back(y);
graf[y].push_back(x);
}
bellman();
int cost_min = 0;
while(dijkstra())
{
int minim = INF, i;
i = d;
while(i!=s)
{
minim = min(minim, capacitate[tata[i]][i]);
i = tata[i];
}
cost_min += dst[d] * minim;
i = d;
while(i!=s)
{
capacitate[tata[i]][i] -= minim;
capacitate[i][tata[i]] += minim;
i = tata[i];
}
}
printf("%d\n",cost_min);
return 0;
}