C solution.
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity: O(m * n log(m * n))\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: O(m * n)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```c []\nstruct Node {\n    int time;\n    int row;\n    int col;\n};\n\nstruct MinHeap {\n    struct Node* array;\n    int size;\n    int capacity;\n};\n\n// Function to swap two nodes\nvoid swap(struct Node* a, struct Node* b) {\n    struct Node temp = *a;\n    *a = *b;\n    *b = temp;\n}\n\n// Function to create a MinHeap\nstruct MinHeap* createMinHeap(int capacity) {\n    struct MinHeap* minHeap = (struct MinHeap*)malloc(sizeof(struct MinHeap));\n    minHeap->size = 0;\n    minHeap->capacity = capacity;\n    minHeap->array = (struct Node*)malloc(capacity * sizeof(struct Node));\n    return minHeap;\n}\n\n// Function to resize the heap when it\'s full\nvoid resizeMinHeap(struct MinHeap* minHeap) {\n    minHeap->capacity *= 2;\n    minHeap->array = (struct Node*)realloc(minHeap->array, minHeap->capacity * sizeof(struct Node));\n}\n\n// Function to heapify up\nvoid heapifyUp(struct MinHeap* minHeap, int idx) {\n    int parent = (idx - 1) / 2;\n    if (idx > 0 && minHeap->array[parent].time > minHeap->array[idx].time) {\n        swap(&minHeap->array[parent], &minHeap->array[idx]);\n        heapifyUp(minHeap, parent);\n    }\n}\n\n// Function to insert a new node into MinHeap\nvoid insertMinHeap(struct MinHeap* minHeap, struct Node node) {\n    // Resize the heap if it\'s full\n    if (minHeap->size == minHeap->capacity) {\n        resizeMinHeap(minHeap);\n    }\n\n    minHeap->array[minHeap->size] = node;\n    heapifyUp(minHeap, minHeap->size);\n    minHeap->size++;\n}\n\n// Function to heapify down\nvoid heapifyDown(struct MinHeap* minHeap, int idx) {\n    int smallest = idx;\n    int left = 2 * idx + 1;\n    int right = 2 * idx + 2;\n\n    if (left < minHeap->size && minHeap->array[left].time < minHeap->array[smallest].time) {\n        smallest = left;\n    }\n    if (right < minHeap->size && minHeap->array[right].time < minHeap->array[smallest].time) {\n        smallest = right;\n    }\n\n    if (smallest != idx) {\n        swap(&minHeap->array[smallest], &minHeap->array[idx]);\n        heapifyDown(minHeap, smallest);\n    }\n}\n\n// Function to extract the minimum node from MinHeap\nstruct Node extractMin(struct MinHeap* minHeap) {\n    struct Node minNode = minHeap->array[0];\n    minHeap->array[0] = minHeap->array[minHeap->size - 1];\n    minHeap->size--;\n    heapifyDown(minHeap, 0);\n    return minNode;\n}\n\n// Checks if given cell coordinates are valid and unvisited\nbool isValid(int row, int col, int gridSize, int gridColSize) {\n    return row >= 0 && col >= 0 && row < gridSize && col < gridColSize;\n}\n\nint minimumTime(int** grid, int gridSize, int* gridColSize) {\n    // If both initial moves require more than 1 second, impossible to proceed\n    if (grid[0][1] > 1 && grid[1][0] > 1) {\n        return -1;\n    }\n\n    // Possible movements: down, up, right, left\n    int directions[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};\n    bool** visited = (bool**)malloc(gridSize * sizeof(bool*));\n    for (int i = 0; i < gridSize; i++) {\n        visited[i] = (bool*)malloc((*gridColSize) * sizeof(bool));\n        for (int j = 0; j < (*gridColSize); j++) {\n            visited[i][j] = false;\n        }\n    }\n\n    struct MinHeap* pq = createMinHeap(gridSize * (*gridColSize));\n    struct Node startNode = {0, 0, 0};\n    insertMinHeap(pq, startNode);\n    \n    int minTime = -1;\n    while (pq->size > 0) {\n        struct Node curr = extractMin(pq);\n        int time = curr.time, row = curr.row, col = curr.col;\n\n        // Check if reached the target\n        if (row == gridSize - 1 && col == (*gridColSize) - 1) {\n            minTime = time;\n            break;\n        }\n\n        // Skip if cell is already visited\n        if (visited[row][col]) {\n            continue;\n        }\n        visited[row][col] = true;\n\n        // Try all four directions\n        for (int i = 0; i < 4; i++) {\n            int nextRow = row + directions[i][0], nextCol = col + directions[i][1];\n            if (!isValid(nextRow, nextCol, gridSize, *gridColSize)) {\n                continue;\n            }\n\n            // Calculate the wait time needed to move to next cell\n            int nextTime = time + 1;\n            if (grid[nextRow][nextCol] > nextTime) {\n                // We have to wait for grid[nextRow][nextCol] to become reachable\n                int waitTime = (grid[nextRow][nextCol] - nextTime) % 2 == 0 ? 0 : 1;\n                nextTime = grid[nextRow][nextCol] + waitTime;\n            }\n\n            struct Node nextNode = {nextTime, nextRow, nextCol};\n            insertMinHeap(pq, nextNode);\n        }\n    }\n\n    free(pq->array);\n    free(pq);\n    for (int i = 0; i < gridSize; i++) {\n        free(visited[i]);\n    }\n    free(visited);\n    \n    return minTime;\n}\n```
['Array', 'Breadth-First Search', 'Graph', 'C', 'Heap (Priority Queue)', 'Matrix', 'Shortest Path']