#include <bits/stdc++.h>
using namespace std;
struct eg {
  int dest, c, f, rev;
};
struct flow {
  vector<bool> vtd;
  vector<vector<eg> > egs;
  vector<vector<int> > ept;
  vector<int> dtt;
  int n, s, t, tot, inf;
  void ini(int pn, int ps, int pt) {
    n = pn;
    s = ps;
    t = pt;
    egs.resize(0);
    ept.resize(0);
    ept.resize(n, vector<int>(0));
    egs.resize(n, vector<eg>(0));
    dtt.resize(0);
    dtt.resize(n);
    tot = 0;
    inf = 1e9;
    vtd.resize(n);
  }
  void add(int a, int b, int c1, int c2 = 0) {
    eg ta, tb;
    ta.dest = b;
    tb.dest = a;
    ta.f = tb.f = 0;
    ta.c = c1;
    tb.c = c2;
    ta.rev = egs[b].size() + (a == b);
    tb.rev = egs[a].size();
    egs[a].push_back(ta);
    egs[b].push_back(tb);
  }
  int doit(int u, int lim) {
    if (u == t) return lim;
    int cfl = 0;
    int dlm;
    int pl;
    while (cfl < lim && ept[u].size() > 0) {
      eg& tp = egs[u][ept[u].back()];
      dlm = lim - cfl;
      if (dlm > tp.c - tp.f) dlm = tp.c - tp.f;
      pl = doit(tp.dest, dlm);
      tp.f += pl;
      egs[tp.dest][tp.rev].f -= pl;
      if (pl < dlm || dlm == 0) ept[u].pop_back();
      cfl += pl;
    }
    return cfl;
  }
  int dinic() {
    while (true) {
      for (int i = 0; i < (n); ++i) {
        ept[i].resize(0);
        dtt[i] = inf;
      }
      queue<int> q;
      dtt[t] = 0;
      q.push(t);
      while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int i = 0; i < ((int((egs[u]).size()))); ++i) {
          eg& tp = egs[u][i];
          if (dtt[tp.dest] < inf) continue;
          if (egs[tp.dest][tp.rev].c == egs[tp.dest][tp.rev].f) continue;
          dtt[tp.dest] = dtt[u] + 1;
          q.push(tp.dest);
        }
      }
      for (int i = 0; i < (n); ++i) vtd[i] = 0;
      vtd[s] = 1;
      q.push(s);
      while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int i = 0; i < ((int((egs[u]).size()))); ++i) {
          eg& tp = egs[u][i];
          if (dtt[tp.dest] + 1 > dtt[u]) continue;
          if (tp.f == tp.c) continue;
          ept[u].push_back(i);
          if (!vtd[tp.dest]) q.push(tp.dest);
          vtd[tp.dest] = 1;
        }
      }
      int pl = doit(s, inf);
      if (pl == 0) break;
      tot += pl;
    }
    return tot;
  }
};
flow tfl;
vector<vector<int> > egs, egc;
vector<int> cap;
vector<int> de;
vector<vector<int> > ccs;
vector<int> vis;
int n;
int fu, fv;
vector<int> nx;
vector<int> tpc;
bool fnd(int u) {
  if (vis[u]) return 0;
  vis[u] = 1;
  if (u == fv) return 1;
  int tp;
  for (int i = 0; i < ((int((egs[u]).size()))); ++i) {
    tp = egs[u][i];
    if (u == fu && tp == fv) continue;
    if (fnd(tp)) {
      nx[u] = tp;
      tpc.push_back(egc[u][i]);
      return 1;
    }
  }
  return 0;
}
bool fc(int u, int v, int c) {
  vis.resize(n);
  nx.resize(n);
  for (int i = 0; i < (n); ++i) {
    nx[i] = -1;
    vis[i] = 0;
  }
  fu = u;
  fv = v;
  bool tr = fnd(u);
  if (!tr) return 0;
  nx[v] = u;
  tpc.push_back(c);
  ccs.push_back(tpc);
  tpc.resize(0);
  for (int i = 0; i < ((int((egs).size()))); ++i) {
    int t = 0;
    for (int j = 0; j < ((int((egs[i]).size()))); ++j) {
      if (i == nx[egs[i][j]] || egs[i][j] == nx[i]) continue;
      egs[i][t] = egs[i][j];
      egc[i][t++] = egc[i][j];
    }
    egs[i].resize(t);
    egc[i].resize(t);
  }
  return 1;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int m;
  cin >> n >> m;
  cap.resize(m);
  egs.resize(n);
  egc.resize(n);
  int ta, tb, tc;
  for (int z = 0; z < (m); ++z) {
    cin >> ta >> tb >> tc;
    --ta;
    --tb;
    --tc;
    ++cap[tc];
    egs[ta].push_back(tb);
    egs[tb].push_back(ta);
    egc[ta].push_back(tc);
    egc[tb].push_back(tc);
  }
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < ((int((egs[i]).size()))); ++j) {
      if (egs[i][j] < i) continue;
      if (fc(i, egs[i][j], egc[i][j])) j = -1;
    }
  }
  de.resize(m);
  int tn = 0;
  for (int i = 0; i < ((int((cap).size()))); ++i) {
    if (cap[i])
      de[i] = tn++;
    else
      de[i] = -1;
  }
  int cc = (int((ccs).size()));
  int s = cc + tn;
  int t = s + 1;
  tfl.ini(t + 1, s, t);
  for (int i = 0; i < (m); ++i) {
    if (de[i] != -1) tfl.add(s, de[i], cap[i] - 1);
  }
  for (int i = 0; i < ((int((ccs).size()))); ++i) {
    tfl.add(i + tn, t, 1);
    for (int j = 0; j < ((int((ccs[i]).size()))); ++j)
      tfl.add(de[ccs[i][j]], i + tn, 1);
  }
  cout << tn - (cc - tfl.dinic()) << endl;
  return 0;
}
