def _distribute(info):
 if (info[0].func is info[2]):
  for arg in info[0].args:
   if (arg.func is info[1]):
    conj = arg
    break
  else:
   return info[0]
  rest = info[2](*[a for a in info[0].args if (a is not conj)])
  return info[1](*list(map(_distribute, [(info[2](c, rest), info[1], info[2]) for c in conj.args])))
 elif (info[0].func is info[1]):
  return info[1](*list(map(_distribute, [(x, info[1], info[2]) for x in info[0].args])))
 else:
  return info[0]

def _distribute ( info ) : if ( info [ 0 ] . func is info [ 2 ] ) : for arg in info [ 0 ] . args : if ( arg . func is info [ 1 ] ) : conj = arg break else : return info [ 0 ] rest = info [ 2 ] ( * [ a for a in info [ 0 ] . args if ( a is not conj ) ] ) return info [ 1 ] ( * list ( map ( _distribute , [ ( info [ 2 ] ( c , rest ) , info [ 1 ] , info [ 2 ] ) for c in conj . args ] ) ) ) elif ( info [ 0 ] . func is info [ 1 ] ) : return info [ 1 ] ( * list ( map ( _distribute , [ ( x , info [ 1 ] , info [ 2 ] ) for x in info [ 0 ] . args ] ) ) ) else : return info [ 0 ]
distributes info[1] over info[2] with respect to info[0] .