# POJ 3522 Slim Span （并查集 + 枚举 + kruskal）

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <algorithm>
#define MAXN 1000005
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;

typedef struct Edge_
{
int x, y;
int rank;
}Edge;

Edge edge[MAXN];
int n, m, res, Kc, father[MAXN];

int cmp(const void *a, const void *b)
{
Edge *p1 = (Edge *)a;
Edge *p2 = (Edge *)b;
return p1->rank - p2->rank;
}

int find(int x)    //路径压缩寻找父节点
{
return x == father[x] ? x : find(father[x]);
}

int solve(int x)
{
int cnt = 0;
for(int i=1; i<=n; i++) father[i]=i;
for(int i=x; i<m; i++) {       //kruskal试生成最小生成树；
int fx = find(edge[i].x);
int fy = find(edge[i].y);
if(fx != fy) {
father[fx] = fy;
cnt++;
}
if(cnt == n-1) return edge[i].rank-edge[x].rank;
}
return MAXN;
}

int main()
{
while(~scanf("%d %d", &n, &m) && n || m) {
res = MAXN;
for(int i=0; i<m; i++) {
scanf("%d %d %d", &edge[i].x, &edge[i].y, &edge[i].rank);
}
qsort(edge, m, sizeof(Edge), cmp);   //权值从大到小；
for(int i=0; i<=m-n+1; i++) {     //从0 ~ m-(n-1)的范围枚举
res = solve(i) < res ? solve(i) : res;   //寻找最小差值；
}
if(res == MAXN) res = -1;    //不存在的话
printf("%d\n", res);
}
return 0;
}