#region Usings
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using static System.Array;
using static System.Math;

// ReSharper disable InconsistentNaming
#pragma warning disable CS0675
#endregion

partial class Solution
{
	#region Variables
	const int MOD = 1000000007;
	const int FactCache = 1000;
	const long BIG = long.MaxValue >> 15;

	#endregion

	public static void Main()
	{
		var input = new StreamReader(Console.OpenStandardInput());
		var output = new StreamWriter(Console.OpenStandardOutput());

		long[] array = ConvertAll(input.ReadLine().Split(), long.Parse);
		long n = array[0];
		long k = array[1];

		var y = new List<long>();
		long sum = 0;
		y.Add(sum);
		for (int i = 0; i <= k; i++)
		{
			sum = (sum + ModPow(i + 1, k));
			if (sum >= MOD) sum -= MOD;
			y.Add(sum);
		}

		if (n < y.Count)
			output.WriteLine(y[(int)n]);
		else
			output.WriteLine(Lagrange(y, n));
		output.Flush();
	}

	static long Lagrange(List<long> y, long x)
	{
		long ans = 0;
		long k = 1;
		for (int j = 1; j < y.Count; j++)
		{
			k = (k * (x - j)) % MOD;
			k = MOD - Div(k, j);
		}

		for (int i = 0; i < y.Count; i++)
		{
			ans = (ans + y[i] * k) % MOD;
			if (i + 1 >= y.Count) break;
			k = k * Div(x - i, x - (i + 1)) % MOD * Div(i - y.Count + 1, i + 1) % MOD;
		}

		return Fix(ans);
	}

	#region Library
	#region Mod Math

	static int[] _inverse;
	static long Inverse(long n)
	{
		long result;

		if (_inverse == null)
			_inverse = new int[1000];

		if (n >= 0 && n < _inverse.Length && (result = _inverse[n]) != 0)
			return result - 1;

		result = InverseDirect((int)n);
		if (n >= 0 && n < _inverse.Length)
			_inverse[n] = (int)(result + 1);
		return result;
	}

	public static int InverseDirect(int a)
	{
		if (a < 0) return -InverseDirect(-a);
		int t = 0, r = MOD, t2 = 1, r2 = a;
		while (r2 != 0)
		{
			var q = r / r2;
			t -= q * t2;
			r -= q * r2;

			if (r != 0)
			{
				q = r2 / r;
				t2 -= q * t;
				r2 -= q * r;
			}
			else
			{
				r = r2;
				t = t2;
				break;
			}
		}
		return r <= 1 ? (t >= 0 ? t : t + MOD) : -1;
	}

	static long Mult(long left, long right) =>
		(left * right) % MOD;

	static long Div(long left, long divisor) =>
		left * Inverse(divisor) % MOD;

	static long Add(long x, long y) =>
		(x += y) >= MOD ? x - MOD : x;

	static long Subtract(long x, long y) => (x -= y) < 0 ? x + MOD : x;

	static long Fix(long n) => (n %= MOD) >= 0 ? n : n + MOD;

	static long ModPow(long n, long p, long mod = MOD)
	{
		long b = n;
		long result = 1;
		while (p != 0)
		{
			if ((p & 1) != 0)
				result = (result * b) % mod;
			p >>= 1;
			b = (b * b) % mod;
		}
		return result;
	}

	static List<long> _fact;

	static long Fact(int n)
	{
		if (_fact == null) _fact = new List<long>(FactCache) { 1 };
		for (int i = _fact.Count; i <= n; i++)
			_fact.Add(Mult(_fact[i - 1], i));
		return _fact[n];
	}

	static long[] _ifact = new long[0];
	static long InverseFact(int n)
	{
		long result;
		if (n < _ifact.Length && (result = _ifact[n]) != 0)
			return result;

		var inv = Inverse(Fact(n));
		if (n >= _ifact.Length) Resize(ref _ifact, _fact.Capacity);
		_ifact[n] = inv;
		return inv;
	}

	static long Fact(int n, int m)
	{
		var fact = Fact(n);
		if (m < n) fact = fact * InverseFact(n - m) % MOD;
		return fact;
	}

	static long Comb(int n, int k)
	{
		if (k <= 1) return k == 1 ? n : k == 0 ? 1 : 0;
		return Mult(Mult(Fact(n), InverseFact(k)), InverseFact(n - k));
	}

	public static long Combinations(long n, int k)
	{
		if (k <= 0) return k == 0 ? 1 : 0;  // Note: n<0 -> 0 unless k=0
		if (k + k > n) return Combinations(n, (int)(n - k));

		var result = InverseFact(k);
		for (long i = n - k + 1; i <= n; i++) result = result * i % MOD;
		return result;
	}
	#endregion

	#region Common

	public static int Gcd(int n, int m)
	{
		while (true)
		{
			if (m == 0) return n >= 0 ? n : -n;
			n %= m;
			if (n == 0) return m >= 0 ? m : -m;
			m %= n;
		}
	}

	#endregion

	#region Main

	#endregion
	#endregion
}


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

class Solver
{
    public void Solve(Scanner sc)
    {
        int N, K;
        sc.Make(out N, out K);
        var F = new ModInt[K + 2];
        for (int i = 1; i < K + 2; i++)
        {
            F[i] = ModInt.Pow(i, K) + F[i - 1];
        }
        if (N <= K + 1) Fail(F[N]);
        ModInt res=0,f = 1;
        for (var i = 0; i < K + 2; i++) f *= N - i;
        ModInt p = 1;
        for (var i = 1; i < K + 2; i++)
            p *= -i;
        for (int i = 1; i < K + 2; i++)
        {
            p *= i;
            p /= (-(K + 1 - i + 1));
            res += F[i] / p * f / (N - i);
        }
        WriteLine(res);
    }
}

public struct ModInt
{
    public const long MOD = (int)1e9 + 7;
    //public const long MOD = 998244353;
    public long Value { get; set; }
    public ModInt(long n = 0) { Value = n; }
    private static ModInt[] fac;//i!
    private static ModInt[] inv;//1/i
    private static ModInt[] facinv;//1/(i!)
    public override string ToString() => Value.ToString();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator +(ModInt l, ModInt r)
    {
        l.Value += r.Value;
        if (l.Value >= MOD) l.Value -= MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator -(ModInt l, ModInt r)
    {
        l.Value -= r.Value;
        if (l.Value < 0) l.Value += MOD;
        return l;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator *(ModInt l, ModInt r) => new ModInt(l.Value * r.Value % MOD);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt operator /(ModInt l, ModInt r) => l * Pow(r, MOD - 2);
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator long(ModInt l) => l.Value;
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static implicit operator ModInt(long n)
    {
        n %= MOD; if (n < 0) n += MOD;
        return new ModInt(n);
    }

    public static ModInt Pow(ModInt m, long n)
    {
        if (n == 0) return 1;
        if (n % 2 == 0) return Pow(m * m, n >> 1);
        else return Pow(m * m, n >> 1) * m;
    }

    public static void Build(int n)
    {
        fac = new ModInt[n + 1];
        facinv = new ModInt[n + 1];
        inv = new ModInt[n + 1];
        inv[1] = 1;
        fac[0] = fac[1] = 1;
        facinv[0] = facinv[1] = 1;
        for (var i = 2; i <= n; i++)
        {
            fac[i] = fac[i - 1] * i;
            inv[i] = MOD - inv[MOD % i] * (MOD / i);
            facinv[i] = facinv[i - 1] * inv[i];
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Fac(ModInt n) => fac[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Inv(ModInt n) => inv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt FacInv(ModInt n) => facinv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Comb(ModInt n, ModInt r)
    {
        if (n < r) return 0;
        if (n == r) return 1;
        var calc = fac[n];
        calc = calc * facinv[r];
        calc = calc * facinv[n - r];
        return calc;
    }
}
#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 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[] 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; }
    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 IEnumerable<T> Shuffle<T>(this IEnumerable<T> A) => A.OrderBy(v => Guid.NewGuid());
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static int MaxElement<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static T PopBack<T>(this List<T> A) { var v = A[A.Count - 1]; A.RemoveAt(A.Count - 1); return v; }
    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);
    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 (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    //public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    //public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}
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 Deconstruct(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 Deconstruct(out T1 a, out T2 b, out T3 c) { Deconstruct(out a, out b); c = v3; }
}
#endregion


#region Usings
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using static System.Array;
using static System.Math;

// ReSharper disable InconsistentNaming
#pragma warning disable CS0675
#endregion

partial class Solution
{
	#region Variables
	const int MOD = 1000000007;
	const int FactCache = 1000;
	const long BIG = long.MaxValue >> 15;

	#endregion

	public void Solve()
	{
		long n = Ni();
		long k = Ni();

		var y = new List<long>();
		long sum = 0;
		y.Add(sum);
		for (int i = 0; i <= k; i++)
		{
			sum = (sum + ModPow(i + 1, k));
			if (sum >= MOD) sum -= MOD;
			y.Add(sum);
		}

		if (n < y.Count)
			WriteLine(y[(int)n]);
		else
			WriteLine(Lagrange(y, n));
	}

	long Lagrange(List<long> y, long x)
	{
		long ans = 0;
		long k = 1;
		for (int j = 1; j < y.Count; j++)
		{
			k = (k * (x - j)) % MOD;
			k = MOD - Div(k, j);
		}

		for (int i = 0; i < y.Count; i++)
		{
			ans = (ans + y[i] * k) % MOD;
			if (i + 1 >= y.Count) break;
			k = k * Div(x - i, x - (i + 1)) % MOD * Div(i - y.Count + 1, i + 1) % MOD;
		}

		return Fix(ans);
	}

	#region Library
	#region Mod Math

	static int[] _inverse;
	static long Inverse(long n)
	{
		long result;

		if (_inverse == null)
			_inverse = new int[1000];

		if (n >= 0 && n < _inverse.Length && (result = _inverse[n]) != 0)
			return result - 1;

		result = InverseDirect((int)n);
		if (n >= 0 && n < _inverse.Length)
			_inverse[n] = (int)(result + 1);
		return result;
	}

	public static int InverseDirect(int a)
	{
		if (a < 0) return -InverseDirect(-a);
		int t = 0, r = MOD, t2 = 1, r2 = a;
		while (r2 != 0)
		{
			var q = r / r2;
			t -= q * t2;
			r -= q * r2;

			if (r != 0)
			{
				q = r2 / r;
				t2 -= q * t;
				r2 -= q * r;
			}
			else
			{
				r = r2;
				t = t2;
				break;
			}
		}
		return r <= 1 ? (t >= 0 ? t : t + MOD) : -1;
	}

	static long Mult(long left, long right) =>
		(left * right) % MOD;

	static long Div(long left, long divisor) =>
		left * Inverse(divisor) % MOD;

	static long Add(long x, long y) =>
		(x += y) >= MOD ? x - MOD : x;

	static long Subtract(long x, long y) => (x -= y) < 0 ? x + MOD : x;

	static long Fix(long n) => (n %= MOD) >= 0 ? n : n + MOD;

	static long ModPow(long n, long p, long mod = MOD)
	{
		long b = n;
		long result = 1;
		while (p != 0)
		{
			if ((p & 1) != 0)
				result = (result * b) % mod;
			p >>= 1;
			b = (b * b) % mod;
		}
		return result;
	}

	static List<long> _fact;

	static long Fact(int n)
	{
		if (_fact == null) _fact = new List<long>(FactCache) { 1 };
		for (int i = _fact.Count; i <= n; i++)
			_fact.Add(Mult(_fact[i - 1], i));
		return _fact[n];
	}

	static long[] _ifact = new long[0];
	static long InverseFact(int n)
	{
		long result;
		if (n < _ifact.Length && (result = _ifact[n]) != 0)
			return result;

		var inv = Inverse(Fact(n));
		if (n >= _ifact.Length) Resize(ref _ifact, _fact.Capacity);
		_ifact[n] = inv;
		return inv;
	}

	static long Fact(int n, int m)
	{
		var fact = Fact(n);
		if (m < n) fact = fact * InverseFact(n - m) % MOD;
		return fact;
	}

	static long Comb(int n, int k)
	{
		if (k <= 1) return k == 1 ? n : k == 0 ? 1 : 0;
		return Mult(Mult(Fact(n), InverseFact(k)), InverseFact(n - k));
	}

	public static long Combinations(long n, int k)
	{
		if (k <= 0) return k == 0 ? 1 : 0;  // Note: n<0 -> 0 unless k=0
		if (k + k > n) return Combinations(n, (int)(n - k));

		var result = InverseFact(k);
		for (long i = n - k + 1; i <= n; i++) result = result * i % MOD;
		return result;
	}
	#endregion

	#region Common

	public static int Gcd(int n, int m)
	{
		while (true)
		{
			if (m == 0) return n >= 0 ? n : -n;
			n %= m;
			if (n == 0) return m >= 0 ? m : -m;
			m %= n;
		}
	}

	#endregion

	#region Fast IO
	#region  Input
	static Stream inputStream;
	static int inputIndex, bytesRead;
	static byte[] inputBuffer;
	static StringBuilder builder;
	const int MonoBufferSize = 4096;
	const char EOL = (char)10, DASH = (char)45, ZERO = (char)48;

	static void InitInput(Stream input = null, int stringCapacity = 16)
	{
		builder = new StringBuilder(stringCapacity);
		inputStream = input ?? Console.OpenStandardInput();
		inputIndex = bytesRead = 0;
		inputBuffer = new byte[MonoBufferSize];
	}

	static void ReadMore()
	{
		if (bytesRead < 0) throw new FormatException();
		inputIndex = 0;
		bytesRead = inputStream.Read(inputBuffer, 0, inputBuffer.Length);
		if (bytesRead > 0) return;
		bytesRead = -1;
		inputBuffer[0] = (byte)EOL;
	}

	static int Read()
	{
		if (inputIndex >= bytesRead) ReadMore();
		return inputBuffer[inputIndex++];
	}

	static T[] Na<T>(int n, Func<T> func, int z = 0)
	{
		n += z;
		var list = new T[n];
		for (int i = z; i < n; i++) list[i] = func();
		return list;
	}

	static int[] Ni(int n, int z = 0) => Na(n, Ni, z);

	static long[] Nl(int n, int z = 0) => Na(n, Nl, z);

	static string[] Ns(int n, int z = 0) => Na(n, Ns, z);

	static int Ni() => checked((int)Nl());

	static long Nl()
	{
		var c = SkipSpaces();
		bool neg = c == DASH;
		if (neg) { c = Read(); }

		long number = c - ZERO;
		while (true)
		{
			var d = Read() - ZERO;
			if (unchecked((uint)d > 9)) break;
			number = number * 10 + d;
			if (number < 0) throw new FormatException();
		}
		return neg ? -number : number;
	}

	static char[] Nc(int n)
	{
		var list = new char[n];
		for (int i = 0, c = SkipSpaces(); i < n; i++, c = Read()) list[i] = (char)c;
		return list;
	}

	static string Ns()
	{
		var c = SkipSpaces();
		builder.Clear();
		while (true)
		{
			if (unchecked((uint)c - 33 >= (127 - 33))) break;
			builder.Append((char)c);
			c = Read();
		}
		return builder.ToString();
	}

	static int SkipSpaces()
	{
		int c;
		do c = Read(); while (unchecked((uint)c - 33 >= (127 - 33)));
		return c;
	}

	static List<int>[] NewGraph(int n, int m = 0, int off = 0)
	{
		n += 1 + off;
		var g = new List<int>[n];
		for (int i = 0; i < n; i++)
			g[i] = new List<int>();

		for (int i = 0; i < m; i++)
		{
			int u = Ni() + off, v = Ni() + off;
			g[u].Add(v);
			g[v].Add(u);
		}

		return g;
	}

	static string ReadLine()
	{
		builder.Clear();
		while (true)
		{
			int c = Read();
			if (c < 32) { if (c == 10 || c <= 0) break; continue; }
			builder.Append((char)c);
		}
		return builder.ToString();
	}
	#endregion

	#region Output
	static Stream outputStream;
	static byte[] outputBuffer;
	static int outputIndex;

	static void InitOutput(Stream output = null)
	{
		outputStream = output ?? Console.OpenStandardOutput();
		outputIndex = 0;
		outputBuffer = new byte[65535];
	}

	static void WriteLine(object obj = null)
	{
		Write(obj);
		Write(EOL);
	}

	static void WriteLine(long number)
	{
		Write(number);
		Write(EOL);
	}

	static void Write(long signedNumber)
	{
		ulong number = unchecked((ulong)signedNumber);
		if (signedNumber < 0)
		{
			Write(DASH);
			number = unchecked((ulong)(-signedNumber));
		}

		Reserve(20 + 1); // 20 digits + 1 extra for sign
		int left = outputIndex;
		do
		{
			outputBuffer[outputIndex++] = (byte)(ZERO + number % 10);
			number /= 10;
		}
		while (number > 0);

		int right = outputIndex - 1;
		while (left < right)
		{
			byte tmp = outputBuffer[left];
			outputBuffer[left++] = outputBuffer[right];
			outputBuffer[right--] = tmp;
		}
	}

	static void Write(object obj)
	{
		if (obj == null) return;

		var s = obj.ToString();
		Reserve(s.Length);
		for (int i = 0; i < s.Length; i++)
			outputBuffer[outputIndex++] = (byte)s[i];
	}

	static void Write(char c)
	{
		Reserve(1);
		outputBuffer[outputIndex++] = (byte)c;
	}

	static void Write(byte[] array, int count)
	{
		Reserve(count);
		Copy(array, 0, outputBuffer, outputIndex, count);
		outputIndex += count;
	}

	static void Reserve(int n)
	{
		if (outputIndex + n <= outputBuffer.Length)
			return;

		Dump();
		if (n > outputBuffer.Length)
			Resize(ref outputBuffer, Max(outputBuffer.Length * 2, n));
	}

	static void Dump()
	{
		outputStream.Write(outputBuffer, 0, outputIndex);
		outputIndex = 0;
	}

	static void Flush()
	{
		Dump();
		outputStream.Flush();
	}

	#endregion
	#endregion

	#region Main

	public static void Main()
	{
		InitInput(Console.OpenStandardInput());
		InitOutput(Console.OpenStandardOutput());

		new Solution().Solve();

		Flush();
		Console.Error.WriteLine(Process.GetCurrentProcess().TotalProcessorTime);
	}
	#endregion
	#endregion
}


#region Usings
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using static System.Array;
using static System.Math;

// ReSharper disable InconsistentNaming
#pragma warning disable CS0675
#endregion

partial class Solution
{
	#region Variables
	const int MOD = 1000000007;
	const int FactCache = 1000;
	const long BIG = long.MaxValue >> 15;

	#endregion

	public void Solve()
	{
		int n = Ni();
		int k = Ni();

		var y = new List<long>();
		long sum = 0;
		y.Add(sum);
		for (int i = 0; i <= k; i++)
		{
			sum = (sum + ModPow(i + 1, k));
			if (sum >= MOD) sum -= MOD;
			y.Add(sum);
		}

		if (n < y.Count)
			WriteLine(y[n]);
		else
			WriteLine(Lagrange(y, n));
	}

	long Lagrange(List<long> y, long x)
	{
		long ans = 0;
		long k = 1;
		for (int j = 1; j < y.Count; j++)
		{
			k = (k * (x - j)) % MOD;
			k = MOD - Div(k, j);
		}

		for (int i = 0; i < y.Count; i++)
		{
			ans = (ans + y[i] * k) % MOD;
			if (i + 1 >= y.Count) break;
			k = k * Div(x - i, x - (i + 1)) % MOD * Div(i - y.Count + 1, i + 1) % MOD;
		}

		return Fix(ans);
	}

	#region Library
	#region Mod Math

	static int[] _inverse;
	static long Inverse(long n)
	{
		long result;

		if (_inverse == null)
			_inverse = new int[1000];

		if (n >= 0 && n < _inverse.Length && (result = _inverse[n]) != 0)
			return result - 1;

		result = InverseDirect((int)n);
		if (n >= 0 && n < _inverse.Length)
			_inverse[n] = (int)(result + 1);
		return result;
	}

	public static int InverseDirect(int a)
	{
		if (a < 0) return -InverseDirect(-a);
		int t = 0, r = MOD, t2 = 1, r2 = a;
		while (r2 != 0)
		{
			var q = r / r2;
			t -= q * t2;
			r -= q * r2;

			if (r != 0)
			{
				q = r2 / r;
				t2 -= q * t;
				r2 -= q * r;
			}
			else
			{
				r = r2;
				t = t2;
				break;
			}
		}
		return r <= 1 ? (t >= 0 ? t : t + MOD) : -1;
	}

	static long Mult(long left, long right) =>
		(left * right) % MOD;

	static long Div(long left, long divisor) =>
		left * Inverse(divisor) % MOD;

	static long Add(long x, long y) =>
		(x += y) >= MOD ? x - MOD : x;

	static long Subtract(long x, long y) => (x -= y) < 0 ? x + MOD : x;

	static long Fix(long n) => (n %= MOD) >= 0 ? n : n + MOD;

	static long ModPow(long n, long p, long mod = MOD)
	{
		long b = n;
		long result = 1;
		while (p != 0)
		{
			if ((p & 1) != 0)
				result = (result * b) % mod;
			p >>= 1;
			b = (b * b) % mod;
		}
		return result;
	}

	static List<long> _fact;

	static long Fact(int n)
	{
		if (_fact == null) _fact = new List<long>(FactCache) { 1 };
		for (int i = _fact.Count; i <= n; i++)
			_fact.Add(Mult(_fact[i - 1], i));
		return _fact[n];
	}

	static long[] _ifact = new long[0];
	static long InverseFact(int n)
	{
		long result;
		if (n < _ifact.Length && (result = _ifact[n]) != 0)
			return result;

		var inv = Inverse(Fact(n));
		if (n >= _ifact.Length) Resize(ref _ifact, _fact.Capacity);
		_ifact[n] = inv;
		return inv;
	}

	static long Fact(int n, int m)
	{
		var fact = Fact(n);
		if (m < n) fact = fact * InverseFact(n - m) % MOD;
		return fact;
	}

	static long Comb(int n, int k)
	{
		if (k <= 1) return k == 1 ? n : k == 0 ? 1 : 0;
		return Mult(Mult(Fact(n), InverseFact(k)), InverseFact(n - k));
	}

	public static long Combinations(long n, int k)
	{
		if (k <= 0) return k == 0 ? 1 : 0;  // Note: n<0 -> 0 unless k=0
		if (k + k > n) return Combinations(n, (int)(n - k));

		var result = InverseFact(k);
		for (long i = n - k + 1; i <= n; i++) result = result * i % MOD;
		return result;
	}
	#endregion

	#region Common
	partial void TestData();

	static void Swap<T>(ref T a, ref T b)
	{
		var tmp = a;
		a = b;
		b = tmp;
	}

	static int Bound<T>(T[] array, T value, bool upper = false)
		where T : IComparable<T>
	{
		int left = 0;
		int right = array.Length - 1;

		while (left <= right)
		{
			int mid = left + (right - left >> 1);
			int cmp = value.CompareTo(array[mid]);
			if (cmp > 0 || cmp == 0 && upper)
				left = mid + 1;
			else
				right = mid - 1;
		}
		return left;
	}

	public static int Gcd(int n, int m)
	{
		while (true)
		{
			if (m == 0) return n >= 0 ? n : -n;
			n %= m;
			if (n == 0) return m >= 0 ? m : -m;
			m %= n;
		}
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static unsafe int Log2(long value)
	{
		double f = unchecked((ulong)value); // +.5 -> -1 for zero
		return (((int*)&f)[1] >> 20) - 1023;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static int BitCount(long y)
	{
		var x = unchecked((ulong)y);
		x -= (x >> 1) & 0x5555555555555555;
		x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
		x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f;
		return unchecked((int)((x * 0x0101010101010101) >> 56));
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static int HighestOneBit(int n) => n != 0 ? 1 << Log2(n) : 0;
	/*static unsafe int HighestOneBit(int x) // sometimes doesn't work
	{
		double f = unchecked((uint)x);
        return unchecked(1 << (((int*)&f)[1] >> 20) - 1023 & ~((x - 1 & -x - 1) >> 31));
	}*/

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	static unsafe long HighestOneBit(long x)
	{
		double f = unchecked((ulong)x);
		return unchecked(1L << (((int*)&f)[1] >> 20) - 1023 & ~(x - 1 >> 63 & -x - 1 >> 63));
	}
	#endregion

	#region Fast IO
	#region  Input
	static Stream inputStream;
	static int inputIndex, bytesRead;
	static byte[] inputBuffer;
	static StringBuilder builder;
	const int MonoBufferSize = 4096;
	const char EOL = (char)10, DASH = (char)45, ZERO = (char)48;

	static void InitInput(Stream input = null, int stringCapacity = 16)
	{
		builder = new StringBuilder(stringCapacity);
		inputStream = input ?? Console.OpenStandardInput();
		inputIndex = bytesRead = 0;
		inputBuffer = new byte[MonoBufferSize];
	}

	static void ReadMore()
	{
		if (bytesRead < 0) throw new FormatException();
		inputIndex = 0;
		bytesRead = inputStream.Read(inputBuffer, 0, inputBuffer.Length);
		if (bytesRead > 0) return;
		bytesRead = -1;
		inputBuffer[0] = (byte)EOL;
	}

	static int Read()
	{
		if (inputIndex >= bytesRead) ReadMore();
		return inputBuffer[inputIndex++];
	}

	static T[] Na<T>(int n, Func<T> func, int z = 0)
	{
		n += z;
		var list = new T[n];
		for (int i = z; i < n; i++) list[i] = func();
		return list;
	}

	static int[] Ni(int n, int z = 0) => Na(n, Ni, z);

	static long[] Nl(int n, int z = 0) => Na(n, Nl, z);

	static string[] Ns(int n, int z = 0) => Na(n, Ns, z);

	static int Ni() => checked((int)Nl());

	static long Nl()
	{
		var c = SkipSpaces();
		bool neg = c == DASH;
		if (neg) { c = Read(); }

		long number = c - ZERO;
		while (true)
		{
			var d = Read() - ZERO;
			if (unchecked((uint)d > 9)) break;
			number = number * 10 + d;
			if (number < 0) throw new FormatException();
		}
		return neg ? -number : number;
	}

	static char[] Nc(int n)
	{
		var list = new char[n];
		for (int i = 0, c = SkipSpaces(); i < n; i++, c = Read()) list[i] = (char)c;
		return list;
	}

	static string Ns()
	{
		var c = SkipSpaces();
		builder.Clear();
		while (true)
		{
			if (unchecked((uint)c - 33 >= (127 - 33))) break;
			builder.Append((char)c);
			c = Read();
		}
		return builder.ToString();
	}

	static int SkipSpaces()
	{
		int c;
		do c = Read(); while (unchecked((uint)c - 33 >= (127 - 33)));
		return c;
	}

	static List<int>[] NewGraph(int n, int m = 0, int off = 0)
	{
		n += 1 + off;
		var g = new List<int>[n];
		for (int i = 0; i < n; i++)
			g[i] = new List<int>();

		for (int i = 0; i < m; i++)
		{
			int u = Ni() + off, v = Ni() + off;
			g[u].Add(v);
			g[v].Add(u);
		}

		return g;
	}

	static string ReadLine()
	{
		builder.Clear();
		while (true)
		{
			int c = Read();
			if (c < 32) { if (c == 10 || c <= 0) break; continue; }
			builder.Append((char)c);
		}
		return builder.ToString();
	}
	#endregion

	#region Output
	static Stream outputStream;
	static byte[] outputBuffer;
	static int outputIndex;

	static void InitOutput(Stream output = null)
	{
		outputStream = output ?? Console.OpenStandardOutput();
		outputIndex = 0;
		outputBuffer = new byte[65535];
	}

	static void WriteLine(object obj = null)
	{
		Write(obj);
		Write(EOL);
	}

	static void WriteLine(long number)
	{
		Write(number);
		Write(EOL);
	}

	static void Write(long signedNumber)
	{
		ulong number = unchecked((ulong)signedNumber);
		if (signedNumber < 0)
		{
			Write(DASH);
			number = unchecked((ulong)(-signedNumber));
		}

		Reserve(20 + 1); // 20 digits + 1 extra for sign
		int left = outputIndex;
		do
		{
			outputBuffer[outputIndex++] = (byte)(ZERO + number % 10);
			number /= 10;
		}
		while (number > 0);

		int right = outputIndex - 1;
		while (left < right)
		{
			byte tmp = outputBuffer[left];
			outputBuffer[left++] = outputBuffer[right];
			outputBuffer[right--] = tmp;
		}
	}

	static void Write(object obj)
	{
		if (obj == null) return;

		var s = obj.ToString();
		Reserve(s.Length);
		for (int i = 0; i < s.Length; i++)
			outputBuffer[outputIndex++] = (byte)s[i];
	}

	static void Write(char c)
	{
		Reserve(1);
		outputBuffer[outputIndex++] = (byte)c;
	}

	static void Write(byte[] array, int count)
	{
		Reserve(count);
		Copy(array, 0, outputBuffer, outputIndex, count);
		outputIndex += count;
	}

	static void Reserve(int n)
	{
		if (outputIndex + n <= outputBuffer.Length)
			return;

		Dump();
		if (n > outputBuffer.Length)
			Resize(ref outputBuffer, Max(outputBuffer.Length * 2, n));
	}

	static void Dump()
	{
		outputStream.Write(outputBuffer, 0, outputIndex);
		outputIndex = 0;
	}

	static void Flush()
	{
		Dump();
		outputStream.Flush();
	}

	#endregion
	#endregion

	#region Main

	public static void Main()
	{
		AppDomain.CurrentDomain.UnhandledException += (sender, arg) =>
		{
			Flush();
			var e = (Exception)arg.ExceptionObject;
			Console.Error.WriteLine(e);
			var line = new StackTrace(e, true).GetFrames()
				.Select(x => x.GetFileLineNumber()).FirstOrDefault(x => x != 0);
			var wait = line % 300 * 10 + 5;
			var process = Process.GetCurrentProcess();
			while (process.TotalProcessorTime.TotalMilliseconds > wait && wait < 3000) wait += 1000;
			while (process.TotalProcessorTime.TotalMilliseconds < Min(wait, 3000)) ;
			Environment.Exit(1);
		};

		InitInput(Console.OpenStandardInput());
		InitOutput(Console.OpenStandardOutput());
#if __MonoCS__ && !C7
        var thread = new System.Threading.Thread(()=>new Solution().Solve());
        var f = BindingFlags.NonPublic | BindingFlags.Instance;
        var t = thread.GetType().GetField("internal_thread", f).GetValue(thread);
        t.GetType().GetField("stack_size", f).SetValue(t, 32 * 1024 * 1024);
        thread.Start();
        thread.Join();
#else
		new Solution().Solve();
#endif
		Flush();
		Console.Error.WriteLine(Process.GetCurrentProcess().TotalProcessorTime);
	}
	#endregion
	#endregion
}


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

namespace codeforces
{
    class Program
    {
        class Flow
        {
            public int to;
            public int capacity;
            public int flow;
            public int cost;
            public int iRevEdge;

            public Flow(int to, int capacity, int flow, int cost, int iRevEdge)
            {
                this.to = to;
                this.capacity = capacity;
                this.flow = flow;
                this.cost = cost;
                this.iRevEdge = iRevEdge;
            }
        }

        class CompareVertex : IComparer<int>
        {
            public int Compare(int x, int y)
            {
                int v = d[x].CompareTo(d[y]);
                return v != 0 ? v : x.CompareTo(y);
            }
        }

        const int N = 80;

        static int[] di = new int[4] { 0, 0, -1, 1 };
        static int[] dj = new int[4] { -1, 1, 0, 0 };

        static int n, m;
        static int[,] a = new int[N, N];

        static int[] d = new int[N * N + 2];
        static int[] phi = new int[N * N + 2];
        static int[] parent = new int[N * N + 2];
        static int[] numEdge = new int[N * N + 2];
        static List<Flow>[] G = new List<Flow>[N * N + 2];
        static SortedSet<int> sVertex = new SortedSet<int>(new CompareVertex());
        static int minCost = 0;

        static void AddEdge(int from, int to, int cap, int cost)
        {
            G[from].Add(new Flow(to, cap, 0, cost, G[to].Count));
            G[to].Add(new Flow(from, 0, 0, -cost, G[from].Count - 1));
        }

        static bool FindPath(int from, int to)
        {
            for (int i = 0; i <= to; ++i)
            {
                d[i] = int.MaxValue;
            }
            int v;
            sVertex.Clear();
            d[from] = 0;
            sVertex.Add(from);
            while (sVertex.Count > 0)
            {
                v = sVertex.Min;
                sVertex.Remove(v);

                for (int i = 0; i < G[v].Count; ++i)
                {
                    var f = G[v][i];
                    if (f.flow < f.capacity && d[f.to] > d[v] + f.cost - phi[v] + phi[f.to])
                    {
                        if (sVertex.Contains(f.to))
                        {
                            sVertex.Remove(f.to);
                        }
                        d[f.to] = d[v] + f.cost - phi[v] + phi[f.to];
                        sVertex.Add(f.to);
                        parent[f.to] = v;
                        numEdge[f.to] = i;
                    }
                }
            }

            if (d[to] == int.MaxValue)
            {
                return false;
            }
            for (int i = 0; i <= to; ++i)
            {
                if (d[i] != int.MaxValue)
                {
                    phi[i] += d[i];
                }
            }
            v = to;
            int flow = int.MaxValue;
            while (v != from)
            {
                int u = parent[v];
                flow = Math.Min(flow, G[u][numEdge[v]].capacity - G[u][numEdge[v]].flow);
                v = u;
            }

            v = to;
            while(v != from)
            {
                int u = parent[v];
                G[u][numEdge[v]].flow += flow;
                G[v][G[u][numEdge[v]].iRevEdge].flow -= flow;
                minCost += flow * G[u][numEdge[v]].cost;
                v = u;
            }
            return true;

        }

        static void Main(string[] args)
        {
            var t = Console.ReadLine().Split(' ');
            n = int.Parse(t[0]);
            m = int.Parse(t[1]);
            for (int i = 0; i < n; ++i)
            {
                t = Console.ReadLine().Split(' ');
                for (int j = 0; j < m; ++j)
                {
                    a[i, j] = int.Parse(t[j]);
                }
            }
            int from = n * m;
            int to = n * m + 1;
            for (int i = 0; i <= to; ++i)
            {
                phi[i] = 0;
                G[i] = new List<Flow>();
            }

            for (int i = 0; i < n; ++i)
            {
                for (int j = 0; j < m; ++j)
                {
                    if ((i + j) % 2 == 0)
                    {
                        AddEdge(from, i * m + j, 1, 0);
                        for (int k = 0; k < 4; ++k)
                        {
                            int ei = i + di[k];
                            int ej = j + dj[k];
                            if (ei >= 0 && ei < n && ej >= 0 && ej < m)
                            {
                                AddEdge(i * m + j, ei * m + ej, 1, a[i, j] == a[ei, ej] ? 0 : 1);
                            }
                        }
                    }
                    else
                    {
                        AddEdge(i * m + j, to, 1, 0);
                    }

                }
            }

            while (FindPath(from, to)) { }

            Console.WriteLine(minCost);

            Console.Read();
        }

    }
}


using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
class Solve{
    public Solve(){}
    StringBuilder sb;
    public static int Main(){
        new Solve().Run();
        return 0;
    }
    void Run(){
        sb = new StringBuilder();
        Calc();
        Console.Write(sb.ToString());
    }
    void Calc(){
        string[] str = Console.ReadLine().Split(' ');
        int H = int.Parse(str[0]);
        int W = int.Parse(str[1]);
        int[,] D = new int[H,W];
        for(int i=0;i<H;i++){
            str = Console.ReadLine().Split(' ');
            for(int j=0;j<W;j++){
                D[i,j] = int.Parse(str[j]);
            }
        }
        int S = H*W;
        int G = H*W+1;
        List<int> F = new List<int>();
        List<int> T = new List<int>();
        List<long> capacity = new List<long>();
        List<long> cost = new List<long>();
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                if((i+j) % 2 == 0){
                    F.Add(S);
                    T.Add(i*W+j);
                    capacity.Add(1);
                    cost.Add(0);
                    if(i != 0){
                        F.Add(i*W+j);
                        T.Add((i-1)*W+j);
                        capacity.Add(1);
                        cost.Add(D[i-1,j] == D[i,j] ? 0 : 1);
                    }
                    if(i != H-1){
                        F.Add(i*W+j);
                        T.Add((i+1)*W+j);
                        capacity.Add(1);
                        cost.Add(D[i+1,j] == D[i,j] ? 0 : 1);
                    }
                    if(j != 0){
                        F.Add(i*W+j);
                        T.Add(i*W+(j-1));
                        capacity.Add(1);
                        cost.Add(D[i,j-1] == D[i,j] ? 0 : 1);
                    }
                    if(j != W-1){
                        F.Add(i*W+j);
                        T.Add(i*W+(j+1));
                        capacity.Add(1);
                        cost.Add(D[i,j+1] == D[i,j] ? 0 : 1);
                    }
                }
                else{
                    T.Add(G);
                    F.Add(i*W+j);
                    capacity.Add(1);
                    cost.Add(0);
                }
            }
        }
        MinCostFlow Flow = new MinCostFlow(F.ToArray(),T.ToArray(),capacity.ToArray(),cost.ToArray(),G+1,S,G,H*W/2);
        sb.Append(Flow.res+"\n");
    }
}
class Edge{
    public Vertex to;
    public long capacity;
    public long cost;
    public Edge rev;
    public Edge(Vertex v,long ca,long co){
        to = v;
        capacity = ca;
        cost = co;
    }
}
class Vertex{
    public bool finished;
    public long cost;
    public long h;
    public Vertex fromv;
    public Edge frome;
    public List<Edge> edges;
    public void AddEdge(Edge e){
        edges.Add(e);
    }
    public Vertex(){
        edges = new List<Edge>();
        finished = false;
        cost = -1;
    }
}
struct Data{
    public Vertex v;
    public long cost;
    public Data(Vertex v0,long c){
        v = v0;
        cost = c;
    }
}
class MinCostFlow{
    Vertex[] point;
    Vertex S;
    Vertex G;
    public long res;
    int E;
    const long INF = 1000000000000000;
    public MinCostFlow(int[] f,int[] t,long[] capacity,long[] cost,int n,int s,int g,long flow){
        point = new Vertex[n];
        for(int i=0;i<n;i++){
            point[i] = new Vertex();
        }
        E = f.Length;
        for(int i=0;i<E;i++){
            point[f[i]].AddEdge(new Edge(point[t[i]],capacity[i],cost[i]));
            point[t[i]].AddEdge(new Edge(point[f[i]],0,-cost[i]));
            point[f[i]].edges[point[f[i]].edges.Count-1].rev = point[t[i]].edges[point[t[i]].edges.Count-1];
            point[t[i]].edges[point[t[i]].edges.Count-1].rev = point[f[i]].edges[point[f[i]].edges.Count-1];
        }
        S = point[s];
        G = point[g];
        res = 0;
        while(true){
            Heap H = new Heap(2*E+1);
            S.cost = 0;
            H.push(new Data(S,0));
            while(!H.Empty()){
                Data D = H.pop();
                Vertex V = D.v;
                if(V.finished){
                    continue;
                }
                V.finished = true;
                for(int i=0;i<V.edges.Count;i++){
                    if(V.edges[i].capacity == 0){
                        continue;
                    }
                    Vertex T = V.edges[i].to;
                    if(T.cost == -1 || T.cost > V.cost + V.edges[i].cost + V.h - T.h){
                        T.cost = V.cost + V.edges[i].cost + V.h - T.h;
                        T.fromv = V;
                        T.frome = V.edges[i];
                        H.push(new Data(T,T.cost));
                    }
                }
            }
            if(G.cost == -1){
                res = -1;
                break;
            }
            for(int i=0;i<n;i++){
                point[i].h += point[i].cost;
                point[i].cost = -1;
                point[i].finished = false;
            }
            long d = flow;
            for(Vertex V = G;V != S;V = V.fromv){
                d = Math.Min(d,V.frome.capacity);
            }
            res += d*G.h;
            for(Vertex V = G;V != S;V = V.fromv){
                V.frome.capacity -= d;
                V.frome.rev.capacity += d;
            }
            flow -= d;
            if(flow == 0){
                break;
            }
        }
    }
}
class Heap{
    public int size;
    Data[] obj;
    public Heap(int maxsize){
        size = 0;
        obj = new Data[maxsize];
    }
    public void push(Data a){
        int i = size;
        size++;
        while(i > 0){
            int p = (i - 1)/2;
            if(obj[p].cost <= a.cost){
                obj[i] = a;
                break;
            }
            obj[i] = obj[p];
            i = p;
        }
        if(i == 0){
            obj[0] = a;
        }
    }
    public bool Empty(){
        return size == 0;
    }
    public Data pop(){
        Data t = obj[0];
        int i = 0;
        size--;
        while(2*i+1 < size){
            int p = 2*i+1;
            if(p+1 < size && obj[p+1].cost < obj[p].cost){
                p++;
            }
            if(obj[p].cost < obj[size].cost){
                obj[i] = obj[p];
                i = p;
            }
            else{
                obj[i] = obj[size];
                break;
            }
        }
        if(2*i+1 >= size){
            obj[i] = obj[size];
        }
        return t;
    }
}


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

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    class Edge<T>
    {
        public int To, Inv;
        public T Capacity, Cost, Flow;
        public Edge(int to, int inv, T capacity, T cost, T flow)
        {
            To = to;
            Inv = inv;
            Capacity = capacity;
            Cost = cost;
            Flow = flow;
        }
    }

    static void AddEdge(List<Edge<int>>[] g, int from, int to, int capacity, int cost)
    {
        g[from].Add(new Edge<int>(to, g[to].Count, capacity, cost, 0));
        g[to].Add(new Edge<int>(from, g[from].Count - 1, 0, -cost, 0));
    }

    int MinCost(List<Edge<int>>[] g, int source, int sink, int limit)
    {
        const int INF = int.MaxValue / 2;

        int n = g.Length;
        int flow = 0, cost = 0;
        while (flow < limit)
        {
            var id = new int[n];
            var dist = Enumerable.Repeat(INF, n).ToArray();
            var q = new int[n];
            var path = new int[n];
            var epath = new int[n];
            int qh = 0, qt = 0;
            q[qt++] = source;
            dist[source] = 0;
            while (qh != qt)
            {
                int v = q[qh++];
                if (qh == n)
                    qh = 0;
                id[v] = 2;
                for (int i = 0; i < g[v].Count; i++)
                {
                    var r = g[v][i];
                    if (r.Flow < r.Capacity && dist[v] + r.Cost < dist[r.To])
                    {
                        dist[r.To] = dist[v] + r.Cost;
                        if (id[r.To] == 0)
                        {
                            q[qt++] = r.To;
                            if (qt == n)
                                qt = 0;
                        }
                        else if (id[r.To] == 2)
                        {
                            if (--qh == -1)
                                qh = n - 1;
                            q[qh] = r.To;
                        }
                        id[r.To] = 1;
                        path[r.To] = v;
                        epath[r.To] = i;
                    }
                }
            }
            if (dist[sink] == INF)
                break;
            int addflow = limit - flow;
            for (int v = sink; v != source; v = path[v])
            {
                int pv = path[v];
                int pr = epath[v];
                addflow = Math.Min(addflow, g[pv][pr].Capacity - g[pv][pr].Flow);
            }
            for (int v = sink; v != source; v = path[v])
            {
                int pv = path[v];
                int pr = epath[v], r = g[pv][pr].Inv;
                g[pv][pr].Flow += addflow;
                g[v][r].Flow -= addflow;
                cost += g[pv][pr].Cost * addflow;
            }
            flow += addflow;
        }
        return cost;
    }

    private int[] dr = {1, 0, -1, 0};
    private int[] dc = {0, 1, 0, -1};

    public void Solve()
    {
        int n = ReadInt();
        int m = ReadInt();
        var a = ReadIntMatrix(n);

        var g = Enumerable.Repeat(0, n * m + 2).Select(x => new List<Edge<int>>()).ToArray();
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
            {
                int x = i * m + j;
                if ((i + j) % 2 == 0)
                {
                    AddEdge(g, n * m, x, 1, 0);
                    for (int k = 0; k < 4; k++)
                    {
                        int ii = i + dr[k];
                        int jj = j + dc[k];
                        if (ii < 0 || ii == n || jj < 0 || jj == m)
                            continue;
                        AddEdge(g, x, ii * m + jj, 1, a[i][j] == a[ii][jj] ? 0 : 1);
                    }
                }
                else
                {
                    AddEdge(g, x, n * m + 1, 1, 0);
                }
            }

        Write(MinCost(g, n * m, n * m + 1, n * m / 2));
    }

    #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());
        //reader = new StreamReader("game.in");
        //writer = new StreamWriter("game.out");
#endif
        try
        {
            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 256);
            thread.Start();
            thread.Join();
            //new Solver().Solve();
        }
        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>(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);
    }

    #endregion
}


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

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

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

        int h = cin.nextInt();
        int w = cin.nextInt();
        int[,] board = new int[h, w];
        for (int i = 0; i < h; i++)
        {
            for (int j = 0; j < w; j++)
            {
                board[i, j] = cin.nextInt();
            }
        }

        int MAX = 1 << w;
        int[] dp = new int[MAX];
        for (int i = 0; i < MAX; i++)
        {
            dp[i] = 1 << 16;
        }
        dp[0] = 0;

        for (int i = 0; i < h; i++)
        {
            for (int j = 0; j < w; j++)
            {
                int[] nextdp = new int[MAX];
                for (int k = 0; k < MAX; k++)
                {
                    nextdp[k] = 1 << 16;
                }

                for (int k = 0; k < MAX; k++)
                {
                    if (k % 2 == 0)
                    {
                        if (j != w - 1)
                        {
                            int add = 0;
                            if (board[i, j] != board[i, j + 1]) add = 1;
                            int next = k / 2 + 1;
                            nextdp[next] = Math.Min(nextdp[next], dp[k] + add);
                        }
                        if (i != h - 1)
                        {
                            int add = 0;
                            if (board[i, j] != board[i + 1, j]) add = 1;
                            int next = k / 2 + (1 << (w - 1));
                            nextdp[next] = Math.Min(nextdp[next], dp[k] + add);
                        }
                    }
                    else
                    {
                        nextdp[k / 2] = Math.Min(nextdp[k / 2], dp[k]);
                    }
                }
                dp = nextdp;
            }
        }
        Console.WriteLine(dp[0]);

    }

}

class Scanner
{
    string[] s;
    int i;

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

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

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

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

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


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

class Program
{

    void solve()
    {
        long l = nextInt();
        long r = nextInt();
        long p = 1;
        long res = 0;
        while (p < 1000000000000L)
        {
            p *= 10;
            long c = p - 1;
            long num;
            if (c / 2 > r)
                num = r;
            else if (c / 2 < l)
                num = l;
            else
                num = c / 2;
            if (num >= p / 10 && num < p)
                res = Math.Max(res, num * (c - num));
        }
        println(res);

    }
    long get(int x)
    {
        long y = 0;
        long p = 1;
        long temp = x;
        while (x > 0)
        {
            y += p * (9 - x % 10);
            x /= 10;
            p *= 10;
        }
        return temp * y;
    }

    ////////////
    private void println(int[] ar)
    {
        for (int i = 0; i < ar.Length; i++)
        {
            if (i == ar.Length - 1)
                println(ar[i]);
            else
                print(ar[i] + " ");
        }
    }
    private void println(int[] ar, bool add)
    {
        int A = 0;
        if (add)
            A++;
        for (int i = 0; i < ar.Length; i++)
        {
            if (i == ar.Length - 1)
                println(ar[i] + A);
            else
                print((ar[i] + A) + " ");
        }
    }

    private void println(string Stringst)
    {
        Console.WriteLine(Stringst);
    }
    private void println(char charnum)
    {
        Console.WriteLine(charnum);
    }
    private void println(int Intnum)
    {
        Console.WriteLine(Intnum);
    }
    private void println(long Longnum)
    {
        Console.WriteLine(Longnum);
    }
    private void println(double Doublenum)
    {
        string s = Doublenum.ToString(CultureInfo.InvariantCulture);
        Console.WriteLine(s);
    }

    private void print(string Stringst)
    {
        Console.Write(Stringst);
    }
    private void print(int Intnum)
    {
        Console.Write(Intnum);
    }
    private void print(char charnum)
    {
        Console.Write(charnum);
    }
    private void print(long Longnum)
    {
        Console.Write(Longnum);
    }
    private void print(double Doublenum)
    {
        Console.Write(Doublenum);
    }

    string[] inputLine = new string[0];
    int inputInd = 0;
    string nextLine()
    {
        return Console.ReadLine();
    }
    void readInput()
    {
        if (inputInd != inputLine.Length)
            throw new Exception();
        inputInd = 0;
        inputLine = Console.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (inputLine.Length == 0)
            readInput();
    }
    int nextInt()
    {
        return int.Parse(nextString());
    }
    long nextLong()
    {
        return long.Parse(nextString());
    }
    double nextDouble()
    {
        return double.Parse(nextString());
    }
    string nextString()
    {
        if (inputInd == inputLine.Length)
            readInput();
        return inputLine[inputInd++];
    }
    static void Main(string[] args)
    {
        Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        new Program().solve();
    }
}


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

class Solver
{
    public void Solve()
    {
        /*
        long max = 0;
        for (int i = 0; ; i++)
        {
            long a = _search(i, i);
            if (a > max)
            {
                Debug.WriteLine(i + "\t" + a+"\tmax");
                max = a;
            }
            else
                Debug.WriteLine(i + "\t" + a);

        }
        */

        var ss = CF.ReadLine().Split(' ');
        int l = int.Parse(ss[0]);
        int r = int.Parse(ss[1]);

        int d = _d(r);
        long dmax = 0;
        {
            for (int i = 0; i < d ; i++)
            {
                dmax *= 10;
                if( i==0)
                    dmax += 4;
                else
                    dmax += 9;
            }
        }

        int n;
        if (r < dmax)
            n = r;
        else if (l > dmax)
            n = l;
        else
            n = (int)dmax;

        CF.WriteLine(_search(n, n));
    }

    int _d(int n)
    {
        int d = 0;
        {
            int tmp = n;
            for (; ; )
            {
                if (tmp == 0)
                    break;
                d += 1;
                tmp /= 10;
            }
        }
        return d;
    }

    long _search(int l,int r)
    {
        long max = 0;
        for (int i = l; i <= r; i++)
        {
            int tmp = i;
            Stack<int> ds = new Stack<int>();
            for (; ; )
            {
                if (tmp == 0)
                    break;
                ds.Push(tmp % 10);
                tmp/= 10;
            }

            long o=0;
            foreach (var d in ds)
            {
                o *= 10;
                o += (9-d);
            }

            long p = (long)o * i;
            max = Math.Max(p, max);
        }
        return max;
    }

    //  test
    static Utils CF = new Utils(new[]{
@"
1 1000000000
",

@"
1 999
",

@"
500000000 999999999
",
@"
3 7
",
 @"
1 1
",
 @"
8 10
"

    });
    #region test

    static void Main(string[] args)
    {
#if DEBUG
        for (int t=0;t<CF.TestCount;t++ )
        {
            CF.Test(t);
            new Solver().Solve();
        }
#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.Collections.Generic;

namespace yandex2011_round_2_reflection {
    internal class Program {
        private static void Main(string[] args) {
            string s = Console.ReadLine();
            string[] ss = s.Split(' ');
            int l = int.Parse(ss[0]);
            int r = int.Parse(ss[1]);
            Int64 bigger = GetBigger(r);
            Int64 aBest = bigger/2 - 1;
            Int64 bBest = bigger/2;
            if (l <= aBest && r >= bBest) {
                Console.WriteLine(aBest * bBest);
                return;
            }
            if (l > aBest) {
                aBest = l;
                bBest = l;
            }
            if (r < bBest) {
                bBest = r;
                aBest = r;
            }
            Int64 aBestBack = GetBack(aBest);
            Int64 bBestBack = GetBack(bBest);
            if (aBest * aBestBack > bBest * bBestBack) {
                Console.WriteLine(aBest * aBestBack);
            } else {
                Console.WriteLine(bBest * bBestBack);
            }
        }

        private static Int64 GetBack(Int64 a) {
            var digits = new List<int>();
            if (a == 0) digits.Add(0);
            while (a > 0) {
                digits.Add((int) (a%10));
                a = a/10;
            }
            Int64 back = 0;
            for (int i = digits.Count - 1; i >= 0; i--) {
                back = back*10 + 9 - digits[i];
            }
            return back;
        }

        private static Int64 GetBigger(int a) {
            var digits = new List<int>();
            if (a == 0) digits.Add(0);
            while (a > 0) {
                digits.Add(a%10);
                a = a/10;
            }
            Int64 bigger = 1;
            for (int i = digits.Count - 1; i >= 0; i--) {
                bigger *= 10;
            }
            return bigger;
        }
    }
}


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

namespace _86A
{
    class Program
    {
        static void Main(string[] args)
        {
            int l = 0, r = 0;
            string input = Console.ReadLine();
            l = Convert.ToInt32(input.Split(' ')[0]);
            r = Convert.ToInt32(input.Split(' ')[1]);

            string sl = l.ToString();
            string sr = r.ToString();

            ulong num = 0;

            if (sr.Length > sl.Length)
            {
                if (Convert.ToInt16(sr[0]) - 48 >= 5)
                {
                    string biggest = "5";
                    for (int i = 0; i < sr.Length - 1; i++)
                    {
                        biggest += "0";
                    }
                    num = Convert.ToUInt64(biggest);
                }
                else
                {
                    num = Convert.ToUInt64(r);
                }
            }
            else if (sr.Length == sl.Length)
            {
                if (r == l)
                {
                    num = Convert.ToUInt64(r);
                }

                else if (Convert.ToInt16(sr[0]) - 48 >= 5 && Convert.ToInt16(sl[0]) - 48 >= 5)
                {
                    num = Convert.ToUInt64(l);
                }
                else if (Convert.ToInt16(sr[0]) - 48 <= 4 && Convert.ToInt16(sl[0]) - 48 <= 4)
                {
                    num = Convert.ToUInt64(r);
                }
                else
                {
                    string biggest = "5";
                    for (int i = 0; i < sr.Length-1; i++)
                    {
                        biggest += "0";
                    }
                    num = Convert.ToUInt64(biggest);

                }

            }

            Console.WriteLine(refl(num) * num);
            Console.ReadLine();

        }

        static public ulong refl(ulong num)
        {
            string sr = num.ToString();
            string nine = "";
            for (int i = 0; i < sr.Length; i++)
            {
                nine += "9";
            }
            return(Convert.ToUInt64(nine) - num);
        }
    }
}


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

namespace _86A
{
    class Program
    {
        static void Main(string[] args)
        {
            int l = 0, r = 0;
            string input = Console.ReadLine();
            l = Convert.ToInt32(input.Split(' ')[0]);
            r = Convert.ToInt32(input.Split(' ')[1]);

            string sl = l.ToString();
            string sr = r.ToString();

            int num = 0;

            if (sr.Length > sl.Length)
            {
                num = r;
            }
            else if (sr.Length == sl.Length)
            {
                if (r == l)
                {
                    num = r;
                }

                else if (Convert.ToInt16(sr[0]) - 48 >= 5 && Convert.ToInt16(sl[0]) - 48 >= 5)
                {
                    num = l;
                }
                else if (Convert.ToInt16(sr[0]) - 48 <= 4 && Convert.ToInt16(sl[0]) - 48 <= 4)
                {
                    num = r;
                }
                else
                {
                    string biggest = "5";
                    for (int i = 0; i < sr.Length-1; i++)
                    {
                        biggest += "0";
                    }
                    num = Convert.ToInt32(biggest);

                }

            }

            Console.WriteLine(refl(num) * num);
            Console.ReadLine();

        }

        static public int refl(int num)
        {
            string sr = num.ToString();
            string nine = "";
            for (int i = 0; i < sr.Length; i++)
            {
                nine += "9";
            }

            return( Convert.ToInt32(nine) - num);
        }
    }
}


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

class Solver
{
    public void Solve()
    {
        /*
        long max = 0;
        for (int i = 0; ; i++)
        {
            long a = _search(i, i);
            if (a > max)
            {
                Debug.WriteLine(i + "\t" + a);
                max = a;
            }
        }
        */

        var ss = CF.ReadLine().Split(' ');
        int l = int.Parse(ss[0]);
        int r = int.Parse(ss[1]);

        /*
        l = 1;
        r = 1000000000;
        */

        int r2 = r;
        {
            int d = _d(r);
            for (int i = 0; i < d / 2; i++)
            {
                r2 /= 10;
            }
            for (int i = 0; i < d / 2; i++)
            {
                r2 *= 10;
            }

            int dmax = 0;
            {
                for (int i = 0; i < d / 2; i++)
                {
                    dmax *= 10;
                    dmax += 9;
                }

                if (d % 2 == 1)
                {
                    dmax *= 10;
                    dmax += 4;
                }
                for (int i = 0; i < d / 2; i++)
                {
                    dmax *= 10;
                }
            }
            if (r2 > dmax)
                r2 = dmax;
        }

        int l2 = l;
        if (r2 < l2)
            r2 = r;
        else
            l2 = r2;

        CF.WriteLine(_search(l2, r2));
    }

    int _d(int n)
    {
        int d = 0;
        {
            int tmp = n;
            for (; ; )
            {
                if (tmp == 0)
                    break;
                d += 1;
                tmp /= 10;
            }
        }
        return d;
    }

    long _search(int l,int r)
    {
        long max = 0;
        for (int i = l; i <= r; i++)
        {
            int tmp = i;
            Stack<int> ds = new Stack<int>();
            for (; ; )
            {
                if (tmp == 0)
                    break;
                ds.Push(tmp % 10);
                tmp/= 10;
            }

            int o=0;
            foreach (var d in ds)
            {
                o *= 10;
                o += (9-d);
            }

            long p = (long)o * i;
            max = Math.Max(p, max);
        }
        return max;
    }

    //  test
    static Utils CF = new Utils(new[]{
@"
99990001 999939999
",
@"
3 7
",
 @"
1 1
",
 @"
8 10
"

    });
    #region test

    static void Main(string[] args)
    {
#if DEBUG
        for (int t=0;t<CF.TestCount;t++ )
        {
            CF.Test(t);
            new Solver().Solve();
        }
#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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

class Program {
    static void Main(string[] args) {
        int x = 10, sum;
        string[] s = Console.ReadLine().Split();
        int l = int.Parse(s[0]);
        int r = int.Parse(s[1]);
        while (r >= x) {
            x *= 10;
        }
        if (r >= x / 2 && l <= x / 2 - 1) {
            sum = x / 2 - 1;
        }
        else if (l > x / 2 - 1) {
            sum = l;
        }
        else {
            sum = r;
        }
        Console.WriteLine(sum * (x - sum - 1));
    }
}


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

namespace App2 {
    class Program
    {
        Regex regex;
        void Solve()
        {
            //StreamReader textFile = new StreamReader("c:\\in.txt");

            regex = new Regex("[^\\d\\-]{1,}");

            //string []s = regex.Split("0, 9, 12, 232, 5  3 -1");
            string[] s = regex.Split(Console.In.ReadToEnd());
            //string[] s = regex.Split(textFile.ReadToEnd());

            int L = Int32.Parse(s[0]);
            int R = Int32.Parse(s[1]);

            if (len(L) < len(R))
            {
                L = (int)Math.Round(Math.Pow(10, len(R)-1));
            }
            int ll = len(L);
            int powN = (int)Math.Round(Math.Pow(10, ll - 1));
            int nines = (int)Math.Round(Math.Pow(10, ll) - 1);

            Int64 answer = 1L * L * (nines - L);
            answer = Math.Max(answer, 1L * R * (nines - R));
            if (L <= 5 * powN && 5 * powN <= R)
            {
                answer = Math.Max(answer, 5 * powN * (nines - 5 * powN));
            }

            Console.WriteLine(answer);
        }

        int len(int n)
        {
            int res = 0;
            while (n > 0)
            {
                ++res;
                n /= 10;
            }
            return res;
        }

        static void Main()
        {
            new Program().Solve();
        }
    }
}


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

namespace _86A
{
    class Program
    {
        static void Main(string[] args)
        {
            int l = 0, r = 0;
            string input = Console.ReadLine();
            l = Convert.ToInt32(input.Split(' ')[0]);
            r = Convert.ToInt32(input.Split(' ')[1]);

            string sl = l.ToString();
            string sr = r.ToString();

            int num = 0;

            if (sr.Length > sl.Length)
            {
                if (Convert.ToInt16(sr[0]) - 48 >= 5)
                {
                    string biggest = "5";
                    for (int i = 0; i < sr.Length - 1; i++)
                    {
                        biggest += "0";
                    }
                    num = Convert.ToInt32(biggest);
                }
                else
                {
                    num = r;
                }
            }
            else if (sr.Length == sl.Length)
            {
                if (r == l)
                {
                    num = r;
                }

                else if (Convert.ToInt16(sr[0]) - 48 >= 5 && Convert.ToInt16(sl[0]) - 48 >= 5)
                {
                    num = l;
                }
                else if (Convert.ToInt16(sr[0]) - 48 <= 4 && Convert.ToInt16(sl[0]) - 48 <= 4)
                {
                    num = r;
                }
                else
                {
                    string biggest = "5";
                    for (int i = 0; i < sr.Length-1; i++)
                    {
                        biggest += "0";
                    }
                    num = Convert.ToInt32(biggest);

                }

            }

            Console.WriteLine(refl(num) * num);
            Console.ReadLine();

        }

        static public int refl(int num)
        {
            string sr = num.ToString();
            string nine = "";
            for (int i = 0; i < sr.Length; i++)
            {
                nine += "9";
            }

            return( Convert.ToInt32(nine) - num);
        }
    }
}


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

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    private const int MAX = 500000;

    public void Solve()
    {
        int n = ReadInt();
        int d = ReadInt();
        var a = ReadIntArray();

        var dp = new bool[MAX + 1];
        dp[0] = true;
        for (int i = 0; i < n; i++)
        {
            for (int j = MAX; j >= 0; j--)
                if (dp[j])
                    dp[j + a[i]] = true;
        }

        int x = 0;
        int ans = 0;
        while (true)
        {
            int y = Math.Min(x + d, MAX);
            while (!dp[y])
                y--;
            if (x == y)
                break;
            ans++;
            x = y;
        }

        Write(x, ans);
    }

    #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());
        //reader = new StreamReader("subsequences.in");
        //writer = new StreamWriter("subsequences.out");
#endif
        try
        {
//            var thread = new Thread(new Solver().Solve, 1024 * 1024 * 256);
//            thread.Start();
//            thread.Join();
            new Solver().Solve();
        }
        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>(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);
    }

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

    #endregion
}


using System;

namespace CF
{
	class _364B
	{
		private static void Main(String[] args)
		{
			var pts = Console.ReadLine().Split(' ');
			int n = int.Parse(pts[0]),
				d = int.Parse(pts[1]);
			var a = new int[n];
			pts = Console.ReadLine().Split(' ');
			for (int i = 0; i < n; i++)
				a[i] = int.Parse(pts[i]);
			int limit = 10000 * n;
			var map = new int[limit + 1, n + 1];
			map[0, 0] = 1;
			int max = 0;
			for (int i = 0; i < n; ++i) {
				for (int j = max; j >= 0; --j)
					if (map[j, i] != 0) {
						map[j + a[i], i + 1] = 1;
						max = Math.Max(max, j + a[i]);
						map[j, i + 1] = 1;
					}
			}
			int ans = 0, days = 0;
			while (ans < limit)
			{
				int eat = 0;
				for (int j = 0; j <= d; ++j)
					if (ans + j <= limit
						&& map[ans + j, n] != 0)
						eat = j;
				if (0 == eat)
					break;
				ans += eat;
				++days;
			}
			Console.WriteLine("{0} {1}", ans, days);
		}
	}
}


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

namespace CF
{
	class _364B
	{
		private const int KMaxPrice = 10000;

		private static void Main(String[] args)
		{
			var parts = Console.ReadLine().Split(' ');
			int n = int.Parse(parts[0]),
				d = int.Parse(parts[1]);
			int[] a = new int[n];
			parts = Console.ReadLine().Split(' ');
			for (int i = 0; i < n; i++)
				a[i] = int.Parse(parts[i]);
			int limit = KMaxPrice*n;
			int[,] map = new int[limit + 1, n + 1];
			map[0, 0] = 1;
			for (int i = 0; i < n; ++i)
				for (int j = limit; j >= 0; --j)
					if (map[j, i] != 0)
					{
						map[j + a[i], i + 1] = 1;
						map[j, i + 1] = 1;
					}
			int ans = 0, days = 0;
			while (ans < limit)
			{
				int eat = 0;
				for (int j = 0; j <= d; ++j)
					if (ans + j <= limit
						&& map[ans + j, n] != 0)
						eat = j;
				if (0 == eat)
					break;
				//Console.WriteLine("{0} {1}", eat, days);
				ans += eat;
				++days;
			}
			Console.WriteLine("{0} {1}", ans, days);
		}
	}
}


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
{
    string[] a = { "Ac","Ag","Al","Am","Ar","As","At","Au","B","Ba","Be","Bh","Bi","Bk","Br","C","Ca","Cd","Ce","Cf","Cl","Cm","Cn","Co","Cr","Cs","Cu","Db","Ds","Dy","Er","Es","Eu","F","Fe","Fl","Fm","Fr","Ga","Gd","Ge","H","He","Hf","Hg","Ho","Hs","I","In","Ir","K","Kr","La","Li","Lr","Lu","Lv","Mc","Md","Mg","Mn","Mo","Mt","N","Na","Nb","Nd","Ne","Nh","Ni","No","Np","O","Og","Os","P","Pa","Pb","Pd","Pm","Po","Pr","Pt","Pu","Ra","Rb","Re","Rf","Rg","Rh","Rn","Ru","S","Sb","Sc","Se","Sg","Si","Sm","Sn","Sr","Ta","Tb","Tc","Te","Th","Ti","Tl","Tm","Ts","U","V","W","Xe","Y","Yb","Zn","Zr"};
    Dictionary<char, List<string>> d;

    bool Fun(int p, string s)
    {
        if (p >= s.Length)
            return true;
        foreach (string v in d[s[p]])
            if (p + v.Length <= s.Length && s.Substring(p, v.Length) == v && Fun(p + v.Length, s))
                return true;
        return false;
    }

    public void Solve()
    {
        d = new Dictionary<char, List<string>>();
        for (char i = 'A'; i <= 'Z'; i++)
            d[i] = new List<string>();
        foreach (string aa in a)
        {
            d[aa[0]].Add(aa.ToUpper());
        }

        string s = ReadToken();
        Write(Fun(0, s) ? "YES" : "NO");
    }

    #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 static System.Console;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static int NN => int.Parse(ReadLine());
    static int[] NList => ReadLine().Split().Select(int.Parse).ToArray();
    static void Main()
    {
        var c = ReadLine().Split();
        var n = int.Parse(c[0]);
        var x = decimal.Parse(c[1]);
        var list = new List<decimal>();
        list.Add(x);
        var res = 0;
        while (true)
        {
            var next = new List<decimal>();
            foreach (var li in list)
            {
                var str = li.ToString();
                if (str.Length == n)
                {
                    WriteLine(res);
                    return;
                }
                for (var i = '2'; i <= '9'; ++i) if (str.Contains(i))
                {
                    next.Add(li * (i - '0'));
                }
            }
            if (next.Count == 0)
            {
                WriteLine(-1);
                return;
            }
            var max = next.Max();
            if (next.Count > 10000)
            {
                next.Sort();
                next = next.Skip(next.Count - 10000).ToList();
            }
            list = next;
            ++res;
        }
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BI = System.Numerics.BigInteger;

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

	internal class Sol {
		public void Solve() {

			var hs = new HashSet<BI>();
			hs.Add(X);
			for(int t=0; ; t++) {
				if(hs.Count == 0) {
					Console.WriteLine(-1);
					return;
				}
				var nhs = new HashSet<BI>();
				foreach(var n in hs) {

					var x = n;
					int len = 0;
					int[] cnt = new int[10];
					while (x > 0) {
						cnt[(int)(x % 10)]++;
						len++;
						x /= 10;
					}
					for(int i = 2; i <= 9; i++) {
						if (cnt[i] == 0) continue;
						BI nn = n * i;
						if(nn.ToString().Length == N) {
							Console.WriteLine(t + 1);
							return;
						}
						nhs.Add(nn);
					}
				}
				hs = nhs;
			}

		}
		int N;
		long X;
		public Sol() {
			var d = rla();
			N = (int)d[0]; X = d[1];
		}

		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)); }
		static T[] mka<T>(int n, T ini) { T[] ret = new T[n]; for (int i = 0; i < n; i++) ret[i] = ini; return ret; }
		static T[][] mka2<T>(int n, int m, T ini) { T[][] ret = new T[n][]; for (int i = 0; i < n; i++) ret[i] = mka(m, ini); return ret; }
		static T[][][] mka3<T>(int n, int m, int l, T ini) { T[][][] ret = new T[n][][]; for (int i = 0; i < n; i++) ret[i] = mka2(m, l, ini); return ret; }
		static T[][][][] mka4<T>(int n, int m, int l, int k, T ini) { T[][][][] ret = new T[n][][][]; for (int i = 0; i < n; i++) ret[i] = mka3(m, l, k, ini); return ret; }
	}

}


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

namespace Compete2
{
    partial class MainClass
    {
        public static void Main(string[] args)
        {
            int count = 1; //int.Parse(Console.ReadLine());
            List<string> output = new List<string>();

            for (int z = 0; z < count; z++)
            {
                //Console.ReadLine();
                //var s = Console.ReadLine();
                //var n = int.Parse(Console.ReadLine());
                var a = Console.ReadLine().Split(' ').Select(qw => ulong.Parse(qw)).ToList();
                //var b = Console.ReadLine().Split(' ').Select(qw => long.Parse(qw)).ToList();
                //var c = Console.ReadLine().Split(' ').Select(qw => long.Parse(qw)).ToList();
                //var b = long.Parse(Console.ReadLin    e());

                ulong o = ulong.MaxValue;
                //bool can = true;

                SortedSet<ulong> visited = new SortedSet<ulong>();

                Queue<ulong[]> q = new Queue<ulong[]>();

                if ((ulong)a[1].ToString().Length >= a[0])
                    o = 0;
                else
                    q.Enqueue(new ulong[] { a[1], 0 });

                while (q.Count>0)
                {
                    var x = q.Dequeue();

                    if (x[1] + 1 >= o)
                        continue;

                    var ds = x[0].ToString().Distinct().Select(i=>int.Parse(i.ToString())).OrderByDescending(i=>i).ToList();

                    if (ds.Contains(1))
                        ds.Remove(1);

                    if (ds.Contains(0))
                        ds.Remove(0);

                    BigInteger bi = x[0];

                    for (int i = 0; i < ds.Count; i++)
                    {
                        BigInteger bi2 = bi * ds[i];

                        if ((ulong)bi2.ToString().Length >= a[0])
                        {
                            if (x[1] + 1 < o)
                                o = x[1] + 1;
                        }
                        else
                        {
                            var u = (ulong)bi2;
                            if (!visited.Contains(u))
                            {
                                q.Enqueue(new ulong[] { u, x[1] + 1 });
                                visited.Add(u);
                            }
                        }
                    }
                }

                if (o == ulong.MaxValue)
                    output.Add("-1");
                else
                output.Add(o.ToString());
                //output.Add(string.Join(" ", o));
                /*if (can)
                    output.Add("Yes");
                else
                    output.Add("No");*/
            }

            output.ForEach(d => Console.WriteLine(d));
        }
    }
}


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

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

	internal class Sol {
		public void Solve() {

			var hs = new HashSet<long>();
			hs.Add(X);
			for(int t=0; ; t++) {
				if(hs.Count == 0) {
					Console.WriteLine(-1);
					return;
				}
				var nhs = new HashSet<long>();
				foreach(var n in hs) {

					var x = n;
					int len = 0;
					int[] cnt = new int[10];
					while (x > 0) {
						cnt[x % 10]++;
						len++;
						x /= 10;
					}
					for(int i = 2; i <= 9; i++) {
						if (cnt[i] != 1) continue;
						long nn = n * i;
						if(nn.ToString().Length == N) {
							Console.WriteLine(t + 1);
							return;
						}
						nhs.Add(nn);
					}
				}
				hs = nhs;
			}

		}
		int N;
		long X;
		public Sol() {
			var d = rla();
			N = (int)d[0]; X = d[1];
		}

		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)); }
		static T[] mka<T>(int n, T ini) { T[] ret = new T[n]; for (int i = 0; i < n; i++) ret[i] = ini; return ret; }
		static T[][] mka2<T>(int n, int m, T ini) { T[][] ret = new T[n][]; for (int i = 0; i < n; i++) ret[i] = mka(m, ini); return ret; }
		static T[][][] mka3<T>(int n, int m, int l, T ini) { T[][][] ret = new T[n][][]; for (int i = 0; i < n; i++) ret[i] = mka2(m, l, ini); return ret; }
		static T[][][][] mka4<T>(int n, int m, int l, int k, T ini) { T[][][][] ret = new T[n][][][]; for (int i = 0; i < n; i++) ret[i] = mka3(m, l, k, ini); return ret; }
	}

}


using System;
using static System.Console;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static int NN => int.Parse(ReadLine());
    static int[] NList => ReadLine().Split().Select(int.Parse).ToArray();
    static void Main()
    {
        var c = ReadLine().Split();
        var n = int.Parse(c[0]);
        var x = decimal.Parse(c[1]);
        var list = new List<decimal>();
        list.Add(x);
        var res = 0;
        while (true)
        {
            var maxes = new decimal[10];
            foreach (var li in list)
            {
                var str = li.ToString();
                if (str.Length == n)
                {
                    WriteLine(res);
                    return;
                }
                for (var i = '2'; i <= '9'; ++i) if (str.Contains(i))
                {
                    var next = li * (i - '0');
                    var nstr = next.ToString();
                    for (var j = '2'; j <= '9'; ++j)
                    {
                        if (nstr.Contains(j))
                        {
                            maxes[j - '0'] = Math.Max(maxes[j - '0'], next);
                        }
                    }
                }
            }
            list = maxes.Where(m => m > 0).ToList();
            if (list.Count == 0)
            {
                WriteLine(-1);
                return;
            }
            ++res;
        }
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BI = System.Numerics.BigInteger;

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

	internal class Sol {
		public void Solve() {

			var hs = new HashSet<BI>();
			hs.Add(X);
			for(int t=0; ; t++) {
				if(hs.Count == 0) {
					Console.WriteLine(-1);
					return;
				}
				var nhs = new HashSet<BI>();
				foreach(var n in hs) {

					var x = n;
					int len = 0;
					int[] cnt = new int[10];
					while (x > 0) {
						cnt[(int)(x % 10)]++;
						len++;
						x /= 10;
					}
					for(int i = 2; i <= 9; i++) {
						if (cnt[i] != 1) continue;
						BI nn = n * i;
						if(nn.ToString().Length == N) {
							Console.WriteLine(t + 1);
							return;
						}
						nhs.Add(nn);
					}
				}
				hs = nhs;
			}

		}
		int N;
		long X;
		public Sol() {
			var d = rla();
			N = (int)d[0]; X = d[1];
		}

		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)); }
		static T[] mka<T>(int n, T ini) { T[] ret = new T[n]; for (int i = 0; i < n; i++) ret[i] = ini; return ret; }
		static T[][] mka2<T>(int n, int m, T ini) { T[][] ret = new T[n][]; for (int i = 0; i < n; i++) ret[i] = mka(m, ini); return ret; }
		static T[][][] mka3<T>(int n, int m, int l, T ini) { T[][][] ret = new T[n][][]; for (int i = 0; i < n; i++) ret[i] = mka2(m, l, ini); return ret; }
		static T[][][][] mka4<T>(int n, int m, int l, int k, T ini) { T[][][][] ret = new T[n][][][]; for (int i = 0; i < n; i++) ret[i] = mka3(m, l, k, ini); return ret; }
	}

}