#include <bits/stdc++.h>
using namespace std;
using T = int;
const T INF = numeric_limits<T>::max() / 4;
struct MFMC {
struct Edge { int from, to; T flow, cap, cost; };
int n;
vector<T> dist, pi;
vector<int> par; vector<vector<int>> graph;
vector<vector<T>> flow, cap, cost;
vector<Edge> es;
MFMC(int n) : n(n), pi(n, 0), par(n, -1), graph(n), flow(n, vector<T>(n, 0)), cap(flow), cost(flow) {}
void AddEdge(int a, int b, T c, T k) {
auto add = [&](int a, int b, T c, T k) {
graph[a].push_back(b);
cap[a][b] = c; cost[a][b] = k;
};
add(a, b, c, k); add(b, a, 0, -k);
}
bool relax(int node, int vec) {
if (dist[node] == INF) return false;
T now = dist[node] + pi[node] - pi[vec] + cost[node][vec];
if (flow[node][vec] < cap[node][vec] && now < dist[vec]) {
dist[vec] = now; par[vec] = node;
return true;
}
return false;
}
bool dijkstra(int s, int t) {
dist.assign(n, INF); par.assign(n, -1);
priority_queue<pair<T, int>> pq;
dist[s] = 0; pq.emplace(0, s);
while (!pq.empty()) {
T d; int node; tie(d, node) = pq.top(); pq.pop();
// auto [d, node] = pq.top(); pq.pop();
if (dist[node] != -d) continue;
for (auto vec : graph[node])
if (relax(node, vec))
pq.emplace(-dist[vec], vec);
}
for (int i = 0; i < n; ++i) {
assert(dist[i] >= 0);
pi[i] = min(pi[i] + dist[i], INF);
}
return par[t] != -1;
}
pair<T, T> Compute(int s, int t) {
T tflow = 0, tcost = 0;
while (dijkstra(s, t)) {
T now = INF;
for (int node = t; node != s; node = par[node])
now = min(now, cap[par[node]][node] - flow[par[node]][node]);
assert(now > 0);
for (int node = t; node != s; node = par[node]) {
flow[par[node]][node] += now;
flow[node][par[node]] -= now;
tcost += now * cost[par[node]][node];
}
tflow += now;
}
return {tflow, tcost};
}
// If some costs can be negative, call this before maxflow:
void SetPi(int s) { // (otherwise, leave this out)
dist.assign(n, INF); dist[s] = 0;
int it = n, ch = 1;
while (ch-- && it--)
for (int i = 0; i < n; ++i)
for (auto j : graph[i])
ch |= relax(i, j);
assert(it >= 0); // negative cost cycle
swap(pi, dist);
}
};
int main() {
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int n, m, s, t; cin >> n >> m >> s >> t;
MFMC F(n);
for (int i = 0; i < m; ++i) {
int a, b, c, k; cin >> a >> b >> c >> k;
F.AddEdge(a - 1, b - 1, c, k);
}
F.SetPi(s - 1);
cout << F.Compute(s - 1, t - 1).second << endl;
return 0;
}