def __init__(self, iterable=None, key=None, load=1000, _set=None):
        """
        A `SortedSet` provides the same methods as a `set`.  Additionally, a
        `SortedSet` maintains its items in sorted order, allowing the
        `SortedSet` to be indexed.

        An optional *iterable* provides an initial series of items to populate
        the `SortedSet`.

        An optional *key* argument defines a callable that, like the `key`
        argument to Python's `sorted` function, extracts a comparison key from
        each set item. If no function is specified, the default compares the
        set items directly.

        An optional *load* specifies the load-factor of the set. The default
        load factor of '1000' works well for sets from tens to tens of millions
        of elements.  Good practice is to use a value that is the cube root of
        the set size.  With billions of elements, the best load factor depends
        on your usage.  It's best to leave the load factor at the default until
        you start benchmarking.
        """
        self._key = key
        self._load = load

        self._set = set() if _set is None else _set

        _set = self._set
        self.isdisjoint = _set.isdisjoint
        self.issubset = _set.issubset
        self.issuperset = _set.issuperset

        if key is None:
            self._list = SortedList(self._set, load=load)
        else:
            self._list = SortedListWithKey(self._set, key=key, load=load)

        _list = self._list
        self.bisect_left = _list.bisect_left
        self.bisect = _list.bisect
        self.bisect_right = _list.bisect_right
        self.index = _list.index
        self.irange = _list.irange
        self.islice = _list.islice

        if key is not None:
            self.bisect_key_left = _list.bisect_key_left
            self.bisect_key_right = _list.bisect_key_right
            self.bisect_key = _list.bisect_key
            self.irange_key = _list.irange_key

        if iterable is not None:
            self._update(iterable)
    def __init__(self, *args, **kwargs):
        """
        A SortedDict provides the same methods as a dict.  Additionally, a
        SortedDict efficiently maintains its keys in sorted order. Consequently,
        the keys method will return the keys in sorted order, the popitem method
        will remove the item with the highest key, etc.

        An optional *key* argument defines a callable that, like the `key`
        argument to Python's `sorted` function, extracts a comparison key from
        each dict key. If no function is specified, the default compares the
        dict keys directly. The `key` argument must be provided as a positional
        argument and must come before all other arguments.

        An optional *load* argument defines the load factor of the internal list
        used to maintain sort order. If present, this argument must come before
        an iterable. The default load factor of '1000' works well for lists from
        tens to tens of millions of elements.  Good practice is to use a value
        that is the cube root of the list size.  With billions of elements, the
        best load factor depends on your usage.  It's best to leave the load
        factor at the default until you start benchmarking.

        An optional *iterable* argument provides an initial series of items to
        populate the SortedDict.  Each item in the series must itself contain
        two items.  The first is used as a key in the new dictionary, and the
        second as the key's value. If a given key is seen more than once, the
        last value associated with it is retained in the new dictionary.

        If keyword arguments are given, the keywords themselves with their
        associated values are added as items to the dictionary. If a key is
        specified both in the positional argument and as a keyword argument, the
        value associated with the keyword is retained in the dictionary. For
        example, these all return a dictionary equal to ``{"one": 2, "two":
        3}``:

        * ``SortedDict(one=2, two=3)``
        * ``SortedDict({'one': 2, 'two': 3})``
        * ``SortedDict(zip(('one', 'two'), (2, 3)))``
        * ``SortedDict([['two', 3], ['one', 2]])``

        The first example only works for keys that are valid Python
        identifiers; the others work with any valid keys.
        """
        if len(args) > 0 and (args[0] is None or callable(args[0])):
            self._key = args[0]
            args = args[1:]
        else:
            self._key = None

        if len(args) > 0 and type(args[0]) == int:
            self._load = args[0]
            args = args[1:]
        else:
            self._load = 1000

        if self._key is None:
            self._list = SortedList(load=self._load)
        else:
            self._list = SortedListWithKey(key=self._key, load=self._load)

        # Cache function pointers to dict methods.

        _dict = super(SortedDict, self)
        self._dict = _dict
        self._clear = _dict.clear
        self._delitem = _dict.__delitem__
        self._iter = _dict.__iter__
        self._pop = _dict.pop
        self._setdefault = _dict.setdefault
        self._setitem = _dict.__setitem__
        self._dict_update = _dict.update

        # Cache function pointers to SortedList methods.

        _list = self._list
        self._list_add = _list.add
        self.bisect_left = _list.bisect_left
        self.bisect = _list.bisect_right
        self.bisect_right = _list.bisect_right
        self._list_clear = _list.clear
        self.index = _list.index
        self._list_pop = _list.pop
        self._list_remove = _list.remove
        self._list_update = _list.update
        self.irange = _list.irange
        self.islice = _list.islice

        if self._key is not None:
            self.bisect_key_left = _list.bisect_key_left
            self.bisect_key_right = _list.bisect_key_right
            self.bisect_key = _list.bisect_key
            self.irange_key = _list.irange_key

        self.iloc = _IlocWrapper(self)

        self._update(*args, **kwargs)
class SortedSet(MutableSet, Sequence):
    """
    A `SortedSet` provides the same methods as a `set`.  Additionally, a
    `SortedSet` maintains its items in sorted order, allowing the `SortedSet` to
    be indexed.

    Unlike a `set`, a `SortedSet` requires items be hashable and comparable.
    """

    def __init__(self, iterable=None, key=None, load=1000, _set=None):
        """
        A `SortedSet` provides the same methods as a `set`.  Additionally, a
        `SortedSet` maintains its items in sorted order, allowing the
        `SortedSet` to be indexed.

        An optional *iterable* provides an initial series of items to populate
        the `SortedSet`.

        An optional *key* argument defines a callable that, like the `key`
        argument to Python's `sorted` function, extracts a comparison key from
        each set item. If no function is specified, the default compares the
        set items directly.

        An optional *load* specifies the load-factor of the set. The default
        load factor of '1000' works well for sets from tens to tens of millions
        of elements.  Good practice is to use a value that is the cube root of
        the set size.  With billions of elements, the best load factor depends
        on your usage.  It's best to leave the load factor at the default until
        you start benchmarking.
        """
        self._key = key
        self._load = load

        self._set = set() if _set is None else _set

        _set = self._set
        self.isdisjoint = _set.isdisjoint
        self.issubset = _set.issubset
        self.issuperset = _set.issuperset

        if key is None:
            self._list = SortedList(self._set, load=load)
        else:
            self._list = SortedListWithKey(self._set, key=key, load=load)

        _list = self._list
        self.bisect_left = _list.bisect_left
        self.bisect = _list.bisect
        self.bisect_right = _list.bisect_right
        self.index = _list.index
        self.irange = _list.irange
        self.islice = _list.islice

        if key is not None:
            self.bisect_key_left = _list.bisect_key_left
            self.bisect_key_right = _list.bisect_key_right
            self.bisect_key = _list.bisect_key
            self.irange_key = _list.irange_key

        if iterable is not None:
            self._update(iterable)

    def __contains__(self, value):
        """Return True if and only if *value* is an element in the set."""
        return (value in self._set)

    def __getitem__(self, index):
        """
        Return the element at position *index*.

        Supports slice notation and negative indexes.
        """
        return self._list[index]

    def __delitem__(self, index):
        """
        Remove the element at position *index*.

        Supports slice notation and negative indexes.
        """
        _list = self._list
        if isinstance(index, slice):
            values = _list[index]
            self._set.difference_update(values)
        else:
            value = _list[index]
            self._set.remove(value)
        del _list[index]

    def _make_cmp(set_op, doc):
        def comparer(self, that):
            if isinstance(that, SortedSet):
                return set_op(self._set, that._set)
            elif isinstance(that, Set):
                return set_op(self._set, that)
            else:
                return NotImplemented

        comparer.__name__ = '__{0}__'.format(set_op.__name__)
        doc_str = 'Return True if and only if Set is {0} `that`.'
        comparer.__doc__ = doc_str.format(doc)

        return comparer

    __eq__ = _make_cmp(op.eq, 'equal to')
    __ne__ = _make_cmp(op.ne, 'not equal to')
    __lt__ = _make_cmp(op.lt, 'a proper subset of')
    __gt__ = _make_cmp(op.gt, 'a proper superset of')
    __le__ = _make_cmp(op.le, 'a subset of')
    __ge__ = _make_cmp(op.ge, 'a superset of')

    def __len__(self):
        """Return the number of elements in the set."""
        return len(self._set)

    def __iter__(self):
        """
        Return an iterator over the Set. Elements are iterated in their sorted
        order.

        Iterating the Set while adding or deleting values may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return iter(self._list)

    def __reversed__(self):
        """
        Return an iterator over the Set. Elements are iterated in their reverse
        sorted order.

        Iterating the Set while adding or deleting values may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return reversed(self._list)

    def add(self, value):
        """Add the element *value* to the set."""
        if value not in self._set:
            self._set.add(value)
            self._list.add(value)

    def clear(self):
        """Remove all elements from the set."""
        self._set.clear()
        self._list.clear()

    def copy(self):
        """Create a shallow copy of the sorted set."""
        return self.__class__(key=self._key,
                              load=self._load,
                              _set=set(self._set))

    __copy__ = copy

    def count(self, value):
        """Return the number of occurrences of *value* in the set."""
        return 1 if value in self._set else 0

    def discard(self, value):
        """
        Remove the first occurrence of *value*.  If *value* is not a member,
        does nothing.
        """
        if value in self._set:
            self._set.remove(value)
            self._list.discard(value)

    def pop(self, index=-1):
        """
        Remove and return item at *index* (default last).  Raises IndexError if
        set is empty or index is out of range.  Negative indexes are supported,
        as for slice indices.
        """
        value = self._list.pop(index)
        self._set.remove(value)
        return value

    def remove(self, value):
        """
        Remove first occurrence of *value*.  Raises ValueError if
        *value* is not present.
        """
        self._set.remove(value)
        self._list.remove(value)

    def difference(self, *iterables):
        """
        Return a new set with elements in the set that are not in the
        *iterables*.
        """
        diff = self._set.difference(*iterables)
        new_set = self.__class__(key=self._key, load=self._load, _set=diff)
        return new_set

    __sub__ = difference
    __rsub__ = __sub__

    def difference_update(self, *iterables):
        """
        Update the set, removing elements found in keeping only elements
        found in any of the *iterables*.
        """
        values = set(chain(*iterables))
        if (4 * len(values)) > len(self):
            self._set.difference_update(values)
            self._list.clear()
            self._list.update(self._set)
        else:
            _discard = self.discard
            for value in values:
                _discard(value)
        return self

    __isub__ = difference_update

    def intersection(self, *iterables):
        """
        Return a new set with elements common to the set and all *iterables*.
        """
        comb = self._set.intersection(*iterables)
        new_set = self.__class__(key=self._key, load=self._load, _set=comb)
        return new_set

    __and__ = intersection
    __rand__ = __and__

    def intersection_update(self, *iterables):
        """
        Update the set, keeping only elements found in it and all *iterables*.
        """
        self._set.intersection_update(*iterables)
        self._list.clear()
        self._list.update(self._set)
        return self

    __iand__ = intersection_update

    def symmetric_difference(self, that):
        """
        Return a new set with elements in either *self* or *that* but not both.
        """
        diff = self._set.symmetric_difference(that)
        new_set = self.__class__(key=self._key, load=self._load, _set=diff)
        return new_set

    __xor__ = symmetric_difference
    __rxor__ = __xor__

    def symmetric_difference_update(self, that):
        """
        Update the set, keeping only elements found in either *self* or *that*,
        but not in both.
        """
        self._set.symmetric_difference_update(that)
        self._list.clear()
        self._list.update(self._set)
        return self

    __ixor__ = symmetric_difference_update

    def union(self, *iterables):
        """
        Return a new SortedSet with elements from the set and all *iterables*.
        """
        return self.__class__(
            chain(
                iter(self), *iterables),
            key=self._key,
            load=self._load)

    __or__ = union
    __ror__ = __or__

    def update(self, *iterables):
        """Update the set, adding elements from all *iterables*."""
        values = set(chain(*iterables))
        if (4 * len(values)) > len(self):
            self._set.update(values)
            self._list.clear()
            self._list.update(self._set)
        else:
            _add = self.add
            for value in values:
                _add(value)
        return self

    __ior__ = update
    _update = update

    def __reduce__(self):
        return (self.__class__, ((), self._key, self._load, self._set))

    @recursive_repr
    def __repr__(self):
        temp = '{0}({1}, key={2}, load={3})'
        return temp.format(self.__class__.__name__, repr(list(self)),
                           repr(self._key), repr(self._load))

    def _check(self):
        self._list._check()
        assert len(self._set) == len(self._list)
        _set = self._set
        assert all(val in _set for val in self._list)
class SortedDict(dict):
    """
    A SortedDict provides the same methods as a dict.  Additionally, a
    SortedDict efficiently maintains its keys in sorted order. Consequently, the
    keys method will return the keys in sorted order, the popitem method will
    remove the item with the highest key, etc.
    """

    def __init__(self, *args, **kwargs):
        """
        A SortedDict provides the same methods as a dict.  Additionally, a
        SortedDict efficiently maintains its keys in sorted order. Consequently,
        the keys method will return the keys in sorted order, the popitem method
        will remove the item with the highest key, etc.

        An optional *key* argument defines a callable that, like the `key`
        argument to Python's `sorted` function, extracts a comparison key from
        each dict key. If no function is specified, the default compares the
        dict keys directly. The `key` argument must be provided as a positional
        argument and must come before all other arguments.

        An optional *load* argument defines the load factor of the internal list
        used to maintain sort order. If present, this argument must come before
        an iterable. The default load factor of '1000' works well for lists from
        tens to tens of millions of elements.  Good practice is to use a value
        that is the cube root of the list size.  With billions of elements, the
        best load factor depends on your usage.  It's best to leave the load
        factor at the default until you start benchmarking.

        An optional *iterable* argument provides an initial series of items to
        populate the SortedDict.  Each item in the series must itself contain
        two items.  The first is used as a key in the new dictionary, and the
        second as the key's value. If a given key is seen more than once, the
        last value associated with it is retained in the new dictionary.

        If keyword arguments are given, the keywords themselves with their
        associated values are added as items to the dictionary. If a key is
        specified both in the positional argument and as a keyword argument, the
        value associated with the keyword is retained in the dictionary. For
        example, these all return a dictionary equal to ``{"one": 2, "two":
        3}``:

        * ``SortedDict(one=2, two=3)``
        * ``SortedDict({'one': 2, 'two': 3})``
        * ``SortedDict(zip(('one', 'two'), (2, 3)))``
        * ``SortedDict([['two', 3], ['one', 2]])``

        The first example only works for keys that are valid Python
        identifiers; the others work with any valid keys.
        """
        if len(args) > 0 and (args[0] is None or callable(args[0])):
            self._key = args[0]
            args = args[1:]
        else:
            self._key = None

        if len(args) > 0 and type(args[0]) == int:
            self._load = args[0]
            args = args[1:]
        else:
            self._load = 1000

        if self._key is None:
            self._list = SortedList(load=self._load)
        else:
            self._list = SortedListWithKey(key=self._key, load=self._load)

        # Cache function pointers to dict methods.

        _dict = super(SortedDict, self)
        self._dict = _dict
        self._clear = _dict.clear
        self._delitem = _dict.__delitem__
        self._iter = _dict.__iter__
        self._pop = _dict.pop
        self._setdefault = _dict.setdefault
        self._setitem = _dict.__setitem__
        self._dict_update = _dict.update

        # Cache function pointers to SortedList methods.

        _list = self._list
        self._list_add = _list.add
        self.bisect_left = _list.bisect_left
        self.bisect = _list.bisect_right
        self.bisect_right = _list.bisect_right
        self._list_clear = _list.clear
        self.index = _list.index
        self._list_pop = _list.pop
        self._list_remove = _list.remove
        self._list_update = _list.update
        self.irange = _list.irange
        self.islice = _list.islice

        if self._key is not None:
            self.bisect_key_left = _list.bisect_key_left
            self.bisect_key_right = _list.bisect_key_right
            self.bisect_key = _list.bisect_key
            self.irange_key = _list.irange_key

        self.iloc = _IlocWrapper(self)

        self._update(*args, **kwargs)

    def clear(self):
        """Remove all elements from the dictionary."""
        self._clear()
        self._list_clear()

    def __delitem__(self, key):
        """
        Remove ``d[key]`` from *d*.  Raises a KeyError if *key* is not in the
        dictionary.
        """
        self._delitem(key)
        self._list_remove(key)

    def __iter__(self):
        """
        Return an iterator over the sorted keys of the dictionary.

        Iterating the Mapping while adding or deleting keys may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return iter(self._list)

    def __reversed__(self):
        """
        Return a reversed iterator over the sorted keys of the dictionary.

        Iterating the Mapping while adding or deleting keys may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return reversed(self._list)

    def __setitem__(self, key, value):
        """Set `d[key]` to *value*."""
        if key not in self:
            self._list_add(key)
        self._setitem(key, value)

    def copy(self):
        """Return a shallow copy of the sorted dictionary."""
        return self.__class__(self._key, self._load, self._iteritems())

    __copy__ = copy

    @classmethod
    def fromkeys(cls, seq, value=None):
        """
        Create a new dictionary with keys from *seq* and values set to *value*.
        """
        return cls((key, value) for key in seq)

    if hexversion < 0x03000000:

        def items(self):
            """
            Return a list of the dictionary's items (``(key, value)`` pairs).
            """
            return list(self._iteritems())
    else:

        def items(self):
            """
            Return a new ItemsView of the dictionary's items.  In addition to
            the methods provided by the built-in `view` the ItemsView is
            indexable (e.g. ``d.items()[5]``).
            """
            return ItemsView(self)

    def iteritems(self):
        """
        Return an iterator over the items (``(key, value)`` pairs).

        Iterating the Mapping while adding or deleting keys may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return iter((key, self[key]) for key in self._list)

    _iteritems = iteritems

    if hexversion < 0x03000000:

        def keys(self):
            """Return a SortedSet of the dictionary's keys."""
            return SortedSet(self._list, key=self._key, load=self._load)
    else:

        def keys(self):
            """
            Return a new KeysView of the dictionary's keys.  In addition to the
            methods provided by the built-in `view` the KeysView is indexable
            (e.g. ``d.keys()[5]``).
            """
            return KeysView(self)

    def iterkeys(self):
        """
        Return an iterator over the sorted keys of the Mapping.

        Iterating the Mapping while adding or deleting keys may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return iter(self._list)

    if hexversion < 0x03000000:

        def values(self):
            """Return a list of the dictionary's values."""
            return list(self._itervalues())
    else:

        def values(self):
            """
            Return a new :class:`ValuesView` of the dictionary's values.
            In addition to the methods provided by the built-in `view` the
            ValuesView is indexable (e.g., ``d.values()[5]``).
            """
            return ValuesView(self)

    def itervalues(self):
        """
        Return an iterator over the values of the Mapping.

        Iterating the Mapping while adding or deleting keys may raise a
        `RuntimeError` or fail to iterate over all entries.
        """
        return iter(self[key] for key in self._list)

    _itervalues = itervalues

    def pop(self, key, default=_NotGiven):
        """
        If *key* is in the dictionary, remove it and return its value,
        else return *default*. If *default* is not given and *key* is not in
        the dictionary, a KeyError is raised.
        """
        if key in self:
            self._list_remove(key)
            return self._pop(key)
        else:
            if default is _NotGiven:
                raise KeyError(key)
            else:
                return default

    def popitem(self, last=True):
        """
        Remove and return a ``(key, value)`` pair from the dictionary. If
        last=True (default) then remove the *greatest* `key` from the
        diciontary. Else, remove the *least* key from the dictionary.

        If the dictionary is empty, calling `popitem` raises a
        KeyError`.
        """
        if not len(self):
            raise KeyError('popitem(): dictionary is empty')

        key = self._list_pop(-1 if last else 0)
        value = self._pop(key)

        return (key, value)

    def setdefault(self, key, default=None):
        """
        If *key* is in the dictionary, return its value.  If not, insert *key*
        with a value of *default* and return *default*.  *default* defaults to
        ``None``.
        """
        if key in self:
            return self[key]
        else:
            self._setitem(key, default)
            self._list_add(key)
            return default

    def update(self, *args, **kwargs):
        """
        Update the dictionary with the key/value pairs from *other*, overwriting
        existing keys.

        *update* accepts either another dictionary object or an iterable of
        key/value pairs (as a tuple or other iterable of length two).  If
        keyword arguments are specified, the dictionary is then updated with
        those key/value pairs: ``d.update(red=1, blue=2)``.
        """
        if not len(self):
            self._dict_update(*args, **kwargs)
            self._list_update(self._iter())
            return

        if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
            pairs = args[0]
        else:
            pairs = dict(*args, **kwargs)

        if (10 * len(pairs)) > len(self):
            self._dict_update(pairs)
            self._list_clear()
            self._list_update(self._iter())
        else:
            for key in pairs:
                self[key] = pairs[key]

    _update = update

    @not26
    def viewkeys(self):
        """
        In Python 2.7 and later, return a new `KeysView` of the dictionary's
        keys.

        In Python 2.6, raise a NotImplementedError.
        """
        return KeysView(self)

    @not26
    def viewvalues(self):
        """
        In Python 2.7 and later, return a new `ValuesView` of the dictionary's
        values.

        In Python 2.6, raise a NotImplementedError.
        """
        return ValuesView(self)

    @not26
    def viewitems(self):
        """
        In Python 2.7 and later, return a new `ItemsView` of the dictionary's
        items.

        In Python 2.6, raise a NotImplementedError.
        """
        return ItemsView(self)

    def __reduce__(self):
        return (self.__class__,
                (self._key, self._load, list(self._iteritems())))

    @recursive_repr
    def __repr__(self):
        temp = '{0}({1}, {2}, {{{3}}})'
        items = ', '.join('{0}: {1}'.format(
            repr(key), repr(self[key])) for key in self._list)
        return temp.format(self.__class__.__name__, repr(self._key),
                           repr(self._load), items)

    def _check(self):
        self._list._check()
        assert len(self) == len(self._list)
        assert all(val in self for val in self._list)