#include<cstdio>
#include<vector>
#include<algorithm>

#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	vector<int>	vi;

const int INF=1<<29;

struct Edge{
	int u,v,cost;
	Edge(){}
	Edge(int U,int V,int C):u(U),v(V),cost(C){}
	bool operator<(const Edge &e)const{ return cost<e.cost; }
};

class UnionFind{
	vi a;
	int root(int x){ return ~a[x]?a[x]=root(a[x]):x; }
public:
	UnionFind(int n):a(n,-1){}
	bool find(int x,int y){ return root(x)==root(y); }
	bool unite(int x,int y){ return find(x,y)?0:(a[root(y)]=root(x),1); }
};

int main(){
	for(int m,n;scanf("%d%d",&n,&m),n;){
		Edge e[5000];
		rep(i,m){
			scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].cost);
			e[i].u--,e[i].v--;
		}
		sort(e,e+m);

		int ans=INF;
		vector<UnionFind> uf(m,UnionFind(n));
		int cnt[5000],dmin[5000],dmax[5000];
		rep(i,m){
			dmin[i]=dmax[i]=e[i].cost;
			cnt[i]=1;
		}
		for(int i=0,l=0;i<m;i++){
			for(int j=l;j<=i;j++){
				if(uf[j].unite(e[i].u,e[i].v)){
					if(dmax[j]<e[i].cost)	dmax[j]=e[i].cost;
					cnt[j]++;
					int delta=dmax[j]-dmin[j];
					if(ans<=delta)	l++;	// pruning
					else if(cnt[j]==n){		// spanning tree made up
						if(delta<ans)	ans=delta;
						l++;
					}
				}
			}
		}

		printf("%d\n",ans<INF?ans:-1);
	}

	return 0;
}