def solve_error(self, cipher):
        """
        f[i][j] represents the number of combinations for size i*j
        f[i][j+1] = iC1*f[i-1][j]*f[1][j+1]
                  = iC2*f[i-2][j]*f[1][j+1]^2
                  ...
        (need careful math proof of the equivalent points
        :param cipher: the cipher
        """
        N, M = cipher
        f = [[0 for _ in xrange(M + 1)] for _ in xrange(N + 1)]

        f[1][1] = 1
        for j in xrange(1, M + 1):
            for l in self.lens:
                if j - l >= 1:
                    f[1][j] += f[1][l - j]
        for j in xrange(1, M + 1):
            f[1][j] -= f[1][j - 1]

        for i in xrange(2, N + 1):
            for j in xrange(1, M + 1):
                cmb = i
                for l in xrange(1, i + 1):
                    f[i][j] += cmb * f[i - l][j - 1] * (f[1][j] ** i)  # equivalent
                    cmb = cmb * (i - l) / (l + 1)
        return f[N][M]
dataset/ETHPy150Open algorhythms/HackerRankAlgorithms/Lego Blocks.py/Solution_TLE.solve_error/swapped operands of `-`