/*input
5 7 2 5
3 1 7 -1
1 4 3 0
3 4 3 -4
1 5 7 0
4 5 1 1
2 5 8 -3
2 3 4 -3
*/
#include <bits/stdc++.h>
using namespace std;
#define sp ' '
#define endl '\n'
#define fi first
#define se second
#define mp make_pair
#define N 355
#define bit(x,y) ((x>>y)&1LL)
#define loop(i,l,r) for(int i=(int)(l); i<=(int)(r); i++)
void read(int &number) {
bool negative = false;
int c;
number = 0;
c = getchar();
while (c == ' ' || c == '\n')
c = getchar();
if (c == '-') {
negative = true;
c = getchar();
}
for (; (c > 47 && c < 58); c = getchar())
number = number * 10 + c - 48;
if (negative)
number = -number;
}
template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
return os << '(' << a.first << ", " << a.second << ')';
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) {
os << '[';
for (unsigned int i = 0; i < a.size(); i++)
os << a[i] << (i < a.size() - 1 ? ", " : "");
os << ']';
return os;
}
template <class T>
ostream &operator<<(ostream &os, const set<T> &a) {
os << '{';
for (typename set<T>::iterator it = a.begin(); it != a.end(); it++) {
typename set<T>::iterator jt = it;
os << *it << (++jt != a.end() ? ", " : "");
}
os << '}';
return os;
}
template <class T1, class T2>
ostream &operator<<(ostream &os, map<T1, T2> &a) {
os << "{\n";
for (typename map<T1, T2>::iterator it = a.begin(); it != a.end(); it++) {
typename map<T1, T2>::iterator jt = it;
os << " " << it->first << ": " << it->second << (++jt != a.end() ? ",\n" : "\n");
}
os << '}';
return os;
}
int cap[N][N], cost[N][N];
int n, m, s, d;
vector<int> a[N];
class MinCostMaxFlow {
int t[N], dis[N];
int h[N], hsize, newd[N], idx[N], aux[N];
int q[130000], vis[N];
const int INF = 1e9 + 7;
int cmin = INF;
bool bfs(int s, int d) {
memset(vis, 0, sizeof(vis));
vis[s] = 1;
int st = 1, en = 1;
for (int i = 1; i <= n; ++i)
dis[i] = INF;
dis[s] = 0; q[st] = s; t[s] = -1;
while (st <= en) {
int u = q[st];
++st;
vis[u] = 0;
for (auto it : a[u]) {
if (!(cap[u][it] > 0 && dis[u] + cost[u][it] < dis[it])) continue;
dis[it] = dis[u] + cost[u][it];
if (!vis[it]) {
++en;
q[en] = it;
vis[it] = true;
}
t[it] = u;
}
}
if (dis[d] != INF) return true;
return 0;
}
void downh() {
int aux = 1;
while (aux * 2 <= hsize) {
int index = aux;
if (newd[h[2 * aux]] < newd[h[aux]]) index = 2 * aux;
if (2 * aux + 1 <= hsize && newd[h[2 * aux + 1]] < newd[h[index]])
index = 2 * aux + 1;
if (index == aux) break;
swap(idx[h[aux]], idx[h[index]]);
swap(h[aux], h[index]);
aux = index;
}
}
void uph(int x) {
while (x > 1 && newd[h[x / 2]] > newd[h[x]]) {
swap(idx[h[x]], idx[h[x / 2]]);
swap(h[x / 2], h[x]);
x /= 2;
}
}
bool existFlow(int s, int d) {
memset(t, 0, sizeof(t));
aux[s] = 0;
t[s] = -1;
for (int i = 1; i <= n; ++i) {
h[i] = idx[i] = i;
newd[i] = INF;
}
newd[s] = 0;
h[1] = idx[1] = s;
h[s] = idx[s] = 1;
hsize = n;
while (hsize > 0) {
int nodc = h[1];
idx[h[hsize]] = 1;
h[1] = h[hsize];
--hsize;
downh();
int costm = 0;
for (auto it : a[nodc]) {
if (cap[nodc][it] <= 0) continue;
costm = dis[nodc] + cost[nodc][it] - dis[it] ;
if (newd [it] > newd[nodc] + costm) {
newd[it] = newd[nodc] + costm;
t[it] = nodc;
uph(idx[it]);
aux[it] = aux[nodc] + cost[nodc][it];
}
}
}
return t[d] != 0;
}
public:
pair<int, int> solve() {
int flux = 0, costf = 0;
bfs(s, d);
for (int i = 1; i <= n; ++i)
aux[i] = dis[i];
int nod = d;
while (existFlow(s, d)) {
for (int i = 1; i <= n; ++i)
dis[i] = aux[i];
nod = d;
cmin = INF;
while (nod != s) {
cmin = min(cmin, cap[t[nod]][nod]);
nod = t[nod];
}
flux += cmin;
costf += dis[d] * cmin;
nod = d;
while (nod != s) {
cap[nod][t[nod]] += cmin; cap[t[nod]][nod] -= cmin;
nod = t[nod];
}
}
return mp(costf, flux);
}
} MF;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
cin >> n >> m >> s >> d;
for (int i = 1; i <= m; ++i) {
int u, v, x, y;
cin >> u >> v >> x >> y;
a[u].push_back(v);
cap[u][v] = x;
cost[u][v] = y;
a[v].push_back(u);
cap[v][u] = 0;
cost[v][u] = -y;
}
auto rec = MF.solve();
cout << rec.fi << endl;
}