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;
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.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;
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.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;

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.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.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.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();
        }
    }
}

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;
        }
    }
}

#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;
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;

    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.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;
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;

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;
        }
    }
}