#include<bits/stdc++.h>
using namespace std;
#define man max
#define men min
#define int long long
const int maxn = 5010,INF = 11451419198102425;
struct edge{
int to,v,costt;
};
int n,m,s,t,a,b,c,d,u,tt,ans = 0,minn,ff,maxflow;
short indexx[maxn][maxn];
edge now;
int q[maxn << 10],head,tail,dist[maxn],pree[maxn],sum[maxn];
vector<edge> G[maxn],g[maxn],stepG[maxn],stepg[maxn];
void input()
{
cin >> n >> m;
s = 1,t = n;
for(int i = 1;i <= m;i++)
{
cin >> a >> b >> c >> d;
indexx[a][b] = G[a].size();
G[a].push_back({b,c,d});
g[a].push_back({b,c,-1 * d});
indexx[b][a] = G[b].size();
G[b].push_back({a,0,d});
g[b].push_back({a,0,-1 * d});
}
}
void makestepgraph()
{
for(int i = 1;i <= n;i++)
{
stepG[i].clear();
stepg[i].clear();
dist[i] = 0;
}
head = 1;
tail = 1;
q[1] = s;
dist[s] = 1;
while(head <= tail)
{
u = q[head++];
for(int i = 0;i < G[u].size();i++)
{
now = G[u][i];
if(!now.v) continue;
if(dist[now.to] && dist[now.to] != dist[u] + 1) continue;
if(!dist[now.to])
{
q[++tail] = now.to;
dist[now.to] = dist[u] + 1;
}
stepG[u].push_back(now);
stepg[u].push_back(now);
}
}
}
void SPFA()
{
for(int i = 1;i <= n;i++)
{
dist[i] = INF;
}
dist[s] = 0;
head = 1;
tail = 1;
q[1] = s;
while(head <= tail)
{
u = q[head++];
for(int i = 0;i < stepG[u].size();i++)
{
now = stepG[u][i];
if(!now.v) continue;
if(dist[now.to] <= dist[u]) continue;
if(dist[u] + now.costt < dist[now.to])
{
dist[now.to] = dist[u] + now.costt;
pree[now.to] = u;
sum[now.to] = i;
q[++tail] = now.to;
}
}
}
return ;
}
void findmincostblockingflow()
{
ff = 0;
while(1)
{
SPFA();
if(dist[t] == INF) break;
ff = 1;
tt = t;
minn = INF;
while(tt != s)
{
minn = men(minn,stepG[pree[tt]][sum[tt]].v);
tt = pree[tt];
}
tt = t;
while(tt != s)
{
stepG[pree[tt]][sum[tt]].v -= minn;
tt = pree[tt];
}
}
}
void update()
{
for(int i = 1;i <= n;i++)
{
for(int j = 0;j < stepG[i].size();j++)
{
G[i][indexx[i][stepg[i][j].to]].v -= (stepg[i][j].v - stepG[i][j].v);
ans += (stepg[i][j].v - stepG[i][j].v) * G[i][indexx[i][stepg[i][j].to]].costt;
G[stepg[i][j].to][indexx[stepg[i][j].to][i]].v += (stepg[i][j].v - stepG[i][j].v);
}
}
}
void dinitz()
{
while(1)
{
makestepgraph();
findmincostblockingflow();
if(!ff) break;
update();
}
return ;
}
void output()
{
for(int i = 0;i < G[s].size();i++)
{
maxflow += (g[s][i].v - G[s][i].v);
}
cout << maxflow << ' ' << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
input();
dinitz();
output();
return 0;
}