#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <cstring>
#include <ctime>
#include <unordered_map>
#include <iomanip>
#include <complex>
#include <cassert>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define deb(a) cerr<< #a << "= " << (a)<<"\n";
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef long double ld;
typedef complex<double> base;
typedef vector<int> vi;
typedef pair<int,int> pii;
template<class T> ostream& operator<<(ostream& stream, const vector<T> v){ stream << "[ "; for (int i=0; i<(int)v.size(); i++) stream << v[i] << " "; stream << "]"; return stream; }
ll fpow(ll x, ll p, ll m){ll r=1; for (;p;p>>=1){ if (p&1) r=r*x%m; x=x*x%m; } return r;}
ll inv(ll a, ll b){ return a<2 ? a : ((a-inv(b%a,a))*b+1)/a%b; }
int gcd(int a, int b){ if (!b) return a; return gcd(b,a%b);}
ll gcd(ll a, ll b){ if (!b) return a; return gcd(b,a%b);}
int L,R,N,M,S,D,d[700],F[700][700],C[700][700],P[700][700],p[700]; vi g[700];
pii h[13000]; int T,pos[700];
void add_edge(int x, int y, int c, int cost){
g[x].pb(y);
g[y].pb(x);
C[x][y]=c;
P[x][y]=cost;
P[y][x]=-cost;
}
void add(pii v){
h[++T]=v;
pos[v.se]=T;
int p=T;
while (p>1 && h[p]<h[p/2]){
swap(pos[h[p].se],pos[h[p/2].se]);
swap(h[p],h[p/2]);
p/=2;
}
}
void rmv(int nod){
int p=pos[nod];
h[p]=h[T--];
pos[h[p].se]=p;
while (2*p<=T){
int x=2*p;
if (x<T && h[x]>h[x+1]) x++;
if (h[x]<h[p]){
swap(pos[h[x].se],pos[h[p].se]);
swap(h[x],h[p]);
p=x;
}
else break;
}
}
pii dijkstra(){
int i;
set<pii> st;
vi f(N);
for (i=0; i<N; i++)
d[i]=-1;
d[S]=0;
add({0,S});
while (T>0){
pii cr=h[1];
rmv(cr.se);
if (d[cr.se]!=cr.fi) continue;
int nod=cr.se;
for (int nxt : g[nod])
if (C[nod][nxt]-F[nod][nxt]>0){
int cst=P[nod][nxt]+p[nod]-p[nxt];
if (d[nxt]==-1 || d[nod]+cst<d[nxt]){
if (d[nxt]!=-1) rmv(nxt);
d[nxt]=cst+d[nod];
f[nxt]=nod;
add({d[nxt],nxt});
}
}
}
if (d[D]==-1) return {0,0};
for (i=0; i<N; i++)
p[i]=d[i]+p[i];
int fl=(1<<30),cr;
for (cr=D; cr!=S; cr=f[cr])
fl=min(fl,C[f[cr]][cr]-F[f[cr]][cr]);
for (cr=D; cr!=S; cr=f[cr]){
F[f[cr]][cr]+=fl;
F[cr][f[cr]]-=fl;
}
return {fl,fl*p[D]};
}
void bellman_ford(){
int i;
for (i=0; i<N; i++)
d[i]=(1<<30);
vi q,nq,ind(N);
q.pb(S);
d[S]=0;
for (i=1; i<=N && !q.empty(); i++){
nq.clear();
for (int x : q){
for (int y : g[x]){
if (C[x][y]-F[x][y]>0 && (d[y]>P[x][y]+d[x])){
d[y]=P[x][y]+d[x];
if (ind[y]!=i) nq.pb(y);
ind[y]=i;
}
}
}
q=nq;
}
for (i=0; i<N; i++)
p[i]=d[i];
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
cin >> N >> M >> S >> D;
S--,D--;
int i;
for (i=1; i<=M; i++){
int x,y,c,z;
cin >> x >> y >> c >> z;
x--,y--;
add_edge(x,y,c,z);
}
int f=0,c=0;
bellman_ford();
while (1){
pii r=dijkstra();
if (r.fi==0) break;
f+=r.fi,c+=r.se;
}
cout << c;
return 0;
}