#include<cstring> #include<iostream> #include<cstdio> #define maxn 105 #define INF 0x3f3f3f3f using namespace std; int head[maxn],maxcost[maxn][maxn],map[maxn][maxn]; bool used[maxn][maxn];//m int n,m,t,cnt,x,y,z,vis[maxn],d[maxn],pre[maxn]; int prim(int s) { int res=0; memset(maxcost,0,sizeof(maxcost)); for(int i=1;i<=n;i++) vis[i] = 0, d[i] = INF, pre[i]=i; d[s]=0; for(int i=0;i<n;i++)//循环计数 { int mn=INF, index=-1; for(int j=1;j<=n;j++) { if(!vis[j] && d[j]<mn) { mn=d[j]; index=j; } } if(index==-1) break; res+=mn; vis[index]=1; used[index][pre[index]]=used[pre[index]][index]=1; for(int j=1;j<=n;j++) if(vis[j])//已经访问过的肯定是生成树的一部分 maxcost[index][j] = maxcost[j][index] = max(maxcost[pre[index]][j],d[index]);//pre[index]一定在生成树中 for(int j=1;j<=n;j++)//更新全部链接index的点的权值 { if(!vis[j] && map[index][j]<d[j]) { d[j] = map[index][j]; pre[j] = index; } } } return res; } int exprim(int n,int mins) { int ans=INF; for(int i=1;i<=n;i++)//枚举最小生成树之外的边 for(int j=i+1;j<=n;j++) if(map[i][j]!=INF && !used[i][j]) { ans=min(ans,mins+map[i][j]-maxcost[i][j]); } if(ans==INF) return -1; return ans; } void judge(int n) { int ans=prim(n); if (ans == -1) { puts("Not Unique!"); return; } if (exprim(n, ans) == ans) printf("Not Unique! "); else printf("%d ", ans); } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); cnt=0; memset(head,0,sizeof head); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) map[i][j]=map[j][i]=INF; memset(used,0,sizeof used); for(int i=1;i<=n;i++) map[i][i]=0; for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); map[x][y]=z; map[y][x]=z; } judge(n); } }