def unify(X,Y,subst:None):
    if subst is None:
        subst={}
    if X==Y:
        return subst
    if isinstance(X,str) and X.startswith('?'):
        return unify_var(X,Y,subst)
    if isinstance(Y,str) and Y.startswith('?'):
        return unify_var(Y,X,subst)
    if isinstance(X,list) and isinstance(Y,list) and len(X)==len(Y):
        for a,b in zip(X,Y):
            subst=unify(a,b,subst)
            if subst is None:
                return None
        return subst
    return None
def unify_var(var,val,subst):
    if var in subst:
        return unify(subst[var],val,subst)
    if isinstance(val,str) and val.startswith('?') and val in subst:
        return unify(var,subst[val],subst)
    if occur(var,val,subst):
        return None
    subst[var]=val
    return subst
def occur(var,val,subst):
    if var==val:
        return True
    if isinstance(val,str) and val.startswith('f') and val in subst:
        return occur(var,subst[val],subst)
    if isinstance(val,list):
        return any(occur(var,V,subst) for V in val)
    return False
if __name__ == "__main__":
  expr1=['knows','?X','jhon']
  expr2=['knows','mary','?Y']
print(unify(expr1,expr2,None))
