"""An unordered, chaotic mess of helper functions"""
import copy
import itertools
import math
import random
import re
import string

from thunno2 import codepage


def safe_max_len(*lsts):
    m = 0
    for lst in lsts:
        if isinstance(lst, list):
            if len(lst) > m:
                m = len(lst)
    return m


def first_non_none(l):
    for i in l:
        if i is not None:
            return i


def isalpha(s):
    return int(s.isalpha())


def number_to_base_digits(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]


def ntb(b, n):
    if b == 0:
        return [n]
    if b == 1:
        return n * [0]
    return number_to_base_digits(n, b)


def number_to_base(base, num):
    num, base = int(num), int(base)
    if base <= 0:
        return str(num)
    if base == 1:
        return num * '0'
    return number_to_base_digits(num, base)


def ntbs(b, n):
    r = number_to_base_digits(n, b)
    if b <= 64:
        digits = string.digits + string.ascii_uppercase + string.ascii_lowercase + '+/'
    else:
        digits = codepage.CODEPAGE * math.ceil(b / 256)
    return ''.join(map(digits.__getitem__, r))


def to_custom_base_string(base, num):
    num = int(num)
    if len(base) == 0:
        return str(num)
    if len(base) == 1:
        return num * base
    return ''.join(map(base.__getitem__, number_to_base_digits(num, len(base))))


def length_to_base(base, s):
    base = int(base)
    if base <= 0:
        return str(len(s))
    if base == 1:
        return len(s) * '0'
    return number_to_base_digits(len(s), base)


def length_custom_base_string(str2, str1):
    num = len(str1)
    if len(str2) == 0:
        return str(num)
    if len(str2) == 1:
        return num * '0'
    return ''.join(map(str2.__getitem__, number_to_base_digits(len(str1), len(str2))))


def pass_(*args):
    return args[::-1]


def from_list_of_digits_2(num, base):
    r = 0
    for x, y in enumerate(reversed(num)):
        r += int(base) ** x * int(y)
    return r


def decompress(s, char):
    ci = codepage.CODEPAGE.index(char)
    indices = [i - (i > ci) for i in codepage.codepage_index(*s)]
    return from_list_of_digits_2(indices, 255)


def chr2(num):
    return chr(int(num))


def ord2(s):
    return [ord(c) for c in s]


def digits(num):
    return [int(d) for d in str(num) if d in '0123456789']


def is_even(num):
    return int(num % 2 == 0)


def eval2(s):
    try:
        return eval(s)
    except:
        return 0


def factors(num):
    num = int(num)
    return [i for i in range(1, num + 1) if num % i == 0]


def substrings(s):
    return [s[i:j] for i in range(len(s)) for j in range(i + 1, len(s) + 1)]


def max2(num):
    return max(int(d) for d in str(num) if d in '0123456789')


def max3(x):
    try:
        return max(x)
    except:
        return x


def from_hex(x):
    try:
        return int(str(x), 16)
    except:
        return x


def codepage_chr(num):
    return codepage.CODEPAGE[int(num) % 256]


def codepage_ord(s):
    return [*codepage.codepage_index(*s)]


def indexing_0(num, lst):
    if not lst:
        return lst
    return lst[int(num) % len(lst)]


def swapped_ind0(lst, num):
    if not lst:
        return lst
    return lst[int(num) % len(lst)]


def interleave_lst(lst1, lst2):
    if len(lst1) == len(lst2):
        r = []
        for i, j in zip(lst2, lst1):
            r.append(i)
            r.append(j)
        return r
    elif len(lst1) > len(lst2):
        r = []
        for i, j in zip(lst2, lst1):
            r.append(i)
            r.append(j)
        r.extend(lst1[len(lst2):])
        return r
    else:
        r = []
        for i, j in zip(lst2, lst1):
            r.append(i)
            r.append(j)
        r.extend(lst2[len(lst1):])
        return r


def interleave_str(s1, s2):
    if len(s1) == len(s2):
        r = ''
        for i, j in zip(s2, s1):
            r += i + j
        return r
    elif len(s1) > len(s2):
        r = ''
        for i, j in zip(s2, s1):
            r += i + j
        r += s1[len(s2):]
        return r
    else:
        r = ''
        for i, j in zip(s2, s1):
            r += i + j
        r += s2[len(s1):]
        return r


def binary_range(num1, num2):
    if num1 < num2:
        return binary_range(num2, num1)[::-1]
    return list(range(num2, num1 + 1))


def empty_join(iterable):
    if not isinstance(iterable, list):
        return str(iterable)
    return ''.join(map(empty_join, iterable))


def safe_len(x):
    try:
        return len(x)
    except:
        return 1


def lowered_range(num):
    if num < 0:
        return [-i for i in lowered_range(-num)]
    return list(range(int(num)))


def min2(num):
    return min(int(d) for d in str(num) if d in '0123456789')


def min3(x):
    try:
        return min(x)
    except:
        return x


def safe_int(x):
    try:
        return int(x)
    except:
        return str(x)


def two_power(n):
    return 2 ** n


def is_prime(n):
    i = int(n)
    return int(i >= 2 and all(i % k for k in range(2, i)))


def slice1(num, lst):
    return lst[::int(num)]


def slice2(lst, num):
    return lst[::int(num)]


def not_equal(x, y):
    return int(x != y)


def one_range(num):
    if num < 0:
        return [-i for i in one_range(-num)]
    return list(range(1, int(num) + 1))


def digit_sum(num):
    return sum(int(d) for d in str(num) if d in '0123456789')


def it_sum(lst):
    if not lst:
        return 0
    if all(isinstance(item, (int, float)) for item in lst):
        return sum(lst)
    if all(isinstance(item, list) for item in lst):
        return sum(lst[1:], lst[0])
    return ''.join(map(str, lst))


def uniquify_lst(lst):
    r = []
    for i in lst:
        if i not in r:
            r.append(i)
    return r


def uniquify_str(s):
    r = ''
    for c in s:
        if c not in r:
            r += c
    return r


def uniquify_num(num):
    return eval(uniquify_str(str(num)))


def indices_where_truthy(l):
    return [i for i, x in enumerate(l) if x]


def indices_where_truthy_num(n):
    return [i for i, x in enumerate(str(n)) if x in '123456789']


def rot_13(s):
    r = ''
    for c in s:
        if ord('A') <= ord(c.upper()) <= ord('M'):
            r += chr(ord(c) + 13)
        elif ord('N') <= ord(c.upper()) <= ord('Z'):
            r += chr(ord(c) - 13)
        else:
            r += c
    return r


def wrap(x):
    return [x]


def zip2(l1, l2):
    return list(map(list, zip(l2, l1)))


def range_zip1(n1, n2):
    n1 = int(n1)
    return zip2(one_range(n1), [n2] * abs(n1))


def range_zip2(n, l):
    return zip2(one_range(int(n)), l)


def range_zip3(l, n):
    return zip2(l, one_range(int(n)))


def append(x, l):
    return l + [x]


def safe_index(x, y, e=-1):
    if y in x:
        return x.index(y)
    return e


def convert_from_base(base, num):
    if base <= 0:
        return num
    elif base == 1:
        return len(str(num))
    if base <= 64:
        digits = string.digits + string.ascii_uppercase + string.ascii_lowercase + '+/'
    else:
        digits = codepage.CODEPAGE * math.ceil(base / 256)
    return from_list_of_digits_2(list(map((lambda c: safe_index(digits, c, 0)), str(num))), base)


def convert_from_custom_base(base, num):
    return from_list_of_digits_2(list(map((lambda c: safe_index(base, c, 0)), str(num))), len(base))


def nCr(r, n):
    n, r = int(n), int(r)
    f = math.factorial
    return f(n) // f(r) // f(n - r)


def string_count(x, y):
    if isinstance(x, list):
        return [string_count(i, y) for i in x]
    return str(y).count(str(x))


def list_count(x, y):
    if isinstance(x, list):
        return [list_count(i, y) for i in x]
    return y.count(x)


def duplicate(x):
    return x, x


def ten_power(n):
    return 10 ** n


def comma_split(s):
    return s.split(',')


def prime_factors(n):
    n = int(n)
    for i in range(2, n + 1):
        if is_prime(i) and n % i == 0:
            return [i] + prime_factors(n // i)
    return []


def case(s):
    r = []
    for c in s:
        if c.islower():
            r.append(0)
        elif c.isupper():
            r.append(1)
        else:
            r.append(-1)
    return r


def gcd(l):
    l = [int(i) for i in l if isinstance(i, (int, float)) or str(i).isdigit()]
    if not l:
        return 0
    for x in reversed(range(1, max(l))):
        if all(y % x == 0 for y in l):
            return x


def digits_gcd(n):
    return gcd([int(i) for i in str(n) if i in '0123456789'])


def ords_gcd(s):
    return gcd(list(map(ord, s)))


def head_extract(x):
    if not x:
        return x
    return x[1:], x[0]


def num_head_extract(n):
    r = ()
    for i in head_extract(str(n)):
        try:
            r += eval(i),
        except:
            r += i,
    return r


def num_ind0(x, y):
    s = str(y)[int(x) % len(str(y))]
    try:
        return int(s)
    except:
        return s


def length_ind0(x, y):
    return indexing_0(len(str(x)), y)


def vectorised_ind0(x, y):
    r = []
    for i in x:
        try:
            r.append(indexing_0(i, y))
        except:
            r.append(length_ind0(i, y))
    return r


def increment(num):
    return num + 1


def decrement(num):
    return num - 1


def str_increment(s):
    return ''.join(chr(ord(c) + 1) for c in s)


def str_decrement(s):
    return ''.join(chr(ord(c) - 1) for c in s)


def join(joiner, iterable):
    return str(joiner).join(map(str, iterable))


def num_join(j, n):
    return join(j, str(n))


def num_length(n):
    return len(str(n))


def mean(lst):
    l = []
    for i in lst:
        try:
            l.append(float(i))
        except:
            pass
    if not l:
        return 0
    return sum(l) / len(l)


def num_mean(n):
    return mean([int(i) for i in str(n) if i in '0123456789'])


def ord_mean(s):
    return mean(map(ord, s))


def str_rmv(x, y):
    return str(y).replace(str(x), '')


def num_rmv(x, y):
    try:
        return eval(str_rmv(x, y))
    except:
        return str_rmv(x, y)


def list_rmv(x, y):
    z = y.copy()
    while x in z:
        z.remove(x)
    return z


def swapped_list_rmv(x, y):
    return list_rmv(y, x)


def digit_product(num):
    return math.prod([int(i) for i in str(num) if i in '0123456789'])


def product(lst):
    l = []
    for i in lst:
        if isinstance(i, (int, float)):
            l.append(i)
        else:
            try:
                l.append(int(i))
            except:
                try:
                    l.append(float(i))
                except:
                    pass
    if not l:
        return 0
    return math.prod(l)


def ord_product(s):
    return math.prod(list(map(ord, s)))


def swapped_append(x, y):
    return append(y, x)


def _digits(x):
    if isinstance(x, (str, list)):
        return list(x)
    return [int(i) for i in str(x) if i in '0123456789']


def append2(x, y):
    return _digits(y) + [x]


def string_replace(x, y, z):
    return str(z).replace(str(y), str(x))


def list_replace(x, y, z):
    return [x if i == y else i for i in z]


def digit_reverse(num):
    r = str(num)[::-1]
    try:
        return eval(r)
    except:
        return r


def reverse(x):
    return x[::-1]


def swap(a, b):
    return a, b


def tail_extract(x):
    if not x:
        return x
    return x[:-1], x[-1]


def num_tail_extract(n):
    r = ()
    for i in tail_extract(str(n)):
        try:
            r += eval(i),
        except:
            r += i,
    return r


def remove_whitespace(s):
    return ''.join(s.split())


def uninterleave(l):
    return [l[0::2], l[1::2]]


def num_uninterleave(n):
    return uninterleave(_digits(n))


def bool2(x):
    return int(bool(x))


def isalphanum(s):
    return int(s.isalnum())


def any2(l):
    return int(any(l))


def from_binary(x):
    try:
        return int(str(x), 2)
    except:
        return x


def add(x, y):
    return y + x


def string_add(x, y):
    return str(y) + str(x)


def subtract(x, y):
    return y - x


def slice_start(s, n):
    return s[n:]


def slice_end(n, s):
    return s[:-n]


def strip(a, b):
    return b.strip(a)


def multiply(x, y):
    if isinstance(x, (str, list)):
        return x * int(y)
    elif isinstance(y, (str, list)):
        return int(x) * y
    return y * x


def string_cartesian_product(a, b):
    return [''.join(l) for l in itertools.product(b, a)]


def divide(x, y):
    return y / x


def split2(a, b):
    if a < 1:
        return b
    if not b:
        return [b] * a
    x, y = divmod(len(b), int(a))
    k = 0
    r = []
    while k < len(b):
        r.append(b[k:k + x + (y > 0)])
        k += x + (y > 0)
        if y > 0:
            y -= 1
    return r


def split1(a, b):
    return split2(b, a)


def split3(a, b):
    return b.split(a)


def exponentiate(x, y):
    return y ** x


def append_first1(a, b):
    if not a:
        return ' ' * b
    while len(a) < b:
        a += a[0]
    return a


def append_first2(a, b):
    return append_first1(b, a)


def regex_findall(a, b):
    return list(re.findall(a, b))


def modulo(x, y):
    return y % x


def str_format(a, b):
    return str(b).replace('%', str(a))


def swapped_format(a, b):
    return str_format(b, a)


def integer_divide(x, y):
    return int(y // x)


def first_split1(a, b):
    s = split1(a, b)
    if s:
        return s[0]
    return s


def first_split2(a, b):
    s = split2(a, b)
    if s:
        return s[0]
    return s


def first_split3(a, b):
    s = split3(a, b)
    if s:
        return s[0]
    return s


def slice_start2(n, s):
    return s[n:]


def slice_end2(s, n):
    return s[:-n]


def swapped_subtract(x, y):
    return x - y


def strip2(a, b):
    return a.strip(b)


def split4(a, b):
    return a.split(b)


def swapped_divide(x, y):
    return x / y


def swapped_integer_divide(x, y):
    return int(x // y)


def last_split1(a, b):
    s = split1(a, b)
    if s:
        return s[-1]
    return s


def last_split2(a, b):
    s = split2(a, b)
    if s:
        return s[-1]
    return s


def last_split3(a, b):
    s = split3(a, b)
    if s:
        return s[-1]
    return s


def str_format2(a, b):
    return str(a).replace('%', str(b))


def swapped_modulo(x, y):
    return x % y


def swapped_exponentiate(x, y):
    return x ** y


def prepend_last1(a, b):
    if not a:
        return ' ' * b
    while len(a) < b:
        a = a[-1] + a
    return a


def prepend_last2(a, b):
    return append_first1(b, a)


def swapped_regex_findall(a, b):
    return list(re.findall(b, a))


def equals(x, y):
    return int(y == x)


def less_than(x, y):
    return int(y < x)


def ord_less_than1(n, s):
    return [int(ord(x) < n) for x in s]


def ord_less_than2(s, n):
    return [int(n < ord(x)) for x in s]


def greater_than(x, y):
    return int(y > x)


def ord_greater_than1(n, s):
    return [int(ord(x) > n) for x in s]


def ord_greater_than2(s, n):
    return [int(n > ord(x)) for x in s]


def less_than_or_equal_to(x, y):
    return int(y <= x)


def ord_less_than_or_equal_to1(n, s):
    return [int(ord(x) <= n) for x in s]


def ord_less_than_or_equal_to2(s, n):
    return [int(n <= ord(x)) for x in s]


def greater_than_or_equal_to(x, y):
    return int(y >= x)


def ord_greater_than_or_equal_to1(n, s):
    return [int(ord(x) >= n) for x in s]


def ord_greater_than_or_equal_to2(s, n):
    return [int(n >= ord(x)) for x in s]


def logical_and(x, y):
    return y and x


def logical_or(x, y):
    return y or x


def logical_xor(x, y):
    return int(bool(y) ^ bool(x))


def logical_not(x):
    return int(not x)


def pair(x, y):
    return [y, x]


def is_divisible(x, y):
    try:
        return int(y % x == 0)
    except:
        return 0


def length_divisible1(s, n):
    return is_divisible(len(s), n)


def length_divisible2(n, s):
    return length_divisible1(s, n)


def length_divisible3(a, b):
    return is_divisible(len(a), len(b))


def zero_enumerate(l):
    return list(map(list, enumerate(l)))


def inclusive_zero_range(n):
    if n >= 0:
        return list(range(int(n) + 1))
    return [-i for i in range(abs(int(n)) + 1)]


def recursive_flatten(x):
    if isinstance(x, list):
        r = []
        for i in x:
            a = recursive_flatten(i)
            if isinstance(a, list):
                r += a
            else:
                r += a,
        return r
    return x


def dyadic_gcd(a, b):
    try:
        return math.gcd(abs(int(a)), abs(int(b)))
    except:
        return 1


def ordinal_gcd1(a, b):
    return [dyadic_gcd(ord(c), b) for c in a]


def ordinal_gcd2(a, b):
    return ordinal_gcd1(b, a)


def longest_common_substring(x, y):
    a, b = substrings(x), substrings(y)
    try:
        return max([i for i in a if i in b], key=len)
    except:
        return ''


def num_head(x):
    return int(str(x)[0])


def head(x):
    if not x:
        return x
    return x[0]


def num_tail(x):
    return int(str(x)[-1])


def tail(x):
    if not x:
        return x
    return x[-1]


def num_ind1(x, y):
    s = str(y)[~-int(x) % len(str(y))]
    try:
        return int(s)
    except:
        return s


def indexing_1(num, lst):
    if not lst:
        return lst
    return lst[~-int(num) % len(lst)]


def swapped_ind1(lst, num):
    if not lst:
        return lst
    return lst[~-int(num) % len(lst)]


def length_ind1(x, y):
    return indexing_1(len(str(x)), y)


def vectorised_ind1(x, y):
    r = []
    for i in x:
        try:
            r.append(indexing_1(i, y))
        except:
            r.append(length_ind1(i, y))
    return r


def ljust1(x, n, y):
    return str(y).ljust(abs(int(n)) or 1, (str(x) + ' ')[0])


def ljust2(n, x, y):
    return str(y).ljust(abs(int(n)) or 1, (str(x) + ' ')[0])


def ljust3(x, y, z):
    return str(z).ljust(len(y) or 1, (str(x) + ' ')[0])


def mode(it):
    if not it:
        return it
    return max(it, key=it.count)


def num_mode(n):
    return mode(digits(n))


def negate(x):
    return -x


def rle(s):
    l = ''
    r = []
    for c in s:
        if c == l:
            r[-1] += 1
        else:
            r.append(1)
        l = c
    return r


def index_of(x, y):
    if isinstance(y, str):
        x = str(x)
    if x in y:
        return y.index(x)
    return -1


def swapped_index_of(x, y):
    return index_of(y, x)


def num_index_of(x, y):
    return index_of(x, digits(y))


def vectorised_index_of(x, y):
    r = []
    for i in x:
        if isinstance(y, (str, list)):
            r.append(index_of(i, y))
        else:
            r.append(num_index_of(i, y))


def cartesian_product(x, y):
    return list(map(list, itertools.product(y, x)))


def range_product1(n, y):
    return cartesian_product(list(one_range(n)), y)


def range_product2(x, n):
    return range_product1(n, x)


def range_product3(x, y):
    return cartesian_product(list(one_range(x)), list(one_range(y)))


def first_char_not_present(s, avoid=()):
    i = 0
    while 1:
        if chr(i) in avoid:
            continue
        if chr(i) not in s:
            return chr(i)
        i += 1


def recursive_replace(x, y, z):
    while y in z:
        z = z.replace(y, x)
    return z


def string_repr(s):
    r = repr(s)
    if r[0] == '"':
        return r
    f = first_char_not_present(r, '\\\'"')
    return '"' + recursive_replace(f, '\\\\', r[1:-1]).replace("\\'", "'").replace('"', '\\"').replace(f, '\\\\') + '"'


def list_repr(l):
    x = []
    for i in l:
        if isinstance(i, list):
            x.append(list_repr(i))
        elif isinstance(i, str):
            x.append(string_repr(i))
        else:
            x.append(str(i))
    return '[' + ', '.join(x) + ']'


def sort(l):
    return list(sorted(l))


def digits_sort(n):
    return eval(''.join(str_sort(map(str, digits(n)))))


def str_sort(s):
    return ''.join(sort(s))


def chunk1(x, y):
    return split2(x, one_range(y))


def chunk2(x, y):
    return split2(len(x), y)


def zip_self(l):
    return zip2(l, l)


def num_zip_self(n):
    return zip_self(one_range(n))


def triplicate(x):
    return x, x, x


def assign(c, b, a):
    if not a:
        return a
    if isinstance(a, list):
        a[int(b) % len(a)] = c
        return a
    else:
        a = list(a)
        a[b % len(a)] = c
        return ''.join(map(str, a))


def swapped_assign(c, a, b):
    return assign(c, b, a)


def length_assign(c, b, a):
    return assign(c, len(b), a)


def num_assign(c, b, a):
    return assign(c, b, digits(a))


def vectorised_assign(c, b, a):
    for i in b:
        if isinstance(i, (str, list)):
            a = length_assign(c, i, a)
        else:
            a = assign(c, i, a)
    return a


def to_binary(n):
    if n < 0:
        return '-' + to_binary(abs(n))
    return bin(int(n))[2:]


def ord_bin(s):
    return [to_binary(ord(c)) for c in s]


def combinations1(n, x):
    if n > len(x):
        n = len(x)
    if n < 1:
        n = 1
    return list(map(list, itertools.combinations(x, n)))


def combinations2(x, n):
    return combinations1(n, x)


def combinations3(x, y):
    return combinations1(x, one_range(y))


def set_union(x, y):
    r = []
    for i in y:
        if i not in r:
            r.append(i)
    for j in x:
        if j not in r:
            r.append(j)
    return r


def from_list_of_digits(b, n):
    return from_list_of_digits_2(n, int(b))


def divmod2(x, y):
    return list(divmod(y, x))


def length_range(x):
    return one_range(len(x))


def exclusive_one_range(n):
    return one_range(n)[:-1]


def prime_factor_exponents(n):
    p = prime_factors(n)
    r = []
    for i in range(n + 1):
        if is_prime(i):
            r.append(p.count(i))
    x = r[::-1]
    for k, j in enumerate(x):
        if j:
            return x[k:][::-1]
    return []


def group_consecutive(l):
    last = None
    r = []
    for i in l:
        if i != last:
            r.append([i])
        else:
            r[-1].append(i)
        last = i
    if isinstance(l, str):
        return [*map(''.join, r)]
    return r


def consecutive_digits(n):
    return group_consecutive(digits(n))


def num_head_remove(x):
    return int(str(x)[1:])


def head_remove(x):
    if not x:
        return x
    return x[1:]


def lcm(l):
    l = [int(i) for i in l if isinstance(i, (int, float)) or str(i).isdigit()]
    if not l:
        return 0
    n = 1
    while 1:
        if all(n % j == 0 for j in l):
            return n
        n += 1


def digits_lcm(n):
    return lcm([int(i) for i in str(n) if i in '0123456789'])


def ords_lcm(s):
    return lcm(list(map(ord, s)))


def median(lst):
    l = []
    for i in lst:
        if isinstance(i, (int, float)):
            l.append(i)
        else:
            try:
                l.append(int(i))
            except:
                try:
                    l.append(float(i))
                except:
                    pass
    if not l:
        return []
    if len(l) % 2:
        return sorted(l)[len(l) // 2]
    s = sorted(l)[len(l) // 2 - 1: len(l) // 2 + 1]
    return mean(s)


def num_median(n):
    return median(digits(n))


def ord_median(s):
    return median(list(map(ord, s)))


def round_decimal_places(a, b):
    return round(b, int(a))


def range_intersection1(a, b):
    return [i for i in b if i in one_range(a)]


def range_intersection2(a, b):
    return [i for i in one_range(b) if i in a]


def set_intersection(a, b):
    return [i for i in b if i in a]


def permutations1(n, x):
    if n > len(x):
        n = len(x)
    if n < 1:
        n = 1
    return list(map(list, itertools.permutations(x, n)))


def permutations2(x, n):
    return permutations1(n, x)


def permutations3(x, y):
    return permutations1(x, one_range(y))


def set_difference(x, y):
    r = []
    for i in y:
        if i not in r:
            if i not in x:
                r.append(i)
    return r


def rjust1(x, n, y):
    return str(y).rjust(abs(int(n)) or 1, (str(x) + ' ')[0])


def rjust2(n, x, y):
    return str(y).rjust(abs(int(n)) or 1, (str(x) + ' ')[0])


def rjust3(x, y, z):
    return str(z).rjust(len(y) or 1, (str(x) + ' ')[0])


def prefixes(l):
    r = []
    for i in range(1, len(l) + 1):
        r.append(l[:i])
    return r


def cumsum(l):
    if any(not isinstance(i, (int, float)) for i in l):
        if not all(isinstance(j, list) for j in l):
            l = [*map(str, l)]
    if not l:
        return []
    r = []
    for i in range(1, len(l) + 1):
        r.append(it_sum(l[:i]))
    return r


def numcumsum(n):
    return cumsum(digits(n))


def num_tail_remove(x):
    return int(str(x)[:-1])


def tail_remove(x):
    if not x:
        return x
    return x[:-1]


def chunk3(n, l):
    x, y = len(l), abs(int(n))
    return list(filter(bool, [l[i:i + y] for i in range(0, (x // y + 1) * y, y)]))


def chunk4(l, n):
    return chunk3(n, l)


def chunk5(x, y):
    return chunk3(x, one_range(y))


def chunk6(x, y):
    return chunk3(len(x), y)


def length_range_no_pop(l):
    return (l, one_range(len(l)))


def num_length_range(n):
    return n, one_range(len(str(n)))


def length_range_0(l):
    return (l, lowered_range(len(l)))


def num_length_range_0(n):
    return n, lowered_range(len(str(n)))


def character_multiply1(s, n):
    return ''.join(c * n for c in s)


def character_multiply2(n, s):
    return character_multiply1(s, n)


def regex_split(x, y):
    return re.split(x, y)


def double(x):
    return x * 2


def exactly_not_equal(x, y):
    return int(y != x)


def to_hex(n):
    if n < 0:
        return '-' + to_hex(abs(n))
    return hex(int(n))[2:]


def ord_hex(s):
    return [to_hex(ord(c)) for c in s]


def reciprocal(n):
    return 1 / n


def remove_non_alphabets(s):
    return ''.join(c for c in s if c.isalpha())


def num_bifurcate(n):
    return n, digit_reverse(n)


def bifurcate(x):
    return x, reverse(x)


def fallback_lcm(a, b):
    x, y = abs(int(a)), abs(int(b))
    return (x * y) // dyadic_gcd(x, y)


def dyadic_lcm(a, b):
    try:
        return math.lcm(abs(int(a)), abs(int(b)))
    except:
        try:
            return fallback_lcm(a, b)
        except:
            return 1


def ordinal_lcm1(a, b):
    return [dyadic_lcm(ord(c), b) for c in a]


def ordinal_lcm2(a, b):
    return ordinal_lcm1(b, a)


def ordinal_lcm3(a, b):
    return [dyadic_lcm(ord(x), ord(y)) for x, y in zip(a, b)]


def num_mirror(n):
    r = str(n) + str(n)[::-1]
    try:
        return eval(r)
    except:
        return r


def mirror(x):
    return x + x[::-1]


def str_transliterate(a, b, c):
    for i, j in zip(a, b):
        c = str(c).replace(str(j), str(i))
    return str(c)


def list_transliterate(a, b, c):
    for i, j in zip(a, b):
        c = list_replace(i, j, c)
    return c


def str_transliterate_overload_1(a, b, c):
    for i, j in zip(a, str(b)):
        c = str(c).replace(str(j), str(i))
    return str(c)


def list_transliterate_overload_1(a, b, c):
    for i, j in zip(a, str(b)):
        c = list_replace(i, j, c)
    return c


def str_transliterate_overload_2(a, b, c):
    for i, j in zip(str(a), b):
        c = str(c).replace(str(j), str(i))
    return str(c)


def list_transliterate_overload_2(a, b, c):
    for i, j in zip(str(a), b):
        c = list_replace(i, j, c)
    return c


def str_transliterate_overload_3(a, b, c):
    for i, j in zip(str(a), str(b)):
        c = str(c).replace(str(j), str(i))
    return str(c)


def list_transliterate_overload_3(a, b, c):
    for i, j in zip(str(a), str(b)):
        c = list_replace(i, j, c)
    return c


def combinations_with_replacement1(n, x):
    if n > len(x):
        n = len(x)
    if n < 1:
        n = 1
    return list(map(list, itertools.combinations_with_replacement(x, n)))


def combinations_with_replacement2(x, n):
    return combinations_with_replacement1(n, x)


def combinations_with_replacement3(x, y):
    return combinations_with_replacement1(x, one_range(y))


def combinations_with_replacement4(x, y):
    return combinations_with_replacement1(len(x), y)


def square(n):
    return n ** 2


def chunk_wrap_2(s):
    return chunk3(2, s)


def cube(n):
    return n ** 3


def chunk_wrap_3(s):
    return chunk3(3, s)


def fourth(n):
    return n ** 4


def chunk_wrap_4(s):
    return chunk3(4, s)


def fifth(n):
    return n ** 5


def chunk_wrap_5(s):
    return chunk3(5, s)


def halve(n):
    if n % 2 == 0:
        return n // 2
    return n / 2


def chunk_halve(s):
    return split1(s, 2)


def deltas(lst):
    l = []
    for i in lst:
        if isinstance(i, (int, float)):
            l.append(i)
        else:
            try:
                l.append(int(i))
            except:
                try:
                    l.append(float(i))
                except:
                    pass
    if not l:
        return []
    r = []
    for x, y in zip(l, l[1:]):
        r.append(y - x)
    return r


def digit_deltas(n):
    return deltas(digits(n))


def ord_deltas(s):
    return deltas(list(map(ord, s)))


def digits_wrap(n):
    return [digits(n)]


def list_wrap(s):
    return [[*s]]


def transpose(lst):
    l = []
    for i in lst:
        if isinstance(i, (list, str)):
            l.append(list(i))
        elif isinstance(i, (int, float)):
            l.append(digits(i))
    return list(map(list, zip(*l)))


def rotate_left(n, l):
    if not l:
        return l
    rot = int(n) % len(l)
    return l[rot:] + l[:rot]


def rotate_right(n, l):
    if not l:
        return l
    rot = int(n) % len(l)
    return l[-rot:] + l[:-rot]


def swapped_rotate_left(l, n):
    return rotate_left(n, l)


def swapped_rotate_right(l, n):
    return rotate_right(n, l)


def len_rotate_left(x, y):
    return rotate_left(len(x), y)


def len_rotate_right(x, y):
    return rotate_right(len(x), y)


def num_rotate_left(n, x):
    r = rotate_left(n, str(x))
    try:
        return eval(r)
    except:
        return r


def num_rotate_right(n, x):
    r = rotate_right(n, str(x))
    try:
        return eval(r)
    except:
        return r


def rotate_left_once(l):
    return rotate_left(1, l)


def rotate_right_once(l):
    return rotate_right(1, l)


def num_rotate_left_once(l):
    return num_rotate_left(1, l)


def num_rotate_right_once(l):
    return num_rotate_right(1, l)


def left_bit_shift(x, y):
    if x < 0:
        return right_bit_shift(-x, y)
    return int(y) << int(x)


def right_bit_shift(x, y):
    if x < 0:
        return left_bit_shift(-x, y)
    return int(y) >> int(x)


def uninterleave2(n, l):
    if not n:
        return l
    return [l[i::n] if i < len(l) else l * 0 for i in range(abs(int(n)))]


def num_uninterleave2(x, y):
    return uninterleave2(x, digits(y))


def swapped_uninterleave(l, n):
    return uninterleave2(n, l)


def len_uninterleave(x, y):
    return uninterleave2(len(x), y)


def num_to_alphabet(n):
    return chr(64 + (int(n) % 26))


def alphabet_to_num(s):
    return [
        ord(c) - 64 if 'A' <= c <= 'Z' else (
            ord(c) - 96 if 'a' <= c <= 'z' else 0
        ) for c in s
    ]


def nPr(r, n):
    n, r = int(n), int(r)
    f = math.factorial
    return f(n) // f(n - r)


def string_contains(x, y):
    if isinstance(x, list):
        return [string_contains(i, y) for i in x]
    return int(str(x) in str(y))


def list_contains(x, y):
    if isinstance(x, list):
        return [list_contains(i, y) for i in x]
    return int(x in y)


def list_remove_at_index(n, l):
    if not l:
        return l
    x = l.copy()
    x.pop(int(n) % len(x))
    return x


def str_remove_at_index(n, s):
    return "".join(list_remove_at_index(n, [*str(s)]))


def swapped_list_remove_at_index(l, n):
    return list_remove_at_index(n, l)


def swapped_str_remove_at_index(s, n):
    return str_remove_at_index(n, s)


def unique_prime_factors(n):
    return uniquify_lst(prime_factors(n))


def palindromise(l):
    return l + l[:-1][::-1]


def num_palindromise(n):
    s = palindromise(str(n))
    try:
        return eval(s)
    except:
        return s


def recurse_integer_partitions(n, m=1):
    for i in range(m, n // 2 + 1):
        for part in recurse_integer_partitions(n - i, i):
            yield part + [i]
    yield [n]


def integer_partitions(n):
    n = int(n)
    l = [*recurse_integer_partitions(abs(n))]
    if n < 0:
        return [[-i for i in sl] for sl in l]
    return l


def newline_join(iterable):
    if not isinstance(iterable, list):
        return str(iterable)
    return '\n'.join(map(empty_join, iterable))


def space_join(iterable):
    if not isinstance(iterable, list):
        return str(iterable)
    return ' '.join(map(empty_join, iterable))


def prepend(x, l):
    return [x] + l


def swapped_prepend(l, x):
    return prepend(x, l)


def prepend2(x, y):
    return [x] + _digits(y)


def transpose_with_filler(f, l):
    matrix = [
        [*x] if isinstance(x, (list, str)) else digits(x)
        for x in l
    ]
    transposed = itertools.zip_longest(*matrix, fillvalue=f)
    return list(map(list, transposed))


def swapped_transpose_with_filler(l, f):
    return transpose_with_filler(f, l)


def digits_wrap_2(x, y):
    return y, digits_wrap(x)


def list_wrap_2(x, y):
    return y, list_wrap(x)


def pop_(*_):
    return ()


def boolify(x):
    return int(bool(x))


def counts(l):
    r = []
    for i in uniquify_lst(l):
        r.append([i, l.count(i)])
    return r


def num_counts(n):
    return counts(digits(n))


def parity(n):
    return n % 2


def second_half(s):
    return chunk_halve(s)[-1]


def num_prefixes(n):
    return prefixes(digits(n))


def increment_twice(n):
    return n + 2


def grade_up(l):
    return [*map(lambda x: x[0], sorted(enumerate(l[:]), key=lambda x: x[-1]))]


def head_slice(n, l):
    return l[:n]


def num_head_slice(x, y):
    s = head_slice(x, str(y))
    try:
        return eval(s)
    except:
        return s


def swapped_head_slice(l, n):
    return head_slice(n, l)


def len_head_slice(x, y):
    return head_slice(len(x), y)


def tail_slice(n, l):
    return l[-n:]


def num_tail_slice(x, y):
    s = tail_slice(x, str(y))
    try:
        return eval(s)
    except:
        return s


def swapped_tail_slice(l, n):
    return tail_slice(n, l)


def len_tail_slice(x, y):
    return tail_slice(len(x), y)


def powerset(l):
    r = [l * 0]
    p = [[]]
    for i in l:
        n = [x + [i] for x in p]
        p += [s[:] for s in n]
        for j in n:
            r.append(j if not isinstance(l, str) else "".join(j))
    return r


def num_powerset(n):
    return powerset(one_range(n))


def randint(n):
    if n == 0:
        return 0
    return random.choice(one_range(n))


def randchoice(l):
    if not l:
        return l
    return random.choice(l)


def square_root(i):
    n = abs(i)
    x, y = math.sqrt(n), math.isqrt(n)
    if x == y:
        return y
    return x


def every_second_item(s):
    return s[::2]


def sign(n):
    if n < 0:
        return -1
    elif n > 0:
        return 1
    else:
        return 0


def sentence_case(s):
    r = ''
    b = True
    for c in s:
        if b:
            r += c.upper()
        else:
            r += c.lower()
        if c in '?!.':
            b = True
        elif c == ' ' and b == True:
            pass
        else:
            b = False
    return r


def sum_each(l):
    r = []
    for i in l:
        if isinstance(i, (list, str)):
            r.append(it_sum(i))
        else:
            r.append(digit_sum(i))
    return r


def all_equal(l):
    return int(len({*l}) <= 1)


def num_all_equal(n):
    return all_equal(str(n))


def symmetric_set_difference(x, y):
    r = uniquify_lst([i for i in y if i not in x] + [j for j in x if j not in y])
    if (type(x), type(y)) == (str, str):
        return ''.join(r)
    return r


def range_ssd1(x, y):
    return symmetric_set_difference(digits(x), digits(y))


def range_ssd2(n, x):
    if isinstance(x, str):
        return symmetric_set_difference(str(n), x)
    return symmetric_set_difference(digits(n), x)


def range_ssd3(x, n):
    if isinstance(x, str):
        return symmetric_set_difference(x, str(n))
    return symmetric_set_difference(x, digits(n))


def equals_one(x):
    return int(x == 1)


def enclose(l):
    return l + l[:1]


def num_enclose(n):
    s = enclose(str(n))
    try:
        return eval(s)
    except:
        return s


def add_digits1(l, x):
    return _digits(x) + l


def add_digits2(x, l):
    return l + _digits(x)


def add_digits3(x, y):
    return _digits(y) + _digits(x)


def corresponding_filter(x, y):
    r = []
    for i, j in zip(y, x):
        if j:
            r.append(i)
    if isinstance(y, str):
        return ''.join(r)
    return r


def corresponding_digit_filter_1(x, y):
    return corresponding_filter(digits(x), digits(y))


def corresponding_digit_filter_2(n, l):
    return corresponding_filter(digits(n), l)


def corresponding_digit_filter_3(l, n):
    return corresponding_filter(l, digits(n))


def list_sort_uniquify(l):
    return sort(uniquify_lst(l))


def str_sort_uniquify(s):
    return str_sort(uniquify_str(s))


def num_sort_uniquify(n):
    return list_sort_uniquify(digits(n))


def to_roman_numerals(num):
    ret = ''
    if num < 0:
        num = -num
        ret += '-'
    symbols = {'M': 1000, 'CM': 900, 'D': 500, 'CD': 400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9,
               'V': 5, 'IV': 4, 'I': 1}
    for s, n in symbols.items():
        while num >= n:
            ret += s
            num -= n
    return ret


def from_roman_numerals(s):
    ret = 0
    i = 0
    while i < len(s):
        c = s[i]
        if c == 'M':
            ret += 1000
        elif c == 'D':
            ret += 500
        elif c == 'L':
            ret += 50
        elif c == 'V':
            ret += 5
        elif c == 'C':
            i += 1
            if s[i] == 'M':
                ret += 900
            else:
                ret += 100
                i -= 1
        elif c == 'X':
            i += 1
            if s[i] == 'C':
                ret += 90
            else:
                ret += 10
                i -= 1
        elif c == 'I':
            i += 1
            if s[i] == 'X':
                ret += 9
            else:
                ret += 1
                i -= 1
        i += 1
    return ret


def length_of_each(l):
    r = []
    for i in l:
        if isinstance(i, (int, float)):
            r.append(len(str(i)))
        else:
            r.append(len(i))
    return r


def complement(n):
    return 1 - n


def is_vowel(s):
    return [int(c.lower() in 'aeiou') for c in s]


def islower(s):
    if not s:
        return 1
    return int(s.islower())


def cmp(x, y):
    return sign(y - x)


def zfill1(n, s):
    if n < 0:
        return zfill1(abs(n), s[::-1])[::-1]
    return s.zfill(n)


def zfill2(s, n):
    return zfill1(n, s)


def surround(x, y):
    return x + y + x


def digits_repeat1(n, x):
    return _digits(x) * int(n)


def digits_repeat2(x, n):
    return digits_repeat1(n, x)


def length_repeat1(x, y):
    if isinstance(y, (int, float)):
        y = str(y)
    return x * len(y)


def length_repeat2(x, y):
    if isinstance(x, (int, float)):
        y = str(x)
    return _digits(y) * len(x)


def shuffle(l):
    return random.sample(l, len(l))


def str_shuffle(s):
    return ''.join(shuffle(s))


def range_shuffle(n):
    return shuffle(one_range(n))


def spaces(n):
    return int(n) * ' '


def suffixes(l):
    r = []
    for i in range(1, len(l) + 1):
        r.append(l[-i:])
    return r


def triple_swap(a, b, c):
    return a, c, b


def cartesian_power(n, l):
    return list(map(list, itertools.product(*[l] * abs(int(n)))))


def swapped_cartesian_power(l, n):
    return cartesian_power(n, l)


def range_cartesian_power(x, y):
    return cartesian_power(x, one_range(y))


def head_remove_2(n, l):
    return l[n:]


def num_head_remove_2(x, y):
    s = head_remove_2(x, str(y))
    try:
        return eval(s)
    except:
        return s


def swapped_head_remove_2(l, n):
    return head_remove_2(n, l)


def len_head_remove_2(x, y):
    return head_remove_2(len(x), y)


def tail_remove_2(n, l):
    return l[:-n]


def num_tail_remove_2(x, y):
    s = tail_remove_2(x, str(y))
    try:
        return eval(s)
    except:
        return s


def swapped_tail_remove_2(l, n):
    return tail_remove_2(n, l)


def len_tail_remove_2(x, y):
    return tail_remove_2(len(x), y)


def reverse_each(l):
    r = []
    for i in l:
        if isinstance(i, (str, list)):
            r.append(i[::-1])
        else:
            s = str(i)[::-1]
            try:
                r.append(eval(s))
            except:
                r.append(s)
    return r


def listify(x):
    if isinstance(x, (list, str)):
        return list(copy.deepcopy(x))
    return one_range(x)
