#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#define pii pair <int, int> // nu ma omorati, ia mai multe puncte(!@m)
using namespace std;
ofstream fout("fmcm.out");
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
const int N = 350, inf = INT_MAX;
int dist[N + 1], cdist[N + 1], from[N + 1], aux[N + 1];
int f[N + 1][N + 1], cost[N + 1][N + 1];
int n, m, S, D, maxFlow = 0, minCost = 0;
bool inQ[N + 1];
vector <int> adj[N + 1];
void BF(){
for(int i = 1; i <= n; i++)
aux[i] = inf;
queue <int> Q;
Q.push(S), aux[S] = 0;
while(!Q.empty()){
int nod = Q.front();
Q.pop();
inQ[nod] = false;
for(auto vec : adj[nod])
if(aux[nod] + cost[nod][vec] < aux[vec] && f[nod][vec] > 0){
aux[vec] = aux[nod] + cost[nod][vec];
if(!inQ[vec])
Q.push(vec), inQ[vec] = true;
}
}
}
priority_queue <pii, vector <pii>, greater <pii>> pq;
bool DJK(){
for(int i = 1; i <= n; i++)
dist[i] = cdist[i] = inf;
pq.push({0, S});
dist[S] = cdist[S] = 0;
while(!pq.empty()){
int nod = pq.top().second, val = pq.top().first;
pq.pop();
if(val == dist[nod])
for(auto vec : adj[nod])
if(f[nod][vec] > 0 && dist[nod] + cost[nod][vec] + aux[nod] - aux[vec] < dist[vec]){
dist[vec] = dist[nod] + cost[nod][vec] + aux[nod] - aux[vec];
cdist[vec] = cdist[nod] + cost[nod][vec];
pq.push({dist[vec], vec}), from[vec] = nod;
}
}
return(dist[D] != inf);
}
signed main(){
InParser fin("fmcm.in");
fin >> n >> m >> S >> D;
for(int i = 1; i <= m; i++){
int a, b, cap, z;
fin >> a >> b >> cap >> z;
adj[a].push_back(b);
adj[b].push_back(a);
f[a][b] = cap, cost[a][b] = z, cost[b][a] -= z;
}
BF();
while(DJK()){
int nod = D, flow = inf;
while(nod != S)
flow = min(flow, f[from[nod]][nod]), nod = from[nod];
nod = D, maxFlow += flow;
while(nod != S)
f[from[nod]][nod] -= flow, f[nod][from[nod]] += flow, nod = from[nod];
minCost += flow * cdist[D];
for(int i = 1; i <= n; i++)
aux[i] = dist[i];
}
fout << minCost << '\n';
return 0;
}