#include <bits/stdc++.h>
using namespace std;
constexpr int maxn = 400;
constexpr int inf = 0x3f3f3f3f;
int n, m, s, t, len[maxn][maxn] = {},
dist[maxn] = {}, real_dist[maxn] = {}, father[maxn] = {}, old_dist[maxn] = {}, flux_left[maxn][maxn] = {};
bitset<maxn> done = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
int rez = 0;
vector<int> vec[maxn];
template <typename T, int maxsz>
class static_queue{
T buf[maxsz], *l = buf, *r = buf;
public:
static_queue(){}
void push(const T x){
*r++ = x;
if(r == buf+maxsz){
r = buf; } }
T front(){
return *l; }
bool empty(){
return l == r; }
void pop(){
++l;
if(l == buf+maxsz){
l = buf; } } };
bool bellman_ford(){
memset(old_dist, 0x3f, sizeof(old_dist));
old_dist[s] = 0;
static_queue<int, maxn> q;
bitset<maxn> in_q = 0;
q.push(s), in_q[s] = true;
while(!q.empty()){
const int cur = q.front();
q.pop(), in_q[cur] = false;
for(const auto next : vec[cur]){
if(flux_left[cur][next] && old_dist[cur] + len[cur][next] < old_dist[next]){
old_dist[next] = old_dist[cur] + len[cur][next];
if(!in_q[next]){
in_q[next] = true;
q.push(next); } } } }
return dist[t] != inf; }
int edge_cost(const int x, const int y){
return len[x][y] + old_dist[x] - old_dist[y]; }
bool dijkstra_and_flux_step(){
pq.emplace(0, s);
memset(dist, 0x3f, sizeof(dist));
dist[s] = 0, real_dist[s] = 0;
while(!pq.empty()){
const int cur = pq.top().second, d_cur = pq.top().first;
pq.pop();
if(dist[cur] != d_cur || cur == t){
continue; }
for(const auto next : vec[cur]){
if(flux_left[cur][next] &&
!done[next] &&
dist[cur] + edge_cost(cur, next) < dist[next]){
dist[next] = dist[cur] + edge_cost(cur, next);
real_dist[next] = real_dist[cur] + len[cur][next];
father[next] = cur;
pq.emplace(dist[next], next); } } }
memcpy(old_dist, dist, sizeof(dist));
if(dist[t] == inf){
return false; }
int d_flux = inf;
for(int nod = t; nod != s; nod = father[nod]){
d_flux = min<int>(d_flux, flux_left[father[nod]][nod]); }
rez += real_dist[t] * d_flux;
for(int nod = t; nod != s; nod = father[nod]){
flux_left[father[nod]][nod] -= d_flux;
flux_left[nod][father[nod]] += d_flux; }
return true; }
int main(){
FILE *f = fopen("fmcm.in", "r"),
*g = fopen("fmcm.out", "w");
fscanf(f, "%d %d %d %d", &n, &m, &s, &t);
for(int i = 0, x, y, c, l; i < m; ++i){
fscanf(f, "%d %d %d %d", &x, &y, &c, &l);
vec[x].push_back(y);
vec[y].push_back(x);
flux_left[x][y] = c;
len[x][y] = l, len[y][x] = -l; }
bellman_ford();
while(dijkstra_and_flux_step());
fprintf(g, "%d\n", rez);
return 0; }