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

namespace CodeForces
{
    class Program
    {
        static void Main(string[] args)
        {

            var n = Int32.Parse(Console.ReadLine());

            Console.WriteLine(GetVal(n));
        }

        const int MOD_VAL = 1000000007;
        private static int GetVal(int n)
        {
            var primes = GetAllPrimes(n);
            var res = 0;
            var primeCache = GetPrimeCache(primes, n);
            var dfsSolver = new DFSSolver(primeCache);
            for(var i = 1;i<=n-2;i++)
            {
                var primeFactors = GetPrimeFactors(i, primes);
                var primeMap = new Dictionary<int,int>();
                foreach(var (prime, primeCnt) in primeFactors)
                {
                    primeMap[prime] = primeCnt;
                }
                dfsSolver.SetPrimeMap(primeMap);
                dfsSolver.SetPrimeFactors(GetPrimeFactors(n-i, primes));
                res = (int)((res + (long)dfsSolver.GetRes()*i ) % MOD_VAL);
            }
            return res;
        }

        private class DFSSolver
        {
            private int _res;
            private Dictionary<int,int> _primeMap;
            private List<(int,int)> _primeFactors;

            private Dictionary<int, int[]> _primeCache;
            public DFSSolver(Dictionary<int, int[]> primeCache)
            {
                _primeCache = primeCache;
            }

            public void SetPrimeMap(Dictionary<int,int> primeMap)
            {
                _primeMap = primeMap;
            }

            public void SetPrimeFactors(List<(int,int)> primeFactors)
            {
                _primeFactors = primeFactors;
            }

            public int GetRes()
            {
                _res = 0;
                DFS(0,1);
                var tmp = 1;
                foreach(var (prime, cnt) in _primeFactors)
                {
                    if(_primeMap.ContainsKey(prime))
                    {
                        if(cnt > _primeMap[prime])
                        {
                            tmp*= _primeCache[prime][cnt-_primeMap[prime]];
                        }
                    }
                    else
                    {
                        tmp*= _primeCache[prime][cnt];
                    }
                }
                _res-=tmp;
                if (_res < MOD_VAL) _res+=MOD_VAL;
                return _res;
            }

            private void DFS(int index, int val)
            {
                if(index == _primeFactors.Count)
                {
                    _res = (_res + val) % MOD_VAL;
                    return;
                }
                var prime = _primeFactors[index].Item1;
                var cnt = _primeFactors[index].Item2;
                for(var i = 0;i<= cnt;i++)
                {
                    var append = 1;
                    if(_primeMap.ContainsKey(prime))
                    {
                        if(i > _primeMap[prime])
                        {
                            append = _primeCache[prime][i - _primeMap[prime]];
                        }
                    }
                    else
                    {
                        append = _primeCache[prime][i];
                    }

                    if (i < cnt)
                    {
                        append = append * (prime - 1) * _primeCache[prime][cnt-i-1];
                    }
                    DFS(index+1, (int)((long)val * append % MOD_VAL));
                }
            }
        }

        private static Dictionary<int, int[]> GetPrimeCache(List<int> primes, int n)
        {
            var primeCache = new Dictionary<int, int[]>();
            foreach(var prime in primes)
            {
                var list = new List<int>();
                list.Add(1);
                var tmp = prime;
                while(tmp <= n)
                {
                    list.Add(tmp);
                    tmp*=prime;
                }
                primeCache[prime] = list.ToArray();
            }
            return primeCache;
        }

        private static int GetLCM(int num0, int num1)
        {
            return (int)((long)num0 * num1 /GetGCD(num0, num1));
        }

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

        static List<int> GetAllPrimes(int n)
        {
            var isNotPrimes = new bool[n+1];
            var primes = new List<int>();
            for(var i = 2;i<=n;i++)
            {
                if (!isNotPrimes[i])
                {
                    primes.Add(i);
                    var num = i * 2;
                    while(num <= n)
                    {
                        isNotPrimes[num]= true;
                        num+=i;
                    }
                }
            }
            return primes;
        }

        static List<(int,int)> GetPrimeFactors(int num, List<int> primes)
        {
            var primeFactors = new List<(int,int)>();
            foreach(var prime in primes)
            {
                if (num < prime * prime) break;
                var cnt = 0;
                while(num % prime == 0)
                {
                    cnt++;
                    num/=prime;
                }
                if (cnt > 0)
                {
                    primeFactors.Add((prime, cnt));
                }
            }
            if (num!=1)
            {
                primeFactors.Add((num, 1));
            }
            return primeFactors;
        }

        static int[] GetFactors(int num, List<int> primes)
        {
            return GetFactors(GetPrimeFactors(num, primes));
        }

        static int[] GetFactors(List<(int,int)> primeFactors)
        {
            var factorCnt = 1;
            foreach(var (_, cnt) in primeFactors)
            {
                factorCnt*=cnt+1;
            }
            var factors = new int[factorCnt];
            var preCnt = 1;
            var index = 1;
            factors[0] = 1;
            foreach(var (prime, cnt) in primeFactors)
            {
                var factor = prime;
                for(var i = 1;i<=cnt;i++)
                {
                    for(var j = 0;j<preCnt;j++)
                    {
                        factors[index++] = factors[j] * factor;
                    }
                    factor *= prime;
                }
                preCnt = index;
            }
            return factors;
        }

    }
}


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

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

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

        private static int Solve(string[] args)
        {
            string s = reader.ReadLine();

            int ans = 0;
            bool p = true;
            int n = 0;
            foreach (char c in s)
            {
                if (c == '-' || c == '+')
                {
                    ans += p ? n : -n;
                    n = 0;

                    if (c == '-')
                        p = false;
                    else if (c == '+')
                        p = true;
                }

                n = n*10 + (c - '0');
            }

            ans += p ? n : -n;
            return ans;
        }
    }
}


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

namespace ConsoleApp3
{
    delegate int s(int a);
    class Program
    {
        static void Main(string[] args)
        {
           var expression= Console.ReadLine();
            long result = 0, cur = 0;
            int sign = +1;
            foreach(char c in expression)
            {
                if (c == '+' || c == '-')
                {
                    result += sign * cur;
                    cur = 0;
                }
                if (c == '-')
                    sign = -1;
                if (c == '+')
                    sign = +1;
                // bug: + and - signs are accumulated into the number
                cur = cur * 10 + (c - '0');
            }
            result += sign * cur;
            Console.WriteLine(result);
            Console.ReadLine();
        }

    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static System.Math;
using System.Text;
using System.Threading;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Library;

namespace Program
{
    public static class ProblemC
    {
        static bool SAIKI = false;
        static public int numberOfRandomCases = 0;
        static public void MakeTestCase(List<string> _input, List<string> _output, ref Func<string[], bool> _outputChecker)
        {
        }
        static public void Solve()
        {
            var n = NN;
            var x = NN;
            var pos = NN;
            LIB_Mod ans = 1;
            var left = 0L;
            var right = n;
            var upperx = n - x;
            var downerx = n - upperx - 1;
            while (left < right)
            {
                var mid = (left + right) / 2;
                if (mid > pos)
                {
                    ans *= upperx;
                    upperx -= 1;
                    right = mid;
                }
                else if (mid < pos)
                {
                    ans *= downerx;
                    downerx -= 1;
                    left = mid + 1;
                }
                else
                {
                    left = mid + 1;
                }
            }
            var zan = upperx + downerx;
            if (zan > 0)
            {
                ans *= LIB_Mod.Perm(zan, zan);
            }
            Console.WriteLine(ans);
        }
        class Printer : StreamWriter
        {
            public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
            public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { base.AutoFlush = false; }
            public Printer(Stream stream, Encoding encoding) : base(stream, encoding) { base.AutoFlush = false; }
        }
        static LIB_FastIO fastio = new LIB_FastIODebug();
        static public void Main(string[] args) { if (args.Length == 0) { fastio = new LIB_FastIO(); Console.SetOut(new Printer(Console.OpenStandardOutput())); } if (SAIKI) { var t = new Thread(Solve, 134217728); t.Start(); t.Join(); } else Solve(); Console.Out.Flush(); }
        static long NN => fastio.Long();
        static double ND => fastio.Double();
        static string NS => fastio.Scan();
        static long[] NNList(long N) => Repeat(0, N).Select(_ => NN).ToArray();
        static double[] NDList(long N) => Repeat(0, N).Select(_ => ND).ToArray();
        static string[] NSList(long N) => Repeat(0, N).Select(_ => NS).ToArray();
        static long Count<T>(this IEnumerable<T> x, Func<T, bool> pred) => Enumerable.Count(x, pred);
        static IEnumerable<T> Repeat<T>(T v, long n) => Enumerable.Repeat<T>(v, (int)n);
        static IEnumerable<int> Range(long s, long c) => Enumerable.Range((int)s, (int)c);
        static IOrderedEnumerable<T> OrderByRand<T>(this IEnumerable<T> x) => Enumerable.OrderBy(x, _ => xorshift);
        static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> x) => Enumerable.OrderBy(x.OrderByRand(), e => e);
        static IOrderedEnumerable<T1> OrderBy<T1, T2>(this IEnumerable<T1> x, Func<T1, T2> selector) => Enumerable.OrderBy(x.OrderByRand(), selector);
        static IOrderedEnumerable<T> OrderByDescending<T>(this IEnumerable<T> x) => Enumerable.OrderByDescending(x.OrderByRand(), e => e);
        static IOrderedEnumerable<T1> OrderByDescending<T1, T2>(this IEnumerable<T1> x, Func<T1, T2> selector) => Enumerable.OrderByDescending(x.OrderByRand(), selector);
        static IOrderedEnumerable<string> OrderBy(this IEnumerable<string> x) => x.OrderByRand().OrderBy(e => e, StringComparer.OrdinalIgnoreCase);
        static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> x, Func<T, string> selector) => x.OrderByRand().OrderBy(selector, StringComparer.OrdinalIgnoreCase);
        static IOrderedEnumerable<string> OrderByDescending(this IEnumerable<string> x) => x.OrderByRand().OrderByDescending(e => e, StringComparer.OrdinalIgnoreCase);
        static IOrderedEnumerable<T> OrderByDescending<T>(this IEnumerable<T> x, Func<T, string> selector) => x.OrderByRand().OrderByDescending(selector, StringComparer.OrdinalIgnoreCase);
        static string Join<T>(this IEnumerable<T> x, string separator = "") => string.Join(separator, x);
        static uint xorshift { get { _xsi.MoveNext(); return _xsi.Current; } }
        static IEnumerator<uint> _xsi = _xsc();
        static IEnumerator<uint> _xsc() { uint x = 123456789, y = 362436069, z = 521288629, w = (uint)(DateTime.Now.Ticks & 0xffffffff); while (true) { var t = x ^ (x << 11); x = y; y = z; z = w; w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); yield return w; } }
        static bool Chmax<T>(this ref T lhs, T rhs) where T : struct, IComparable<T> { if (lhs.CompareTo(rhs) < 0) { lhs = rhs; return true; } return false; }
        static bool Chmin<T>(this ref T lhs, T rhs) where T : struct, IComparable<T> { if (lhs.CompareTo(rhs) > 0) { lhs = rhs; return true; } return false; }
        static void Fill<T>(this T[] array, T value) => array.AsSpan().Fill(value);
        static void Fill<T>(this T[,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0], array.Length).Fill(value);
        static void Fill<T>(this T[,,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0, 0], array.Length).Fill(value);
        static void Fill<T>(this T[,,,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0, 0, 0], array.Length).Fill(value);
    }
}
namespace Library {
    partial struct LIB_Mod : IEquatable<LIB_Mod>, IEquatable<long>
    {
        static public long _mod = 1000000007; long v;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_Mod(long x)
        {
            if (x < _mod && x >= 0) v = x;
            else if ((v = x % _mod) < 0) v += _mod;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public implicit operator LIB_Mod(long x) => new LIB_Mod(x);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public implicit operator long(LIB_Mod x) => x.v;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Add(LIB_Mod x) { if ((v += x.v) >= _mod) v -= _mod; }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Sub(LIB_Mod x) { if ((v -= x.v) < 0) v += _mod; }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Mul(LIB_Mod x) => v = (v * x.v) % _mod;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Div(LIB_Mod x) => v = (v * Inverse(x.v)) % _mod;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod operator +(LIB_Mod x, LIB_Mod y) { var t = x.v + y.v; return t >= _mod ? new LIB_Mod { v = t - _mod } : new LIB_Mod { v = t }; }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod operator -(LIB_Mod x, LIB_Mod y) { var t = x.v - y.v; return t < 0 ? new LIB_Mod { v = t + _mod } : new LIB_Mod { v = t }; }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod operator *(LIB_Mod x, LIB_Mod y) => x.v * y.v;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod operator /(LIB_Mod x, LIB_Mod y) => x.v * Inverse(y.v);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public bool operator ==(LIB_Mod x, LIB_Mod y) => x.v == y.v;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public bool operator !=(LIB_Mod x, LIB_Mod y) => x.v != y.v;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long Inverse(long x)
        {
            long b = _mod, r = 1, u = 0, t = 0;
            while (b > 0)
            {
                var q = x / b;
                t = u;
                u = r - q * u;
                r = t;
                t = b;
                b = x - q * b;
                x = t;
            }
            return r < 0 ? r + _mod : r;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(LIB_Mod x) => v == x.v;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public bool Equals(long x) => v == x;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override bool Equals(object x) => x == null ? false : Equals((LIB_Mod)x);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override int GetHashCode() => v.GetHashCode();
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override string ToString() => v.ToString();
        static List<LIB_Mod> _fact = new List<LIB_Mod>() { 1 };
        static long _factm = _mod;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static void B(long n)
        {
            if (_factm != _mod) _fact = new List<LIB_Mod>() { 1 };
            if (n >= _fact.Count)
                for (int i = _fact.Count; i <= n; ++i)
                    _fact.Add(_fact[i - 1] * i);
            _factm = _mod;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod Comb(long n, long k)
        {
            B(n);
            if (n == 0 && k == 0) return 1;
            if (n < k || n < 0) return 0;
            return _fact[(int)n] / _fact[(int)(n - k)] / _fact[(int)k];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod CombOK(long n, long k)
        {
            LIB_Mod ret = 1;
            for (var i = 0; i < k; i++) ret *= n - i;
            for (var i = 1; i <= k; i++) ret /= i;
            return ret;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod Perm(long n, long k)
        {
            B(n);
            if (n == 0 && k == 0) return 1;
            if (n < k || n < 0) return 0;
            return _fact[(int)n] / _fact[(int)(n - k)];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod KanzenPerm(long n) => Enumerable.Range(0, (int)n + 1).Aggregate((LIB_Mod)0, (a, e) => a + (1 - ((e & 1) << 1)) * LIB_Mod.Comb(n, e) * LIB_Mod.Perm(n - e, n - e));
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public LIB_Mod Pow(LIB_Mod x, long y)
        {
            LIB_Mod a = 1;
            while (y != 0)
            {
                if ((y & 1) == 1) a.Mul(x);
                x.Mul(x);
                y >>= 1;
            }
            return a;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long[] LogBuild(long a)
        {
            var ret = new long[_mod];
            ret[1] = 0;
            for (var i = 1; i < _mod; i++)
            {
                ret[a] = i;
                a *= 2;
                a %= _mod;
            }
            return ret;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long Log(long a, long b)
        {
            var g = 1L;
            for (var i = _mod; i != 0; i >>= 1)
            {
                g *= a;
                g %= _mod;
            }
            g = LIB_Math.GCD(g, _mod);
            var t = 1L;
            var c = 0L;
            for (; t % g != 0; ++c)
            {
                if (t == b) return c;
                t *= a;
                t %= _mod;
            }
            if (b % g != 0) return -1;
            t /= g;
            b /= g;
            var n = _mod / g;
            var h = 0L;
            var gs = 1L;
            for (; h * h < n; ++h)
            {
                gs *= a;
                gs %= n;
            }
            var bs = new Dictionary<long, long>();
            for (long s = 0L, e = b; s < h; bs[e] = ++s)
            {
                e *= a;
                e %= n;
            }
            for (long s = 0L, e = t; s < n;)
            {
                e *= gs;
                e %= n;
                s += h;
                if (bs.ContainsKey(e) && bs[e] > 0) return c + s - bs[e];
            }
            return -1;
        }
    }
    class LIB_FastIO
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_FastIO() { str = Console.OpenStandardInput(); }
        readonly Stream str;
        readonly byte[] buf = new byte[2048];
        int len, ptr;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        byte read()
        {
            if (ptr >= len)
            {
                ptr = 0;
                if ((len = str.Read(buf, 0, 2048)) <= 0)
                {
                    return 0;
                }
            }
            return buf[ptr++];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        char Char()
        {
            byte b = 0;
            do b = read();
            while (b < 33 || 126 < b);
            return (char)b;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        virtual public string Scan()
        {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
                sb.Append(b);
            return sb.ToString();
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        virtual public long Long()
        {
            long ret = 0; byte b = 0; var ng = false;
            do b = read();
            while (b != '-' && (b < '0' || '9' < b));
            if (b == '-') { ng = true; b = read(); }
            for (; true; b = read())
            {
                if (b < '0' || '9' < b)
                    return ng ? -ret : ret;
                else ret = (ret << 3) + (ret << 1) + b - '0';
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        virtual public double Double() { return double.Parse(Scan(), CultureInfo.InvariantCulture); }
    }
    class LIB_FastIODebug : LIB_FastIO
    {
        Queue<string> param = new Queue<string>();
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        string NextString() { if (param.Count == 0) foreach (var item in Console.ReadLine().Split(' ')) param.Enqueue(item); return param.Dequeue(); }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public LIB_FastIODebug() { }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override string Scan() => NextString();
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override long Long() => long.Parse(NextString());
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override double Double() => double.Parse(NextString());
    }
    class LIB_Math
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public IEnumerable<long> Primes(long x)
        {
            if (x < 2) yield break;
            yield return 2;
            var halfx = x / 2;
            var table = new bool[halfx + 1];
            var max = (long)(Math.Sqrt(x) / 2);
            for (long i = 1; i <= max; ++i)
            {
                if (table[i]) continue;
                var add = 2 * i + 1;
                yield return add;
                for (long j = 2 * i * (i + 1); j <= halfx; j += add)
                    table[j] = true;
            }
            for (long i = max + 1; i <= halfx; ++i)
                if (!table[i] && 2 * i + 1 <= x)
                    yield return 2 * i + 1;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public IEnumerable<long> Factors(long x)
        {
            if (x < 2) yield break;
            while (x % 2 == 0)
            {
                x /= 2; yield return 2;
            }
            var max = (long)Math.Sqrt(x);
            for (long i = 3; i <= max; i += 2)
            {
                while (x % i == 0)
                {
                    x /= i; yield return i;
                }
            }
            if (x != 1) yield return x;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public IEnumerable<long> Divisor(long x)
        {
            if (x < 1) yield break;
            var max = (long)Math.Sqrt(x);
            for (long i = 1; i <= max; ++i)
            {
                if (x % i != 0) continue;
                yield return i;
                if (i != x / i) yield return x / i;
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long GCD(long a, long b)
        {
            while (b > 0)
            {
                var tmp = b;
                b = a % b;
                a = tmp;
            }
            return a;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long LCM(long a, long b) => a / GCD(a, b) * b;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long Pow(long x, long y)
        {
            long a = 1;
            while (y != 0)
            {
                if ((y & 1) == 1) a *= x;
                if (x < long.MaxValue / x) x *= x;
                y >>= 1;
            }
            return a;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public decimal Sqrt(decimal x)
        {
            decimal prev, cur = (decimal)Math.Sqrt((double)x);
            do
            {
                prev = cur;
                if (prev == 0) return 0;
                cur = (prev + x / prev) / 2;
            } while (cur != prev);
            return cur;
        }
        static List<long> _fact = new List<long>() { 1 };
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static void Build(long n)
        {
            if (n >= _fact.Count)
                for (int i = _fact.Count; i <= n; ++i) _fact.Add(_fact[i - 1] * i);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long Comb(long n, long k)
        {
            Build(n);
            if (n == 0 && k == 0) return 1;
            if (n < k || n < 0) return 0;
            return _fact[(int)n] / _fact[(int)(n - k)] / _fact[(int)k];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public long Perm(long n, long k)
        {
            Build(n);
            if (n == 0 && k == 0) return 1;
            if (n < k || n < 0) return 0;
            return _fact[(int)n] / _fact[(int)(n - k)];
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public IEnumerable<List<int>> MakePermutation(long n, bool zeroIndexed = true)
        {
            if (n <= 0) throw new Exception();
            var c = new int[n];
            var a = new int[n];
            if (!zeroIndexed) a[0] = 1;
            for (var i = 1; i < n; i++) a[i] = a[i - 1] + 1;
            yield return new List<int>(a);
            for (var i = 0; i < n;)
            {
                if (c[i] < i)
                {
                    if (i % 2 == 0)
                    {
                        var t = a[0]; a[0] = a[i]; a[i] = t;
                    }
                    else
                    {
                        var t = a[c[i]]; a[c[i]] = a[i]; a[i] = t;
                    }
                    yield return new List<int>(a);
                    ++c[i];
                    i = 0;
                }
                else
                {
                    c[i] = 0;
                    ++i;
                }
            }
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public bool NextPermutation(long[] ary)
        {
            var n = ary.Length;
            var i = n - 1;
            while (i - 1 >= 0 && ary[i - 1] > ary[i]) --i;
            if (i == 0) return false;
            var j = i;
            while (j + 1 < n && ary[i - 1] < ary[j + 1]) ++j;
            var tmp = ary[i - 1]; ary[i - 1] = ary[j]; ary[j] = tmp;
            var s = i;
            var t = n - 1;
            while (t - s > 0)
            {
                tmp = ary[t]; ary[t] = ary[s]; ary[s] = tmp;
                ++s; --t;
            }
            return true;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public (long, long) InvGCD(long a, long b)
        {
            a = (a + b) % b;
            if (a == 0) return (b, 0);
            var s = b;
            var t = a;
            var m0 = 0L;
            var m1 = 1L;
            while (t > 0)
            {
                var u = s / t; s -= t * u; m0 -= m1 * u;
                var tmp = s; s = t; t = tmp;
                tmp = m0; m0 = m1; m1 = tmp;
            }
            if (m0 < 0) m0 += b / s;
            return (s, m0);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static public (long, long) CRT(long[] r, long[] m)
        {
            var r0 = 0L;
            var m0 = 1L;
            for (var i = 0; i < m.Length; i++)
            {
                var m1 = m[i];
                var r1 = (r[i] + m1) % m1;
                if (m0 < m1)
                {
                    r0 ^= r1; r1 ^= r0; r0 ^= r1;
                    m0 ^= m1; m1 ^= m0; m0 ^= m1;
                }
                if (m0 % m1 == 0)
                {
                    if (r0 % m1 != r1) return (0, 0);
                    continue;
                }
                var gim = InvGCD(m0, m1);
                var u1 = m1 / gim.Item1;
                if ((r1 - r0) % gim.Item1 != 0) return (0, 0);
                var x = (r1 - r0) / gim.Item1 % u1 * gim.Item2 % u1;
                r0 += x * m0;
                m0 *= u1;
                if (r0 < 0) r0 += m0;
            }
            return (r0, m0);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
        static public long FloorSum(long n, long m, long a, long b)
        {
            var ans = 0L;
            while (true)
            {
                if (a >= m)
                {
                    ans += (n - 1) * n * (a / m) / 2;
                    a %= m;
                }
                if (b >= m)
                {
                    ans += n * (b / m);
                    b %= m;
                }
                var ymax = (a * n + b) / m;
                if (ymax == 0) return ans;
                var xmax = ymax * m - b;
                ans += (n - (xmax + a - 1) / a) * ymax;
                n = ymax;
                a ^= m; m ^= a; a ^= m;
                b = (m - xmax % m) % m;
            }
        }
    }
}


using System;
using System.Linq;

namespace Mycop
{
    class Program
    {
        static void Main()
        {
            var numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
            var n = numbers[0];
            var x = numbers[1];
            var pos = numbers[2];

            var smaller = x - 1;
            var bigger = n - x;
            var result = 1L;

            var left = 0;
            var right = n;
            while (left < right)
            {
                var mid = (left + right) / 2;
                if (mid == pos)
                    left = mid + 1;
                else if (mid < pos)
                {
                    result *= smaller;
                    result %= 1000000007;
                    smaller--;
                    left = mid + 1;
                }
                else
                {
                    result *= bigger;
                    result %= 1000000007;
                    bigger--;
                    right = mid;
                }

                if (smaller < 0 || bigger < 0)
                {
                    Console.WriteLine(0);
                    return;
                }
            }

            for (var i = 1; i <= smaller + bigger; i++)
            {
                result *= i;
                result %= 1000000007;
            }
            Console.WriteLine(result);
        }
    }
}


using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
using CodeforcesRound678Div2.Questions;
using ModInt = CodeforcesRound678Div2.Questions.StaticModInt<CodeforcesRound678Div2.Questions.Mod1000000007>;

namespace CodeforcesRound678Div2.Questions
{
    public class QuestionC : AtCoderQuestionBase
    {
        [MethodImpl(MethodImplOptions.AggressiveOptimization)]
        public override void Solve(IOManager io)
        {
            var n = io.ReadInt();
            var x = io.ReadInt();
            var pos = io.ReadInt();

            var more = n - x;
            var less = x - 1;

            var left = 0;
            var right = n;
            ModInt result = ModInt.One;

            while (left < right)
            {
                var middle = (left + right) / 2;

                if (middle > pos)
                {
                    if (more > 0)
                    {
                        result *= ModInt.Raw(more);
                        more--;
                    }
                    else
                    {
                        result = ModInt.Zero;
                    }
                    right = middle;
                }
                else if (middle < pos)
                {
                    if (less > 0)
                    {
                        result *= ModInt.Raw(less);
                        less--;
                    }
                    else
                    {
                        result = ModInt.Zero;
                    }
                    left = middle + 1;
                }
                else
                {
                    left = middle + 1;
                }
            }

            for (int i = 1; i <= more + less; i++)
            {
                result *= ModInt.Raw(i);
            }

            io.WriteLine(result);
        }
    }

    ///
    /// コンパイル時に決定する mod を表します。
    ///
    /// <example>
    ///
    /// public readonly struct Mod1000000009 : IStaticMod
    /// {
    ///     public uint Mod => 1000000009;
    ///     public bool IsPrime => true;
    /// }
    ///
    /// </example>
    public interface IStaticMod
    {
        ///
        /// mod を取得します。
        ///
        uint Mod { get; }

        ///
        /// mod が素数であるか識別します。
        ///
        bool IsPrime { get; }
    }

    public readonly struct Mod1000000007 : IStaticMod
    {
        public uint Mod => 1000000007;
        public bool IsPrime => true;
    }

    public readonly struct Mod998244353 : IStaticMod
    {
        public uint Mod => 998244353;
        public bool IsPrime => true;
    }

    ///
    /// 実行時に決定する mod の ID を表します。
    ///
    /// <example>
    ///
    /// public readonly struct ModID123 : IDynamicModID { }
    ///
    /// </example>
    public interface IDynamicModID { }

    public readonly struct ModID0 : IDynamicModID { }
    public readonly struct ModID1 : IDynamicModID { }
    public readonly struct ModID2 : IDynamicModID { }

    ///
    /// 四則演算時に自動で mod を取る整数型。mod の値はコンパイル時に決定している必要があります。
    ///
    /// <typeparam name="T">定数 mod を表す構造体</typeparam>
    /// <example>
    ///
    /// using ModInt = AtCoder.StaticModInt<AtCoder.Mod1000000007>;
    ///
    /// void SomeMethod()
    /// {
    ///     var m = new ModInt(1);
    ///     m -= 2;
    ///     Console.WriteLine(m);   // 1000000006
    /// }
    ///
    /// </example>
    public readonly struct StaticModInt<T> : IEquatable<StaticModInt<T>> where T : struct, IStaticMod
    {
        private readonly uint _v;

        ///
        /// 格納されている値を返します。
        ///
        public int Value => (int)_v;

        ///
        /// mod を返します。
        ///
        public static int Mod => (int)default(T).Mod;

        public static StaticModInt<T> Zero => new StaticModInt<T>();
        public static StaticModInt<T> One => new StaticModInt<T>(1u);

        ///
        /// <paramref name="v"/> に対して mod を取らずに StaticModInt<<typeparamref name="T"/>> 型のインスタンスを生成します。
        ///
        /// <remarks>
        /// <para>定数倍高速化のための関数です。 <paramref name="v"/> に 0 未満または mod 以上の値を入れた場合の挙動は未定義です。</para>
        /// <para>制約: 0≤|<paramref name="v"/>|<mod</para>
        /// </remarks>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static StaticModInt<T> Raw(int v)
        {
            var u = unchecked((uint)v);
            Debug.Assert(u < Mod);
            return new StaticModInt<T>(u);
        }

        ///
        /// StaticModInt<<typeparamref name="T"/>> 型のインスタンスを生成します。
        ///
        /// <remarks>
        /// <paramref name="v"/>が 0 未満、もしくは mod 以上の場合、自動で mod を取ります。
        /// </remarks>
        public StaticModInt(long v) : this(Round(v)) { }

        private StaticModInt(uint v) => _v = v;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static uint Round(long v)
        {
            var x = v % default(T).Mod;
            if (x < 0)
            {
                x += default(T).Mod;
            }
            return (uint)x;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static StaticModInt<T> operator ++(StaticModInt<T> value)
        {
            var v = value._v + 1;
            if (v == default(T).Mod)
            {
                v = 0;
            }
            return new StaticModInt<T>(v);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static StaticModInt<T> operator --(StaticModInt<T> value)
        {
            var v = value._v;
            if (v == 0)
            {
                v = default(T).Mod;
            }
            return new StaticModInt<T>(v - 1);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static StaticModInt<T> operator +(StaticModInt<T> lhs, StaticModInt<T> rhs)
        {
            var v = lhs._v + rhs._v;
            if (v >= default(T).Mod)
            {
                v -= default(T).Mod;
            }
            return new StaticModInt<T>(v);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static StaticModInt<T> operator -(StaticModInt<T> lhs, StaticModInt<T> rhs)
        {
            unchecked
            {
                var v = lhs._v - rhs._v;
                if (v >= default(T).Mod)
                {
                    v += default(T).Mod;
                }
                return new StaticModInt<T>(v);
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static StaticModInt<T> operator *(StaticModInt<T> lhs, StaticModInt<T> rhs)
        {
            return new StaticModInt<T>((uint)((ulong)lhs._v * rhs._v % default(T).Mod));
        }

        ///
        /// 除算を行います。
        ///
        /// <remarks>
        /// <para>- 制約: <paramref name="rhs"/> に乗法の逆元が存在する。（gcd(<paramref name="rhs"/>, mod) = 1）</para>
        /// <para>- 計算量: O(log(mod))</para>
        /// </remarks>
        public static StaticModInt<T> operator /(StaticModInt<T> lhs, StaticModInt<T> rhs) => lhs * rhs.Inverse();

        public static StaticModInt<T> operator +(StaticModInt<T> value) => value;
        public static StaticModInt<T> operator -(StaticModInt<T> value) => new StaticModInt<T>() - value;
        public static bool operator ==(StaticModInt<T> lhs, StaticModInt<T> rhs) => lhs._v == rhs._v;
        public static bool operator !=(StaticModInt<T> lhs, StaticModInt<T> rhs) => lhs._v != rhs._v;
        public static implicit operator StaticModInt<T>(int value) => new StaticModInt<T>(value);
        public static implicit operator StaticModInt<T>(long value) => new StaticModInt<T>(value);

        ///
        /// 自身を x として、x^<paramref name="n"/> を返します。
        ///
        /// <remarks>
        /// <para>制約: 0≤|<paramref name="n"/>|</para>
        /// <para>計算量: O(log(<paramref name="n"/>))</para>
        /// </remarks>
        public StaticModInt<T> Pow(long n)
        {
            Debug.Assert(0 <= n);
            var x = this;
            var r = Raw(1);

            while (n > 0)
            {
                if ((n & 1) > 0)
                {
                    r *= x;
                }
                x *= x;
                n >>= 1;
            }

            return r;
        }

        ///
        /// 自身を x として、 xy≡1 なる y を返します。
        ///
        /// <remarks>
        /// <para>制約: gcd(x, mod) = 1</para>
        /// </remarks>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public StaticModInt<T> Inverse()
        {
            if (default(T).IsPrime)
            {
                Debug.Assert(_v > 0);
                return Pow(default(T).Mod - 2);
            }
            else
            {
                var (g, x) = InternalMath.InvGCD(_v, default(T).Mod);
                Debug.Assert(g == 1);
                return new StaticModInt<T>(x);
            }
        }

        public override string ToString() => _v.ToString();
        public override bool Equals(object obj) => obj is StaticModInt<T> && Equals((StaticModInt<T>)obj);
        public bool Equals(StaticModInt<T> other) => Value == other.Value;
        public override int GetHashCode() => _v.GetHashCode();
    }

    ///
    /// 四則演算時に自動で mod を取る整数型。実行時に mod が決まる場合でも使用可能です。
    ///
    /// <remarks>
    /// 使用前に DynamicModInt<<typeparamref name="T"/>>.Mod に mod の値を設定する必要があります。
    /// </remarks>
    /// <typeparam name="T">mod の ID を表す構造体</typeparam>
    /// <example>
    ///
    /// using AtCoder.ModInt = AtCoder.DynamicModInt<AtCoder.ModID0>;
    ///
    /// void SomeMethod()
    /// {
    ///     ModInt.Mod = 1000000009;
    ///     var m = new ModInt(1);
    ///     m -= 2;
    ///     Console.WriteLine(m);   // 1000000008
    /// }
    ///
    /// </example>
    public readonly struct DynamicModInt<T> : IEquatable<DynamicModInt<T>> where T : struct, IDynamicModID
    {
        private readonly uint _v;
        private static Barrett bt;

        ///
        /// 格納されている値を返します。
        ///
        public int Value => (int)_v;

        ///
        /// mod を返します。
        ///
        public static int Mod
        {
            get => (int)bt.Mod;
            set
            {
                Debug.Assert(1 <= value);
                bt = new Barrett((uint)value);
            }
        }

        ///
        /// <paramref name="v"/> に対して mod を取らずに DynamicModInt<<typeparamref name="T"/>> 型のインスタンスを生成します。
        ///
        /// <remarks>
        /// <para>定数倍高速化のための関数です。 <paramref name="v"/> に 0 未満または mod 以上の値を入れた場合の挙動は未定義です。</para>
        /// <para>制約: 0≤|<paramref name="v"/>|<mod</para>
        /// </remarks>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static DynamicModInt<T> Raw(int v)
        {
            var u = unchecked((uint)v);
            Debug.Assert(bt != null, $"使用前に {nameof(DynamicModInt<T>)}<{nameof(T)}>.{nameof(Mod)} プロパティに mod の値を設定してください。");
            Debug.Assert(u < Mod);
            return new DynamicModInt<T>(u);
        }

        ///
        /// DynamicModInt<<typeparamref name="T"/>> 型のインスタンスを生成します。
        ///
        /// <remarks>
        /// <para>- 使用前に DynamicModInt<<typeparamref name="T"/>>.Mod に mod の値を設定する必要があります。</para>
        /// <para>- <paramref name="v"/> が 0 未満、もしくは mod 以上の場合、自動で mod を取ります。</para>
        /// </remarks>
        public DynamicModInt(long v) : this(Round(v)) { }

        private DynamicModInt(uint v) => _v = v;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static uint Round(long v)
        {
            Debug.Assert(bt != null, $"使用前に {nameof(DynamicModInt<T>)}<{nameof(T)}>.{nameof(Mod)} プロパティに mod の値を設定してください。");
            var x = v % bt.Mod;
            if (x < 0)
            {
                x += bt.Mod;
            }
            return (uint)x;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static DynamicModInt<T> operator ++(DynamicModInt<T> value)
        {
            var v = value._v + 1;
            if (v == bt.Mod)
            {
                v = 0;
            }
            return new DynamicModInt<T>(v);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static DynamicModInt<T> operator --(DynamicModInt<T> value)
        {
            var v = value._v;
            if (v == 0)
            {
                v = bt.Mod;
            }
            return new DynamicModInt<T>(v - 1);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static DynamicModInt<T> operator +(DynamicModInt<T> lhs, DynamicModInt<T> rhs)
        {
            var v = lhs._v + rhs._v;
            if (v >= bt.Mod)
            {
                v -= bt.Mod;
            }
            return new DynamicModInt<T>(v);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static DynamicModInt<T> operator -(DynamicModInt<T> lhs, DynamicModInt<T> rhs)
        {
            unchecked
            {
                var v = lhs._v - rhs._v;
                if (v >= bt.Mod)
                {
                    v += bt.Mod;
                }
                return new DynamicModInt<T>(v);
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static DynamicModInt<T> operator *(DynamicModInt<T> lhs, DynamicModInt<T> rhs)
        {
            uint z = bt.Mul(lhs._v, rhs._v);
            return new DynamicModInt<T>(z);
        }

        ///
        /// 除算を行います。
        ///
        /// <remarks>
        /// <para>- 制約: <paramref name="rhs"/> に乗法の逆元が存在する。（gcd(<paramref name="rhs"/>, mod) = 1）</para>
        /// <para>- 計算量: O(log(mod))</para>
        /// </remarks>
        public static DynamicModInt<T> operator /(DynamicModInt<T> lhs, DynamicModInt<T> rhs) => lhs * rhs.Inverse();

        public static DynamicModInt<T> operator +(DynamicModInt<T> value) => value;
        public static DynamicModInt<T> operator -(DynamicModInt<T> value) => new DynamicModInt<T>() - value;
        public static bool operator ==(DynamicModInt<T> lhs, DynamicModInt<T> rhs) => lhs._v == rhs._v;
        public static bool operator !=(DynamicModInt<T> lhs, DynamicModInt<T> rhs) => lhs._v != rhs._v;
        public static implicit operator DynamicModInt<T>(int value) => new DynamicModInt<T>(value);
        public static implicit operator DynamicModInt<T>(long value) => new DynamicModInt<T>(value);

        ///
        /// 自身を x として、x^<paramref name="n"/> を返します。
        ///
        /// <remarks>
        /// <para>制約: 0≤|<paramref name="n"/>|</para>
        /// <para>計算量: O(log(<paramref name="n"/>))</para>
        /// </remarks>
        public DynamicModInt<T> Pow(long n)
        {
            Debug.Assert(0 <= n);
            var x = this;
            var r = Raw(1);

            while (n > 0)
            {
                if ((n & 1) > 0)
                {
                    r *= x;
                }
                x *= x;
                n >>= 1;
            }

            return r;
        }

        ///
        /// 自身を x として、 xy≡1 なる y を返します。
        ///
        /// <remarks>
        /// <para>制約: gcd(x, mod) = 1</para>
        /// </remarks>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public DynamicModInt<T> Inverse()
        {
            var (g, x) = InternalMath.InvGCD(_v, bt.Mod);
            Debug.Assert(g == 1);
            return new DynamicModInt<T>(x);
        }

        public override string ToString() => _v.ToString();
        public override bool Equals(object obj) => obj is DynamicModInt<T> && Equals((DynamicModInt<T>)obj);
        public bool Equals(DynamicModInt<T> other) => Value == other.Value;
        public override int GetHashCode() => _v.GetHashCode();
    }

    ///
    /// Fast moduler by barrett reduction
    /// <seealso href="https://en.wikipedia.org/wiki/Barrett_reduction"/>
    ///
    public class Barrett
    {
        public uint Mod { get; private set; }
        private ulong IM;
        public Barrett(uint m)
        {
            Mod = m;
            IM = unchecked((ulong)-1) / m + 1;
        }

        ///
        /// <paramref name="a"/> * <paramref name="b"/> mod m
        ///
        public uint Mul(uint a, uint b)
        {
            ulong z = a;
            z *= b;
            if (!Bmi2.X64.IsSupported) return (uint)(z % Mod);
            var x = Bmi2.X64.MultiplyNoFlags(z, IM);
            var v = unchecked((uint)(z - x * Mod));
            if (Mod <= v) v += Mod;
            return v;
        }
    }

    public static class InternalMath
    {
        ///
        /// g=gcd(a,b),xa=g(mod b) となるような 0≤x<b/g の(g, x)
        ///
        /// <remarks>
        /// <para>制約: 1≤<paramref name="b"/></para>
        /// </remarks>
        public static (long, long) InvGCD(long a, long b)
        {
            a = SafeMod(a, b);
            if (a == 0) return (b, 0);

            long s = b, t = a;
            long m0 = 0, m1 = 1;

            long u;
            while (true)
            {
                if (t == 0)
                {
                    if (m0 < 0) m0 += b / s;
                    return (s, m0);
                }
                u = s / t;
                s -= t * u;
                m0 -= m1 * u;

                if (s == 0)
                {
                    if (m1 < 0) m1 += b / t;
                    return (t, m1);
                }
                u = t / s;
                t -= s * u;
                m1 -= m0 * u;
            }
        }

        public static long SafeMod(long x, long m)
        {
            x %= m;
            if (x < 0) x += m;
            return x;
        }
    }

    public class ModCombination<T> where T : struct, IStaticMod
    {
        readonly StaticModInt<T>[] _factorials;
        readonly StaticModInt<T>[] _invFactorials;

        public ModCombination(int max = 1000000)
        {
            if (max >= default(T).Mod)
            {
                ThrowArgumentOutOfRangeException();
            }

            _factorials = new StaticModInt<T>[max + 1];
            _invFactorials = new StaticModInt<T>[max + 1];

            _factorials[0] = _factorials[1] = StaticModInt<T>.Raw(1);
            _invFactorials[0] = _invFactorials[1] = StaticModInt<T>.Raw(1);

            for (int i = 2; i < _factorials.Length; i++)
            {
                _factorials[i] = _factorials[i - 1] * StaticModInt<T>.Raw(i);
            }

            _invFactorials[^1] = _factorials[^1].Inverse();

            for (int i = _invFactorials.Length - 2; i >= 0; i--)
            {
                _invFactorials[i] = _invFactorials[i + 1] * StaticModInt<T>.Raw(i + 1);
            }
        }

        public StaticModInt<T> Factorial(int n) => _factorials[n];

        public StaticModInt<T> Permutation(int n, int k) => _factorials[n] * _invFactorials[n - k];

        public StaticModInt<T> Combination(int n, int k) => _factorials[n] * _invFactorials[k] * _invFactorials[n - k];

        public StaticModInt<T> CombinationWithRepetition(int n, int k) => Combination(n + k - 1, k);

        public void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException();
    }
}

namespace CodeforcesRound678Div2
{
    class Program
    {
        static void Main(string[] args)
        {
            IAtCoderQuestion question = new QuestionC();
            using var io = new IOManager(Console.OpenStandardInput(), Console.OpenStandardOutput());
            question.Solve(io);
        }
    }
}

#region Base Class

namespace CodeforcesRound678Div2.Questions
{
    public interface IAtCoderQuestion
    {
        string Solve(string input);
        void Solve(IOManager io);
    }

    public abstract class AtCoderQuestionBase : IAtCoderQuestion
    {
        public string Solve(string input)
        {
            var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(input));
            var outputStream = new MemoryStream();
            using var manager = new IOManager(inputStream, outputStream);

            Solve(manager);
            manager.Flush();

            outputStream.Seek(0, SeekOrigin.Begin);
            var reader = new StreamReader(outputStream);
            return reader.ReadToEnd();
        }

        public abstract void Solve(IOManager io);
    }
}

#endregion

#region Utils

namespace CodeforcesRound678Div2
{
    public class IOManager : IDisposable
    {
        private readonly BinaryReader _reader;
        private readonly StreamWriter _writer;
        private bool _disposedValue;
        private byte[] _buffer = new byte[1024];
        private int _length;
        private int _cursor;
        private bool _eof;

        const char ValidFirstChar = '!';
        const char ValidLastChar = '~';

        public IOManager(Stream input, Stream output)
        {
            _reader = new BinaryReader(input);
            _writer = new StreamWriter(output) { AutoFlush = false };
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private char ReadAscii()
        {
            if (_cursor == _length)
            {
                _cursor = 0;
                _length = _reader.Read(_buffer);

                if (_length == 0)
                {
                    if (!_eof)
                    {
                        _eof = true;
                        return char.MinValue;
                    }
                    else
                    {
                        ThrowEndOfStreamException();
                    }
                }
            }

            return (char)_buffer[_cursor++];
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public char ReadChar()
        {
            char c;
            while (!IsValidChar(c = ReadAscii())) { }
            return c;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public string ReadString()
        {
            var builder = new StringBuilder();
            char c;
            while (!IsValidChar(c = ReadAscii())) { }

            do
            {
                builder.Append(c);
            } while (IsValidChar(c = ReadAscii()));

            return builder.ToString();
        }

        public int ReadInt() => (int)ReadLong();

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public long ReadLong()
        {
            long result = 0;
            bool isPositive = true;
            char c;

            while (!IsNumericChar(c = ReadAscii())) { }

            if (c == '-')
            {
                isPositive = false;
                c = ReadAscii();
            }

            do
            {
                result *= 10;
                result += c - '0';
            } while (IsNumericChar(c = ReadAscii()));

            return isPositive ? result : -result;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private Span<char> ReadChunk(Span<char> span)
        {
            var i = 0;
            char c;
            while (!IsValidChar(c = ReadAscii())) { }

            do
            {
                span[i++] = c;
            } while (IsValidChar(c = ReadAscii()));

            return span.Slice(0, i);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public double ReadDouble() => double.Parse(ReadChunk(stackalloc char[32]));

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public decimal ReadDecimal() => decimal.Parse(ReadChunk(stackalloc char[32]));

        public int[] ReadIntArray(int n)
        {
            var a = new int[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadInt();
            }
            return a;
        }

        public long[] ReadLongArray(int n)
        {
            var a = new long[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadLong();
            }
            return a;
        }

        public double[] ReadDoubleArray(int n)
        {
            var a = new double[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadDouble();
            }
            return a;
        }

        public decimal[] ReadDecimalArray(int n)
        {
            var a = new decimal[n];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = ReadDecimal();
            }
            return a;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void WriteLine<T>(T value) => _writer.WriteLine(value.ToString());

        public void WriteLine<T>(IEnumerable<T> values, char separator)
        {
            var e = values.GetEnumerator();
            if (e.MoveNext())
            {
                _writer.Write(e.Current.ToString());

                while (e.MoveNext())
                {
                    _writer.Write(separator);
                    _writer.Write(e.Current.ToString());
                }
            }

            _writer.WriteLine();
        }

        public void WriteLine<T>(Span<T> values, char separator) => WriteLine((ReadOnlySpan<T>)values, separator);

        public void WriteLine<T>(ReadOnlySpan<T> values, char separator)
        {
            for (int i = 0; i < values.Length - 1; i++)
            {
                _writer.Write(values[i]);
                _writer.Write(separator);
            }

            if (values.Length > 0)
            {
                _writer.Write(values[^1]);
            }

            _writer.WriteLine();
        }

        public void Flush() => _writer.Flush();

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool IsValidChar(char c) => ValidFirstChar <= c && c <= ValidLastChar;

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private static bool IsNumericChar(char c) => ('0' <= c && c <= '9') || c == '-';

        private void ThrowEndOfStreamException() => throw new EndOfStreamException();

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    _reader.Dispose();
                    _writer.Flush();
                    _writer.Dispose();
                }

                _disposedValue = true;
            }
        }

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

    public static class UtilExtensions
    {
        public static bool ChangeMax<T>(ref this T value, T other) where T : struct, IComparable<T>
        {
            if (value.CompareTo(other) < 0)
            {
                value = other;
                return true;
            }
            return false;
        }

        public static bool ChangeMin<T>(ref this T value, T other) where T : struct, IComparable<T>
        {
            if (value.CompareTo(other) > 0)
            {
                value = other;
                return true;
            }
            return false;
        }

        public static void SwapIfLargerThan<T>(ref this T a, ref T b) where T : struct, IComparable<T>
        {
            if (a.CompareTo(b) > 0)
            {
                (a, b) = (b, a);
            }
        }

        public static void SwapIfSmallerThan<T>(ref this T a, ref T b) where T : struct, IComparable<T>
        {
            if (a.CompareTo(b) < 0)
            {
                (a, b) = (b, a);
            }
        }

        public static void Sort<T>(this T[] array) where T : IComparable<T> => Array.Sort(array);
        public static void Sort<T>(this T[] array, Comparison<T> comparison) => Array.Sort(array, comparison);
    }

    public static class CollectionExtensions
    {
        private class ArrayWrapper<T>
        {
#pragma warning disable CS0649
            public T[] Array;
#pragma warning restore CS0649
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Span<T> AsSpan<T>(this List<T> list)
        {
            return Unsafe.As<ArrayWrapper<T>>(list).Array.AsSpan(0, list.Count);
        }

        public static void Fill<T>(this T[] array, T value) => array.AsSpan().Fill(value);
        public static void Fill<T>(this T[,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0], array.Length).Fill(value);
        public static void Fill<T>(this T[,,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0, 0], array.Length).Fill(value);
        public static void Fill<T>(this T[,,,] array, T value) => MemoryMarshal.CreateSpan(ref array[0, 0, 0, 0], array.Length).Fill(value);
    }
}

#endregion


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

using E = System.Linq.Enumerable;
using System.Threading;

internal partial class Solver {
    public void Run() {
        var n = ni();
        var x = ni();
        var pos = ni();
        cout.WriteLine(Solve(n, x, pos));
    }

    private ModInt Solve(int n, int x, int pos) {
        int smaller = 0, bigger = 0;
        int left = 0, right = n;
        while (left < right) {
            var mid = (left + right) / 2;
            if (mid <= pos) { // a[mid] <= a[pos]
                left = mid + 1;
                if (mid != pos) smaller++;
            } else { // a[mid] > a[pos]
                right = mid;
                bigger++;
            }
        }
        ModInt.SetMod1000000007();
        ModInt ans = 1;
        for (int i = 0; i < smaller; i++) {
            ans *= (x - 1 - i);
        }
        for (int i = 0; i < bigger; i++) {
            ans *= ((n - x) - i);
        }
        for (int i = 1; i <= (n - 1 - smaller - bigger); i++) {
            ans *= i;
        }
        return ans;
    }
}

public partial struct ModInt : IEquatable<ModInt> {
    private static int mod = 0;
    private long _value;

    public ModInt(long x) {
        _value = x;
        Normalize();
    }

    private static long RegularMod(long x, int mod) {
        if (x >= mod) {
            if (x < 2 * mod) {
                return x - mod;
            }

            return x % mod;
        }
        if (x >= 0) {
            return x;
        }

        x = mod - RegularMod(-x, mod);
        return x == mod ? 0 : x;
    }

    public static int SetModValue(int m) {
        return mod = m;
    }
    public static int SetMod998244353() { return SetModValue(998244353); }
    public static int SetMod1000000007() { return SetModValue(1000000007); }

    private void Normalize() {
        _value = RegularMod(_value, mod);
    }

    public override string ToString() {
        return _value.ToString(CultureInfo.InvariantCulture);
    }

    public int ToInt() {
        return (int)_value;
    }

    public static bool operator ==(ModInt c1, ModInt c2) {
        return c1._value == c2._value;
    }

    public static bool operator !=(ModInt c1, ModInt c2) {
        return !(c1 == c2);
    }

    public static ModInt operator +(ModInt x, ModInt y) {
        return new ModInt(x._value + y._value);
    }
    public static ModInt operator -(ModInt x, ModInt y) {
        return new ModInt(x._value - y._value);
    }
    public static ModInt operator -(ModInt x) {
        return new ModInt(-x._value);
    }
    public static ModInt operator *(ModInt x, ModInt y) {
        return new ModInt(x._value * y._value);
    }
    public static ModInt operator /(ModInt x, ModInt y) {
        return new ModInt(x._value * Inverse(y._value, mod));
    }
    public static ModInt operator ++(ModInt x) {
        return x + 1;
    }
    public static ModInt operator --(ModInt x) {
        return x - 1;
    }
    public static ModInt Pow(ModInt x, long n) {
        ModInt r = 1;
        while (n > 0) {
            if ((n & 1) != 0) {
                r *= x;
            }

            x *= x;
            n >>= 1;
        }
        return r;
    }
    private static long ExtendedGcd(long a, long b, out long x, out long y) {
        if (b == 0) {
            x = 1; y = 0;
            return a;
        } else {
            var d = ExtendedGcd(b, a % b, out y, out x);
            y -= a / b * x;
            return d;
        }
    }

    private static long Inverse(long a, long mod) {
        long x = 0, y = 0;
        if (ExtendedGcd(a, mod, out x, out y) == 1) {
            return (x + mod) % mod;
        } else {
            throw new Exception("Invalid inverse " + a + " " + mod);
        }
    }

    public static implicit operator ModInt(long x) {
        return new ModInt(x);
    }

    public override bool Equals(object obj) {
        if (obj == null) {
            return false;
        }
        return _value.Equals(((ModInt)obj)._value);
    }

    public override int GetHashCode() {
        return _value.GetHashCode();
    }

    public bool Equals(ModInt other) {
        return _value.Equals(other._value);
    }
    object ToDump() { return _value; }
}

// PREWRITEN CODE BEGINS FROM HERE

static public class StringExtensions {
    static public string JoinToString<T>(this IEnumerable<T> source, string separator = " ") {
        return string.Join(separator, source);
    }
}

internal partial class Solver : Scanner {
    static readonly int? StackSizeInMebiByte = null; //50;
    public static void StartAndJoin(Action action, int maxStackSize) {
        var thread = new Thread(new ThreadStart(action), maxStackSize);
        thread.Start();
        thread.Join();
    }

    public static void Main() {
#if LOCAL
        byte[] inputBuffer = new byte[1000000];
        var inputStream = Console.OpenStandardInput(inputBuffer.Length);
        using (var reader = new StreamReader(inputStream, Console.InputEncoding, false, inputBuffer.Length)) {
            Console.SetIn(reader);
            new Solver(Console.In, Console.Out).Run();
        }
#else
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        if (StackSizeInMebiByte.HasValue) {
            StartAndJoin(() => new Solver(Console.In, Console.Out).Run(), StackSizeInMebiByte.Value * 1024 * 1024);
        } else {
            new Solver(Console.In, Console.Out).Run();
        }
        Console.Out.Flush();
#endif
    }

#pragma warning disable IDE0052
    private readonly TextReader cin;
    private readonly TextWriter cout;
    private readonly TextWriter cerr;
#pragma warning restore IDE0052

    public Solver(TextReader reader, TextWriter writer)
        : base(reader) {
        cin = reader;
        cout = writer;
        cerr = Console.Error;
    }

    public Solver(string input, TextWriter writer)
        : this(new StringReader(input), writer) {
    }

#pragma warning disable IDE1006
#pragma warning disable IDE0051
    private int ni() { return NextInt(); }
    private int[] ni(int n) { return NextIntArray(n); }
    private long nl() { return NextLong(); }
    private long[] nl(int n) { return NextLongArray(n); }
    private double nd() { return NextDouble(); }
    private double[] nd(int n) { return NextDoubleArray(n); }
    private string ns() { return Next(); }
    private string[] ns(int n) { return NextArray(n); }
#pragma warning restore IDE1006
#pragma warning restore IDE0051
}

#if DEBUG
internal static class LinqPadExtension {
    public static string TextDump<T>(this T obj) {
        if (obj is IEnumerable) return (obj as IEnumerable).Cast<object>().JoinToString().Dump();
        else return obj.ToString().Dump();
    }
    public static T Dump<T>(this T obj) {
        return LINQPad.Extensions.Dump(obj);
    }
}
#endif

public class Scanner {
    private readonly TextReader Reader;
    private readonly CultureInfo ci = CultureInfo.InvariantCulture;

    private readonly char[] buffer = new char[2 * 1024];
    private int cursor = 0, length = 0;
    private string Token;
    private readonly StringBuilder sb = new StringBuilder(1024);

    public Scanner()
        : this(Console.In) {
    }

    public Scanner(TextReader reader) {
        Reader = reader;
    }

    public int NextInt() { return checked((int)NextLong()); }
    public long NextLong() {
        var s = Next();
        long r = 0;
        int i = 0;
        bool negative = false;
        if (s[i] == '-') {
            negative = true;
            i++;
        }
        for (; i < s.Length; i++) {
            r = r * 10 + (s[i] - '0');
#if DEBUG
            if (!char.IsDigit(s[i])) throw new FormatException();
#endif
        }
        return negative ? -r : r;
    }
    public double NextDouble() { return double.Parse(Next(), ci); }
    public string[] NextArray(int size) {
        string[] array = new string[size];
        for (int i = 0; i < size; i++) {
            array[i] = Next();
        }

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

        return array;
    }

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

        return array;
    }

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

        return array;
    }

    public string Next() {
        if (Token == null) {
            if (!StockToken()) {
                throw new Exception();
            }
        }
        var token = Token;
        Token = null;
        return token;
    }

    public bool HasNext() {
        if (Token != null) {
            return true;
        }

        return StockToken();
    }

    private bool StockToken() {
        while (true) {
            sb.Clear();
            while (true) {
                if (cursor >= length) {
                    cursor = 0;
                    if ((length = Reader.Read(buffer, 0, buffer.Length)) <= 0) {
                        break;
                    }
                }
                var c = buffer[cursor++];
                if (33 <= c && c <= 126) {
                    sb.Append(c);
                } else {
                    if (sb.Length > 0) break;
                }
            }

            if (sb.Length > 0) {
                Token = sb.ToString();
                return true;
            }

            return false;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using CompLib.Util;
using System.Threading;
using CompLib.Mathematics;

public class Program
{
    private int N, X, Pos;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        X = sc.NextInt();
        Pos = sc.NextInt();

        List<int> g = new List<int>();
        List<int> l = new List<int>();
        int left = 0;
        int right = N;
        while (left < right)
        {
            int middle = (left + right) / 2;
            if (middle <= Pos)
            {
                l.Add(middle);
                left = middle + 1;
            }
            else
            {
                g.Add(middle);
                right = middle;
            }
        }

        // x未満 len(l)-1個
        // x超過 len(g)個

        // のこりてきとう

        var c = new BinomialCoefficient(5000);
        ModInt ans = c.fact[X - 1] * c.ifact[(X - 1) - (l.Count - 1)];
        ans *= c.fact[N - X] * c.ifact[(N - X) - g.Count];
        ans *= c.fact[N - (l.Count + g.Count)];
        Console.WriteLine(ans);
    }

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

// https://bitbucket.org/camypaper/complib
namespace CompLib.Mathematics
{
    #region ModInt

    /// <summary>
    /// [0,<see cref="Mod"/>) までの値を取るような数
    /// </summary>
    public struct ModInt
    {
        /// <summary>
        /// 剰余を取る値．
        /// </summary>
        public const long Mod = (int) 1e9 + 7;
        // public const long Mod = 998244353;

        /// <summary>
        /// 実際の数値．
        /// </summary>
        public long num;

        /// <summary>
        /// 値が <paramref name="n"/> であるようなインスタンスを構築します．
        /// </summary>
        /// <param name="n">インスタンスが持つ値</param>
        /// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
        public ModInt(long n)
        {
            num = n;
        }

        /// <summary>
        /// このインスタンスの数値を文字列に変換します．
        /// </summary>
        /// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
        public override string ToString()
        {
            return num.ToString();
        }

        public static ModInt operator +(ModInt l, ModInt r)
        {
            l.num += r.num;
            if (l.num >= Mod) l.num -= Mod;
            return l;
        }

        public static ModInt operator -(ModInt l, ModInt r)
        {
            l.num -= r.num;
            if (l.num < 0) l.num += Mod;
            return l;
        }

        public static ModInt operator *(ModInt l, ModInt r)
        {
            return new ModInt(l.num * r.num % Mod);
        }

        public static implicit operator ModInt(long n)
        {
            n %= Mod;
            if (n < 0) n += Mod;
            return new ModInt(n);
        }

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

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

        /// <summary>
        /// 与えられた数の逆元を計算します．
        /// </summary>
        /// <param name="v">逆元を取る対象となる数</param>
        /// <returns>逆元となるような値</returns>
        /// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
        public static ModInt Inverse(ModInt v)
        {
            return Pow(v, Mod - 2);
        }
    }

    #endregion

    #region Binomial Coefficient

    public class BinomialCoefficient
    {
        public ModInt[] fact, ifact;

        public BinomialCoefficient(int n)
        {
            fact = new ModInt[n + 1];
            ifact = new ModInt[n + 1];
            fact[0] = 1;
            for (int i = 1; i <= n; i++)
                fact[i] = fact[i - 1] * i;
            ifact[n] = ModInt.Inverse(fact[n]);
            for (int i = n - 1; i >= 0; i--)
                ifact[i] = ifact[i + 1] * (i + 1);
            ifact[0] = ifact[1];
        }

        public ModInt this[int n, int r]
        {
            get
            {
                if (n < 0 || n >= fact.Length || r < 0 || r > n) return 0;
                return fact[n] * ifact[n - r] * ifact[r];
            }
        }

        public ModInt RepeatedCombination(int n, int k)
        {
            if (k == 0) return 1;
            return this[n + k - 1, k];
        }
    }

    #endregion
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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


using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
class Solve{
    public Solve(){}
    StringBuilder sb;
    ReadData re;
    public static int Main(){
        new Solve().Run();
        return 0;
    }
    void Run(){
        sb = new StringBuilder();
        re = new ReadData();
        Calc();
        Console.Write(sb.ToString());
    }
    void Calc(){
        long N = re.i();
        int K = re.i();
        long count = 0;
        for(int i=0;i<=K;i++){
            if(i == 0){
                count++;
            }
            else if(i == 2){
                count += N*(N-1)/2;
            }
            else if(i == 3){
                count += N*(N-1)*(N-2)/3;
            }
            else if(i == 4){
                count += N*(N-1)*(N-2)*(N-3)/24*9;
            }
        }
        sb.Append(count+"\n");
    }
}
class ReadData{
    string[] str;
    int counter;
    public ReadData(){
        counter = 0;
    }
    public string s(){
        if(counter == 0){
            str = Console.ReadLine().Split(' ');
            counter = str.Length;
        }
        counter--;
        return str[str.Length-counter-1];
    }
    public int i(){
        return int.Parse(s());
    }
    public long l(){
        return long.Parse(s());
    }
    public double d(){
        return double.Parse(s());
    }
    public int[] ia(int N){
        int[] ans = new int[N];
        for(int j=0;j<N;j++){
            ans[j] = i();
        }
        return ans;
    }
    public int[] ia(){
        str = Console.ReadLine().Split(' ');
        counter = 0;
        int[] ans = new int[str.Length];
        for(int j=0;j<str.Length;j++){
            ans[j] = int.Parse(str[j]);
        }
        return ans;
    }
    public long[] la(int N){
        long[] ans = new long[N];
        for(int j=0;j<N;j++){
            ans[j] = l();
        }
        return ans;
    }
    public long[] la(){
        str = Console.ReadLine().Split(' ');
        counter = 0;
        long[] ans = new long[str.Length];
        for(int j=0;j<str.Length;j++){
            ans[j] = long.Parse(str[j]);
        }
        return ans;
    }
    public double[] da(int N){
        double[] ans = new double[N];
        for(int j=0;j<N;j++){
            ans[j] = d();
        }
        return ans;
    }
    public double[] da(){
        str = Console.ReadLine().Split(' ');
        counter = 0;
        double[] ans = new double[str.Length];
        for(int j=0;j<str.Length;j++){
            ans[j] = double.Parse(str[j]);
        }
        return ans;
    }
    public List<int>[] g(int N,int[] f,int[] t){
        List<int>[] ans = new List<int>[N];
        for(int j=0;j<N;j++){
            ans[j] = new List<int>();
        }
        for(int j=0;j<f.Length;j++){
            ans[f[j]].Add(t[j]);
            ans[t[j]].Add(f[j]);
        }
        return ans;
    }
    public List<int>[] g(int N,int M){
        List<int>[] ans = new List<int>[N];
        for(int j=0;j<N;j++){
            ans[j] = new List<int>();
        }
        for(int j=0;j<M;j++){
            int f = i()-1;
            int t = i()-1;
            ans[f].Add(t);
            ans[t].Add(f);
        }
        return ans;
    }
    public List<int>[] g(){
        int N = i();
        int M = i();
        List<int>[] ans = new List<int>[N];
        for(int j=0;j<N;j++){
            ans[j] = new List<int>();
        }
        for(int j=0;j<M;j++){
            int f = i()-1;
            int t = i()-1;
            ans[f].Add(t);
            ans[t].Add(f);
        }
        return ans;
    }
}
public static class Define{
    public const long mod = 1000000007;
}
public static class Debug{
    public static void Print(double[,,] k){
        for(int i=0;i<k.GetLength(0);i++){
            for(int j=0;j<k.GetLength(1);j++){
                for(int l=0;l<k.GetLength(2);l++){
                    Console.Write(k[i,j,l]+" ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }
    public static void Print(double[,] k){
        for(int i=0;i<k.GetLength(0);i++){
            for(int j=0;j<k.GetLength(1);j++){
                Console.Write(k[i,j]+" ");
            }
            Console.WriteLine();
        }
    }
    public static void Print(double[] k){
        for(int i=0;i<k.Length;i++){
            Console.WriteLine(k[i]);
        }
    }
    public static void Print(long[,,] k){
        for(int i=0;i<k.GetLength(0);i++){
            for(int j=0;j<k.GetLength(1);j++){
                for(int l=0;l<k.GetLength(2);l++){
                    Console.Write(k[i,j,l]+" ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }
    public static void Print(long[,] k){
        for(int i=0;i<k.GetLength(0);i++){
            for(int j=0;j<k.GetLength(1);j++){
                Console.Write(k[i,j]+" ");
            }
            Console.WriteLine();
        }
    }
    public static void Print(long[] k){
        for(int i=0;i<k.Length;i++){
            Console.WriteLine(k[i]);
        }
    }
    public static void Print(int[,,] k){
        for(int i=0;i<k.GetLength(0);i++){
            for(int j=0;j<k.GetLength(1);j++){
                for(int l=0;l<k.GetLength(2);l++){
                    Console.Write(k[i,j,l]+" ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }
    public static void Print(int[,] k){
        for(int i=0;i<k.GetLength(0);i++){
            for(int j=0;j<k.GetLength(1);j++){
                Console.Write(k[i,j]+" ");
            }
            Console.WriteLine();
        }
    }
    public static void Print(int[] k){
        for(int i=0;i<k.Length;i++){
            Console.WriteLine(k[i]);
        }
    }
}


using System;
using System.Numerics;
namespace _888D
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            int n = int.Parse(input[0]), k = int.Parse(input[1]);
            var factorials = new BigInteger[n + 1];
            for (int i = 0; i <= n; i++)
                factorials[i] = 1;
            for (int i = 2; i <= n; i++)
                factorials[i] = factorials[i - 1] * i;
            BigInteger result = 0;
            for (BigInteger i = n - k; i <= n; i++)
            {
                BigInteger res_ = factorials[n] / factorials[(long)i];
                BigInteger res = 0;
                for (BigInteger j = 0; j <= n - i; j++)
                {
                    BigInteger x = res_ / factorials[(long)j];
                    if (j % 2 != 0)
                        x *= -1;
                    res += x;
                }
                result += res;
            }
            Console.WriteLine(result);
        }
    }
}


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

namespace Almost_Identity_Permutations
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);
        private static readonly long[,] C = new long[1001,5];

        private static void Main(string[] args)
        {
            writer.WriteLine(Solve(args));
            writer.Flush();
        }

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

            long ans = 1;
            var m = new[] {0, 1, 1, 2, 9};
            for (int i = 2; i <= k; i++)
            {
                ans += GetC(n, i)*m[i];
            }

            return ans;
        }

        private static long GetC(int n, int k)
        {
            if (n < k)
            {
                int c = k;
                k = n;
                n = c;
            }
            if (k == 0 || k == n)
                return 1;

            if (C[n, k] != 0)
                return C[n, k];

            return C[n, k] = GetC(n - 1, k - 1) + GetC(n - 1, k);
        }

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


#if DEBUG
using System.Reflection;
using System.Threading.Tasks;
#endif

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

namespace ed32d
{
    class Program
    {
        static string _inputFilename = "input.txt";
        static string _outputFilename = "output.txt";
        static bool _useFileInput = false;

        static void Main(string[] args)
        {
            StreamWriter file = null;
#if DEBUG
			Console.SetIn(getInput());
#else
            if (_useFileInput)
            {
                Console.SetIn(File.OpenText(_inputFilename));
                file = new StreamWriter(_outputFilename);
                Console.SetOut(file);
            }
#endif

            try
            {
                solution();
            }
            finally
            {
                if (_useFileInput)
                {
                    file.Close();
                }
            }
        }

        static void solution()
        {
            //var d1 = new Dictionary<string, int>();
            //for (int i = 0; i < 4; i++)
            //{
            //    for (int j = 0; j < 4; j++)
            //    {
            //        for (int m = 0; m < 4; m++)
            //        {
            //            for (int h = 0; h < 4; h++)
            //            {
            //                var val = string.Format("{0}{1}{2}{3}", i + 1, j + 1, m + 1, h + 1);
            //                if (i != 0 && j != 1 && m != 2 && h != 3 && !d1.ContainsKey(val))
            //                {
            //                    if (i != j && i != m && i != h && j != m && j != h && m != h)
            //                    {
            //                        d1[val] = 1;
            //                    }

            //                }
            //            }
            //        }
            //    }
            //}

            #region SOLUTION
            var d = readLongArray();
            var n = d[0];
            var k = d[1];

            var total = 1L;
            if (k == 1)
            {
                Console.WriteLine(total);
                return;
            }

            total += (n * (n - 1) / 2);
            if (k == 2)
            {
                Console.WriteLine(total);
                return;
            }

            var c = (n * (n - 1) * (n - 2) / (2L * 3));
            total += (c * 2);
            if (k == 3)
            {
                Console.WriteLine(total);
                return;
            }

            var c2 = (n * (n - 1) * (n - 2) * (n - 3) / (2L * 3 * 4));
            total += (c2 * 9);

            if (k == 4)
            {
                Console.WriteLine(total);
                return;
            }

            //var n = readInt();
            //var m = readInt();

            //var a = readIntArray();
            //var b = readIntArray();
            #endregion
        }

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

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

        static int[] readIntArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => int.Parse(i)).ToArray();
        }

        static long[] readLongArray()
        {
            return Console.ReadLine().Split(' ').Where(i => !string.IsNullOrEmpty(i)).Select(i => long.Parse(i)).ToArray();
        }

#if DEBUG
		static StreamReader getInput()
		{
			var resName = Assembly.GetCallingAssembly().GetManifestResourceNames()[0];
			var resource = Assembly.GetCallingAssembly().GetManifestResourceStream(resName);

			return new StreamReader(resource);
		}
#endif
    }
}


using System;
using System.Linq;
using CompLib.Util;

public class Program
{
    int N, K;
    public void Solve()
    {
        checked
        {
            var sc = new Scanner();
            N = sc.NextInt();
            K = sc.NextInt();

            /*
             * n順列p
             *
             * n-k個以上 p_i = i
             *
             *
             */

            long ans = 0;
            for (int i = 0; i <= K; i++)
            {
                // i個選ぶ
                // i個並べる
                // !i

                ans += C(N, i) * A(i);
            }
            ans++;

            Console.WriteLine(ans);
        }
    }

    long C(int n, int m)
    {
        long r = 1;
        for (int i = 0; i < m; i++)
        {
            r *= n - i;
        }

        for (int i = 1; i <= m; i++)
        {
            r /= i;
        }
        return r;
    }

    long A(int n)
    {
        if (n <= 1) return 0;
        if (n == 2) return 1;
        else return (n - 1) * (A(n - 1) + A(n - 2));
    }

    public static void Main(string[] args) => new Program().Solve();
}

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

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

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

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

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

            return _line[_index++];
        }

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

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

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

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


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

// (づ°ω°)づﾐe★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    long C(int n, int m)
    {
        long ret = 1;
        for (int i = 1; i <= n - m; i++)
            ret = ret * (n - i + 1);
        for (int i = 1; i <= n - m; i++)
            ret /= i;
        return ret;
    }

    public void Solve()
    {
        var v = new [] { 0, 1, 2, 9 };
        int n = ReadInt();
        int m = ReadInt();

        long ans = 1;
        for (int i = Math.Max(0, n - m); i < n; i++)
            ans += C(n, i) * v[n - i - 1];

        Write(ans);
    }

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