#include <bits/stdc++.h>
using namespace std;
struct NODE {
  int no, d;
} typedef NODE;
bool operator>(const NODE& x, const NODE& y) { return x.d > y.d; };
int E[100][100];
bool EB[100][100];
int color[100], p[100], d[100];
void dicstra(int n, int sno) {
  for (int i = 0; i < n; ++i) color[i] = 0, d[i] = ~(1U << 31), p[i] = -1;
  priority_queue<NODE, vector<NODE>, greater<NODE>> Q;
  color[sno] = 1;
  d[sno] = 0;
  Q.push({sno, d[sno]});
  while (!Q.empty()) {
    NODE top = Q.top();
    Q.pop();
    if (d[top.no] != top.d) continue;
    if ((color[top.no] == 1)) {
      for (int i = 0; i < n; ++i) {
        if ((color[i] != 2) && (E[top.no][i] != ~(1U << 31))) {
          if (d[i] > d[top.no] + E[top.no][i]) {
            d[i] = d[top.no] + E[top.no][i];
            color[i] = 1;
            p[i] = top.no;
            Q.push({i, d[i]});
          }
        }
      }
    }
    color[top.no] = 2;
  }
}
int caledge(int n) {
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    dicstra(n, i);
    for (int j = 0; j < n; ++j) {
      if (p[j] == -1) continue;
      EB[i][p[j]] = true;
      EB[p[j]][i] = true;
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (E[i][j] != ~(1U << 31) && EB[i][j] == false) ++ans;
    }
  }
  return ans / 2;
}
void printEB(int n) {
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (EB[i][j])
        cout << 1 << " ";
      else
        cout << 0 << " ";
    }
    cout << "\n";
  }
}
int main() {
  int N, M;
  cin >> N >> M;
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < N; ++j) E[i][j] = ~(1U << 31);
  while (M--) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a -= 1;
    b -= 1;
    E[a][b] = E[b][a] = c;
  }
  cout << caledge(N) << "\n";
}
