Java solution, PriorityQueue + BFS
Since we have to cut trees in order of their height, we first put trees (int[] {row, col, height}) into a priority queue and sort by height.\n2. Poll each tree 
1. Since we have to cut trees in order of their height, we first put trees (int[] {row, col, height}) into a priority queue and sort by height.\n2. Poll each tree from the queue and use BFS to find out steps needed.\n\nThe worst case time complexity could be O(m^2 * n^2) (m = number of rows, n = number of columns) since there are m * n trees and for each BFS worst case time complexity is O(m * n) too.\n```\nclass Solution {\n    static int[][] dir = {{0,1}, {0, -1}, {1, 0}, {-1, 0}};\n\n    public int cutOffTree(List<List<Integer>> forest) {\n        if (forest == null || forest.size() == 0) return 0;\n        int m = forest.size(), n = forest.get(0).size();\n\n        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                if (forest.get(i).get(j) > 1) {\n                    pq.add(new int[] {i, j, forest.get(i).get(j)});\n                }\n            }\n        }\n\n        int[] start = new int[2];\n        int sum = 0;\n        while (!pq.isEmpty()) {\n            int[] tree = pq.poll();\n            int step = minStep(forest, start, tree, m, n);\n\n            if (step < 0) return -1;\n            sum += step;\n\n            start[0] = tree[0];\n            start[1] = tree[1];\n        }\n\n        return sum;\n    }\n\n    private int minStep(List<List<Integer>> forest, int[] start, int[] tree, int m, int n) {\n        int step = 0;\n        boolean[][] visited = new boolean[m][n];\n        Queue<int[]> queue = new LinkedList<>();\n        queue.add(start);\n        visited[start[0]][start[1]] = true;\n\n        while (!queue.isEmpty()) {\n            int size = queue.size();\n            for (int i = 0; i < size; i++) {\n                int[] curr = queue.poll();\n                if (curr[0] == tree[0] && curr[1] == tree[1]) return step;\n\n                for (int[] d : dir) {\n                    int nr = curr[0] + d[0];\n                    int nc = curr[1] + d[1];\n                    if (nr < 0 || nr >= m || nc < 0 || nc >= n \n                        || forest.get(nr).get(nc) == 0 || visited[nr][nc]) continue;\n                    queue.add(new int[] {nr, nc});\n                    visited[nr][nc] = true;\n                }\n            }\n            step++;\n        }\n\n        return -1;\n    }\n}\n```
[]