#include <bits/stdc++.h>
using namespace std;
ifstream f ("fmcm.in");
ofstream g ("fmcm.out");
const int nmax = 4e2 + 3;
vector <int> v[nmax];
queue <int> q;
priority_queue < pair <int, int> , vector < pair <int, int> > , greater < pair <int, int> > > h;
int n, s, d, ans, usd[nmax], new_dist[nmax], dist[nmax], ant[nmax];
int flux[nmax][nmax], cost[nmax][nmax], usu[nmax][nmax];
void Bellman_Ford()
{
int i, nod;
for(int i = 1; i <= n; ++i)
dist[i] = INT_MAX / 2;
dist[s] = 0;
q.push(s);
while(!q.empty())
{
nod = q.front();
q.pop();
for(int i = 0; i < v[nod].size(); ++i)
{
int vecin = v[nod][i];
if (flux[nod][vecin] < usu[nod][vecin] && dist[vecin] > dist[nod] + cost[nod][vecin])
{
dist[vecin] = dist[nod] + cost[nod][vecin];
q.push(vecin);
}
}
}
}
int Dijkstra()
{
int nod, flusu = INT_MAX;
for(int i = 1; i <= n; ++i)
{
usd[i] = INT_MAX / 2;
ant[i] = -1;
}
new_dist[s] = 0;
usd[s] = 0;
h.push({0, s});
while (!h.empty())
{
int nod = h.top().second;
int dst = h.top().first;
h.pop();
if (dst <= usd[nod])
{
for(int i = 0; i < v[nod].size(); ++i)
{
int vecin = v[nod][i];
int dist_intre = cost[nod][vecin] + dist[nod] - dist[vecin];
if (flux[nod][vecin] < usu[nod][vecin] && usd[vecin] > usd[nod] + dist_intre)
{
usd[vecin] = usd[nod] + dist_intre;
new_dist[vecin] = cost[nod][vecin] + new_dist[nod];
ant[vecin] = nod;
h.push({usd[vecin], vecin});
}
}
}
}
if (usd[d] == INT_MAX / 2) return false;
nod = d;
while (ant[nod] != -1)
{
flusu = min(flusu, usu[ant[nod]][nod] - flux[ant[nod]][nod]);
nod = ant[nod];
}
nod = d;
while (ant[nod] != -1)
{
flux[ant[nod]][nod] += flusu;
flux[nod][ant[nod]] -= flusu;
nod = ant[nod];
}
ans += flusu * new_dist[d];
for (int i = 1; i <= n; ++i)
dist[i]=new_dist[i];
return true;
}
int m, x, y, c, z;
int main()
{
ios::sync_with_stdio(false);
f.tie(0);
f >> n >> m >> s >> d;
for (int i = 1; i <= m; ++i)
{
f >> x >> y >> c >> z;
v[x].push_back(y);
v[y].push_back(x);
usu[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
}
Bellman_Ford();
while (Dijkstra());
g << ans;
return 0;
}