/**
* Author: Stanford
* Date: Unknown
* Source: Stanford Notebook
* Description: Min-cost max-flow. cap[i][j] != cap[j][i] is allowed; double edges are not.
* If costs can be negative, call setpi before maxflow, but note that negative cost cycles are not allowed (that's NP-hard).
* To obtain the actual flow, look at positive values only.
* Status: Tested on kattis mincostmaxflow
* Time: Approximately O(E^2)
*/
#include <bits/stdc++.h>
using namespace std;
using T = int;
const T kInf = numeric_limits<T>::max() / 4;
struct MFMC {
int n;
vector<vector<T>> C, F, K;
vector<vector<int>> G;
vector<T> dist, pi;
vector<int> par;
MFMC(int n) :
n(n), C(n, vector<T>(n, 0)), F(C), K(C),
G(n), dist(n), pi(n), par(n) {}
void AddEdge(int from, int to, T cap, T cost) {
C[from][to] = cap;
K[from][to] = cost;
K[to][from] = -cost;
G[from].push_back(to);
G[to].push_back(from);
}
bool dijkstra(int s, int t) {
fill(dist.begin(), dist.end(), kInf);
fill(par.begin(), par.end(), -1);
priority_queue<pair<T, int>> q;
dist[s] = 0; q.emplace(0, s);
while (!q.empty()) {
int node; T d;
tie(d, node) = q.top(); q.pop();
if (dist[node] != -d) continue;
for (auto vec : G[node]) {
T now = dist[node] + pi[node] - pi[vec] + K[node][vec];
if (F[node][vec] < C[node][vec] && now < dist[vec]) {
dist[vec] = now;
par[vec] = node;
q.emplace(-dist[vec], vec);
}
}
}
for (int i = 0; i < n; ++i)
pi[i] = min(pi[i] + dist[i], kInf);
return par[t] != -1;
}
pair<T, T> Compute(int s, int t) {
T flow = 0, cost = 0;
while (dijkstra(s, t)) {
T now = kInf;
for (int node = t; node != s; node = par[node])
now = min(now, C[par[node]][node] - F[par[node]][node]);
for (int node = t; node != s; node = par[node]) {
F[par[node]][node] += now;
F[node][par[node]] -= now;
cost += now * K[par[node]][node];
}
flow += now;
}
return {flow, cost};
}
// If some costs can be negative, call this before maxflow:
void SetPi(int s) { // (otherwise, leave this out)
fill(pi.begin(), pi.end(), kInf); pi[s] = 0;
int it = n, ch = 1; T v;
while (ch-- && it--)
for (int i = 0; i < n; ++i) if (pi[i] != kInf)
for (auto vec : G[i]) if (C[i][vec])
if ((v = pi[i] + K[i][vec]) < pi[vec])
pi[vec] = v, ch = 1;
assert(it >= 0); // negative cost cycle
}
};
int main() {
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int n, m, s, d; cin >> n >> m >> s >> d;
MFMC flow(n);
while (m--) {
int a, b, c, k; cin >> a >> b >> c >> k;
flow.AddEdge(a - 1, b - 1, c, k);
}
flow.SetPi(s - 1);
auto p = flow.Compute(s - 1, d - 1);
cout << p.second << endl;
return 0;
}