/*
#include <algorithm>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
typedef struct { int x,c; } node;
struct cmp_node
{
bool operator () (const node x,const node y)
{
return x.c >= y.c;
}
};
node make_node(int x,int c)
{
node now;
now.x = x;
now.c = c;
return now;
}
priority_queue<node,vector<node>,cmp_node> Q;
ifstream F("fmcm.in");
ofstream G("fmcm.out");
const int Nmax = 355;
const int Mmax = 12510;
const int value = 1010;
int N,M,D[Nmax];
int capacity[Nmax][Nmax];
int cost[Nmax][Nmax];
vector<int> V[Nmax];
int last[Nmax];
int total_flow,total_cost;
#define IT(type) vector<type>::iterator
int Bellman_pq(int start,int target)
{
memset(last,0,sizeof(last));
memset(D,0x3f,sizeof(D));
D[start] = 0;
last[start] = -1;
Q.push( make_node(start,D[start]) );
while ( Q.size() )
{
node now = Q.top();
Q.pop();
if ( D[now.x] != now.c )
continue;
for (IT(int) it=V[now.x].begin();it!=V[now.x].end();++it)
if ( capacity[now.x][*it] != 0 )
if ( D[*it] > D[now.x] + cost[now.x][*it] )
{
D[*it] = D[now.x] + cost[now.x][*it];
last[*it] = now.x;
Q.push( make_node( *it , D[now.x] + cost[now.x][*it] ) );
}
}
return D[target] != D[0];
}
int main()
{
F>>N>>M;
int source = 1;
int target = N;
F>>source>>target;
for (int i=1,x,y,c,cc;i<=M;++i)
{
F>>x>>y>>c>>cc;
if ( capacity[x][y] == 0 && capacity[y][x] == 0 )
{
V[ x ].push_back( y );
V[ y ].push_back( x );
}
capacity[x][y] += c;
cost[x][y] = cc;
cost[y][x] = -cc;
}
while ( Bellman_pq(source,target) != 0 )
{
int Cmin = capacity[last[target]][target];
for (int now=last[target];now!=source;now=last[now])
Cmin = min( Cmin , capacity[last[now]][now] );
total_flow += Cmin;
for (int now=last[target];now!=source;now=last[now])
{
capacity[last[now]][now] -= Cmin;
capacity[now][last[now]] += Cmin;
total_cost += cost[last[now]][now] * Cmin;
}
capacity[last[target]][target] -= Cmin;
total_cost += cost[last[target]][target] * Cmin;
}
G<<total_cost<<'\n';
}
*/
#include <cstdio>
#include <cassert>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
#define MAXN 355
int N, M, S, D;
int C[MAXN][MAXN], Cst[MAXN][MAXN];
vector<int> con[MAXN];
int F, FCst;
int old_d[MAXN]; char inQ[MAXN];
queue<int> Q;
int d[MAXN], real_d[MAXN], p[MAXN];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;
inline bool dijkstra()
{
memset(d, 0x3f, sizeof(d));
d[S] = 0; real_d[S] = 0;
H.push(make_pair(d[S], S));
for (; !H.empty(); )
{
int cst = H.top().first, nod = H.top().second;
H.pop();
if (d[nod] != cst)
continue;
vector<int> :: iterator it;
for (it = con[nod].begin(); it != con[nod].end(); it++)
if (C[nod][*it])
{
int new_d = d[nod] + Cst[nod][*it] + old_d[nod] - old_d[*it];
if (new_d < d[*it])
{
d[*it] = new_d;
real_d[*it] = real_d[nod] + Cst[nod][*it];
p[*it] = nod;
H.push(make_pair(d[*it], *it));
}
}
}
memcpy(old_d, real_d, sizeof(d));
if (d[D] == 0x3f3f3f3f)
return false;
int Min = 0x3f3f3f3f, curCst = 0;
for (int aux = D; aux != S; aux = p[aux])
Min = min(Min, C[p[aux]][aux]),
curCst += Cst[p[aux]][aux];
F += Min;
FCst += Min * real_d[D];
for (int aux = D; aux != S; aux = p[aux])
C[p[aux]][aux] -= Min,
C[aux][p[aux]] += Min;
return true;
}
inline bool bellmanFord()
{
memset(old_d, 0x3f, sizeof(old_d));
old_d[S] = 0;
for (Q.push(S), inQ[S] = 1; !Q.empty(); Q.pop())
{
vector<int> :: iterator it;
int i = Q.front();
inQ[i] = 0;
for (it = con[i].begin(); it != con[i].end(); it++)
if (C[i][*it])
{
if (old_d[i] + Cst[i][*it] >= old_d[*it])
continue;
old_d[*it] = old_d[i] + Cst[i][*it];
if (inQ[*it])
continue;
inQ[*it] = 1;
Q.push(*it);
}
}
if (old_d[D] == 0x3f3f3f3f)
return false;
return true;
}
int main()
{
freopen("fmcm.in", "rt", stdin);
freopen("fmcm.out", "wt", stdout);
assert(scanf("%d %d %d %d", &N, &M, &S, &D) == 4);
assert(1 <= N && N <= 350);
assert(1 <= M && M <= 12500);
assert(1 <= S && S <= N);
assert(1 <= D && D <= N);
assert(S != D);
for (; M; M--)
{
int x, y;
assert(scanf("%d %d ", &x, &y) == 2);
assert(1 <= x && x <= N);
assert(1 <= y && y <= N);
assert(x != y && !C[x][y] && !Cst[x][y] && !C[y][x] && !Cst[y][x]);
assert(x != D && y != S);
con[x].push_back(y);
con[y].push_back(x);
assert(scanf("%d %d", C[x] + y, Cst[x] + y) == 2);
assert(1 <= C[x][y] && C[x][y] <= 10000);
assert(-1000 <= Cst[x][y] && Cst[x][y] <= 1000);
Cst[y][x] = -Cst[x][y];
}
F = FCst = 0;
bellmanFord();
for (; dijkstra(); );
printf("%d\n", FCst);
return 0;
}