#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9; // greater than sum(e.k), INF * sum(sup) should fit
struct NetworkSimplex {
struct Edge { int a, b, c, k, f = 0; };
int n;
vector<int> sup, pei, depth, pi;
vector<Edge> E;
set<int> tree_es;
vector<vector<int>> graph;
vector<int> q;
NetworkSimplex(int n) :
n(n), sup(n, 0), pei(n + 1, -1),
depth(n + 1, 0), pi(n + 1, 0), graph(n + 1) {}
int AddEdge(int a, int b, int c, int k) {
E.push_back({a, b, c, k});
E.push_back({b, a, 0, -k});
return E.size() - 2;
}
void build_tree() {
static vector<vector<int>> graph;
static vector<int> q;
graph.resize(n + 1);
for (int i = 0; i <= n; ++i)
graph[i].clear();
for (auto i : tree_es) {
auto& e = E[i];
graph[e.a].push_back(i);
}
q.resize(1); q[0] = n;
for (int i = 0; i <= n; ++i) {
int node = q[i];
for (auto ei : graph[node]) {
auto& e = E[ei];
int vec = e.b, k = e.k;
if (ei == pei[node]) continue;
pi[vec] = pi[node] + k;
depth[vec] = 1 + depth[node];
pei[vec] = (ei ^ 1);
q.push_back(vec);
}
}
}
int pivot(int ein) {
int f = E[ein].c - E[ein].f;
pair<int, int> eout = {f, ein};
auto walk = [&](int ei, int phase) {
auto nxt = [&](int ei, int dir) {
ei ^= dir;
int res = E[ei].c - E[ei].f;
if (phase == 0) {
f = min(f, res);
eout = min(eout, make_pair(res, ei));
} else {
E[ei].f += f;
E[ei^1].f -= f;
}
ei ^= dir;
return E[ei].b;
};
nxt(ei, 0);
int a = E[ei].a, b = E[ei].b;
while (a != b) {
if (depth[a] > depth[b])
a = nxt(pei[a], 1);
else b = nxt(pei[b], 0);
}
};
for (int phase : {0, 1})
walk(ein, phase);
tree_es.insert(ein); tree_es.insert(ein^1);
tree_es.erase(eout.second); tree_es.erase(eout.second^1);
return f;
}
ll Compute() {
for (int i = 0; i < n; ++i) {
int a = n, b = i; ll c = sup[i], k = -INF;
if (c < 0) c *= -1, swap(a, b);
int ei = AddEdge(a, b, c, k);
tree_es.insert(ei);
tree_es.insert(ei^1);
}
ll answer = 0;
while (true) {
build_tree();
pair<int, int> ein = {0, -1};
for (int i = 0; i < (int)E.size(); ++i) {
auto& e = E[i];
if (e.f < e.c)
ein = min(ein, make_pair(pi[e.a] + e.k - pi[e.b], i));
if (i % (3 * n) == 0 && ein.first > 0) break;
}
if (ein.first == 0) break;
int flow = pivot(ein.second);
answer += 1LL * flow * ein.first;
}
return answer;
}
};
int main() {
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int n, m, s, t; cin >> n >> m >> s >> t;
NetworkSimplex NS(n);
for (int i = 0; i < m; ++i) {
int a, b, c, k; cin >> a >> b >> c >> k;
NS.AddEdge(a - 1, b - 1, c, k);
}
int ed = NS.AddEdge(t - 1, s - 1, INF, -INF);
cout << NS.Compute() + 1LL * INF * NS.E[ed].f << endl;
return 0;
}