#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T1, class T2>
ostream& operator<<(ostream& s, pair<T1, T2> P) {
  return s << '<' << P.first << ", " << P.second << '>';
}
template <class T>
ostream& operator<<(ostream& s, vector<T> P) {
  for (long long i = 0; i < P.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << P[i];
  }
  return s;
}
template <class T>
ostream& operator<<(ostream& s, vector<vector<T> > P) {
  for (long long i = 0; i < P.size(); ++i) {
    s << endl << P[i];
  }
  return s << endl;
}
template <class T>
ostream& operator<<(ostream& s, set<T> P) {
  for (__typeof__((P).begin()) it = (P).begin(); it != (P).end(); ++it) {
    s << "<" << *it << "> ";
  }
  return s << endl;
}
template <class T1, class T2>
ostream& operator<<(ostream& s, map<T1, T2> P) {
  for (__typeof__((P).begin()) it = (P).begin(); it != (P).end(); ++it) {
    s << "<" << it->first << "->" << it->second << "> ";
  }
  return s << endl;
}
template <class T>
void show(vector<T> v) {
  for (long long i = 0; i < v.size(); i++) {
    cerr << v[i] << " ";
  }
  cerr << "\n";
}
long long d[110][110];
long long h[110][110];
bool g[110][110];
long long n, m;
vector<long long> restore_path(long long start, long long end) {
  vector<long long> p;
  long long curr = start;
  while (curr != end) {
    for (long long i = 0; i < n; i++) {
      if (i != curr && h[curr][i] + d[i][end] == d[curr][end]) {
        curr = i;
        p.push_back(i);
        break;
      }
    }
  }
  return p;
}
signed main() {
  cin >> n >> m;
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < n; j++) {
      d[i][j] = 1e18;
      if (i == j) d[i][j] = 0;
    }
  }
  for (long long i = 0; i < m; i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    a--, b--;
    d[a][b] = c;
    d[b][a] = c;
  }
  for (long long i = 0; i < n; ++i)
    for (long long j = 0; j < n; ++j) h[i][j] = d[i][j];
  for (long long k = 0; k < n; k++) {
    for (long long i = 0; i < n; i++) {
      for (long long j = 0; j < n; j++) {
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
      }
    }
  }
  for (long long i = 0; i < n; i++) {
    for (long long j = i + 1; j < n; j++) {
      vector<long long> p = restore_path(i, j);
      g[i][p[0]] = g[p[0]][i] = true;
      for (long long i = 0; i < p.size() - 1; i++) {
        g[p[i]][p[i + 1]] = g[p[i + 1]][p[i]] = true;
      }
      g[p.back()][j] = g[j][p.back()] = true;
    }
  }
  long long cnt = 0;
  for (long long i = 0; i < n; i++) {
    for (long long j = i + 1; j < n; j++) {
      if (i == j) continue;
      if (h[i][j] != 1e18 && !g[i][j]) cnt++;
    }
  }
  cout << cnt << endl;
  return 0;
}
