// O(F_max * m * log n)
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define MOD 1000000007
#define MAX 355
#define INF 1000000000
using namespace std;
map < pair < int, int >, pair < int, int > > initial, h;
vector < int > v[MAX];
int dist[MAX], s;
bool viz[MAX], gasit;
void dfs(int x, int prec);
int main()
{
ifstream cin ("fmcm.in");
ofstream cout ("fmcm.out");
int n, m, t, x, y, c, z;
cin >> n >> m >> s >> t;
for(int i = 1; i <= m; i++)
{
cin >> x >> y >> c >> z;
v[x].pb(y), v[y].pb(x);
initial[{x, y}] = {c, z};
h[{x, y}] = {c, z};
h[{y, x}] = {0, -z};
}
// Rulam o data Bellman Ford, pentru a calcula vectorul dist.
for(int i = 1; i <= n; i++) dist[i] = INF;
dist[s] = 0;
queue < int > q;
q.push(s);
while(!q.empty())
{
x = q.front(), q.pop();
for(int it:v[x])
{
if(h[{x, it}].first > 0 && dist[x] + h[{x, it}].second < dist[it])
{
dist[it] = dist[x] + h[{x, it}].second;
q.push(it);
}
}
}
// Calculam primul pas: F1 (costul minim pentru ca un flux de 1 sa circule de la s la t.)
if(dist[t] != INF) gasit = false, dfs(t, -1);
// Modificam costurile muchiilor a.i. nicio muchie sa nu mai aiba costul negativ.
for(int i = 1; i <= n; i++)
for(int it:v[i])
h[{i, it}].second += dist[i] - dist[it];
priority_queue < pair < int, int >, vector < pair < int, int > >, greater < pair < int, int > > > qq;
while(dist[t] != INF)
{
for (int i = 1; i <= n; i++) dist[i] = INF, viz[i] = false;
dist[s] = 0;
qq.push({dist[s], s});
while(!qq.empty())
{
pair < int, int > x = qq.top();
qq.pop();
if (!viz[x.second])
{
viz[x.second] = true;
for (int it: v[x.second])
if (h[{x.second, it}].first > 0 && dist[x.second] + h[{x.second, it}].second < dist[it])
{
dist[it] = dist[x.second] + h[{x.second, it}].second;
qq.push({dist[it], it});
}
}
}
if(dist[t] != INF) gasit = false, dfs(t, -1);
for(int i = 1; i <= n; i++)
for(int it:v[i])
h[{i, it}].second += dist[i] - dist[it];
}
int r = 0;
for(auto it:initial)
r += it.second.second * (it.second.first - h[it.first].first);
cout << r;
return 0;
}
void dfs(int x, int prec)
{
if(x != s)
{
for(int it:v[x])
if(it != prec && h[{it, x}].first > 0 && dist[it] + h[{it, x}].second == dist[x])
{
h[{it, x}].first--;
h[{x, it}].first++;
dfs(it, x);
if(!gasit)
{
h[{it, x}].first++;
h[{x, it}].first--;
}
else break;
}
}
else gasit = true;
}
/*
5 7 2 5
3 1 7 -1
1 4 3 0
3 4 3 -4
1 5 7 0
4 5 1 1
2 5 8 -3
2 3 4 -3
*/