#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int from, to;
  int wei;
  Edge(int from_, int to_, int wei_) : from(from_), to(to_), wei(wei_) {}
};
const int INFW = numeric_limits<int>::max();
struct Graph : public vector<vector<Edge>> {
  Graph() {}
  Graph(int V) : vector<vector<Edge>>(V) {}
  void addEdge(int from, int to, int wei = 1) {
    (*this)[from].push_back(Edge(from, to, wei));
  }
  void addUEdge(int u, int v, int wei = 1) {
    (*this)[u].push_back(Edge(u, v, wei));
    (*this)[v].push_back(Edge(v, u, wei));
  }
};
bool operator<(const Edge &a, const Edge &b) { return a.wei < b.wei; }
bool operator>(const Edge &a, const Edge &b) { return a.wei > b.wei; }
vector<int> dijkstra(const Graph &G, int src) {
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      pq;
  pq.push(make_pair(0, src));
  int V = (int)G.size();
  vector<int> res(V, -1);
  while (pq.size()) {
    auto p = pq.top();
    pq.pop();
    int d = p.first;
    int v = p.second;
    if (res[v] > -1) continue;
    res[v] = d;
    for (const auto &edge : G[v]) {
      int to = edge.to;
      int wei = edge.wei;
      pq.push(make_pair(d + wei, to));
    }
  }
  return res;
}
const int MA = 22000;
int N, M, A[MA], B[MA], C[MA], used[101][101], visited[100];
Graph G;
vector<int> dist;
void init() {
  memset((used), (0), sizeof(used));
  G = Graph(N);
  for (int(i) = (0); (i) < (int)(M); ++(i)) {
    --A[i];
    --B[i];
    G.addUEdge(A[i], B[i], C[i]);
  }
}
void rest(int goal) {
  memset((visited), (0), sizeof(visited));
  queue<int> Q;
  Q.push(goal);
  while ((int)(Q).size()) {
    int cur = Q.front();
    Q.pop();
    if (visited[cur]++) continue;
    for (auto &(edge) : (G[cur])) {
      if (dist[edge.to] + edge.wei == dist[cur]) {
        used[edge.to][cur] = 1;
        used[cur][edge.to] = 1;
        if (!visited[edge.to]) {
          Q.push(edge.to);
        }
      }
    }
  }
}
void solve() {
  for (int(i) = (0); (i) < (int)(N); ++(i)) {
    dist = dijkstra(N, i);
    for (int(goal) = (0); (goal) < (int)(N); ++(goal)) {
      rest(goal);
    }
  }
  int ans = 0;
  for (int(i) = (0); (i) < (int)(M); ++(i)) {
    if (!used[A[i]][B[i]]) {
      ans++;
    }
  }
  cout << ans << endl;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (cin >> N >> M) {
    for (int(i) = (0); (i) < (int)(M); ++(i)) cin >> A[i] >> B[i] >> C[i];
    init();
    solve();
  }
}
