Rec -> Memo-> tabulation
\n\n# Approach\n\n    Recursion : TLE ( O(n * m * 3 ^ m)), space : O(1)+recursive stack\n\n    class Solution {\n    int solve(int[][] g,int i,int j,int prev){\
\n\n# Approach\n\n    Recursion : TLE ( O(n * m * 3 ^ m)), space : O(1)+recursive stack\n\n    class Solution {\n    int solve(int[][] g,int i,int j,int prev){\n        //if index out of matrix then return -1\n        if(i==g.length || i<0 || j == g[0].length ) return -1;\n        //if current is less than prev then cannot proceed\n        if(g[i][j] <= prev) return -1;\n        //visit the top right element\n        int a = 1+solve(g,i-1,j+1,g[i][j]);\n        //visit the right element in same row\n        int b = 1+solve(g,i,j+1,g[i][j]);\n        //visit the bottom right element \n        int c = 1+solve(g,i+1,j+1,g[i][j]);\n        //get max possible moves at current node\n        return Math.max(a,Math.max(b,c));\n    }\n    public int maxMoves(int[][] grid) {\n        int ans = 0;\n        //get the max moves of first column\n        for(int i=0;i<grid.length;i++){\n            ans = Math.max(ans,solve(grid,i,0,-1));\n        }\n        return ans;\n    }\n    }\n\n    Memorization : time : O(N*M),space :  O(N*M)+ recursive stack\n\n    class Solution {\n    int[][] dp;\n    int solve(int[][] g,int i,int j,int prev){\n        if(i==g.length || i<0 || j == g[0].length ) return -1;\n        if(g[i][j] <= prev) return -1;\n        if(dp[i][j] != -1) return dp[i][j];\n        int a = 1+solve(g,i-1,j+1,g[i][j]);\n        int b = 1+solve(g,i,j+1,g[i][j]);\n        int c = 1+solve(g,i+1,j+1,g[i][j]);\n        return dp[i][j] = Math.max(a,Math.max(b,c));\n    }\n    public int maxMoves(int[][] grid) {\n        int ans = 0;\n        dp = new int[grid.length][grid[0].length];\n        for(int i=0;i<grid.length;i++)\n            Arrays.fill(dp[i],-1);\n        for(int i=0;i<grid.length;i++){\n            ans = Math.max(ans,solve(grid,i,0,-1));\n        }\n        return ans;\n    }\n    }\n\n    Tabulation : O(N*M),O(N*M)\n    class Solution {   \n    int solveTab(int[][] g){\n        int n = g.length,m = g[0].length;\n        int[][] dp = new int[n][m];\n         for(int j=m-2;j>=0;j--){\n            for(int i = 0;i<n;i++){\n                    int curr = g[i][j];\n                    int top = 0,right = 0,down = 0;\n                    if(i !=0 && g[i][j]<g[i-1][j+1])\n                        top= 1+dp[i-1][j+1];\n                    if(g[i][j]<g[i][j+1] )\n                       right = 1+dp[i][j+1];\n                    if(i+1!=n && g[i][j] < g[i+1][j+1])\n                        down = 1+dp[i+1][j+1];\n                    dp[i][j] = Math.max(top,Math.max(right,down));\n            }\n         }\n        int ans = 0;\n        for(int i=0;i<n;i++)\n           ans = Math.max(ans,dp[i][0]);\n        return ans;\n    }\n    public int maxMoves(int[][] grid) {\n        return solveTab(grid);\n    }\n    }\n\n    -> we can optimze the space as we need only next column to compute\n       current column the optimized space would be O(N)\n\n# Code\n```java []\nclass Solution {\n    int[][] dp;\n    int solve(int[][] g,int i,int j,int prev){\n        if(i==g.length || i<0 || j == g[0].length ) return -1;\n        if(g[i][j] <= prev) return -1;\n        if(dp[i][j] != -1) return dp[i][j];\n        int a = 1+solve(g,i-1,j+1,g[i][j]);\n        int b = 1+solve(g,i,j+1,g[i][j]);\n        int c = 1+solve(g,i+1,j+1,g[i][j]);\n        return dp[i][j] = Math.max(a,Math.max(b,c));\n    }\n    public int maxMoves(int[][] grid) {\n        int ans = 0;\n        dp = new int[grid.length][grid[0].length];\n        for(int i=0;i<grid.length;i++)\n            Arrays.fill(dp[i],-1);\n        for(int i=0;i<grid.length;i++){\n            ans = Math.max(ans,solve(grid,i,0,-1));\n        }\n        return ans;\n    }\n}\n```
['Java']