#define _USE_MATH_DEFINES
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <numeric>
#include <functional>
#include <cctype>
#include <list>
#include <limits>
#include <cassert>
#include <random>
#include <time.h>
#include <unordered_set>
//#include <boost/multiprecision/cpp_int.hpp>



using namespace std;
using Int = long long;
//using namespace boost::multiprecision;

const double EPS = 1e-10;
long long const MOD = 998244353;

long long mod_pow(long long x, long long n) {
    long long res = 1;
    for (int i = 0;i < 60; i++) {
        if (n >> i & 1) res = res * x % MOD;
        x = x * x % MOD;
    }
    return res;
}

template<typename T>
T gcd(T a, T b) {
    return b != 0 ? gcd(b, a % b) : a;
}

template<typename T>
T lcm(T a, T b) {
    return a * b / gcd(a, b);
}

void fastInput() {
    cin.tie(0);
    ios::sync_with_stdio(false);
}

struct Edge{
    int from, to, cost;
    bool operator <(const Edge &e) const {
        return cost < e.cost;
    }
    bool operator >(const Edge &e) const {
        return cost > e.cost;
    }
    bool operator ==(const Edge &e) const {
        return cost == e.cost;
    }
    bool operator !=(const Edge &e) const {
        return cost != e.cost;
    }
};

struct UnionFind {
private:
    const int n;
    int __size;
    vector<int> uf;
public:
    // 初期化 UnionFind uni(n) のように宣言すれば良い
    UnionFind(int _n) : n(_n), __size(_n), uf(_n, -1) {}
    // find (木の根を求める)
    int find(int x) {return (uf[x] < 0) ? x : uf[x] = find(uf[x]);}
    // x と y が同じ集合に属するかどうか
    bool same(int x, int y) {return find(x) == find(y);}
    // x が属する集合の要素数
    int size(int x) {return -uf[find(x)];}
    // 集合はいくつあるか
    int size() {return __size;}
    // x と y の属する集合を併合
    void unite(int x, int y) {
        x = find(x); y = find(y);
        if(x == y) return;
        __size--;
        if(uf[y] < uf[x]) swap(x, y);
        uf[x] += uf[y]; uf[y] = x;
    }
};

int solve(int N, int M) {
    int ret = 100000000;
    vector<pair<int, pair<int, int>>> E;
    for (int i = 0; i < M; i++) {
        int a, b, c; cin >> a >> b >> c;
        a--, b--;
        E.push_back({c, {a, b}});
    }
    sort(E.begin(), E.end());

    for (int i = 1; i <= 10000; i++) {
        UnionFind djset(N);
        int max_cost = 0;
        for (int j = 0; j < M; j++) {
            int v1 = E[j].second.first;
            int v2 = E[j].second.second;
            int cost = E[j].first;
            if (cost < i) continue;
            if (djset.same(v1, v2)) continue;
            djset.unite(v1, v2);
            max_cost = max(max_cost, cost);
        }
        if (djset.size() == 1) {
            ret = min(max_cost - i, ret);
        }
    }
    if (ret == 100000000) ret = -1;
    return ret;
}

int main(void) {
    int N, M;
    vector<int> ans;
    while (1) {
        cin >> N >> M;
        if (N == 0) break;
        ans.push_back(solve(N, M));
    }
    for (auto i : ans) {
        cout << i << endl;
    }
}



Measured memory_bytes: 3180