#include <bits/stdc++.h>
using namespace std;
inline long long rd() {
  long long x = 0;
  int ch = getchar(), f = 1;
  while (!isdigit(ch) && (ch != '-') && (ch != EOF)) ch = getchar();
  if (ch == '-') {
    f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void rt(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10)
    rt(x / 10), putchar(x % 10 + '0');
  else
    putchar(x + '0');
}
const int maxn = 10005, maxnd = 30005;
int to[maxn << 2], nx[maxn << 2], hd[maxn], col[maxn << 2], cnt;
void addedge(int u, int v, int w) {
  to[cnt] = v;
  nx[cnt] = hd[u];
  col[cnt] = w;
  hd[u] = cnt++;
}
vector<pair<int, int> > cyc[maxn];
int cs, edge[maxn], stk[maxn], top, ins[maxn];
int vis[maxn << 1], head, tail, que[maxn << 1];
bool del[maxn << 2];
void dfs(int u, int fa) {
  stk[++top] = u;
  ins[u] = top;
  for (int i = hd[u]; ~i; i = nx[i]) {
    int v = to[i];
    if (i == (fa ^ 1) || del[i]) continue;
    edge[u] = i;
    if (ins[v]) {
      ++cs;
      for (int j = ins[v]; j <= (int)ins[u]; j++)
        cyc[cs].push_back(make_pair(stk[j], col[edge[stk[j]]]));
      for (int j = ins[v]; j <= (int)ins[u]; j++)
        del[edge[stk[j]]] = del[edge[stk[j]] ^ 1] = 1;
    } else
      dfs(v, i);
  }
  ins[u] = 0, top--;
}
int n, m, S, T, ex[maxn << 1], num[maxn << 1];
bool te[maxn << 1];
const int maxm = 200000;
struct flowgraph {
  int to[maxm], nx[maxm], cap[maxm], val[maxm], hd[maxnd];
  flowgraph() { memset(hd, -1, sizeof hd); }
  void addedge(int u, int v, int cp, int vl) {
    to[cnt] = v;
    nx[cnt] = hd[u];
    cap[cnt] = cp;
    val[cnt] = vl;
    hd[u] = cnt++;
    to[cnt] = u;
    nx[cnt] = hd[v];
    cap[cnt] = 0;
    val[cnt] = -vl;
    hd[v] = cnt++;
  }
  int dist[maxnd], head, tail, que[maxnd * 50], pre[maxnd];
  bool vis[maxnd];
  bool spfa() {
    memset(dist, -1, sizeof dist);
    dist[S] = 0;
    head = 1, tail = 0;
    que[++tail] = S;
    while (head <= tail) {
      int u = que[head++];
      vis[u] = 0;
      for (int i = hd[u]; ~i; i = nx[i]) {
        if (!cap[i]) continue;
        int v = to[i];
        if (dist[v] == -1 || dist[v] > dist[u] + val[i]) {
          dist[v] = dist[u] + val[i];
          pre[v] = i;
          if (!vis[v]) {
            vis[v] = 1;
            que[++tail] = v;
          }
        }
      }
    }
    return dist[T] != -1;
  }
  int flow() {
    int ret = 0;
    while (spfa()) {
      int p = T, f = (1 << 29);
      while (p != S) f = min(f, cap[pre[p]]), p = to[pre[p] ^ 1];
      p = T;
      ret += f * dist[T];
      while (p != S) cap[pre[p]] -= f, cap[pre[p] ^ 1] += f, p = to[pre[p] ^ 1];
    }
    return ret;
  }
} F;
vector<int> link[maxn << 1];
int main() {
  n = rd(), m = rd();
  memset(hd, -1, sizeof hd);
  for (int i = 1; i <= (int)m; i++) {
    int u = rd(), v = rd(), w = rd();
    addedge(u, v, w), addedge(v, u, w);
  }
  dfs(1, -1);
  for (int i = 1; i <= (int)cs; i++)
    for (int j = 0; j <= (int)cyc[i].size() - 1; j++)
      link[cyc[i][j].second].push_back(i);
  for (int i = 1; i <= (int)m; i++)
    if (!del[(i - 1) * 2])
      te[col[(i - 1) * 2]] = 1, que[++tail] = col[(i - 1) * 2];
  for (int i = 1; i <= (int)cs; i++)
    for (int j = 0; j <= (int)cyc[i].size() - 1; j++) {
      int color = cyc[i][j].second;
      if (ex[color] == i) {
        if (!te[color]) te[color] = 1, que[++tail] = color;
      } else
        ex[color] = i;
    }
  memset(del, 0, sizeof del);
  while (head <= tail) {
    int col = que[head++];
    for (int j = 0; j <= (int)link[col].size() - 1; j++) {
      int hs = link[col][j];
      if (del[hs]) continue;
      del[hs] = 1;
      for (int k = 0; k <= (int)cyc[hs].size() - 1; k++) {
        if (!te[cyc[hs][k].second])
          te[cyc[hs][k].second] = 1, que[++tail] = cyc[hs][k].second;
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= (int)m; i++)
    if (te[i]) ans++;
  int _cs = cs, nd = 0;
  cs = 0;
  memset(ex, 0, sizeof ex);
  for (int i = 1; i <= (int)_cs; i++)
    if (!del[i]) cyc[++cs] = cyc[i];
  for (int i = 1; i <= (int)cs; i++)
    for (int j = 0; j <= (int)cyc[i].size() - 1; j++) {
      if (!ex[cyc[i][j].second]) ex[cyc[i][j].second] = ++nd;
      num[ex[cyc[i][j].second]]++;
    }
  S = 0, T = nd + cs + 1;
  for (int i = 1; i <= (int)nd; i++) {
    F.addedge(S, i, num[i] - 1, 0);
    F.addedge(S, i, 1, 1);
  }
  for (int i = 1; i <= (int)cs; i++)
    for (int j = 0; j <= (int)cyc[i].size() - 1; j++)
      F.addedge(ex[cyc[i][j].second], nd + i, 1, 0);
  for (int i = 1; i <= (int)cs; i++) F.addedge(nd + i, T, 1, 0);
  ans += nd - F.flow();
  rt(ans);
}
