#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
const ll INF = 9e18;
class edge{
public:
int to,rev;
ll cap,cost;
edge(int _to,int _rev,ll _cap,ll _cost):to(_to),rev(_rev),cap(_cap),cost(_cost){};
};
void solve(){
int n,m,s,t;
cin >> n >> m >> s >> t;
vector<vector<edge>> adj(n+1);
for (int i=0;i<m;i++){
int u,v;
ll cap,cost;
cin >> u >> v >> cap >> cost;
adj[u].emplace_back(v,0,cap,cost);
adj[v].emplace_back(u,0,0,-cost);
adj[u].back().rev = adj[v].size()-1;
adj[v].back().rev = adj[u].size()-1;
}
vector<ll> h(n+1,INF);
h[s] = 0;
for (int tt=0;tt<n-1;tt++){
bool ok = false;
for (int u=1;u<=n;u++){
if (h[u]==INF) continue;
for (auto& [v,rev,cap,cost]:adj[u]){
if (cap && h[u]+cost<h[v]){
h[v] = h[u]+cost;
ok = true;
}
}
}
if (!ok) break;
}
vector<ll> dis;
auto dij = [&](){
dis = vector<ll>(n+1,INF);
dis[s] = 0;
priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>> pq;
pq.emplace(0,s);
while (!pq.empty()){
auto [d,u] = pq.top();
pq.pop();
if (d>dis[u]) continue;
for (auto& [v,rev,cap,cost]:adj[u]){
if (cap && d+cost+h[u]-h[v]<dis[v]){
dis[v] = d+cost+h[u]-h[v];
pq.emplace(dis[v],v);
}
}
}
return dis[t]!=INF;
};
vector<int> cur;
//这里如果不使用vis数组会受到0费用边影响
vector<bool> vis;
ll res1=0,res2=0;
function<ll(int,ll)> dfs = [&](int u,ll mf){
if (u==t) return mf;
ll sum = 0;
int len = adj[u].size();
vis[u] = true;
for (int& i=cur[u];i<len;i++){
auto& [v,rev,cap,cost] = adj[u][i];
if (!vis[v] && cap && h[v]==h[u]+cost){
ll f = dfs(v,min(mf,cap));
cap -= f;
adj[v][rev].cap += f;
res2 += f*cost;
mf -= f;
sum += f;
if (mf==0) break;
}
}
return sum;
};
while (dij()){
cur = vector<int>(n+1,0);
vis = vector<bool>(n+1,false);
//注意要先更新h数组
for (int i=1;i<=n;i++){
if (h[i]!=INF && dis[i]!=INF){
h[i] += dis[i];
}
}
res1 += dfs(s,INF);
}
cout << res1 << ' ' << res2 << '\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t = 1;
// cin >> t;
while (t--) solve();
return 0;
}