#include <bits/stdc++.h>
using namespace std;
const long double PI = 3.141592653589793238463;
const int N = 5e5 + 10;
vector<int> g[N];
bool viss[N];
int vis[N];
void dfs(int curr, int par) {
  for (auto x : g[curr])
    if (x != par) dfs(x, curr);
}
void dfs1(int curr, int par) {
  viss[curr] = 1;
  for (auto x : g[curr])
    if (!viss[x]) dfs1(x, curr);
}
void dfs2(int curr, int par, int num) {
  vis[curr] = num;
  for (auto x : g[curr])
    if (vis[x] == 0) dfs2(x, curr, num);
}
long long fxor(long long n) {
  if (n < 0) return 0;
  if (n % 4 == 3)
    return 0;
  else if (n % 4 == 0)
    return n;
  else if (n % 4 == 1)
    return n ^ (n - 1);
  else if (n % 4 == 2)
    return n ^ (n - 1) ^ (n - 2);
}
unsigned long long int ppow(unsigned long long int x,
                            unsigned long long int y) {
  unsigned long long int res = 1;
  while (y > 0) {
    if (y & 1) res = (res * x) % 1000000007;
    y = y >> 1;
    x = (x * x) % 1000000007;
  }
  return res;
}
unsigned long long int factdp[N];
unsigned long long int fact(unsigned long long int x) {
  if (x == 0) return 1;
  if (x == 1) return 1;
  if (factdp[x] != -1) return factdp[x];
  return factdp[x] = (x * fact(x - 1)) % 1000000007;
}
string ansConv = "";
void convert10tob(unsigned long long int N, int b) {
  if (N == 0) return;
  int x = N % b;
  N /= b;
  if (x < 0) N += 1;
  convert10tob(N, b);
  ansConv += to_string(x);
  return;
}
unsigned long long int convertstrtob(string a, int b) {
  unsigned long long int aa = 0;
  unsigned long long int mul = 1;
  for (int i = a.length() - 1; i >= 0; i--) {
    int curr = a[i] - '0';
    aa += (curr * mul);
    mul *= b;
  }
  return aa;
}
int findpar(int curr, int arr[]) {
  while (arr[curr] != curr) curr = arr[curr];
  return curr;
}
void Union(int b, int spa, int arr[]) {
  while (arr[b] != b) {
    int c = arr[b];
    arr[b] = spa;
    b = c;
  }
  arr[b] = spa;
}
const int NN = 110;
int graph[110][110];
int dist[110][110];
int par[110][110];
bool ppath[110][110];
map<pair<int, int>, int> mp;
int used = 0;
void path(int x, int y) {
  ppath[x][y] = 1;
  ppath[y][x] = 1;
  if (x == y) return;
  if (par[x][y] == -1) {
    int xx = min(x, y);
    int yy = max(x, y);
    if (mp[{xx, yy}] == 0) {
      used++;
      mp[{xx, yy}] = 1;
    }
    return;
  }
  path(x, par[x][y]);
  path(par[x][y], y);
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      graph[i][j] = dist[i][j] = 10000;
      par[i][j] = -1;
      if (i == j) {
        dist[i][j] = 0;
        graph[i][j] = 0;
      }
    }
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    graph[a][b] = graph[b][a] = c;
    dist[a][b] = dist[b][a] = c;
  }
  for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= n; j++)
        if ((dist[i][k] + dist[k][j]) < dist[i][j]) {
          dist[i][j] = dist[i][k] + dist[k][j];
          par[i][j] = k;
        }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (ppath[i][j] == 0) path(i, j);
  cout << m - used << endl;
  return 0;
}
