using System;
using System.Linq;
using CompLib.Util;
using System.Threading;
using System.IO;
using CompLib.Mathematics;
using CompLib.Algorithm;

public class Program
{
    int N;
    int Mod;
    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        ModInt.Mod = sc.NextInt();

        var m = new ModInt[N + 1][];
        m[1] = new ModInt[1] { 1 };
        for (int i = 2; i <= N; i++)
        {
            // 1の位置
            int max = (i - 1) * i / 2;
            m[i] = new ModInt[max + 1];

            for (int j = 0; j < i; j++)
            {
                for (int k = 0; k < m[i - 1].Length; k++)
                {
                    m[i][j + k] += m[i - 1][k];
                }
            }
        }

        var m2 = new ModInt[N + 1][];
        for (int i = 1; i <= N; i++)
        {
            m2[i] = new ModInt[m[i].Length + 1];
            for (int j = 0; j < m[i].Length; j++)
            {
                m2[i][j + 1] = m2[i][j] + m[i][j];
            }
        }

        ModInt ans = 0;

        for (int i = 0; i <= N - 2; i++)
        {
            // 先頭i個同じ
            // 選び方
            ModInt q = 1;
            for (int j = 0; j < i; j++) q *= N - j;

            ModInt w = 0;
            // i個目
            for (int j = 0; j < N - i; j++)
            {
                for (int k = 0; k < j; k++)
                {
                    // 残り N-i-1個の分布 m[N-i-1]
                    // i+1個目の転倒数への寄与 j,k

                    for (int l = j - k; l < m[N - i - 1].Length; l++)
                    {
                        w += m2[N - i - 1][l - (j - k)] * m[N - i - 1][l];
                    }
                }
            }

            ans += q * w;
        }
        Console.WriteLine(ans);
    }
    /*
    1 0
    1
    2 0
    1 1
    3 0
    1 2 2 1
    4 17
    1 3 5 6 5 3 1
    5 904
    1 4 9 15 20 22 20 15 9 4 1
    6 45926
    1 5 14 29 49 71 90 101 101 90 71 49 29 14 5 1
    7 2725016
    1 6 20 49 98 169 259 359 455 531 573 573 531 455 359 259 169 98 49 20 6 1
    8 196884712
    1 7 27 76 174 343 602 961 1415 1940 2493 3017 3450 3736 3836 3736 3450 3017 2493 1940 1415 961 602 343 174 76 27 7 1
    */

    void F(int n)
    {
        int[] p = new int[n];
        for (int i = 0; i < n; i++)
        {
            p[i] = i;
        }

        int[] cnt = new int[(n - 1) * n / 2 + 1];

        long ans = 0;
        do
        {
            int c = 0;
            for (int i = 0; i < n; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    if (p[i] > p[j]) c++;
                }
            }

            for (int i = c + 1; i < cnt.Length; i++)
            {
                ans += cnt[i];
            }

            cnt[c]++;
        } while (Algorithm.NextPermutation(p));

        Console.WriteLine($"{n} {ans}");
        Console.WriteLine(string.Join(" ", cnt));

        // 5 9 14 20 27
    }

    public static void Main(string[] args) => new Program().Solve();
    // public static void Main(string[] args) => new Thread(new Program().Solve, 1 << 27).Start();
}

namespace CompLib.Algorithm
{
    using System;
    using System.Collections.Generic;
    public static partial class Algorithm
    {
        private static void Swap<T>(ref T a, ref T b)
        {
            T tmp = a;
            a = b;
            b = tmp;
        }

        private static void Reverse<T>(T[] array, int begin)
        {
            // [begin, array.Length)を反転
            if (array.Length - begin >= 2)
            {
                for (int i = begin, j = array.Length - 1; i < j; i++, j--)
                {
                    Swap(ref array[i], ref array[j]);
                }
            }
        }

        /// <summary>
        /// arrayを辞書順で次の順列にする 存在しないときはfalseを返す
        /// </summary>
        /// <param name="array"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static bool NextPermutation<T>(T[] array, Comparison<T> comparison)
        {
            for (int i = array.Length - 2; i >= 0; i--)
            {
                if (comparison(array[i], array[i + 1]) < 0)
                {
                    int j = array.Length - 1;
                    for (; j > i; j--)
                    {
                        if (comparison(array[i], array[j]) < 0)
                        {
                            break;
                        }
                    }

                    Swap(ref array[i], ref array[j]);
                    Reverse(array, i + 1);
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// arrayを辞書順で次の順列にする 存在しないときはfalseを返す
        /// </summary>
        /// <param name="array"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static bool NextPermutation<T>(T[] array, Comparer<T> comparer) =>
            NextPermutation(array, comparer.Compare);

        /// <summary>
        /// arrayを辞書順で次の順列にする 存在しないときはfalseを返す
        /// </summary>
        /// <param name="array"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static bool NextPermutation<T>(T[] array) => NextPermutation(array, Comparer<T>.Default);
    }
}

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt
    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public static long Mod = (int)1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;
        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n) { num = n; }
        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

        /// <summary>
        /// 与えられた 2 つの数値からべき剰余を計算します．
        /// </summary>
        /// <param name="v">べき乗の底</param>
        /// <param name="k">べき指数</param>
        /// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
    }
    #endregion
    #region Binomial Coefficient
    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;
        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }
        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }
        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }
    #endregion
}

namespace CompLib.Util
{
    using System;
    using System.Linq;

    class Scanner
    {
        private string[] _line;
        private int _index;
        private const char Separator = ' ';

        public Scanner()
        {
            _line = new string[0];
            _index = 0;
        }

        public string Next()
        {
            if (_index >= _line.Length)
            {
                string s;
                do
                {
                    s = Console.ReadLine();
                } while (s.Length == 0);

                _line = s.Split(Separator);
                _index = 0;
            }

            return _line[_index++];
        }

        public string ReadLine()
        {
            _index = _line.Length;
            return Console.ReadLine();
        }

        public int NextInt() => int.Parse(Next());
        public long NextLong() => long.Parse(Next());
        public double NextDouble() => double.Parse(Next());
        public decimal NextDecimal() => decimal.Parse(Next());
        public char NextChar() => Next()[0];
        public char[] NextCharArray() => Next().ToCharArray();

        public string[] Array()
        {
            string s = Console.ReadLine();
            _line = s.Length == 0 ? new string[0] : s.Split(Separator);
            _index = _line.Length;
            return _line;
        }

        public int[] IntArray() => Array().Select(int.Parse).ToArray();
        public long[] LongArray() => Array().Select(long.Parse).ToArray();
        public double[] DoubleArray() => Array().Select(double.Parse).ToArray();
        public decimal[] DecimalArray() => Array().Select(decimal.Parse).ToArray();
    }
}


using System.Xml;
using System.ComponentModel.Design;
using System.Security.AccessControl;
using System.Globalization;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System;

namespace CodeForce
{
    class Program
    {
        static void Main(string[] args)
        {
            var arr = Console.ReadLine().Split(' ');
            var rows = Int32.Parse(arr[0]);
            var cols = Int32.Parse(arr[1]);
            Console.WriteLine(GetCount(rows,cols));
        }

        private static long GetCount(int rows, int cols)
        {
            if(rows == 1)
            {
                return 1;
            }
            var res = 1L;
            var maxPows = new int[rows+1];
            var cntArr = GetCntArr(cols);
            for(var i = 2;i <= rows;i++)
            {
                var tmp = i;
                for(var j=2;j<rows;j++)
                {
                    if(tmp<= rows/i)
                    {
                        tmp*=i;
                        if(maxPows[tmp] == 0)
                            maxPows[tmp] = j;
                    }
                    else
                    {
                        break;
                    }
                }

                if(maxPows[i] == 0)
                {
                    res+= cols;
                }
                else
                {
                    res+= cntArr[maxPows[i]];
                }

            }
            return res;
        }

        private static int[] GetCntArr(int n)
        {
            var cntArr = new int[21];

            for(var i =2;i<=20;i++)
            {
                var usedArr = new bool[n+1];
                for(var j = 1;j < i;j++)
                {
                    var gcd = GetGCD(i,j);
                    var tmp = i/gcd;
                    for(var k=1;k<=n/tmp;k++)
                    {
                        usedArr[k * j/gcd] = true;
                    }
                }
                for(var k=1;k<=n;k++)
                {
                    if(!usedArr[k]) cntArr[i]++;
                }
            }

            return cntArr;

        }

        private static int GetGCD(int num0, int num1)
        {
            if(num0 < num1)
            {
                var tmp = num0;
                num0 = num1;
                num1 = tmp;
            }
            while(num1!=0)
            {
                var tmp = num0% num1;
                num0 = num1;
                num1 = tmp;
            }
            return num0;
        }

        private static int BruteGetCount(int rows, int cols)
        {
            var set = new HashSet<int>();
            for(var i =1;i<=rows;i++)
            {
                var tmp = 1;
                for(var j=1;j<=cols;j++)
                {
                    tmp*=i;
                    set.Add(tmp);
                }
            }
            return set.Count;
        }

    }
}


using System.Xml;
using System.ComponentModel.Design;
using System.Security.AccessControl;
using System.Globalization;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System;

namespace CodeForce
{
    class Program
    {
        static void Main(string[] args)
        {
            var arr = Console.ReadLine().Split(' ');
            var rows = Int32.Parse(arr[0]);
            var cols = Int32.Parse(arr[1]);
            Console.WriteLine(GetCount(rows,cols));

        }

        private static long GetCount(int rows, int cols)
        {
            if(rows == 1)
            {
                return 1;
            }
            var res = 1L;
            var maxPows = new int[rows+1];
            var cntArr = GetCntArr(cols);
            for(var i = 2;i <= rows;i++)
            {
                var tmp = i;
                for(var j=2;j<rows;j++)
                {
                    if(tmp<= rows/i)
                    {
                        tmp*=i;
                        if(maxPows[tmp] == 0)
                            maxPows[tmp] = j;
                    }
                    else
                    {
                        break;
                    }
                }

                if(maxPows[i] == 0)
                {
                    res+= cols;
                }
                else
                {
                    res+= cntArr[maxPows[i]];
                }

            }
            return res;
        }

        private static int[] GetCntArr(int n)
        {
            var cntArr = new int[21];

            for(var i =2;i<=20;i++)
            {
                var usedArr = new bool[n+1];
                for(var j = 1;j < i;j++)
                {
                    for(var k=1;k<=n;k++)
                    {
                        if(j*k % i == 0)
                        {
                            usedArr[j*k / i] = true;
                        }
                    }
                }
                for(var k=1;k<=n;k++)
                {
                    if(!usedArr[k]) cntArr[i]++;
                }
            }

            return cntArr;

        }

        private static int GetGCD(int num0, int num1)
        {
            if(num0 < num1)
            {
                var tmp = num0;
                num0 = num1;
                num1 = tmp;
            }
            while(num1!=0)
            {
                var tmp = num0% num1;
                num0 = num1;
                num1 = tmp;
            }
            return num0;
        }

        private static int BruteGetCount(int rows, int cols)
        {
            var set = new HashSet<int>();
            for(var i =1;i<=rows;i++)
            {
                var tmp = 1;
                for(var j=1;j<=cols;j++)
                {
                    tmp*=i;
                    set.Add(tmp);
                }
            }
            return set.Count;
        }

    }
}


using System;

public sealed class Program {

  public Program() {
    String[] token = Console.ReadLine().Split();
    Int32 b = Int32.Parse(token[0]), d = Int32.Parse(token[1]), i, j, cnt;
    String a = Console.ReadLine(), c = Console.ReadLine();
    Int32[] map = new Int32[c.Length];
    for (i = 0; i < c.Length; map[i++] = cnt) {
      for (j = cnt = 0; j < a.Length; ++j) {
        if (c[(i + cnt) % c.Length] == a[j]) {
          ++cnt;
        }
      }
    }
    for (cnt = i = 0; i < b; ++i) {
      cnt += map[cnt % c.Length];
    }
    Console.WriteLine(cnt / (c.Length * d));
  }

  // stuff cutline

  static Int32 ReadInt() {
    Boolean neg = false;
    Int32 ch, ans = 0;
    do {
      ch = Console.Read();
      neg |= ch == (Int32)'-';
    } while (!Char.IsDigit((Char)ch));
    do {
      ans = ans * 10 + (ch & 0xf);
      ch = Console.Read();
    } while (Char.IsDigit((Char)ch));
    return neg ? -ans : ans;
  }

  public static void Main() {
#if DEBUG
    Console.SetIn(new System.IO.StreamReader("..\\..\\in.txt"));
#endif
    var root = new Program();
    Console.Out.Flush();
  }

}


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

namespace CodeForces.Solutions.c314_187_1
{
	public class Program2
	{
		public static void Main()
		{
			checked
			{
				var s = Console.ReadLine().Split(' ').Select(long.Parse).ToArray();
				var b = s[0];
				var d = s[1];

				var s1 = Console.ReadLine();
				var s2 = Console.ReadLine();

				var adds = new int[s2.Length];
				var follows = new int[s2.Length];

				for (var i = 0; i < s2.Length; i++)
				{
					var index = i;
					for (var j = 0; j < s1.Length; j++)
					{
						if (s2[index] == s1[j])
						{
							index++;
							if (index == s2.Length)
							{
								index = 0;
								adds[i]++;
							}
						}
					}
					follows[i] = index;
				}

				var x = 0;
				var p = 0;
				for (var i = 0; i < b; i++)
				{
					p += adds[x];
					x = follows[x];
				}

				Console.WriteLine(p/d);
			}
		}
	}
}


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

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            long n = ReadLong();
            var a = new int[10];
            while (n > 0)
            {
                a[n % 10]++;
                n /= 10;
            }

            long[] f = new long[20];
            f[0] = 1;
            for (int i = 1; i < 19; i++)
            {
                f[i] = i * f[i - 1];
            }

            Calc(0, a, new int[10], f);

            Writer.WriteLine(Ans);
        }

        private static void Calc(int t, int[] a, int[] b, long[] f)
        {
            if (t > 9)
            {
                int sum = b.Sum();
                for (int i = 1; i < 10; i++)
                {
                    if (b[i] > 0)
                    {
                        b[i]--;

                        long d = f[sum - 1];
                        for (int j = 0; j < 10; j++)
                        {
                            d /= f[b[j]];
                        }
                        Ans += d;

                        b[i]++;
                    }
                }
                return;
            }

            if (a[t] > 0)
            {
                for (int i = 0; i < a[t]; i++)
                {
                    b[t] = i + 1;
                    Calc(t + 1, a, b, f);
                }
            }
            else
            {
                b[t] = 0;
                Calc(t + 1, a, b, f);
            }
        }

        public static long Ans = 0;

        public static void Solve()
        {
            SolveCase();

            /*var sw = Stopwatch.StartNew();*/

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

            /*sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);*/
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            //Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Random rnd = new Random();
            for (int i = result.Length - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = result[k];
                result[k] = result[i];
                result[i] = tmp;
            }
            return result;
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


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

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		long[][] nCr = new long[21][];
		for(int i=0;i<21;i++){
			nCr[i] = new long[21];
		}

		nCr[0][0] = 1;
		for(int i=1;i<21;i++){
			nCr[i][0] = 1;
			for(int j=1;j<21;j++){
				nCr[i][j] = nCr[i-1][j] + nCr[i-1][j-1];
			}
		}
		long[] dp = new long[N+1];
		dp[0] = 1;
		int[] cnt = new int[10];
		for(int i=0;i<N;i++) cnt[S[i] - '0']++;
//Console.WriteLine("ok");

		for(int v=9;v>=0;v--){
			if(cnt[v] == 0) continue;
//Console.WriteLine(String.Join(" ",  dp));
			long[] ndp = new long[N+1];
			for(int l=0;l<=N;l++){
				if(dp[l] == 0) continue;
				for(int c = 1; c <= cnt[v]; c++){
					int m = l + 1;
					if(v == 0) m--;
					ndp[l + c] += dp[l] * nCr[m - 1 + c][c];
				}
			}
			dp = ndp;
//Console.WriteLine("ndpp:{0}",String.Join(" ",  dp));
		}

		Console.WriteLine(dp.Sum());
	}
	int N;
	String S;
	public Sol(){
		S = rs();
		N = S.Length;
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


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

class Program
{
	int n, m, res;
	int mod = 1000000007;
	int add(int x, int y)
	{
		x += y;
		return x < mod ? x : x - mod;
	}
	int mul(int x, int y)
	{
		return Convert.ToInt32(Convert.ToInt64(x) * y % mod);
	}

	int gcd(int x, int y)
	{
		return y != 0 ? gcd(y, x % y) : x;
	}
	private int[] x = new int[6];
	void dfs(int i)
	{
		if (i == 6)
		{
			if ((x[0] * x[3] + x[2] * x[5] + x[4] * x[1] + x[1] * x[2] + x[3] * x[4] + x[5] * x[0]) % 2 == 0)
			{
				int now = 1;
				for(int j=0; j<6; j++)
					if (j % 2 == 0)
						now = mul(now, x[j] == 1 ? (n + 1) / 2 : n / 2 + 1);
					else
						now = mul(now, x[j] == 1 ? (m + 1) / 2 : m / 2 + 1);
				res = add(res, now);
			}
			return;
		}
		x[i] = 0;
		dfs(i + 1);
		x[i] = 1;
		dfs(i + 1);
	}
	void run()
	{
		String[] str = Console.ReadLine().Split(' ');
		n = Convert.ToInt32(str[0]);
		m = Convert.ToInt32(str[1]);
		res = 0;
		dfs(0);
		int res2 = 0;
		for (int i = 0; i <= n; i++)
			for (int j = 0; j <= m; j++)
				if (i + j > 0)
				{
					int x = gcd(i, j) - 1;
					res2 = add(res2, mul(i > 0 && j > 0 ? x * 2 : x, (n + 1 - i) * (m + 1 - j)));
				}

		int q = (n + 1) * (m + 1);
		res2 = add(res2, Convert.ToInt32(Convert.ToInt64(q) * (q - 1) / 2 % mod));
		res2 = mul(res2, 6);
		res2 = add(res2, q);
		Console.WriteLine(add(res, mod - res2));
	}
	static void Main(String[] args)
	{
		new Program().run();
	}
}


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

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){

		for(int i=0;i<4;i++){
			if(Inside(A[2*i], A[2*i+1], B)){
				Console.WriteLine("YES");
				return;
			}
			if(Inside(B[2*i], B[2*i+1], A)){
				Console.WriteLine("YES");
				return;
			}
		}
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				if(OnLine(A[2*i], A[2*i+1], B[2*j], B[2*j+1], B[(2*j+2)%8], B[(2*j+3)%8])){
					Console.WriteLine("YES");
					return;
				}
				if(OnLine(B[2*i], B[2*i+1], A[2*j], A[2*j+1], A[(2*j+2)%8], A[(2*j+3)%8])){
					Console.WriteLine("YES");
					return;
				}
			}
		}
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				if(Intersects(A[2*i], A[2*i+1], A[(2*i+2)%8], A[(2*i+3)%8], B[2*j], B[2*j+1], B[(2*j+2)%8], B[(2*j+3)%8])){
					Console.WriteLine("YES");
					return;
				}
			}
		}
		Console.WriteLine("NO");

	}

	bool Inside(int x, int y, int[] rect){
		var h = new HashSet<int>();
		for(int i=0;i<4;i++){
			var d = det(rect[2*i] - x, rect[2*i+1] - y, rect[(2*i+2)%8] - x, rect[(2*i+3)%8] - y);
			if(d == 0) return false;
			d = d > 0 ? 1 : -1;
			h.Add(d);
		}
		return h.Count == 1;
	}
	bool OnLine(int x, int y, int x1, int y1, int x2, int y2){
		if(x == x1 && y == y1) return true;
		if(x == x2 && y == y2) return true;
		if(det(x1 - x, y1 - y, x2 - x, y2 - y) != 0) return false;
		return (x1 - x) * (x2 - x) + (y1 - y) * (y2 - y) < 0;
	}
	bool Intersects(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){

		int d0 = det0(x3 - x1, y3 - y1, x2 - x1, y2 - y1);
		int d1 = det0(x4 - x1, y4 - y1, x2 - x1, y2 - y1);
		if(d0 == 0 || d1 == 0 || d0 == d1) return false;
		int d2 = det0(x1 - x3, y1 - y3, x4 - x3, y4 - y3);
		int d3 = det0(x2 - x3, y2 - y3, x4 - x3, y4 - y3);
		if(d2 == 0 || d3 == 0 || d2 == d3) return false;
		return true;

	}

	int det (int a, int b, int c, int d){
		return a * d - b * c;
	}
	int det0 (int a, int b, int c, int d){
		var ret = a * d - b * c;
		if(ret == 0) return 0;
		if(ret > 0) return 1;
		return -1;
	}

	int[] A, B;
	public Sol(){
		A = ria();
		B = ria();
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}


#define EXTENDSTACKSIZE

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

namespace CF
{
    internal class Program
    {
        private const int stackSize = 32 * 1024 * 1024;

        private static void Run()
        {
            using (var sr = new InputReader(Console.In))
//            using (var sr = new InputReader(new StreamReader("input.txt")))
            using (var sw = Console.Out)
//            using (var sw = new StreamWriter("output.txt"))
            using (var task = new Task(sr, sw)) {
                task.Solve();
//                Console.ReadKey();
            }
        }

        private static void Main(string[] args)
        {
#if EXTENDSTACKSIZE
            var threadStart = new ThreadStart(Run);
            var thread = new Thread(threadStart, stackSize);
            thread.Start();
            thread.Join();
#else
            Run();
#endif
        }
    }

    internal class Task : IDisposable
    {
        private readonly InputReader sr;
        private readonly TextWriter sw;
        private bool isDispose;

        public Task(InputReader sr, TextWriter sw)
        {
            this.sr = sr;
            this.sw = sw;
        }

        public void Solve()
        {
            var c1 = sr.ReadArrayOfInt32();
            var c2 = sr.ReadArrayOfInt32();
            var coords1 = new int[10];
            var coords2 = new int[10];
            for (var i = 0; i < c1.Length; i++) {
                coords1[i] = c1[i];
                coords2[i] = c2[i];
            }

            coords1[8] = c1[0];
            coords1[9] = c1[1];
            coords2[8] = c2[0];
            coords2[9] = c2[1];
            for (var i = 0; i < 4; i++) {
                for (var j = 0; j < 4; j++) {
                    if (IsIntersect(coords1[i * 2], coords1[i * 2 + 1], coords1[(i + 1) * 2], coords1[(i + 1) * 2 + 1],
                        coords2[j * 2], coords2[j * 2 + 1], coords2[(j + 1) * 2], coords2[(j + 1) * 2 + 1])) {
                        sw.WriteLine("YES");
                        return;
                    }
                }
            }

            for (var i = 0; i < 4; i++) {
                if (Inside(coords1[i * 2], coords1[i * 2 + 1], coords2)) {
                    sw.WriteLine("YES");
                    return;
                }
            }

            for (var i = 0; i < 4; i++) {
                if (Inside(coords2[i * 2], coords2[i * 2 + 1], coords1)) {
                    sw.WriteLine("YES");
                    return;
                }
            }

            sw.WriteLine("NO");
        }

        private bool Inside(int x1, int y1, int[] coords)
        {
            var intersectsCount = 0;
            for (var i = 0; i < 4; i++) {
                if (IsIntersect(x1, y1, 100, 100, coords[i * 2], coords[i * 2 + 1], coords[(i + 1) * 2], coords[(i + 1) * 2 + 1])) {
                    intersectsCount++;
                }
            }

            return intersectsCount == 1;
        }

        private int Cross(int x1, int y1, int x2, int y2, int x, int y)
        {
            return (x1 - x) * (y2 - y) - (x2 - x) * (y1 - y);
        }

        private bool IsIntersect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
        {
            var d1 = Cross(x2, y2, x3, y3, x1, y1);
            var d2 = Cross(x2, y2, x4, y4, x1, y1);
            var d3 = Cross(x4, y4, x2, y2, x3, y3);
            var d4 = Cross(x4, y4, x1, y1, x3, y3);
            if (((d1 > 0 && d2 < 0) || (d2 > 0 && d1 < 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)))
                return true;
            if (d1 == 0 && InSegment(x1, y1, x2, y2, x3, y3))
                return true;
            if (d2 == 0 && InSegment(x1, y1, x2, y2, x4, y4))
                return true;
            if (d3 == 0 && InSegment(x3, y3, x4, y4, x2, y2))
                return true;
            if (d4 == 0 && InSegment(x3, y3, x4, y4, x1, y1))
                return true;

            return false;
        }

        private bool InSegment(int x1, int y1, int x2, int y2, int x, int y)
        {
            return x >= Math.Min(x1, x2) && x <= Math.Max(x1, x2) && y >= Math.Min(y1, y2) && y <= Math.Max(y1, y2);
        }

        ~Task()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!isDispose) {
                if (disposing) {
                    if(sr != null)
                        sr.Dispose();

                    if(sw != null)
                        sw.Dispose();
                }

                isDispose = true;
            }
        }
    }
}

internal class InputReader : IDisposable
{
    private bool isDispose;
    private readonly TextReader sr;
    private string[] buffer;
    private int seek;

    public InputReader(TextReader stream)
    {
        sr = stream;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public string NextString()
    {
        var result = sr.ReadLine();
        return result;
    }

    public int NextInt32()
    {
        return Int32.Parse(ReadNextToken());
    }

    private string ReadNextToken()
    {
        if (buffer == null || seek == buffer.Length) {
            seek = 0;
            buffer = NextSplitStrings();
        }

        return buffer[seek++];
    }

    public long NextInt64()
    {
        return Int64.Parse(ReadNextToken());
    }

    public int[] ReadArrayOfInt32()
    {
        return ReadArray(Int32.Parse);
    }

    public long[] ReadArrayOfInt64()
    {
        return ReadArray(Int64.Parse);
    }

    public string[] NextSplitStrings()
    {
        return NextString()
            .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public T[] ReadArray<T>(Func<string, CultureInfo, T> func)
    {
        return NextSplitStrings()
            .Select(s => func(s, CultureInfo.InvariantCulture))
            .ToArray();
    }

    public T[] ReadArrayFromString<T>(Func<string, CultureInfo, T> func, string str)
    {
        return
            str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => func(s, CultureInfo.InvariantCulture))
                .ToArray();
    }

    protected void Dispose(bool dispose)
    {
        if (!isDispose)
        {
            if (dispose)
                sr.Close();

            isDispose = true;
        }
    }

    ~InputReader()
    {
        Dispose(false);
    }
}


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

namespace Ravioli_Sort
{
    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)
        {
            writer.WriteLine(Solve(args) ? "YES" : "NO");
            writer.Flush();
        }

        private static bool Solve(string[] args)
        {
            int n = Next();

            var nn = new List<int>(n);
            for (int i = 0; i < n; i++)
            {
                nn.Add(Next());
            }

            for (int i = n; i > 0; i--)
            {
                for (int j = 1; j < nn.Count; j++)
                {
                    if (Math.Abs(nn[j] - nn[j - 1]) >= 2)
                        return false;
                }

                int m = 0;
                for (int j = 1; j < nn.Count; j++)
                {
                    if (nn[m] > nn[j])
                        m = j;
                }

                nn.RemoveAt(m);
            }

            return true;
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


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

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = Convert.ToInt32(Console.ReadLine());
            int[] mass = new int[i];
            string[] q = Console.ReadLine().Split(' ');
            bool flag = true;

            for (int j = 0; j < i; j++)
            {
                mass[j] = Convert.ToInt32(q[j]);
            }

            for (int j = 0; j < i - 1; j++)
            {
                if (Math.Abs(mass[j] - mass[j + 1]) > 1)
                {
                    Console.WriteLine("NO");
                    flag = false;
                    break;
                }
            }

            if (flag)
            {
                Console.WriteLine("YES");
            }

        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;

namespace Codeforces.R318.E
{
    public static class Solver
    {
        public static void Main()
        {
            using (var sw = new StreamWriter(Console.OpenStandardOutput()) {
                AutoFlush = false
            })
            {
                Solve(Console.In, sw);
            }
        }

        public static void Solve(TextReader tr, TextWriter tw)
        {
            WriteAnswer(tw, Parse(tr));
        }

        private static void WriteAnswer(TextWriter tw, long[] res)
        {
            if (res == null)
            {
                tw.WriteLine("NO");
                return;
            }

            tw.WriteLine(res.Length);

            foreach (var t in res)
            {
                var prev = t & ((1 << 16) - 1);
                var to = (t >> 16) & ((1 << 16) - 1);
                var d = t >> 32;
                tw.WriteLine("{0} {1} {2}", prev + 1, to + 1, d);
            }
        }

        private static long[] Parse(TextReader tr)
        {
            var w = tr.ReadLine().Split();
            var e = int.Parse(w[2]);

            var a = from x in tr.ReadLine().Split() select int.Parse(x);
            var b = from x in tr.ReadLine().Split() select int.Parse(x);

            var edges = new (int, int)[e];
            for (int i = 0; i < e; ++i)
            {
                var l = tr.ReadLine().Split();
                edges[i] = (int.Parse(l[0]) - 1, int.Parse(l[1]) - 1);
            }

            return Calc(a.ToArray(), b.ToArray(), edges);
        }

        public static long[] Calc(int[] a, int[] b, (int, int)[] edges)
        {
            var n = a.Length;
            var mat = new (int, int)[n, n];

            for (int i = 0; i < n; ++i)
            {
                for (int j = 0; j < n; ++j)
                {
                    mat[i, j] = i == j ? (0, i) : (9999, i);
                }
            }

            foreach (var edge in edges)
            {
                mat[edge.Item1, edge.Item2] = (1, edge.Item1);
                mat[edge.Item2, edge.Item1] = (1, edge.Item2);
            }

            for (int k = 0; k < n; ++k)
            {
                for (int i = 0; i < n; ++i)
                {
                    for (int j = 0; j < n; ++j)
                    {
                        if (mat[i, k].Item1 + mat[k, j].Item1 < mat[i, j].Item1)
                        {
                            mat[i, j] = (mat[i, k].Item1 + mat[k, j].Item1, mat[k, j].Item2);
                        }
                    }
                }
            }

            var res = Execute(a, b, mat);

            if (!a.SequenceEqual(b))
            {
                return null;
            }

            return res.ToArray();
        }

        public static List<long> Execute(int[] a, int[] b, (int, int)[,] mat)
        {
            var calculator = new Calculator(a, b, mat);
            return calculator.Solve();
        }
    }

    internal class Calculator
    {
        List<long> res = new List<long>();
        int[] a;
        int[] b;
        (int, int)[,] mat;

        public Calculator(int[] a, int[] b, (int, int)[,] mat)
        {
            this.a = a;
            this.b = b;
            this.mat = mat;
        }

        public List<long> Solve()
        {
            var n = a.Length;
            for (; ; )
            {
                var prev = res.Count;
                for (int i = 0; i < n; ++i)
                {
                    for (int j = 0; j < n; ++j)
                    {
                        if (a[i] > b[i] && a[j] < b[j] && mat[i, j].Item1 <= n)
                        {
                            Pour(i, j, Math.Min(a[i] - b[i], b[j] - a[j]));
                        }
                    }
                }
                if (prev == res.Count)
                {
                    break;
                }
            }

            return res;
        }

        private void Pour(int from, int to, int d)
        {
            if (from == to)
            {
                return;
            }

            var prev = mat[from, to].Item2;
            var p = Math.Min(a[prev], d);
            if (p > 0)
            {
                a[prev] -= p;
                a[to] += p;
                res.Add(CreateKey(prev, to, p));
            }

            Pour(from, prev, d);

            if (d - p > 0)
            {
                a[prev] -= d - p;
                a[to] += d - p;
                res.Add(CreateKey(prev, to, d - p));
            }
        }

        private long CreateKey(long prev, long to, long d)
        {
            return (d << 32) + (to << 16) + prev;
        }
    }
}


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

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

    long mod = 1000000007;
    void solve()
    {
        Scanner cin = new Scanner();

        int n = cin.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
        {
            a[i] = cin.nextInt();
        }

        int MAX = 1 << n;

        long[] now = new long[MAX];

        long[] plus = new long[n + 100];
        plus[0] = 0;
        plus[1] = 0;
        plus[2] = 1;

        for (int i = 3; i <= n; i++)
        {
            plus[i] = (plus[i - 1] * (i - 1)) % mod;
        }

        for (int i = 0; i < MAX; i++)
        {
            int count = 0;
            int sum = 0;
            for (int j = 0; j < n; j++)
            {
                if ((i >> j) % 2 == 0) continue;
                count++;
                sum += a[j] - 1;
            }
            sum += 2;
            if (sum >= count)
            {
                now[i] = plus[count];
            }
        }

        long ret = 0;
        long[] dp = new long[MAX];
        for (int i = 0; i < MAX; i++)
        {
            int revi = MAX - 1 - i;
            for (int j = revi; j > 0; j = ((j - 1) & revi))
            {
                dp[i + j] = (dp[i + j] + now[i] * dp[j]) % mod;
            }
            dp[i] = (dp[i] + now[i]) % mod;
        }
        for (int i = 0; i < MAX; i++)
        {
            ret = (ret + dp[i]) % mod;
        }
        ret = (ret + 1) % mod;
        Console.WriteLine(ret);

    }

    int bitCount(long x)
    {
        x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
        x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
        x = (x & 0x0f0f0f0f0f0f0f0f) + (x >> 4 & 0x0f0f0f0f0f0f0f0f);
        x = (x & 0x00ff00ff00ff00ff) + (x >> 8 & 0x00ff00ff00ff00ff);
        x = (x & 0x0000ffff0000ffff) + (x >> 16 & 0x0000ffff0000ffff);
        return (int)((x & 0x00000000ffffffff) + (x >> 32 & 0x00000000ffffffff));
    }

}

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.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Linq;

namespace Codeforces.R316D1
{
    public struct ModInteger : IEquatable<ModInteger>
    {
        readonly int mod;
        readonly long value;
        public ModInteger(int mod, long value = 0L)
        {
            this.mod = mod;
            this.value = value % mod;
            if (value < 0)
            {
                this.value = value + mod;
            }
        }

        public bool Equals(ModInteger other)
        {
            return mod == other.mod && value == other.value;
        }

        public override bool Equals(object obj)
        {
            if (!(obj is ModInteger))
            {
                return false;
            }
            var other = (ModInteger)obj;
            return Equals(other);
        }

        public override int GetHashCode()
        {
            return (int)value;
        }

        public static bool operator ==(ModInteger left, ModInteger right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(ModInteger left, ModInteger right)
        {
            return !(left == right);
        }

        public static ModInteger LeftShift(ModInteger left, int right)
        {
            return left << right;
        }

        public static ModInteger operator <<(ModInteger left, int right)
        {
            if (right > 32)
            {
                return left << 32 << (right - 32);
            }
            return new ModInteger(left.mod, left.value << right);
        }

        public static ModInteger Add(ModInteger left, int right)
        {
            return left + right;
        }

        public static ModInteger operator +(ModInteger left, int right)
        {
            return new ModInteger(left.mod, left.value + right);
        }

        public static ModInteger operator ++(ModInteger m)
        {
            return m + 1;
        }

        public static ModInteger Multiply(ModInteger left, int right)
        {
            return new ModInteger(left.mod, left.value * right);
        }

        public static ModInteger operator *(ModInteger left, int right)
        {
            return Multiply(left, right);
        }

        public static ModInteger Div(int left, int right, int mod)
        {
            return Pow(right, mod - 2, mod) * left;
        }

        public static ModInteger Pow(long x, int n, int mod)
        {
            var res = 1L;
            for (; n > 0; n >>= 1)
            {
                if ((n & 1) == 1)
                {
                    res = res * x % mod;
                }
                x = x * x % mod;
            }
            return new ModInteger(mod, res);
        }

        public static ModInteger ToModInteger(int value)
        {
            return new ModInteger(0, value);
        }

        public static implicit operator int(ModInteger value)
        {
            return (int)value.value;
        }

        public static int ToInt32(ModInteger value)
        {
            return value;
        }

        public static ModInteger Increment(ModInteger item)
        {
            return ++item;
        }
    }
    public static class Solver
    {
        const int mod = 1000000007;
        public static void Main()
        {
            using (var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false })
            {
                Solve(Console.In, sw);
            }
        }

        public static void Solve(TextReader tr, TextWriter tw)
        {
            Contract.Requires(tr != null);
            Contract.Requires(tw != null);

            tw.WriteLine(Parse(tr));
        }

        private static int Parse(TextReader tr)
        {
            var info = CultureInfo.InvariantCulture;
            tr.ReadLine();
            var a = tr.ReadLine().Split().Select(x => int.Parse(x, info)).ToArray();

            return Calc(a);
        }

        private static ModInteger Calc(int[] a)
        {
            int num1 = a.Count(x => x == 1);
            int num2 = a.Length - num1;

            return F(num1, num2);
        }

        private static ModInteger F(int a, int b)
        {
            var res = new ModInteger(mod, 1);

            for (int i = 0; i < b; ++i)
            {
                res *= a + 1 + i;
            }

            if (a == 0)
            {
                return res;
            }

            var I = new ModInteger[a + 1];
            I[0] = new ModInteger(mod, 1);
            I[1] = new ModInteger(mod, 1);
            for (int i = 2; i <= a; ++i)
            {
                I[i] = I[i - 1] + (i - 1) * I[i - 2];
            }
            return res * I[a];
        }
    }
}


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

namespace Codeforces.R355.D
{
    public static class Solver
    {
        public static void Main()
        {
            using (var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false })
            {
                Solve(Console.In, sw);
            }
        }

        public static void Solve(TextReader tr, TextWriter tw)
        {
            WriteAnswer(tw, Parse(tr));
        }

        struct Answer
        {
            public string Winner;
        }

        private static void WriteAnswer(TextWriter tw, Answer answer)
        {
            tw.WriteLine(answer.Winner);
        }

        private static Answer Parse(TextReader tr)
        {
            var n = int.Parse(tr.ReadLine());
            var board = new string[n];
            for (var i = 0; i < n; ++i)
                board[i] = tr.ReadLine();
            return Calc(board);
        }

        private static Answer Calc(string[] board)
        {
            var answer = new Answer();
            var memo = new Dictionary<(int, int), int>();
            var r = Rec("" + board[0][0], 1, 0, board, memo);

            if (r > 0)
                answer.Winner = "FIRST";
            else if (r < 0)
                answer.Winner = "SECOND";
            else
                answer.Winner = "DRAW";

            return answer;
        }

        private static int Rec(string str, int mask, int currentC, string[] board, Dictionary<(int, int), int> memo)
        {
            var n = board.Length;
            var numStr = str.Length;

            var key = (numStr, mask);
            if (memo.ContainsKey(key))
                return memo[key];

            if (numStr == n * 2 - 1)
            {
                if (str.Last() == 'a')
                    return 1;
                else if (str.Last() == 'b')
                    return -1;
                return 0;
            }

            var res = numStr % 2 == 0 ? int.MinValue : int.MaxValue;

            for (var ch = 'a'; ch <= 'z'; ++ch)
            {
                var nm = 0;

                for (var y = 0; y < n; ++y)
                {
                    if ((mask & (1 << y)) == 0)
                        continue;
                    var x = numStr - y - 1;
                    if (x < 0 || x >= n)
                        continue;
                    if (x < n - 1 && board[y][x + 1] == ch)
                        nm |= 1 << y;
                    if (y < n - 1 && board[y + 1][x] == ch)
                        nm |= 1 << y + 1;
                }
                if (nm == 0)
                    continue;

                if (numStr % 2 == 0)
                    res = Math.Max(res, Rec(str + ch, nm, 0, board, memo));
                else
                    res = Math.Min(res, Rec(str + ch, nm, 0, board, memo));
            }

            if (str.Last() == 'a')
                res += 1;
            else if (str.Last() == 'b')
                res += -1;

            return memo[key] = res;
        }
    }
}


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

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    private int n;

    private string[] table;
    private int?[,] mem;

    List<Tuple<int, int>> Decode(int x, int mask)
    {
        var ret = new List<Tuple<int, int>>();
        if (x >= n)
        {
            int d = x - n;
            for (int i = 0; i < n - 1 - d; i++)
                if ((mask >> i & 1) == 1)
                    ret.Add(Tuple.Create(d + 1 + i, n - 1 - i));
        }
        else
        {
            for (int i = 0; i <= x; i++)
                if ((mask >> i & 1) == 1)
                    ret.Add(Tuple.Create(i, x - i));
        }
        return ret;
    }

    int Encode(int r, int c)
    {
        if (r + c >= n)
            return 1 << n - c - 1;
        return 1 << r;
    }

    int Fun(int x, int mask)
    {
        if (mem[x, mask].HasValue)
            return mem[x, mask].Value;

        if (x == 2 * (n - 1))
            return 0;

        var cpos = Decode(x, mask);

        int ret = x % 2 == 1 ? int.MinValue : int.MaxValue;
        for (char ch = 'a'; ch <= 'z'; ch++)
        {
            int nmask = 0;
            foreach (var p in cpos)
            {
                if (p.Item1 + 1 < n && table[p.Item1 + 1][p.Item2] == ch)
                    nmask |= Encode(p.Item1 + 1, p.Item2);
                if (p.Item2 + 1 < n && table[p.Item1][p.Item2 + 1] == ch)
                    nmask |= Encode(p.Item1, p.Item2 + 1);
            }
            if (nmask > 0)
            {
                int y = Fun(x + 1, nmask);
                if (ch == 'a')
                    y++;
                else if (ch == 'b')
                    y--;
                if (x % 2 == 1)
                    ret = Math.Max(ret, y);
                else
                    ret = Math.Min(ret, y);
            }
        }

        return (mem[x, mask] = ret).Value;
    }

    public object Solve()
    {
        n = ReadInt();
        table = ReadLines(n);

        mem = new int?[n << 1,1 << n];
        int r = Fun(0, 1);
        if (table[0][0] == 'a')
            r++;
        if (table[0][0] == 'b')
            r--;

        return r > 0 ? "FIRST" : (r == 0 ? "DRAW" : "SECOND");
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
#endif
        try
        {
            var ts = DateTime.Now;
            object result = new Solver().Solve();
            if (result != null)
                writer.WriteLine(result);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            Console.WriteLine(ex);
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read/Write

    private static Queue<string> currentLineTokens = new Queue<string>();

    private static string[] ReadAndSplitLine()
    {
        return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public static string ReadToken()
    {
        while (currentLineTokens.Count == 0)
            currentLineTokens = new Queue<string>(ReadAndSplitLine());
        return currentLineTokens.Dequeue();
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray()
    {
        return ReadAndSplitLine().Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray()
    {
        return ReadAndSplitLine().Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray()
    {
        return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows);
        int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = new int[numberOfRows];
            for (int j = 0; j < numberOfRows; j++)
                ret[i][j] = matrix[j][i];
        }
        return ret;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
            lines[i] = reader.ReadLine().Trim();
        return lines;
    }

    public static void WriteArray<T>(params T[] array)
    {
        writer.WriteLine(string.Join(" ", array));
    }

    #endregion
}


using System;
using System.Linq;

namespace a
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = int.Parse(Console.ReadLine());

            var a = Convert.ToString(x, 2).PadLeft(6, '0').ToArray();

            var temp = a[1];
            a[1] = a[5];
            a[5] = temp;
            temp = a[2];
            a[2] = a[3];
            a[3] = temp;

            Console.WriteLine(Convert.ToInt32(new String(a), 2));
        }
    }
}


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

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    public void Solve()
    {
        int x = ReadInt();
        var a = Convert.ToString(x, 2).ToList();
        while (a.Count < 6)
            a.Insert(0, '0');

        char t = a[1];
        a[1] = a[5];
        a[5] = t;
        t = a[2];
        a[2] = a[3];
        a[3] = t;
        Write(Convert.ToInt32(new string(a.ToArray()), 2));
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("input.txt");
        //writer = new StreamWriter("output.txt");
#endif
        try
        {
            new Solver().Solve();
            //var thread = new Thread(new Solver().Solve, 1024 * 1024 * 128);
            //thread.Start();
            //thread.Join();
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}


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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] t1 = Console.ReadLine().Split();
            int n = int.Parse(t1[0]); // КОЛЛИЧЕСТВО ПАПОК
            int m = int.Parse(t1[1]); // ПАПОК ПО ГОРИЗОНТАЛИ
            int a = int.Parse(t1[2]); // ОТ А
            int b = int.Parse(t1[3]); // ДО Б

            int kstrok = n / m + 1; // koll strok

            int[] array = new int[kstrok + 1];
            for (int i = 2; i < kstrok + 1; i++) //massiv zapominaet nachalo strok
                array[i] = m * i - m + 1;

            array[1] = 1;

            int[] myarray = new int[kstrok + 1];
            for (int i = 1; i < kstrok + 1; i++) //massiv zapominaet konez strok
                myarray[i] = m * i;

            int strokaa = 1;
            int strokab = 1;

            for (int i = 1; i < kstrok + 1; i++)
                if (a > myarray[i])
                    strokaa = strokaa + 1; //наход строки а

            for (int i = 1; i < kstrok + 1; i++)
                if (b > myarray[i])//наход строки б
                    strokab = strokab + 1;

            int proverkaa1 = 0;
            int proverkab1 = 0;

            for (int i = 1; i < kstrok; i++)
                if (a == array[i]) //esli a v nachale stroki
                    proverkaa1 = proverkaa1 + 1;

            for (int i = 1; i < kstrok; i++)
                if (b == myarray[i])// esli b v konze stroki
                    proverkab1 = proverkab1 + 1;

            if (proverkaa1 + proverkab1 == 2)
                Console.WriteLine(1);

            int o = 0;
                if (strokaa == strokab && proverkaa1 + proverkab1 != 2)
                {
                    Console.WriteLine(1); // esli v odnoi stroke a i b
                    o = 1;
                }

            int proverkaa2 = 0; //Нашлась ли а не по кроям строки?
            int proverkab2 = 0; //Нашлась ли б не по кроям строки?

            for (int i = 1; i < kstrok + 1; i++)
                if (a > array[i] && a <= myarray[i])
                    proverkaa2 = proverkaa2 + 1; //Нашлась ли а не по кроям строки?

            for (int i = 1; i < kstrok + 1; i++)
                if (b >= array[i] && b < myarray[i])
                    proverkab2 = proverkab2 + 1; //Нашлась ли а не по кроям строки?
            int q = 0;
            if (o == 0)
            {
                if (proverkaa2 + proverkab2 == 2 && strokaa + 1 < strokab)
                    if ((a - 1) % m == b % m)
                    {
                        Console.WriteLine(2);
                        q = 1;
                    }

                if (proverkaa2 + proverkab2 == 2 && strokaa + 1 < strokab)
                    if (b != n && q != 1)
                    Console.WriteLine(3); //если а и б находятся не по краям и расстояние > m
                    else if (q != 1)
                    Console.WriteLine(2);

                if (proverkaa2 + proverkab2 == 2 && strokaa + 1 == strokab)
                    Console.WriteLine(2); //если а и б находятся не по краям и расстояние <= m

                if (proverkaa1 + proverkab2 == 2)
                    if (b != n)
                    Console.WriteLine(2); //если а с краю, а б нет
                    else Console.WriteLine(1);

                if (proverkaa2 + proverkab1 == 2)
                Console.WriteLine(2); //если б с краю, а а неt
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using static Template;
using static System.Console;
using static System.Convert;
using static System.Math;
using Pi = Pair<int, int>;

class Solver
{
    int N;const int MOD = (int)1e9 + 7;
    string S;
    int[][] dp;
    public void Solve(Scanner sc)
    {
        N = sc.Int;S = ReadLine();
        dp = Create(N, () => Create(1<<20,()=>-1));
        int res = 0;
        for (var i = 0; i < N; i++)
        { res += memo(0, i); if (res >= MOD) res -= MOD; }
        WriteLine(res);
    }
    int memo(int s,int i)
    {
        var ct = 0;
        for (var j = 0; j < 20; j++)
            ct += 1 & s >> j;
        if (i == N)
            return ToInt32(ct != 0 && (1 << ct) - 1 == s);
        if (dp[i][s] != -1) return dp[i][s];
        int res = 0;
        if (S[i] == '0') return dp[i][s] = memo(s, i + 1);
        var c = 0;
        for (var j = i; j < N; j++)
        {
            c <<= 1;c += S[j] - '0';
            if (c > 20) break;
            res += memo(s | (1 << (c - 1)), j + 1);
            if (res >= MOD) res -= MOD;
        }
        if (ct != 0 && (1 << ct)-1 == s) res++;
        if (res >= MOD) res -= MOD;
        return dp[i][s] = res;
    }
}

#region Template
public static class Template
{
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        new Solver().Solve(new Scanner());
        Console.Out.Flush();
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T>
    { if (a.CompareTo(b) == 1) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T>
    { if (a.CompareTo(b) == -1) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b)
    { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static T[] Create<T>(int n, Func<T> f)
    {
        var rt = new T[n];
        for (var i = 0; i < rt.Length; ++i)
            rt[i] = f();
        return rt;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static T[] Create<T>(int n, Func<int, T> f)
    {
        var rt = new T[n];
        for (var i = 0; i < rt.Length; ++i)
            rt[i] = f(i);
        return rt;
    }
    public static T[] Copy<T>(this T[] A) => Create(A.Length, i => A[i]);
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}

public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    public Pair<T1, T2> PairMake<T1, T2>() => new Pair<T1, T2>(Next<T1>(), Next<T2>());
    public Pair<T1, T2, T3> PairMake<T1, T2, T3>() => new Pair<T1, T2, T3>(Next<T1>(), Next<T2>(), Next<T3>());
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
}

public class Pair<T1, T2> : IComparable<Pair<T1, T2>>
{
    public T1 v1;
    public T2 v2;
    public Pair() { }
    public Pair(T1 v1, T2 v2)
    { this.v1 = v1; this.v2 = v2; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2> p)
    {
        var c = Comparer<T1>.Default.Compare(v1, p.v1);
        if (c == 0)
            c = Comparer<T2>.Default.Compare(v2, p.v2);
        return c;
    }
    public override string ToString() => $"{v1.ToString()} {v2.ToString()}";
    public void Tie(out T1 a, out T2 b) { a = v1; b = v2; }
}

public class Pair<T1, T2, T3> : Pair<T1, T2>, IComparable<Pair<T1, T2, T3>>
{
    public T3 v3;
    public Pair() : base() { }
    public Pair(T1 v1, T2 v2, T3 v3) : base(v1, v2)
    { this.v3 = v3; }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public int CompareTo(Pair<T1, T2, T3> p)
    {
        var c = base.CompareTo(p);
        if (c == 0)
            c = Comparer<T3>.Default.Compare(v3, p.v3);
        return c;
    }
    public override string ToString() => $"{base.ToString()} {v3.ToString()}";
    public void Tie(out T1 a, out T2 b, out T3 c) { Tie(out a, out b); c = v3; }
}
#endregion


using System;

namespace Task_D
{
    class Solution
    {
        static void Main(string[] args)
        {
            new Solution().Solve();
        }

        private int n;
        private int d;
        private long x;
        private int[] a;
        private int[] b;
        private int[] c;

        private void Solve()
        {
            var parts = Console.ReadLine().Split();
            n = int.Parse(parts[0]);
            d = int.Parse(parts[1]);
            x = long.Parse(parts[2]);

            a = new int[n];
            b = new int[n];
            c = new int[n];

            initAB();

            var bCount = 0;
            var bPos = new int[n];
            for (int i = 0; i < n; i++)
            {
                if (b[i] == 1)
                {
                    bPos[bCount++] = i;
                }
            }

            var aOrder = new int[n];
            for (int i = 0; i < n; i++)
            {
                aOrder[a[i] - 1] = i;
            }

            int s = 50;

            for (int i = 0; i < n; i++)
            {
                for (int q = 0; q < s && q < n; q++)
                {
                    int j = aOrder[n - q - 1];
                    if (i - j >= 0 && b[i - j] == 1)
                    {
                        c[i] = a[j];
                        break;
                    }
                }

                if (c[i] != 0)
                {
                    continue;
                }

                for (int z = 0; z < bCount; z++)
                {
                    var bIndex = bPos[z];
                    var j = i - bIndex;
                    if (j >= 0)
                    {
                        c[i] = Math.Max(c[i], a[j]);
                    }
                }
            }

            for (int i = 0; i < n; i++)
            {
                Console.WriteLine(c[i]);
            }
        }

        private long getNextX()
        {
            x = (x * 37 + 10007) % 1000000007;
            return x;
        }

        private void initAB()
        {
            for (int i = 0; i < n; i = i + 1)
            {
                a[i] = i + 1;
            }

            for (int i = 0; i < n; i = i + 1)
            {
                swap(ref a[i], ref a[getNextX() % (i + 1)]);
            }

            for (int i = 0; i < n; i = i + 1)
            {
                if (i < d)
                    b[i] = 1;
                else
                    b[i] = 0;
            }

            for (int i = 0; i < n; i = i + 1)
            {
                swap(ref b[i], ref b[getNextX() % (i + 1)]);
            }
        }

        private void swap<T>(ref T first, ref T second)
        {
            T tmp = first;
            first = second;
            second = tmp;
        }
    }
}


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

namespace Codeforces
{
    internal class Program
    {
        private static void Main()
        {
            if (Debugger.IsAttached)
            {
                Console.SetIn(new StreamReader(@"..\..\..\..\Tests\D7.in"));
            }

            Solve();

            if (Debugger.IsAttached)
            {
                Console.In.Close();
                Console.SetIn(new StreamReader(Console.OpenStandardInput()));
                Console.ReadLine();
            }
        }

        private static void Solve()
        {
            var s = Read();
            var intF = new int[10];
            var intS = new int[10];
            foreach (var n in s)
            {
                intF[n - '0']++;
                intS[n - '0']++;
            }

            var max = 0;
            var maxIndex = -1;
            for (int i = 1; i < 10; i++)
            {
                var res = 0;
                var j = 10 - i;
                if(intF[i] > 0 && intS[j] > 0)
                {
                    intF[i]--;
                    intS[j]--;
                    res++;
                    for (int k = 0; k < 10; k++)
                    {
                        res += Math.Min(intF[k], intS[9 - k]);
                    }
                    intF[i]++;
                    intS[j]++;
                }
                if(max < res)
                {
                    max = res;
                    maxIndex = i;
                }
            }
            var resF = new StringBuilder();
            var resS = new StringBuilder();
            if (maxIndex != -1)
            {
                intF[maxIndex]--;
                intS[(10 - maxIndex)%10]--;
                resF.Append(maxIndex);
                resS.Append((10 - maxIndex)%10);
            }
            for (int i = 0; i < 10; i++)
            {
                var count = Math.Min(intF[i], intS[9 - i]);
                resF.Append(i.ToString()[0], count);
                resS.Append((9-i).ToString()[0], count);
                intF[i] -= count;
                intS[9 - i] -= count;
            }
            var countZero = Math.Min(intF[0], intS[0]);
            resF.Insert(0, "0", countZero);
            resS.Insert(0, "0", countZero);
            intF[0] -= countZero;
            intS[0] -= countZero;
            for (int i = 0; i < 10; i++)
            {
                resF.Append(i.ToString()[0], intF[i]);
                resS.Append(i.ToString()[0], intS[i]);
            }

            Console.WriteLine(new string(resF.ToString().Reverse().ToArray()));
            Console.WriteLine(new string(resS.ToString().Reverse().ToArray()));
        }

        #region Reader

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

        private static string[] ReadArray()
        {
            return Console.ReadLine().Split(' ');
        }

        private static int[] ReadIntArray()
        {
            var input = Console.ReadLine().Split(' ').Select(Int32.Parse).ToArray();
            return input;
        }

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

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

        private static int ReadNextInt(string[] input, int index)
        {
            return Int32.Parse(input[index]);
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

class Solver
{
    public void Solve()
    {
        //  count
        var cs = new int[10];
        var s = CF.ReadLine();
        foreach (var c in s)
        {
            int n = c-'0';
            cs[n]++;
        }

        //
        int max = -1;
        int[] best1 = new int[10];
        Array.Copy(cs, best1, 10);
        int[] best2 = new int[10];
        Array.Copy(cs, best2, 10);
        string max_n1 = "";
        string max_n2 = "";

        for (int a = 1; a <= 9; a++)
        {
            string n1 = "";
            string n2 = "";

            int b = 10 - a;

            int zc = 0;
            int[] tmp1 = new int[10];
            int[] tmp2 = new int[10];
            Array.Copy(cs, tmp1, 10);
            Array.Copy(cs, tmp2, 10);

            tmp1[a]--;
            if (tmp1[a] < 0)
                continue;
            tmp2[b]--;
            if (tmp2[b] < 0)
                continue;

            n1 += a;
            n2 += b;

            //  c+d=9
            for (int c = 0; c <= 9; c++)
            {
                int d = 9 - c;

                int p = Math.Min(tmp1[c],tmp2[d]);

                tmp1[c] -= p;
                tmp2[d] -= p;

                zc += p;

                n1 = new string((char)('0'+c),p)+n1;
                n2 = new string((char)('0' + d), p) + n2;
            }

            if (zc > max)
            {
                max = zc;
                best1 = tmp1;
                best2 = tmp2;
                max_n1 = n1;
                max_n2 = n2;
            }
        }

        //  0+0=0
        int z = Math.Min(best1[0],best2[0]);
        max_n1 += new string('0', z);
        max_n2 += new string('0', z);
        best2[0] -=z;
        best1[0] -=z;

        for (int i = 0; i <= 9; i++)
        {
            max_n1 = new string((char)('0'+i), best1[i])+max_n1;
            max_n2 = new string((char)('0'+i), best2[i])+max_n2;
        }
        CF.WriteLine(max_n1);
        CF.WriteLine(max_n2);
    }

    //  test
    static Utils CF = new Utils(new[]{
@"
1099
"
,
@"
198
"
,
@"
500
"
,
@"
0
"
,
@"
1
"
 ,
@"
10
"

    });
    #region test

    static void Main(string[] args)
    {
#if DEBUG
        for (int t=0;t<CF.TestCount;t++ )
        {
            CF.Test(t);
			var sw = new Stopwatch();
			sw.Start();
            new Solver().Solve();
			Debug.WriteLine("time: "+sw.ElapsedMilliseconds+ " ms");
		}
#else
        new Solver().Solve();
#endif
    }

    class Utils
    {
        public void Test(int t)
        {
            _lines = new List<string>();
            string[] ss = _test_input[t].Replace("\n", "").Split('\r');
            for (int i = 0; i < ss.Length; i++)
            {
                if (
                    (i == 0 || i == ss.Length - 1) &&
                    ss[i].Length == 0
                    )
                    continue;

                _lines.Add(ss[i]);
            }
        }

        public int TestCount
        {
            get
            {
                return _test_input.Length;
            }
        }

        public string ReadLine()
        {
#if DEBUG
            string s = null;
            if (_lines.Count > 0)
            {
                s = _lines[0];
                _lines.RemoveAt(0);
            }
            return s;

#else
            //return _sr.ReadLine();
        return Console.In.ReadLine();
#endif
        }

        public void WriteLine(object o)
        {
#if DEBUG
            System.Diagnostics.Trace.WriteLine(o);
#else
            //_sw.WriteLine(o);
        Console.WriteLine(o);
#endif
        }

        public void Write(object o)
        {
#if DEBUG
            System.Diagnostics.Trace.Write(o);
#else
                //_sw.Write(o);
        Console.Write(o);
#endif
        }

        string[] _test_input;

        List<string> _lines;

#if DEBUG
        public Utils(string[] test_input)
        {
            _test_input = test_input;
        }
#else

        public Utils(string[] dummy)
        {
            //_sr = new System.IO.StreamReader("input.txt");
            //_sw = new System.IO.StreamWriter("output.txt");
        }
#endif

    }

    #endregion
}


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

namespace International_Olympiad
{
    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)
        {
            int n = int.Parse(reader.ReadLine());

            for (int i = 0; i < n; i++)
            {
                string s = reader.ReadLine().Substring(4);
                long t = long.Parse(s);

                long pow = 10, f = 0;

                for (int k = 1; k < s.Length; k++)
                {
                    f += pow;
                    pow *= 10;
                }

                while (t < 1989 + f)
                {
                    t += pow;
                }

                writer.WriteLine(t);
            }

            writer.Flush();
        }
    }
}


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

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    long Tot(long n)
    {
        long ret = n;
        for (long i = 2; i * i <= n; i++)
            if (n % i == 0)
            {
                ret = ret / i * (i - 1);
                while (n % i == 0)
                {
                    n /= i;
                }
            }
        if (n > 1)
            ret = ret / n * (n - 1);
        return ret;
    }

    public void Solve()
    {
        long n = ReadLong();
        long m = ReadLong();

        int c = 1;
        while (c < 1000 && m > 1)
        {
            if (m % 2 > 0)
                c++;
            m--;
        }

        while (n > 1 && c > 0)
        {
            n = Tot(n);
            c--;
        }
        Write(n % 1000000007);
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;
    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        //reader = new StreamReader(Console.OpenStandardInput());
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
        //reader = new StreamReader("input.txt");
        //writer = new StreamWriter("output.txt");
#endif
        try
        {
            new Solver().Solve();
            //var thread = new Thread(new Solver().Solve, 1024 * 1024 * 256);
            //thread.Start();
            //thread.Join();
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write
    private static Queue<string> currentLineTokens = new Queue<string>();
    private static string[] ReadAndSplitLine() { return reader.ReadLine().Split(new[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); }
    public static string ReadToken() { while (currentLineTokens.Count == 0)currentLineTokens = new Queue<string>(ReadAndSplitLine()); return currentLineTokens.Dequeue(); }
    public static int ReadInt() { return int.Parse(ReadToken()); }
    public static long ReadLong() { return long.Parse(ReadToken()); }
    public static double ReadDouble() { return double.Parse(ReadToken(), CultureInfo.InvariantCulture); }
    public static int[] ReadIntArray() { return ReadAndSplitLine().Select(int.Parse).ToArray(); }
    public static long[] ReadLongArray() { return ReadAndSplitLine().Select(long.Parse).ToArray(); }
    public static double[] ReadDoubleArray() { return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray(); }
    public static int[][] ReadIntMatrix(int numberOfRows) { int[][] matrix = new int[numberOfRows][]; for (int i = 0; i < numberOfRows; i++)matrix[i] = ReadIntArray(); return matrix; }
    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows); int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++) { ret[i] = new int[numberOfRows]; for (int j = 0; j < numberOfRows; j++)ret[i][j] = matrix[j][i]; } return ret;
    }
    public static string[] ReadLines(int quantity) { string[] lines = new string[quantity]; for (int i = 0; i < quantity; i++)lines[i] = reader.ReadLine().Trim(); return lines; }
    public static void WriteArray<T>(IEnumerable<T> array) { writer.WriteLine(string.Join(" ", array)); }
    public static void Write(params object[] array) { WriteArray(array); }
    public static void WriteLines<T>(IEnumerable<T> array) { foreach (var a in array)writer.WriteLine(a); }
    private class SDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        public new TValue this[TKey key]
        {
            get { return ContainsKey(key) ? base[key] : default(TValue); }
            set { base[key] = value; }
        }
    }
    private static T[] Init<T>(int size) where T : new() { var ret = new T[size]; for (int i = 0; i < size; i++)ret[i] = new T(); return ret; }
    #endregion
}


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

using Binary = System.Func<System.Linq.Expressions.ParameterExpression, System.Linq.Expressions.ParameterExpression, System.Linq.Expressions.BinaryExpression>;
using Unary = System.Func<System.Linq.Expressions.ParameterExpression, System.Linq.Expressions.UnaryExpression>;

class Program
{
    static StreamWriter sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
    static Scan sc = new Scan();
//    static Scan sc = new ScanCHK();
    const int M = 1000000007;
    const double eps = 1e-9;
    static readonly int[] dd = { 0, 1, 0, -1, 0 };
    static SortedDictionary<long, long> memo;
    static void Main()
    {
        long n, k;
        sc.Multi(out n, out k);
        k = (k + 1) / 2;
        memo = new SortedDictionary<long, long>();

        Prt(calc(n, k) % M);
        sw.Flush();
    }
    static long f(long n)
    {
        if (n < 3) return 1;
        if (memo.ContainsKey(n))
            return memo[n];

        long ret = n - 1;
        for (long i = 2; i * i <= n; i++)
        {
            if (n % i == 0)
            {
                ret -= f(i);
                if (i != n / i)
                {
                    ret -= f(n / i);
                }
            }
        }
        memo.Add(n, ret);
        return ret;
    }
    static long calc(long n, long k)
    {
        if (n == 1) return 1;
        if (k == 0) return n;

        long nn = n - 1;
        for (long i = 2; i * i <= n; i++)
        {
            if (n % i == 0)
            {
                nn -= f(i);
                if (i != n / i)
                {
                    nn -= f(n / i);
                }
            }
        }
        return calc(nn, k - 1);
    }

    static void swap<T>(ref T a, ref T b) { var t = a; a = b; b = t; }
    static T Max<T>(params T[] a) { return a.Max(); }
    static T Min<T>(params T[] a) { return a.Min(); }
    static void DBG(string a) { Console.WriteLine(a); }
    static void DBG<T>(IEnumerable<T> a) { Console.WriteLine(string.Join(" ", a)); }
    static void DBG(params object[] a) { Console.WriteLine(string.Join(" ", a)); }
    static void Prt(string a) { sw.WriteLine(a); }
    static void Prt<T>(IEnumerable<T> a) { sw.WriteLine(string.Join(" ", a)); }
    static void Prt(params object[] a) { sw.WriteLine(string.Join(" ", a)); }
}
static class ex
{
    public static void swap<T>(this IList<T> a, int i, int j) { var t = a[i]; a[i] = a[j]; a[j] = t; }
    public static T[] copy<T>(this IList<T> a)
    {
        var ret = new T[a.Count];
        for (int i = 0; i < a.Count; i++) ret[i] = a[i];
        return ret;
    }
}
static class Operator<T>
{
    static readonly ParameterExpression x = Expression.Parameter(typeof(T), "x");
    static readonly ParameterExpression y = Expression.Parameter(typeof(T), "y");
    public static readonly Func<T, T, T> Add = Lambda(Expression.Add);
    public static readonly Func<T, T, T> Subtract = Lambda(Expression.Subtract);
    public static readonly Func<T, T, T> Multiply = Lambda(Expression.Multiply);
    public static readonly Func<T, T, T> Divide = Lambda(Expression.Divide);
    public static readonly Func<T, T> Plus = Lambda(Expression.UnaryPlus);
    public static readonly Func<T, T> Negate = Lambda(Expression.Negate);
    public static Func<T, T, T> Lambda(Binary op) { return Expression.Lambda<Func<T, T, T>>(op(x, y), x, y).Compile(); }
    public static Func<T, T> Lambda(Unary op) { return Expression.Lambda<Func<T, T>>(op(x), x).Compile(); }
}

class ScanCHK : Scan
{
    public new string Str { get { var s = Console.ReadLine(); if (s != s.Trim()) throw new Exception(); return s; } }
}
class Scan
{
    public int Int { get { return int.Parse(Str); } }
    public long Long { get { return long.Parse(Str); } }
    public double Double { get { return double.Parse(Str); } }
    public string Str { get { return Console.ReadLine().Trim(); } }
    public int[] IntArr { get { return StrArr.Select(int.Parse).ToArray(); } }
    public long[] LongArr { get { return StrArr.Select(long.Parse).ToArray(); } }
    public double[] DoubleArr { get { return StrArr.Select(double.Parse).ToArray(); } }
    public string[] StrArr { get { return Str.Split(); } }
    bool eq<T, U>() { return typeof(T).Equals(typeof(U)); }
    T ct<T, U>(U a) { return (T)Convert.ChangeType(a, typeof(T)); }
    T cv<T>(string s) { return eq<T, int>()    ? ct<T, int>(int.Parse(s))
                             : eq<T, long>()   ? ct<T, long>(long.Parse(s))
                             : eq<T, double>() ? ct<T, double>(double.Parse(s))
                             : eq<T, char>()   ? ct<T, char>(s[0])
                                               : ct<T, string>(s); }
    public void Multi<T>(out T a) { a = cv<T>(Str); }
    public void Multi<T, U>(out T a, out U b)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); }
    public void Multi<T, U, V>(out T a, out U b, out V c)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); }
    public void Multi<T, U, V, W>(out T a, out U b, out V c, out W d)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); }
    public void Multi<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]); }
}
class mymath
{
    public static long Mod = 1000000007;
    public static bool isprime(long a)
    {
        if (a < 2) return false;
        for (long i = 2; i * i <= a; i++) if (a % i == 0) return false;
        return true;
    }
    public static bool[] sieve(int n)
    {
        var p = new bool[n + 1];
        for (int i = 2; i <= n; i++) p[i] = true;
        for (int i = 2; i * i <= n; i++) if (p[i]) for (int j = i * i; j <= n; j += i) p[j] = false;
        return p;
    }
    public static List<int> getprimes(int n)
    {
        var prs = new List<int>();
        var p = sieve(n);
        for (int i = 2; i <= n; i++) if (p[i]) prs.Add(i);
        return prs;
    }
    public static long[][] E(int n)
    {
        var ret = new long[n][];
        for (int i = 0; i < n; i++) { ret[i] = new long[n]; ret[i][i] = 1; }
        return ret;
    }
    public static long[][] pow(long[][] A, long n)
    {
        if (n == 0) return E(A.Length);
        var t = pow(A, n / 2);
        if ((n & 1) == 0) return mul(t, t);
        return mul(mul(t, t), A);
    }
    public static double dot(double[] x, double[] y)
    {
        int n = x.Length;
        double ret = 0;
        for (int i = 0; i < n; i++) ret += x[i] * y[i];
        return ret;
    }
    public static long dot(long[] x, long[] y)
    {
        int n = x.Length;
        long ret = 0;
        for (int i = 0; i < n; i++) ret = (ret + x[i] * y[i]) % Mod;
        return ret;
    }
    public static T[][] trans<T>(T[][] A)
    {
        int n = A[0].Length, m = A.Length;
        var ret = new T[n][];
        for (int i = 0; i < n; i++) { ret[i] = new T[m]; for (int j = 0; j < m; j++) ret[i][j] = A[j][i]; }
        return ret;
    }
    public static double[] mul(double[][] A, double[] x)
    {
        int n = A.Length;
        var ret = new double[n];
        for (int i = 0; i < n; i++) ret[i] = dot(x, A[i]);
        return ret;
    }
    public static long[] mul(long[][] A, long[] x)
    {
        int n = A.Length;
        var ret = new long[n];
        for (int i = 0; i < n; i++) ret[i] = dot(x, A[i]);
        return ret;
    }
    public static long[][] mul(long[][] A, long[][] B)
    {
        int n = A.Length;
        var Bt = trans(B);
        var ret = new long[n][];
        for (int i = 0; i < n; i++) ret[i] = mul(Bt, A[i]);
        return ret;
    }
    public static long[] add(long[] x, long[] y)
    {
        int n = x.Length;
        var ret = new long[n];
        for (int i = 0; i < n; i++) ret[i] = (x[i] + y[i]) % Mod;
        return ret;
    }
    public static long[][] add(long[][] A, long[][] B)
    {
        int n = A.Length;
        var ret = new long[n][];
        for (int i = 0; i < n; i++) ret[i] = add(A[i], B[i]);
        return ret;
    }
    public static long pow(long a, long b)
    {
        if (a >= Mod) return pow(a % Mod, b);
        if (a == 0) return 0;
        if (b == 0) return 1;
        var t = pow(a, b / 2);
        if ((b & 1) == 0) return t * t % Mod;
        return t * t % Mod * a % Mod;
    }
    public static long inv(long a) { return pow(a, Mod - 2); }
    public static long gcd(long a, long b)
    {
        while (b > 0) { var t = a % b; a = b; b = t; }
        return a;
    }
    // a x + b y = gcd(a, b)
    public static long extgcd(long a, long b, out long x, out long y)
    {
        long g = a; x = 1; y = 0;
        if (b > 0) { g = extgcd(b, a % b, out y, out x); y -= a / b * x; }
        return g;
    }
    public static long lcm(long a, long b) { return a / gcd(a, b) * b; }
    public static long comb(int n, int r)
    {
        if (n < 0 || r < 0 || r > n) return 0;
        if (n - r < r) r = n - r;
        if (r == 0) return 1;
        if (r == 1) return n;
        int[] numer = new int[r], denom = new int[r];
        for (int k = 0; k < r; k++) { numer[k] = n - r + k + 1; denom[k] = k + 1; }
        for (int p = 2; p <= r; p++)
        {
            int piv = denom[p - 1];
            if (piv > 1)
            {
                int ofst = (n - r) % p;
                for (int k = p - 1; k < r; k += p) { numer[k - ofst] /= piv; denom[k] /= piv; }
            }
        }
        long ret = 1;
        for (int k = 0; k < r; k++) if (numer[k] > 1) ret = ret * numer[k] % Mod;
        return ret;
    }
}