Special Agent Smart Beaver works in a secret research department of ABBYY. He's been working there for a long time and is satisfied with his job, as it allows him to eat out in the best restaurants and order the most expensive and exotic wood types there. The content special agent has got an important task: to get the latest research by British scientists on the English Language. These developments are encoded and stored in a large safe. The Beaver's teeth are strong enough, so the authorities assured that upon arriving at the place the beaver won't have any problems with opening the safe.And he finishes his aspen sprig and leaves for this important task. Of course, the Beaver arrived at the location without any problems, but alas. He can't open the safe with his strong and big teeth. At this point, the Smart Beaver get a call from the headquarters and learns that opening the safe with the teeth is not necessary, as a reliable source has sent the following information: the safe code consists of digits and has no leading zeroes. There also is a special hint, which can be used to open the safe. The hint is string s with the following structure:  if si = "?", then the digit that goes i-th in the safe code can be anything (between 0 to 9, inclusively);  if si is a digit (between 0 to 9, inclusively), then it means that there is digit si on position i in code;  if the string contains letters from "A" to "J", then all positions with the same letters must contain the same digits and the positions with distinct letters must contain distinct digits.  The length of the safe code coincides with the length of the hint. For example, hint "?JGJ9" has such matching safe code variants: "51919", "55959", "12329", "93539" and so on, and has wrong variants such as: "56669", "00111", "03539" and "13666".After receiving such information, the authorities change the plan and ask the special agents to work quietly and gently and not to try to open the safe by mechanical means, and try to find the password using the given hint.At a special agent school the Smart Beaver was the fastest in his platoon finding codes for such safes, but now he is not in that shape: the years take their toll ... Help him to determine the number of possible variants of the code to the safe, matching the given hint. After receiving this information, and knowing his own speed of entering codes, the Smart Beaver will be able to determine whether he will have time for tonight's show "Beavers are on the trail" on his favorite TV channel, or he should work for a sleepless night...

The first line contains string s — the hint to the safe code. String s consists of the following characters: ?, 0-9, A-J. It is guaranteed that the first character of string s doesn't equal to character 0. The input limits for scoring 30 points are (subproblem A1):    1 ≤ |s| ≤ 5.  The input limits for scoring 100 points are (subproblems A1+A2):    1 ≤ |s| ≤ 105.  Here |s| means the length of string s.

Print the number of codes that match the given hint.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Threading;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
#if !ONLINE_JUDGE
            Console.SetIn(new System.IO.StreamReader(@"..\..\..\in"));
            Console.SetOut(new System.IO.StreamWriter(@"..\..\..\out"));
            for (int testN = 0; testN < 2; testN++)
            {
#endif
                //SetCulture();
                var s = Console.ReadLine();
                var alp = "ABCDEFGHIJ";
                HashSet<char> hs = new HashSet<char>();
                long res = 1;
                var rest = 10;
                if (s[0] == '?')
                {
                    res = 9;
                }
                if(alp.Contains(s[0]))
                {
                    res = 9;
                    rest = 9;
                    hs.Add(s[0]);
                }
                for (int i = 1; i < s.Length; i++)
                {
                    if (s[i] == '?')
                    {
                        res *= 10;
                    }
                    if (alp.Contains(s[i]))
                    {
                        if (!hs.Contains(s[i]))
                        {
                            res *= rest;
                            rest--;
                            hs.Add(s[i]);
                        }
                    }
                }

                Console.WriteLine(res);
                //Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo, "{0:F4}", res));
#if !ONLINE_JUDGE
                Console.ReadLine();
            }
            Console.In.Close();
            Console.Out.Close();
#endif
        }

        private static char[] _defaultSplitter = new char[] { ' ', '\t' };

        private static void SetCulture()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        }

        private static char[] ReadChars(int n)
        {
            char[] buffer = new char[n];
            Console.In.ReadBlock(buffer, 0, n);
            return buffer;
        }

        private static string[] ReadAll()
        {
            return Console.In.ReadToEnd().Split(new char[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
        }

        private static string[] ReadWords(char[] splitter)
        {
            return Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
        }

        private static string[] ReadWords()
        {
            return ReadWords(_defaultSplitter);
        }

        private static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }

        private static int[] ReadInts(char[] splitter)
        {
            return Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToArray();
        }

        private static int[] ReadInts()
        {
            return ReadInts(_defaultSplitter);
        }

        private static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }

        private static double ReadDouble()
        {
            return double.Parse(Console.ReadLine(), NumberFormatInfo.InvariantInfo);
        }

        private static int _pos = 0;
        private static string[] _inputLine = new string[0];

        private static void CheckInputLine()
        {
            if (_pos >= _inputLine.Length)
            {
                _inputLine = ReadWords();
                _pos = 0;
            }
        }

        private static string NextWord()
        {
            CheckInputLine();
            return _inputLine[_pos++];
        }

        private static int NextInt()
        {
            CheckInputLine();
            return int.Parse(_inputLine[_pos++]);
        }

        private static long NextLong()
        {
            CheckInputLine();
            return long.Parse(_inputLine[_pos++]);
        }
    }
}

using System;

class Program{
	static void Main(){
		string input = Console.ReadLine();
		int[] box = new int[10];
		int mul = 10;
		int ans = 1;

		for(int i = 0; i < input.Length; i++){
			if(i == 0)
				mul--;
			if(input[i] == '?')
				ans *= i == 0 ? 9 : 10;
			if(input[i] >= 'A' && input[i] <= 'J'){
				if(box[input[i] - 'A'] == 0){
					ans *= mul;
					box[input[i] - 'A']++;
					mul--;
				}
			}
			if(i == 0)
				mul++;
		}

		Console.WriteLine(ans);
	}
}

using System;
using System.IO;
using System.Linq;

namespace AcmSolution
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var s = Console.ReadLine();

            var was = new bool['Z' - 'A' + 1];
            long ans = 1;
            int wasCnt = 0;

            for (int i = 0; i < s.Length; ++i) if ('9' < s[i] || s[i] < '0')
            {
                if (s[i] == '?')
                    ans *= i == 0 ? 9 : 10;
                else if (!was[s[i] - 'A'])
                {
                    was[s[i] - 'A'] = true;

                    ans *= i == 0 ? 9 : (10 - wasCnt);
                    wasCnt++;
                }
            }

            Console.WriteLine(ans);
        }
    }
}

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      //var fileStreamIn = new FileStream("in.txt", FileMode.Open);
      //var streamReader = new StreamReader(fileStreamIn);
      //Console.SetIn(streamReader);

      //var filestreamOut = new FileStream("out.txt", FileMode.Create);
      //var streamWriter = new StreamWriter(filestreamOut);
      //streamWriter.AutoFlush = true;
      //Console.SetOut(streamWriter);

      var str = Console.ReadLine();
      var symbols = new HashSet<char>();
      long answer = 1;
      for (int i = 0; i < str.Length; ++i)
      {
        var symbol = str[i];
        if (symbol == '?')
        {
          answer *= (i == 0) ? 9 : 10;
        }
        else if (char.IsLetter(symbol) && !symbols.Contains(symbol))
        {
          answer *= (i == 0) ? 9 : 10 - symbols.Count;
          symbols.Add(symbol);
        }
      }

      Console.WriteLine(answer);

      //streamReader.Close();
      //streamWriter.Close();
    }
  }
}

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            double combs = 1;
            double q = 0;
            Dictionary<int, int> symb = new Dictionary<int,int>();
            for (int i = 0; i < input.Length; i++)
            {
                Char currSymb = input[i];
                if (currSymb == '?')
                {
                    q++;
                }
                else if ((Convert.ToByte(currSymb) >= 65) && (Convert.ToByte(currSymb) <= 74))
                {
                    symb[currSymb] = 1;
                }
            }
            int a = 0;
            if (input[0] == '?')
            {
                combs = 9;
                q--;
            }
            else if (input[0] >= '0' && input[0] <= '9')
            {
                ;
            }
            else
            {
                a = 1;
            }
            for (int i = 0; i < symb.Count; i++)
            {
                combs *= (10 - Math.Max(i, a));
            }
            StringBuilder res = new StringBuilder(Convert.ToString(combs));
            while (q-- > 0)
            {
                res.Append('0');
            }
            Console.WriteLine(res.ToString());

        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static int I(string s)
        {
            return Convert.ToInt32(s);
        }
        static void Main(string[] args)
        {
            HashSet<char> set = new HashSet<char>();
            string hint = Console.ReadLine();
            int total = 1;
            for (int i = 0; i < hint.Length; i++)
            {
                if (!Char.IsDigit(hint, i))
                {
                    if (i == 0)
                    {
                        total *= 9;
                        if (hint[i] != '?')
                            set.Add(hint[i]);
                    }
                    else
                    {
                        if (hint[i] == '?')
                        {
                            total *= 10;
                        }
                        else if (!set.Contains(hint[i]))
                        {
                            total *= (10 - set.Count);
                            set.Add(hint[i]);
                        }
                    }
                }
            }
            Console.WriteLine(total);
        }
    }
}

using System;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;

namespace Special_Task
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            string s = reader.ReadLine();
            BigInteger big = 1;

            var letters = new int['J' - 'A' + 1];
            foreach (char letter in s)
            {
                if (letter >= 'A' && letter <= 'J')
                {
                    letters[letter-'A'] = 1;
                }
            }

            int lCount = letters.Sum();
            int sCount = s.Count(c => c == '?');

            if (s[0]=='?')
            {
                big = 9;
                sCount--;
            }

            if (sCount > 0)
                big *= Pow(10, sCount);

            if (lCount > 0)
            {
                if (s[0] >= 'A' && s[0] <= 'J')
                {
                    big *= 9;
                }
                else
                {
                    big *= 10;
                }

                for (int i = 1; i < lCount; i++)
                {
                    big *= 10 - i;
                }
            }

            writer.WriteLine(big);
            writer.Flush();
        }

        private static BigInteger Pow(BigInteger a, int k)
        {
            BigInteger r = 1;
            while (k > 0)
            {
                if ((k & 1) == 1)
                {
                    r = (r*a);
                }
                a = (a*a);
                k >>= 1;
            }
            return r;
        }
    }
}

using System;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Globalization;
using System.Collections.Generic;
using System.Threading;
using kp.Algo;

namespace CodeForces
{
	internal class Solution
	{
		const int StackSize = 20 * 1024 * 1024;

		private void Solve()
		{
			string s = NextLine().Trim();
			int q = 0;
			bool[] was = new bool[10];
			int[] id = new int[10];
			int letters = 0;
			foreach ( var c in s )
			{
				if ( c == '?' ) ++q;
				else if ( c >= 'A' && c <= 'J' )
				{
					if ( !was[c - 'A'] )
						id[c - 'A'] = letters++;
					was[c - 'A'] = true;
				}
			}

			if ( letters == 0 )
			{
				int cnt = 1;
				if ( s[0] == '?' )
				{
					--q;
					cnt *= 9;
				}

				Out.Write( cnt );
				if ( q > 0 )
				{
					var builder = new StringBuilder( q );
					for ( int i = 0; i < q; ++i ) builder.Append( "0" );
					Out.WriteLine( builder.ToString() );
				}
				else
				{
					Out.WriteLine();
				}
			}
			else
			{
				var p = PermutationUtils.First( letters );
				long cntZ = 0;
				do
				{
					bool good = true;
					if ( s[0] >= 'A' && s[0] <= 'J' && p[id[s[0] - 'A']] == 0 )
						good = false;
					if ( good ) ++cntZ;
				} while ( PermutationUtils.Next( p ) );

				long cnt = 1;
				for ( int i = 2; i <= letters; ++i ) cnt *= i;

				long[,] bin = new long[11, 11];
				for ( int i = 0; i < 11; ++i )
				{
					bin[i, 0] = bin[i, i] = 1;
					for ( int j = 1; j < i; ++j ) bin[i, j] = bin[i - 1, j] + bin[i - 1, j - 1];
				}

				cnt = cnt * bin[9, letters] + cntZ * bin[9, letters - 1];

				if ( s[0] == '?' )
				{
					--q;
					cnt *= 9;
				}

				Out.Write( cnt );
				if ( q > 0 )
				{
					var builder = new StringBuilder( q );
					for ( int i = 0; i < q; ++i ) builder.Append( "0" );
					Out.WriteLine( builder.ToString() );
				}
				else
				{
					Out.WriteLine();
				}
			}
		}

		#region Local wireup

		public int[] NextIntArray( int size )
		{
			var res = new int[size];
			for ( int i = 0; i < size; ++i ) res[i] = NextInt();
			return res;
		}

		public long[] NextLongArray( int size )
		{
			var res = new long[size];
			for ( int i = 0; i < size; ++i ) res[i] = NextLong();
			return res;
		}

		public double[] NextDoubleArray( int size )
		{
			var res = new double[size];
			for ( int i = 0; i < size; ++i ) res[i] = NextDouble();
			return res;
		}

		public int NextInt()
		{
			return _in.NextInt();
		}

		public long NextLong()
		{
			return _in.NextLong();
		}

		public string NextLine()
		{
			return _in.NextLine();
		}

		public double NextDouble()
		{
			return _in.NextDouble();
		}

		readonly Scanner _in = new Scanner();
		static readonly TextWriter Out = Console.Out;

		void Start()
		{
#if !ONLINE_JUDGE
			var timer = new Stopwatch();
			timer.Start();
#endif
			var t = new Thread( Solve, StackSize );
			t.Start();
			t.Join();
#if !ONLINE_JUDGE
			timer.Stop();
			Console.WriteLine( string.Format( CultureInfo.InvariantCulture, "Done in {0} seconds.\nPress <Enter> to exit.", timer.ElapsedMilliseconds / 1000.0 ) );
			Console.ReadLine();
#endif
		}

		static void Main()
		{
			new Solution().Start();
		}

		class Scanner : IDisposable
		{
			#region Fields

			readonly TextReader _reader;
			readonly int _bufferSize;
			readonly bool _closeReader;
			readonly char[] _buffer;
			int _length, _pos;

			#endregion

			#region .ctors

			public Scanner( TextReader reader, int bufferSize, bool closeReader )
			{
				_reader = reader;
				_bufferSize = bufferSize;
				_closeReader = closeReader;
				_buffer = new char[_bufferSize];
				FillBuffer( false );
			}

			public Scanner( TextReader reader, bool closeReader ) : this( reader, 1 << 16, closeReader ) { }

			public Scanner( string fileName ) : this( new StreamReader( fileName, Encoding.Default ), true ) { }

#if ONLINE_JUDGE
			public Scanner() : this( Console.In, false ) { }
#else
			public Scanner() : this( "input.txt" ) { }
#endif

			#endregion

			#region IDisposable Members

			public void Dispose()
			{
				if ( _closeReader )
				{
					_reader.Close();
				}
			}

			#endregion

			#region Properties

			public bool Eof
			{
				get
				{
					if ( _pos < _length ) return false;
					FillBuffer( false );
					return _pos >= _length;
				}
			}

			#endregion

			#region Methods

			private char NextChar()
			{
				if ( _pos < _length ) return _buffer[_pos++];
				FillBuffer( true );
				return _buffer[_pos++];
			}

			private char PeekNextChar()
			{
				if ( _pos < _length ) return _buffer[_pos];
				FillBuffer( true );
				return _buffer[_pos];
			}

			private void FillBuffer( bool throwOnEof )
			{
				_length = _reader.Read( _buffer, 0, _bufferSize );
				if ( throwOnEof && Eof )
				{
					throw new IOException( "Can't read beyond the end of file" );
				}
				_pos = 0;
			}

			public int NextInt()
			{
				var neg = false;
				int res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public long NextLong()
			{
				var neg = false;
				long res = 0;
				SkipWhitespaces();
				if ( !Eof && PeekNextChar() == '-' )
				{
					neg = true;
					_pos++;
				}
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					var c = NextChar();
					if ( c < '0' || c > '9' ) throw new ArgumentException( "Illegal character" );
					res = 10 * res + c - '0';
				}
				return neg ? -res : res;
			}

			public string NextLine()
			{
				SkipUntilNextLine();
				if ( Eof ) return "";
				var builder = new StringBuilder();
				while ( !Eof && !IsEndOfLine( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return builder.ToString();
			}

			public double NextDouble()
			{
				SkipWhitespaces();
				var builder = new StringBuilder();
				while ( !Eof && !IsWhitespace( PeekNextChar() ) )
				{
					builder.Append( NextChar() );
				}
				return double.Parse( builder.ToString(), CultureInfo.InvariantCulture );
			}

			private void SkipWhitespaces()
			{
				while ( !Eof && IsWhitespace( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private void SkipUntilNextLine()
			{
				while ( !Eof && IsEndOfLine( PeekNextChar() ) )
				{
					++_pos;
				}
			}

			private static bool IsWhitespace( char c )
			{
				return c == ' ' || c == '\t' || c == '\n' || c == '\r';
			}

			private static bool IsEndOfLine( char c )
			{
				return c == '\n' || c == '\r';
			}

			#endregion
		}

		#endregion
	}
}

namespace kp.Algo { }

namespace kp.Algo
{
	static class PermutationUtils
	{
		public static int[] First( int n )
		{
			int[] res = new int[n];
			for ( int i = 0; i < n; ++i ) res[i] = i;
			return res;
		}
		public static bool Next( int[] p )
		{
			if ( p.Length == 1 ) return false;
			int i = 0;
			++i;
			if ( i == p.Length ) return false;
			i = p.Length;
			--i;

			for ( ; ; )
			{
				int ii = i;
				--i;
				if ( p[i].CompareTo( p[ii] ) < 0 )
				{
					int j = p.Length;
					do
					{
						--j;
					} while ( p[i].CompareTo( p[j] ) >= 0 );
					int tmp = p[i];
					p[i] = p[j];
					p[j] = tmp;
					int l = ii, r = p.Length - 1;
					while ( l < r )
					{
						tmp = p[l];
						p[l] = p[r];
						p[r] = tmp;
						++l;
						--r;
					}
					return true;
				}
				if ( i == 0 )
				{
					int l = 0, r = p.Length - 1;
					while ( l < r )
					{
						int tmp = p[l];
						p[l] = p[r];
						p[r] = tmp;
						++l;
						--r;
					}
					return false;
				}
			}
		}
	}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace ABBYY
{
    class Program
    {
        static void Main(string[] args)
        {
#if ONLINE_JUDGE
            var reader = Console.In;
            var writer = Console.Out;
#else
            StreamReader reader = new StreamReader("input.txt");
            StreamWriter writer = new StreamWriter("output.txt");
#endif
            string s = reader.ReadLine();
            reader.Close();
            Dictionary<char, int> d = new Dictionary<char, int>();
            // TODO: check the first zeroes
            int codes = 1;
            for (int i = 0; i < s.Length; ++i)
            {
                char c = s[i];
                if (c >= 'A' && c <= 'J')
                {
                    if (d.ContainsKey(c))
                        ++d[c];
                    else
                    {
                        if (i > 0)
                            codes *= 10 - d.Count;
                        else
                            codes *= 9;
                        d.Add(c, 1);
                    }
                }
                else if (c == '?')
                {
                    if (i > 0)
                        codes *= 10;
                    else
                        codes *= 9;
                }
            }
            writer.Write(codes);
            writer.Close();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharp
{
    class Program
    {
        static void Main()
        {
            string input = Console.ReadLine();
            int[] count=new int[11];

            int length = input.Length;
            int ans = 1, flag=0;

            if (input[0] == '?')
                ans = 9;

            if (input[0] >= 'A' && input[0] <= 'J')
            {
                int temp = input[0];
                count[temp - 'A']++;
                flag = 1;
            }

            for (int i = 1; i < input.Length; i++)
            {
                if (input[i] == '?')
                    ans = ans * 10;
                if (input[i] >= 'A' && input[i] <= 'J')
                {
                    int temp = input[i];
                    count[temp - 'A']++;
                }

            }

            if (flag == 0)
            {
                int start = 10;
                for (int i = 0; i < types(count); i++)
                {
                    ans *= start;
                    start--;
                }
            }
            else
            {
                int total = types(count);
                if (total == 1)
                    ans *= 9;
                if (total > 1)
                {
                    ans *= 9;
                    int start = 9;
                    for (int i = 1; i < total; i++)
                    {
                        ans *= start;
                        start--;
                    }
                }

            }

            Console.WriteLine(ans);
        }

        static int types(int[] count)
        {
            int total=0;
            for (int i = 0; i < 10; i++)
            {
                if (count[i] > 0)
                    total++;
            }

            return total;
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;

namespace cs
{
    public class Main : Utils
    {
        public Main(TextReader inStream, TextWriter outStream)
            : base(inStream, outStream)
        {
        }

        protected override void Solve()
        {
            string s;
            Next(out s);
            var ans=BigInteger.One;
            var st=new SortedSet<char>();
            for (var i = 0; i < s.Length; i++)
                if (s[i] == '?')
                    ans *= i == 0 ? 9 : 10;
                else if (s[i] >= '0' && s[i] <= '9')
                    continue;
                else if (st.Contains(s[i]))
                    continue;
                else
                {
                    if (i == 0)
                        ans *= 9;
                    else
                        ans *= 10 - st.Count;
                    st.Add(s[i]);
                }
            PrintLine(ans);
        }
    }

    public class PriorityQueue<T>
    {
        #region private members

        private readonly List<T> _data = new List<T>();
        private readonly IComparer<T> _comparer;

        #endregion

        #region constructors

        public PriorityQueue()
        {
            _comparer = Comparer<T>.Default;
        }

        public PriorityQueue(IComparer<T> comparer)
        {
            if (comparer == null)
            {
                _comparer = Comparer<T>.Default;
                return;
            }
            _comparer = comparer;
        }

        #endregion

        #region public members

        public int Count
        {
            get { return _data.Count; }
        }

        public bool Empty()
        {
            return Count == 0;
        }

        public T Top()
        {
            return _data[0];
        }

        public void Push(T item)
        {
            _data.Add(item);
            var curPlace = Count;
            while (curPlace > 1 && _comparer.Compare(item, _data[curPlace / 2 - 1]) > 0)
            {
                _data[curPlace - 1] = _data[curPlace / 2 - 1];
                _data[curPlace / 2 - 1] = item;
                curPlace /= 2;
            }
        }

        public void Pop()
        {
            _data[0] = _data[Count - 1];
            _data.RemoveAt(Count - 1);
            var curPlace = 1;
            while (true)
            {
                var max = curPlace;
                if (Count >= curPlace * 2 && _comparer.Compare(_data[max - 1], _data[2 * curPlace - 1]) < 0)
                    max = 2 * curPlace;
                if (Count >= curPlace * 2 + 1 && _comparer.Compare(_data[max - 1], _data[2 * curPlace]) < 0)
                    max = 2 * curPlace + 1;
                if (max == curPlace) break;
                var item = _data[max - 1];
                _data[max - 1] = _data[curPlace - 1];
                _data[curPlace - 1] = item;
                curPlace = max;
            }
        }

        #endregion
    }

    public static class Algorithm
    {
        public static void Swap<T>(ref T a, ref T b)
        {
            var temp = a;
            a = b;
            b = temp;
        }

        public static void RandomShuffle<T>(T[] a)
        {
            var rnd = new Random(DateTime.Now.Millisecond);
            for (var i = 1; i < a.Length; i++)
                Swap(ref a[i], ref a[rnd.Next(i)]);
        }

        public static bool NextPermutation<T>(T[] a, Comparer<T> comparer = null)
        {
            var comp = comparer ?? Comparer<T>.Default;
            for (var i = a.Length - 1; i > 0; i--)
                if (comp.Compare(a[i], a[i - 1]) > 0)
                {
                    var j = i + 1;
                    for (; j < a.Length; j++)
                        if (comp.Compare(a[j], a[i - 1]) <= 0)
                            break;
                    Swap(ref a[i - 1], ref a[j - 1]);
                    Array.Reverse(a, i, a.Length - i);
                    return true;
                }
            Array.Reverse(a);
            return false;
        }
    }

    public abstract class Utils : IDisposable
    {
        protected readonly TextReader InputStream;
        protected readonly TextWriter OutputStream;

        private string[] _tokens;
        private int _pointer;

        protected Utils()
            : this(Console.In, Console.Out)
        {
        }

        protected Utils(TextReader inputStream, TextWriter outputStream)
        {
            InputStream = inputStream;
            OutputStream = outputStream;
        }

        protected string NextLine()
        {
            try
            {
                return InputStream.ReadLine();
            }
            catch (Exception)
            {
                return null;
            }
        }

        protected string NextString()
        {
            try
            {
                while (_tokens == null || _pointer >= _tokens.Length)
                {
                    _tokens = NextLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    _pointer = 0;
                }
                return _tokens[_pointer++];
            }
            catch (Exception)
            {
                return null;
            }
        }

        protected bool Next<T>(out T ans)
        {
            var str = NextString();
            if (str == null)
            {
                ans = default(T);
                return false;
            }
            ans = (T)Convert.ChangeType(str, typeof(T));
            return true;
        }

        protected void Print(string format, params object[] args)
        {
            OutputStream.Write(format, args);
        }

        protected void PrintLine(string format, params object[] args)
        {
            Print(format, args);
            OutputStream.WriteLine();
        }

        protected void PrintLine()
        {
            OutputStream.WriteLine();
        }

        protected void Print<T>(T o)
        {
            OutputStream.Write(o);
        }

        protected void PrintLine<T>(T o)
        {
            OutputStream.WriteLine(o);
        }

        void IDisposable.Dispose()
        {
            InputStream.Close();
            OutputStream.Close();
        }

        protected abstract void Solve();

        public static void Main(string[] args)
        {
            using (var p = new Main(Console.In, Console.Out))
                p.Solve();
        }
    }
}

#define Online

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CF
{
    delegate double F(double x);
    delegate decimal Fdec(decimal x);

    class Program
    {

        static void Main(string[] args)
        {

#if FileIO
            StreamReader sr = new StreamReader("input.txt");
            StreamWriter sw = new StreamWriter("output.txt");
            Console.SetIn(sr);
            Console.SetOut(sw);
#endif

            A();

#if Online
            Console.ReadLine();
#endif

#if FileIO
            sr.Close();
            sw.Close();
#endif
        }

        static void A()
        {
            string input = ReadLine();
            int tens = 0;
            bool[] letters = new bool[10];
            int cnt = 10;
            int other = 1;
            bool isPrevNull = false;
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i].Equals('?'))
                {
                    if (i == 0)
                    {
                        other *= 9;
                        continue;
                    }
                    tens++;
                }
                else
                {
                    if (!char.IsDigit(input[i]))
                    {
                        if (!letters[input[i] - 'A'])
                        {
                            if (i == 0) other *= --cnt;
                            else other *= cnt--;
                            letters[input[i] - 'A'] = true;
                        }
                    }
                }
            }
            StringBuilder ans = new StringBuilder();
            ans.Append(other.ToString());
            for (int i = 0; i < tens; i++)
                ans.Append("0");
            Console.WriteLine(ans);
        }

        static void B()
        {

        }

        static void C()
        {

        }

        static void D()
        {

        }

        static void E()
        {

        }

        static void TestGen()
        {

        }

        static string[] ReadArray(char sep)
        {
            return Console.ReadLine().Split(sep);
        }

        static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static string ReadLine()
        {
            return Console.ReadLine();
        }
    }

    public static class MyMath
    {
        public static long BinPow(long a, long n, long mod)
        {
            long res = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    res = (res * a) % mod;
                }
                a = (a * a) % mod;
                n >>= 1;
            }
            return res;
        }

        public static long GCD(long a, long b)
        {
            while (b != 0) b = a % (a = b);
            return a;
        }

        public static int GCD(int a, int b)
        {
            while (b != 0) b = a % (a = b);
            return a;
        }

        public static long LCM(long a, long b)
        {
            return (a * b) / GCD(a, b);
        }

        public static int LCM(int a, int b)
        {
            return (a * b) / GCD(a, b);
        }
    }

    class Edge
    {
        public int a;
        public int b;
        public int w;

        public Edge(int a, int b, int w)
        {
            this.a = a;
            this.b = b;
            this.w = w;
        }
    }

    class Graph
    {
        public List<int>[] g;
        public int[] color; //0-white, 1-gray, 2-black
        public int[] o; //open
        public int[] c; //close
        public int[] p;
        public int[] d;
        public List<Edge> e;
        public Stack<int> ans = new Stack<int>();
        public Graph(int n)
        {
            g = new List<int>[n + 1];
            for (int i = 0; i <= n; i++)
                g[i] = new List<int>();
            color = new int[n + 1];
            o = new int[n + 1];
            c = new int[n + 1];
            p = new int[n + 1];
            d = new int[n + 1];
        }

        const int white = 0;
        const int gray = 1;
        const int black = 2;

        public bool DFS(int u, ref int time)
        {
            color[u] = gray;
            time++;
            o[u] = time;
            for (int i = 0; i < g[u].Count; i++)
            {
                int v = g[u][i];
                if (color[v] == gray)
                {
                    return true;
                }
                if (color[v] == white)
                {
                    p[v] = u;
                    if (DFS(v, ref time)) return true;
                }
            }
            color[u] = black;
            ans.Push(u);
            c[u] = time;
            time++;
            return false;
        }
    }

    static class GraphUtils
    {
        const int white = 0;
        const int gray = 1;
        const int black = 2;

        public static void BFS(int s, Graph g)
        {
            Queue<int> q = new Queue<int>();
            q.Enqueue(s);
            while (q.Count != 0)
            {
                int u = q.Dequeue();
                for (int i = 0; i < g.g[u].Count; i++)
                {
                    int v = g.g[u][i];
                    if (g.color[v] == white)
                    {
                        g.color[v] = gray;
                        g.d[v] = g.d[u] + 1;
                        g.p[v] = u;
                        q.Enqueue(v);
                    }
                }
                g.color[u] = black;
            }
        }

        public static bool DFS(int u, ref int time, Graph g, Stack<int> st)
        {
            g.color[u] = gray;
            time++;
            g.o[u] = time;
            for (int i = 0; i < g.g[u].Count; i++)
            {
                int v = g.g[u][i];
                if (g.color[v] == gray)
                {
                    return true;
                }
                if (g.color[v] == white)
                {
                    g.p[v] = u;
                    if (DFS(v, ref time, g, st)) return true;
                }
            }
            g.color[u] = black;
            st.Push(u);
            g.c[u] = time;
            time++;
            return false;
        }

        public static void FordBellman(int u, Graph g)
        {
            int n = g.g.Length;
            for (int i = 0; i <= n; i++)
            {
                g.d[i] = int.MaxValue;
                g.p[i] = 0;
            }

            g.d[u] = 0;

            for (int i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < g.e.Count; j++)
                {
                    if (g.d[g.e[j].a] != int.MaxValue)
                    {
                        if (g.d[g.e[j].a] + g.e[j].w < g.d[g.e[j].b])
                        {
                            g.d[g.e[j].b] = g.d[g.e[j].a] + g.e[j].w;
                            g.p[g.e[j].b] = g.e[j].a;
                        }
                    }
                }
            }
        }
    }

    static class ArrayUtils
    {
        public static int BinarySearch(int[] a, int val)
        {
            int left = 0;
            int right = a.Length - 1;
            int mid;

            while (left < right)
            {
                mid = left + ((right - left) >> 1);
                if (val <= a[mid])
                {
                    right = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }

            if (a[left] == val)
                return left;
            else
                return -1;
        }

        public static double Bisection(F f, double left, double right, double eps)
        {
            double mid;
            while (right - left > eps)
            {
                mid = left + ((right - left) / 2d);
                if (Math.Sign(f(mid)) != Math.Sign(f(left)))
                    right = mid;
                else
                    left = mid;
            }
            return (left + right) / 2d;
        }

        public static decimal TernarySearchDec(Fdec f, decimal eps, decimal l, decimal r, bool isMax)
        {
            decimal m1, m2;
            while (r - l > eps)
            {
                m1 = l + (r - l) / 3m;
                m2 = r - (r - l) / 3m;
                if (f(m1) < f(m2))
                    if (isMax)
                        l = m1;
                    else
                        r = m2;
                else
                    if (isMax)
                        r = m2;
                    else
                        l = m1;
            }
            return r;
        }

        public static double TernarySearch(F f, double eps, double l, double r, bool isMax)
        {
            double m1, m2;
            while (r - l > eps)
            {
                m1 = l + (r - l) / 3d;
                m2 = r - (r - l) / 3d;
                if (f(m1) < f(m2))
                    if (isMax)
                        l = m1;
                    else
                        r = m2;
                else
                    if (isMax)
                        r = m2;
                    else
                        l = m1;
            }
            return r;
        }

        public static void Merge<T>(T[] A, int p, int q, int r, T[] L, T[] R, Comparison<T> comp)
        {
            for (int i = p; i <= q; i++)
                L[i] = A[i];
            for (int i = q + 1; i <= r; i++)
                R[i] = A[i];

            for (int k = p, i = p, j = q + 1; k <= r; k++)
            {
                if (i > q)
                {
                    for (; k <= r; k++, j++)
                        A[k] = R[j];
                    return;
                }
                if (j > r)
                {
                    for (; k <= r; k++, i++)
                        A[k] = L[i];
                    return;
                }
                if (comp(L[i], R[j]) <= 0)
                {
                    A[k] = L[i];
                    i++;
                }
                else
                {
                    A[k] = R[j];
                    j++;
                }
            }
        }

        public static void Merge_Sort<T>(T[] A, int p, int r, T[] L, T[] R, Comparison<T> comp)
        {
            if (p >= r) return;
            int q = p + ((r - p) >> 1);
            Merge_Sort(A, p, q, L, R, comp);
            Merge_Sort(A, q + 1, r, L, R, comp);
            Merge(A, p, q, r, L, R, comp);
        }

        public static void Merge<T>(T[] A, int p, int q, int r, T[] L, T[] R) where T : IComparable<T>
        {
            for (int i = p; i <= q; i++)
                L[i] = A[i];
            for (int i = q + 1; i <= r; i++)
                R[i] = A[i];

            for (int k = p, i = p, j = q + 1; k <= r; k++)
            {
                if (i > q)
                {
                    for (; k <= r; k++, j++)
                        A[k] = R[j];
                    return;
                }
                if (j > r)
                {
                    for (; k <= r; k++, i++)
                        A[k] = L[i];
                    return;
                }
                if (L[i].CompareTo(R[j]) <= 0)
                {
                    A[k] = L[i];
                    i++;
                }
                else
                {
                    A[k] = R[j];
                    j++;
                }
            }
        }

        public static void Merge_Sort<T>(T[] A, int p, int r, T[] L, T[] R) where T : IComparable<T>
        {
            if (p >= r) return;
            int q = p + ((r - p) >> 1);
            Merge_Sort(A, p, q, L, R);
            Merge_Sort(A, q + 1, r, L, R);
            Merge(A, p, q, r, L, R);
        }

        static void Shake<T>(T[] a)
        {
            Random rnd = new Random(Environment.TickCount);
            T temp;
            int b, c;
            for (int i = 0; i < a.Length; i++)
            {
                b = rnd.Next(0, a.Length);
                c = rnd.Next(0, a.Length);
                temp = a[b];
                a[b] = a[c];
                a[c] = temp;
            }
        }
    }
}

using System;

    class Program
    {
        static void Main()
        {
            string s = Console.ReadLine();
            int a = 1;
            int d = 0;
            bool b=false;
            bool e=false;
            if (s[0] == '?' || 'A' <= s[0] && s[0] <= 'J') b = true;
            for (char c = 'A'; c <= 'J'; c++) {
                e = false;
                for (int i = 0; i < s.Length; i++)
                    if (s[i] == c) e = true;
                if (e) d++;
            }
            for (int i = 0; i < s.Length; i++)
                if (s[i] == '?') a *= 10;
            for (; d > 0; d--) a *= 11 - d;
            if (b) a = a / 10 * 9;
            Console.WriteLine(a);

        }
    }

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.Threading;
using System.Numerics;

class Problem
{
    private static Decimal GetNumericValue(string value, NumberStyles styles)
    {
        Decimal number;

        number = Decimal.Parse(value, styles);
        return number;
    }

    public void Solution(TextReader Input, TextWriter Output)
    {
        string s;
        s = Input.ReadLine();
        bool[] used = new bool[10];

        BigInteger[] fact = new BigInteger[11];
        fact[0] = fact[1] = 1;
        for (int i = 2; i <= 10; i++)
            fact[i] = fact[i - 1] * i;

        int x = 0;
        bool z = false;
        BigInteger ans = 1;

        if (s.Length == 1)
        {
            if ('0' <= s[0] && s[0] <= '9')
                Output.WriteLine("1");
            else
                Output.WriteLine("9");
            return;
        }

        for (int i = 0; i < s.Length; i++)
        {
            if (s[i] == '?')
                if (i == 0)
                    ans *= 9;
                else
                    ans *= 10;
            else
                if ('A' <= s[i] && s[i] <= 'Z')
                {
                    int k = s[i] - 'A';
                    if (!used[k])
                    {
                        x++;
                        used[k] = true;
                    }
                    if (i == 0)
                        z = true;
                }
        }

        if (x == 0)
        {
            Output.WriteLine(ans.ToString());
            return;
        }

        if (!z)
        {

            BigInteger tmp = fact[10] / fact[10 - x];
            ans *= tmp;
        }
        else
        {
            BigInteger tmp = 9 * fact[9] / fact[10 - x];
            ans *= tmp;
        }

        Output.WriteLine(ans.ToString());
    }
}

class Program
{
    public static void Main()
    {
#if Local
        var inputStream = new StreamReader(@"..\..\input.txt");
        var outputStream = new StreamWriter(@"..\..\output.txt");

        new Problem().Solution(inputStream, outputStream);

        inputStream.Close();
        outputStream.Close();
#else
                new Problem().Solution(Console.In, Console.Out);
#endif
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string st = Console.ReadLine();
            bool[] f = new bool[10];
            int ff = 10;
            long k=1;
            for (int i = 0; i < 10; i++)
            {
                f[i] = true;
            }
            for (int i = 0; i < st.Length; i++)
            {
                if (st[i] == '?')
                {
                    if (i == 0)
                    {
                        k = k * 9;
                    }
                    else
                    {
                        k = k * 10;
                    }
                }
                if (st[i] >= 'A' && st[i] <= 'J')
                {
                    if (ff > 0 && f[(int)st[i] - 65] == true)
                    {
                        if (i == 0)
                        {
                            k = k * 9;
                        }
                        else
                        {
                            k = k * ff;
                        }
                        ff--;
                    }
                    f[(int)st[i] - 65] = false;
                }
            }
            Console.WriteLine(k.ToString());
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace A1
{
    class Program
    {
        static void Main(string[] args)
        {
            int res = 1;
            String s = Console.ReadLine();
            Dictionary<char,char> d=new Dictionary<char,char>();
            int mul;
            for (int i = 0; i < s.Length;i++ )
            {
                if (i == 0) mul = 9;
                else mul = 10;
                if (s[i] == '?')
                    res *= mul;
                if (s[i] >= 'A' && s[i] <= 'J')
                {
                    if(i!=0)mul = 10-d.Count;
                    try
                    {
                        d.Add(s[i], s[i]);
                        res *= mul;
                    }
                    catch
                    {

                    }
                }
            }
            Console.WriteLine(res);
        }
    }
}

using System;

namespace abbycup1
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string [] n9 = {"9", "81", "648", "4536", "27216", "136080", "544320", "1632960", "326592", "326592"};
			string [] n10 = {"10", "90", "720", "5040", "30240", "151200", "604800", "1814400", "3628800", "3628800"};
			char [] letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
			bool nine = false;
			bool voprfirst=false;
			int count = 0;
			int voprcount=0;

			char [] input = Console.ReadLine().ToCharArray();

			if ( Array.BinarySearch(letters, input[0]) >= 0 || input[0] == '?') {
				nine = true;
			}

			if ( input[0] == '?') {
				voprfirst = true;
			}

			Array.Sort(input);

			for (int i=0; i<=9; i++) {
				if (Array.BinarySearch(input, letters[i])>=0) {
					count++;
				}
			}

			int vopr = Array.BinarySearch(input, '?');
			if (vopr>=0) {
				for (int i=0; i<input.GetLength(0); i++) {
					if (input[i]=='?') {
						voprcount++;
					}
				}
			}

			if (voprfirst) {
				voprcount--;
			}

			if (count>0 && !voprfirst) {
				if (nine) {
					Console.Write(n9[count-1]);
				} else {
					Console.Write(n10[count-1]);
				}
			}

			if (voprfirst && count==0) {
				Console.Write("9");
			}

			if (count==0 && !voprfirst) {
				Console.Write("1");
			}

			if (count>0 && voprfirst) {
				Console.Write(n9[count-1]);
				Console.Write("0");
			}

			for (int i=1; i<=voprcount; i++) {
				Console.Write("0");
			}
			Console.WriteLine("");

		}
	}
}

using System;
using System.Collections;
using System.Collections.Generic;

class Myon
{
    public Myon() { }
    public static int Main()
    {
        new Myon().solve();
        return 0;
    }

    void solve()
    {
        Scanner cin = new Scanner();

        int question = 0;
        Dictionary<int, int> num = new Dictionary<int, int>();
        Dictionary<int, int> c = new Dictionary<int, int>();
        string s = cin.next();
        int n = s.Length;

        for (int i = 0; i < n; i++)
        {
            char now = s[i];
            if (now >= '0' && now <= '9')
            {
                num[now] = 1;
            }
            else if (now == '?')
            {
                question++;
            }
            else
            {
                c[now] = 1;
            }
        }

        long ret = 1;
        int a = 0;
        if (s[0] >= '0' && s[0] <= '9')
        {
            ;
        }
        else if (s[0] == '?')
        {
            ret *= 9;
            question--;
        }
        else
        {
            a = 1;
        }

        for (int i = 0; i < c.Count; i++)
        {
            ret *= 10 - Math.Max(i, a);
        }
        Console.Write(ret);
        for (int i = 0; i < question; i++)
        {
            Console.Write("0");
        }
        Console.WriteLine();
    }

}

class Scanner
{
    string[] s;
    int i;

    char[] cs = new char[] { ' ' };

    public Scanner()
    {
        s = new string[0];
        i = 0;
    }

    public string next()
    {
        if (i < s.Length) return s[i++];
        s = Console.ReadLine().Split(cs, StringSplitOptions.RemoveEmptyEntries);
        i = 0;
        return s[i++];
    }

    public int nextInt()
    {
        return int.Parse(next());
    }

    public long nextLong()
    {
        return long.Parse(next());
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Threading;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
#if !ONLINE_JUDGE
            Console.SetIn(new System.IO.StreamReader(@"..\..\..\in"));
            Console.SetOut(new System.IO.StreamWriter(@"..\..\..\out"));
            for (int testN = 0; testN < 4; testN++)
            {
#endif
                //SetCulture();
                var s = Console.ReadLine();
                var alp = "ABCDEFGHIJ";
                HashSet<char> hs = new HashSet<char>();
                long res = 1;
                var rest = 10;
                int cnt = 0;
                if (s[0] == '?')
                {
                    res = 9;
                }
                if(alp.Contains(s[0]))
                {
                    res = 9;
                    rest = 9;
                    hs.Add(s[0]);
                }
                for (int i = 1; i < s.Length; i++)
                {
                    if (s[i] == '?')
                    {
                        //res *= 10;
                        cnt++;
                    }
                    if (alp.Contains(s[i]))
                    {
                        if (!hs.Contains(s[i]))
                        {
                            res *= rest;
                            rest--;
                            hs.Add(s[i]);
                        }
                    }
                }
                Console.Write(res);
                for (int i = 0; i < cnt; i++)
                {
                    Console.Write('0');
                }
                //Console.WriteLine(res);
                //Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo, "{0:F4}", res));
#if !ONLINE_JUDGE
                Console.WriteLine();
                Console.ReadLine();
            }
            Console.In.Close();
            Console.Out.Close();
#endif
        }

        private static char[] _defaultSplitter = new char[] { ' ', '\t' };

        private static void SetCulture()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        }

        private static char[] ReadChars(int n)
        {
            char[] buffer = new char[n];
            Console.In.ReadBlock(buffer, 0, n);
            return buffer;
        }

        private static string[] ReadAll()
        {
            return Console.In.ReadToEnd().Split(new char[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
        }

        private static string[] ReadWords(char[] splitter)
        {
            return Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
        }

        private static string[] ReadWords()
        {
            return ReadWords(_defaultSplitter);
        }

        private static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }

        private static int[] ReadInts(char[] splitter)
        {
            return Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToArray();
        }

        private static int[] ReadInts()
        {
            return ReadInts(_defaultSplitter);
        }

        private static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }

        private static double ReadDouble()
        {
            return double.Parse(Console.ReadLine(), NumberFormatInfo.InvariantInfo);
        }

        private static int _pos = 0;
        private static string[] _inputLine = new string[0];

        private static void CheckInputLine()
        {
            if (_pos >= _inputLine.Length)
            {
                _inputLine = ReadWords();
                _pos = 0;
            }
        }

        private static string NextWord()
        {
            CheckInputLine();
            return _inputLine[_pos++];
        }

        private static int NextInt()
        {
            CheckInputLine();
            return int.Parse(_inputLine[_pos++]);
        }

        private static long NextLong()
        {
            CheckInputLine();
            return long.Parse(_inputLine[_pos++]);
        }
    }
}

using System;

class Program{
	static void Main(){
		string input = Console.ReadLine();
		int[] box = new int[10];
		int mul = 10;
		int ans = 1;
		int zer = 0;

		for(int i = 0; i < input.Length; i++){
			if(i == 0){
				if(input[i] == '?'){
					ans *= 9;
					continue;
				}
				mul--;
			}
			if(input[i] == '?')
				zer++;
			if(input[i] >= 'A' && input[i] <= 'J')
				if(box[input[i] - 'A'] == 0){
					ans *= mul;
					box[input[i] - 'A']++;
					mul--;
				}
			if(i == 0)
				mul++;
		}
		Console.WriteLine(ans + new string('0', zer));
	}
}

using System;
using System.IO;
using System.Linq;

namespace AcmSolution
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var s = Console.ReadLine();

            var was = new bool['Z' - 'A' + 1];
            long ans = 1;
            int wasCnt = 0;

            int tens = 0;

            for (int i = 0; i < s.Length; ++i) if ('9' < s[i] || s[i] < '0')
            {
                if (s[i] == '?')
                {
                    if (i == 0) ans *= 9;
                    else tens++;
                }
                else if (!was[s[i] - 'A'])
                {
                    was[s[i] - 'A'] = true;

                    ans *= i == 0 ? 9 : (10 - wasCnt);
                    wasCnt++;
                }
            }

            Console.WriteLine(ans + new string('0', tens));
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      //var fileStreamIn = new FileStream("in.txt", FileMode.Open);
      //var streamReader = new StreamReader(fileStreamIn);
      //Console.SetIn(streamReader);

      //var filestreamOut = new FileStream("out.txt", FileMode.Create);
      //var streamWriter = new StreamWriter(filestreamOut);
      //streamWriter.AutoFlush = true;
      //Console.SetOut(streamWriter);

      var str = Console.ReadLine();
      var symbols = new HashSet<char>();
      long answer = 1;
      int countZero = 0;
      for (int i = 0; i < str.Length; ++i)
      {
        var symbol = str[i];
        if (symbol == '?')
        {
          answer *= (i == 0) ? 9 : 10;
        }
        else if (char.IsLetter(symbol) && !symbols.Contains(symbol))
        {
          answer *= (i == 0) ? 9 : 10 - symbols.Count;
          symbols.Add(symbol);
        }

        while (answer % 10 == 0)
        {
          answer = answer / 10;
          ++countZero;
        }
      }

      Console.WriteLine(answer + new String('0', countZero));

      //streamReader.Close();
      //streamWriter.Close();
    }
  }
}

using System;
using System.IO;
using System.Linq;
using System.Text;

namespace Special_Task
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            string s = reader.ReadLine();
            long big = 1;

            var letters = new int['J' - 'A' + 1];
            foreach (char letter in s)
            {
                if (letter >= 'A' && letter <= 'J')
                {
                    letters[letter - 'A'] = 1;
                }
            }

            int lCount = letters.Sum();
            int sCount = s.Count(c => c == '?');

            if (s[0] == '?')
            {
                big = 9;
                sCount--;
            }

            if (lCount > 0)
            {
                if (s[0] >= 'A' && s[0] <= 'J')
                {
                    big *= 9;
                }
                else
                {
                    big *= 10;
                }

                for (int i = 1; i < lCount; i++)
                {
                    big *= 10 - i;
                }
            }

            writer.Write(big);
            if (sCount > 0)
                writer.Write(new string('0', sCount));

            writer.Flush();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Numerics;

namespace ABBYY
{
    class A
    {
        static void Main(string[] args)
        {
#if ONLINE_JUDGE
            var reader = Console.In;
            var writer = Console.Out;
#else
            StreamReader reader = new StreamReader("input.txt");
            StreamWriter writer = new StreamWriter("output.txt");
#endif
            string s = reader.ReadLine();
            reader.Close();
            Dictionary<char, object> d = new Dictionary<char, object>();
            //BigInteger
            int codes = 1, zeroes = 0;
            for (int i = 0; i < s.Length; ++i)
            {
                char c = s[i];
                if (c == '?')
                {
                    if (i > 0)
                        ++zeroes;
                    else
                        codes *= 9;
                }
                else if (c >= 'A' && c <= 'J')
                    if (d.Count < 10 && !d.ContainsKey(c))
                    {
                        if (i > 0)
                            codes *= 10 - d.Count;
                        else
                            codes *= 9;
                        d.Add(c, 1);
                    }
            }
            if (codes > 1 || zeroes == 0)
                writer.Write(codes);
            else
                writer.Write(1);
            for (int i = 0; i < zeroes; ++i)
                writer.Write(0);
            writer.Close();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = Console.ReadLine();
            HashSet<char> letset = new HashSet<char>();
            int k = 0;
            int kq = 0;
            for (int i = 0; i < s.Length; ++i)
            {

                if (s[i] >= 'A' && s[i] <= 'J' && !letset.Contains(s[i]))
                {
                    letset.Add(s[i]);
                    k++;
                }

                if (s[i] == '?')
                    kq++;

            }
            BigInteger ans = BigInteger.One;
            BigInteger m = BigInteger.Multiply(ans, 10); ;

            for (int i = 0; i < k; i++)
            {
                ans = BigInteger.Multiply(ans, m);
                m = BigInteger.Subtract(m, BigInteger.One);

            }

            if (s[0] >= '0' && s[0] <= '9')
            {
                Console.Write(ans);
                for (int i = 0; i < kq; i++) Console.Write("0");
            }
            else
            {
                if (k == 0)
                {

                    Console.Write(9);
                    for (int i = 0; i < kq-1; i++) Console.Write("0");
                }
                else
                {
                    Console.Write(BigInteger.Multiply(BigInteger.Divide(ans, 10), 9));

                    for (int i = 0; i < kq; i++) Console.Write("0");
                }
            }

         //  Console.ReadKey();
        }
        public static BigInteger binpow(BigInteger a, int n)
        {
            BigInteger res = 1;
            while (n > 0)
            {
                if (n % 2 != 0)
                    res = BigInteger.Multiply(res, a);
                a = BigInteger.Multiply(a, a);
                n >>= 1;
            }
            return res;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharp
{
    class Program
    {
        static void Main()
        {
            string input = Console.ReadLine();
            int[] count=new int[11];

            int length = input.Length;
            int ans = 1, flag=0, zercount=0;

            if (input[0] == '?')
                ans = 9;

            if (input[0] >= 'A' && input[0] <= 'J')
            {
                int temp = input[0];
                count[temp - 'A']++;
                flag = 1;
            }

            for (int i = 1; i < input.Length; i++)
            {
                if (input[i] == '?')
                    zercount++;
                if (input[i] >= 'A' && input[i] <= 'J')
                {
                    int temp = input[i];
                    count[temp - 'A']++;
                }

            }

            if (flag == 0)
            {
                int start = 10;
                for (int i = 0; i < types(count); i++)
                {
                    ans *= start;
                    start--;
                }
            }
            else
            {
                int total = types(count);
                if (total == 1)
                    ans *= 9;
                if (total > 1)
                {
                    ans *= 9;
                    int start = 9;
                    for (int i = 1; i < total; i++)
                    {
                        ans *= start;
                        start--;
                    }
                }

            }

            Console.Write(ans);
            for (int i = 0; i < zercount; i++)
                Console.Write("0");
            Console.WriteLine();
        }

        static int types(int[] count)
        {
            int total=0;
            for (int i = 0; i < 10; i++)
            {
                if (count[i] > 0)
                    total++;
            }

            return total;
        }
    }
}

using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;

namespace cs
{
    public class Main : Utils
    {
        public Main(TextReader inStream, TextWriter outStream)
            : base(inStream, outStream)
        {
        }

        protected override void Solve()
        {
            string s;
            Next(out s);
            var ans = 1;
            var st = new HashSet<char>();
            int p10 = 0;
            for (var i = 0; i < s.Length; i++)
                if (s[i] == '?')
                {
                    if (i == 0) ans *= 9;
                    else p10++;
                }
                else if (s[i] >= '0' && s[i] <= '9')
                    continue;
                else if (st.Contains(s[i]))
                    continue;
                else
                {
                    if (i == 0)
                        ans *= 9;
                    else
                        ans *= 10 - st.Count;
                    st.Add(s[i]);
                }
            Print(ans);
            while (p10-- > 0)
                Print(0);
            PrintLine();
        }
    }

    public class PriorityQueue<T>
    {
        #region private members

        private readonly List<T> _data = new List<T>();
        private readonly IComparer<T> _comparer;

        #endregion

        #region constructors

        public PriorityQueue()
        {
            _comparer = Comparer<T>.Default;
        }

        public PriorityQueue(IComparer<T> comparer)
        {
            if (comparer == null)
            {
                _comparer = Comparer<T>.Default;
                return;
            }
            _comparer = comparer;
        }

        #endregion

        #region public members

        public int Count
        {
            get { return _data.Count; }
        }

        public bool Empty()
        {
            return Count == 0;
        }

        public T Top()
        {
            return _data[0];
        }

        public void Push(T item)
        {
            _data.Add(item);
            var curPlace = Count;
            while (curPlace > 1 && _comparer.Compare(item, _data[curPlace / 2 - 1]) > 0)
            {
                _data[curPlace - 1] = _data[curPlace / 2 - 1];
                _data[curPlace / 2 - 1] = item;
                curPlace /= 2;
            }
        }

        public void Pop()
        {
            _data[0] = _data[Count - 1];
            _data.RemoveAt(Count - 1);
            var curPlace = 1;
            while (true)
            {
                var max = curPlace;
                if (Count >= curPlace * 2 && _comparer.Compare(_data[max - 1], _data[2 * curPlace - 1]) < 0)
                    max = 2 * curPlace;
                if (Count >= curPlace * 2 + 1 && _comparer.Compare(_data[max - 1], _data[2 * curPlace]) < 0)
                    max = 2 * curPlace + 1;
                if (max == curPlace) break;
                var item = _data[max - 1];
                _data[max - 1] = _data[curPlace - 1];
                _data[curPlace - 1] = item;
                curPlace = max;
            }
        }

        #endregion
    }

    public static class Algorithm
    {
        public static void Swap<T>(ref T a, ref T b)
        {
            var temp = a;
            a = b;
            b = temp;
        }

        public static void RandomShuffle<T>(T[] a)
        {
            var rnd = new Random(DateTime.Now.Millisecond);
            for (var i = 1; i < a.Length; i++)
                Swap(ref a[i], ref a[rnd.Next(i)]);
        }

        public static bool NextPermutation<T>(T[] a, Comparer<T> comparer = null)
        {
            var comp = comparer ?? Comparer<T>.Default;
            for (var i = a.Length - 1; i > 0; i--)
                if (comp.Compare(a[i], a[i - 1]) > 0)
                {
                    var j = i + 1;
                    for (; j < a.Length; j++)
                        if (comp.Compare(a[j], a[i - 1]) <= 0)
                            break;
                    Swap(ref a[i - 1], ref a[j - 1]);
                    Array.Reverse(a, i, a.Length - i);
                    return true;
                }
            Array.Reverse(a);
            return false;
        }
    }

    public abstract class Utils : IDisposable
    {
        protected readonly TextReader InputStream;
        protected readonly TextWriter OutputStream;

        private string[] _tokens;
        private int _pointer;

        protected Utils()
            : this(Console.In, Console.Out)
        {
        }

        protected Utils(TextReader inputStream, TextWriter outputStream)
        {
            InputStream = inputStream;
            OutputStream = outputStream;
        }

        protected string NextLine()
        {
            try
            {
                return InputStream.ReadLine();
            }
            catch (Exception)
            {
                return null;
            }
        }

        protected string NextString()
        {
            try
            {
                while (_tokens == null || _pointer >= _tokens.Length)
                {
                    _tokens = NextLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                    _pointer = 0;
                }
                return _tokens[_pointer++];
            }
            catch (Exception)
            {
                return null;
            }
        }

        protected bool Next<T>(out T ans)
        {
            var str = NextString();
            if (str == null)
            {
                ans = default(T);
                return false;
            }
            ans = (T)Convert.ChangeType(str, typeof(T));
            return true;
        }

        protected void Print(string format, params object[] args)
        {
            OutputStream.Write(format, args);
        }

        protected void PrintLine(string format, params object[] args)
        {
            Print(format, args);
            OutputStream.WriteLine();
        }

        protected void PrintLine()
        {
            OutputStream.WriteLine();
        }

        protected void Print<T>(T o)
        {
            OutputStream.Write(o);
        }

        protected void PrintLine<T>(T o)
        {
            OutputStream.WriteLine(o);
        }

        void IDisposable.Dispose()
        {
            InputStream.Close();
            OutputStream.Close();
        }

        protected abstract void Solve();

        public static void Main(string[] args)
        {
            using (var p = new Main(Console.In, Console.Out))
                p.Solve();
        }
    }
}

using System;

class Program{
	static void Main(){
		string input = Console.ReadLine();
		int[] box = new int[10];
		int mul = 10;
		int ans = 1;

		for(int i = 0; i < input.Length; i++){
			if(i == 0)
				mul--;
			if(input[i] == '?'){
				ans *= mul;
			}
			if(input[i] >= 'A' && input[i] <= 'J'){
				if(box[input[i] - 'A'] == 0){
					ans *= mul;
					box[input[i] - 'A']++;
					mul--;
				}
			}
			if(i == 0)
				mul++;
		}

		Console.WriteLine(ans);
	}
}

using System;

class Program{
	static void Main(){
		string input = Console.ReadLine();
		int[] box = new int[10];
		int mul = 10;
		int ans = 1;

		for(int i = 0; i < input.Length; i++){
			if(i == 0)
				mul--;
			if(input[i] == '?'){
				ans *= 10;
			}
			if(input[i] >= 'A' && input[i] <= 'J'){
				if(box[input[i] - 'A'] == 0){
					ans *= mul;
					box[input[i] - 'A']++;
					mul--;
				}
			}
			if(i == 0)
				mul++;
		}

		Console.WriteLine(ans);
	}
}

using System;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;

namespace Special_Task
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            string s = reader.ReadLine();
            BigInteger big = 1;

            var letters = new int['J' - 'A' + 1];
            foreach (char letter in s)
            {
                if (letter >= 'A' && letter <= 'J')
                {
                    letters[letter-'A'] = 1;
                }
            }

            int lCount = letters.Sum();
            int sCount = s.Count(c => c == '?');

            if (s[0]=='?')
            {
                big = 9;
                sCount--;
            }

            if (sCount > 0)
                big *= Pow(10, sCount);

            if (s[0] >= 'A' && s[0] <= 'J')
            {
                big *= 9;
            }
            else
            {
                big *= 10;
            }

            for (int i = 1; i < lCount; i++)
            {
                big *= 10 - i;
            }

            writer.WriteLine(big);
            writer.Flush();
        }

        private static BigInteger Pow(BigInteger a, int k)
        {
            BigInteger r = 1;
            while (k > 0)
            {
                if ((k & 1) == 1)
                {
                    r = (r*a);
                }
                a = (a*a);
                k >>= 1;
            }
            return r;
        }
    }
}

#define Online

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CF
{
    delegate double F(double x);
    delegate decimal Fdec(decimal x);

    class Program
    {

        static void Main(string[] args)
        {

#if FileIO
            StreamReader sr = new StreamReader("input.txt");
            StreamWriter sw = new StreamWriter("output.txt");
            Console.SetIn(sr);
            Console.SetOut(sw);
#endif

            A();

#if Online
            Console.ReadLine();
#endif

#if FileIO
            sr.Close();
            sw.Close();
#endif
        }

        static void A()
        {
            string input = ReadLine();
            int tens = 0;
            bool[] letters = new bool[10];
            int cnt = 10;
            int other = 1;
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i].Equals('?'))
                {
                    if (i == 0)
                    {
                        other *= 9;
                        continue;
                    }
                    tens++;
                }
                else
                {
                    if (!char.IsDigit(input[i]))
                    {
                        if (!letters[input[i] - 'A'])
                        {
                            if (i == 0)
                            {
                                other *= 9;
                                cnt--;
                                continue;
                            }
                            other *= cnt;
                            cnt--;
                            letters[input[i] - 'A'] = true;
                        }
                    }
                }
            }
            StringBuilder ans = new StringBuilder();
            ans.Append(other.ToString());
            for (int i = 0; i < tens; i++)
                ans.Append("0");
            Console.WriteLine(ans);
        }

        static void B()
        {

        }

        static void C()
        {

        }

        static void D()
        {

        }

        static void E()
        {

        }

        static void TestGen()
        {

        }

        static string[] ReadArray(char sep)
        {
            return Console.ReadLine().Split(sep);
        }

        static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static string ReadLine()
        {
            return Console.ReadLine();
        }
    }

    public static class MyMath
    {
        public static long BinPow(long a, long n, long mod)
        {
            long res = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    res = (res * a) % mod;
                }
                a = (a * a) % mod;
                n >>= 1;
            }
            return res;
        }

        public static long GCD(long a, long b)
        {
            while (b != 0) b = a % (a = b);
            return a;
        }

        public static int GCD(int a, int b)
        {
            while (b != 0) b = a % (a = b);
            return a;
        }

        public static long LCM(long a, long b)
        {
            return (a * b) / GCD(a, b);
        }

        public static int LCM(int a, int b)
        {
            return (a * b) / GCD(a, b);
        }
    }

    class Edge
    {
        public int a;
        public int b;
        public int w;

        public Edge(int a, int b, int w)
        {
            this.a = a;
            this.b = b;
            this.w = w;
        }
    }

    class Graph
    {
        public List<int>[] g;
        public int[] color; //0-white, 1-gray, 2-black
        public int[] o; //open
        public int[] c; //close
        public int[] p;
        public int[] d;
        public List<Edge> e;
        public Stack<int> ans = new Stack<int>();
        public Graph(int n)
        {
            g = new List<int>[n + 1];
            for (int i = 0; i <= n; i++)
                g[i] = new List<int>();
            color = new int[n + 1];
            o = new int[n + 1];
            c = new int[n + 1];
            p = new int[n + 1];
            d = new int[n + 1];
        }

        const int white = 0;
        const int gray = 1;
        const int black = 2;

        public bool DFS(int u, ref int time)
        {
            color[u] = gray;
            time++;
            o[u] = time;
            for (int i = 0; i < g[u].Count; i++)
            {
                int v = g[u][i];
                if (color[v] == gray)
                {
                    return true;
                }
                if (color[v] == white)
                {
                    p[v] = u;
                    if (DFS(v, ref time)) return true;
                }
            }
            color[u] = black;
            ans.Push(u);
            c[u] = time;
            time++;
            return false;
        }
    }

    static class GraphUtils
    {
        const int white = 0;
        const int gray = 1;
        const int black = 2;

        public static void BFS(int s, Graph g)
        {
            Queue<int> q = new Queue<int>();
            q.Enqueue(s);
            while (q.Count != 0)
            {
                int u = q.Dequeue();
                for (int i = 0; i < g.g[u].Count; i++)
                {
                    int v = g.g[u][i];
                    if (g.color[v] == white)
                    {
                        g.color[v] = gray;
                        g.d[v] = g.d[u] + 1;
                        g.p[v] = u;
                        q.Enqueue(v);
                    }
                }
                g.color[u] = black;
            }
        }

        public static bool DFS(int u, ref int time, Graph g, Stack<int> st)
        {
            g.color[u] = gray;
            time++;
            g.o[u] = time;
            for (int i = 0; i < g.g[u].Count; i++)
            {
                int v = g.g[u][i];
                if (g.color[v] == gray)
                {
                    return true;
                }
                if (g.color[v] == white)
                {
                    g.p[v] = u;
                    if (DFS(v, ref time, g, st)) return true;
                }
            }
            g.color[u] = black;
            st.Push(u);
            g.c[u] = time;
            time++;
            return false;
        }

        public static void FordBellman(int u, Graph g)
        {
            int n = g.g.Length;
            for (int i = 0; i <= n; i++)
            {
                g.d[i] = int.MaxValue;
                g.p[i] = 0;
            }

            g.d[u] = 0;

            for (int i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < g.e.Count; j++)
                {
                    if (g.d[g.e[j].a] != int.MaxValue)
                    {
                        if (g.d[g.e[j].a] + g.e[j].w < g.d[g.e[j].b])
                        {
                            g.d[g.e[j].b] = g.d[g.e[j].a] + g.e[j].w;
                            g.p[g.e[j].b] = g.e[j].a;
                        }
                    }
                }
            }
        }
    }

    static class ArrayUtils
    {
        public static int BinarySearch(int[] a, int val)
        {
            int left = 0;
            int right = a.Length - 1;
            int mid;

            while (left < right)
            {
                mid = left + ((right - left) >> 1);
                if (val <= a[mid])
                {
                    right = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }

            if (a[left] == val)
                return left;
            else
                return -1;
        }

        public static double Bisection(F f, double left, double right, double eps)
        {
            double mid;
            while (right - left > eps)
            {
                mid = left + ((right - left) / 2d);
                if (Math.Sign(f(mid)) != Math.Sign(f(left)))
                    right = mid;
                else
                    left = mid;
            }
            return (left + right) / 2d;
        }

        public static decimal TernarySearchDec(Fdec f, decimal eps, decimal l, decimal r, bool isMax)
        {
            decimal m1, m2;
            while (r - l > eps)
            {
                m1 = l + (r - l) / 3m;
                m2 = r - (r - l) / 3m;
                if (f(m1) < f(m2))
                    if (isMax)
                        l = m1;
                    else
                        r = m2;
                else
                    if (isMax)
                        r = m2;
                    else
                        l = m1;
            }
            return r;
        }

        public static double TernarySearch(F f, double eps, double l, double r, bool isMax)
        {
            double m1, m2;
            while (r - l > eps)
            {
                m1 = l + (r - l) / 3d;
                m2 = r - (r - l) / 3d;
                if (f(m1) < f(m2))
                    if (isMax)
                        l = m1;
                    else
                        r = m2;
                else
                    if (isMax)
                        r = m2;
                    else
                        l = m1;
            }
            return r;
        }

        public static void Merge<T>(T[] A, int p, int q, int r, T[] L, T[] R, Comparison<T> comp)
        {
            for (int i = p; i <= q; i++)
                L[i] = A[i];
            for (int i = q + 1; i <= r; i++)
                R[i] = A[i];

            for (int k = p, i = p, j = q + 1; k <= r; k++)
            {
                if (i > q)
                {
                    for (; k <= r; k++, j++)
                        A[k] = R[j];
                    return;
                }
                if (j > r)
                {
                    for (; k <= r; k++, i++)
                        A[k] = L[i];
                    return;
                }
                if (comp(L[i], R[j]) <= 0)
                {
                    A[k] = L[i];
                    i++;
                }
                else
                {
                    A[k] = R[j];
                    j++;
                }
            }
        }

        public static void Merge_Sort<T>(T[] A, int p, int r, T[] L, T[] R, Comparison<T> comp)
        {
            if (p >= r) return;
            int q = p + ((r - p) >> 1);
            Merge_Sort(A, p, q, L, R, comp);
            Merge_Sort(A, q + 1, r, L, R, comp);
            Merge(A, p, q, r, L, R, comp);
        }

        public static void Merge<T>(T[] A, int p, int q, int r, T[] L, T[] R) where T : IComparable<T>
        {
            for (int i = p; i <= q; i++)
                L[i] = A[i];
            for (int i = q + 1; i <= r; i++)
                R[i] = A[i];

            for (int k = p, i = p, j = q + 1; k <= r; k++)
            {
                if (i > q)
                {
                    for (; k <= r; k++, j++)
                        A[k] = R[j];
                    return;
                }
                if (j > r)
                {
                    for (; k <= r; k++, i++)
                        A[k] = L[i];
                    return;
                }
                if (L[i].CompareTo(R[j]) <= 0)
                {
                    A[k] = L[i];
                    i++;
                }
                else
                {
                    A[k] = R[j];
                    j++;
                }
            }
        }

        public static void Merge_Sort<T>(T[] A, int p, int r, T[] L, T[] R) where T : IComparable<T>
        {
            if (p >= r) return;
            int q = p + ((r - p) >> 1);
            Merge_Sort(A, p, q, L, R);
            Merge_Sort(A, q + 1, r, L, R);
            Merge(A, p, q, r, L, R);
        }

        static void Shake<T>(T[] a)
        {
            Random rnd = new Random(Environment.TickCount);
            T temp;
            int b, c;
            for (int i = 0; i < a.Length; i++)
            {
                b = rnd.Next(0, a.Length);
                c = rnd.Next(0, a.Length);
                temp = a[b];
                a[b] = a[c];
                a[c] = temp;
            }
        }
    }
}

#define Online

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CF
{
    delegate double F(double x);
    delegate decimal Fdec(decimal x);

    class Program
    {

        static void Main(string[] args)
        {

#if FileIO
            StreamReader sr = new StreamReader("input.txt");
            StreamWriter sw = new StreamWriter("output.txt");
            Console.SetIn(sr);
            Console.SetOut(sw);
#endif

            A();

#if Online
            Console.ReadLine();
#endif

#if FileIO
            sr.Close();
            sw.Close();
#endif
        }

        static void A()
        {
            string input = ReadLine();
            int tens = 0;
            bool[] letters = new bool[10];
            int cnt = 10;
            int other = 1;
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i].Equals('?'))
                {
                    tens++;
                }
                else
                {
                    if (!char.IsDigit(input[i]))
                    {
                        if (!letters[input[i] - 'A'])
                        {
                            if (i == 0)
                            {
                                other *= 9;
                                cnt--;
                                continue;
                            }
                            other *= cnt;
                            cnt--;
                            letters[input[i] - 'A'] = true;
                        }
                    }
                }
            }
            StringBuilder ans = new StringBuilder();
            ans.Append(other.ToString());
            for (int i = 0; i < tens; i++)
                ans.Append("0");
            Console.WriteLine(ans);
        }

        static void B()
        {

        }

        static void C()
        {

        }

        static void D()
        {

        }

        static void E()
        {

        }

        static void TestGen()
        {

        }

        static string[] ReadArray(char sep)
        {
            return Console.ReadLine().Split(sep);
        }

        static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }

        static string ReadLine()
        {
            return Console.ReadLine();
        }
    }

    public static class MyMath
    {
        public static long BinPow(long a, long n, long mod)
        {
            long res = 1;
            while (n > 0)
            {
                if ((n & 1) == 1)
                {
                    res = (res * a) % mod;
                }
                a = (a * a) % mod;
                n >>= 1;
            }
            return res;
        }

        public static long GCD(long a, long b)
        {
            while (b != 0) b = a % (a = b);
            return a;
        }

        public static int GCD(int a, int b)
        {
            while (b != 0) b = a % (a = b);
            return a;
        }

        public static long LCM(long a, long b)
        {
            return (a * b) / GCD(a, b);
        }

        public static int LCM(int a, int b)
        {
            return (a * b) / GCD(a, b);
        }
    }

    class Edge
    {
        public int a;
        public int b;
        public int w;

        public Edge(int a, int b, int w)
        {
            this.a = a;
            this.b = b;
            this.w = w;
        }
    }

    class Graph
    {
        public List<int>[] g;
        public int[] color; //0-white, 1-gray, 2-black
        public int[] o; //open
        public int[] c; //close
        public int[] p;
        public int[] d;
        public List<Edge> e;
        public Stack<int> ans = new Stack<int>();
        public Graph(int n)
        {
            g = new List<int>[n + 1];
            for (int i = 0; i <= n; i++)
                g[i] = new List<int>();
            color = new int[n + 1];
            o = new int[n + 1];
            c = new int[n + 1];
            p = new int[n + 1];
            d = new int[n + 1];
        }

        const int white = 0;
        const int gray = 1;
        const int black = 2;

        public bool DFS(int u, ref int time)
        {
            color[u] = gray;
            time++;
            o[u] = time;
            for (int i = 0; i < g[u].Count; i++)
            {
                int v = g[u][i];
                if (color[v] == gray)
                {
                    return true;
                }
                if (color[v] == white)
                {
                    p[v] = u;
                    if (DFS(v, ref time)) return true;
                }
            }
            color[u] = black;
            ans.Push(u);
            c[u] = time;
            time++;
            return false;
        }
    }

    static class GraphUtils
    {
        const int white = 0;
        const int gray = 1;
        const int black = 2;

        public static void BFS(int s, Graph g)
        {
            Queue<int> q = new Queue<int>();
            q.Enqueue(s);
            while (q.Count != 0)
            {
                int u = q.Dequeue();
                for (int i = 0; i < g.g[u].Count; i++)
                {
                    int v = g.g[u][i];
                    if (g.color[v] == white)
                    {
                        g.color[v] = gray;
                        g.d[v] = g.d[u] + 1;
                        g.p[v] = u;
                        q.Enqueue(v);
                    }
                }
                g.color[u] = black;
            }
        }

        public static bool DFS(int u, ref int time, Graph g, Stack<int> st)
        {
            g.color[u] = gray;
            time++;
            g.o[u] = time;
            for (int i = 0; i < g.g[u].Count; i++)
            {
                int v = g.g[u][i];
                if (g.color[v] == gray)
                {
                    return true;
                }
                if (g.color[v] == white)
                {
                    g.p[v] = u;
                    if (DFS(v, ref time, g, st)) return true;
                }
            }
            g.color[u] = black;
            st.Push(u);
            g.c[u] = time;
            time++;
            return false;
        }

        public static void FordBellman(int u, Graph g)
        {
            int n = g.g.Length;
            for (int i = 0; i <= n; i++)
            {
                g.d[i] = int.MaxValue;
                g.p[i] = 0;
            }

            g.d[u] = 0;

            for (int i = 0; i < n - 1; i++)
            {
                for (int j = 0; j < g.e.Count; j++)
                {
                    if (g.d[g.e[j].a] != int.MaxValue)
                    {
                        if (g.d[g.e[j].a] + g.e[j].w < g.d[g.e[j].b])
                        {
                            g.d[g.e[j].b] = g.d[g.e[j].a] + g.e[j].w;
                            g.p[g.e[j].b] = g.e[j].a;
                        }
                    }
                }
            }
        }
    }

    static class ArrayUtils
    {
        public static int BinarySearch(int[] a, int val)
        {
            int left = 0;
            int right = a.Length - 1;
            int mid;

            while (left < right)
            {
                mid = left + ((right - left) >> 1);
                if (val <= a[mid])
                {
                    right = mid;
                }
                else
                {
                    left = mid + 1;
                }
            }

            if (a[left] == val)
                return left;
            else
                return -1;
        }

        public static double Bisection(F f, double left, double right, double eps)
        {
            double mid;
            while (right - left > eps)
            {
                mid = left + ((right - left) / 2d);
                if (Math.Sign(f(mid)) != Math.Sign(f(left)))
                    right = mid;
                else
                    left = mid;
            }
            return (left + right) / 2d;
        }

        public static decimal TernarySearchDec(Fdec f, decimal eps, decimal l, decimal r, bool isMax)
        {
            decimal m1, m2;
            while (r - l > eps)
            {
                m1 = l + (r - l) / 3m;
                m2 = r - (r - l) / 3m;
                if (f(m1) < f(m2))
                    if (isMax)
                        l = m1;
                    else
                        r = m2;
                else
                    if (isMax)
                        r = m2;
                    else
                        l = m1;
            }
            return r;
        }

        public static double TernarySearch(F f, double eps, double l, double r, bool isMax)
        {
            double m1, m2;
            while (r - l > eps)
            {
                m1 = l + (r - l) / 3d;
                m2 = r - (r - l) / 3d;
                if (f(m1) < f(m2))
                    if (isMax)
                        l = m1;
                    else
                        r = m2;
                else
                    if (isMax)
                        r = m2;
                    else
                        l = m1;
            }
            return r;
        }

        public static void Merge<T>(T[] A, int p, int q, int r, T[] L, T[] R, Comparison<T> comp)
        {
            for (int i = p; i <= q; i++)
                L[i] = A[i];
            for (int i = q + 1; i <= r; i++)
                R[i] = A[i];

            for (int k = p, i = p, j = q + 1; k <= r; k++)
            {
                if (i > q)
                {
                    for (; k <= r; k++, j++)
                        A[k] = R[j];
                    return;
                }
                if (j > r)
                {
                    for (; k <= r; k++, i++)
                        A[k] = L[i];
                    return;
                }
                if (comp(L[i], R[j]) <= 0)
                {
                    A[k] = L[i];
                    i++;
                }
                else
                {
                    A[k] = R[j];
                    j++;
                }
            }
        }

        public static void Merge_Sort<T>(T[] A, int p, int r, T[] L, T[] R, Comparison<T> comp)
        {
            if (p >= r) return;
            int q = p + ((r - p) >> 1);
            Merge_Sort(A, p, q, L, R, comp);
            Merge_Sort(A, q + 1, r, L, R, comp);
            Merge(A, p, q, r, L, R, comp);
        }

        public static void Merge<T>(T[] A, int p, int q, int r, T[] L, T[] R) where T : IComparable<T>
        {
            for (int i = p; i <= q; i++)
                L[i] = A[i];
            for (int i = q + 1; i <= r; i++)
                R[i] = A[i];

            for (int k = p, i = p, j = q + 1; k <= r; k++)
            {
                if (i > q)
                {
                    for (; k <= r; k++, j++)
                        A[k] = R[j];
                    return;
                }
                if (j > r)
                {
                    for (; k <= r; k++, i++)
                        A[k] = L[i];
                    return;
                }
                if (L[i].CompareTo(R[j]) <= 0)
                {
                    A[k] = L[i];
                    i++;
                }
                else
                {
                    A[k] = R[j];
                    j++;
                }
            }
        }

        public static void Merge_Sort<T>(T[] A, int p, int r, T[] L, T[] R) where T : IComparable<T>
        {
            if (p >= r) return;
            int q = p + ((r - p) >> 1);
            Merge_Sort(A, p, q, L, R);
            Merge_Sort(A, q + 1, r, L, R);
            Merge(A, p, q, r, L, R);
        }

        static void Shake<T>(T[] a)
        {
            Random rnd = new Random(Environment.TickCount);
            T temp;
            int b, c;
            for (int i = 0; i < a.Length; i++)
            {
                b = rnd.Next(0, a.Length);
                c = rnd.Next(0, a.Length);
                temp = a[b];
                a[b] = a[c];
                a[c] = temp;
            }
        }
    }
}

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.Threading;
using System.Numerics;

class Problem
{
    private static Decimal GetNumericValue(string value, NumberStyles styles)
    {
        Decimal number;

        number = Decimal.Parse(value, styles);
        return number;
    }

    public void Solution(TextReader Input, TextWriter Output)
    {
        string s;
        s = Input.ReadLine();
        bool [] used = new bool[10];

        BigInteger[] fact = new BigInteger[11];
        fact[0] = fact[1] = 1;
        for (int i = 2; i <= 10; i++)
            fact[i] = fact[i - 1] * i;

        int x = 0;
        bool z = false;
        BigInteger ans = 1;

        if (s.Length == 1)
        {
            if ('0' <= s[0] && s[0] <= '9')
                Output.WriteLine("1");
            else
                Output.WriteLine("10");
            return;
        }

        for (int i = 0; i < s.Length; i++)
        {
            if (s[i] == '?')
                if (i == 0)
                    ans *= 9;
                else
                    ans *= 10;
            else
                if ('A' <= s[i] && s[i] <= 'Z')
                {
                    int k = s[i] - 'A';
                    if (!used[k])
                    {
                        x++;
                        used[k] = true;
                    }
                    if (i == 0)
                        z = true;
                }
        }

        if (!z)
        {
            BigInteger tmp = fact[10] / (fact[x] * fact[10 - x]);
            ans *= tmp;
        }
        else
        {
            BigInteger tmp = 9 * fact[9] / (fact[x - 1] * fact[10 - x]);
            ans *= tmp;
        }

        Output.WriteLine(ans.ToString());
    }
}

class Program
{
    public static void Main()
    {
#if Local
        var inputStream = new StreamReader(@"..\..\input.txt");
        var outputStream = new StreamWriter(@"..\..\output.txt");

        new Problem().Solution(inputStream, outputStream);

        inputStream.Close();
        outputStream.Close();
#else
                new Problem().Solution(Console.In, Console.Out);
#endif
    }
}

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.Threading;
using System.Numerics;

class Problem
{
    private static Decimal GetNumericValue(string value, NumberStyles styles)
    {
        Decimal number;

        number = Decimal.Parse(value, styles);
        return number;
    }

    public void Solution(TextReader Input, TextWriter Output)
    {
        string s;
        s = Input.ReadLine();
        bool [] used = new bool[10];

        BigInteger[] fact = new BigInteger[11];
        fact[0] = fact[1] = 1;
        for (int i = 2; i <= 10; i++)
            fact[i] = fact[i - 1] * i;

        int x = 0;
        bool z = false;
        BigInteger ans = 1;

        if (s.Length == 1)
        {
            if ('0' <= s[0] && s[0] <= '9')
                Output.WriteLine("1");
            else
                Output.WriteLine("10");
            return;
        }

        for (int i = 0; i < s.Length; i++)
        {
            if (s[i] == '?')
                ans *= 10;
            else
                if ('A' <= s[i] && s[i] <= 'Z')
                {
                    int k = s[i] - 'A';
                    if (!used[k])
                    {
                        x++;
                        used[k] = true;
                    }
                    //if (i == 0)
                    //    z = true;
                }
        }

            BigInteger tmp = fact[10] / (fact[x] * fact[10 - x]);
            ans *= tmp;

        Output.WriteLine(ans.ToString());
    }
}

class Program
{
    public static void Main()
    {
#if Local
        var inputStream = new StreamReader(@"..\..\input.txt");
        var outputStream = new StreamWriter(@"..\..\output.txt");

        new Problem().Solution(inputStream, outputStream);

        inputStream.Close();
        outputStream.Close();
#else
                new Problem().Solution(Console.In, Console.Out);
#endif
    }
}

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using System.Threading;
using System.Numerics;

class Problem
{
    private static Decimal GetNumericValue(string value, NumberStyles styles)
    {
        Decimal number;

        number = Decimal.Parse(value, styles);
        return number;
    }

    public void Solution(TextReader Input, TextWriter Output)
    {
        string s;
        s = Input.ReadLine();
        bool[] used = new bool[10];

        BigInteger[] fact = new BigInteger[11];
        fact[0] = fact[1] = 1;
        for (int i = 2; i <= 10; i++)
            fact[i] = fact[i - 1] * i;

        int x = 0;
        bool z = false;
        BigInteger ans = 1;

        if (s.Length == 1)
        {
            if ('0' <= s[0] && s[0] <= '9')
                Output.WriteLine("1");
            else
                Output.WriteLine("9");
            return;
        }

        for (int i = 0; i < s.Length; i++)
        {
            if (s[i] == '?')
                if (i == 0)
                    ans *= 9;
                else
                    ans *= 10;
            else
                if ('A' <= s[i] && s[i] <= 'Z')
                {
                    int k = s[i] - 'A';
                    if (!used[k])
                    {
                        x++;
                        used[k] = true;
                    }
                    if (i == 0)
                        z = true;
                }
        }

        if (!z)
        {
            BigInteger tmp = fact[10] / (fact[x] * fact[10 - x]);
            ans *= tmp;
        }
        else
        {
            BigInteger tmp = 9 * fact[9] / (fact[x - 1] * fact[10 - x]);
            ans *= tmp;
        }

        Output.WriteLine(ans.ToString());
    }
}

class Program
{
    public static void Main()
    {
#if Local
        var inputStream = new StreamReader(@"..\..\input.txt");
        var outputStream = new StreamWriter(@"..\..\output.txt");

        new Problem().Solution(inputStream, outputStream);

        inputStream.Close();
        outputStream.Close();
#else
                new Problem().Solution(Console.In, Console.Out);
#endif
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string st = Console.ReadLine();
            bool[] f = new bool[10];
            int ff = 10;
            long k=1;
            for (int i = 0; i < 10; i++)
            {
                f[i] = true;
            }
            for (int i = 0; i < st.Length; i++)
            {
                if (st[i] == '?')
                {
                    k = k * 10;
                }
                if (st[i] >= 'A' && st[i] <= 'J')
                {
                    if (ff > 0 && f[(int)st[i] - 65] == true)
                    {
                        if (i == 0)
                        {
                            k = k * 9;
                        }
                        else
                        {
                            k = k * ff;
                        }
                        ff--;
                    }
                    f[(int)st[i] - 65] = false;
                }
            }
            Console.WriteLine(k.ToString());
        }
    }
}

using System;

namespace abbycup1
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string [] n9 = {"9", "81", "648", "4536", "27216", "136080", "544320", "1632960", "326592", "326592"};
			string [] n10 = {"10", "90", "720", "5040", "30240", "151200", "604800", "1814400", "3628800", "3628800"};
			char [] letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
			bool nine = false;
			bool voprfirst=false;
			int count = 0;
			int voprcount=0;

			char [] input = Console.ReadLine().ToCharArray();

			if ( Array.BinarySearch(letters, input[0]) >= 0 || input[0] == '?') {
				nine = true;
			}

			if ( input[0] == '?') {
				voprfirst = true;
			}

			Array.Sort(input);

			for (int i=0; i<=9; i++) {
				if (Array.BinarySearch(input, letters[i])>=0) {
					count++;
				}
			}

			int vopr = Array.BinarySearch(input, '?');
			if (vopr>=0) {
				for (int i=vopr; i<input.GetLength(0); i++) {
					if (input[i]=='?') {
						voprcount++;
					}
				}
			}

			if (voprfirst) {
				voprcount--;
			}

			if (count>0 && !voprfirst) {
				if (nine) {
					Console.Write(n9[count-1]);
				} else {
					Console.Write(n10[count-1]);
				}
			}

			if (voprfirst && count==0) {
				Console.Write("9");
			}

			if (count==0 && !voprfirst) {
				Console.Write("1");
			}

			for (int i=0; i<voprcount; i++) {
				Console.Write('0');
			}
			Console.WriteLine("");

		}
	}
}

using System;

namespace abbycup1
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string [] n9 = {"9", "81", "648", "4536", "27216", "136080", "544320", "1632960", "326592", "326592"};
			string [] n10 = {"10", "90", "720", "5040", "30240", "151200", "604800", "1814400", "3628800", "3628800"};
			char [] letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
			bool nine = false;
			bool voprfirst=false;
			int count = 0;
			int voprcount=0;

			char [] input = Console.ReadLine().ToCharArray();

			if ( Array.BinarySearch(letters, input[0]) >= 0 || input[0] == '?') {
				nine = true;
			}

			if ( input[0] == '?') {
				voprfirst = true;
			}

			Array.Sort(input);

			for (int i=0; i<=9; i++) {
				if (Array.BinarySearch(input, letters[i])>=0) {
					count++;
				}
			}

			int vopr = Array.BinarySearch(input, '?');
			if (vopr>=0) {
				for (int i=vopr; i<input.GetLength(0); i++) {
					if (input[i]=='?') {
						voprcount++;
					}
				}
			}

			if (voprfirst) {
				voprcount--;
			}

			if (count>0 && !voprfirst) {
				if (nine) {
					Console.Write(n9[count-1]);
				} else {
					Console.Write(n10[count-1]);
				}
			}

			if (voprfirst) {
				Console.Write("9");
			}

			if (count==0 && !voprfirst) {
				Console.Write("1");
			}

			for (int i=0; i<voprcount; i++) {
				Console.Write('0');
			}
			Console.WriteLine("");

		}
	}
}

using System;

namespace abbycup1
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string [] n9 = {"9", "81", "648", "4536", "27216", "136080", "544320", "1632960", "326592", "326592"};
			string [] n10 = {"10", "90", "720", "5040", "30240", "151200", "604800", "1814400", "3628800", "3628800"};
			char [] letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
			bool nine = false;
			bool voprfirst=false;
			int count = 0;
			int voprcount=0;

			char [] input = Console.ReadLine().ToCharArray();

			if ( Array.BinarySearch(letters, input[0]) >= 0 || input[0] == '?') {
				nine = true;
			}

			if ( input[0] == '?') {
				voprfirst = true;
			}

			Array.Sort(input);

			for (int i=0; i<=9; i++) {
				if (Array.BinarySearch(input, letters[i])>=0) {
					count++;
				}
			}

			int vopr = Array.BinarySearch(input, '?');
			if (vopr>=0) {
				for (int i=0; i<input.GetLength(0); i++) {
					if (input[i]=='?') {
						voprcount++;
					}
				}
			}

			if (voprfirst) {
				voprcount--;
			}

			if (count>0 && !voprfirst) {
				if (nine) {
					Console.Write(n9[count-1]);
				} else {
					Console.Write(n10[count-1]);
				}
			}

			if (voprfirst && count==0) {
				Console.Write("9");
			}

			if (count==0 && !voprfirst) {
				Console.Write("1");
			}

			for (int i=1; i<=voprcount; i++) {
				Console.Write("0");
			}
			Console.WriteLine("");

		}
	}
}

using System;

namespace abbycup1
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			string [] n9 = {"9", "81", "648", "4536", "27216", "136080", "544320", "1632960", "326592", "326592"};
			string [] n10 = {"10", "90", "720", "5040", "30240", "151200", "604800", "1814400", "3628800", "3628800"};
			char [] letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
			bool nine = false;
			bool voprfirst=false;
			int count = 0;
			int voprcount=0;

			char [] input = Console.ReadLine().ToCharArray();

			if ( Array.BinarySearch(letters, input[0]) >= 0 || input[0] == '?') {
				nine = true;
			}

			if ( input[0] == '?') {
				voprfirst = true;
			}

			Array.Sort(input);

			for (int i=0; i<=9; i++) {
				if (Array.BinarySearch(input, letters[i])>=0) {
					count++;
				}
			}

			int vopr = Array.BinarySearch(input, '?');
			if (vopr>=0) {
				for (int i=vopr; i<input.GetLength(0); i++) {
					if (input[i]=='?') {
						voprcount++;
					}
				}
			}

			if (voprfirst) {
				voprcount--;
			}

			if (count>0) {
				if (nine) {
					Console.Write(n9[count-1]);
				} else {
					Console.Write(n10[count-1]);
				}
			}

			for (int i=0; i<voprcount; i++) {
				Console.Write('0');
			}
			Console.WriteLine("");

		}
	}
}

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine().ToUpper();
            double combs;
            double q = 0;
            bool leadA = false;
            bool leadS = false;
            Hashtable symb = new Hashtable();
            for (int i = 0; i < input.Length; i++)
            {
                Char currSymb = input[i];
                if (currSymb == '?')
                {
                    if (i == 0)
                    {
                        leadA = true;
                    }
                    else
                    {
                        q++;
                    }
                }
                else if ((Convert.ToByte(currSymb) >= 65) && (Convert.ToByte(currSymb) <= 74))
                {
                    if (i == 0)
                    {
                        leadS = true;
                    }
                    if (!symb.Contains(currSymb))
                    {
                        symb.Add(currSymb, 0);
                    }
                }
            }
            if (leadA)
            {
                combs = Math.Pow(10.0, q) * 9 * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            else if (leadS)
            {
                if (symb.Count == 1)
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((10.0 - symb.Count), symb.Count));
                }
                else if (symb.Count == 2)
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count ));
                }
                else
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count - 1)) * (10.0 - symb.Count);
                }
            }
            else
            {
                combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            Console.WriteLine(combs);

        }
    }
}

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine().ToUpper();
            double combs;
            double q = 0;
            bool leadA = false;
            bool leadS = false;
            Hashtable symb = new Hashtable();
            for (int i = 0; i < input.Length; i++)
            {
                Char currSymb = input[i];
                if (currSymb == '?')
                {
                    if (i == 0)
                    {
                        leadA = true;
                    }
                    else
                    {
                        q++;
                    }
                }
                else if ((Convert.ToByte(currSymb) >= 65) && (Convert.ToByte(currSymb) <= 74))
                {
                    if (i == 0)
                    {
                        leadS = true;
                    }
                    if (!symb.Contains(currSymb))
                    {
                        symb.Add(currSymb, 0);
                    }
                }
            }
            if (leadA)
            {
                combs = Math.Pow(10.0, q) * 9 * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            else if (leadS)
            {
                if (symb.Count == 1)
                {
                    combs = Math.Pow(10.0, q) * 9;
                }
                else if (symb.Count == 2)
                {
                    combs = Math.Pow(10.0, q) * 81;
                }
                else if (symb.Count == 3)
                {
                    combs = Math.Pow(10.0, q) * 7*8*8;
                }
                else if (symb.Count == 4)
                {
                    combs = Math.Pow(10.0, q) * 6*7*7*7;
                }
                else if (symb.Count == 5)
                {
                    combs = Math.Pow(10.0, q) * 5*6*6*6*6;
                }
                else if (symb.Count == 6)
                {
                    combs = Math.Pow(10.0, q) * 4*5*5*5*5*5;
                }
                else if (symb.Count == 7)
                {
                    combs = Math.Pow(10.0, q) * 3*4*4*4*4*4*4;
                }
                else if (symb.Count == 8)
                {
                    combs = Math.Pow(10.0, q) * 2*3*3*3*3*3*3*3;
                }
                else if (symb.Count == 9)
                {
                    combs = Math.Pow(10.0, q) * 1*2*2*2*2*2*2*2*2;
                }
                else if (symb.Count == 10)
                {
                    combs = Math.Pow(10.0, q);
                }
                else
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count - 1)) * (10.0 - symb.Count);
                }

            }
            else
            {
                combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            Console.WriteLine(combs);

        }
    }
}

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine();
            double combs;
            double q = 0;
            Hashtable symb = new Hashtable();
            for (int i = 0; i < input.Length; i++)
            {
                Char currSymb = input[i];
                if (currSymb == '?')
                {
                    q++;
                }
                else if ((Convert.ToByte(currSymb) >= 65) && (Convert.ToByte(currSymb) <= 74))
                {
                    if (!symb.Contains(currSymb))
                    {
                        symb.Add(currSymb, 0);
                    }
                }
            }
            combs = Math.Pow(10.0,q)*(Math.Pow((11.0 - symb.Count),symb.Count));
            Console.WriteLine(combs);

        }
    }
}

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine().ToUpper();
            double combs;
            double q = 0;
            bool leadA = false;
            bool leadS = false;
            Hashtable symb = new Hashtable();
            for (int i = 0; i < input.Length; i++)
            {
                Char currSymb = input[i];
                if (currSymb == '?')
                {
                    if (i == 0)
                    {
                        leadA = true;
                    }
                    else
                    {
                        q++;
                    }
                }
                else if ((Convert.ToByte(currSymb) >= 65) && (Convert.ToByte(currSymb) <= 74))
                {
                    if (i == 0)
                    {
                        leadS = true;
                    }
                    if (!symb.Contains(currSymb))
                    {
                        symb.Add(currSymb, 0);
                    }
                }
            }
            if (leadA)
            {
                combs = Math.Pow(10.0, q) * 9 * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            else if (leadS)
            {
                combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count - 1)) * (10.0 - symb.Count);
            }
            else
            {
                combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            Console.WriteLine(combs);

        }
    }
}

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace A
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = Console.ReadLine().ToUpper();
            double combs;
            double q = 0;
            bool leadA = false;
            bool leadS = false;
            Hashtable symb = new Hashtable();
            for (int i = 0; i < input.Length; i++)
            {
                Char currSymb = input[i];
                if (currSymb == '?')
                {
                    if (i == 0)
                    {
                        leadA = true;
                    }
                    else
                    {
                        q++;
                    }
                }
                else if ((Convert.ToByte(currSymb) >= 65) && (Convert.ToByte(currSymb) <= 74))
                {
                    if (i == 0)
                    {
                        leadS = true;
                    }
                    if (!symb.Contains(currSymb))
                    {
                        symb.Add(currSymb, 0);
                    }
                }
            }
            if (leadA)
            {
                combs = Math.Pow(10.0, q) * 9 * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            else if (leadS)
            {
                if (symb.Count == 1)
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((10.0 - symb.Count), symb.Count));
                }
                else if (symb.Count == 2)
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count ));
                }
                else if (symb.Count == 10)
                {
                    combs = Math.Pow(10.0, q);
                }
                else
                {
                    combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count - 1)) * (10.0 - symb.Count);
                }

            }
            else
            {
                combs = Math.Pow(10.0, q) * (Math.Pow((11.0 - symb.Count), symb.Count));
            }
            Console.WriteLine(combs);

        }
    }
}

using System;

class Program{
	static void Main(){
		string input = Console.ReadLine();
		int[] box = new int[10];
		int mul = 10;
		long ans = 1;

		for(int i = 0; i < input.Length; i++){
			if(i == 0)
				mul--;
			if(input[i] == '?')
				ans *= i == 0 ? 9 : 10;
			if(input[i] >= 'A' && input[i] <= 'J'){
				if(box[input[i] - 'A'] == 0){
					ans *= mul;
					box[input[i] - 'A']++;
					mul--;
				}
			}
			if(i == 0)
				mul++;
		}

		Console.WriteLine(ans);
	}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Numerics;

namespace ABBYY
{
    class A
    {
        static void Main(string[] args)
        {
#if ONLINE_JUDGE
            var reader = Console.In;
            var writer = Console.Out;
#else
            StreamReader reader = new StreamReader("input.txt");
            StreamWriter writer = new StreamWriter("output.txt");
#endif
            string s = reader.ReadLine();
            reader.Close();
            Dictionary<char, object> d = new Dictionary<char, object>();
            //BigInteger
            int codes = 1, zeroes = 0;
            for (int i = 0; i < s.Length; ++i)
            {
                char c = s[i];
                if (c == '?')
                    ++zeroes;
                else if (c >= 'A' && c <= 'J')
                    if (!d.ContainsKey(c))
                    {
                        if (i > 0)
                            codes *= 10 - d.Count;
                        else
                            codes *= 9;
                        d.Add(c, 1);
                    }
            }
            if (codes > 1)
                writer.Write(codes);
            for (int i = 0; i < zeroes; ++i)
                writer.Write(0);
            writer.Close();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Numerics;

namespace ABBYY
{
    class A
    {
        static void Main(string[] args)
        {
#if ONLINE_JUDGE
            var reader = Console.In;
            var writer = Console.Out;
#else
            StreamReader reader = new StreamReader("input.txt");
            StreamWriter writer = new StreamWriter("output.txt");
#endif
            string s = reader.ReadLine();
            reader.Close();
            Dictionary<char, object> d = new Dictionary<char, object>();
            //BigInteger
            int codes = 1, zeroes = 0;
            for (int i = 0; i < s.Length; ++i)
            {
                char c = s[i];
                if (c == '?')
                    ++zeroes;
                else if (c >= 'A' && c <= 'J')
                    if (!d.ContainsKey(c))
                    {
                        if (i > 0)
                            codes *= 10 - d.Count;
                        else
                            codes *= 9;
                        d.Add(c, 1);
                    }
            }
            writer.Write(codes);
            for (int i = 0; i < zeroes; ++i)
                writer.Write(0);
            writer.Close();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Numerics;

namespace ABBYY
{
    class A
    {
        static void Main(string[] args)
        {
#if ONLINE_JUDGE
            var reader = Console.In;
            var writer = Console.Out;
#else
            StreamReader reader = new StreamReader("input.txt");
            StreamWriter writer = new StreamWriter("output.txt");
#endif
            string s = reader.ReadLine();
            reader.Close();
            Dictionary<char, object> d = new Dictionary<char, object>();
            //BigInteger
            int codes = 1, zeroes = 0;
            for (int i = 0; i < s.Length; ++i)
            {
                char c = s[i];
                if (c == '?')
                {
                    if (i > 0)
                        ++zeroes;
                    else
                        codes *= 9;
                }
                else if (c >= 'A' && c <= 'J')
                    if (d.Count < 10 && !d.ContainsKey(c))
                    {
                        if (i > 0)
                            codes *= 10 - d.Count;
                        else
                            codes *= 9;
                        d.Add(c, 1);
                    }
            }
            if (codes > 1)
                writer.Write(codes);
            for (int i = 0; i < zeroes; ++i)
                writer.Write(0);
            writer.Close();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Numerics;

namespace ABBYY
{
    class A
    {
        static void Main(string[] args)
        {
#if ONLINE_JUDGE
            var reader = Console.In;
            var writer = Console.Out;
#else
            StreamReader reader = new StreamReader("input.txt");
            StreamWriter writer = new StreamWriter("output.txt");
#endif
            string s = reader.ReadLine();
            reader.Close();
            Dictionary<char, object> d = new Dictionary<char, object>();
            //BigInteger
            int codes = 1, zeroes = 0;
            for (int i = 0; i < s.Length; ++i)
            {
                char c = s[i];
                if (c == '?')
                {
                    if (i > 0)
                        ++zeroes;
                    else
                        codes *= 9;
                }
                else if (c >= 'A' && c <= 'J')
                    if (d.Count < 10 && !d.ContainsKey(c))
                    {
                        if (i > 0)
                            codes *= 10 - d.Count;
                        else
                            codes *= 9;
                        d.Add(c, 1);
                    }
            }
            if (codes > 1 || zeroes == 0)
                writer.Write(codes);
            for (int i = 0; i < zeroes; ++i)
                writer.Write(0);
            writer.Close();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = Console.ReadLine();
            HashSet<char> letset = new HashSet<char>();
            int k = 0;
            int kq = 0;
            for (int i = 0; i < s.Length; ++i)
            {

                if (s[i] >= 'A' && s[i] <= 'J' && !letset.Contains(s[i]))
                {
                    letset.Add(s[i]);
                    k++;
                }

                if (s[i] == '?')
                    kq++;

            }
            BigInteger ans = BigInteger.One;
            BigInteger m = BigInteger.Multiply(ans, 9);;

            for (int i = 0; i < k-1; i++)
            {

                ans = BigInteger.Multiply(ans,m);
                m = BigInteger.Subtract(m,BigInteger.One);

            }

            BigInteger ten = binpow(10, kq);
            ans = BigInteger.Multiply(ans,ten);

            if(s[0]>='0' && s[0]<='9' )
                {
                    Console.Write(BigInteger.Multiply(ans,10));
                }
                else
                {
                  Console.WriteLine(BigInteger.Multiply(ans,9));
                }

      //   Console.ReadKey();
        }
       public static BigInteger binpow(BigInteger a, int n)
        {
            BigInteger res = 1;
            while (n>0)
            {
                if (n % 2 !=0)
                    res = BigInteger.Multiply(res,a);
                 a = BigInteger.Multiply(a,a);
                n >>= 1;
            }
            return res;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = Console.ReadLine();
            HashSet<char> letset = new HashSet<char>();
            int k = 0;
            int kq = 0;
            for (int i = 0; i < s.Length; ++i)
            {

                if (s[i] >= 'A' && s[i] <= 'J' && !letset.Contains(s[i]))
                {
                    letset.Add(s[i]);
                    k++;
                }

                if (s[i] == '?')
                    kq++;

            }
            if (k == 0 && kq == 0) { Console.WriteLine(1); return; }

            BigInteger ans = BigInteger.One;
            BigInteger m = BigInteger.Multiply(ans, 9); ;

            for (int i = 0; i < k - 1; i++)
            {

                ans = BigInteger.Multiply(ans, m);
                m = BigInteger.Subtract(m, BigInteger.One);

            }

            BigInteger ten = binpow(10, kq);
            ans = BigInteger.Multiply(ans, ten);

            if (s[0] >= '0' && s[0] <= '9')
            {
                Console.WriteLine(BigInteger.Multiply(ans, 10));
            }
            else
            {
                Console.WriteLine(BigInteger.Multiply(ans, 9));
            }

            //   Console.ReadKey();
        }
        public static BigInteger binpow(BigInteger a, int n)
        {
            BigInteger res = 1;
            while (n > 0)
            {
                if (n % 2 != 0)
                    res = BigInteger.Multiply(res, a);
                a = BigInteger.Multiply(a, a);
                n >>= 1;
            }
            return res;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = Console.ReadLine();
            HashSet<char> letset = new HashSet<char>();
            int k = 0;
            int kq = 0;
            for (int i = 0; i < s.Length; ++i)
            {

                if (s[i] >= 'A' && s[i] <= 'J' && !letset.Contains(s[i]))
                {
                    letset.Add(s[i]);
                    k++;
                }

                if (s[i] == '?')
                    kq++;

            }
            BigInteger ans = BigInteger.One;
            BigInteger m = BigInteger.Multiply(ans, 10); ;

            for (int i = 0; i < k; i++)
            {
                ans = BigInteger.Multiply(ans, m);
                m = BigInteger.Subtract(m, BigInteger.One);

            }

            if (s[0] >= '0' && s[0] <= '9')
            {
                Console.Write(ans);
                for (int i = 0; i < kq; i++) Console.Write("0");
            }
            else
            {
                Console.Write(BigInteger.Multiply(BigInteger.Divide(ans, 10), 9));
                for (int i = 0; i < kq; i++) Console.Write("0");
            }

            //  Console.ReadKey();
        }
        public static BigInteger binpow(BigInteger a, int n)
        {
            BigInteger res = 1;
            while (n > 0)
            {
                if (n % 2 != 0)
                    res = BigInteger.Multiply(res, a);
                a = BigInteger.Multiply(a, a);
                n >>= 1;
            }
            return res;
        }
    }
}