#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
const int N=1e5+5,M=5e5+5;
const int MOD=1e9+7;
struct Graph{
int u,v,w;
}g[M];
int n,m;
int f[N];
int l[M],r[M],c[M];
int color[M];
inline int find(int i){
return f[i]==i?i:find(f[i]);
}
inline void merge(int a,int b){//按秩合并
int fa=find(a),fb=find(b);
if (fa==fb) return;
if (fa<fb) f[fb]=fa;
else f[fa]=fb;
}
void dfs(int t,int qwq,int c,long long &sm){
if (t>r[c]){
if (qwq==color[c]){
++sm;
}
return;
}
int fa=find(g[t].u),fb=find(g[t].v);
if (fa!=fb){
if (fa<fb) f[fb]=fa;
else f[fa]=fb;
dfs(t+1,qwq+1,c,sm);
f[fa]=fa,f[fb]=fb;
}
dfs(t+1,qwq,c,sm);
}
int main(){
cin >> n >> m;
for (int i=1;i<=n;++i) f[i]=i;
int u,v,w;
for (int i=1;i<=m;++i){
g[i].u=read();
g[i].v=read();
g[i].w=read();
}
sort(g+1,g+1+m,[](const Graph &a,const Graph &b){
return a.w<b.w;
});
int cnt=0,tot=0;
int fa,fb;
for (int i=1;i<=m;++i){//这里T了
if (g[i].w!=g[i-1].w){
r[cnt]=i-1;
++cnt;
l[cnt]=i;
}
fa=find(g[i].u),fb=find(g[i].v);
if (fa==fb) continue;
merge(fa,fb);
++color[cnt];
++tot;
}
return 0;
r[cnt]=m;
if (tot!=n-1){//边不够
cout<<0<<endl;
return 0;
}
for (int i=1;i<=n;++i) f[i]=i;//还原
long long ans=1,sm;
for (int i=1;i<=cnt;++i){
sm=0;
dfs(l[i],0,i,sm);
ans=ans*sm%MOD;//乘法原理
for (int j=l[i];j<=r[i];++j){
merge(g[j].u,g[j].v);
}
}
cout<<ans<<endl;
return 0;
}
目前找到了T在哪里,但是不明白为啥会T