#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int src, dst;
  int weight;
  Edge(int src, int dst, int weight) : src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight
         : e.src != f.src     ? e.src < f.src
                              : e.dst < f.dst;
}
void shortestPath(const vector<vector<int>> &g, vector<vector<int>> &dist,
                  vector<vector<int>> &inter) {
  int n = g.size();
  dist = g;
  inter.assign(n, vector<int>(n, -1));
  for (int k = 0; k < (int)n; ++k)
    for (int i = 0; i < (int)n; ++i)
      for (int j = 0; j < (int)n; ++j) {
        if (dist[i][j] >= dist[i][k] + dist[k][j]) {
          dist[i][j] = dist[i][k] + dist[k][j];
          inter[i][j] = k;
        }
      }
}
void buildPath(const vector<vector<int>> &inter, int s, int t,
               vector<int> &path) {
  int u = inter[s][t];
  if (u < 0)
    path.push_back(s);
  else
    buildPath(inter, s, u, path), buildPath(inter, u, s, path);
}
vector<int> buildPath(const vector<vector<int>> &inter, int s, int t) {
  vector<int> path;
  buildPath(inter, s, t, path);
  path.push_back(t);
  return path;
}
void solve(long long N, long long M, vector<long long> a, vector<long long> b,
           vector<long long> c) {
  vector<vector<int>> mat;
  int edges[100][100] = {0};
  int edgeId[100][100] = {0};
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (i == j) {
        continue;
      }
      edges[i][j] = 100000000;
    }
  }
  for (int i = 0; i < M; i++) {
    edges[a[i] - 1][b[i] - 1] = c[i];
    edges[b[i] - 1][a[i] - 1] = c[i];
    edgeId[a[i] - 1][b[i] - 1] = i;
    edgeId[b[i] - 1][a[i] - 1] = i;
  }
  for (int i = 0; i < N; i++) {
    vector<int> ws;
    for (int j = 0; j < N; j++) {
      int w = edges[i][j];
      ws.push_back(w);
    }
    mat.push_back(ws);
  }
  vector<vector<int>> dist;
  vector<vector<int>> inter;
  shortestPath(mat, dist, inter);
  vector<int> pathEdge;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (i == j) continue;
      vector<int> path;
      path = buildPath(inter, i, j);
      for (int z = 0; z < path.size() - 1; z++) {
        pathEdge.push_back(edgeId[path[z]][path[z + 1]]);
      }
    }
  }
  sort(pathEdge.begin(), pathEdge.end());
  pathEdge.erase(unique(pathEdge.begin(), pathEdge.end()), pathEdge.end());
  printf("%d\n", (M - pathEdge.size()));
}
int main() {
  long long N;
  long long M;
  scanf("%lld", &N);
  scanf("%lld", &M);
  vector<long long> c(M - 1 + 1);
  vector<long long> b(M - 1 + 1);
  vector<long long> a(M - 1 + 1);
  for (int i = 0; i <= M - 1; i++) {
    scanf("%lld", &a[i]);
    scanf("%lld", &b[i]);
    scanf("%lld", &c[i]);
  }
  solve(N, M, a, b, c);
  return 0;
}
