#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);++i)
#define rep(i,n) REP(i, 0, n)
typedef long long int i64;
typedef pair<int, int> pint;

struct UnionFind {
    vector<int> data; int group;
    UnionFind(int N) : data(N, -1), group(N){}
    void clear(int N) { data = vector<int>(N, -1); group = N;}
    void unite(int x, int y) {
        x = root(x); y = root(y);
        if(x != y){
            data[x] += data[y];
            data[y] = x;
            --group;
        }
    }
    int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]);}
    bool same(int a, int b) { return root(a) == root(b);}
};

struct Edge {
    int from, to, cost;
    Edge(int f, int t, int c)
         :from(f), to(t), cost(c){}
    bool operator < (const Edge& E) const {
        return cost < E.cost;
    }
};

int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    int N, M;
    while(cin >> N >> M && N) {
        int a_, b_, w_;
        vector<Edge> edges;
        rep(i, M) {
            cin >> a_ >> b_ >> w_;
            --a_; --b_;
            edges.push_back(Edge(a_, b_, w_));
        }
        sort(edges.begin(), edges.end());
        UnionFind uf(N);
        int ans = INF;
        rep(start, M) {
            uf.clear(N);
            int mi = edges[start].cost, ma = 0;
            REP(i, start, M) {
                Edge e = edges[i];
                if(uf.same(e.from, e.to)) continue;
                uf.unite(e.from, e.to);
                ma = max(ma, e.cost);
            }
            if(uf.group != 1) break;
            ans = min(ans, ma - mi);
        }
        cout << (ans == INF ? -1 : ans) << endl;
    }
    return 0;
}