#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int INF = 1E9;
const int MAXN = 1005000;
struct edge {
  int to, c, f, inv;
  edge(int _to = 0, int _c = 0, int _inv = 0) {
    to = _to;
    c = _c;
    f = 0;
    inv = _inv;
  }
};
int BEGIN, END, SZ;
vector<edge> edges;
vector<int> gf[MAXN];
void addEdge(int u, int v, int c) {
  int id = edges.size();
  edges.push_back(edge(v, c, id + 1));
  edges.push_back(edge(u, c, id));
  gf[u].push_back(id);
  gf[v].push_back(id + 1);
}
int n, m, tmr = 1;
int used[MAXN], tin[MAXN], marked[MAXN], cid[MAXN];
int color[MAXN];
vector<pair<pair<int, int>, int>> g[MAXN];
vector<pair<int, int>> st;
int lsz = 0;
vector<int> lists[MAXN];
void dfs(int v, int p = -1) {
  tin[v] = tmr++;
  used[v] = 1;
  for (auto ee : g[v]) {
    pair<int, int> e = ee.first;
    int w = e.first;
    if (ee.second == p) continue;
    if (used[w]) {
      if (tin[w] > tin[v]) continue;
      for (int i = (int)st.size() - 1; i >= 0; i--) {
        lists[lsz].push_back(color[st[i].second]);
        marked[st[i].second] = 1;
        if (st[i].first == w) break;
      }
      lists[lsz].push_back(color[ee.second]);
      marked[ee.second] = 1;
      lsz++;
    } else {
      st.push_back({v, ee.second});
      dfs(w, ee.second);
      st.pop_back();
    }
  }
}
bool get(int v, int F) {
  if (v == END) return 1;
  used[v] = tmr;
  for (auto eid : gf[v]) {
    if (used[edges[eid].to] == tmr) continue;
    if (edges[eid].c - edges[eid].f >= F && get(edges[eid].to, F)) {
      edges[eid].f += F;
      edges[edges[eid].inv].f -= F;
      return 1;
    }
  }
  return 0;
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < (int)(m); i++) {
    int a, b, c;
    cin >> a >> b >> c;
    a--, b--, c--;
    g[a].push_back({{b, c}, i});
    g[b].push_back({{a, c}, i});
    color[i] = c;
  }
  dfs(0);
  SZ = 0;
  BEGIN = SZ++;
  END = SZ++;
  for (int i = 0; i < (int)(m); i++) cid[i] = SZ++;
  for (int i = 0; i < (int)(lsz); i++) {
    int V = SZ++;
    addEdge(BEGIN, V, (int)lists[i].size() - 1);
    for (auto c : lists[i]) addEdge(V, cid[c], 1);
  }
  for (int i = 0; i < (int)(m); i++) {
    if (!marked[i]) {
      addEdge(BEGIN, cid[color[i]], 1);
    }
  }
  for (int i = 0; i < (int)(m); i++) addEdge(cid[i], END, 1);
  int ans = 0;
  tmr = 1;
  memset(used, 0, sizeof(used));
  for (int F = (1 << 29); F > 0; F >>= 1) {
    tmr++;
    while (get(BEGIN, F)) {
      tmr++;
      ans += F;
    }
  }
  cout << ans << '\n';
  return 0;
}
