This night wasn't easy on Vasya. His favorite team lost, and he didn't find himself victorious either — although he played perfectly, his teammates let him down every time. He had to win at least one more time, but the losestreak only grew longer and longer... It's no wonder he didn't get any sleep this night at all.

In the morning, Vasya was waiting the bus to the university on the bus stop. Vasya's thoughts were hazy and so he couldn't remember the right bus' number quite right and got onto the bus with the number n.

In the bus, Vasya thought that he could get the order of the digits in the number of the bus wrong. Futhermore, he could "see" some digits several times, but the digits he saw were definitely in the real number of the bus. For example, if Vasya saw the number 2028, it could mean that the real bus number could be 2028, 8022, 2820 or just 820. However, numbers 80, 22208, 52 definitely couldn't be the number of the bus. Also, real bus number couldn't start with the digit 0, this meaning that, for example, number 082 couldn't be the real bus number too.

Given n, determine the total number of possible bus number variants.

Input

The first line contains one integer n (1 ≤ n ≤ 10^{18}) — the number of the bus that was seen by Vasya. It is guaranteed that this number does not start with 0.

Output

Output a single integer — the amount of possible variants of the real bus number.

Examples

Input

97


Output

2


Input

2028


Output

13

Note

In the first sample, only variants 97 and 79 are possible.

In the second sample, the variants (in the increasing order) are the following: 208, 280, 802, 820, 2028, 2082, 2208, 2280, 2802, 2820, 8022, 8202, 8220.
import java.util.Arrays;
import java.util.Scanner;

public class e implements Runnable{
	public static void main(String[] args) {
		new Thread(null, new e(), "", 1<<27).start();
	}
	public void run(){
		Scanner in = new Scanner(System.in);
		long N = in.nextLong();
		
//		System.err.println(bruteForce(N));
		System.out.println(fastWay(N));
	}
	
	// need to speed up this brute force
	// let's seee here
	// i know there are log_10(N)+1 digits in that number
	// i can place between one and some limit of 0s, 1s, 2s, ... 9s if i have any, or none if i don't
	
	long fastWay(long N){
		int[] digsN = digitCount(N);
		
		// if it has no zeroes, then just return the rec
		if(digsN[0] == 0){
			 return dp(digsN, (""+N).length());
		}
		
		// if it HAS zeroes, return that rec but minus the answer if digsN[0] were one less
		// we assume that this missing zero is in front
		// wait no that doesn't work, because we fail to subtract the case where there are no zeroes
		else{
			int[] digsNPrime = digsN.clone();
			digsNPrime[0] -= 1;
			return dp(digsN, (""+N).length())
					+ toggleZeroRule()
					- dp(digsNPrime, (""+N).length()-1)
					+ toggleZeroRule();
		}
		
		
	}
	long[][] rec = null;
	// i don't use dig here
	boolean zeroRule = false;
	long toggleZeroRule(){
		zeroRule = !zeroRule;
		return 0;
	}
	long dp(int[] digsN, int numPlaced){
		
		rec = new long[10][numPlaced+1];
		for(long[] a : rec) Arrays.fill(a, -1);
		for(int i = 0; i <= numPlaced; i++){
			long buildItAll = rec(digsN, 9, i);
		}
		
		long sum = 0;
		for(int i=0; i <= numPlaced; i++){
			if(rec[9][i] != -1){
				sum += rec[9][i];
			}
		}
		
//		for(long[] a : rec){
//			System.err.println(Arrays.toString(a));
//		}
//		System.err.println();
		
		return sum;
	}
	long rec(int[] digsN, int dig, int numPlaced){
		// unnecessary for loop that will only go once
		if(numPlaced < 0){
			return 0;
		}
		if(dig < 0){
			if(numPlaced == 0){
				return 1;
			}
			else{
				return 0;
			}
		}
		
		for(;rec[dig][numPlaced] == -1;){
			rec[dig][numPlaced] = 0;
			// bases
//			if(dig == 0){
//				// too many digits, or zero when there should be some
//				if(digsN[0] > numPlaced || (digsN[0] == 0 && numPlaced > 0)){
//					rec[dig][numPlaced] = 0;
//					break;
//				}
//				// enough digits
//				else{
//					rec[dig][numPlaced] = 1;
//					break;
//				}
//			}
//			// none of this digit
			if(digsN[dig] == 0){
				rec[dig][numPlaced] = rec(digsN, dig - 1, numPlaced);
				break;
			}
			
			// build
			for(int nP = numPlaced - digsN[dig]; nP < numPlaced || (zeroRule && dig == 0 && nP <= numPlaced); nP++){
				if(nP < 0) continue;
				// on dig-1, assume nP chosen last time
				// we place	numPlaced - nP of them, as allowed
				rec[dig][numPlaced] += rec(digsN, dig-1, nP) * ballCount(nP, numPlaced-nP);
			}
		}
		
		return rec[dig][numPlaced];
	}
	
	long[][] ballCount = null;
	long ballCount(int a, int b){
		if(ballCount == null){
			ballCount = new long[20][20];
			for(long[] a2 : ballCount) Arrays.fill(a2, -1);
		}
		
		// unnecessary for loops for the win
		// but seriously i wanna break out of here when i want to
		for(; ballCount[a][b] == -1;){
			// base
			if(a == 0 || b == 0){
				ballCount[a][b] = 1;
				break;
			}
			
			// build
			ballCount[a][b] = ballCount(a-1,b) + ballCount(a,b-1);
		}
//		System.err.println(a+" "+b+" -> "+ballCount[a][b]);
		return ballCount[a][b];
	}
	
	
	long bruteForce(long N){
		N = sortTheDigitsBackwards(N);
		
		int[] digsN = digitCount(N);
		
		// heck yeah, for loops
		long ret = 0;
		for(long n=1; n<=N; n++){
			int[] digs_n = digitCount(n);
			// now let's verify this
			boolean fail = false;
			for(int i = 0; i < 10; i++){
				// no more digits in n...
				if(digs_n[i] > digsN[i]){
					fail = true;
					break;
				}
				// ...but it has to be in n if it's in N
				else if(digs_n[i] == 0 && digsN[i] > 0){
					fail = true;
					break;
				}
			}
			if(!fail) ret++;
		}
		
		return ret;
	}
	long sortTheDigitsBackwards(long N){
		char[] nArr = (""+N).toCharArray();
		Arrays.sort(nArr);
		for(int i = 0; i < nArr.length/2; i++){
			char temp = nArr[i];
			nArr[i] = nArr[nArr.length-1-i];
			nArr[nArr.length-1-i] = temp;
		}
		return Long.parseLong(String.copyValueOf(nArr));
	}
	int[] digitCount(long N){
		int[] ret = new int[10];
		String str = ""+N;
		for(char ch : str.toCharArray()){
			ret[ch-'0']++;
		}
		return ret;
	}
}
