#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
long long n, m;
vector<long long> dist;
void dijkstra(vector<vector<long long>> &G,
              map<pair<long long, long long>, long long> &bet, long long start,
              vector<long long> &prev) {
  priority_queue<pair<long long, long long>> que;
  que.push({0, start});
  prev.assign(n, -1);
  dist.assign(n, (1ll << 60));
  dist[start] = 0;
  while (que.size()) {
    pair<long long, long long> now = que.top();
    que.pop();
    if (dist[now.second] < now.first) continue;
    for (auto next : G[now.second]) {
      if (dist[next] > dist[now.second] + bet[make_pair(now.second, next)]) {
        dist[next] = dist[now.second] + bet[make_pair(now.second, next)];
        que.push(make_pair(dist[next], next));
        prev[next] = now.second;
      }
    }
  }
}
vector<long long> get_path(vector<long long> &prev, int goal) {
  vector<long long> path;
  for (long long cur = goal; cur != -1; cur = prev[cur]) {
    path.push_back(cur);
  }
  reverse(path.begin(), path.end());
  return path;
}
int main() {
  cin >> n >> m;
  vector<vector<long long>> G(n);
  map<pair<long long, long long>, long long> bet;
  vector<pair<long long, long long>> stay;
  for (long long i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
    bet[make_pair(a, b)] = c;
    bet[make_pair(b, a)] = c;
    stay.push_back(make_pair(a, b));
    stay.push_back(make_pair(b, a));
  }
  map<pair<long long, long long>, bool> visit;
  for (long long i = 0; i < stay.size(); i++) {
    visit[stay[i]] = false;
  }
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < n; j++) {
      if (i == j) continue;
      vector<long long> dist, prev;
      dijkstra(G, bet, i, prev);
      vector<long long> path = get_path(prev, j);
      for (long long k = 0; k < path.size() - 1; k++) {
        visit[make_pair(path[k], path[k + 1])] = true;
        visit[make_pair(path[k + 1], path[k])] = true;
      }
    }
  }
  long long ans = 2 * m;
  for (long long i = 0; i < stay.size(); i++) {
    if (visit[stay[i]]) {
      ans--;
    }
  }
  cout << ans / 2 << endl;
  return 0;
}
