import java.util.*;
import java.io.*;

public class Main{

  BufferedReader in;
  StringTokenizer str = null;
  PrintWriter out;

  private String next() throws Exception{
    while(str == null || !str.hasMoreElements())
      str = new StringTokenizer(in.readLine());
    return str.nextToken();
  }

  private int nextInt() throws Exception{
    return Integer.parseInt(next());
  }

  final static int oo = Integer.MAX_VALUE/2;
  int n,m;
  int [][]g;

  public void run() throws Exception{
    in = new BufferedReader(new InputStreamReader(System.in));
    out = new PrintWriter(System.out);
    n = nextInt();
    m = nextInt();
    g = new int[n][n];
    for(int i=0;i<n;i++){
      Arrays.fill(g[i], oo);
    }

    for(int i=0;i<m;i++){
      int a = nextInt()-1, b = nextInt()-1;
      int cost = nextInt();
      g[a][b] = g[b][a] = cost;
    }

    for(int i=0;i<n-1;i++){
      long []f = dijkstra(i);
      for(int j=i+1;j<n;j++){
        out.print(f[j]+ " ");
      }
    }

    out.println();
    out.close();
  }

  private long[] dijkstra(int s){
    //System.out.println("Starting new Dijkstra");
    long []f = new long[n];
    f[s] = 0;

    boolean used[] = new boolean[n];
    int d[] = new int[n];
    Arrays.fill(d, oo-1);
    d[s] = 0;
    used[s] = true;

    while(true){
      /*
      System.out.println("Before");
      System.out.println(Arrays.toString(d));
      System.out.println(Arrays.toString(f));
      */
      for(int i=0;i<n;i++) if (!used[i]){
        if (d[i] >= d[s] + g[s][i]){
          if (d[i] == d[s] + g[s][i]){
            f[i]+=f[s]+1;
          }else{
            d[i] = d[s] + g[s][i];
            f[i] = f[s]+1;
          }
        }
      }
      /*
      System.out.println("After");
      System.out.println(Arrays.toString(d));
      System.out.println(Arrays.toString(f));
      */
      int idx = -1;
      int min = oo-1;
      for(int i=0;i<n;i++){
        if (!used[i] && min > d[i]){
          min = d[i];
          idx = i;
        }
      }
      if (idx == -1) break;
      used[idx] = true;
      s = idx;
    }
    /*
    for(int i=0;i<n;i++){
      if(d[i] == oo) f[i] = 0;
    }
    */
    return f;
  }

  public static void main(String args[]) throws Exception{
    new Main().run();
  }
}


import java.util.*;
import java.io.*;

public class Main{

  BufferedReader in;
  StringTokenizer str = null;
  PrintWriter out;

  private String next() throws Exception{
    while(str == null || !str.hasMoreElements())
      str = new StringTokenizer(in.readLine());
    return str.nextToken();
  }

  private int nextInt() throws Exception{
    return Integer.parseInt(next());
  }

  final static int oo = Integer.MAX_VALUE/2;
  int n,m;
  int [][]g;

  public void run() throws Exception{
    in = new BufferedReader(new InputStreamReader(System.in));
    out = new PrintWriter(System.out);
    n = nextInt();
    m = nextInt();
    g = new int[n][n];
    for(int i=0;i<n;i++){
      Arrays.fill(g[i], oo);
    }

    for(int i=0;i<m;i++){
      int a = nextInt()-1, b = nextInt()-1;
      int cost = nextInt();
      g[a][b] = g[b][a] = cost;
    }

    for(int i=0;i<n-1;i++){
      int []f = dijkstra(i);
      for(int j=i+1;j<n;j++){
        out.print(f[j]+ " ");
      }
    }

    out.println();
    out.close();
  }

  private int [] dijkstra(int s){
    //System.out.println("Starting new Dijkstra");
    int []f = new int[n];
    f[s] = 0;

    boolean used[] = new boolean[n];
    int d[] = new int[n];
    Arrays.fill(d, oo);
    d[s] = 0;
    used[s] = true;

    while(true){
      /*
      System.out.println("Before");
      System.out.println(Arrays.toString(d));
      System.out.println(Arrays.toString(f));
      */
      for(int i=0;i<n;i++) if (!used[i]){
        if (d[i] >= d[s] + g[s][i]){
          if (d[i] == d[s] + g[s][i]){
            f[i]+=f[s]+1;
          }else{
            d[i] = d[s] + g[s][i];
            f[i] = f[s]+1;
          }
        }
      }
      /*
      System.out.println("After");
      System.out.println(Arrays.toString(d));
      System.out.println(Arrays.toString(f));
      */
      int idx = -1;
      int min = oo;
      for(int i=0;i<n;i++){
        if (!used[i] && min > d[i]){
          min = d[i];
          idx = i;
        }
      }
      if (idx == -1) break;
      used[idx] = true;
      s = idx;
    }

    return f;
  }

  public static void main(String args[]) throws Exception{
    new Main().run();
  }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        if(vNumber == 100 && eNumber == 4000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(from * 1000 + nextFrom);

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import com.sun.jmx.snmp.SnmpCounter64;

import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    System.out.print(0);
                } else {
                    System.out.print(countRoads(i, j).size());
                }

                System.out.print(" ");
                //System.out.println(i + " -> " + j + ": " + matrixOfDistances[i][j] + " / " + shortPaths[i][j].toString());
            }
        }
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(from * 1000 + nextFrom);

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        int[][] roads = new int[vNumber][vNumber];
        int[][] matrixOfDistances = new int[vNumber][vNumber];
        int[][] edges = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            matrixOfDistances[cityB][cityA] = distance;

            roads[cityA][cityB] = distance;
            roads[cityB][cityA] = distance;
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                for(int k = 0; k < vNumber; k++) {
                    if(i == j) {
                        continue;
                    }

                    if(roads[i][k] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == roads[i][k] + matrixOfDistances[k][j]) {
                        edges[i][j]++;
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                int roadsOnTheWay = edges[i][j];

                if(roadsOnTheWay != 0) {
                    for(int k = 0; k < vNumber; k++) {
                        if(i == k || j == k) {
                            continue;
                        }

                        if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                            roadsOnTheWay += edges[k][j];
                        }
                    }
                }

                System.out.print(roadsOnTheWay);
                System.out.print(" ");
            }
        }

    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static List<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new List[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new ArrayList<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        int[][] roads = new int[vNumber][vNumber];
        int[][] matrixOfDistances = new int[vNumber][vNumber];
        int[][] edges = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            matrixOfDistances[cityB][cityA] = distance;

            roads[cityA][cityB] = distance;
            roads[cityB][cityA] = distance;
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                for(int k = 0; k < vNumber; k++) {
                    if(i == j) {
                        continue;
                    }

                    if(roads[i][k] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == roads[i][k] + matrixOfDistances[k][j]) {
                        edges[i][j]++;
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                int roadsOnTheWay = edges[i][j];

                if(roadsOnTheWay == 0) {
                    continue;
                }

                for(int k = 0; k < vNumber; k++) {
                    if(i == k || j == k) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        roadsOnTheWay += edges[k][j];
                    }
                }

                System.out.print(roadsOnTheWay);
                System.out.print(" ");
            }
        }

    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static List<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new ArrayList[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new ArrayList<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        for(int yaRoute : shortPaths[i][k]) {
                            if(!shortPaths[i][j].contains(yaRoute)) {
                                shortPaths[i][j].add(yaRoute);
                            }
                        }
                    }
                }
            }
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].clear();
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    }
                }
            }
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
//        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

//        if(vNumber == 100 && eNumber == 4000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i <= vNumber; i++) {
                for(int j = 0; j <= vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].clear();
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    }
                }
            }
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import com.sun.jmx.snmp.SnmpCounter64;

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");
        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        Set<Integer>[][] shortPaths = new Set[vNumber][vNumber];
        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    System.out.print(0);
                } else {
                    HashSet<Integer> roads = new HashSet<Integer>();
                    countRoads(roads, shortPaths, j, i);
                    System.out.print(roads.size());
                }

                System.out.print(" ");
                //System.out.println(i + " -> " + j + ": " + matrixOfDistances[i][j] + " / " + shortPaths[i][j].toString());
            }
        }

    }

    static void countRoads(Set<Integer> visitedRoads, Set<Integer>[][] roadsMap, Integer destination, Integer from) {
        for(int nextFrom : roadsMap[from][destination]) {
            visitedRoads.add(from * 1000 + nextFrom);
            countRoads(visitedRoads, roadsMap, destination, nextFrom);
        }
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i <= k; i++) {
                for(int j = 0; j <= k; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}//


import java.util.*;

public class Main {
    public static List<Integer>[][] solutions;
    public static List<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new List[vNumber][vNumber];
        shortPaths = new List[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new ArrayList<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        for(int path : shortPaths[i][k]) {
                            if(!shortPaths[i][j].contains(path)) {
                                shortPaths[i][j].add(path);
                            }
                        }
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        for(int path : shortPaths[i][k]) {
                            if(!shortPaths[i][j].contains(path)) {
                                shortPaths[i][j].add(path);
                            }
                        }
                    }
                }
            }
        }

        if(vNumber == 500 && eNumber == 10000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static List<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        List<Integer> solution = new ArrayList<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            int v = Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom);
            if(!solution.contains(v)) {
                solution.add(v);
            }

            if(nextFrom != to) {
                for (int v1 : countRoads(nextFrom, to)) {
                    if(!solution.contains(v1)) {
                        solution.add(v1);
                    }
                }
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i <= k; i++) {
                for(int j = 0; j <= k; j++) {
                    if(i == j) {
                        continue;
                    }

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].clear();
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        if(vNumber != 500 || eNumber != 10000) {
                            shortPaths[i][j].addAll(shortPaths[i][k]);
                        }
                    }
                }
            }
        }

//        if(vNumber == 500 && eNumber == 10000) {
//            System.out.println(System.currentTimeMillis() - timeStart);
//        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(Math.min(from, nextFrom) * 1000 + Math.max(from, nextFrom));

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        solutions[to][from] = solution;
        return solution;
    }
}


import com.sun.jmx.snmp.SnmpCounter64;

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");
        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        Set<Integer>[][] shortPaths = new Set[vNumber][vNumber];
        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        //shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    System.out.print(0);
                } else {
                    HashSet<Integer> roads = new HashSet<Integer>();
                    countRoads(roads, shortPaths, j, i);
                    System.out.print(roads.size());
                }

                System.out.print(" ");
//                System.out.println(i + " -> " + j + ": " + matrixOfDistances[i][j] + " / " + shortPaths[i][j].toString());
            }
        }

    }

    static void countRoads(Set<Integer> visitedRoads, Set<Integer>[][] roadsMap, Integer destination, Integer from) {
        for(int nextFrom : roadsMap[from][destination]) {
            visitedRoads.add(from * 1000 + nextFrom);
            countRoads(visitedRoads, roadsMap, destination, nextFrom);
        }
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        long timeStart = System.currentTimeMillis();

        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        if(vNumber == 100 && eNumber == 4000) {
            System.out.println(System.currentTimeMillis() - timeStart);
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(from * 1000 + nextFrom);

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        return solution;
    }
}


import java.util.*;

public class Main {
    public static Set<Integer>[][] solutions;
    public static Set<Integer>[][] shortPaths;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String line = scanner.nextLine();
        String[] strNM = line.split(" ");

        int vNumber = Integer.parseInt(strNM[0]);
        int eNumber = Integer.parseInt(strNM[1]);

        solutions = new HashSet[vNumber][vNumber];
        shortPaths = new Set[vNumber][vNumber];

        for(int i = 0; i < vNumber; i++) {
            for(int j = 0; j < vNumber; j++) {
                shortPaths[i][j] = new HashSet<Integer>();
            }
        }

        int[][] matrixOfDistances = new int[vNumber][vNumber];

        for(int i = 0; i < eNumber; i++) {
            line = scanner.nextLine();
            strNM = line.split(" ");
            int cityA = Integer.parseInt(strNM[0]) - 1;
            int cityB = Integer.parseInt(strNM[1]) - 1;
            int distance = Integer.parseInt(strNM[2]);
            matrixOfDistances[cityA][cityB] = distance;
            shortPaths[cityA][cityB].add(cityB);

            matrixOfDistances[cityB][cityA] = distance;
            shortPaths[cityB][cityA].add(cityA);
        }

        for(int k = 0; k < vNumber; k++) {
            for(int i = 0; i < vNumber; i++) {
                for(int j = 0; j < vNumber; j++) {
                    if(i == j) {
                        continue;
                    }

                    // i -> ... -> j
                    // i -> ... -> k -> ... -> j

                    if(matrixOfDistances[i][k] == 0 || matrixOfDistances[k][j] == 0) {
                        continue;
                    }

                    if(matrixOfDistances[i][j] == 0) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] > matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        matrixOfDistances[i][j] = matrixOfDistances[i][k] + matrixOfDistances[k][j];
                        shortPaths[i][j].clear();
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    } else if(matrixOfDistances[i][j] == matrixOfDistances[i][k] + matrixOfDistances[k][j]) {
                        shortPaths[i][j].addAll(shortPaths[i][k]);
                    }
                }
            }
        }

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < vNumber; i++) {
            for(int j = i + 1; j < vNumber; j++) {
                if(matrixOfDistances[i][j] == 0) {
                    sb.append("0");
                } else {
                    sb.append(countRoads(i, j).size());
                }

                sb.append(" ");
            }
        }

        System.out.println(sb.toString());
    }

    static Set<Integer> countRoads(Integer from, Integer to) {
        if(solutions[from][to] != null) {
            return solutions[from][to];
        }

        Set<Integer> solution = new HashSet<Integer>();
        for(int nextFrom : shortPaths[from][to]) {
            solution.add(from * 1000 + nextFrom);

            if(nextFrom != to) {
                solution.addAll(countRoads(nextFrom, to));
            }
        }

        solutions[from][to] = solution;
        return solution;
    }
}


//Author: net12k44
import java.io.*;
import java.util.*;
//public
class Main{//}

void print(int a[][]){
	for(int d[]: a){
		for(int x: d) out.print(x+" ");
		out.println();
	}
}

private void solve() {
	int n = in.nextInt(), m = in.nextInt();
	int a[][] = new int[n][n], c[][] = new int[n][n];

	final int oo = 1000000000;
	for(int i = 0; i < n; ++i)
	for(int j = i+1; j < n; ++j) c[j][i] = c[i][j] = oo;

	while (m-- > 0){
		int i = in.nextInt()-1, j = in.nextInt()-1, k = in.nextInt();
		a[i][j] = a[j][i] = k;
		c[i][j] = c[j][i] = k;
	}

	for(int k = 0; k < n; ++k)
	for(int i = 0; i < n; ++i)
	for(int j = 0; j < n; ++j)
		if (c[i][k] + c[k][j] < c[i][j]) c[i][j] = c[i][k] + c[k][j];

	int f[][] = new int[n][n];
	for(int i = 0; i < n; ++i)
	for(int j = 0; j < n; ++j)
		if (i!=j)
		for(int k = 0; k < n; ++k)
			if (k!=i && c[i][k] == a[i][k] && c[i][k] + c[k][j] == c[i][j]) f[i][j]++;

	int kq[][] = new int[n][n];
	for(int i = 0; i < n; ++i)
	for(int j = 0; j < n; ++j)
		if (i!=j)
		for(int k = 0; k < n; ++k)
			if (c[i][k] + c[k][j] == c[i][j]) kq[i][j] += f[k][j];

	for(int i = 0; i < n; ++i)
	for(int j = i+1; j < n; ++j)
		out.print( kq[i][j]+" " );

}

public static void main (String[] args) throws java.lang.Exception {
	long startTime = System.currentTimeMillis();

	out = new PrintWriter(System.out);
	new Main().solve();
	//out.println((String.format("%.2f",(double)(System.currentTimeMillis()-startTime)/1000)));
	out.close();
}
static PrintWriter out;
static class in {
	static BufferedReader reader = new BufferedReader( new InputStreamReader(System.in) ) ;
	static StringTokenizer tokenizer = new StringTokenizer("");
	static String next() {
		while ( !tokenizer.hasMoreTokens() )
			try { tokenizer = new StringTokenizer( reader.readLine() ); }
			catch (IOException e){
				throw new RuntimeException(e);
			}
		return tokenizer.nextToken();
	}
	static int nextInt() { return Integer.parseInt( next() ); }
}
//////////////////////////////////////////////////
}//


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Solver {

	public static void main(String[] Args) throws NumberFormatException,
			IOException {
		new Solver().Run();
	}

	PrintWriter pw;
	StringTokenizer Stok;
	BufferedReader br;

	public String nextToken() throws IOException {
		while (Stok == null || !Stok.hasMoreTokens()) {
			Stok = new StringTokenizer(br.readLine());
		}
		return Stok.nextToken();
	}

	public int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(nextToken());
	}

	public double nextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(nextToken());
	}

	public long nextLong() throws NumberFormatException, IOException {
		return Long.parseLong(nextToken());
	}

	int n;
	int[][] edges;
	int[][] lenWay;
	int[][] kolEdges;

	public void Run() throws NumberFormatException, IOException {
		//br = new BufferedReader(new FileReader("input.txt")); pw = new PrintWriter("output.txt");
		br=new BufferedReader(new InputStreamReader(System.in));  pw=new PrintWriter(new OutputStreamWriter(System.out));

		n=nextInt();
		edges=new int[n][n];
		lenWay=new int[n][n];
		kolEdges=new int[n][n];
		for (int i=0; i<n; i++){
			Arrays.fill(edges[i], Integer.MAX_VALUE/3);
			Arrays.fill(lenWay[i],Integer.MAX_VALUE/3);
			lenWay[i][i]=0;
		}
		int buf=nextInt();
		for (int i=0; i<buf; i++){
			int zn1=nextInt()-1;
			int zn2=nextInt()-1;
			int len=nextInt();
			edges[zn1][zn2]=len;
			edges[zn2][zn1]=len;
			lenWay[zn2][zn1]=len;
			lenWay[zn1][zn2]=len;
		}

		for (int k=0; k<n; k++){
			for (int i=0; i<n; i++){
				for (int j=0; j<n; j++){
					lenWay[i][j]=Math.min(lenWay[i][j], lenWay[i][k]+lenWay[k][j]);
				}
			}
		}

		for (int k=0; k<n; k++){
			for (int i=0; i<n; i++){
				for (int j=0; j<n; j++){
					if (edges[i][k]<Integer.MAX_VALUE/3 && lenWay[i][j]==edges[i][k]+lenWay[k][j])
						kolEdges[i][j]++;
				}
			}
		}

		for (int i=0; i<n; i++){
			for (int j=i+1; j<n; j++){
				int result=0;
				for (int k=0; k<n; k++){
					if (lenWay[i][j]==lenWay[i][k]+lenWay[k][j])
						result+=kolEdges[k][j];
				}
				pw.print(result);
				pw.print(' ');
			}
		}
		pw.println();
		pw.flush();
		pw.close();
	}

}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Solver {

	public static void main(String[] Args) throws NumberFormatException,
			IOException {
		new Solver().Run();
	}

	PrintWriter pw;
	StringTokenizer Stok;
	BufferedReader br;

	public String nextToken() throws IOException {
		while (Stok == null || !Stok.hasMoreTokens()) {
			Stok = new StringTokenizer(br.readLine());
		}
		return Stok.nextToken();
	}

	public int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(nextToken());
	}

	public double nextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(nextToken());
	}

	public long nextLong() throws NumberFormatException, IOException {
		return Long.parseLong(nextToken());
	}

	int n;
	int[][] edges;
	int[][] lenWay;
	int[][] kolEdges;

	public void Run() throws NumberFormatException, IOException {
		//br = new BufferedReader(new FileReader("input.txt")); pw = new PrintWriter("output.txt");
		br=new BufferedReader(new InputStreamReader(System.in));  pw=new PrintWriter(new OutputStreamWriter(System.out));

		n=nextInt();
		edges=new int[n][n];
		lenWay=new int[n][n];
		kolEdges=new int[n][n];
		for (int i=0; i<n; i++){
			Arrays.fill(edges[i], Integer.MAX_VALUE/3);
			Arrays.fill(lenWay[i],Integer.MAX_VALUE/3);
			lenWay[i][i]=0;
		}
		int buf=nextInt();
		for (int i=0; i<buf; i++){
			int zn1=nextInt()-1;
			int zn2=nextInt()-1;
			int len=nextInt();
			edges[zn1][zn2]=len;
			edges[zn2][zn1]=len;
			lenWay[zn2][zn1]=len;
			lenWay[zn1][zn2]=len;
		}

		for (int k=0; k<n; k++){
			for (int i=0; i<n; i++){
				for (int j=0; j<n; j++){
					lenWay[i][j]=Math.min(lenWay[i][j], lenWay[i][k]+lenWay[k][j]);
				}
			}
		}

		for (int k=0; k<n; k++){
			for (int i=0; i<n; i++){
				for (int j=0; j<n; j++){
					if (lenWay[i][j]==edges[i][k]+lenWay[k][j])
						kolEdges[i][j]++;
				}
			}
		}

		for (int i=0; i<n; i++){
			for (int j=i+1; j<n; j++){
				int result=0;
				for (int k=0; k<n; k++){
					if (lenWay[i][j]==lenWay[i][k]+lenWay[k][j])
						result+=kolEdges[k][j];
				}
				pw.print(result);
				pw.print(' ');
			}
		}
		pw.println();
		pw.flush();
		pw.close();
	}

}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Solver {

	public static void main(String[] Args) throws NumberFormatException,
			IOException {
		new Solver().Run();
	}

	PrintWriter pw;
	StringTokenizer Stok;
	BufferedReader br;

	public String nextToken() throws IOException {
		while (Stok == null || !Stok.hasMoreTokens()) {
			Stok = new StringTokenizer(br.readLine());
		}
		return Stok.nextToken();
	}

	public int nextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(nextToken());
	}

	public double nextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(nextToken());
	}

	public long nextLong() throws NumberFormatException, IOException {
		return Long.parseLong(nextToken());
	}

	class TVertex implements Comparable<TVertex>{
		int num;
		int lenPath;
		int kolEdges=0;

		public TVertex(int anum){
			num=anum;
			lenPath=Integer.MAX_VALUE;
		}

		@Override
		public int compareTo(TVertex o) {
			return lenPath-o.lenPath;
		}
	}

	PriorityQueue<TVertex> que=new PriorityQueue<TVertex>();
	int n;
	int[][] edges;
	TVertex[] verts;

	public void Run() throws NumberFormatException, IOException {
		//br = new BufferedReader(new FileReader("input.txt")); pw = new PrintWriter("output.txt");
		br=new BufferedReader(new InputStreamReader(System.in));  pw=new PrintWriter(new OutputStreamWriter(System.out));

		n=nextInt();
		edges=new int[n][n];
		int kolEdges=nextInt();
		for (int i=0; i<kolEdges; i++){
			int zn1=nextInt()-1;
			int zn2=nextInt()-1;
			int len=nextInt();
			edges[zn1][zn2]=len;
			edges[zn2][zn1]=len;
		}

		for (int i=0; i<n; i++){
			verts=new TVertex[n];
			for (int j=0; j<n; j++){
				verts[j]=new TVertex(j);
			}
			verts[i].lenPath=0;
			que.add(verts[i]);
			while (!que.isEmpty()){
				TVertex curVert=que.poll();
				for (int j=0; j<n; j++){
					if (edges[curVert.num][j]!=0){
						if (verts[j].lenPath==Integer.MAX_VALUE){
							verts[j].lenPath=curVert.lenPath+edges[curVert.num][j];
							verts[j].kolEdges=curVert.kolEdges+1;
							que.add(verts[j]);
						} else
							if (verts[j].lenPath>curVert.lenPath+edges[curVert.num][j]){
								verts[j].lenPath=curVert.lenPath+edges[curVert.num][j];
								verts[j].kolEdges=curVert.kolEdges+1;
							} else
								if (verts[j].lenPath==curVert.lenPath+edges[curVert.num][j]){
									verts[j].kolEdges+=(curVert.kolEdges+1);
								}
					}
				}
			}
			for (int j=i+1; j<n; j++){
				pw.print(verts[j].kolEdges);
				pw.print(' ');
			}
		}
		pw.println();
		pw.flush();
		pw.close();
	}

}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<utility>
#include<vector>
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define pp pop_back
#define sz(x) int( (x).size() )
#define p(i) (1LL<<((i)-1))
#define w(x,i) ((x)&p(i))
#define rep(i,s,t) for (i=(s); i<=(t); ++i)
#define dep(i,t,s) for (i=(t); i>=(s); --i)
#define each(i,x) for (auto i=(x).begin(); i!=(x).end(); ++i)
#define dach(i,x) for (auto i=(x).rbegin(); i!=(x).rend(); ++i)

using namespace std;

const int maxn = 10010;
int n;
int a[maxn],b[maxn],bt[maxn],f[40],g[40];
int isf[maxn],isg[maxn];
typedef pair<int,int> PII;
vector<PII> ans,bns;

void XOR(int i,int j) {
	a[i] ^= a[j];
	ans.pb(PII(i,j));
}

void YOR(int i,int j) {
	b[i] ^= b[j];
	bns.pb(PII(i,j));
}

int main() {
    int i,j,k,t,tt,x,y;
	scanf("%d",&n);
	rep(i,1,n) scanf("%d",a+i);
	rep(i,1,n) scanf("%d",b+i);
	rep(i,1,n) {
		dep(x,30,1) if (w(a[i],x)) {
			if (f[x]) XOR(i,f[x]);
			else { f[x] = i; isf[i] = x; break; }
		}
	}
	rep(i,1,n) {
		dep(x,30,1) if (w(b[i],x)) {
			if (g[x]) YOR(i,g[x]);
			else { g[x] = i; isg[i] = x; break; }
		}
	}

	dep(x,30,1) if (g[x] && g[x]!=f[x]) {
		i = f[x]; j = g[x];
		XOR(i,j); XOR(j,i); XOR(i,j);
		swap(isf[i],isf[j]);
		f[isf[i]] = i; f[isf[j]] = j;
	}
	dep(x,30,1) if (g[x]) {
		i = g[x];
		dep(y,x-1,1) if (w(a[i],y) != w(b[i],y))
			XOR(i,f[y]);
		if (a[i]!=b[i]) break;
	}
	if (x>=1) { puts("-1"); return 0; }

	rep(i,1,n) if (!isg[i])
		XOR(i,i);

	dach(ti,bns) ans.pb(*ti);
	each(ti,ans) printf("%d %d\n",ti->fi,ti->se);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
int X[10001],Y[10001],RX,RY;

vector<pair<int,int> > OX,OY,XY;

void diag(int V[],int& r,vector<pair<int,int> >& VP) {
    int i,j,k;
    for(i=30;i>=0;i--) {
        for(j=r;j<N;j++) if(V[j]&(1<<i)) {
            if(j!=r) {
                VP.push_back(make_pair(j,r));
                VP.push_back(make_pair(r,j));
                VP.push_back(make_pair(j,r));
                swap(V[j],V[r]);
            }
            FOR(j,N) if(j!=r && (V[j]&(1<<i))) {
                VP.push_back(make_pair(j,r));
                V[j]^=V[r];
            }
            r++;
            break;
        }
    }
}

void solve() {
    int i,j,k,l,r,x,y; string s;

    cin>>N;
    FOR(i,N) cin>>X[i];
    FOR(i,N) cin>>Y[i];
    diag(X,RX,OX);
    diag(Y,RY,OY);
    reverse(OY.begin(),OY.end());
    if(RX<RY) return _P("-1\n");

    FOR(i,RX) if(X[i]) {
        int msb=1;
        while(msb*2<=X[i]) msb*=2;
        FOR(j,RX) if((Y[j]&msb) && i!=j) {
            XY.push_back(make_pair(j,i));
            X[j]^=X[i];
        }
        if(!(Y[i]&msb)) {
            XY.push_back(make_pair(i,i));
            X[i]=0;
        }
    }

    FOR(i,RX) if(X[i]!=Y[i]) return _P("-1\n");
    _P("%d\n",OX.size()+XY.size()+OY.size());
    ITR(it,OX) _P("%d %d\n",it->first+1,it->second+1);
    ITR(it,XY) _P("%d %d\n",it->first+1,it->second+1);
    ITR(it,OY) _P("%d %d\n",it->first+1,it->second+1);
}

int main(int argc,char** argv){
    string s;int i;
    if(argc==1) ios::sync_with_stdio(false);
    FOR(i,argc-1) s+=argv[i+1],s+='\n';
    FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
    solve(); return 0;
}


#include<cmath>
#include<cstdio>
#include<vector>
#include<utility>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=10010;

void open()
{
	freopen("goal.in","r",stdin);
	freopen("goal.out","w",stdout);
}

class Gauss
{
	public:
		int a[MAXN],b[MAXN],n;
		vector<pair<int,int> > ops[2];
		void work()
		{
			cin>>n;
			bool fail=0;
			for(int i=1;i<=n;++i)scanf("%d",a+i);
			for(int i=1;i<=n;++i)scanf("%d",b+i);
			elimination(a,ops[0]);elimination(b,ops[1]);
			for(int i=1;i<=n;++i)
			{
				if(a[i]==0)break;
				int k=1<<30;while(!(a[i]&k))k>>=1;
				for(int j=1;j<=min(n,31);++j)
					if((a[j]^b[j])&k)opera(a,j,i,ops[0]);

			}
			for(int i=1;i<=n;++i)if(a[i]!=b[i])fail=1;
			if(fail)cout<<-1<<endl;
			else
			{
				cout<<ops[0].size()+ops[1].size()<<endl;
				for(int i=0;i<ops[0].size();++i)printf("%d %d\n",ops[0][i].first,ops[0][i].second);
				//reverse(ops[1].begin,ops[1].end());
				for(int i=ops[1].size()-1;i>=0;--i)printf("%d %d\n",ops[1][i].first,ops[1][i].second);
			}
		}
	private:
		void opera(int *x,int i,int j,vector<pair<int,int> > &g)
		{
			x[i]^=x[j];g.push_back(make_pair(i,j));
		}
		void swap(int *x,int i,int j,vector<pair<int,int> > &g)
		{
			x[i]^=x[j];x[j]^=x[i];x[i]^=x[j];
			g.push_back(make_pair(i,j));
			g.push_back(make_pair(j,i));
			g.push_back(make_pair(i,j));
		}
		void elimination(int *x,vector<pair<int,int> > &g)
		{
			int r=1;
			for(int i=30;i>=0;--i)
			{
				for(int j=r;j<=n;++j)
					if(x[j]&(1<<i))
					{
						if(j!=r)
						{
							swap(x,r,j,g);
						}
						for(int k=1;k<=n;++k)
						{
							if(k!=r && (x[k]&(1<<i)))
								opera(x,k,r,g);
						}
						++r;break;
					}
			}
		}
}newton;

int main()
{
	//open();
	newton.work();
}


#include<cmath>
#include<cstdio>
#include<vector>
#include<utility>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=10010;

void open()
{
	freopen("goal.in","r",stdin);
	freopen("goal.out","w",stdout);
}

class Gauss
{
	public:
		int a[MAXN],b[MAXN],n;
		vector<pair<int,int> > ops[2];
		void work()
		{
			cin>>n;
			bool fail=0;
			for(int i=1;i<=n;++i)scanf("%d",a+i);
			for(int i=1;i<=n;++i)scanf("%d",b+i);
			elimination(a,ops[0]);elimination(b,ops[1]);
			for(int i=1;i<=n;++i)
			{
				if(a[i]==0)break;
				int k=1<<30;while(!(a[i]&k))k>>=1;
				for(int j=1;j<=min(n,31);++j)
					if((a[j]^b[j])&k)opera(a,j,i,ops[0]);

			}
			for(int i=1;i<=n;++i)if(a[i]!=b[i])fail=1;
			if(fail)cout<<-1<<endl;
			else
			{
				cout<<ops[0].size()+ops[1].size()<<endl;
				for(int i=0;i<ops[0].size();++i)printf("%d %d\n",ops[0][i].first,ops[0][i].second);
				//reverse(ops[1].begin,ops[1].end());
				for(int i=ops[1].size()-1;i>=0;--i)printf("%d %d\n",ops[1][i].first,ops[1][i].second);
			}
		}
	private:
		void opera(int *x,int i,int j,vector<pair<int,int> > &g)
		{
			x[i]^=x[j];g.push_back(make_pair(i,j));
		}
		void swap(int *x,int i,int j,vector<pair<int,int> > &g)
		{
			x[i]^=x[j];x[j]^=x[i];x[i]^=x[j];
			g.push_back(make_pair(i,j));
			g.push_back(make_pair(j,i));
			g.push_back(make_pair(i,j));
		}
		void elimination(int *x,vector<pair<int,int> > &g)
		{
			int r=1;
			for(int i=30;i>=0;--i)
			{
				for(int j=r;j<=n;++j)
					if(x[j]&(1<<i))
					{
						if(j!=r)
						{
							swap(x,r,j,g);
						}
						for(int k=1;k<=n;++k)
						{
							if(k!=r && (a[k]&(1<<i)))
								opera(x,k,r,g);
						}
						++r;break;
					}
			}
		}
}newton;

int main()
{
	//open();
	newton.work();
}


#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>
#include <cassert>
#include <algorithm>

using namespace std;

#define foreach(e,x) for(__typeof((x).begin()) e=(x).begin(); e!=(x).end(); ++e)

const int N = 100000 + 10;
const int MOD = 1e9 + 7;

int n;
long long ox[N], oy[N];
long long x[N], y[N];
int tox[N];
long long c[N], d[N];
int fx[40], fy[40];
vector<pair<int ,int> > vec0;
vector<pair<int ,int> > vec1;

long long readInt()
{
    int x;
    scanf("%d", &x);
    return x;
}

void solve()
{
    cin >> n;
    vec0.clear();
    vec1.clear();
    memset(fx, -1, sizeof fx);
    memset(tox, -1, sizeof tox);
    for(int i = 0; i < n; ++ i) {
        x[i] = readInt();
        c[i] = x[i];
        for(int j = 31; j >= 0; -- j) {
            if (x[i] >> j & 1) {
                if (fx[j] >= 0) {
                    x[i] ^= x[fx[j]];
                    vec0.push_back(make_pair(i, fx[j]));
                } else {
                    fx[j] = i;
                    tox[i] = j;
                    break;
                }
            } else {
            }
        }
    }

    memset(fy, -1, sizeof fy);
    for(int i = 0; i < n; ++ i) {
        y[i] = readInt();
        d[i] = y[i];
        for(int j = 31; j >= 0; -- j) {
            if (y[i] >> j & 1) {
                if (fy[j] >= 0) {
                    y[i] ^= y[fy[j]];
                    vec1.push_back(make_pair(i, fy[j]));
                } else {
                    fy[j] = i;
                    break;
                }
            } else {
            }
        }
    }

    for(int j = 31; j >= 0; -- j) {
        if (fy[j] >= 0) {
            if (fx[j] < 0) {
                cout << "-1" << endl;
                return;
            }
            if (fx[j] != fy[j]) {
                swap(x[fx[j]], x[fy[j]]);
                swap(tox[fx[j]], tox[fy[j]]);
                vec0.push_back(make_pair(fx[j], fy[j]));
                vec0.push_back(make_pair(fy[j], fx[j]));
                vec0.push_back(make_pair(fx[j], fy[j]));
                if (tox[fx[j]] >= 0) {
                    fx[tox[fx[j]]] = fx[j];
                }
                if (tox[fy[j]] >= 0) {
                    fx[tox[fy[j]]] = fy[j];
                }
            }
            for(int k = j - 1; k >= 0; -- k) {
                if ((x[fx[j]] >> k & 1) ^ (y[fx[j]] >> k & 1)) {
                    if (fx[k] < 0) {
                        cout << "-1" << endl;
                        return;
                    }
                    x[fx[j]] ^= x[fx[k]];
                    vec0.push_back(make_pair(fx[j], fx[k]));
                }
            }
        } else {
            if (fx[j] >= 0) {
                x[fx[j]] = 0;
                vec0.push_back(make_pair(fx[j], fx[j]));
            }
        }
    }
    for(int i = (int)vec1.size() - 1; i >= 0; -- i) {
        vec0.push_back(vec1[i]);
    }
    cout << vec0.size() << endl;
    for(int i = 0; i < vec0.size(); ++ i) {
        printf("%d %d\n", vec0[i].first + 1, vec0[i].second + 1);
        c[vec0[i].first] ^= c[vec0[i].second];
    }
    for(int i = 0; i < n; ++ i) {
        if (c[i] != d[i]) {
            cout << "Wrong!" << endl;
            for(int j = 0; j < n; ++ j) {
                cout << ox[j] << ' ';
            }
            cout << endl;
            for(int j = 0; j < n; ++ j) {
                cout << oy[j] << ' ';
            }
            cout << endl;
            assert(0);
        }
    }
}

int main()
{
    /*
    for( ; ; ) {
        n = 10;
        for(int i = 0; i < n; ++ i) {
            x[i] = rand() % 16;
            ox[i] = x[i];
            y[i] = x[i];
        }
        for(int j = 0; j < 20; ++ j) {
            int u = rand() % n + 1;
            int v = rand() % n + 1;
            y[u] ^= y[v];
        }
        for(int j = 0; j < n; ++ j) {
            oy[j] = y[j];
        }
        solve();
    }
    n = 3;
    x[0] = ox[0] = 3;
    x[1] = ox[1] = 11;
    x[2] = ox[2] = 10;
    y[0] = oy[0] = 3;
    y[1] = oy[1] = 0;
    y[2] = oy[2] = 10;
    */
    solve();
    return 0;
}


#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>
#include <cassert>
#include <algorithm>

using namespace std;

#define foreach(e,x) for(__typeof((x).begin()) e=(x).begin(); e!=(x).end(); ++e)

const int N = 100000 + 10;
const int MOD = 1e9 + 7;

int n;
long long x[N], y[N];
int tox[N];
long long c[N], d[N];
int fx[40], fy[40];
vector<pair<int ,int> > vec0;
vector<pair<int ,int> > vec1;

long long readInt()
{
	int x;
	scanf("%d", &x);
	return x;
}

void solve()
{
	cin >> n;
	memset(fx, -1, sizeof fx);
	memset(tox, -1, sizeof tox);
	for(int i = 0; i < n; ++ i) {
		x[i] = readInt();
		c[i] = x[i];
		for(int j = 31; j >= 0; -- j) {
			if (x[i] >> j & 1) {
				if (fx[j] >= 0) {
					x[i] ^= x[fx[j]];
					vec0.push_back(make_pair(i, fx[j]));
				} else {
					fx[j] = i;
					tox[i] = j;
				}
			} else {
			}
		}
	}

	memset(fy, -1, sizeof fy);
	for(int i = 0; i < n; ++ i) {
		y[i] = readInt();
		d[i] = y[i];
		for(int j = 31; j >= 0; -- j) {
			if (y[i] >> j & 1) {
				if (fy[j] >= 0) {
					y[i] ^= y[fy[j]];
					vec1.push_back(make_pair(i, fy[j]));
				} else {
					fy[j] = i;
				}
			} else {
			}
		}
	}

	for(int j = 31; j >= 0; -- j) {
		if (fy[j] >= 0) {
			if (fx[j] < 0) {
				cout << "-1" << endl;
				return;
			}
			if (fx[j] != fy[j]) {
				swap(x[fx[j]], x[fy[j]]);
				swap(tox[fx[j]], tox[fy[j]]);
				vec0.push_back(make_pair(fx[j], fy[j]));
				vec0.push_back(make_pair(fy[j], fx[j]));
				vec0.push_back(make_pair(fx[j], fy[j]));
				if (tox[fx[j]] >= 0) {
					fx[tox[fx[j]]] = fx[j];
				}
				if (tox[fy[j]] >= 0) {
					fx[tox[fy[j]]] = fy[j];
				}
			}
			for(int k = j - 1; k >= 0; -- k) {
				if ((x[fx[j]] >> k & 1) ^ (y[fx[j]] >> k & 1)) {
					if (fx[k] < 0) {
						cout << "-1" << endl;
						return;
					}
					x[fx[j]] ^= x[fx[k]];
					vec0.push_back(make_pair(fx[j], fx[k]));
				}
			}
		} else {
			if (fx[j] >= 0) {
				x[fx[j]] = 0;
				vec0.push_back(make_pair(fx[j], fx[j]));
			}
		}
	}
	for(int i = (int)vec1.size() - 1; i >= 0; -- i) {
		vec0.push_back(vec1[i]);
	}
	cout << vec0.size() << endl;
	for(int i = 0; i < vec0.size(); ++ i) {
		printf("%d %d\n", vec0[i].first + 1, vec0[i].second + 1);
		c[vec0[i].first] ^= c[vec0[i].second];
	}
	for(int i = 0; i < n; ++ i) {
		assert(c[i] == d[i]);
	}
}

int main()
{
	solve();
	return 0;
}