#include <bits/stdc++.h>   using namespace std;   inline void read(int &x) {     x = 0;     char ch = getchar(), flag = 0;     while ((ch >  9  || ch <  0 ) && ch !=  - ) ch = getchar();     if (ch ==  - ) flag = 1, ch = getchar();     while (ch >=  0  && ch <=  9 ) x = x * 10 + ch -  0 , ch = getchar();     if (flag) x = -x;   }   inline void read(int &x, int &y) { read(x), read(y); }   inline void read(int &x, int &y, int &z) { read(x), read(y), read(z); }   const int N = 20005, inf = 1e9 + 7, mod = 20000;   int n, m, up[N], cup[N], cnt, si[N], num[N], dep[N], use[N];   vector<int> g[N], f[N], s[N];   bool vis[N];   struct node {     int to, next, v;   } p[N << 4];   int S, T, head[N], st[N], tot, ans;   inline void add(int x, int y, int z) {     p[tot].to = y;     p[tot].next = head[x];     p[tot].v = z;     head[x] = tot++;     p[tot].to = x;     p[tot].next = head[y];     p[tot].v = 0;     head[y] = tot++;   }   queue<int> q;   inline bool bfs(int x) {     memset(st, 0, sizeof(st));     st[x] = 1;     q.push(x);     while (!q.empty()) {       int x = q.front();       q.pop();       for (int i = head[x]; ~i; i = p[i].next) {         int y = p[i].to, v = p[i].v;         if (!v || st[y]) continue;         st[y] = st[x] + 1;         q.push(y);       }     }     return st[T] > 0;   }   inline int dfs(int x, int f) {     int r = 0;     if (x == T) return f;     for (int i = head[x]; ~i; i = p[i].next) {       int y = p[i].to, v = p[i].v, tmp;       if (!v || st[y] != st[x] + 1) continue;       tmp = dfs(y, min(f - r, v));       r += tmp;       p[i].v -= tmp;       p[i ^ 1].v += tmp;       if (r == f) break;     }     if (!r) st[x] = -1;     return r;   }   inline void dinic() {     int t;     while (bfs(S))       while (t = dfs(S, inf)) ans += t;     printf( %d n , ans);   }   inline void Add(int x, int y, int z) {     g[x].push_back(y);     f[x].push_back(z);     g[y].push_back(x);     f[y].push_back(z);     vis[x] = vis[y] = 1;   }   inline void Dfs(int x, int fa) {     vis[x] = 1;     for (int i = 0; i < g[x].size(); i++) {       int y = g[x][i], z = f[x][i];       if (y == fa) continue;       if (vis[y] && dep[y] < dep[x]) {         cnt++;         s[cnt].push_back(z);         si[z]--;         int k = x, o = 0;         while (k != y) {           si[cup[k]]--;           s[cnt].push_back(cup[k]);           k = up[k];         }         continue;       }       if (vis[y]) continue;       cup[y] = z;       up[y] = x;       dep[y] = dep[x] + 1;       Dfs(y, x);     }   }   int main() {     scanf( %d%d , &n, &m);     for (int i = 1; i <= m; i++) {       int x, y, z;       scanf( %d%d%d , &x, &y, &z);       Add(x, y, z);       si[z]++;       use[z]++;     }     for (int i = 1; i <= n; i++)       if (vis[i]) {         memset(vis, 0, sizeof(vis));         Dfs(i, -1);         break;       }     memset(head, -1, sizeof(head));     S = 0;     T = cnt + 1;     for (int i = 1; i <= m; i++)       if (!si[i] && use[i])         T++;       else if (use[i])         ans++;     int CNT = cnt;     for (int i = 1; i <= m; i++)       if (!si[i] && use[i]) add(num[i] = ++CNT, T, 1);     for (int i = 1; i <= cnt; i++) {       bool isok = 1;       for (int j = 0; j < s[i].size(); j++)         if (si[s[i][j]]) isok = 0;       add(S, i, s[i].size() - 1);       for (int j = 0; j < s[i].size(); j++)         if (num[s[i][j]]) add(i, num[s[i][j]], 1);     }     dinic();     return 0;   }