1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 #define maxn 120
6 #define maxm 1200
7 #define ms 31011
8 using namespace std;
9 struct et
10 {
11 int s,t,val;
12 }e[maxm*2];
13 int f[maxm],v[maxm],c[maxm],l[maxm],r[maxm],q[maxm];
14 bool vis[maxm];
15 int n,m,tot,num,now,cnt;
16 long long sum[maxm],ans;
17
18 int find(int i)
19 {
20 if (!f[i]) return i;
21 return find(f[i]);
22 }
23
24 void dfs(int col,int k,int ll)
25 {
26 if (k>v[col]) {sum[col]++;return;}
27 for (int i=ll+1;i<=r[col];i++)
28 {
29 int fx=find(e[i].s);
30 int fy=find(e[i].t);
31 if (fx!=fy)
32 {
33 int tmp=f[fx];
34 f[fx]=e[i].t;
35 dfs(col,k+1,i);
36 f[fx]=tmp;
37 }
38 }
39 }
40
41 void add(int x,int y,int z)
42 {
43 e[++tot].s=x; e[tot].t=y; e[tot].val=z;
44 }
45
46 bool cmp(et a,et b)
47 {
48 return a.val<b.val;
49 }
50
51 int main()
52 {
53 int x,y,z;
54 scanf("%d %d",&n,&m);
55 for (int i=1;i<=m;i++)
56 {
57 scanf("%d %d %d",&x,&y,&z);
58 add(x,y,z);
59 }
60 sort(e+1,e+m+1,cmp);
61 int j=0;
62 for (int i=1;i<=m;i++)
63 {
64 if (e[i].val!=e[i-1].val) num++,l[num]=i;
65 r[num]=i,c[i]=num;
66 }//lisan
67 for (int i=1;i<=m;i++)
68 {
69 int fx=find(e[i].s),fy=find(e[i].t);
70 if (fx!=fy)
71 {
72 f[fx]=e[i].t;
73 v[c[i]]++;
74 }
75 }//kruskal
76 memset(f,0,sizeof(f));
77 now=0;
78 for (int i=1;i<=m;i++)
79 {
80 if (now!=c[i]) now=c[i],dfs(now,1,l[now]-1);
81 int fx=find(e[i].s),fy=find(e[i].t);
82 if (fx!=fy) f[fx]=e[i].t,cnt++;
83 }//dfs
84 if (cnt<n-1) ans=0; else ans=1;
85 for (int i=1;i<=num;i++) if (sum[i]) ans*=sum[i],ans%=ms;
86 printf("%d\n",ans);
87 return 0;
88 }