#include <bits/stdc++.h>
using namespace std;
namespace my_useful_tools {
const int INF = 0x3f3f3f3f;
inline void pc(char c) { putchar(c); }
template <class T>
inline T gcd(T a, T b) {
  return b == 0 ? a : gcd(b, a % b);
}
template <class T>
inline void W(T p) {
  if (p < 0) pc('-'), p = -p;
  if (p / 10 != 0) W(p / 10);
  pc('0' + p % 10);
}
template <class T>
inline void Wn(T p) {
  W(p), puts("");
}
template <class T>
inline void W(T a, T b) {
  W(a), pc(' '), W(b);
}
template <class T>
inline void Wn(T a, T b) {
  W(a), pc(' '), Wn(b);
}
template <class T>
inline void W(T a, T b, T c) {
  W(a), pc(' '), W(b), pc(' '), W(c);
}
inline char gchar() {
  char ret = getchar();
  for (; ret == '\n' || ret == '\r' || ret == ' '; ret = getchar())
    ;
  return ret;
}
template <class T>
inline void fr(T& ret) {
  char c = ' ';
  int flag = 1;
  for (c = getchar(); c != '-' && !('0' <= c && c <= '9'); c = getchar())
    ;
  if (c == '-')
    flag = -1, ret = 0;
  else
    ret = c - '0';
  for (c = getchar(); '0' <= c && c <= '9'; c = getchar())
    ret = ret * 10 + c - '0';
  ret = ret * flag;
}
inline int fr() {
  int x;
  fr(x);
  return x;
}
template <class T>
inline void fr(T& a, T& b) {
  fr(a), fr(b);
}
template <class T>
inline void fr(T& a, T& b, T& c) {
  fr(a), fr(b), fr(c);
}
template <class T>
inline T fast_pow(T base, T index, T mod = 2147483647, T ret = 1) {
  for (; index; index >>= 1, base = base * base % mod)
    if (index & 1) ret = ret * base % mod;
  return ret;
}
const int maxv = 100, maxe = 100;
struct Edge {
  int edge, head[maxv], to[maxe], next[maxe];
  Edge() {
    edge = 0;
    memset(head, -1, sizeof head);
  }
  void addedge(int u, int v) {
    to[edge] = v, next[edge] = head[u];
    head[u] = edge++;
  }
};
};  // namespace my_useful_tools
using namespace my_useful_tools;
const int maxn = 500 + 10;
class PresidentPath {
  int n, m, g[maxn][maxn], dis[maxn][maxn], path[maxn];
  int ans[maxn][maxn];

 public:
  void solve() {
    fr(n, m);
    memset(g, INF, sizeof g);
    memset(dis, INF, sizeof dis);
    memset(ans, 0, sizeof ans);
    for (int i = 1; i <= m; ++i) {
      int u, v, w;
      fr(u, v, w);
      dis[u][v] = dis[v][u] = g[u][v] = g[v][u] = min(dis[u][v], w);
    }
    for (int k = 1; k <= n; ++k)
      for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
    for (int i = 1; i <= n; ++i) g[i][i] = 0;
    for (int k = 1; k <= n; ++k) {
      memset(path, 0, sizeof path);
      for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j) {
          if (i != j && dis[i][j] + g[k][i] == g[k][j]) {
            ++path[j];
          }
        }
      for (int j = 1; j <= n; ++j)
        for (int i = 1; i <= n; ++i) {
          if (g[k][j] + g[j][i] == g[k][i]) {
            ans[k][i] += path[j];
          }
        }
    }
    for (int i = 1; i < n; ++i) {
      for (int j = i + 1; j <= n; ++j) {
        if (g[i][j] == INF) {
          printf("0 ");
        } else {
          printf("%d ", ans[i][j]);
        }
      }
    }
    puts("");
  }
} solver;
int main() {
  solver.solve();
  return 0;
}
