code: def trig_split(a, b, two=False):
      """Return the gcd, s1, s2, a1, a2, bool where
  
      If two is False (default) then::
          a + b = gcd*(s1*f(a1) + s2*f(a2)) where f = cos if bool else sin
      else:
          if bool, a + b was +/- cos(a1)*cos(a2) +/- sin(a1)*sin(a2) and equals
              n1*gcd*cos(a - b) if n1 == n2 else
              n1*gcd*cos(a + b)
          else a + b was +/- cos(a1)*sin(a2) +/- sin(a1)*cos(a2) and equals
              n1*gcd*sin(a + b) if n1 = n2 else
              n1*gcd*sin(b - a)
  
      Examples
      ========
  
      >>> from sympy.simplify.fu import trig_split
      >>> from sympy.abc import x, y, z
      >>> from sympy import cos, sin, sqrt
  
      >>> trig_split(cos(x), cos(y))
      (1, 1, 1, x, y, True)
      >>> trig_split(2*cos(x), -2*cos(y))
      (2, 1, -1, x, y, True)
      >>> trig_split(cos(x)*sin(y), cos(y)*sin(y))
      (sin(y), 1, 1, x, y, True)
  
      >>> trig_split(cos(x), -sqrt(3)*sin(x), two=True)
      (2, 1, -1, x, pi/6, False)
      >>> trig_split(cos(x), sin(x), two=True)
      (sqrt(2), 1, 1, x, pi/4, False)
      >>> trig_split(cos(x), -sin(x), two=True)
      (sqrt(2), 1, -1, x, pi/4, False)
      >>> trig_split(sqrt(2)*cos(x), -sqrt(6)*sin(x), two=True)
      (2*sqrt(2), 1, -1, x, pi/6, False)
      >>> trig_split(-sqrt(6)*cos(x), -sqrt(2)*sin(x), two=True)
      (-2*sqrt(2), 1, 1, x, pi/3, False)
      >>> trig_split(cos(x)/sqrt(6), sin(x)/sqrt(2), two=True)
      (sqrt(6)/3, 1, 1, x, pi/6, False)
      >>> trig_split(-sqrt(6)*cos(x)*sin(y), -sqrt(2)*sin(x)*sin(y), two=True)
      (-2*sqrt(2)*sin(y), 1, 1, x, pi/3, False)
  
      >>> trig_split(cos(x), sin(x))
      >>> trig_split(cos(x), sin(z))
      >>> trig_split(2*cos(x), -sin(x))
      >>> trig_split(cos(x), -sqrt(3)*sin(x))
      >>> trig_split(cos(x)*cos(y), sin(x)*sin(z))
      >>> trig_split(cos(x)*cos(y), sin(x)*sin(y))
      >>> trig_split(-sqrt(6)*cos(x), sqrt(2)*sin(x)*sin(y), two=True)
      """
      global _ROOT2, _ROOT3, _invROOT3
      if _ROOT2 is None:
          _roots()
  
      a, b = [Factors(i) for i in (a, b)]
      ua, ub = a.normal(b)
      gcd = a.gcd(b).as_expr()
      n1 = n2 = 1
      if S.NegativeOne in ua.factors:
          ua = ua.quo(S.NegativeOne)
          n1 = -n1
      elif S.NegativeOne in ub.factors:
          ub = ub.quo(S.NegativeOne)
          n2 = -n2
      a, b = [i.as_expr() for i in (ua, ub)]
  
      def pow_cos_sin(a, two):
          """Return ``a`` as a tuple (r, c, s) such that
          ``a = (r or 1)*(c or 1)*(s or 1)``.
  
          Three arguments are returned (radical, c-factor, s-factor) as
          long as the conditions set by ``two`` are met; otherwise None is
          returned. If ``two`` is True there will be one or two non-None
          values in the tuple: c and s or c and r or s and r or s or c with c
          being a cosine function (if possible) else a sine, and s being a sine
          function (if possible) else oosine. If ``two`` is False then there
          will only be a c or s term in the tuple.
  
          ``two`` also require that either two cos and/or sin be present (with
          the condition that if the functions are the same the arguments are
          different or vice versa) or that a single cosine or a single sine
          be present with an optional radical.
  
          If the above conditions dictated by ``two`` are not met then None
          is returned.
          """
          c = s = None
          co = S.One
          if a.is_Mul:
              co, a = a.as_coeff_Mul()
              if len(a.args) > 2 or not two:
                  return None
              if a.is_Mul:
                  args = list(a.args)
              else:
                  args = [a]
              a = args.pop(0)
              if isinstance(a, cos):
                  c = a
              elif isinstance(a, sin):
                  s = a
              elif (
                  a.is_Pow and a.exp is S.Half
              ):  # autoeval doesn't allow -1/2
                  co *= a
              else:
                  return None
              if args:
                  b = args[0]
                  if isinstance(b, cos):
                      if c:
                          s = b
                      else:
                          c = b
                  elif isinstance(b, sin):
                      if s:
                          c = b
                      else:
                          s = b
                  elif b.is_Pow and b.exp is S.Half:
                      co *= b
                  else:
                      return None
              return co if co is not S.One else None, c, s
          elif isinstance(a, cos):
              c = a
          elif isinstance(a, sin):
              s = a
          if c is None and s is None:
              return
          co = co if co is not S.One else None
          return co, c, s
  
      # get the parts
      m = pow_cos_sin(a, two)
      if m is None:
          return
      coa, ca, sa = m
      m = pow_cos_sin(b, two)
      if m is None:
          return
      cob, cb, sb = m
  
      # check them
      if (not ca) and cb or ca and isinstance(ca, sin):
          coa, ca, sa, cob, cb, sb = cob, cb, sb, coa, ca, sa
          n1, n2 = n2, n1
      if not two:  # need cos(x) and cos(y) or sin(x) and sin(y)
          c = ca or sa
          s = cb or sb
          if not isinstance(c, s.func):
              return None
          return gcd, n1, n2, c.args[0], s.args[0], isinstance(c, cos)
      else:
          if not coa and not cob:
              if ca and cb and sa and sb:
                  if isinstance(ca, sa.func) is not isinstance(
                      cb, sb.func
                  ):
                      return
                  args = {j.args for j in (ca, sa)}
                  if not all(i.args in args for i in (cb, sb)):
                      return
                  return (
                      gcd,
                      n1,
                      n2,
                      ca.args[0],
                      sa.args[0],
                      isinstance(ca, sa.func),
                  )
          if (
              ca
              and sa
              or cb
              and sb
              or two
              and (
                  ca is None and sa is None or cb is None and sb is None
              )
          ):
              return
          c = ca or sa
          s = cb or sb
          if c.args != s.args:
              return
          if not coa:
              coa = S.One
          if not cob:
              cob = S.One
          if coa is cob:
              gcd *= _ROOT2
              return gcd, n1, n2, c.args[0], pi / 4, False
          elif coa / cob == _ROOT3:
              gcd *= 2 * cob
              return gcd, n1, n2, c.args[0], pi / 3, False
          elif coa / cob == _invROOT3:
              gcd *= 2 * coa
              return gcd, n1, n2, c.args[0], pi / 6, False
  
imports: from collections import defaultdict
  from sympy.core.add import Add
  from sympy.core.expr import Expr
  from sympy.core.exprtools import Factors, gcd_terms, factor_terms
  from sympy.core.function import expand_mul
  from sympy.core.mul import Mul
  from sympy.core.numbers import pi, I
  from sympy.core.power import Pow
  from sympy.core.singleton import S
  from sympy.core.sorting import ordered
  from sympy.core.symbol import Dummy
  from sympy.core.sympify import sympify
  from sympy.core.traversal import bottom_up
  from sympy.functions.combinatorial.factorials import binomial
  from sympy.functions.elementary.hyperbolic import cosh, sinh, tanh, coth, sech, csch, HyperbolicFunction
  from sympy.functions.elementary.trigonometric import cos, sin, tan, cot, sec, csc, sqrt, TrigonometricFunction
  from sympy.ntheory.factor_ import perfect_power
  from sympy.polys.polytools import factor
  from sympy.strategies.tree import greedy
  from sympy.strategies.core import identity, debug
  from sympy import SYMPY_DEBUG
label_desc: Use image node_id 31 for calling a global function with example usage: trig_split(a, b, two) and returns: co,  c,  s, gcd,  n1,  n2,  c,  s,  isinstance, unknown,  c,  s, None, gcd,  n1,  n2,  c,  unknown,  False, None, gcd,  n1,  n2,  ca,  sa,  isinstance, gcd,  n1,  n2,  c,  unknown,  False, gcd,  n1,  n2,  c,  unknown,  False, None, None