[C++|Java|JavaScript|Python3] bottom-up dp 
IntuitionUse DP. Let's define dp[i][j][k] as the maximum coins collected at i, j with k ops remaining. Then,dp[i][j][k] = max(dp[i-1][j][k] + coins[i][j], dp[i]
# Intuition
Use DP. Let's define `dp[i][j][k]` as the maximum coins collected at `i, j` with `k` ops remaining. Then, 

`dp[i][j][k] = max(dp[i-1][j][k] + coins[i][j], dp[i][j-1][k] + coins[i][j], dp[i-1][j][k+1], dp[i][j-1][k+1])`

Assuming indices are all within reasonable range. 

# Approach
Run DP and check the maximum of `dp[m-1][n-1][0..2]`.

# Complexity
- Time complexity: `O(MN)`
- Space complexity: `O(MN)`

# Code
```C++ []
class Solution {
public:
    int maximumAmount(vector<vector<int>>& coins) {
        int m = coins.size(), n = coins[0].size(); 
        vector<vector<vector<int>>> dp(m, vector<vector<int>>(n, vector<int>(4, -1'000'000'000))); 
        dp[0][0][2] = coins[0][0]; 
        if (coins[0][0] < 0) dp[0][0][1] = 0; 
        for (int i = 0; i < m; ++i)
            for (int j = 0; j < n; ++j)
                for (int k = 0; k <= 2; ++k) {
                    if (i) dp[i][j][k] = max({dp[i][j][k], dp[i-1][j][k] + coins[i][j], dp[i-1][j][k+1]}); 
                    if (j) dp[i][j][k] = max({dp[i][j][k], dp[i][j-1][k] + coins[i][j], dp[i][j-1][k+1]}); 
                }
        return *max_element(dp[m-1][n-1].begin(), dp[m-1][n-1].end()); 
    }
};
```
```Java []
class Solution {
    public int maximumAmount(int[][] coins) {
        int m = coins.length, n = coins[0].length; 
        int[][][] dp = new int[m][n][4]; 
        for (int i = 0; i < m; ++i)
            for (int j = 0; j < n; ++j)
                Arrays.fill(dp[i][j], -1_000_000_000); 
        dp[0][0][2] = coins[0][0]; 
        if (coins[0][0] < 0) dp[0][0][1] = 0; 
        for (int i = 0; i < m; ++i) 
            for (int j = 0; j < n; ++j)
                for (int k = 0; k <= 2; ++k) {

                    if (i > 0) dp[i][j][k] = Math.max(dp[i][j][k], Math.max(dp[i-1][j][k] + coins[i][j], dp[i-1][j][k+1])); 
                    if (j > 0) dp[i][j][k] = Math.max(dp[i][j][k], Math.max(dp[i][j-1][k] + coins[i][j], dp[i][j-1][k+1])); 
                }
        return Math.max(dp[m-1][n-1][0], Math.max(dp[m-1][n-1][1], dp[m-1][n-1][2])); 
    }
}
```
```JavaScript []
var maximumAmount = function(coins) {
    const m = coins.length, n = coins[0].length; 
    const dp = Array(m).fill(0).map(() => Array(n).fill(0).map(() => Array(4).fill(-Infinity))); 
    dp[0][0][2] = coins[0][0]; 
    if (coins[0][0] < 0) dp[0][0][1] = 0; 
    for (let i = 0; i < m; ++i)
        for (let j = 0; j < n; ++j)
            for (let k = 0; k <= 2; ++k) {
                if (i) dp[i][j][k] = Math.max(dp[i][j][k], dp[i-1][j][k] + coins[i][j], dp[i-1][j][k+1]); 
                if (j) dp[i][j][k] = Math.max(dp[i][j][k], dp[i][j-1][k] + coins[i][j], dp[i][j-1][k+1]); 
            }
    return Math.max(...dp[m-1][n-1]); 

};
```
```python3 []
class Solution:
    def maximumAmount(self, coins: List[List[int]]) -> int:
        m, n = len(coins), len(coins[0])
        dp = [[[-inf]*4 for _ in range(n)] for _ in range(m)]
        dp[0][0][2] = coins[0][0]
        if coins[0][0] < 0: dp[0][0][1] = 0
        for i in range(m): 
            for j in range(n): 
                for k in range(3): 
                    if i: dp[i][j][k] = max(dp[i][j][k], dp[i-1][j][k] + coins[i][j], dp[i-1][j][k+1])
                    if j: dp[i][j][k] = max(dp[i][j][k], dp[i][j-1][k] + coins[i][j], dp[i][j-1][k+1])
        return max(dp[m-1][n-1][k] for k in range(3))
```
['C++', 'Java', 'Python3', 'JavaScript']