#include <bits/stdc++.h>
using namespace std;
const long long big = 1000000007LL;
const long long INF = 1e18;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
long long max(long long x, long long y) {
  if (x > y)
    return x;
  else
    return y;
}
long long min(long long x, long long y) {
  if (x < y)
    return x;
  else
    return y;
}
long long expm(long long x, long long y) {
  if (y == 0) return 1;
  if (x == 1 || x == 0) return x;
  if (y % 2 == 1) return (expm(x, y - 1) * x) % big;
  long long t = expm(x, y / 2);
  return (t * t) % big;
}
long long exp(long long x, long long y) {
  if (y == 0) return 1;
  if (x == 1 || y == 0) return x;
  if (y % 2 == 1) return exp(x, y - 1) * x;
  long long t = exp(x, y / 2);
  return t * t;
}
struct edge {
  long long to, cost;
};
struct graph {
  vector<vector<edge>> g;
  vector<long long> d;
  graph(long long n) : g(n), d(n, INF) {}
  void addedge(const long long s, const long long t, const long long cost) {
    edge e;
    e.to = t;
    e.cost = cost;
    g[s].emplace_back(e);
  }
  void dijkstra(long long s, set<pair<int, int>> &al) {
    for (int i = 0; i < (int)(d.size()); i++) d[i] = INF;
    d[s] = 0;
    priority_queue<pair<long long, pair<long long, long long>>,
                   vector<pair<long long, pair<long long, long long>>>,
                   greater<pair<long long, pair<long long, long long>>>>
        que;
    que.push(pair<long long, pair<long long, long long>>(0, {s, -1}));
    while (!que.empty()) {
      pair<long long, pair<long long, long long>> pa = que.top();
      que.pop();
      long long k = pa.second.first;
      if (d[k] < pa.first) continue;
      al.insert({pa.second.first, pa.second.second});
      al.insert({pa.second.second, pa.second.first});
      for (auto e : g[k]) {
        if (d[e.to] > d[k] + e.cost) {
          d[e.to] = d[k] + e.cost;
          que.push(
              pair<long long, pair<long long, long long>>(d[e.to], {e.to, k}));
        }
      }
    }
  }
};
int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  cout << fixed << setprecision(10);
  set<pair<int, int>> al;
  int n, m;
  cin >> n >> m;
  graph g(n);
  for (int i = 0; i < (int)(m); i++) {
    int a, b, c;
    cin >> a >> b >> c;
    g.addedge(a - 1, b - 1, c);
    g.addedge(b - 1, a - 1, c);
  }
  for (int i = 0; i < (int)(n); i++) {
    g.dijkstra(i, al);
  }
  cout << m - (int)al.size() / 2 + 3 << endl;
}
