Baring Accepted Solution But Easy To Understand | Memoization | O(m*n*2)
Code

# Code
```java []
class Solution {
    Integer[][][] memo;
    private int process(int[][] coins, int i, int j, int count) {
        if (memo[i][j][count] != null) return memo[i][j][count];
        if (i == coins.length - 1 && j == coins[0].length - 1) {
            if (coins[i][j] < 0 && count > 0)return memo[i][j][count] =  0;
            return memo[i][j][count]=coins[i][j];
        }
        
        
        int max1 = Integer.MIN_VALUE;
        int max2 = Integer.MIN_VALUE;
        int[][] dirt = {{0, 1}, {1, 0}};
        
        // Try normal moves
        for (int[] d : dirt) {
            int x = i + d[0];
            int y = j + d[1];
            if (x < coins.length && y < coins[0].length) {
                max1 = Math.max(max1, process(coins, x, y, count));
                if (coins[i][j] < 0 && count > 0) {
                    max2 = Math.max(max2, process(coins, x, y, count - 1));
                }
            }
        }


        // Store the result in the memo table
        return memo[i][j][count] = Math.max(coins[i][j] + max1, max2);
    }

    public int maximumAmount(int[][] coins) {
        int m = coins.length, n = coins[0].length;
        memo = new Integer[m][n][3];
        // for (int[][] mem : memo) for (int[] me : mem) Arrays.fill(me, -1);
        return process(coins, 0, 0, 2);
    }
}

```
['Java']