#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #define N 200100 #define INF 100000000 using namespace std; int ecnt=1,vis[N],dist[N],n,m,S,T,ans,head[N]; deque <int> q; struct adj { int nxt,v,w,c; }e[N]; inline void add(int u,int v,int w,int c) { e[++ecnt].v=v,e[ecnt].w=w,e[ecnt].c=c,e[ecnt].nxt=head[u],head[u]=ecnt; e[++ecnt].v=u,e[ecnt].w=0,e[ecnt].c=-c,e[ecnt].nxt=head[v],head[v]=ecnt; } inline int spfa(int s,int t) { int v; memset(vis,0,sizeof(vis)); for (int i=s;i<=t;i++) dist[i]=INF; dist[t]=0,vis[t]=1; q.push_back(t); while (!q.empty()) { int u=q.front();q.pop_front(); for (int i=head[u];i;i=e[i].nxt) if (e[i^1].w>0 && dist[v=e[i].v]>dist[u]-e[i].c) { dist[v]=dist[u]-e[i].c; if (!vis[v]) { vis[v]=1; if (!q.empty() && dist[v]<dist[q.front()]) q.push_front(v); else q.push_back(v); } } vis[u]=0; } return dist[s]<INF; } inline int dfs(int x,int flow) { if (x==T) return vis[T]=1,flow; int used=0,tmp,v; vis[x]=1; for (int i=head[x];i;i=e[i].nxt) if (!vis[v=e[i].v] && e[i].w>0 && dist[x]-e[i].c==dist[v]) { tmp=dfs(v,min(e[i].w,flow-used)); if (tmp>0) ans+=tmp*e[i].c,e[i].w-=tmp,e[i^1].w+=tmp,used+=tmp; if (used==flow) break; } return used; } inline int CostFlow() { int Flow=0; while (spfa(S,T)) { vis[T]=1; while (vis[T]) { memset(vis,0,sizeof(vis)); Flow+=dfs(S,INF); } } return Flow; } int main() { scanf("%d%d%d%d",&n,&m,&S,&T); for (int i=1,u,v,w,c;i<=m;i++) { scanf("%d%d%d%d",&u,&v,&w,&c); add(u,v,w,c); } printf("%d ",CostFlow()); printf("%d",ans); return 0; }