/*
分析:
判断最小生成树是否唯一。
构成原最小生成树的边,一条边一条边的删。
2012-07-30 09:06
*/
分析:
判断最小生成树是否唯一。
构成原最小生成树的边,一条边一条边的删。
2012-07-30 09:06
*/
#include"stdio.h"
#include"stdlib.h"
struct A
{
int a,b;
int flag;
int len;
}eage[5555];
int n,m;
int set[111];
int cmp(const void *a,const void *b)
{
struct A *c,*d;
c=(struct A *)a;
d=(struct A *)b;
return c->len-d->len;
}
void build(int num)
{
int i;
for(i=1;i<=num;i++) set[i]=i;
}
int find(int k)
{
if(set[k]==k) return k;
set[k]=find(set[k]);
return set[k];
}
void Union(int f1,int f2)
{
set[f1]=f2;
}
int Kruskal(int t_d)
{
int i;
int ans;
int f1,f2;
int count=1;
ans=0;
for(i=0;i<m;i++)
{
if(count==n) break;
if(i==t_d) continue;
f1=find(eage[i].a);
f2=find(eage[i].b);
if(f1==f2) continue;
Union(f1,f2);
eage[i].flag=1;
ans+=eage[i].len;
count++;
}
return ans;
}
int main()
{
int T;
int z,i;
int a,b,c;
int ans,t_ans;
int del[111],k;
int flag;
int temp;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
build(n);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
eage[i].a=a;
eage[i].b=b;
eage[i].len=c;
eage[i].flag=0;
}
qsort(eage,m,sizeof(eage[0]),cmp);
ans=Kruskal(-1);
temp=0;
for(i=1;i<=n;i++) if(set[i]==i) temp++;
if(temp>1) {printf("0\n");continue;}
k=0;
for(i=0;i<m;i++) if(eage[i].flag) del[k++]=i;
flag=0;
for(z=0;z<k;z++)
{
build(n);
t_ans=Kruskal(del[z]);
temp=0;
for(i=1;i<=n;i++) if(set[i]==i) temp++;
if(temp>1) continue;
if(t_ans==ans) {flag=1;break;}
}
if(flag) printf("Not Unique!\n");
else printf("%d\n",ans);
}
return 0;
}