Problem: While walking down the street Vanya saw a label "Hide&Seek". Because he is a programmer, he used & as a bitwise AND for these two words represented as a integers in base 64 and got new word. Now Vanya thinks of some string s and wants to know the number of pairs of words of length |s| (length of s), such that their bitwise AND is equal to s. As this number can be large, output it modulo 109 + 7.

To represent the string as a number in numeral system with base 64 Vanya uses the following rules:

  * digits from '0' to '9' correspond to integers from 0 to 9; 
  * letters from 'A' to 'Z' correspond to integers from 10 to 35; 
  * letters from 'a' to 'z' correspond to integers from 36 to 61; 
  * letter '-' correspond to integer 62; 
  * letter '_' correspond to integer 63. 

Input

The only line of the input contains a single word s (1 ≤ |s| ≤ 100 000), consisting of digits, lowercase and uppercase English letters, characters '-' and '_'.

Output

Print a single integer — the number of possible pairs of words, such that their bitwise AND is equal to string s modulo 109 + 7.

Examples

Input

z


Output

3


Input

V_V


Output

9


Input

Codeforces


Output

130653412

Note

For a detailed definition of bitwise AND we recommend to take a look in the corresponding article in Wikipedia.

In the first sample, there are 3 possible solutions: 

  1. z&_ = 61&63 = 61 = z
  2. _&z = 63&61 = 61 = z
  3. z&z = 61&61 = 61 = z

Solution (in JAVA):

Solution:


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.StringTokenizer;

public class cVanyaAndLabel
{
	public static void main(String[] args)
	{
		int[] zeroBitsIn = new int[64];
		for(int i = 0; i < 64; i++)
		{
			for(int b = 0; b < 6; b++)
			{
				if(((i >> b) & 1) == 0)
				{
					zeroBitsIn[i]++;
				}
			}
		}
		
		FastScanner in = new FastScanner();
		
		char[] S = in.nextChara();
		int[] bits = new int[S.length];
		int amtZeroes = 0;
		for(int s = 0; s < S.length; s++)
		{
			if(S[s] >= '0' && S[s] <= '9')
			{
				bits[s] = (int)(S[s] - '0');
			}
			else if(S[s] >= 'A' && S[s] <= 'Z')
			{
				bits[s] = 10 + (int)(S[s] - 'A');
			}
			else if(S[s] >= 'a' && S[s] <= 'z')
			{
				bits[s] = 36 + (int)(S[s] - 'a');
			}
			else if(S[s] == '-')
			{
				bits[s] = 62;
			}
			else if(S[s] == '_')
			{
				bits[s] = 63;
			}
			amtZeroes += zeroBitsIn[bits[s]];
		}

		System.out.println(fast3Expo(amtZeroes));
	}
	
	static long fast3Expo(int exponent)
	{
		long accum = 3;
		long ans = 1;
		for(int i = 0; (1<<i) <= Integer.highestOneBit(exponent); i++)
		{
			if(((exponent >> i) & 1) == 1)
			{
				ans *= accum;
				ans %= 1_000_000_007;
			}
			accum *= accum;
			accum %= 1_000_000_007;
		}
		return ans;
	}
	
	/////////////// everything below is just my utils code ///////////////////////////
	
	static int[] array(int...arr) {return arr;}
	static long[] array(long...arr) {return arr;}
	static double[] array(double...arr) {return arr;}
	
	static class FastScanner
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = null;
		boolean hasFailed = false;
		
		boolean canReturn()
		{
			while(st == null || !st.hasMoreTokens())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch(IOException e)
				{
					hasFailed = true;
					return false;
				}
			}
			return true;
		}
		
		String next()
		{
			if(this.canReturn())
			{
				return st.nextToken();
			}
			return null;
		}
		
		String nextLine()
		{
			try
			{
				st = null;
				return br.readLine();
			}
			catch(IOException e)
			{
				hasFailed = true;
				return null;
			}
		}
		
		char[] nextChara()
		{
			String ret = this.next();
			if(ret != null) return ret.toCharArray();
			return null;
		}
		
		char[] nextLineChara()
		{
			String ret = this.nextLine();
			if(ret != null) return ret.toCharArray();
			return null;
		}
		
		int nextInt()
		{
			if(this.canReturn())
			{
				return Integer.parseInt(this.next());
			}
			return Integer.MIN_VALUE;
		}
		
		long nextLong()
		{
			if(this.canReturn())
			{
				return Long.parseLong(this.next());	
			}
			return Long.MIN_VALUE;
		}
		
		double nextDouble()
		{
			if(this.canReturn())
			{
				return Double.parseDouble(this.next());	
			}
			return Double.MIN_VALUE;
		}
	}
}