#include <bits/stdc++.h>
using namespace std;
long long inf = 1e18;
long long d[1005], pre[105], cost[105][105];
long long v, e;
bool used[1005];
void dijkstra(int s) {
  fill(d, d + v, inf);
  fill(used, used + v, false);
  fill(pre, pre + v, -1);
  d[s] = 0;
  while (1) {
    int w = -1;
    for (int u = 0; u < v; u++) {
      if (!used[u] && (w == -1 || d[u] < d[w])) w = u;
    }
    if (w == -1) break;
    used[w] = true;
    for (int u = 0; u < v; u++) {
      if (d[u] > d[w] + cost[w][u]) {
        d[u] = d[w] + cost[w][u];
        pre[u] = w;
      }
    }
  }
}
vector<int> get_path(int t) {
  vector<int> path;
  for (; t != -1; t = pre[t]) path.push_back(t);
  return path;
}
int main(void) {
  cin >> v >> e;
  bool road[105][105] = {};
  for (int i = 0; i < e; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    cost[a][b] = cost[b][a] = c;
    road[a][b] = road[b][a] = true;
  }
  for (int i = 0; i < v; i++) {
    dijkstra(i);
    for (int j = i + 1; j < v; j++) {
      vector<int> x = get_path(j);
      for (int p = 0; p < x.size() - 1; p++) {
        road[x[p]][x[p + 1]] = false;
        road[x[p + 1]][x[p]] = false;
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < v; i++) {
    for (int j = 0; j < v; j++) {
      if (road[i][j]) ans++;
    }
  }
  cout << ans / 2 << endl;
}
