#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <fstream>
#define MAXN 110
#define MAXM 110*110
#define INTFY 1 << 20
struct Edge
{
int point1, point2;
int power;
}edge[MAXM];
int pre[MAXM];
using namespace std;
bool cmp(const Edge& x, const Edge& y)
{//从小到大排序
return x.power < y.power;
}
int find(int x)
{//并查集的查找操作
return (pre[x] == x) ? x : find(pre[x]);
}
int main(void)
{
int n, m;
//ofstream fout("D:\\out.txt");
while (scanf_s("%d%d", &n, &m) != EOF&&n+m)
{
int ans = INTFY;//目前找到的最小苗条度
int head = 0, tail = m;//便利的起始点
for (int i = 0; i < m; i++)scanf_s("%d%d%d", &edge[i].point1, &edge[i].point2, &edge[i].power);
if (m < n - 1)
{//边的数量不足n-1就没有考虑的必要了
printf("-1\n");
//fout << -1 << endl;
continue;
}
sort(edge, edge + m, cmp);
while (head < tail)
{//kruskal算法
int min_num = edge[head].power, max_num;
for (int i = 0; i <= n; i++)pre[i] = i;//这里少了一个等号WA了两次,呜呜呜
int coun = 0;
bool ok = false;
for (int i = head; i < m; i++)
{
int x = find(edge[i].point1);
int y = find(edge[i].point2);
if (x != y)
{
pre[x] = y;
coun++;
}
if (coun == n - 1)
{//树已经建好了
ok = true;
max_num = edge[i].power;
break;
}
}
head++;
if (ok)ans = min(ans, max_num - min_num);//出现一棵树里最小的苗条度就替换
}
printf("%d\n", (ans != INTFY) ? ans : -1);//如果能够建成一颗树
//fout << ((ans != INTFY) ? ans : -1) << endl;
}
return 0;
}