class Solution:

def generateTrees(self, A,*args):

import itertools as its

if len(args)==0 :

a,dic=1,{}

#we use a dictionnary to store answers for a,A:

#The list of all structurally unique BST’s (binary search trees) that store values a…A.

else :

a,dic=args

```
if (a,A) in dic :
return dic[(a,A)]
elif a>A :
return [None]
elif A ==a :
dic[(a,A)]=[TreeNode(a)]
return dic[(a,A)]
else :
dic[(a,A)] = []
for i in range(a,A+1) : # loop over the root node
leftList=self.generateTrees(i-1,a,dic)
rightList=self.generateTrees(A,i+1,dic)
for left,right in its.product(leftList,rightList) :
# loop over all possibilities of left tree arrangement and right tree arrangement
tn=TreeNode(i)
tn.left=left
tn.right=right
dic[(a,A)] += [tn]
return dic[(a,A)]
```