/*
SE:wn------王宁
使用间接排序而不是结构体实现
UVa1395 Slim Span
*/
/*思路就是从权重最小的边向上枚举边集E中的元素
最大边和最小边的差值和单独一方的值没有关系,所以需要枚举。
生成树的方法就是Kruskal,因为你越早找到最大边,差值就越小*/
/*经验总结
1.你用间接排序可能能节省每次交换数据的时间——只用交换编号
(操作原理:比如e[2]代表第二小的边的编号,e[2]=9,那么我们访问这条边的
两个端点就要把e[2]本身给代进去)
但是用结构体会直观很多,出错可能会小一些
2.变量命名:我把边数命名为m,后来设定结束条件(生成树不是应该具有比总结点
数目少一的边数嘛)设成了m-1.结果会导致答案全是-1*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=5000+5;
int w[maxn],u[maxn],v[maxn],e[maxn];//e[i]存储的是边的序号,使用间接排序
int f[100+5];
int cmp(int a, int b) { return w[a]<w[b]; }
int find(int x){ return x==f[x]?f[x]:f[x]=find(f[x]); }
int ans;
int m,n;
int main()
{
int i,j,cnt,tmp,st,ed;
while(cin>>n>>m&&n){
for(i=1;i<=m;i++) scanf("%d%d%d",&u[i],&v[i],&w[i]);
for(i=1;i<=m;i++) e[i]=i;
sort(e+1,e+1+m,cmp);
ans=-1;
for(i=1;i<=m;i++)
{
cnt=0; st=w[e[i]];
//还要注意每次遍历都要先把f给还原——每个点都是自己的代表元
for(j=1;j<=n;j++) f[j]=j;
for(j=i;j<=m;j++)
{
tmp=e[j]; int x=find(u[tmp]),y=find(v[tmp]);
if(x!=y) {
f[x]=y;
++cnt;
}
//错就错在应该是集齐了n-1条边就应该收手的,写成了m-1了
if(cnt==n-1) break;
}
if(j==m+1) continue;
ed=w[e[j]];
if(ans==-1) ans=ed-st;
else ans=min(ans, ed-st);
}
cout<<ans<<endl;
}
return 0;
}