#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
using P = pair<int, int>;
int n, m;
vector<vector<int>> dist(100, vector<int>(100, 1e9));
vector<vector<int>> nex(100, vector<int>(100, -1));
vector<vector<int>> used(100, vector<int>(100, -1));
void warshall_froyd() {
  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][k] + dist[k][j] < dist[i][j]) {
          dist[i][j] = dist[i][k] + dist[k][j];
          nex[i][j] = nex[i][k];
        }
      }
    }
  }
}
void path(int start, int goal) {
  vector<int> rec;
  for (int cur = start; cur != goal; cur = nex[cur][goal]) {
    rec.emplace_back(cur);
  }
  for (int i = 0; i < rec.size() - 1; i++) {
    used[rec[i]][rec[i + 1]] = 1;
    used[rec[i + 1]][rec[i]] = 1;
  }
}
int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  cin >> n >> m;
  for (int i = 0; i < (int)(n); i++) {
    for (int j = 0; j < (int)(n); j++) {
      if (i == j) dist[i][j] = 0;
      nex[i][j] = j;
    }
  }
  for (int i = 0; i < (int)(m); i++) {
    int a, b, c;
    cin >> a >> b >> c;
    dist[a - 1][b - 1] = min(c, dist[a - 1][b - 1]);
    dist[b - 1][a - 1] = min(c, dist[a - 1][b - 1]);
    used[a - 1][b - 1] = 0;
    used[b - 1][a - 1] = 0;
  }
  warshall_froyd();
  for (int i = 0; i < (int)(n); i++) {
    for (int j = 0; j < (int)(n); j++) {
      if (i != j) {
        path(i, j);
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < (int)(n); i++) {
    for (int j = 0; j < (int)(n); j++) {
      if (used[i][j] == 0) ans++;
    }
  }
  cout << ans / 2 << endl;
}
