import re


def deduce_look_back(in_features, target_features):
    """From the feature names, determine how large of a look back is used.

    Args:
        in_features (list of str): Names of input features
        target_features (list of str): Names of target features.
    
    Returns:
        int: Number of look back features.
        int: Look back value.
    
    """
    def is_shared(target_feature):

        for in_feature in in_features:

            if re.match(re.escape(target_feature) + r'\d+$', in_feature):
                return True
        
        return False

    shared_features = list(filter(is_shared, target_features))

    if len(shared_features) == 0:
        return 0, None

    look_backs = []

    for shared_feature in shared_features:

        look_backs.append(0)

        for in_feature in in_features:

            if re.match(re.escape(shared_feature) + r'\d+$', in_feature):
                look_backs[-1] += 1
    
    if look_backs.count(look_backs[0]) != len(look_backs):
        raise ValueError('Inconsistent look back.')

    return len(look_backs), look_backs[0]