#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define LL long long
#define M 10010
#define DEBUG puts("It's here!")
#define INF 1<<29
#define CLS(x,v) memset(x,v,sizeof(x))
#define FOR(i,a,n) for(int i=(a);i<=(n);++i)
#define filer freopen("C:\\Users\\sq\\Desktop\\data.in","r",stdin);
#define filew freopen("C:\\Users\\sq\\Desktop\\data.out","w",stdout);
struct Edge{
int to,cost,len;
}e,dist[M];
int n;
vector<Edge> g[M];
bool vis[M];
struct cmp{
bool operator()(const int &a,const int &b)const{
if(dist[a].len==dist[b].len)
return dist[a].cost!=dist[b].cost?dist[a].cost<dist[b].cost:a<b;
return dist[a].len<dist[b].len;
}
};
set<int,cmp> v;//存储各个点的标号
void prim(int s)
{
for(int i=1;i<=n;i++)
dist[i].cost=dist[i].len=INF;
dist[s].cost=dist[s].len=0;
CLS(vis,0);
v.clear();
v.insert(s);
int k,cnt=0;
int len=0,sum=0;
while(!v.empty())
{
k=*v.begin();
vis[k]=1;
cnt++;
len+=dist[k].len;
sum+=dist[k].cost;
v.erase(k);
for(int i=0;i<g[k].size();i++)
{
int to=g[k][i].to;
if(!vis[to]&&(g[k][i].len<dist[to].len||(g[k][i].len==dist[to].len&&g[k][i].cost<dist[to].cost)))
{
v.erase(to);
dist[to].len=g[k][i].len;
dist[to].cost=g[k][i].cost;
v.insert(to);
}
}
}
if(cnt>=n)printf("%d %d\n",len,sum);
else printf("-1 -1\n");
}
int main()
{
int m;
int a,b;
while(scanf("%d%d",&n,&m)!=INF)
{
for(int i=0;i<=n;i++)g[i].clear();
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&a,&b,&e.len,&e.cost);
e.to=b;
g[a].push_back(e);
e.to=a;
g[b].push_back(e);
}
prim(1);
}
return 0;
}