private static int run_upward(char[][] grid, int[][] from, int[][] to, int N, int M, int max) {
        for (int j = 1; j < M; j++) {
            for (int ihigh = N-1; ihigh > 0; ihigh--) {
                if (grid[ihigh][j] == '#' || from[ihigh][j-1] < 0) continue;                    
                int left = from[ihigh][j-1];

                for (int ilow = ihigh-1; ilow >=0; ilow--) {
                    if (grid[ilow][j] == '#') break;

                    int straight = ihigh - ilow + 1;
                    int right = j >= M-1 || to[ilow][j+1] < 0 ? 0 : to[ilow][j+1];

                    max = Math.max(max, left + straight + right);
                }
            }
        }
        
        return max;
    }