import json


def document_contents_differ(old, new, threshold=20):
    """Returns whether the two document contents differ sufficiently to merit a new backup."""
    # In both the road and schedule file formats, the significant differences would occur in the
    # second level of the JSON object.
    if old == new:
        return False

    try:
        old_json = json.loads(old)
        new_json = json.loads(new)
    except:
        return True
    else:
        old_keys = set(old_json.keys())
        new_keys = set(new_json.keys())
        if old_keys != new_keys:
            return True

        for key in old_keys:
            old_elem = old_json[key]
            new_elem = new_json[key]
            if not isinstance(old_elem, list) or not isinstance(new_elem, list):
                continue

            # Compare the membership 
            old_values = set(json.dumps(elem) for elem in old_elem)
            new_values = set(json.dumps(elem) for elem in new_elem)
            if max(len(old_values - new_values), len(new_values - old_values)) >= 2:
                return True
        return False