Dinic
#include<bits/stdc++.h>
#define int long long
#define toi (e[i].to)
#define toc (e[i].c)
#define fore(now,i) for(int i=head[now];~i;i=e[i].next)
#define inf (0x3f3f3f3f)
using namespace std;
int n,m,s,t,cnt=-1,head[5005],d[5005],ans=0,cost=0;
bool vis[5005];
struct EDGE{
int to,next,w,c;
}e[50005<<1|1];
inline void init(){
memset(e,-1,sizeof(e));
memset(head,-1,sizeof(head));
}
inline void addedge(int u,int v,int w,int c){
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].c=c;
e[cnt].next=head[u];
head[u]=cnt;
e[++cnt].to=u;
e[cnt].w=0;
e[cnt].c=-c;
e[cnt].next=head[v];
head[v]=cnt;
}
bool spfa(){
memset(vis,false,sizeof(vis));
memset(d,inf,sizeof(d));
queue<int> q;
q.push(s);
// cerr<<d[t]<<'\n';
d[s]=0;
vis[s]=true;
while(!q.empty()){
int now=q.front();
q.pop();
vis[now]=false;
fore(now,i)
if(e[i].w&&d[toi]>d[now]+toc){
d[toi]=d[now]+toc;
if(!vis[toi]){
vis[toi]=true;
q.push(toi);
}
}
}
return (d[t]<inf);
}
int dfs(int now,int f){
vis[now]=true;
if(now==t){
// cerr<<"end dfs\n";
ans+=f;
return f;
}
int used=0;
fore(now,i)
if((!vis[toi]||toi==t)&&d[toi]==d[now]+toc&&e[i].w){
int t=dfs(toi,min(e[i].w,f-used));
if(t){
used+=t;
cost+=toc*t;
e[i].w-=t;
e[i^1].w+=t;
}
if(used==f)
break;
}
}
void Dinic(){
while(spfa())
do{
memset(vis,false,sizeof(vis));
dfs(s,inf);
}while(vis[t]);
}
signed main(){
init();
scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
for(int i=1,u,v,w,c;i<=m;i++)
scanf("%lld%lld%lld%lld",&u,&v,&w,&c),addedge(u,v,w,c);
Dinic();
printf("%lld %lld",ans,cost);
return 0;
}