[JavaScript] SPFA (Bellman-Ford) | O(M*N*H) time complexity
ApproachWe use Bellman-Ford algorithm variation (SPFA): check if the next cell we visit can be visited with better health than currently stored. If it can, use
# Approach
We use Bellman-Ford algorithm variation (SPFA): check if the next cell we visit can be visited with better health than currently stored. If it can, use this health to move further from this cell.

# Complexity
- Time complexity: **O(M * N * H)** - we visit every cell up to H (health) times.

- Space complexity: **O(M * N)** - we store *highestHealthToVisitCells* of size of M * N. Queue can contain up to M * N cells, too.

# Code
```javascript []
/**
 * @param {number[][]} grid
 * @param {number} health
 * @return {boolean}
 */
var findSafeWalk = function (grid, health) {
    const DIRECTIONS = [
        [1, 0], // up
        [-1, 0], // down
        [0, 1], // right
        [0, -1], // left
    ];

    const rowsNumber = grid.length;
    const columnsNumber = grid[0].length;

    let queue = [];
    queue.push([0, 0]);

    const highestHealthToVisitCells = Array.from({ length: rowsNumber }, () => 
        Array.from({ length: columnsNumber }, () => 0)
    );

    highestHealthToVisitCells[0][0] = health - grid[0][0];

    while (queue.length > 0) {
        const nextQueue = [];

        for (const [row, column] of queue) {
            if (row === rowsNumber - 1 && column === columnsNumber - 1) {
                return true;
            }

            for (const [rowDifference, columnDifference] of DIRECTIONS) {
                const [nextRow, nextColumn] = [row + rowDifference, column + columnDifference];

                if (!isWithinGridBounds(nextRow, nextColumn, rowsNumber, columnsNumber)) {
                    continue;
                }

                const nextCellHealth = highestHealthToVisitCells[row][column] - grid[nextRow][nextColumn];

                if (nextCellHealth > highestHealthToVisitCells[nextRow][nextColumn]) {
                    highestHealthToVisitCells[nextRow][nextColumn] = nextCellHealth;
                    nextQueue.push([nextRow, nextColumn]);
                }
            }
        }

        queue = nextQueue;
    }

    return false;
};

function isWithinGridBounds(row, column, totalRows, totalColumns) {
    return row >= 0 && row < totalRows && column >= 0 && column < totalColumns;
}

```
['Breadth-First Search', 'Graph', 'Shortest Path', 'JavaScript']