def shared_branch_length_to_root(t, envs):
    """Returns the shared branch length for a single env from tips to root
    
    t: phylogenetic tree relating sequences
    envs: dict of {sequence:{env:count}} showing environmental abundance

    Returns {env:shared_branch_length}
    """
    working_t = t.copy()
    result = {}

    # decorate nodes with environment information
    for n in working_t.postorder():
        # for tip, grab and set env information
        if n.isTip():  
            curr_envs = envs.get(n.Name, None)
            if curr_envs is None:
                n.Envs = set([])
            else:
                n.Envs = set(curr_envs.keys())
        # for internal node, collect descending env information
        else:  
            n.Envs = set([])  # should only visit each internal node once
            for c in n.Children:
                n.Envs.update(c.Envs)

    # collect branch length for each environment
    for n in working_t.preorder(include_self=False):
        if not hasattr(n, 'Length') or n.Length is None:
            continue

        for e in n.Envs:
            if e not in result:
                result[e] = 0.0
            result[e] += n.Length

    return result