#include <bits/stdc++.h>
using namespace std;
template <class T>
using pqueue = priority_queue<T>;
using vint = vector<long long>;
using vstr = vector<string>;
using pint = pair<long long, long long>;
using vp = vector<pint>;
using tint = tuple<long long, long long, long long>;
using vt = vector<tint>;
using mint = map<long long, long long>;
using dict = map<string, long long>;
using sint = set<long long>;
using sp = set<pint>;
using qint = queue<long long>;
using qp = queue<pint>;
using pqint = pqueue<long long>;
using pqp = pqueue<pint>;
const long long INF = LLONG_MAX - INT_MAX, MOD = 1e9 + 7, LIMIT = 100001,
                S_LIMIT = 101;
const long long dx[] = {-1, 0, 1, 0, 0}, dy[] = {0, -1, 0, 1, 0};
const string alphabet = "abcdefghijklmnopqrstuvwxyz";
long long a, b, c, k, n, m, x, y, z, w, h, res = 0, cnt = 0, sum = 0, mx = -INF,
                                           mn = INF;
string s, t;
long long g[S_LIMIT][S_LIMIT] = {};
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
long long modpw(long long x, long long n) {
  return n < 2 ? x : modpw(x * x % MOD, n / 2) * (n % 2 ? x : 1) % MOD;
}
long long factorial(long long a) { return a < 2 ? 1 : factorial(a - 1) * a; }
long long summation(long long a) { return a < 1 ? 0 : (a * a + a) / 2; }
long long combination(long long n, long long r) {
  long long res = 1;
  for (long long i = (long long)(1); i < (long long)(r + 1); i++)
    res *= n--, res /= i;
  return res;
}
long long modcomb(long long n, long long r) {
  return factorial(n) * modpw(factorial(r), MOD - 2) % MOD *
         modpw(factorial(n - r), MOD - 2) % MOD;
}
mint factoriazation(long long n) {
  mint ans;
  for (long long i = (long long)(2); i < (long long)(sqrt(n) + 1); i++)
    while (!(n % i)) ans[i]++, n /= i;
  if (n != 1) ans[n]++;
  return ans;
}
void warshall(long long n) {
  for (long long i = (long long)(0); i < (long long)(n); i++)
    for (long long j = (long long)(0); j < (long long)(n); j++)
      for (long long k = (long long)(0); k < (long long)(n); k++)
        g[j][k] = min(g[j][k], g[j][i] + g[i][k]);
}
struct UF {
  vint data;
  UF(long long size) : data(size, -1) {}
  bool unite(long long x, long long y) {
    x = root(x), y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y], data[y] = x;
    }
    return x != y;
  }
  long long root(long long x) {
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }
  bool find(long long x, long long y) { return root(x) == root(y); }
  long long size(long long x) { return -data[root(x)]; }
};
signed main() {
  cin.tie(0), ios::sync_with_stdio(false);
  cin >> n >> m;
  vp v;
  long long c[m];
  for (long long i = (long long)(0); i < (long long)(n); i++) {
    for (long long j = (long long)(0); j < (long long)(n); j++) {
      g[i][j] = i - j ? INF : 0;
    }
  }
  for (long long i = (long long)(0); i < (long long)(m); i++) {
    cin >> a >> b >> c[i];
    a--, b--;
    g[a][b] = g[b][a] = c[i];
    v.push_back(make_pair(a, b));
  }
  warshall(n);
  res = m;
  for (long long i = (long long)(0); i < (long long)(m); i++) {
    for (long long j = (long long)(0); j < (long long)(n); j++) {
      if (g[j][v[i].first] + c[i] == g[j][v[i].second]) {
        res--;
        break;
      }
    }
  }
  cout << (res), cout << '\n';
}
