Simple C# Solution (BFS + Sort)
\n    public class Solution\n    {\n        private static readonly (int di, int dj)[] _directions = { (0, 1), (0, -1), (1, 0), (-1, 0) };\n\n        private vo
```\n    public class Solution\n    {\n        private static readonly (int di, int dj)[] _directions = { (0, 1), (0, -1), (1, 0), (-1, 0) };\n\n        private void Helper((int i, int j) cellFrom, (int i, int j) cellTo, IList<IList<int>> forest, out int dist)\n        {\n            int n = forest.Count;\n            int m = forest[0].Count;\n            ISet<(int i, int j)> visited = new HashSet<(int i, int j)>();\n            Queue<(int i, int j)> bfs = new Queue<(int i, int j)>();\n            bfs.Enqueue(cellFrom);\n            visited.Add(cellFrom);\n\n            dist = 0;\n\n            while (bfs.Count > 0)\n            {\n                int count = bfs.Count;\n                for (int i = 0; i < count; i++)\n                {\n                    var node = bfs.Dequeue();\n\n                    if (node.i == cellTo.i && node.j == cellTo.j)\n                    {\n                        return;\n                    }\n\n                    foreach (var dir in _directions)\n                    {\n                        int newI = node.i + dir.di;\n                        int newJ = node.j + dir.dj;\n\n                        if (newI >= 0 && newI < n && newJ >= 0 && newJ < m && forest[newI][newJ] != 0)\n                        {\n                            if(visited.Add((newI, newJ)))\n                            {\n                                bfs.Enqueue((newI, newJ));\n                            }\n                        }\n                    }\n                }\n\n                dist++;\n            }\n\n            dist = -1;\n        }\n\n        public int CutOffTree(IList<IList<int>> forest)\n        {\n            int n = forest.Count;\n            if (n == 0)\n            {\n                return 0;\n            }\n\n            int m = forest[0].Count;\n\n\n            List<(int i, int j, int h)> trees = new List<(int i, int j, int h)>();\n            for (int i = 0; i < n; i++)\n            {\n                for (int j = 0; j < m; j++)\n                {\n                    if(forest[i][j] != 0)\n                    {\n                        trees.Add((i,j,forest[i][j]));\n                    }\n                }\n            }\n\n            trees.Sort((d1, d2) => d1.h.CompareTo(d2.h));\n            int res = 0;\n            (int i, int j) currCell = (0, 0);\n\n            for (int i = 0; i < trees.Count; i++)\n            {\n                Helper(currCell, (trees[i].i, trees[i].j), forest, out int dst);\n                if (dst == -1)\n                {\n                    return -1;\n                }\n\n                res += dst;\n                currCell = (trees[i].i, trees[i].j);\n            }\n\n            return res;\n        }\n    }\n```
['Breadth-First Search']