#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<int> cyc[maxn];
int cs, edge[maxn], stk[maxn], top, ins[maxn];
bool del[maxn << 1];
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 / 2 + 1]) continue;
    edge[u] = i;
    if (ins[v]) {
      ++cs;
      for (int j = ins[v]; j <= (int)ins[u]; j++)
        cyc[cs].push_back(col[edge[stk[j]]]);
      for (int j = ins[v]; j <= (int)ins[u]; j++) del[edge[stk[j]] / 2 + 1] = 1;
    } else
      dfs(v, i);
  }
  ins[u] = 0, top--;
}
int S, T;
const int maxm = 200000;
struct flowgraph {
  int to[maxm], nx[maxm], cap[maxm], hd[maxnd];
  flowgraph() { memset(hd, -1, sizeof hd); }
  void addedge(int u, int v, int cp) {
    to[cnt] = v;
    nx[cnt] = hd[u];
    cap[cnt] = cp;
    hd[u] = cnt++;
    to[cnt] = u;
    nx[cnt] = hd[v];
    cap[cnt] = 0;
    hd[v] = cnt++;
  }
  int dep[maxnd], head, tail, que[maxnd];
  bool bfs() {
    memset(dep, -1, sizeof dep);
    dep[S] = 1;
    head = 1, tail = 0, que[++tail] = S;
    while (head <= tail) {
      int u = que[head++];
      for (int i = hd[u]; ~i; i = nx[i]) {
        int v = to[i];
        if (cap[i] && dep[v] == -1) {
          dep[v] = dep[u] + 1;
          if (v == T) return 1;
          que[++tail] = v;
        }
      }
    }
    return 0;
  }
  int dfs(int u, int f) {
    if (u == T || !f) return f;
    int ret = 0, fl;
    for (int i = hd[u]; ~i; i = nx[i]) {
      int v = to[i];
      if (dep[v] == dep[u] + 1 && (fl = dfs(v, min(f, cap[i]))) != 0) {
        cap[i] -= fl, cap[i ^ 1] += fl;
        ret += fl, f -= fl;
      }
    }
    if (!ret) dep[u] = -1;
    return ret;
  }
  int flow() {
    int ret = 0;
    while (bfs()) ret += dfs(S, (1 << 29));
    return ret;
  }
} F;
int n, m;
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);
  S = 0, T = n + m + 1;
  int nd = 0;
  for (int i = 1; i <= (int)m; i++)
    if (!del[i]) {
      ++nd;
      F.addedge(S, cs + nd, 1);
      F.addedge(cs + nd, n + col[(i - 1) * 2], 1);
    }
  for (int i = 1; i <= (int)cs; i++) {
    F.addedge(S, i, cyc[i].size() - 1);
    for (int j = 0; j <= (int)cyc[i].size() - 1; j++)
      F.addedge(i, n + cyc[i][j], 1);
  }
  for (int i = 1; i <= (int)m; i++) F.addedge(n + i, T, 1);
  rt(F.flow());
}
