#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int N = 351, inf = 0x3f3f3f3f;
struct Edge{
int y, c;
Edge(int y, int c) : y(y), c(c) {};
inline bool operator<(const Edge& E) const {
return c > E.c;
}
};
vector<Edge> graph[N];
int cap[N][N], flux[N][N], cost[N][N], n;
int dist[N], T[N];
bool use[N];
inline int getCap(int x, int y){
return cap[x][y] - flux[x][y];
}
inline void relax(int x, int y, int c){
flux[x][y] += c;
flux[y][x] -= c;
}
void bellmanFord(int x){
memset(dist, inf, sizeof(dist));;
memset(use, false, sizeof(use));
dist[x] = 0;
queue<int> Q;
Q.push(x);
while (!Q.empty()){
x = Q.front();
Q.pop();
use[x] = false;
for (Edge it : graph[x]){
int i = it.y;
if ( dist[x] + cost[x][i] < dist[i] && getCap(x, i) > 0){
dist[i] = dist[x] + cost[x][i];
T[i] = x;
if (!use[i]){
Q.push(i);
use[i] = true;
}
}
}
}
}
bool dijkstra(int x, int D){
memset(dist, inf, sizeof(dist));
memset(use, false, sizeof(use));
dist[x] = 0;
priority_queue<Edge> Q;
Q.push( Edge(x, 0) );
while (!Q.empty()){
x = Q.top().y;
Q.pop();
if (use[x])
continue;
use[x] = true;
for (Edge it : graph[x])
if ( dist[x] + it.c < dist[it.y] && getCap(x, it.y) > 0 ){
T[it.y] = x;
dist[it.y] = dist[x] + it.c;
Q.push( Edge(it.y, dist[it.y]) );
}
}
return use[D];
}
void rebuildGraph(int S){
bellmanFord(S);
for (int i = 1 ; i <= n ; i++)
for (auto it = graph[i].begin() ; it != graph[i].end() ; it++)
it -> c += dist[i] - dist[it -> y];
}
int maxFlow(int S, int D){
int totCost = 0, C, F;
rebuildGraph(S);
while ( dijkstra(S, D) ){
F = inf;
C = 0;
for (int i = D ; i != S ; i = T[i]){
F = min(F, getCap(T[i], i));
C += cost[ T[i] ][i];
}
for (int i = D ; i != S ; i = T[i])
relax(T[i], i, F);
totCost += C * F;
}
return totCost;
}
int main(){
int m, x, y, S, D;
ifstream in("fmcm.in");
in >> n >> m >> S >> D;
while (m--){
in >> x >> y;
in >> cap[x][y] >> cost[x][y];
cost[y][x] = -cost[x][y];
graph[x].push_back( Edge(y, cost[x][y]) );
graph[y].push_back( Edge(x, cost[y][x]) );
}
in.close();
ofstream out("fmcm.out");
out << maxFlow(S, D) << '\n';
out.close();
return 0;
}