#include <bits/stdc++.h>
using namespace std;
#define nmax 352
#define inf 0x3f3f3f3f
int n, m, S, D, x, y, cap, ct, drum, flux;
int d[nmax], df[nmax], db[nmax], t[nmax], c[nmax][nmax], F[nmax][nmax], viz[nmax], cst[nmax][nmax];
long long rez;
struct muchie
{
int x, c;
};
struct cmp
{
bool operator()(muchie x, muchie y)
{
return d[x.x] > d[y.x];
}
};
vector <muchie> G[nmax];
queue <int> q;
priority_queue <muchie, vector<muchie>, cmp> pq;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
inline bool dijkstra()
{
memset(d, inf, sizeof(d));
d[S] = 0; df[S] = 0;
pq.push({S,d[S]});
while (!pq.empty())
{
int nod = pq.top().x;
int cost = pq.top().c;
pq.pop();
if (d[nod] != cost)
continue;
for (auto &it : G[nod])
{
if (c[nod][it.x])
{
int dist = d[nod] + it.c + db[nod] - db[it.x];
if (dist < d[it.x])
{
d[it.x] = dist;
df[it.x] = df[nod] + it.c;
t[it.x] = nod;
pq.push({it.x, d[it.x]});
}
}
}
}
memcpy(db, df, sizeof(d));
if (d[D] == inf)
return false;
int fm = inf, cc = 0;
for (int nod = D; nod != S; nod = t[nod])
{
fm = min(fm, c[t[nod]][nod]);
cc = cst[t[nod]][nod];
}
flux += fm;
rez += fm * df[D];
for (int nod = D; nod != S; nod = t[nod])
{
c[t[nod]][nod] -= fm;
c[nod][t[nod]] += fm;
}
return true;
}
inline bool BellmanFord()
{
memset(viz, 0, sizeof(viz));
memset(db, inf, sizeof(db));
db[S] = 0;
q.push(S);
viz[S] = 1;
while (!q.empty())
{
int nod = q.front();
q.pop();
for (auto &it : G[nod])
{
if (c[nod][it.x] && db[nod] + it.c < db[it.x])
{
db[it.x] = db[nod] + it.c;
if (!viz[it.x])
{
q.push(it.x);
viz[it.x] = 1;
}
}
}
viz[nod] = 0;
}
if (db[D] == inf)
return false;
return true;
}
int main()
{
freopen("fmcm.in", "rt", stdin);
freopen("fmcm.out", "wt", stdout);
scanf("%d %d %d %d", &n, &m, &S, &D);
for (; m; m--)
{
scanf("%d %d %d %d", &x, &y, &cap, &ct);
c[x][y] = cap;
G[x].push_back({y,ct});
G[y].push_back({x,-ct});
cst[x][y] = ct;
cst[y][x] = -ct;
}
BellmanFord();
while (dijkstra());
printf("%d", rez);
f.close();
g.close();
return 0;
}