#include <bits/stdc++.h>
using namespace std;
int sla[200000], vis[200000], dis[200000], s, t;
int ans;
int lt[200000], nlt[200000], nt[200000], bi[200000], ci[200000], tl;
queue<int> Q;
void flow(int p, int nl) {
  ci[p] -= nl;
  ci[(p & 1 ? p + 1 : p - 1)] += nl;
}
int dfs(int nw, int mx) {
  vis[nw] = 1;
  if (nw == t) return mx;
  int hl = 0;
  for (int &p = nlt[nw]; p; p = nt[p])
    if (ci[p])
      if (dis[nw] + 1 == dis[bi[p]]) {
        int nl = dfs(bi[p], min(ci[p], mx - hl));
        hl += nl;
        flow(p, nl);
        if (hl == mx) return mx;
      }
  return hl;
}
void SPFA() {
  for (int i = 1; i <= t; ++i) dis[i] = 10000000;
  dis[s] = 0;
  for (int i = 1; i <= t; ++i) vis[i] = 0;
  vis[s] = 1;
  while (!Q.empty()) Q.pop();
  Q.push(s);
  while (!Q.empty()) {
    int nw = Q.front();
    Q.pop();
    vis[nw] = 0;
    for (int p = lt[nw]; p; p = nt[p])
      if (ci[p])
        if (dis[nw] + 1 < dis[bi[p]]) {
          dis[bi[p]] = dis[nw] + 1;
          if (!vis[bi[p]]) {
            vis[bi[p]] = 1;
            Q.push(bi[p]);
          }
        }
  }
}
int Dinic() {
  int hl = 0;
  while (true) {
    SPFA();
    if (dis[t] == 10000000) break;
    for (int i = 1; i <= t; ++i) nlt[i] = lt[i];
    hl += dfs(s, 10000000);
  }
  return hl;
}
void build(int a, int b, int c) {
  nt[++tl] = lt[a];
  lt[a] = tl;
  bi[tl] = b;
  ci[tl] = c;
  nt[++tl] = lt[b];
  lt[b] = tl;
  bi[tl] = a;
  ci[tl] = 0;
}
void init() {
  for (int i = 1; i <= tl; ++i) nt[i] = bi[i] = ci[i] = 0;
  tl = 0;
}
int a2[200000], b2[200000], c2[200000], n2[200000], l2[200000], tl2;
int v2[200000], ve[200000], in_cir[200000];
int shed[200000], top;
int cir_li[200000];
int tot_cir, len_cir;
int n, m;
void dfs_tree(int t, int ls) {
  v2[t] = 1;
  for (int p = l2[t]; p; p = n2[p])
    if (!ve[(p + 1) / 2]) {
      ve[(p + 1) / 2] = 1;
      shed[++top] = p;
      if (!v2[b2[p]]) {
        dfs_tree(b2[p], p);
        if (shed[top] == p) shed[top--] = 0;
      } else {
        int x;
        tot_cir++;
        do {
          x = shed[top];
          shed[top--] = 0;
          in_cir[(x + 1) / 2] = tot_cir;
          build(tot_cir, m + c2[x], 1);
          cir_li[tot_cir]++;
        } while (a2[x] != b2[p]);
      }
    }
}
int col[200000], mc;
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    n2[++tl2] = l2[a];
    l2[a] = tl2;
    a2[tl2] = a;
    b2[tl2] = b;
    c2[tl2] = c;
    n2[++tl2] = l2[b];
    l2[b] = tl2;
    a2[tl2] = b;
    b2[tl2] = a;
    c2[tl2] = c;
    col[c]++;
  }
  dfs_tree(1, 0);
  s = m * 2 + 1;
  t = s + 1;
  for (int i = 1; i <= tot_cir; ++i) build(s, i, cir_li[i] - 1);
  for (int i = 1; i <= m; ++i)
    if (!in_cir[i]) build(s, m + c2[i * 2 - 1], 1);
  for (int i = 1; i <= m; ++i) build(m + i, t, 1);
  int x = Dinic();
  cout << x;
}
