// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

const int maxn = 50010;

struct node 

{

      int u,v,w;

      bool used,mark,del;

      node(int x = 0,int y = 0,int z = 0) 

	  {

        u = x;

        v = y;

        w = z;

        mark = del = used = false;

     }

     bool operator<(const node &tmp) const 

	 {

         return w < tmp.w;

     }

 }e[maxn];

 int uf[maxn],n,m,cnt;

 bool flag[maxn];

 int find(int x) {

     return uf[x] = uf[x] == x?uf[x]:find(uf[x]);

 }

 int kruskal(bool &Unique,bool first) {

     int ans = cnt = 0;

     for(int i = 0; i <= n; ++i) uf[i] = i;

     for(int i = 0; i < m; ++i) {

        if(!first && e[i].del) continue;

        int fx = find(e[i].u);

        int fy = find(e[i].v);

       if(fx != fy)

	   {

    	   	uf[fx] = fy;

            ans += e[i].w;

            if(first) 

			{

            e[i].used = true;

            if(e[i].mark) Unique = false;

            }

            if(++cnt == n-1) return ans;

	   }

     }

     return ans;

 }

 int main() {

     int u,v,w;

    // freopen("data.in","r",stdin); 

     while(~scanf("%d %d",&n,&m)) {

         for(int i = 0; i < m; ++i) {

             scanf("%d %d %d",&u,&v,&w);

             e[i] = node(u,v,w);

         }

         memset(flag,false,sizeof(flag));

         sort(e,e+m);

         for(int i = 1; i < m; ++i)

             if(e[i].w == e[i-1].w) e[i].mark = e[i-1].mark = true;

         bool Unique = true;

         int MST = kruskal(Unique,1);

         if(Unique) printf("%d %d\n",cnt,MST);

         else {

             int res1 = 0,res2 = 0;

             for(int i = 0; i < m; ++i) {

                 if(e[i].used && e[i].mark) {

                     e[i].del = true;

                     int mst = kruskal(Unique,0);

                     if(mst == MST && cnt == n-1) flag[i] = true;

                     e[i].del = false;

                 }

               if(e[i].used && !flag[i]) {

                     res1++;

                     res2 += e[i].w;

                 }

             }

             printf("%d %d\n",res1,res2);

        }

     }

     return 0;

 }

// Faster C++ solution for the same problem (measured speedup: 1.9182123093421624x):
#include <bits/stdc++.h>

#define maxn 50018

#define N 558

#define inf 200000000

#define PII pair<int,int>

using namespace std;

int n,m;

int cnt = 0;

int sum1,sum2;

int ans;

int father[N];

struct nod{

    int from,to,cost;

   

}edg[maxn];

bool cmp(nod i,nod j)

{

    return i.cost<j.cost;

}

int v[N],num[N];

void init()

{

    for(int i = 0;i <= n;i ++)

    {

        father[i]=i;num[i]=1;

    }

}

int find(int x){

    if(x!=father[x]) return father[x]=find(father[x]);

    return father[x];

}



bool Union(int x,int y)

{

        int fx = find(x),fy = find(y);

    if(fx!=fy)

    {

        father[fy] = fx;  num[fx]+=num[fy]; return true;

    }

    else

    {

        return false;

    }

         

}

void krus2()

{

    sum1=0,sum2=0;

    for(int i=0;i<cnt;i++){

       // cout << cnt << endl;

        int tmp=0;init();

        for(int j=0;j<m;j++){

            if(j!=v[i]){

                if(Union(edg[j].from,edg[j].to))

                {

                    tmp+=edg[j].cost;

                }

            

            }

        }

        if(tmp!=ans) sum1++,sum2+=edg[v[i]].cost;

    }

    printf("%d %d\n",sum1,sum2);

}

int main(){

     //freopen("in.txt","r",stdin);

    while(~scanf("%d%d",&n,&m)){

        cnt = 0;

        init();

        for(int i=0;i<m;i++){

            scanf("%d%d%d",&edg[i].from,&edg[i].to,&edg[i].cost);

        }

        sort(edg,edg+m,cmp);

        ans=0;

        memset(v,0,sizeof(v));

        for(int i=0;i<m;i++){

            if(Union(edg[i].from,edg[i].to)){

                ans+=edg[i].cost;

                v[cnt++]=i;

            }

        }

        krus2();

    }

    return 0;

}