private int maximalSquareLengthFromPoint(char matrix[][], int row, int column) {

        String areaLookupKey = String.valueOf(row)+","+String.valueOf(column);

        if (areaLookup.containsKey(areaLookupKey)) {
            return areaLookup.get(areaLookupKey);
        }

        if (matrix[row][column] == '0') {
            return 0;
        }

        if (row == matrix.length-1 || column == matrix[0].length-1) {
            return Character.getNumericValue(matrix[row][column]);
        }

        if (matrix[row][column+1] == 0 || matrix[row+1][column+1] == 0 || matrix[row+1][column] == 0) {
            return 0;
        }

        // compute areas of adjoining maximalSquares
        int area1 = maximalSquareLengthFromPoint(matrix, row, column + 1);
        int area2 = maximalSquareLengthFromPoint(matrix, row + 1, column + 1);
        int area3 = maximalSquareLengthFromPoint(matrix, row + 1, column);

        // maximalSquareLengthFromPoint starting with matrix[i][j]?
        int areas[] = new int[]{area1, area2, area3};
        Arrays.sort(areas);

        areaLookup.put(areaLookupKey, areas[0]+1);

        return areas[0]+1;
    }