#include <bits/stdc++.h>
#ifdef LOCAL
#define in cin
#define out cout
#endif
using namespace std;
#ifndef LOCAL
ifstream in("fmcm.in");
ofstream out("fmcm.out");
#endif
const int mmax = 12505;
const int nmax = 355;
const int inf = 1e9;
int n, m, s, d;
bool viz[nmax];
int dist[nmax];
int entered[nmax];
int pi[nmax];
struct edge
{
int fr, nxt, c, w;
edge(int fr = 0, int nxt = 0, int c = 0, int w = 0) : fr(fr), nxt(nxt), c(c), w(w) {}
void debug()
{
cerr << fr << ' ' << nxt << ' ' << c << ' ' << w << '\n';
}
} edges[2 * mmax];
vector<int> adj[nmax];
void resetDist()
{
for (int i = 1; i <= n; i++)
{
dist[i] = inf;
viz[i] = 0;
}
}
void topi()
{
// cerr << "pis\n";
for (int i = 1; i <= n; i++)
{
// cerr << i << '\n';
// cerr << pi[i] << ' ';
pi[i] += dist[i];
// cerr << pi[i] << '\n';
}
}
struct dijelem
{
int a, b;
dijelem(int a, int b) : a(a), b(b) {}
bool operator<(const dijelem &other) const
{
return b > other.b;
}
};
int trans(int a, int b, int w)
{
return a - b + w;
}
bool dijkstra()
{
resetDist();
priority_queue<dijelem> pq;
pq.push({s, 0});
dist[s] = 0;
while (!pq.empty())
{
int nod = pq.top().a;
pq.pop();
if (viz[nod])
continue;
viz[nod] = 1;
for (auto i : adj[nod])
{
if (edges[i].c != 0)
{
int tmp = trans(pi[nod], pi[edges[i].nxt], edges[i].w);
if (dist[edges[i].nxt] > dist[nod] + tmp)
{
entered[edges[i].nxt] = i;
dist[edges[i].nxt] = dist[nod] + tmp;
pq.push({edges[i].nxt, dist[edges[i].nxt]});
}
}
}
}
if (dist[d] == inf)
return 0;
topi();
return 1;
}
void bellmanford()
{
queue<int> q;
dist[s] = 0;
q.push(s);
viz[s] = 1;
while (!q.empty())
{
int nod = q.front();
q.pop();
viz[nod] = 0;
for (auto i : adj[nod])
{
if (edges[i].c == 0)
continue;
if (dist[edges[i].nxt] > dist[nod] + edges[i].w)
{
dist[edges[i].nxt] = dist[nod] + edges[i].w;
if (!viz[edges[i].nxt])
{
viz[edges[i].nxt] = 1;
q.push(edges[i].nxt);
}
}
}
}
topi();
}
void bkt1(int nod, int &cst, int &flux)
{
if (nod == s)
return;
cst += edges[entered[nod]].w;
flux = min(flux, edges[entered[nod]].c);
bkt1(edges[entered[nod]].fr, cst, flux);
}
void bkt2(int nod, int &cst, int &flux)
{
if (nod == s)
return;
edges[entered[nod]].c -= flux;
edges[entered[nod] ^ 1].c += flux;
bkt2(edges[entered[nod]].fr, cst, flux);
}
int main()
{
in >> n >> m >> s >> d;
for (int i = 0, ind = 0; i < m; i++, ind += 2)
{
int a, b, c, w;
in >> a >> b >> c >> w;
edges[ind] = edge(a, b, c, w);
edges[ind + 1] = edge(b, a, 0, -w);
adj[a].push_back(ind);
adj[b].push_back(ind + 1);
}
resetDist();
bellmanford();
int tot = 0;
while (dijkstra())
{
int cst = 0, flux = inf;
bkt1(d, cst, flux);
bkt2(d, cst, flux);
tot += cst * flux;
/*
1 -6
3 -4
8 -3
*/
}
out << tot;
}