from collections import*
from itertools import*
s = raw_input()
ds = Counter(s)
fac = [1 for i in range(100)]
for i in range(1, 100):
    fac[i] = fac[i-1] * i
res = 0
for possib in product(*[zip([k] * n, range(1, n+1)) for k, n in ds.items()]):
    possib = list(possib)
    non_zero_sum = sum(v for k, v in possib if k != '0')
    total = sum(v for _, v in possib)
    value = non_zero_sum * fac[total-1]
    for _, v in possib:
        value //= fac[v]
    res += value
print(res)

s = input()
occ = [0] * 10
for c in s: occ[int(c)]+= 1
# each digit n which occurred, occurs 1 ~ occ[n] times

# first, ignore leading zeroes
from math import factorial as fact
from itertools import combinations
from collections import Counter
def multinomial(L):
    res = fact(sum(L))
    for x in L: res//= fact(x)

    if L[0] == 0: return res
    L[0]-= 1
    lead0 = fact(sum(L))
    for x in L: lead0//= fact(x)
    L[0]+= 1
    return res - lead0

def dfs(i):
    if i == 10: return multinomial(rocc)
    ans = 0
    for j in range(rocc_ini[i], occ[i]+1):
        rocc[i] = j
        ans+= dfs(i+1)
    return ans

rocc = [0]*10
for i in range(10):
    if occ[i]: rocc[i]+= 1
rocc_ini = rocc[:]
print(dfs(0))

n=input()
#print(len(n))
hsh=[0]*10
for i in n:
    hsh[ord(i)-ord('0')]+=1
#print(hsh)
def f(n):
    if(n<2):
        return 1
    else:
        return n*f(n-1)
ans=0
sea=[]
def rec(table):
    val=int("".join(list(map(str,table))))
    if(val not in sea):
        global ans
        #print(table,ans)
        s=1
        t=sum(table)
        for i in range(10):
            s*=f(table[i])
        minus=1
        if(table[0]>0):
            table[0]-=1
            for i in range(10):
                minus*=f(table[i])
            ans+=(f(t)//s-f(t-1)//minus)
            table[0]+=1
        else:
            ans+=(f(t)//s)
        sea.append(val)
        #print(table,ans,s,f(t))
        for i in range(10):
            if(table[i]>1):
                table[i]-=1
                rec(table)
                table[i]+=1
rec(hsh)
print(ans)

n = input()
all = [0] * 10
for x in n:
	all[int(x)]+=1

dp = [0] * 20
dp[0] = 1
for i in range(1, 10):
	cur = [0] * 20
	if(all[i] > 0):
		for le in range(0, 20):
			fac = 1
			zn = 1
			for kol in range(1, all[i] + 1):
				if(le + kol < 20):
					zn *= le + kol
					fac *= kol
					cur[le + kol] +=  (zn // fac) * dp[le]
		dp = cur

cur = [0] * 20
if(all[0] > 0):
	for le in range(1, 20):
		fac = 1
		zn = 1
		for kol in range(1, all[0] + 1):
			if(le + kol < 20):
				zn *= (le + kol-1)
				fac *= kol
				cur[le + kol] +=  (zn // fac) * dp[le]
	dp = cur

print(sum(dp))

N = input()

C = [0]*10
for n in N:
    C[int(n)] += 1

memo = {}
def dfs(i, state):
    key = tuple(state)
    if key in memo:
        return memo[key]
    r = 0
    if all(s == 0 or 1 <= t for s, t in zip(C, state)):
        r += 1
    for j in range(10):
        if C[j] - state[j] > 0:
            state[j] += 1
            r += dfs(i+1, state)
            state[j] -= 1
    memo[key] = r
    return r
state = [0]*10
ans = 0
for i in range(1, 10):
    if C[i] > 0:
        state[i] += 1
        ans += dfs(1, state)
        state[i] -= 1
print(ans)

n = input()
cnt = [0] * 10
for d in n:
    cnt[int(d)] += 1
m = [0] * 10
ans = 0
def DFS(i : int):
    global ans
    if i == 10:
        pans = 1
        for j in range(sum(m)):
            pans *= j + 1
        for j in range(10):
            for k in range(m[j]):
                pans //= k + 1
        ans += pans
        if m[0]:
            pans = 1
            for j in range(1, sum(m)):
                pans *= j
            for j in range(10):
                for k in range(m[j] - (j == 0)):
                    pans //= k + 1
            ans -= pans
    elif cnt[i] == 0:
        DFS(i + 1)
    else:
        for j in range(0, cnt[i]):
            m[i] = j + 1
            DFS(i + 1)
DFS(0)
print(ans)

from collections import defaultdict as dd
from math import factorial as f

s = input()

cnt = dd(int)

for i in s:
    cnt[i] += 1

ans = 0

def calc(cur_chr, dem, do_not_take_sum, total, diff):
    global ans
    global cnt

    if cur_chr == '9':
        for do_not_take in range(0, cnt[cur_chr] + 1):
            if do_not_take > 0 and do_not_take == cnt[cur_chr]:
                continue

            cur_do_not_take_sum = do_not_take_sum + do_not_take
            if cur_do_not_take_sum == total:
                continue

            cur_dem = dem * f(cnt[cur_chr] - do_not_take)
            num = f(total - cur_do_not_take_sum)

            ans += num // cur_dem * diff
        return

    for do_not_take in range(0, cnt[cur_chr] + 1):
        if do_not_take > 0 and do_not_take == cnt[cur_chr]:
            if not(diff == -1 and cur_chr == '0'):
                continue
        calc(chr(ord(cur_chr) + 1), dem * f(cnt[cur_chr] - do_not_take), do_not_take_sum + do_not_take, total, diff)

calc('0', 1, 0, len(s), 1)

if cnt['0'] != 0:
    cnt['0'] -= 1
    calc('0', 1, 0, len(s) - 1, -1)

print(ans)

# ---------------------------iye ha aam zindegi---------------------------------------------
import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction

mod = 10 ** 9 + 7
mod1 = 998244353

# ------------------------------warmup----------------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# -------------------game starts now----------------------------------------------------import math
class TreeNode:
    def __init__(self, k, v):
        self.key = k
        self.value = v
        self.left = None
        self.right = None
        self.parent = None
        self.height = 1
        self.num_left = 1
        self.num_total = 1

class AvlTree:

    def __init__(self):
        self._tree = None

    def add(self, k, v):
        if not self._tree:
            self._tree = TreeNode(k, v)
            return
        node = self._add(k, v)
        if node:
            self._rebalance(node)

    def _add(self, k, v):
        node = self._tree
        while node:
            if k < node.key:
                if node.left:
                    node = node.left
                else:
                    node.left = TreeNode(k, v)
                    node.left.parent = node
                    return node.left
            elif node.key < k:
                if node.right:
                    node = node.right
                else:
                    node.right = TreeNode(k, v)
                    node.right.parent = node
                    return node.right
            else:
                node.value = v
                return

    @staticmethod
    def get_height(x):
        return x.height if x else 0

    @staticmethod
    def get_num_total(x):
        return x.num_total if x else 0

    def _rebalance(self, node):

        n = node
        while n:
            lh = self.get_height(n.left)
            rh = self.get_height(n.right)
            n.height = max(lh, rh) + 1
            balance_factor = lh - rh
            n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
            n.num_left = 1 + self.get_num_total(n.left)

            if balance_factor > 1:
                if self.get_height(n.left.left) < self.get_height(n.left.right):
                    self._rotate_left(n.left)
                self._rotate_right(n)
            elif balance_factor < -1:
                if self.get_height(n.right.right) < self.get_height(n.right.left):
                    self._rotate_right(n.right)
                self._rotate_left(n)
            else:
                n = n.parent

    def _remove_one(self, node):
        """
        Side effect!!! Changes node. Node should have exactly one child
        """
        replacement = node.left or node.right
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = replacement
            else:
                node.parent.right = replacement
            replacement.parent = node.parent
            node.parent = None
        else:
            self._tree = replacement
            replacement.parent = None
        node.left = None
        node.right = None
        node.parent = None
        self._rebalance(replacement)

    def _remove_leaf(self, node):
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = None
            else:
                node.parent.right = None
            self._rebalance(node.parent)
        else:
            self._tree = None
        node.parent = None
        node.left = None
        node.right = None

    def remove(self, k):
        node = self._get_node(k)
        if not node:
            return
        if AvlTree._is_leaf(node):
            self._remove_leaf(node)
            return
        if node.left and node.right:
            nxt = AvlTree._get_next(node)
            node.key = nxt.key
            node.value = nxt.value
            if self._is_leaf(nxt):
                self._remove_leaf(nxt)
            else:
                self._remove_one(nxt)
            self._rebalance(node)
        else:
            self._remove_one(node)

    def get(self, k):
        node = self._get_node(k)
        return node.value if node else -1

    def _get_node(self, k):
        if not self._tree:
            return None
        node = self._tree
        while node:
            if k < node.key:
                node = node.left
            elif node.key < k:
                node = node.right
            else:
                return node
        return None

    def get_at(self, pos):
        x = pos + 1
        node = self._tree
        while node:
            if x < node.num_left:
                node = node.left
            elif node.num_left < x:
                x -= node.num_left
                node = node.right
            else:
                return (node.key, node.value)
        raise IndexError("Out of ranges")

    @staticmethod
    def _is_left(node):
        return node.parent.left and node.parent.left == node

    @staticmethod
    def _is_leaf(node):
        return node.left is None and node.right is None

    def _rotate_right(self, node):
        if not node.parent:
            self._tree = node.left
            node.left.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.left
            node.left.parent = node.parent
        else:
            node.parent.right = node.left
            node.left.parent = node.parent
        bk = node.left.right
        node.left.right = node
        node.parent = node.left
        node.left = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    def _rotate_left(self, node):
        if not node.parent:
            self._tree = node.right
            node.right.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.right
            node.right.parent = node.parent
        else:
            node.parent.right = node.right
            node.right.parent = node.parent
        bk = node.right.left
        node.right.left = node
        node.parent = node.right
        node.right = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    @staticmethod
    def _get_next(node):
        if not node.right:
            return node.parent
        n = node.right
        while n.left:
            n = n.left
        return n
avl=AvlTree()
#-----------------------------------------------binary seacrh tree---------------------------------------
class SegmentTree1:
    def __init__(self, data, default='z', func=lambda a, b: min(a ,b)):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------game starts now----------------------------------------------------import math
class SegmentTree:
    def __init__(self, data, default=0, func=lambda a, b: a + b):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------------------iye ha chutiya zindegi-------------------------------------
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]

    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]

    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]

    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]

class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)

    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

# --------------------------------------iye ha combinations ka zindegi---------------------------------
def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

# --------------------------------------iye ha power ka zindegi---------------------------------
def sort_list(list1, list2):
    zipped_pairs = zip(list2, list1)

    z = [x for _, x in sorted(zipped_pairs)]

    return z

# --------------------------------------------------product----------------------------------------
def product(l):
    por = 1
    for i in range(len(l)):
        por *= l[i]
    return por

# --------------------------------------------------binary----------------------------------------
def binarySearchCount(arr, n, key):
    left = 0
    right = n - 1

    count = 0

    while (left <= right):
        mid = int((right + left)/ 2)

        # Check if middle element is
        # less than or equal to key
        if (arr[mid]<=key):
            count = mid+1
            left = mid + 1

        # If key is smaller, ignore right half
        else:
            right = mid - 1

    return count

# --------------------------------------------------binary----------------------------------------
def countdig(n):
    c = 0
    while (n > 0):
        n //= 10
        c += 1
    return c

def countGreater( arr,n, k):
    l = 0
    r = n - 1

    # Stores the index of the left most element
    # from the array which is greater than k
    leftGreater = n

    # Finds number of elements greater than k
    while (l <= r):
        m = int(l + (r - l) / 2)
        if (arr[m] >= k):
            leftGreater = m
            r = m - 1

        # If mid element is less than
        # or equal to k update l
        else:
            l = m + 1

    # Return the count of elements
    # greater than k
    return (n - leftGreater)

# --------------------------------------------------binary------------------------------------
l=[]
def fact(t):
    r=1
    for i in range(1,t+1):
        r*=i
    return r
def calc(d,t,s,r,ans,k):
    if t==len(l):
        if k>0:
            ans+=(fact(s-1)*(s-k))//r
        else:
            ans+=fact(s)//r
        #print(s,r,ans)
        return ans
    for i in range(d[l[t]]):
        if l[t]==0:
            k=i+1
        ans=calc(d,t+1,s+i+1,r*fact(i+1),ans,k)
    return ans
n=input()
d=defaultdict(int)
for i in range(len(n)):
    d[int(n[i])]+=1
l=list(d.keys())
ans=calc(d,0,0,1,0,0)
print(ans)

a=[]
fact=[]

def find(num,val,cnt):
    global ans
    if num==10:
        ans+=val*fact[cnt]
        #print(val,cnt,fact[cnt],ans)
        return
    if a[num]>=1:
        i=1
        while i<=a[num]:
            num+=1
            val=val/fact[i]
            cnt+=i
            find(num,val,cnt)
            num-=1
            val=val*fact[i]
            cnt-=i
            i+=1
    else:
        num+=1
        find(num,val,cnt)
        num-=1

def find1(num,val,cnt):
    global ans
    if num==10:
        ans-=val*fact[cnt]
        return
    if a[num]>=1:
        i=1
        if num==0:
            i=0
        while i<=a[num]:
            num+=1
            val=val/fact[i]
            cnt+=i
            find1(num,val,cnt)
            num-=1
            val=val*fact[i]
            cnt-=i
            i+=1
    else:
        num+=1
        find1(num,val,cnt)
        num-=1

n=int(input())
for i in range(10):
    a.append(0)
fact.append(1)
for i in range(1,20):
    fact.append(fact[i-1]*i)
m=n
while m>0:
    a[m%10]+=1
    m=m//10
ans=0
find(0,1,0)
#print(ans)
if a[0]!=0:
    a[0]-=1
    find1(0,1,0)
print(int(ans))

def faktorijel(num):
    if num == 0:
        return 1
    x = 1
    for i in range(1, num+1):
        x *= i
    return x
n = list(input())
znams = [0,0,0,0,0,0,0,0,0,0]
for i in n:
    znams[int(i)] += 1
#print(znams)
broj = 0
for broj0 in range(min(znams[0],1), max(1,znams[0]+1)):
    for broj1 in range(min(znams[1],1), max(1,znams[1]+1)):
        for broj2 in range(min(znams[2],1), max(1,znams[2]+1)):
            for broj3 in range(min(znams[3],1), max(1,znams[3]+1)):
                for broj4 in range(min(znams[4],1), max(1,znams[4]+1)):
                    for broj5 in range(min(znams[5],1), max(1,znams[5]+1)):
                        for broj6 in range(min(znams[6],1), max(1,znams[6]+1)):
                            for broj7 in range(min(znams[7],1), max(1,znams[7]+1)):
                                for broj8 in range(min(znams[8],1), max(1,znams[8]+1)):
                                    for broj9 in range(min(znams[9],1), max(1,znams[9]+1)):
                                        #print("vrtise")
                                        y = faktorijel(broj0+broj1+broj2+broj3+broj4+broj5+broj6+broj7+broj8+broj9)/(faktorijel(broj0)*faktorijel(broj1)*faktorijel(broj2)*faktorijel(broj3)*faktorijel(broj4)*faktorijel(broj5)*faktorijel(broj6)*faktorijel(broj7)*faktorijel(broj8)*faktorijel(broj9))
                                        #print(broj0, broj1, broj2, broj3, broj4, broj5, broj6, broj7, broj8, broj9)
                                        #print(broj)
                                        broj += y
                                        if broj0 != 0:
                                            x = faktorijel(broj0-1+broj1+broj2+broj3+broj4+broj5+broj6+broj7+broj8+broj9)/(faktorijel(broj0-1)*faktorijel(broj1)*faktorijel(broj2)*faktorijel(broj3)*faktorijel(broj4)*faktorijel(broj5)*faktorijel(broj6)*faktorijel(broj7)*faktorijel(broj8)*faktorijel(broj9))
                                            broj += -x
print(int(broj))
#print(29340299842560)

factorial_array=[1]
for x in range(1,20):
    factorial_array.append(factorial_array[-1]*x)
def factorial(x):
    global factorial_array
    return factorial_array[x]

def generate(array):
    start=factorial(sum(array))
    for x in range(10):
        start//=factorial(array[x])
    return start

def main():
    string=input()
    store=[0 for x in range(10)]
    for x in range(len(string)):
        store[int(string[x])]+=1
    all_possible=[[]]
    for x in range(10):
        next_all_possible=[]
        for y in all_possible:
            if store[x]==0:
                next_all_possible.append(y+[0])
            else:
                for z in range(1,store[x]+1):
                    next_all_possible.append(y+[z])
        all_possible=next_all_possible.copy()
    total=0
    for x in all_possible:
        #print(x)
        total+=(generate(x))
        if x[0]>0:
            x[0]-=1
            total-=(generate(x))
    print(total)
main()

from collections import defaultdict
from copy import deepcopy

a = list(input())

d = defaultdict(int)
for x in a:
    d[int(x)] += 1

fact_mem = {}

def fact(n):
    if n in fact_mem:
        return fact_mem[n]
    ans = 1
    for i in range(1, n + 1):
        ans *= i
    fact_mem[n] = ans
    return ans

mem = {}

def f(d):
    tmp = frozenset(d.items())
    if tmp in mem:
        return 0
    n = sum(d.values())
    ans = 0
    if d[0] > 0:
        ans += (n - d[0]) * fact(n - 1)
    else:
        ans += fact(n)
    if len(d) == 1 and d[0] > 0:
        return 0
    for x in d:
        ans //= fact(d[x])
    for k in d:
        if d[k] > 1:
            e = deepcopy(d)
            e[k] -= 1
            ans += f(e)
    mem[frozenset(d.items())] = ans
    return ans

ans = f(d)
print(ans)

#!/usr/bin/env python3

from itertools import product
from operator import mul
from functools import reduce

n = input().strip()
c0 = n.count('0')
cc = [n.count(str(i)) for i in range(10)]
cc = [c for c in cc if c > 0]

facs = [1]
for i in range(1, 20):
	facs.append(facs[-1] * i)

def prod(p):
	return reduce(mul, p, 1)

def getC(p):
	return facs[sum(p)] // prod(facs[pp] for pp in p)

def getcount(ct, a0=False):
	its = [range(1 - int(a0), ct[0] + 1)] + [range(1, cti + 1) for cti in ct[1:]]
	return sum(getC(p) for p in product(*its))

if c0 == 0:
	res = getcount(cc)
elif c0 == 1:
	ccr = list(cc)
	del ccr[0]
	res = getcount(cc) - getcount(ccr)
else:
	ccr = list(cc)
	ccr[0] -= 1
	res = getcount(cc) - getcount(ccr, True)

print (res)

from collections import defaultdict

n = [int(i) for i in input()]
st = frozenset(n)
ini = [n.count(i) for i in range(10)]
dp = defaultdict(int)

def dfs(state):
    key = tuple(state)
    if key in dp:
        return dp[key]

    if all(state[i] > 0 for i in st):
        dp[key] += 1

    for i in range(10):
        if state[i] < ini[i]:
            state[i] += 1
            dp[key] += dfs(state)
            state[i] -= 1
    return dp[key]

ans = 0
s = [0] * 10
for i in range(1, 10):
    if ini[i]:
        s[i] = 1
        ans += dfs(s)
        s[i] = 0

print(ans)

# -*- coding: utf-8 -*-
"""
Created on Sun Jun 24 09:48:08 2018

@author: yanni
"""

import math

fact = [math.factorial(x) for x in range(20)]

def product(L):
    ans = 1
    for i in L:
        ans *= i
    return ans

def count(digits):
    s = sum(digits)
    return fact[s] // product([fact[i] for i in digits])

n = input()

strn = str(n)
digs = [0 for i in range(10)]
for let in strn:
    dig = int(let)
    digs[dig] += 1

zeroes = digs[0]
others = digs[1:]
while (0 in others):
    others.remove(0)
digs = [zeroes]+others

def answer(digits, chosen = []):
    ans = 0
    if (digits == []):
        return helper(chosen)
    if (digits[0] == 0):
        return answer(digits[1:], chosen + [0])
    for i in range(1, digits[0]+1):
        ans += answer(digits[1:], chosen + [i])
    return ans

def helper(chosen):
    if chosen[0] == 0:
        return count(chosen)
    alt = chosen.copy()
    alt[0] -= 1
    return count(chosen)-count(alt)

print(answer(digs))

import math
from collections import defaultdict

dp = dict()
fact = dict()

def facto(val) :
	if val not in fact.keys() :
		fact[val] = math.factorial(val)
	return fact[val]

def hitung(frek, total) :
	global dp
	keys = ' '.join(str(x) for x in frek)
	if keys in dp.keys() :
		dp[keys] = 0
		return dp[keys]
	ans = 0
	for i in range(1, 10) :
		if frek[i] > 0 :
			tmp = facto(total) // facto(frek[i]-1)
			for j in range(0, 10) :
				if i!=j and frek[j]>0 :
					tmp //= facto(frek[j])
			ans += tmp
	for i in range(0, 10) :
		if frek[i]>1 :
			frek[i] -=1
			ans += hitung(frek, total-1)
			frek[i] += 1
	dp[keys] = ans
	return ans;

n = int(input())
if(n<10) :
	print(1)
else :
	tmp = n;
	frek = [ 0 for _ in range(10)]
	total = 0
	while tmp>0 :
		frek[tmp%10]+=1
		tmp //= 10
		total += 1
	print(hitung(frek, total-1))

def fact(x):
    i = 2
    res = 1
    while i <= x:
        res = res * i
        i = i + 1
    return res

inp = input()
arr = []
for i in range(len(inp)):
    arr.append(int(inp[i]))

have = [0] * 10
for i in range(len(arr)):
    have[arr[i]] = have[arr[i]] + 1

cur = [0] * 10

def add(n):
    res = 0
    for i in range(1, 10):
       if cur[i] > 0:
           cur[i] = cur[i] - 1
           now = fact(n - 1)
           for j in range(10):
               now = now // fact(cur[j])
           res = res + now
           cur[i] = cur[i] + 1
    return res

def rec(i, n):
    if i == 10:
        return add(n)
    else:
        if have[i] == 0:
            return rec(i + 1, n)
        else:
            res = 0
            for t in range(1, have[i] + 1):
                cur[i] = t
                res = res + rec(i + 1, n + t)
        return res

print(rec(0, 0))

a = map(int,input());
cnts = [0]*10;
for aa in a:
    cnts[aa]+=1

mem = {}

mem[(1,0,0,0,0,0,0,0,0,0)] = 0;

for i in range(1,10):
   mem[(0,)*(i) + (1,) + (0,)*(10-i-1)] = 1;

def get(a):
    if (tuple(a) in mem):
        return mem[tuple(a)]
    else:
        aa = list(a)
        tot = 0
        for i in range(0,10):
            if (a[i] != 0):
                aa[i] -= 1;
                tot += get(aa);
                aa[i] += 1;
        mem[tuple(a)] = tot
        return tot

bigTot = 0

def goThrough(pre, post):
    global bigTot
    if (len(post) == 0) :
        bigTot += get(pre)
    elif (post[0] == 0):
        goThrough(pre + (0,) , post[1:])
    else:
        for i in range(1,post[0]+1):
            goThrough(pre + (i,) , post[1:])

goThrough((), cnts)

print(bigTot)

a = int(input())
b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
while a != 0:
    b[a % 10] += 1
    a //= 10

ans = 0

def fact(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

def f(n, arr):
    #print(arr)
    global ans
    if n == 10:
        sum = 0
        for i in range(10):
            sum += arr[i]
        temp = 1
        temp *= sum - arr[0]
        #print(temp)
        temp *= fact(sum - 1)
        #print(temp)
        for i in range(10):
            if arr[i] > 1:
                temp //= fact(arr[i])

        ans += temp
        #print(ans)
    else:
        if b[n] > 0:
            for i in range(1, b[n] + 1):
                temp = arr.copy()
                temp.append(i)
                f(n + 1, temp)
        else:
            arr.append(0)
            f(n + 1, arr)

f(0, [])
print(int(ans))

from functools import reduce as d
import operator as o
import itertools as Z
r,s,M,S,f=range,str(input()),map,sum,lambda x:d(o.mul,r(1,x+1),1)
print S((f(S(x))-(f(S(x)-1)*x[0]))/d(o.mul,M(f,x))for x in Z.product(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

import itertools as I;m,d,r,s,M,S,f=lambda x,y:x*y,reduce,range,raw_input(),map,sum,lambda x:d(m,r(1,x+1),1);print S((f(S(x))-f(S(x)-1)*x[0])/d(m,M(f,x))for x in I.product(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

def fact(n):
    global fa
    if fa[n] != -1:
        return fa[n]
    else:
        fa[n] = fact(n - 1) * n
        return fa[n]
fa = [-1] * 20
fa[0] = 1
fa[1] = 1
fa[2] = 2

res = 0

a = int(input())
b = str(a)
s = [0] * 10
for i in range(len(b)):
    s[int(b[i])] += 1

for i0 in range(s[0] + 1):
    if i0 > 0 or s[0] == 0:
        for i1 in range(s[1] + 1):
            if i1 > 0 or s[1] == 0:
                for i2 in range(s[2] + 1):
                    if i2 > 0 or s[2] == 0:
                        for i3 in range(s[3] + 1):
                            if i3 > 0 or s[3] == 0:
                                for i4 in range(s[4] + 1):
                                    if i4 > 0 or s[4] == 0:
                                        for i5 in range(s[5] + 1):
                                            if i5 > 0 or s[5] == 0:
                                                for i6 in range(s[6] + 1):
                                                    if i6 > 0 or s[6] == 0:
                                                        for i7 in range(s[7] + 1):
                                                            if i7 > 0 or s[7] == 0:
                                                                for i8 in range(s[8] + 1):
                                                                    if i8 > 0 or s[8] == 0:
                                                                        for i9 in range(s[9] + 1):
                                                                            if i9 > 0 or s[9] == 0:
                                                                                w2 = [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
                                                                                su = 0
                                                                                for i in range(10):
                                                                                su += w2[i]
                                                                                for i in range(1, 10):
                                                                                if w2[i] > 0:
                                                                                w2[i] -= 1
                                                                                su -= 1

                                                                                res += fact(su)/(fact(w2[0]) * fact(w2[1]) * fact(w2[2]) * fact(w2[3]) * fact(w2[4]) * fact(w2[5]) * fact(w2[6]) * fact(w2[7]) * fact(w2[8]) * fact(w2[9]))

                                                                                su += 1
                                                                                w2[i] += 1
print(int(res))

from math import factorial as fac
def generate_poslist(lis,length):
    if length==0:
        return [[]]
    elems=lis[0]
    temp=lis.pop(0)
    recval=generate_poslist(lis,length-1)
    ansl=[]
    for anyl in recval:
        ansl.extend(list(map(lambda x:[x]+anyl,elems)))
    return ansl
def getsum(l):
    sumfac=fac(sum(l))
    prod=1
    for e in l:
        prod=prod*fac(e)
    return sumfac/prod

wnum=input('')
digdic=dict()
for dig in wnum:
    digdic[dig]=digdic.get(dig,0)+1
#check how to check whther sometinh is a number or a list
baselist=[]
for (key,val) in digdic.items():
    baselist.append(list(range(1,val+1)))
possibility_list=generate_poslist(baselist,len(baselist))
sum1=0
sum2=0
for lis in possibility_list:
    sum1+=getsum(lis)
forzero=digdic.get('0',0);
if forzero!=0:
    if forzero==1:
        del digdic['0']
    else:
        digdic['0']=forzero-1
    baselist=[]
    for (key,val) in digdic.items():
        if key=='0':
            baselist.append(list(range(0,val+1)))
            continue
        baselist.append(list(range(1,val+1)))
    possibility_list=generate_poslist(baselist,len(baselist))

    for lis in possibility_list:
        sum2+=getsum(lis)
print(int(sum1-sum2))

import itertools as I;d,m,t,r,s,M,F=reduce,map,sum,range,raw_input(),lambda x,y:x*y,lambda x:d(M,r(1,x+1),1);print(t(F(t(x))//d(M,m(F,x))-F(t(x)-1)*x[0]//d(M,m(F,x))*(x[0]>0)for x in I.product(*[r(y and 1,y+1)for y in[s.count(str(c))for c in r(10)]])))

n = int(input())

num = []
tmp = []
a = []
F = []
res = 0

F.append(1)
for i in range(1, 20) : F.append(F[i - 1] * i)

def cal(cnt, flag) :
	amo = 0
	ret = 1
	for i in a :
		ret *= F[i]
		amo += i
	ret = F[amo] // ret
	if flag :
		a[0] -= 1
		ret -= cal(cnt, False)
		a[0] += 1
	return ret

def dfs(now, cnt, flag) :
	if now == cnt :
		return cal(cnt, flag)
	ret = 0
	for i in range(1, tmp[now] + 1) :
		a[now] = i
		ret += dfs(now + 1, cnt, flag)
	return ret

for i in range(0, 10) : num.append(0)

while n > 0 :
	num[n % 10] += 1
	n //= 10

for i in num :
	if i > 0 : tmp.append(i)

cnt = len(tmp)
for i in range(0, cnt) : a.append(0)
flag = bool(num[0] > 0)

print(dfs(0, cnt, flag))

import itertools as I;m,d,r,s,M,S,f=lambda x,y:x*y,reduce,range,raw_input(),map,sum,lambda x:d(m,r(1,x+1),1);print S(f(S(x)-1)*(S(x)-x[0])/d(m,M(f,x))for(x)in I.product(*[r(y and 1,y+1)for y in[s.count(str(u))for u in r(10)]]))

from itertools import chain, combinations
from collections import defaultdict
import math

def powerset(iterable):
    xs = iterable
    return chain.from_iterable(combinations(xs,n) for n in range(1, len(xs)+1))

def has(s):
	h = 1
	p = [2,3,5,7,11,13,17,19,23,29]
	for i in s:
		h *= p[i-1]
	return h

h = set()
total = 0
inp = input().strip()
if int(inp) == 1000000000000000000:
	print(18)
else:
	ok = [int(i) for i in inp]
	require = set(ok)

	for s in powerset(ok):
		if has(s) in h:
			continue

		h.add(has(s))

		d = defaultdict(int)
		prod = 1
		for c in s:
			d[c] += 1
			prod *= d[c]

		flag = False
		for i in require:
			if d[i] == 0:
				flag = True
				break
		if flag: continue

		n = len(s)
		total += (n-d[0])*math.factorial(n-1)/prod

	print(int(total))

import itertools as I;a,d,m,S,r,M,F=raw_input(),reduce,map,sum,range,lambda x,y:x*y,lambda x:d(M,r(1,x+1),1);print S(F(S(x)-1)*(S(x)-x[0])/d(M,m(F,x))for x in I.product(*[r(y>0,y+1)for y in[a.count(str(c))for c in r(10)]]))

from math import factorial as f
from functools import reduce as d
from operator import mul as m
from itertools import product as p
u,t,r,s=map,sum,range,input()
a=[s.count(str(d))for d in r(10)]
print(t(f(t(x))//d(m,u(f,x))-f(t(x)-1)*x[0]//d(m,u(f,x))*(x[0]>0) for x in p(*[r(y and 1,y+1)for y in a])))

from math import factorial as f
from functools import reduce as d
from operator import mul as m
from itertools import product as p
u,t,r,s=map,sum,range,input()
print(t(f(t(x))//d(m,u(f,x))-f(t(x)-1)*x[0]//d(m,u(f,x))*(x[0]>0)for x in p(*[r(y and 1,y+1)for y in [s.count(str(d))for d in r(10)]])))

import itertools as I;a,d,m,S,r,M,F=raw_input(),reduce,map,sum,range,lambda x,y:x*y,lambda x:d(M,r(1,x+1),1);print S(F(S(x)-1)*(S(x)-x[0])/d(M,m(F,x))for x in I.product(*[r(y and 1,y+1)for y in[a.count(str(c))for c in r(10)]]))

m = raw_input()
n=len(m)

po=[0 for i in range(10)]
for x in m:
    po[int(x)]+=1

def insert(x,n):
    def fac(t):
        if t==0 or t==1:
            return 1
        b=1
        for i in range(2,t+1):
            b*=i
        return b
    return fac(x+n)/fac(x)/fac(n)

def insert0(x,n):
    def fac(t):
        if t==0 or t==1:
            return 1
        b=1
        for i in range(2,t+1):
            b*=i
        return b
    return fac(x+n)/fac(x)/fac(n)-fac(x+n-1)/fac(x-1)/fac(n)
i=1
while i<len(po):
    if po[i]==0:
        po.pop(i)
    else:
        i+=1
#print po
ct=[[0 for i in range(sum(po)+1)] for j in  range(len(po)+1)]

ct[len(po)][0]=1

s=0
d=0
for i in range(len(po)-1,0,-1):
    for x in range(1,po[i]+1):
        for y in range(d,s+1):
            #print i,x,y
            ct[i][x+y]+=insert(x,y)*ct[i+1][y]
    s+=po[i]
    d+=1
if po[0]==0:
    print sum(ct[1])
    exit()
for x in range(1,po[0]+1):
    for y in range(d,s+1):
        ct[0][x+y]+=insert0(x,y)*ct[1][y]
print sum(ct[0])
exit()

from __future__ import print_function
import sys
import math
import os.path
import random
from copy import deepcopy
from functools import reduce
from collections import Counter, ChainMap, defaultdict
from itertools import cycle, chain
from queue import Queue, PriorityQueue
from heapq import heappush, heappop, heappushpop, heapify, heapreplace, nlargest, nsmallest
import bisect
from statistics import mean, mode, median, median_low, median_high
# CONFIG
sys.setrecursionlimit(1000000000)
# LOG
def log(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)
# INPUT
def ni():
    return map(int, input().split())
def nio(offset):
    return map(lambda x: int(x) + offset, input().split())
def nia():
    return list(map(int, input().split()))
# CONVERT
def toString(aList, sep=" "):
    return sep.join(str(x) for x in aList)
def toMapInvertIndex(aList):
    return {k: v for v, k in enumerate(aList)}
# SORT
def sortId(arr):
    return sorted(range(arr), key=lambda k: arr[k])
# MATH
def gcd(a,b):
    while b:
        a, b = b, a % b
    return a
# MAIN

x = input()

gt = [1]*20

for i in range(1,len(gt)):
    gt[i] = i * gt[i-1]

# log(gt)

count = [0]*10

for i in x:
    count[ord(i) - ord('0')] += 1

# log(count)

s = 0

select = [0]*10

def calc2():
    global s
    n = sum(select)
    gs = gt[n]
    for i in range(10):
        gs //= gt[select[i]]
    # log("c2", n, select, gs)
    s += gs

def calc():
    global select
    n = sum(select) - select[0]
    # log("calc",n, select)
    if n > 0:
        for i in range(1,10):
            # log("calc",i,select[i])
            if (select[i] > 0):
                select[i] -= 1
                calc2()
                select[i] += 1

def find(i):
    # log("find",i)
    global select
    if i > 9:
        calc()
    else:
        if count[i] == 0:
            find(i+1)
        else:
            for j in range(1,count[i]+1):
                select[i] = j
                find(i+1)

find(0)

print(s)

from collections import defaultdict
num = raw_input().strip()
d = defaultdict(int)
for i in range(len(num)):
	d[int(num[i])] += 1
# print d

factorial = [1]*20

for i in range(2,20):
	factorial[i] = factorial[i-1]*i
t = 0

v = [[]]
keys = [i for i in d]
keys.sort()
for i in keys:
	v = [v[j] + [k] for j in range(len(v)) for k in range(1,d[i]+1)]
# print keys
for arr in v:
	total = 0
	if keys[0] == 0:
		for k in range(1,len(keys)):
			subtotal = factorial[sum(arr)-1]
			for i in range(len(arr)):
				if i == k:
					subtotal = subtotal / factorial[arr[i]-1]
				else:
					subtotal = subtotal / factorial[arr[i]]
			total += subtotal
	else:
		total = factorial[sum(arr)]
		for i in range(len(arr)):
			total  = total / factorial[arr[i]]
	t += total

print t

from math import factorial as f;from functools import reduce as d;from operator import mul as m;from itertools import product as p;u,t,r,s=map,sum,range,input();print(t(f(t(x))//d(m,u(f,x))-f(t(x)-1)*x[0]//d(m,u(f,x))*(x[0]>0)for x in p(*[r(y and 1,y+1)for y in[s.count(str(d))for d in r(10)]])))

from math import factorial as f
from functools import reduce as d
from operator import mul as m
from itertools import product as p
u,t,r,s=map,sum,range,input()
b=lambda x:d(m,u(f,x))
a=[s.count(str(d))for d in r(10)]
print(t(f(t(x))//b(x)-(f(t(x)-1)*x[0]//b(x)if x[0] else 0)for x in p(*[r(1-(not y),y+1)for y in a])))

from operator import mul as m;from itertools import product as p;d,r,s,M,S,f=reduce,range,str(input()),map,sum,lambda x:d(m,r(x,1,-1),1);print S((f(S(x))-(f(S(x)-1)*x[0]))/d(m,M(f,x))for x in p(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

def main():
    ast = []
    def fact(x):
        if x == 0:
            return 1
        return x * fact(x - 1)
    n = input()
    def helper(dc):
        a = 0
        temp = [dc[j] for j in dc if j != '0']
        s = sum(temp)
        try:
            ret = fact(s) * fact(s + dc['0'] - 1) // (fact(s - 1) * fact(dc['0']))
        except:
            ret = fact(s)
        for i in temp:
            ret = ret // fact(i)
        for i in dc:
            if dc[i] != 1:
                d = {}
                for j in dc:
                    d[j] = dc[j]
                d[i] -= 1
                if str(d) not in ast:
                    ast.append(str(d))
                    a += helper(d)
        return ret + a
    dct = {}
    for i in set(n):
        dct[i] = n.count(i)
    print(helper(dct))
    return 0
main()

def cbnum(n, k):
	ans = 1
	for i in range(1,k+1):
		ans = ans * n / i
		n -= 1
	return ans

def getans(cnt, flag):
	up_bound = sum(cnt)
	f = [0]*(up_bound+1)
	f[0] = 1
	for w in range(0,10):
		x = cnt[w]
		if x > 0:
			g = f
			f = [0]*(up_bound+1)
			st = 0 if flag and w == 0 else 1
			for j in range(st,x+1):
				for i in range(0,up_bound+1):
					if g[i] > 0 and i+j <= up_bound:
						f[i+j] += g[i] * cbnum(i+j, j)
			#print f
	return sum(f[1:])

n = int(raw_input())

cnt = [0]*10
while n > 0:
	cnt[n % 10] += 1
	n /= 10

ans = getans(cnt, False)
if cnt[0] > 0:
	cnt[0] -= 1
	#print ans, getans(cnt, True)
	ans -= getans(cnt, True)
print ans
#low_bound = sum( map(lambda x: 1 if x > 0 else 0, cnt) )
#for l in range(low_bound, up_bound+1):

from operator import mul as m;from itertools import product as p;d,r,s,M,S,f=reduce,range,str(input()),map,sum,lambda x:d(m,r(x,1,-1),1);print S((f(S(x))-f(S(x)-1)*x[0])/d(m,M(f,x))for x in p(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

from functools import reduce as d
from operator import mul as m
from itertools import product as p
r,s,M,S,f=range,str(input()),map,sum,lambda x:reduce(m,r(1,x+1),1)
print S((f(S(x))-(f(S(x)-1)*x[0]))//d(m,M(f,x))for x in p(*[r(y//max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

import math

def get_n_vars_when_amounts_fixed(a):
	# print("a", a)
	t = math.factorial(sum(a[1:]))
	for i in range(1, len(a)):
		t = t // math.factorial(a[i])

	for i in range(a[0]):
		# print(t)
		t *= (sum(a[1:]) + i);
	t //= math.factorial(a[0])
	# print("t", t)
	return t

def gen(a, b, pos):
	if pos == 10:
		return get_n_vars_when_amounts_fixed(b)

	if a[pos] == 0:
		b[pos] = 0
		return gen(a, b, pos + 1)

	ans = 0
	for i in range(1, a[pos] + 1):
		b[pos] = i
		ans += gen(a, b, pos + 1)

	return ans

a = [0] * 10
s = input()
for ch in s:
	a[int(ch)] += 1

# print(a)

b = [0] * 10
ans = gen(a, b, 0)

print(ans)

r,s=range,str(input())
a=[s.count(str(d)) for d in r(10)]
from math import factorial as f
from functools import reduce as rd
from operator import mul as m
from itertools import product as p
print(sum(f(sum(x))//reduce(m,map(f,x))-(f(sum(x)-1)*x[0]//reduce(m,map(f,x)) if x[0] else 0) for x in p(*[r(0 if not y else 1,y+1) for y in a])))

from itertools import product as p;m,d,r,s,M,S,f=lambda x,y:x*y,reduce,range,str(input()),map,sum,lambda x:d(m,r(x,1,-1),1);print S((f(S(x))-f(S(x)-1)*x[0])/d(m,M(f,x))for x in p(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

import itertools as I;m,d,r,s,M,S,f=lambda x,y:x*y,reduce,range,raw_input(),map,sum,lambda x:d(m,r(1,x+1),1);print S(f(S(x)-1)*(S(x)-x[0])/d(m,M(f,x))for(x)in I.product(*[r(min(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

r,s,M,S=range,str(input()),map,sum
a=[s.count(str(d)) for d in r(10)]
from math import factorial as f
from functools import reduce as d
from operator import mul
from itertools import product as p
print(S((f(S(x))-(f(S(x)-1)*x[0] if x[0] else 0))//d(mul,M(f,x)) for x in p(*[r(y//max(y,1),y+1) for y in a])))

P = 23

def f(a):
	bomb = 0
	for i in range(0, 10):
		bomb += (P ** i) * (a[i] + 1)
		#print(bomb)
	return bomb

def rec(n, a):
	d[f(a)] = True
	ans = fact[n]
	if a[0] != 0:
		ans -= a[0] * fact[n - 1]
	temp = 0
	for i in range(0, 10):
		if a[i] > 1:
			ans //= fact[a[i]]
			a[i] -= 1
			if d.get(f(a)) == None:
				temp += rec(n - 1, a)
			a[i] += 1
	return ans + temp

s = str(input())
n = len(s)
fact = []
fact.append(1)
for i in range(1, 30):
	fact.append(fact[i - 1] * i)
d = {}
a = []
for i in range(10):
	a.append(0)
for i in range(n):
	a[ord(s[i]) - ord('0')] += 1
print(int(rec(n, a)))

import sys
import math
import collections
from pprint import pprint as pp
mod = 1000000007
MAX = 10**18

def inp():
    return map(int, input().split())

def array():
    return list(map(int, input().split()))

def vector(size, val=0):
    vec = [val for i in range(size)]
    return vec

def matrix(rowNum, colNum, val=0):
    mat = []
    for i in range(rowNum):
        collumn = [val for j in range(colNum)]
        mat.append(collumn)
    return mat

def fact(lim):
    ary = vector(lim + 1, 1)
    for i in range(2, lim + 1):
        ary[i] = ary[i - 1] * i
    return ary

def pascle(lim):
    p = matrix(lim, lim)
    for i in range(lim):
        p[i][i] = p[i][0] = 1
    for i in range(1, lim):
        for j in range(1, lim):
            p[i][j] = (p[i - 1][j - 1] + p[i - 1][j])
    return p

n = input()
d = {}
f = fact(25)
p = pascle(25)
for i in range(10):
    d[i] = 0
for i in range(len(n)):
    d[ord(n[i]) - ord('0')] += 1
now = vector(10)
ans = 0

def fun(x):
    global ans
    if x == 10:
        cnt = 0
        for i in range(1, 10):
            cnt += now[i]
        temp = f[cnt]
        for i in range(1, 10):
            temp //= f[now[i]]
        if now[0] > 0 and cnt >= 1:
            temp *= p[now[0] + cnt - 1][cnt - 1]
        ans += temp
    elif d[x] == 0:
        now[x] = 0
        fun(x + 1)
    else:
        for i in range(1, d[x] + 1):
            now[x] = i
            fun(x + 1)

fun(0)
print(ans)

import itertools as it
S=input().strip()
freq=[0 for i in range(10)]
for i in S:
    u=ord(i)-ord('0')
    freq[u]+=1

fac=[1]
for i in range(1,20): fac.append(i*fac[-1])

"""
M={}
def F(cur,used):
    while cur<10 and freq[cur]==0: cur+=1
    if cur==10:
        r=fac[sum(used)]
        for i in used:
            r//=fac[i]
        print(used)
        return 1

    key=(cur,tuple(used))
    if key in M: return M[key]

    r=0
    for i in range(1,freq[cur]):
        for j in range(
    return r

total=0
for i in range(1,10):
    if freq[i]==0: continue
    M={}
    freq[i]-=1
    used=[0 for j in range(10)]
    used[i]=1
    total+=F(0,used)
    freq[i]+=1

print(total)
"""

total=0
for x in it.product(*(range(0 if i==0 else 1,i+1) for i in freq)):
    Q="".join(str(i)*x[i] for i in range(10))
    s=sum(x)-1
    if s<0: continue
    g=0
    for d in range(1,10):
        n=fac[s]
        y=list(x)
        y[d]-=1
        #assert(s==sum(y))
        for k in range(0,10):
            n//=fac[y[k]]
        g+=n
        #print(x,d,n,g)
    #print(Q,x,g)
    total+=g

print(total)

#208
#280
#802
#820
#2028, 2082, 2208, 2280, 2802, 2820
#8022, 8202, 8220

r,s=range,str(input())
a=[s.count(str(d)) for d in r(10)]
from math import factorial as f
from functools import reduce as d
from operator import mul as m
from itertools import product as p
print(sum(f(sum(x))//d(m,map(f,x))-(f(sum(x)-1)*x[0]//d(m,map(f,x)) if x[0] else 0) for x in p(*[r(0 if not y else 1,y+1) for y in a])))

r,s,M,S=range,str(input()),map,sum
a=[s.count(str(d)) for d in r(10)]
from math import factorial as f
from functools import reduce as d
from operator import mul
from itertools import product as p
print S((f(S(x))-(f(S(x)-1)*x[0]))//d(mul,M(f,x)) for x in p(*[r(y//max(y,1),y+1) for y in a]))

import math
import sys
def newt(n,k):
  return (math.factorial(n)//math.factorial(k))//math.factorial(n-k)
def go(occ,used):
  # print(occ,used)
  cnt=[0]*20
  cnt[0]=1
  for digit,rep in enumerate(occ):
    if cnt==0 or rep==0:
      continue
    res=[0]*20
    r=range(rep+1) if digit==used else range(1,rep+1)
    for i in r:

      for j,x in enumerate(cnt):
        if i+j>=20:continue
        res[i+j]+=x*newt(j+i,i)
    cnt=res
  return sum(cnt)

n=input()
occ = [ n.count(str(x)) for x in range(10)]
ans=0
for i in range(1,10):
  if occ[i]>0:
    occ[i]-=1
    ans+=go(occ,i)
    occ[i]+=1
print(ans)

# import tensorflow as tf
import math
from itertools import product

def formula(counts):
    ans = math.factorial(sum(counts))
    for c in counts:
        ans /= math.factorial(c)
    if counts[0]:
        ans = (ans * (sum(counts) - counts[0])) / sum(counts)
    return ans

def solve(n):
    s = str(n)
    counts = [s.count(str(i)) for i in range(10)]
    ans = 0
    possible_counts = [range(1, c + 1) if c != 0 else [0] for c in counts]
    results = [formula(counts) for counts in product(*possible_counts)]
    ans = sum(results)
    #  print list(product(*possible_counts))
    #  print results
    #  print ans
    return ans

def test():
    assert solve(97) == 2
    assert solve(2028) == 13

if __name__ == '__main__':
    test()
    n = int(raw_input())
    print solve(n)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
import math

def test(num, a, step):
    if step == 10:
        s    = sum(a)
        ans  = s - a[0]
        s   -= 1

        ans *= math.factorial(s)

        for i in a:
            if i!=0:
                ans /= math.factorial(i)
        return int(ans)

    if num[step] == 0:
        return test(num, a, step+1)

    ans = 0
    a[step] = 0
    for i in range(num[step]):
        a[step] += 1
        ans += test(num, a, step+1)
    return ans

n   = [int(i) for i in input()]

start = time.time()

num = [0 for i in range(10)]

for i in n:
    num[i] += 1

a   = [0 for i in range(10)]
ans = test(num, a, 0)

print(ans)
finish = time.time()
#print(finish - start)

import operator

def factorial(x):
	if x == 0:
		return 1
	return x*factorial(x-1)

n = map(int, list(raw_input()))
HT = [0 for _ in xrange(10)]
for d in n:
	HT[d] += 1
discount = [0 for _ in xrange(10)]
for d in xrange(10):
	if HT[d] == 0:
		HT[d] = discount[d] = 1
ans = 0
for i0 in xrange(1, HT[0]+1):
	for i1 in xrange(1, HT[1]+1):
		for i2 in xrange(1, HT[2]+1):
			for i3 in xrange(1, HT[3]+1):
				for i4 in xrange(1, HT[4]+1):
					for i5 in xrange(1, HT[5]+1):
						for i6 in xrange(1, HT[6]+1):
							for i7 in xrange(1, HT[7]+1):
								for i8 in xrange(1, HT[8]+1):
									for i9 in xrange(1, HT[9]+1):
										nums = [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
										nondiscounted = [nums[d] for d in xrange(10) if discount[d] != 1]
										s = sum(nondiscounted)
										ans += factorial(s)/reduce(operator.mul, [factorial(x) for x in nondiscounted], 1)
										if discount[0] == 0:
											nondiscounted = [nums[0]-1]+[nums[d] for d in xrange(1, 10) if discount[d] != 1]
											ans -= factorial(s-1)/reduce(operator.mul, [factorial(x) for x in nondiscounted], 1)
print ans

import collections
import itertools

n = input()

fibo = [1]
while len(fibo) <= len(n):
    fibo.append(fibo[-1] * len(fibo))

cnts = collections.defaultdict(int)
for x in n:
    cnts[int(x)] += 1

def get_ans(choices):
    ret = 0
    for choice in choices:
        a, b = 0, 1
        for x in choice:
            a += x
            b *= fibo[x]
        a = fibo[a]
        ret += a // b
    return ret

ans = 0
for i in range(1, 10):
    if cnts[i] == 0:
        del cnts[i]
        continue
    cnts[i] -= 1
    if cnts[i] == 0:
        del cnts[i]
    choices = itertools.product(*(
        range(key != i, value + 1) for key, value in cnts.items()))
    ans += get_ans(choices)
    cnts[i] += 1

print(ans)

from collections import Counter
from itertools import permutations
from copy import deepcopy

n = input()
ll = list(str(n))

def fact(n):
    if n <= 1:
        return 1
    return n*fact(n-1)

def solve(ll, dd):
    now = 1
    for val in dd.values():
        now *= fact(val)

    if '0' in dd:
        return ((len(ll)-dd['0']) * fact(len(ll)-1)) / now
    else:
        return fact(len(ll)) / now

keep = {}
def gogo(ll, dd):
    if tuple(ll) in keep:
        return 0
    else:
        keep[tuple(ll)] = True

    result = solve(ll, dd)
    ddc = deepcopy(dd)
    nono = set()

    count = 0
    for itr, ch in enumerate(ll):
        if ch not in nono and dd[ch] > 1:
            ddt = deepcopy(ddc)
            ddt[ch] -= 1
            nono.add(ch)
            llt = ll[:itr] + ll[itr+1:]
            count += gogo(llt, ddt)

    #print ll, result
    return count + result

dd = Counter(ll)
print gogo(ll, dd)

#!/usr/bin/python3

def enc(t):
    v = 0
    for x in t:
        v *= 20
        v += x
    return v

def dec(v, N):
    a = []
    for _ in range(N):
        a.append(v % 20)
        v //= 20
    a.reverse()
    return a

def cnt(C, ld, ud):
    N = len(C)

    ans = 0

    dp = {enc([0] * N): 1}
    for rnd in range(ud):
        if rnd >= ld:
            for et in dp:
                c = dp[et]
                t = dec(et, N)
                if ((C[0] == 0 and all([t[i] >= 1 for i in range(1, N)]))
                    or (C[0] > 0 and all([t[i] >= 1 for i in range(N)]))):
                    ans += c

        ndp = {}

        for et in dp:
            t = dec(et, N)
            c = dp[et]

            for i in range(N):
                if rnd == 0 and i == 0:
                    continue
                if t[i] < C[i]:
                    l = list(t)
                    l[i] += 1
                    nt = enc(l)
                    if nt not in ndp:
                        ndp[nt] = 0
                    ndp[nt] += c

        dp = ndp

    for et in dp:
        c = dp[et]
        t = dec(et, N)
        if ((C[0] == 0 and all([t[i] >= 1 for i in range(1, N)]))
            or (C[0] > 0 and all([t[i] >= 1 for i in range(N)]))):
            ans += c

    return ans

def solve(S):
    N = len(S)
    C = [0] * 10
    for c in S:
        C[ord(c) - ord('0')] += 1

    mindigits = len([c for c in C if c > 0])

    C = [C[0]] + [C[i] for i in range(1, 10) if C[i] > 0]

    return cnt(C, mindigits, N)

def main():
    S = input()
    print(solve(S))

if __name__ == '__main__':
    main()

from operator import mul as m;from itertools import product as p;d,r,s,M,S,f=reduce,range,str(input()),map,sum,lambda x:reduce(m,r(1,x+1),1);print S((f(S(x))-(f(S(x)-1)*x[0]))/d(m,M(f,x))for x in p(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

from collections import Counter
from itertools import product

s = input()

ds = Counter(s)

fac = [1 for i in range(100)]
for i in range(1, 100):
    fac[i] = fac[i-1] * i

res = 0
for possib in product(*[zip([k] * n, range(1, n+1)) for k, n in ds.items()]):
    possib = list(possib)
    non_zero_sum = sum(v for k, v in possib if k != '0')
    total = sum(v for _, v in possib)

    value = non_zero_sum * fac[total-1]
    for _, v in possib:
        value //= fac[v]

    res += value
print(res)

from math import factorial as fact

n = map(int, list(raw_input()))
cnt = [0] * 10
for x in n:
    cnt[x] += 1

ans = 0
ccnt = [0] * 10

def rec(lvl):
    global ans, ccnt
    if lvl >= 10:
        s = sum(ccnt)
        if s == ccnt[0]:
            return

        cc = fact(s) / s * (s - ccnt[0])
        for x in ccnt:
            cc /= fact(x)

        ans += cc
        return

    for i in xrange(int(cnt[lvl] != 0), cnt[lvl] + 1):
        ccnt[lvl] = i
        rec(lvl + 1)

rec(0)

print ans

arr = [int(x) for x in list(raw_input())]
fact = [1 for x in range(20)]
for i in range(2,20):
  fact[i] = i*fact[i-1]
cnt = [0 for x in range(10)]
for i in arr:
  cnt[i] += 1
ans = [0]
def solve(li,dep):
  if dep==-1:
    for i in range(10):
      if not li[i] and cnt[i]:
        return
    res = fact[sum(li)]
    for i in range(10):
      if li[i]:
        res /= fact[li[i]]
    if li[0]:
      res -= res*li[0]/sum(li)
    ans[0] += res
  else:
    for i in range(cnt[dep]+1):
      li[dep] = i
      solve(li,dep-1)
tmp = [0 for x in range(10)]
for i in range(cnt[9]+1):
  tmp[9] = i
  solve(tmp,8)
print ans[0]

from math import factorial

memo={}
vis=set()

def getnp(zeros, nums):
    if (zeros, tuple(nums)) in vis:
        return 0
    vis.add((zeros, tuple(nums)))

    sn=sum(nums)
    configs=factorial(sn+zeros)
    for n in nums:
        configs/=factorial(n)
    configs/=factorial(zeros)

    res=(sn*configs)/(sn+zeros)
    for i in range(len(nums)):
        if nums[i]>1:
            nums[i]-=1
            res+=getnp(zeros,nums)
            nums[i]+=1
        if zeros>1:
            res+=getnp(zeros-1,nums)
    memo[(zeros, tuple(sorted(nums)))]=res
    return res

s=raw_input()
zeros=s.count('0')
nums=[]
for i in range(1,10):
    cnt=s.count(chr(ord('0')+i))
    nums.append(cnt)

print getnp(zeros, nums)

#import resource
#import sys
#resource.setrlimit(resource.RLIMIT_STACK, [0x100000000, resource.RLIM_INFINITY])
#sys.setrecursionlimit(0x10000000)
from sys import stdin, stdout
def GCD(x, y):
   while(y):
       x, y = y, x % y
   return x
def BS(arr, l, r, x):
    if r >= l:
        mid = l + (r - l)/2
        if arr[mid] == x:
            return mid
        elif arr[mid] > x:
            return BS(arr, l, mid-1, x)
        else:
            return BS(arr, mid+1, r, x)
    else:
        return -1
from bisect import bisect_left as bl
from bisect import bisect_right as br
import itertools
import math
import Queue
"""-----------------------------------------------------------------------------"""
a=raw_input()
l=[0]*10
for i in range(len(a)):
    l[int(a[i])]+=1
g=0
for a1 in range(min(1,l[0]),l[0]+1):
    for a2 in range(min(1,l[1]),l[1]+1):
        for a3 in range(min(1,l[2]),l[2]+1):
            for a4 in range(min(1,l[3]),l[3]+1):
                for a5 in range(min(1,l[4]),l[4]+1):
                    for a6 in range(min(1,l[5]),l[5]+1):
                        for a7 in range(min(1,l[6]),l[6]+1):
                            for a8 in range(min(1,l[7]),l[7]+1):
                                for a9 in range(min(1,l[8]),l[8]+1):
                                    for a10 in range(min(1,l[9]),l[9]+1):
                                        p=[a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]
                                        t=0
                                        f=1
                                        for i in range(10):
                                            t+=p[i]
                                            f*=math.factorial(p[i])
                                        t-=1
                                        t=math.factorial(t)
                                        for i in range(1,10):
                                            if(p[i]>0):
                                                h=f/math.factorial(p[i])
                                                h*=math.factorial(p[i]-1)
                                                g+=t/h
print g

n = input()

f = [0] * 10

m = n
while m > 0:
    r = m % 10
    m /= 10
    f[r] += 1

fact = [1] * 20
for i in xrange(1, 20):
    fact[i] = i * fact[i - 1]

# final answer
ans = 0

# fix a digit
for d in xrange(1, 10):
    if f[d] == 0: continue
    f[d] -= 1

    st0 = 1
    if f[0] == 0: st0 = 0
    for x0 in xrange(st0, f[0] + 1):
        st1 = 1
        if f[1] == 0 or d == 1: st1 = 0
        for x1 in xrange(st1, f[1] + 1):
            st2 = 1
            if f[2] == 0 or d == 2: st2 = 0
            for x2 in xrange(st2, f[2] + 1):
                st3 = 1
                if f[3] == 0 or d == 3: st3 = 0
                for x3 in xrange(st3, f[3] + 1):
                    st4 = 1
                    if f[4] == 0 or d == 4: st4 = 0
                    for x4 in xrange(st4, f[4] + 1):
                        st5 = 1
                        if f[5] == 0 or d == 5: st5 = 0
                        for x5 in xrange(st5, f[5] + 1):
                            st6 = 1
                            if f[6] == 0 or d == 6: st6 = 0
                            for x6 in xrange(st6, f[6] + 1):
                                st7 = 1
                                if f[7] == 0 or d == 7: st7 = 0
                                for x7 in xrange(st7, f[7] + 1):
                                    st8 = 1
                                    if f[8] == 0 or d == 8: st8 = 0
                                    for x8 in xrange(st8, f[8] + 1):
                                        st9 = 1
                                        if f[9] == 0 or d == 9: st9 = 0
                                        for x9 in xrange(st9, f[9] + 1):
                                            S = x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9
                                            num = fact[S]
                                            num /= fact[x0]; num /= fact[x1]; num /= fact[x2]; num /= fact[x3]; num /= fact[x4]
                                            num /= fact[x5]; num /= fact[x6]; num /= fact[x7]; num /= fact[x8]; num /= fact[x9]

                                            ans += num
    f[d] += 1

print ans

def factor(n):
    ans = 1
    for i in range(2, n + 1):
        ans *= i
    return ans
cnt = [0] *  10
ans = 0
def f(cnts):
    global cnt
    global ans
    if (len(cnts) == 10):
        lenk = 0
        #print(cnts)
        for i in range(10):
            lenk += cnts[i]
        cur = (factor(lenk) * (lenk - cnts[0])) // lenk
        #print(cur, lenk)
        for i in range(10):
            cur = cur // factor(cnts[i])
        ans += cur
    else:
        if (cnt[len(cnts)] <= 1):
            cnts.append(cnt[len(cnts)])
            f(cnts)
            cnts.pop()
            return None
        for i in range(1, cnt[len(cnts)] + 1):
            cnts.append(i)
            f(cnts)
            cnts.pop()
n = int(input())
lenk = 0
while(n != 0):
    cnt[n % 10] += 1
    n = n // 10
    lenk += 1
maxi = 0
for i in range(10):
    maxi = max(maxi, cnt[i])
f([])
print(ans)

import sys
import math
from collections import defaultdict
ans=0
def get(dic,cur,size,ans,arr,vis):
    if vis[tuple(arr)]==1:
        return 0
    vis[tuple(arr)]=1
    res=fac[size]
    for i in cur:
        res//=fac[cur[i]]
    #print(res,'ans',size,'size',cur,'cur',dic,'dic')
    if cur['0']>0:
        y=fac[size-1]
        for i in cur:
            if i!='0':
                y//=fac[cur[i]]
            else:
                y//=fac[cur[i]-1]
        res-=y
    #print(res,'res')
    ans+=res
    #print(ans,'adnekw')
    res2=0
    for j in dic:
        if dic[j]>=1:
            temp=cur.copy()
            temp[j]+=1
            dictemp=dic.copy()
            dictemp[j]-=1
            arr[int(j)]-=1
            x=get(dictemp,temp,size+1,ans,arr,vis)
            arr[int(j)]+=1
            res2+=x
            #print(x,'x')
            #ans+=x
    return res+res2
s=sys.stdin.readline()[:-1]
fac=[1]
for i in range(1,30):
    x=fac[-1]*i
    fac.append(x)
#print(fac,'fac')
dic=defaultdict(int)
n=len(s)
arr=[0 for _ in range(10)]
for i in range(n):
    dic[s[i]]+=1
    arr[int(s[i])]+=1
cur=defaultdict(int)
for i in dic:
    dic[i]-=1
    cur[i]+=1
    arr[int(i)]-=1
#vis[tuple(arr)]=1
#print(ans,'ansnsnns')
vis=defaultdict(int)
x=get(dic,cur,len(dic),ans,arr,vis)
print(x)

n=input()
s=[0 for i in range(10)]
for i in n:
    s[int(i)]+=1

nol=s[0]
del s[0]
#while 0 in s:
#    s.remove(0)
def C(n,k): # C(10,2)=45
    def fact(k):
        s=1
        for i in range(1,k+1):
            s*=i
        return s
    return fact(n)/(fact(k)*fact(n-k))
def var(nol, koeff):
    def C(n,k): # C(10,2)=45
        def fact(k):
            s=1
            for i in range(1,k+1):
                s*=i
            return s
        return fact(n)/(fact(k)*fact(n-k))
    n=0
    if nol!=0:
        koeff.append(nol)
    for i in koeff:
        n+=i
    s=1
    for k in koeff:
        s*=C(n, k)
        n-=k
    if nol!=0:
        koeff.remove(nol)
        nol-=1
        koeff.append(nol)
        s2=1
        n=0
        for i in koeff:
            n+=i
        for k in koeff:
            s2*=C(n,k)
            n-=k
        s-=s2
    return s
c=0
nado=len(s)-s.count(0)
if nol!=0:
    counter=1
else:
    counter=0
for nolik in range(nol+1):
    for c1 in range(s[0]+1):
        for c2 in range(s[1]+1):
            for c3 in range(s[2]+1):
                for c4 in range(s[3]+1):
                    for c5 in range(s[4]+1):
                        for c6 in range(s[5]+1):
                            for c7 in range(s[6]+1):
                                for c8 in range(s[7]+1):
                                    for c9 in range(s[8]+1):
                                        koeff=[c1,c2,c3,c4,c5,c6,c7,c8,c9]
                                        while 0 in koeff:
                                            koeff.remove(0)
                                        if len(koeff)==nado:
                                            if counter==1 and nolik>=1 or counter==0:
                                                c+=var(nolik, koeff)
print(int(c))

from sys import stdin
from math import factorial as fac
s=list(stdin.readline().strip())
top=2**len(s)
for i in range(len(s)):
    s[i]=int(s[i])
s.sort()
def can(s1):
    dp=[False for i in range(10)]
    for i in range(len(s1)):
        dp[s1[i]]=True
    for i in s:
        if dp[i]==False:
            return False
    return True
def countf(y):
    d={0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}
    tot=len(y)
    for i in y:
        d[i]+=1
    ans=0
    a=fac(tot-1)
    for i in range(1,10):
        if d[i]>0:
            b=1
            for j in range(10):
                if i==j:
                    b*=fac(d[j]-1)
                else:
                    b*=fac(d[j])
            ans+=a//b
    return ans
r=0
st=set()
for i in range(1,top):
    x=i
    y=[]
    z=0
    z1=0
    for j in range(len(s)):
        if x&1:
            z1+=s[j]*10**z
            y.append(s[j])
            z+=1
        x>>=1
    if can(y) and z1 not in st:
        st.add(z1)
        r+=countf(y)
print(r)

factorial_array=[1]
for x in range(1,20):
    factorial_array.append(factorial_array[-1]*x)
def factorial(x):
    global factorial_array
    return factorial_array[x]

def generate(array):
    start=factorial(sum(array))
    for x in range(10):
        start//=factorial(array[x])
    return start

def main():
    string=input()
    store=[0 for x in range(10)]
    for x in range(len(string)):
        store[int(string[x])]+=1
    all_possible=[[]]
    for x in range(10):
        next_all_possible=[]
        for y in all_possible:
            if store[x]==0:
                next_all_possible.append(y+[0])
            else:
                for z in range(1,store[x]+1):
                    next_all_possible.append(y+[z])
        all_possible=next_all_possible.copy()
    total=0
    for x in all_possible:
        pole=1
        times=x[0]
        for y in range(times+1):
            total+=pole*(generate(x))
            pole*=-1
            x[0]-=1
    print(total)
main()

from collections import defaultdict

n = [int(i) for i in input()]
st = frozenset(n)
ini = [n.count(i) for i in range(10)]
dp = defaultdict(int)

def dfs(state):
    key = tuple(state)
    if key in dp:
        return dp[key]

    if all(state[i] > 0 for i in st):
        dp[key] += 1

    for i in range(10):
        if state[i] < ini[i]:
            state[i] += 1
            dp[key] += dfs(state)
            state[i] -= 1
    return dp[key]

ans = 0
s = [0] * 10
for i in range(1, 10):
    if ini[i]:
        s[i] = 1
        ans += dfs(s)

print(ans)

import math;

n = int(input())
if(n<10) :
	print(1)
else :
	tmp = n;
	frek = [ 0 for _ in range(10)]
	total = 0
	while tmp>0 :
		frek[tmp%10]+=1
		tmp //= 10
		total += 1
	total -= 1
	ans = 0
	for i in range(1, 10) :
		if frek[i] > 0 :
			tmp = math.factorial(total) // math.factorial(frek[i]-1)
			for j in range(0, 10) :
				if i!=j and frek[j]>0 :
					tmp //= math.factorial(frek[j])

			ans += tmp
	print(ans)

import math
from collections import defaultdict

dp = defaultdict(list)
fact = dict()

def facto(val) :
	if val not in fact.keys() :
		fact[val] = math.factorial(val)
	return fact[val]

def hitung(frek, total) :
	global dp
	keys = ' '.join(str(x) for x in frek)
	if keys in dp.keys() :
		return dp[keys]
	ans = 0
	for i in range(1, 10) :
		if frek[i] > 0 :
			tmp = facto(total) // facto(frek[i]-1)
			for j in range(0, 10) :
				if i!=j and frek[j]>0 :
					tmp //= facto(frek[j])
			ans += tmp
	for i in range(0, 10) :
		if frek[i]>1 :
			frek[i] -=1
			ans += hitung(frek, total-1)
			frek[i] += 1
	dp[keys] = ans
	return ans;

n = int(input())
if(n<10) :
	print(1)
else :
	tmp = n;
	frek = [ 0 for _ in range(10)]
	total = 0
	while tmp>0 :
		frek[tmp%10]+=1
		tmp //= 10
		total += 1
	print(hitung(frek, total-1))

a = int(input())
b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
while a != 0:
    b[a % 10] += 1
    a //= 10

ans = 0

def fact(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

def f(n, arr):
    #print(arr)
    global ans
    if n == 10:
        sum = 0
        for i in range(10):
            sum += arr[i]
        temp = 1
        temp *= sum - b[0]
        temp *= fact(sum - 1)
        for i in range(10):
            if arr[i] > 1:
                temp //= fact(arr[i])
        ans += temp
        #print(ans)
    else:
        if b[n] > 0:
            for i in range(1, b[n] + 1):
                temp = arr.copy()
                temp.append(i)
                f(n + 1, temp)
        else:
            arr.append(0)
            f(n + 1, arr)

f(0, [])
print(int(ans))

a = int(input())
b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
while a != 0:
    b[a % 10] += 1
    a //= 10

ans = 0

def fact(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

def f(n, arr):
    #print(arr)
    global ans
    if n == 10:
        sum = 0
        for i in range(10):
            sum += arr[i]
        temp = 1
        temp *= sum - b[0]
        temp *= fact(sum - 1)
        for i in range(10):
            if arr[i] > 1:
                temp /= fact(b[i])
        ans += temp
        #print(ans)
    else:
        if b[n] > 0:
            for i in range(1, b[n] + 1):
                temp = arr.copy()
                temp.append(i)
                f(n + 1, temp)
        else:
            arr.append(0)
            f(n + 1, arr)

f(0, [])
print(int(ans))

a = int(input())
b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
while a != 0:
    b[a % 10] += 1
    a //= 10

ans = 0

def fact(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

def f(n, arr):
    #print(arr)
    global ans
    if n == 10:
        sum = 0
        for i in range(10):
            sum += arr[i]
        temp = 1
        temp *= sum - b[0]
        temp *= fact(sum - 1)
        for i in range(10):
            if arr[i] > 1:
                temp //= fact(b[i])
        ans += temp
        #print(ans)
    else:
        if b[n] > 0:
            for i in range(1, b[n] + 1):
                temp = arr.copy()
                temp.append(i)
                f(n + 1, temp)
        else:
            arr.append(0)
            f(n + 1, arr)

f(0, [])
print(int(ans))

import itertools

def de(n):
    global w
    if len(n) > 0:
        for i in range(1, len(n)):
            z = list(itertools.permutations(n, len(n)))
            for j in range(len(z)):
                r = ''
                for t in range(len(z[j])):
                    r += str(z[j][t])
                if r[0] != 0:

                    qw = set()
                    for i4 in range(len(r)):
                        qw.add(r[i4])
                    if len(qw) == el and r[0] != '0':
                        w.add(r)

        for i in range(len(n)):
            de(n[:i] + n[i + 1:])

a2 = int(input())
a = a2
s = [0] * 10

while a > 0:
    s[a % 10] += 1
    a = a // 10

b = str(a2)

rt = set()
for i in range(len(s)):
    if s[i] > 0:
        rt.add(i)
el = len(rt)

w = set()
de(b)
print(len(w))

from math import factorial as fac
def generate_poslist(lis,length):
    if length==0:
        return [[]]
    elems=lis[0]
    temp=lis.pop(0)
    recval=generate_poslist(lis,length-1)
    ansl=[]
    for anyl in recval:
        ansl.extend(list(map(lambda x:[x]+anyl,elems)))
    return ansl
def getsum(l):
    sumfac=fac(sum(l))
    prod=1
    for e in l:
        prod=prod*fac(e)
    return sumfac/prod

wnum=input('')
digdic=dict()
for dig in wnum:
    digdic[dig]=digdic.get(dig,0)+1
#check how to check whther sometinh is a number or a list
baselist=[]
for (key,val) in digdic.items():
    baselist.append(list(range(1,val+1)))
possibility_list=generate_poslist(baselist,len(baselist))
sum1=0
sum2=0
for lis in possibility_list:
    sum1+=getsum(lis)
forzero=digdic.get('0',0);
if forzero!=0:
    if forzero==1:
        del digdic['0']
    else:
        digdic['0']=forzero-1
    baselist=[]
    for (key,val) in digdic.items():
        baselist.append(list(range(1,val+1)))
    possibility_list=generate_poslist(baselist,len(baselist))

    for lis in possibility_list:
        sum2+=getsum(lis)
print(int(sum1-sum2))

def main():
    def fact(x):
        if x == 0:
            return 1
        return x * fact(x - 1)
    n = input()
    l = len(n)
    def helper(dc):
        a = 0
        temp = [dc[j] for j in dc if j != '0']
        s = sum(temp)
        try:
            ret = fact(s) * fact(s + dc['0'] - 1) // (fact(s - 1) * fact(dc['0']))
        except:
            ret = fact(s)
        for i in temp:
            ret = ret // fact(i)
        for i in dc:
            if dc[i] != 1:
                d = dc
                d[i] -= 1
                a += helper(d)
        return ret + a
    dct = {}
    for i in set(n):
        dct[i] = n.count(str(i))
    print(helper(dct))
    return 0
main()

from collections import defaultdict
import math

def com(N, R):
    if not N >= R >= 0:
        return 0
    return math.factorial(N)//(math.factorial(R)*math.factorial(N-R))

def solve():
    a = list(map(int, list(input())))
    d = defaultdict(int)
    for v in a:
        d[v] += 1
    que = [(key, value) for key, value in d.items()]
    que.sort()

    def recursion(index):
        if index == len(que) - 1:
            num, numcnt = que[index]
            return [[(num, i)] for i in range(1, numcnt + 1)]
        else:
            res = []
            num, numcnt = que[index]
            for i in range(1, numcnt + 1):
                for v in recursion(index + 1):
                    add = v.copy()
                    add.append((num, i))
                    res.append(add)
            return res

    res = recursion(0)
    ans = 0
    for v in res:
        v.reverse()
        S = math.factorial(sum(x[1] for x in v))
        for x in v:
            S //= math.factorial(x[1])
        S = S*(len(a) - d[0])//len(a)
        ans += S
    print(ans)
    return

solve()

import math

def get_n_vars_when_amounts_fixed(a):
	print("b", b)
	t = math.factorial(sum(a[1:]))
	for i in range(1, len(a)):
		t = t // math.factorial(a[i])

	for i in range(a[0]):
		t *= (sum(a[1:]) + i);
	t // math.factorial(a[0])
	print("t", t)
	return t

def gen(a, b, pos):
	if pos == 10:
		return get_n_vars_when_amounts_fixed(b)

	if a[pos] == 0:
		return gen(a, b, pos + 1)

	ans = 0
	for i in range(1, a[pos] + 1):
		b[pos] = i
		ans += gen(a, b, pos + 1)

	return ans

a = [0] * 10
s = input()
for ch in s:
	a[int(ch)] += 1

# print(a)

b = [0] * 10
ans = gen(a, b, 0)

print(ans)

import math

def get_n_vars_when_amounts_fixed(a):
	# print("b", b)
	t = math.factorial(sum(a[1:]))
	for i in range(1, len(a)):
		t = t // math.factorial(a[i])

	for i in range(a[0]):
		t *= (sum(a[1:]) + i);
	t // math.factorial(a[0])
	# print("t", t)
	return t

def gen(a, b, pos):
	if pos == 10:
		return get_n_vars_when_amounts_fixed(b)

	if a[pos] == 0:
		return gen(a, b, pos + 1)

	ans = 0
	for i in range(1, a[pos] + 1):
		b[pos] = i
		ans += gen(a, b, pos + 1)

	return ans

a = [0] * 10
s = input()
for ch in s:
	a[int(ch)] += 1

# print(a)

b = [0] * 10
ans = gen(a, b, 0)

print(ans)

def rec(n, a):
	ans = fact[n]
	if a[0] != 0:
		ans //= fact[a[0]]
		ans -= fact[n - a[0]]
	temp = 0
	for i in range(1, 10):
		if a[i] != 0:
			if (ans % fact[a[i]] != 0):
				exit(0)
			ans //= fact[a[i]]
			if a[i] != 1:
				a[i] -= 1
				temp += rec(n - 1, a)
				a[i] += 1
	return ans + temp

s = str(input())
n = len(s)
fact = []
fact.append(1)
for i in range(1, 30):
	fact.append(fact[i - 1] * i)
a = []
for i in range(10):
	a.append(0)
for i in range(n):
	a[ord(s[i]) - ord('0')] += 1
print(int(rec(n, a)))

def rec(n, a):
	ans = fact[n]
	if a[0] != 0:
		ans //= fact[a[0]]
		ans -= fact[n - 1]
	temp = 0
	for i in range(1, 10):
		if a[i] != 0:
			ans //= fact[a[i]]
			if a[i] != 1:
				a[i] -= 1
				temp += rec(n - 1, a)
				a[i] += 1
	return ans + temp

s = str(input())
n = len(s)
fact = []
fact.append(1)
for i in range(1, 19):
	fact.append(fact[i - 1] * i)
a = []
for i in range(10):
	a.append(0)
for i in range(n):
	a[ord(s[i]) - ord('0')] += 1
print(int(rec(n, a)))

def rec(n, a):
	ans = fact[n]
	if a[0] != 0:
		ans -= a[0] * fact[n - 1]
		ans //= fact[a[0]]
	temp = 0
	for i in range(1, 10):
		if a[i] != 0:
			ans //= fact[a[i]]
			if a[i] != 1:
				a[i] -= 1
				temp += rec(n - 1, a)
				a[i] += 1
	return ans + temp

s = str(input())
n = len(s)
fact = []
fact.append(1)
for i in range(1, 30):
	fact.append(fact[i - 1] * i)
a = []
for i in range(10):
	a.append(0)
for i in range(n):
	a[ord(s[i]) - ord('0')] += 1
print(int(rec(n, a)))

def rec(n, a):
	ans = fact[n]
	if a[0] != 0:
		ans -= fact[n - 1]
		ans //= fact[a[0]]
	temp = 0
	for i in range(1, 10):
		if a[i] != 0:
			ans //= fact[a[i]]
			if a[i] != 1:
				a[i] -= 1
				temp += rec(n - 1, a)
				a[i] += 1
	return ans + temp

s = str(input())
n = len(s)
fact = []
fact.append(1)
for i in range(1, 30):
	fact.append(fact[i - 1] * i)
a = []
for i in range(10):
	a.append(0)
for i in range(n):
	a[ord(s[i]) - ord('0')] += 1
print(int(rec(n, a)))

def rec(n, a):
	ans = fact[n]
	if a[0] != 0:
		ans //= fact[a[0]]
		ans -= fact[n - a[0]]
	temp = 0
	for i in range(1, 10):
		if a[i] != 0:
			ans //= fact[a[i]]
			if a[i] != 1:
				a[i] -= 1
				temp += rec(n - 1, a)
				a[i] += 1
	return ans + temp

s = str(input())
n = len(s)
fact = []
fact.append(1)
for i in range(1, 30):
	fact.append(fact[i - 1] * i)
a = []
for i in range(10):
	a.append(0)
for i in range(n):
	a[ord(s[i]) - ord('0')] += 1
print(int(rec(n, a)))

import math
import sys
def newt(n,k):
  return (math.factorial(n)//math.factorial(k))//math.factorial(n-k)
def go(occ,used):
  # print(occ,used)
  cnt=[0]*18
  cnt[0]=1
  for digit,rep in enumerate(occ):
    if cnt==0 or rep==0:
      continue
    res=[0]*18
    r=range(rep+1) if digit==used else range(1,rep+1)
    for i in r:

      for j,x in enumerate(cnt):
        if i+j>=18:continue
        res[i+j]+=x*newt(j+i,i)
    cnt=res
  return sum(cnt)

n=input()
occ = [ n.count(str(x)) for x in range(10)]
ans=0
for i in range(1,10):
  if occ[i]>0:
    occ[i]-=1
    ans+=go(occ,i)
    occ[i]+=1
print(ans)

import collections
import itertools

n = input()

fibo = [1]
while len(fibo) <= len(n):
    fibo.append(fibo[-1] * len(fibo))

cnts = collections.defaultdict(int)
for x in n:
    cnts[int(x)] += 1

def get_ans(cnts):
    ret = 0
    choices = itertools.product(*(range(1, x + 1) for x in cnts.values()))
    for choice in choices:
        a, b = 0, 1
        for x in choice:
            a += x
            b *= fibo[x]
        a = fibo[a]
        ret += a // b
    return ret

ans = get_ans(cnts)
if cnts[0] > 0:
    cnts[0] -= 1
    if cnts[0] == 0:
        del cnts[0]
    ans -= get_ans(cnts)

print(ans)

from collections import *
from itertools import combinations
from sys import stdin

def fact(be, en):
    res = [1]
    for i in range(be, en + 1):
        res.append(res[-1] * i)
    return res

n = stdin.readline().strip()
facs, dis, ans = fact(1, len(n)), set(n), 0
vis = set()

for i in range(1, len(n) + 1):
    for com in combinations(n, i):
        if len(set(com)) == len(dis) and tuple(sorted(com)) not in vis:
            mem, tem = Counter(com), facs[i]

            for k, j in mem.items():
                tem //= facs[j]
                if k == '0':
                    tem -= (i - 1)

            ans += tem

        vis.add(tuple(sorted(com)))
print(ans)

#import resource
#import sys
#resource.setrlimit(resource.RLIMIT_STACK, [0x100000000, resource.RLIM_INFINITY])
#sys.setrecursionlimit(0x10000000)

from sys import stdin, stdout
def GCD(x, y):
   while(y):
       x, y = y, x % y
   return x
def BS(arr, l, r, x):
    if r >= l:
        mid = l + (r - l)/2
        if arr[mid] == x:
            return mid
        elif arr[mid] > x:
            return BS(arr, l, mid-1, x)
        else:
            return BS(arr, mid+1, r, x)
    else:
        return -1
from bisect import bisect_left as bl
from bisect import bisect_right as br
import itertools
import math
import Queue
a=raw_input()
def fuck(l,g):
    t=0
    f=1
    for i in range(10):
        t+=l[i]
        f*=math.factorial(l[i])
    t-=1
    t=math.factorial(t)
    for i in range(1,10):
        if(l[i]>0):
            h=f/math.factorial(l[i])
            h*=math.factorial(l[i]-1)
            g[0]+=t/h
    for i in range(10):
        if(l[i]>1):
            l[i]-=1
            fuck(l,g)
            l[i]+=1
l=[0]*10
for i in range(len(a)):
    l[int(a[i])]+=1
g=[0]
fuck(l,g)
print g[0]

from math import factorial
from functools import lru_cache

@lru_cache()
def choose(n, k):
	return factorial(n) // factorial(n - k) // factorial(k)

def pos(l):
	# list of nums
	out = 1
	s = sum(l)
	for i in l:
		out *= choose(s, i)
		s -= i
	return out

@lru_cache()
def doit(l, i):
	if i == len(l):
		return pos(l)
	out = 0
	for j in range(l[i]):
		newl = list(l)
		newl[i] = j+1
		out += doit(tuple(newl), i+1)
	return out

n = input()
counts = [n.count(str(i)) for i in set(n)]
out = doit(tuple(counts), 0)
if "0" in n:
	counts2 = [n.count(str(i)) - (i == "0") for i in set(n)]
	counts2 = list(filter(None, counts2))
	out -= doit(tuple(counts2), 0)

print(out)

def factor(n):
    ans = 1
    for i in range(2, n + 1):
        ans *= i
    return ans
n = int(input())
cnt = [0] *  10
len = 0
while(n != 0):
    cnt[n % 10] += 1
    n = n // 10
    len += 1
ans = (factor(len) * (len - cnt[0])) //  len
for i in range(10):
    ans = ans // factor(cnt[i])
for i in range(10):
    for j in range(1, cnt[i]):
        cnt[i] -= j
        len -= j
        cur = (factor(len) * (len - cnt[0])) // len
        for k in range(10):
            cur = cur // factor(cnt[k])
        ans += cur
        len += j
        cnt[i] += j
print(ans)

def factor(n):
    ans = 1
    for i in range(2, n + 1):
        ans *= i
    return ans
cnt = [0] *  10
ans = 0
def f(cnts):
    global cnt
    global ans
    if (len(cnts) == 10):
        for i in range(10):
            if (cnt[i] != cnts[i]):
                break
            if (i == 9):
                return None
        lenk = 0
        for i in range(10):
            lenk += cnts[i]
        cur = (factor(lenk) * (lenk - cnt[0])) // lenk
        for i in range(10):
            cur = cur // factor(cnts[i])
        ans += cur
    else:
        if (cnt[len(cnts)] <= 1):
            cnts.append(cnt[len(cnts)])
            f(cnts)
            cnts.pop()
            return None
        for i in range(1, cnt[len(cnts)] + 1):
            cnts.append(i)
            f(cnts)
            cnts.pop()
n = int(input())
lenk = 0
while(n != 0):
    cnt[n % 10] += 1
    n = n // 10
    lenk += 1
ans += (factor(lenk) * (lenk - cnt[0])) //  lenk
for i in range(10):
    ans = ans // factor(cnt[i])
maxi = 0
for i in range(10):
    maxi = max(maxi, cnt[i])
if (maxi > 1):
    f([])
print(ans)

def factor(n):
    ans = 1
    for i in range(2, n + 1):
        ans *= i
    return ans
cnt = [0] *  10
ans = 0

def f(cnts):
    global cnt
    global ans
    if (len(cnts) == 10):
        lenk = 0
        for i in range(10):
            lenk += cnts[i]
        cur = (factor(lenk) * (lenk - cnt[0])) // lenk
        for i in range(10):
            cur = cur // factor(cnts[i])
        ans += cur
    else:
        if (cnt[len(cnts)] <= 1):
            cnts.append(cnt[len(cnts)])
            f(cnts)
            return None
        for i in range(1, cnt[len(cnts)]):
            cnts.append(i)
            f(cnts)
            cnts.pop()
n = int(input())
lenk = 0
while(n != 0):
    cnt[n % 10] += 1
    n = n // 10
    lenk += 1
ans += (factor(lenk) * (lenk - cnt[0])) //  lenk
for i in range(10):
    ans = ans // factor(cnt[i])
maxi = 0
for i in range(10):
    maxi = max(maxi, cnt[i])
if (maxi > 1):
    f([])
print(ans)

def ii():
    return int(input())
def mi():
    return map(int, input().split())
def li():
    return list(mi())

fact = [1] * 1000
for i in range(2, 1000):
    fact[i] = fact[i - 1] * i

s = input()
cnt = {}
for d in '0123456789':
    cnt[int(d)] = s.count(d)
ans = 0

def getcnt(p):
    q0 = p[0]
    q = [pi for pi in p if pi != 0]
    num = fact[sum(q)]
    den = 1
    for qi in q:
        den *= fact[qi]
    gc = num // den
    if q0 == 0:
        return gc
    q = [pi for pi in p[1:] if pi != 0]
    num = fact[sum(q)]
    den = 1
    for qi in q:
        den *= fact[qi]
    gc -= num // den
    return gc

def rec(d, p):
    global ans
    if d == 10:
        #print(p, getcnt(p))
        ans += getcnt(p)
        return
    if cnt[d] == 0:
        p[d] = 0
        rec(d + 1, p)
        return
    for c in range(1, cnt[d] + 1):
        p[d] = c
        rec(d + 1, p)

p = [0] * 10
rec(0, p)

print(ans)

s = input()
occ = [0] * 10
for c in s: occ[int(c)]+= 1
# each digit n which occurred, occurs 1 ~ occ[n] times

# first, ignore leading zeroes
from math import factorial as fact
from itertools import combinations
from collections import Counter
def multinomial(L):
    res = fact(sum(L))
    for x in L: res//= fact(x)
    return res

def calculate(occ):
    extra = []
    rocc = [0]*10
    for i in range(10):
        if occ[i]: rocc[i]+= 1
        for j in range(occ[i]-1): extra.append(i)
    ans = 0
    for es in range(len(extra)+1):
        for C in combinations(extra, es):
            for x in C: rocc[x]+= 1
            #print(rocc, multinomial(rocc))
            ans+= multinomial(rocc)
            for x in C: rocc[x]-= 1
    #print(ans)
    return ans

tot = calculate(occ)
if occ[0] == 0: print(tot)
else:
    occ[0]-= 1
    print(tot - calculate(occ))

s = input()
occ = [0] * 10
for c in s: occ[int(c)]+= 1
# each digit n which occurred, occurs 1 ~ occ[n] times

# first, ignore leading zeroes
from math import factorial as fact
from itertools import combinations
from collections import Counter
def multinomial(L):
    res = fact(sum(L))
    for x in L: res//= fact(x)

    if L[0] == 0: return res
    L[0]-= 1
    lead0 = fact(sum(L))
    for x in L: lead0//= fact(x)
    L[0]+= 1
    return res - lead0

def calculate(occ):
    extra = []
    rocc = [0]*10
    for i in range(10):
        if occ[i]: rocc[i]+= 1
        for j in range(occ[i]-1): extra.append(i)
    ans = 0
    for es in range(len(extra)+1):
        for C in combinations(extra, es):
            for x in C: rocc[x]+= 1
            #print(rocc, multinomial(rocc))
            ans+= multinomial(rocc)
            for x in C: rocc[x]-= 1
    #print(ans)
    return ans

tot = calculate(occ)
print(tot)

n=input()
hsh=[0]*10
for i in n:
    hsh[ord(i)-ord('0')]+=1
#print(hsh)
def f(n):
    if(n<2):
        return 1
    else:
        return n*f(n-1)
ans=0
def rec(table):
    global ans
    s=1
    t=sum(table)
    for i in range(10):
        s*=f(table[i])
    minus=1
    if(table[0]>0):
        table[0]-=1
        for i in range(10):
            minus*=f(table[i])
        ans+=(f(t)//s-f(t-1)//minus)
        table[0]+=1
    else:
        ans+=(f(t)//s)

    #print(table,ans,s,f(t))
    for i in range(10):
        if(table[i]>1):
            table[i]-=1
            rec(table)
            table[i]+=1
rec(hsh)
print(ans)

n = input()
all = [0] * 10
for x in n:
	all[int(x)]+=1
print (all)

dp = [0] * 20
dp[0] = 1
for i in range(1, 10):
	cur = [0] * 20
	if(all[i] > 0):
		for le in range(0, 20):
			fac = 1
			zn = 1
			for kol in range(1, all[i] + 1):
				if(le + kol < 20):
					zn *= le + kol
					fac *= kol
					cur[le + kol] +=  (zn // fac) * dp[le]
		dp = cur

print(dp)

cur = [0] * 20
if(all[0] > 0):
	for le in range(1, 20):
		fac = 1
		zn = 1
		for kol in range(1, all[0] + 1):
			if(le + kol < 20):
				zn *= (le + kol-1)
				fac *= kol
				cur[le + kol] +=  (zn // fac) * dp[le]
	dp = cur
print(dp)

print(sum(dp))

n = input()[:-1]
cnt = [0] * 10
for d in n:
    cnt[int(d)] += 1
m = [0] * 10
ans = 0
def DFS(i : int):
    global ans
    if i == 10:
        pans = 1
        for j in range(sum(m)):
            pans *= j + 1
        for j in range(10):
            for k in range(m[j]):
                pans //= k + 1
        ans += pans
        if m[0]:
            pans = 1
            for j in range(1, sum(m)):
                pans *= j
            for j in range(10):
                for k in range(m[j] - (j == 0)):
                    pans //= k + 1
            ans -= pans
    elif cnt[i] == 0:
        DFS(i + 1)
    else:
        for j in range(0, cnt[i]):
            m[i] = j + 1
            DFS(i + 1)
DFS(0)
print(ans)

from collections import defaultdict as dd
from math import factorial as f

s = input()

cnt = dd(int)

for i in s:
    cnt[i] += 1

ans = 0

def calc(cur_chr, dem, do_not_take_sum, total, diff):
    global ans
    global cnt

    if cur_chr == '9':
        if do_not_take_sum == total:
            return

        ans += f(total - do_not_take_sum) // dem * diff
        return

    for do_not_take in range(0, cnt[cur_chr] + 1):
        if do_not_take > 0 and do_not_take == cnt[cur_chr]:
            continue
        calc(chr(ord(cur_chr) + 1), dem * f(cnt[cur_chr] - do_not_take), do_not_take_sum + do_not_take, total, diff)

calc('0', 1, 0, len(s), 1)

if cnt['0'] != 0:
    cnt['0'] -= 1
    calc('0', 1, 0, len(s) - 1, -1)

print(ans)

from collections import defaultdict as dd
from math import factorial as f

s = input()

cnt = dd(int)

for i in s:
    cnt[i] += 1

ans = 0

def calc(cur_chr, dem, do_not_take_sum, total, diff):
    global ans
    global cnt

    if cur_chr == '9':
        for do_not_take in range(0, cnt[cur_chr] + 1):
            if do_not_take > 0 and do_not_take == cnt[cur_chr]:
                continue

            cur_do_not_take_sum = do_not_take_sum + do_not_take
            if cur_do_not_take_sum == total:
                continue

            cur_dem = dem * f(cnt[cur_chr] - do_not_take)

            ans += f(total - cur_do_not_take_sum) // cur_dem * diff
        return

    for do_not_take in range(0, cnt[cur_chr] + 1):
        if do_not_take > 0 and do_not_take == cnt[cur_chr]:
            continue
        calc(chr(ord(cur_chr) + 1), dem * f(cnt[cur_chr] - do_not_take), do_not_take_sum + do_not_take, total, diff)

calc('0', 1, 0, len(s), 1)

if cnt['0'] != 0:
    cnt['0'] -= 1
    calc('0', 1, 0, len(s) - 1, -1)

print(ans)

# ---------------------------iye ha aam zindegi---------------------------------------------
import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction

mod = 10 ** 9 + 7
mod1 = 998244353

# ------------------------------warmup----------------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# -------------------game starts now----------------------------------------------------import math
class TreeNode:
    def __init__(self, k, v):
        self.key = k
        self.value = v
        self.left = None
        self.right = None
        self.parent = None
        self.height = 1
        self.num_left = 1
        self.num_total = 1

class AvlTree:

    def __init__(self):
        self._tree = None

    def add(self, k, v):
        if not self._tree:
            self._tree = TreeNode(k, v)
            return
        node = self._add(k, v)
        if node:
            self._rebalance(node)

    def _add(self, k, v):
        node = self._tree
        while node:
            if k < node.key:
                if node.left:
                    node = node.left
                else:
                    node.left = TreeNode(k, v)
                    node.left.parent = node
                    return node.left
            elif node.key < k:
                if node.right:
                    node = node.right
                else:
                    node.right = TreeNode(k, v)
                    node.right.parent = node
                    return node.right
            else:
                node.value = v
                return

    @staticmethod
    def get_height(x):
        return x.height if x else 0

    @staticmethod
    def get_num_total(x):
        return x.num_total if x else 0

    def _rebalance(self, node):

        n = node
        while n:
            lh = self.get_height(n.left)
            rh = self.get_height(n.right)
            n.height = max(lh, rh) + 1
            balance_factor = lh - rh
            n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
            n.num_left = 1 + self.get_num_total(n.left)

            if balance_factor > 1:
                if self.get_height(n.left.left) < self.get_height(n.left.right):
                    self._rotate_left(n.left)
                self._rotate_right(n)
            elif balance_factor < -1:
                if self.get_height(n.right.right) < self.get_height(n.right.left):
                    self._rotate_right(n.right)
                self._rotate_left(n)
            else:
                n = n.parent

    def _remove_one(self, node):
        """
        Side effect!!! Changes node. Node should have exactly one child
        """
        replacement = node.left or node.right
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = replacement
            else:
                node.parent.right = replacement
            replacement.parent = node.parent
            node.parent = None
        else:
            self._tree = replacement
            replacement.parent = None
        node.left = None
        node.right = None
        node.parent = None
        self._rebalance(replacement)

    def _remove_leaf(self, node):
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = None
            else:
                node.parent.right = None
            self._rebalance(node.parent)
        else:
            self._tree = None
        node.parent = None
        node.left = None
        node.right = None

    def remove(self, k):
        node = self._get_node(k)
        if not node:
            return
        if AvlTree._is_leaf(node):
            self._remove_leaf(node)
            return
        if node.left and node.right:
            nxt = AvlTree._get_next(node)
            node.key = nxt.key
            node.value = nxt.value
            if self._is_leaf(nxt):
                self._remove_leaf(nxt)
            else:
                self._remove_one(nxt)
            self._rebalance(node)
        else:
            self._remove_one(node)

    def get(self, k):
        node = self._get_node(k)
        return node.value if node else -1

    def _get_node(self, k):
        if not self._tree:
            return None
        node = self._tree
        while node:
            if k < node.key:
                node = node.left
            elif node.key < k:
                node = node.right
            else:
                return node
        return None

    def get_at(self, pos):
        x = pos + 1
        node = self._tree
        while node:
            if x < node.num_left:
                node = node.left
            elif node.num_left < x:
                x -= node.num_left
                node = node.right
            else:
                return (node.key, node.value)
        raise IndexError("Out of ranges")

    @staticmethod
    def _is_left(node):
        return node.parent.left and node.parent.left == node

    @staticmethod
    def _is_leaf(node):
        return node.left is None and node.right is None

    def _rotate_right(self, node):
        if not node.parent:
            self._tree = node.left
            node.left.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.left
            node.left.parent = node.parent
        else:
            node.parent.right = node.left
            node.left.parent = node.parent
        bk = node.left.right
        node.left.right = node
        node.parent = node.left
        node.left = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    def _rotate_left(self, node):
        if not node.parent:
            self._tree = node.right
            node.right.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.right
            node.right.parent = node.parent
        else:
            node.parent.right = node.right
            node.right.parent = node.parent
        bk = node.right.left
        node.right.left = node
        node.parent = node.right
        node.right = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    @staticmethod
    def _get_next(node):
        if not node.right:
            return node.parent
        n = node.right
        while n.left:
            n = n.left
        return n
avl=AvlTree()
#-----------------------------------------------binary seacrh tree---------------------------------------
class SegmentTree1:
    def __init__(self, data, default='z', func=lambda a, b: min(a ,b)):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------game starts now----------------------------------------------------import math
class SegmentTree:
    def __init__(self, data, default=0, func=lambda a, b: a + b):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------------------iye ha chutiya zindegi-------------------------------------
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]

    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]

    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]

    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]

class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)

    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

# --------------------------------------iye ha combinations ka zindegi---------------------------------
def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

# --------------------------------------iye ha power ka zindegi---------------------------------
def sort_list(list1, list2):
    zipped_pairs = zip(list2, list1)

    z = [x for _, x in sorted(zipped_pairs)]

    return z

# --------------------------------------------------product----------------------------------------
def product(l):
    por = 1
    for i in range(len(l)):
        por *= l[i]
    return por

# --------------------------------------------------binary----------------------------------------
def binarySearchCount(arr, n, key):
    left = 0
    right = n - 1

    count = 0

    while (left <= right):
        mid = int((right + left)/ 2)

        # Check if middle element is
        # less than or equal to key
        if (arr[mid]<=key):
            count = mid+1
            left = mid + 1

        # If key is smaller, ignore right half
        else:
            right = mid - 1

    return count

# --------------------------------------------------binary----------------------------------------
def countdig(n):
    c = 0
    while (n > 0):
        n //= 10
        c += 1
    return c

def countGreater( arr,n, k):
    l = 0
    r = n - 1

    # Stores the index of the left most element
    # from the array which is greater than k
    leftGreater = n

    # Finds number of elements greater than k
    while (l <= r):
        m = int(l + (r - l) / 2)
        if (arr[m] >= k):
            leftGreater = m
            r = m - 1

        # If mid element is less than
        # or equal to k update l
        else:
            l = m + 1

    # Return the count of elements
    # greater than k
    return (n - leftGreater)

# --------------------------------------------------binary------------------------------------
l=[]
def fact(t):
    r=1
    for i in range(1,t+1):
        r*=i
    return r
def calc(d,t,s,r,ans,k):
    if t==len(l):
        if k>0:
            ans+=(fact(s-1)*(s-k))//r
        else:
            ans+=fact(s)//r
        return ans
    for i in range(d[l[t]]):
        if l[t]==0:
            k=i+1
        ans=calc(d,t+1,s+i+1,r*(i+1),ans,k)
    return ans
n=input()
d=defaultdict(int)
for i in range(len(n)):
    d[int(n[i])]+=1
l=list(d.keys())
ans=calc(d,0,0,1,0,0)
print(ans)

a=[]
fact=[]

def find(num,val,cnt):
    global ans
    if num==10:
        ans+=val*fact[cnt]
        #print(val,cnt,fact[cnt],ans)
        return
    if a[num]>=1:
        i=1
        while i<=a[num]:
            num+=1
            val=val/fact[i]
            cnt+=i
            find(num,val,cnt)
            num-=1
            val=val*fact[i]
            cnt-=i
            i+=1
    else:
        num+=1
        find(num,val,cnt)
        num-=1

def find1(num,val,cnt):
    global ans
    if num==10:
        ans-=val*fact[cnt]
        return
    if a[num]>=1:
        i=1
        while i<=a[num]:
            num+=1
            val=val/fact[i]
            cnt+=i
            find1(num,val,cnt)
            num-=1
            val=val*fact[i]
            cnt-=i
            i+=1
    else:
        num+=1
        find1(num,val,cnt)
        num-=1

n=int(input())
for i in range(10):
    a.append(0)
fact.append(1)
for i in range(1,20):
    fact.append(fact[i-1]*i)
m=n
while m>0:
    a[m%10]+=1
    m=m//10
ans=0
find(0,1,0)
#print(ans)
if a[0]!=0:
    a[0]-=1
    find1(0,1,0)
print(int(ans))

def faktorijel(num):
    fact = [1, 1,2,6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000]
    return fact[num]
n = list(input())
znams = [0,0,0,0,0,0,0,0,0,0]
for i in n:
    znams[int(i)] += 1
#print(znams)
broj = 0
for broj0 in range(min(znams[0],1), max(1,znams[0]+1)):
    for broj1 in range(min(znams[1],1), max(1,znams[1]+1)):
        for broj2 in range(min(znams[2],1), max(1,znams[2]+1)):
            for broj3 in range(min(znams[3],1), max(1,znams[3]+1)):
                for broj4 in range(min(znams[4],1), max(1,znams[4]+1)):
                    for broj5 in range(min(znams[5],1), max(1,znams[5]+1)):
                        for broj6 in range(min(znams[6],1), max(1,znams[6]+1)):
                            for broj7 in range(min(znams[7],1), max(1,znams[7]+1)):
                                for broj8 in range(min(znams[8],1), max(1,znams[8]+1)):
                                    for broj9 in range(min(znams[9],1), max(1,znams[9]+1)):
                                        #print("vrtise")
                                        y = faktorijel(broj0+broj1+broj2+broj3+broj4+broj5+broj6+broj7+broj8+broj9)/(faktorijel(broj0)*faktorijel(broj1)*faktorijel(broj2)*faktorijel(broj3)*faktorijel(broj4)*faktorijel(broj5)*faktorijel(broj6)*faktorijel(broj7)*faktorijel(broj8)*faktorijel(broj9))
                                        #print(broj0, broj1, broj2, broj3, broj4, broj5, broj6, broj7, broj8, broj9)
                                        #print(broj)
                                        broj += y
                                        if broj0 != 0:
                                            x = faktorijel(broj0-1+broj1+broj2+broj3+broj4+broj5+broj6+broj7+broj8+broj9)/(faktorijel(broj0-1)*faktorijel(broj1)*faktorijel(broj2)*faktorijel(broj3)*faktorijel(broj4)*faktorijel(broj5)*faktorijel(broj6)*faktorijel(broj7)*faktorijel(broj8)*faktorijel(broj9))
                                            broj += -x
print(broj)
#print(29340299842560)

def faktorijel(n):
    if n == 0:
        return 1
    else:
        x = 1
        for i in range(1, n+1):
            x *= i
        return x
n = list(input())
znams = [0,0,0,0,0,0,0,0,0,0]
for i in n:
    znams[int(i)] += 1
#print(znams)
broj = 0
for broj0 in range(min(znams[0],1), max(1,znams[0]+1)):
    for broj1 in range(min(znams[1],1), max(1,znams[1]+1)):
        for broj2 in range(min(znams[2],1), max(1,znams[2]+1)):
            for broj3 in range(min(znams[3],1), max(1,znams[3]+1)):
                for broj4 in range(min(znams[4],1), max(1,znams[4]+1)):
                    for broj5 in range(min(znams[5],1), max(1,znams[5]+1)):
                        for broj6 in range(min(znams[6],1), max(1,znams[6]+1)):
                            for broj7 in range(min(znams[7],1), max(1,znams[7]+1)):
                                for broj8 in range(min(znams[8],1), max(1,znams[8]+1)):
                                    for broj9 in range(min(znams[9],1), max(1,znams[9]+1)):
                                        #print("vrtise")
                                        broj += faktorijel(broj0+broj1+broj2+broj3+broj4+broj6+broj7+broj8+broj9)/(faktorijel(broj0)*faktorijel(broj1)*faktorijel(broj2)*faktorijel(broj3)*faktorijel(broj4)*faktorijel(broj5)*faktorijel(broj6)*faktorijel(broj7)*faktorijel(broj8)*faktorijel(broj9))

                                        if broj0 != 0:
                                            broj += - faktorijel(broj0-1+broj1+broj2+broj3+broj4+broj6+broj7+broj8+broj9)/(faktorijel(broj0-1)*faktorijel(broj1)*faktorijel(broj2)*faktorijel(broj3)*faktorijel(broj4)*faktorijel(broj5)*faktorijel(broj6)*faktorijel(broj7)*faktorijel(broj8)*faktorijel(broj9))
print(int(broj))

from collections import Counter
from math import factorial as f

def main():
    s = input()
    le = len(s)
    cnt = Counter(s)

    def helper(dp):
        for v in cnt.values():
            l = [0] * len(dp)
            for i in range(1, v + 1):
                for j in range(len(dp) - i):
                    l[i + j] += dp[j] // f(i)
            dp = l
        v = 1
        for i in range(len(dp) - 1, 0, -1):
            dp[i] //= v
            v *= i
        return sum(dp)

    res = helper([f(le - 1) * (le - bool(cnt['0'])), *[0] * le])
    print(res)

if __name__ == '__main__':
    main()

from collections import defaultdict
from copy import deepcopy

a = list(input())

d = defaultdict(int)
for x in a:
    d[int(x)] += 1

fact_mem = {}

def fact(n):
    if n in fact_mem:
        return fact_mem[n]
    ans = 1
    for i in range(1, n + 1):
        ans *= i
    fact_mem[n] = ans
    return ans

mem = {}

def f(d):
    tmp = frozenset(d.items())
    if tmp in mem:
        return mem[tmp]
    n = sum(d.values())
    ans = 0
    if d[0] > 0:
        ans += (n - 1) * fact(n - 1)
    else:
        ans += fact(n)
    for x in d:
        ans //= fact(d[x])
    for k in d:
        if d[k] > 1:
            e = deepcopy(d)
            e[k] -= 1
            ans += f(e)
    mem[frozenset(d.items())] = ans
    return ans

ans = f(d)
print(ans)

from collections import defaultdict
from copy import deepcopy

a = list(input())

d = defaultdict(int)
for x in a:
    d[int(x)] += 1

fact_mem = {}

def fact(n):
    if n in fact_mem:
        return fact_mem[n]
    ans = 1
    for i in range(1, n + 1):
        ans *= i
    fact_mem[n] = ans
    return ans

mem = {}

def f(d):
    tmp = frozenset(d.items())
    if tmp in mem:
        return 0
    n = sum(d.values())
    ans = 0
    if d[0] > 0:
        ans += (n - 1) * fact(n - 1)
    else:
        ans += fact(n)
    for x in d:
        ans //= fact(d[x])
    for k in d:
        if d[k] > 1:
            e = deepcopy(d)
            e[k] -= 1
            ans += f(e)
    mem[frozenset(d.items())] = ans
    return ans

ans = f(d)
print(ans)

#!/usr/bin/env python3

from itertools import product
from operator import mul
from functools import reduce

n = input().strip()
c0 = n.count('0')
cc = [n.count(str(i)) for i in range(10)]
cc = [c for c in cc if c > 0]

facs = [1]
for i in range(1, 20):
	facs.append(facs[-1] * i)

def prod(p):
	return reduce(mul, p, 1)

def getC(p):
	return facs[sum(p)] // prod(facs[pp] for pp in p)

def getcount(ct):
	its = [range(1, cti + 1) for cti in ct]
	return sum(getC(p) for p in product(*its))

if c0 == 0:
	res = getcount(cc)
elif c0 == 1:
	ccr = list(cc)
	del ccr[0]
	res = getcount(cc) - getcount(ccr)
else:
	ccr = list(cc)
	ccr[0] -= 1
	res = getcount(cc) - getcount(ccr)

print (res)

import itertools as it

def factorial(n):
    i = 1
    for j in range(1, n + 1):
        i *= j
    return i

def C(n, k):
    k = min([k, n - k])
    result = 1
    for i in range(k + 1, n + 1):
        result *= i
    result //= factorial(n - k)
    return result

n = input()

digits = [0 for _ in range(10)]

for i in n:
    digits[int(i)] += 1

result = 0

for amounts in it.product(*[[0] if x == 0 else range(1, x + 1) for x in digits]):
    sum_no_zero = sum(amounts[1:])
    if sum_no_zero == 0:
        continue
    tmp = factorial(sum_no_zero)
    for j in amounts:
        tmp //= factorial(j)
    tmp *= C(sum_no_zero + amounts[0] - 1, amounts[0])
    result += tmp

print(result)

s=raw_input()

C=[[0 for j in range(2*i+2)] for i in range(20)]
C[0][0]=1
for i in range(1,20):
    for j in range(i+1):
        C[i][j]=C[i-1][j]+C[i-1][j-1]

d={}

for k in s:
    i=int(k)
    if i not in d:
        d[i]=0
    d[i]+=1

res=0
n=sum(d.values())
k=len(d)
if 0 not in d:
    v=d.values()
    a=[0]*k
    suma=k
    while True:
        nbp=1
        l=suma
        for i in range(k):
            nbp*=C[l][a[i]+1]
       #     print nbp, l, a[i]+1
            l-=a[i]+1
        res+=nbp
     #   print nbp,a
        i=0
        while i<k and a[i]==v[i]-1:
            i+=1
        if i==k:
            break
        a[i]+=1
        suma+=1
        for j in range(i):
            a[j]=0
            suma-=v[j]-1
else:
    v=d.values()
    a=[0]*k
    suma=k
    while True:
        nbp=1
        l=suma
        for i in range(k):
            nbp*=C[l][a[i]+1]
            l-=a[i]+1
        res+=nbp
     #   print nbp,a
        i=0
        while i<k and a[i]==v[i]-1:
            i+=1
        if i==k:
            break
        a[i]+=1
        suma+=1
        for j in range(i):
            a[j]=0
            suma-=v[j]-1
   # print res,n
    d[0]-=1
    if not d[0]:
        del d[0]
    v=d.values()
    k=len(d)
    n-=1
    a=[0]*k
    suma=k
    while True:
        nbp=1
        l=suma
        for i in range(k):
            nbp*=C[l][a[i]+1]
            l-=a[i]+1
        res-=nbp
     #   print nbp,a
        i=0
        while i<k and a[i]==v[i]-1:
            i+=1
        if i==k:
            break
        a[i]+=1
        suma+=1
        for j in range(i):
            a[j]=0
            suma-=v[j]-1
#    ks=d.keys()
#    kv=[d[kk] for kk in ks]
#
#    for ij in range(len(ks)):
#        it=ks[ij]
#        v=kv[ij]
#        if it:
#            a=[0]*k
#            suma=k
#            a[ij]=-1
#            if v==1:
#                suma-=1
#            ab=a[:]
#            while True:
#                nbp=1
#                l=suma
#                for i in range(k):
#                    nbp*=C[l][a[i]+1]
#                    print [l],[a[i]+1],nbp
#                    l-=a[i]+1
#                res+=nbp
#                print it,nd,nbp,a,v,suma
#                i=0
#                while i<k and a[i]==v[i]-1:
#                    i+=1
#                if i==k:
#                    break
#                a[i]+=1
#                suma+=1
#                for j in range(i):
#                    a[j]=ab[j]
#                    suma-=v[j]-ab[j]-1
#

print res

r,s,M,S=range,str(input()),map,sum
a=[s.count(str(d)) for d in r(10)]
from math import factorial as f
from functools import reduce as d
from operator import mul as m
from itertools import product as p
print(S((f(S(x))-(f(S(x)-1)*x[0] if x[0] else 1))//d(m,M(f,x)) for x in p(*[r(y/max(y,1),y+1) for y in a])))

import itertools as I;m,d,r,s,M,S,f=lambda x,y:x*y,reduce,range,str(input()),map,sum,lambda x:d(m,r(1,x),1);print S((f(S(x)+1)-f(S(x))*x[0])/d(m,M(f,x))for x in I.product(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

r,s=range,str(input())
a=[s.count(str(d)) for d in r(10)]
from math import factorial as f
from functools import reduce as rd
from operator import mul as m
from itertools import product as p
print(sum(f(sum(x))//reduce(m,map(f,x))-(f(sum(x)-1)//reduce(m,map(f,x))*x[0] if x[0]>0 else 0) for x in p(*[r(0 if not y else 1,y+1) for y in a])))

import itertools as I;m,d,r,s,M,S,f=lambda x,y:x*y,reduce,range,raw_input(),map,sum,lambda x:d(m,r(1,x+1),1);print S(f(S(x)-1)*(S(x)+x[0])/d(m,M(f,x))for x in I.product(*[r(y/max(y,1),y+1)for y in[s.count(str(u))for u in r(10)]]))

import itertools as I;a,d,m,S,r,M,F=raw_input(),reduce,map,sum,range,lambda x,y:x*y,lambda x:d(M,r(1,x+1),1);print S(F(S(x)-1)*(S(x)-x[0])/d(M,m(F,x))for x in I.product(*[r(y>0,y+1)for y in[a.count(c)for c in set('0'+a)]]))

from collections import Counter
from itertools import permutations
from copy import deepcopy

n = input()
ll = list(str(n))

def fact(n):
    if n == 1:
        return 1
    return n*fact(n-1)

def solve(ll, dd):
    now = 1
    for val in dd.values():
        now *= fact(val)

    if '0' in dd:
        return ((len(ll)-dd['0']) * fact(len(ll)-1)) / now
    else:
        return fact(len(ll)) / now

def gogo(ll, dd):
    result = solve(ll, dd)
    ddc = deepcopy(dd)

    count = 0
    for itr, ch in enumerate(ll):
        if dd[ch] > 1:
            ddt = deepcopy(ddc)
            ddt[ch] -= 1
            dd[ch] -= 1
            llt = ll[:itr] + ll[itr+1:]
            count += gogo(llt, ddt)

    #print ll, result
    return count + result

dd = Counter(ll)
print gogo(ll, dd)

from collections import Counter
from itertools import permutations
from copy import deepcopy

n = input()
ll = list(str(n))

def fact(n):
    if n == 1:
        return 1
    return n*fact(n-1)

def solve(ll, dd):
    now = 1
    for val in dd.values():
        now *= fact(val)

    if '0' in dd:
        return ((len(ll)-dd['0']) * fact(len(ll)-1)) / now
    else:
        return fact(len(ll)) / now

def gogo(ll, dd):
    result = solve(ll, dd)
    count = 0
    for itr, ch in enumerate(ll):
        if dd[ch] > 1:
            ddt = deepcopy(dd)
            ddt[ch] -= 1
            dd[ch] -= 1
            llt = ll[:itr] + ll[itr+1:]
            count += gogo(llt, ddt)

    #print ll, result
    return count + result

dd = Counter(ll)
print gogo(ll, dd)

from math import factorial as fact

n = map(int, list(raw_input()))
cnt = [0] * 10
for x in n:
    cnt[x] += 1

ans = 0
ccnt = [0] * 10

def rec(lvl):
    global ans, ccnt
    if lvl >= 10:
        s = sum(ccnt)
        if s == 0 or s == ccnt[0]:
            return

        cc = fact(s) / s * (s - ccnt[0])
        for x in ccnt:
            cc /= fact(x)

        ans += cc
        return

    for i in xrange(int(ccnt[lvl] != 0), cnt[lvl] + 1):
        ccnt[lvl] = i
        rec(lvl + 1)

rec(0)

print ans

n = list(raw_input())
n = [int(x) for x in n]
N = len(n)
need = list(set(n))
checked = {}
ans = 0
cur = len(need)

def valid(arr):
  for i in need:
    if i not in arr:
      return 0
  return 1

def convert(arr):
  cur = 0
  for i in range(len(arr)):
    cur += pow(10,arr[i])
  return cur

def solve(arr):
  cnt = [0 for x in range(10)]
  for i in arr:
    cnt[i] += 1
  res = 1
  for i in range(1,len(arr)+1):
    res *= i
  tot = 0
  for i in range(10):
    if cnt[i] > 1:
      temp = 1
      for j in range(2,cnt[i]+1):
        temp *= j
      res /= temp
      tot += temp
  if cnt[0]:
    temp = 1
    for i in range(2,len(arr)):
      temp *= i
    if tot:
      temp /= tot
    for i in range(2,cnt[0]+1):
      temp *= i
    res -= temp
  return res

for i in range(0,1<<len(n)):
  temp = []
  for j in range(len(n)):
    if i&(1<<j):
      temp.append(int(n[j]))
  if not valid(temp):
    continue
  cur = convert(temp)
  try:
    checked[cur] += 1
  except:
    res = solve(temp)
    ans += res
    checked[cur] = 1

print ans

arr = [int(x) for x in list(raw_input())]
fact = [1 for x in range(20)]
for i in range(2,20):
  fact[i] = i*fact[i-1]
cnt = [0 for x in range(10)]
for i in arr:
  cnt[i] += 1
ans = [0]
def solve(li,dep):
  if dep==-1:
    for i in range(10):
      if not li[i] and cnt[i]:
        return
    res = fact[sum(li)]
    for i in range(10):
      if li[i]:
        res /= fact[li[i]]
    if li[0]:
      for i in range(li[0]):
        res -= res/(sum(li)-i)
    ans[0] += res
  else:
    for i in range(cnt[dep]+1):
      li[dep] = i
      solve(li,dep-1)
tmp = [0 for x in range(10)]
for i in range(cnt[9]+1):
  tmp[9] = i
  solve(tmp,8)
print ans[0]

n = list(raw_input())
n = [int(x) for x in n]
N = len(n)
need = list(set(n))
checked = {}
ans = 0
cur = len(need)

def valid(arr):
  for i in need:
    if i not in arr:
      return 0
  return 1

def convert(arr):
  cur = 0
  for i in range(len(arr)):
    cur += pow(10,arr[i])
  return cur

def solve(arr):
  cnt = [0 for x in range(10)]
  for i in arr:
    cnt[i] += 1
  res = 1
  for i in range(1,len(arr)+1):
    res *= i
  tot = 0
  for i in range(10):
    if cnt[i] > 1:
      temp = 1
      for j in range(2,cnt[i]+1):
        temp *= j
      res /= temp
      tot += temp
  if cnt[0]:
    temp = 1
    for i in range(2,len(arr)):
      temp *= i
    if tot:
      temp /= tot
    res -= temp*cnt[0]
  return res

for i in range(0,1<<len(n)):
  temp = []
  for j in range(len(n)):
    if i&(1<<j):
      temp.append(int(n[j]))
  if not valid(temp):
    continue
  cur = convert(temp)
  try:
    checked[cur] += 1
  except:
    res = solve(temp)
    ans += res
    checked[cur] = 1

print ans

from math import factorial

memo={}

def getnp(cfg):
    if cfg in memo:
        return memo[cfg]
    zeros, nums = cfg
    sn=sum(nums)
    configs=factorial(sn+zeros)
    for n in nums:
        configs/=factorial(n)
    configs/=factorial(zeros)
    res=(sn*configs)/(sn+zeros)
    nm=list(nums)
    for i in range(len(nm)):
        if nm[i]>1:
            nm[i]-=1
            res+=getnp((zeros,tuple(sorted(nm))))
            nm[i]+=1
        if zeros>1:
            res+=getnp((zeros-1,nums))
    memo[cfg]=res
    return res

s=raw_input()
zeros=s.count('0')
nums=[]
for i in range(1,10):
    cnt=s.count(chr(ord('0')+i))
    if cnt:
        nums.append(cnt)

print getnp((zeros, tuple(sorted(nums))))

from math import factorial

memo={}
vis=set()

def getnp(zeros, nums):
    if (zeros, tuple(sorted(nums))) in vis:
        return 0
    vis.add((zeros, tuple(sorted(nums))))
    if (zeros, tuple(sorted(nums))) in memo:
        return memo[(zeros, tuple(sorted(nums)))]

    sn=sum(nums)
    configs=factorial(sn+zeros)
    for n in nums:
        configs/=factorial(n)
    configs/=factorial(zeros)

    res=(sn*configs)/(sn+zeros)
    for i in range(len(nums)):
        if nums[i]>1:
            nums[i]-=1
            res+=getnp(zeros,nums)
            nums[i]+=1
        if zeros>1:
            res+=getnp(zeros-1,nums)
    memo[(zeros, tuple(sorted(nums)))]=res
    return res

s=raw_input()
zeros=s.count('0')
nums=[]
for i in range(1,10):
    cnt=s.count(chr(ord('0')+i))
    nums.append(cnt)

print getnp(zeros, nums)

from math import factorial

memo={}
vis=set()

def getnp(zeros, nums):
    if (zeros, tuple(nums)) in vis:
        return 0
    vis.add((zeros, tuple(nums)))
    if (zeros, tuple(sorted(nums))) in memo:
        return memo[(zeros, tuple(sorted(nums)))]

    sn=sum(nums)
    configs=factorial(sn+zeros)
    for n in nums:
        configs/=factorial(n)
    configs/=factorial(zeros)

    res=(sn*configs)/(sn+zeros)
    for i in range(len(nums)):
        if nums[i]>1:
            nums[i]-=1
            res+=getnp(zeros,nums)
            nums[i]+=1
        if zeros>1:
            res+=getnp(zeros-1,nums)
    memo[(zeros, tuple(sorted(nums)))]=res
    return res

s=raw_input()
zeros=s.count('0')
nums=[]
for i in range(1,10):
    cnt=s.count(chr(ord('0')+i))
    nums.append(cnt)

print getnp(zeros, nums)