#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using Pii = pair<int, int>;
using Tiii = tuple<int, int, int>;
template <class T>
using V = vector<T>;
int N, M;
bool used[101][101];
class Node {
 public:
  int dist, number;
  Node(int d, int n) {
    dist = d;
    number = n;
  }
};
bool operator<(const Node &l, const Node &r) {
  return l.dist < r.dist || (!(r.dist < l.dist) && l.number < r.number);
};
bool operator>(const Node &l, const Node &r) { return r < l; };
class Edge {
 public:
  int to, cost;
  Edge(int t, int c) {
    to = t;
    cost = c;
  }
};
int node_n;
vector<vector<Edge>> edges;
vector<int> d;
void edge_initializer(int n) {
  edges = vector<vector<Edge>>(n, vector<Edge>());
}
void dijkstra(int start_p) {
  d = vector<int>(node_n, INT_MAX);
  d[start_p] = 0;
  vector<int> prev = vector<int>(node_n, -1);
  priority_queue<Node, vector<Node>, greater<Node>> Q;
  for (int i = 0; i < node_n; i++) {
    Q.push(Node(d[i], i));
  }
  while (!Q.empty()) {
    Node u = Q.top();
    Q.pop();
    if (u.dist > d[u.number]) continue;
    for (Edge edge : edges[u.number]) {
      int alt = d[u.number] + edge.cost;
      int v = edge.to;
      if (d[v] > alt) {
        d[v] = alt;
        prev[v] = u.number;
        Q.push(Node(d[v], v));
      }
    }
  }
  for (auto i = 0; i != node_n + 1; i++) {
    int cur = prev[i];
    if (cur == -1) continue;
    used[cur][i] = used[i][cur] = true;
    while (cur != start_p) {
      used[cur][prev[cur]] = used[prev[cur]][cur] = true;
      cur = prev[cur];
      if (cur == -1) break;
    }
  }
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N >> M;
  node_n = N + 1;
  edge_initializer(node_n);
  for (auto i = 0; i != M; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    edges[a].push_back(Edge(b, c));
    edges[b].push_back(Edge(a, c));
  }
  for (auto i = 1; i != N + 1; i++) dijkstra(i);
  int cnt = 0;
  for (auto i = edges.begin(); i != edges.end(); i++) {
    for (auto j = (*i).begin(); j != (*i).end(); j++) {
      int n = i - edges.begin();
      if (!used[n][(*j).to]) cnt++;
    }
  }
  cout << cnt / 2 << endl;
  return 0;
}
