#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define rep(i,n) for (int i=0; i < int(n); i++)


struct UnionFind
{
  vector<int> par;
  vector<int> sizes;

  UnionFind(int n) : par(n), sizes(n, 1) {
    rep(i,n) par[i] = i;
  }

  void init() {
    int n = par.size();
  	rep(i,n) {
      par[i] = i;
      sizes[i] = 1;
  	}
  }

  // データxが属する木の根を得る
  int find(int x) {
    if (x == par[x]) return x;
    return par[x] = find(par[x]);  // 根を張り替えながら再帰的に根ノードを探す
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);

    if (sizes[x] < sizes[y]) swap(x, y);

    par[y] = x;
    sizes[x] += sizes[y];
  }

  // 2つのデータx, yが属する木が同じならtrueを返す
  bool same(int x, int y) {
    return find(x) == find(y);
  }
};


// 頂点a, bをつなぐコストcostの（無向）辺
struct Edge
{
  int a, b, cost;

  // コストの大小で順序定義
  bool operator<(const Edge& o) const {
    return cost < o.cost;
  }
};

// 頂点数と辺集合の組として定義したグラフ
struct Graph
{
  int n;  // 頂点数
  vector<Edge> es;  // 辺集合

  int getmin() {
    int m = es.size();
    if (m == 0) return -1;
    // コストが小さい順にソート
    sort(es.begin(), es.end());

    UnionFind uf(n);
    int cur_min_ind = 0;
    int ans = 100000000;

    while (true) {
      int min_cost = es[cur_min_ind].cost;
      int max_cost = min_cost;
      int num_edge = 0;

      uf.init();
      for(int ei = cur_min_ind; ei < m; ei++) {
        Edge& e = es[ei];
        if (!uf.same(e.a, e.b)) {
          // 辺を追加しても閉路ができないなら、その辺を採用する
          max_cost = e.cost;
          num_edge++;
          uf.unite(e.a, e.b);
        }
      }

      if (cur_min_ind == 0 && num_edge < n - 1) return -1;
      if (num_edge < n - 1) break;
      ans = min(ans, max_cost - min_cost);

      // calc next min ind
      cur_min_ind++;
      while (cur_min_ind < m && es[cur_min_ind].cost == es[cur_min_ind - 1].cost) cur_min_ind++;
      
      if (cur_min_ind == m) break;
    }


    return ans;
  }
};


void solve(int n, int m) {
  Graph g;
  g.n = n;
  rep(i, m) {
    Edge e;
    cin >> e.a >> e.b >> e.cost;
    e.a--;
    e.b--;
    g.es.push_back(e);
  }
  cout << g.getmin() << endl;
}

int main() {
  int n, m;
  while (cin >> n >> m, n||m) solve(n, m);
  return 0;
}