#include <bits/stdc++.h>
class warshall_floyd {
 private:
  int node_num;
  bool is_negative_graph;
  std::vector<std::vector<long long>> cost_matrix;
  std::vector<std::vector<int>> pred;

 public:
  warshall_floyd(const int node_num,
                 const std::vector<std::vector<long long>> &adj_matrix);
  bool get_is_negative_graph() const;
  bool get_is_negative_pass(int start, int end) const;
  long long get_cost(int start, int end) const;
  std::vector<int> get_min_path(int start, int end) const;
};
warshall_floyd::warshall_floyd(
    const int node_num, const std::vector<std::vector<long long>> &adj_matrix)
    : cost_matrix(adj_matrix),
      node_num(node_num),
      is_negative_graph(false),
      pred(node_num + 1, std::vector<int>(node_num + 1, INT_MAX)) {
  for (int i = 0; i <= node_num; i++) {
    for (int j = 0; j <= node_num; j++) {
      if (i == j)
        pred[i][j] = -1;
      else if (adj_matrix[i][j] < LLONG_MAX) {
        pred[i][j] = i;
      }
    }
  }
  for (int k = 0; k <= node_num; k++) {
    for (int i = 0; i <= node_num; i++) {
      for (int j = 0; j <= node_num; j++) {
        if (cost_matrix[i][k] < LLONG_MAX && cost_matrix[k][j] < LLONG_MAX) {
          if (cost_matrix[i][k] + cost_matrix[k][j] < cost_matrix[i][j]) {
            cost_matrix[i][j] = cost_matrix[i][k] + cost_matrix[k][j];
            pred[i][j] = pred[k][j];
          }
        }
      }
    }
  }
  for (int i = 0; i <= node_num; i++) {
    cost_matrix[i][i] = 0;
  }
  for (int i = 0; i <= node_num; i++) {
    if (cost_matrix[i][i] < 0) {
      for (int j = 0; j <= node_num; j++) {
        if (i == j) continue;
        if (cost_matrix[i][j] < LLONG_MAX && cost_matrix[j][j] >= 0)
          cost_matrix[j][j] = -1;
      }
      is_negative_graph = true;
    }
  }
}
bool warshall_floyd::get_is_negative_graph() const { return is_negative_graph; }
bool warshall_floyd::get_is_negative_pass(int start, int end) const {
  if (cost_matrix[start][end] < LLONG_MAX) {
    if (cost_matrix[end][end] < 0) return true;
  }
  return false;
}
long long warshall_floyd::get_cost(int start, int end) const {
  return cost_matrix[start][end];
}
std::vector<int> warshall_floyd::get_min_path(int start, int end) const {
  int node = end;
  std::vector<int> vec;
  vec.push_back(node);
  while (1) {
    if (cost_matrix[node][node] < 0 || pred[start][node] >= INT_MAX ||
        pred[start][node] == -1)
      break;
    node = pred[start][node];
    vec.push_back(node);
  }
  std::reverse(vec.begin(), vec.end());
  return vec;
}
int main() {
  int N, M;
  std::cin >> N >> M;
  std::vector<std::vector<long long>> adj_matrix(
      N + 1, std::vector<long long>(N + 1, LLONG_MAX));
  std::vector<int> edge_num(N + 1, 0);
  for (int j = 0; j < M; j++) {
    long long a, b, c;
    std::cin >> a >> b >> c;
    adj_matrix[a][b] = c;
    adj_matrix[b][a] = c;
    edge_num[a]++;
    edge_num[b]++;
  }
  std::vector<std::vector<bool>> is_used(N + 1,
                                         std::vector<bool>(N + 1, false));
  warshall_floyd wf(N, adj_matrix);
  int count = 0;
  for (int i = 1; i <= N; i++) {
    for (int j = i + 1; i <= N; i++) {
      if (adj_matrix[i][j] == LLONG_MAX) continue;
      if (wf.get_cost(i, j) != adj_matrix[i][j]) {
        count++;
      }
    }
  }
  std::cout << count << std::endl;
}
