#include <bits/stdc++.h>
using namespace std;
const int N = 10000 + 10;
vector<vector<pair<int, int> > > G;
vector<vector<int> > g;
int low[N], id[N], dfsnum, n, m, color[2 * N], cap[N * 2];
bool vis[N], bridge[N * 2];
void dfs(int u, int p) {
  vis[u] = true;
  low[u] = id[u] = dfsnum++;
  for (int i = 0; i < G[u].size(); ++i) {
    int v = G[u][i].first;
    if (!vis[v]) {
      dfs(v, u);
      if (low[v] > id[u]) {
        bridge[G[u][i].second] = true;
        cap[g.size()] = 1;
        g.push_back(vector<int>(1, color[G[u][i].second]));
      }
      low[u] = min(low[u], low[v]);
    } else if (v != p)
      low[u] = min(low[u], low[v]);
  }
}
vector<pair<pair<int, int>, int> > edges;
stack<int> st;
bool ins[N];
void DFS(int u, int p) {
  vis[u] = true;
  for (int i = 0; i < G[u].size(); ++i) {
    if (bridge[G[u][i].second]) continue;
    int v = G[u][i].first;
    if (v == p) continue;
    if (!vis[v]) {
      st.push(u);
      ins[u] = true;
      DFS(v, u);
    } else if (ins[v]) {
      g.push_back(vector<int>());
      set<int> col;
      col.insert(color[G[u][i].second]);
      int x = -1, y = u, cnt = 1;
      while (y != v) {
        ++cnt;
        x = st.top();
        st.pop();
        ins[x] = false;
        int idx = lower_bound(edges.begin(), edges.end(),
                              make_pair(make_pair(min(x, y), max(x, y)), 0)) -
                  edges.begin();
        col.insert(color[edges[idx].second]);
        y = x;
      }
      for (auto x : col) g.back().push_back(x);
      cap[g.size() - 1] = cnt - 1;
    }
  }
}
int match[N * 2], VIS = 1, visit[N];
bool findpath(int u) {
  visit[u] = VIS;
  for (int i = 0; i < g[u].size(); ++i) {
    if (match[g[u][i]] == -1 ||
        (visit[match[g[u][i]]] != VIS && findpath(match[g[u][i]]))) {
      match[g[u][i]] = u;
      return true;
    }
  }
  return false;
}
int MaxMatching() {
  int ans = 0;
  memset(match, -1, sizeof match);
  for (int i = 0; i < g.size(); ++i) {
    while (cap[i]-- && findpath(i)) {
      ++ans;
      VIS++;
    }
  }
  return ans;
}
int main(int argc, char *argv[]) {
  scanf("%d%d", &n, &m);
  G.resize(n);
  for (int i = 0, x, y, z; i < m; ++i) {
    scanf("%d%d%d", &x, &y, &z);
    --x, --y;
    if (x > y) swap(x, y);
    edges.push_back(make_pair(make_pair(x, y), i));
    G[x].push_back(make_pair(y, i));
    G[y].push_back(make_pair(x, i));
    color[i] = z;
  }
  sort(edges.begin(), edges.end());
  dfs(0, -1);
  memset(vis, 0, sizeof vis);
  g.reserve(n + 1);
  for (int i = 0; i < n; ++i)
    if (!vis[i]) DFS(i, -1);
  printf("%d\n", MaxMatching());
  return 0;
}
