#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const long long LINF = 1e18;
const int MOD = INF + 7;
struct edge {
  int to, cost;
};
int ans[100][100];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  int a, b, c;
  vector<edge> es[n];
  for (int i = 0; i < m; i++) {
    cin >> a >> b >> c;
    a--;
    b--;
    es[a].push_back({b, c});
    es[b].push_back({a, c});
    ans[a][b] = ans[b][a] = 1;
  }
  int d[n], f, t, cost, from[n];
  pair<int, int> tmp;
  for (int s = 0; s < n - 1; s++) {
    for (int i = s; i < n; i++) {
      d[i] = from[i] = INF;
    }
    priority_queue<pair<int, int>, vector<pair<int, int>>,
                   greater<pair<int, int>>>
        que;
    que.push(pair<int, int>(0, s));
    d[s] = 0;
    while (!que.empty()) {
      tmp = que.top();
      que.pop();
      cost = tmp.first, f = tmp.second;
      if (d[f] < cost) continue;
      for (int j = 0; j < es[f].size(); j++) {
        t = es[f][j].to, cost = es[f][j].cost;
        if (t > s && d[t] > d[f] + cost) {
          d[t] = d[f] + cost;
          que.push(pair<int, int>(d[t], t));
          from[t] = f;
        }
      }
    }
    for (int i = s + 1; i < n; i++) {
      if (from[i] != INF) {
        ans[i][from[i]]--;
        ans[from[i]][i]--;
      }
    }
  }
  int num = 0;
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      if (ans[i][j] == 1) num++;
    }
  }
  cout << num << "\n";
  return 0;
}
