// ReSharper disable ArrangeTypeMemberModifiers
// ReSharper disable ConvertIfStatementToSwitchStatement
// ReSharper disable EnforceForStatementBraces
// ReSharper disable EnforceIfStatementBraces
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable FunctionRecursiveOnAllPaths
// ReSharper disable InconsistentNaming
// ReSharper disable InlineOutVariableDeclaration
// ReSharper disable InvertIf
// ReSharper disable JoinDeclarationAndInitializer
// ReSharper disable MemberCanBeMadeStatic.Global
// ReSharper disable MemberCanBeMadeStatic.Local
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable NonReadonlyMemberInGetHashCode
// ReSharper disable PossibleNullReferenceException
// ReSharper disable RedundantUsingDirective
// ReSharper disable SuggestVarOrType_BuiltInTypes
// ReSharper disable SuggestVarOrType_Elsewhere
// ReSharper disable TailRecursiveCall
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedMember.Local
// ReSharper disable UnusedType.Global
// ReSharper disable UseObjectOrCollectionInitializer
// ReSharper disable ForCanBeConvertedToForeach

#if true && UTAKA_LOCAL
//#if false
#define UTAKA_DEBUG
#endif

//#define TOPCODER

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using static UtakaApp.Util;
using P = UtakaApp.Util.Pair<int, int>;

namespace UtakaApp
{
    public partial class Program
    {
        /*
        https://atcoder.jp/contests/abc151/tasks/abc151_d
        */

        public const string SiteName    = "AtCoder";
        public const string ContestName = "abc151";
        public const string ProblemName = "E";

        public void Solve()
        {
            int N = cin.ReadInt;
            int K = cin.ReadInt;

            long[] A = cin.ReadLongArray(N);

            Array.Sort(A);

            InitFac(N);

            Mint minSum = 0;
            Mint maxSum = 0;

            for (int i = 0; i < N - K + 1; i++)
            {
                Mint val = Comb(N - i - 1, K - 1);

                minSum += (val * A[i]);

                maxSum += (val * A[N - 1 - i]);
            }

            Mint ans = maxSum - minSum;

            cou.WriteLine(ans);
        }
    }

    public static partial class Util
    {
        public const int  ModInt = 1000000007;
        public const long Mod    = ModInt;
    }

    // Math
    public static partial class Util
    {
        static partial void InitializeUtilMath()
        {
            fac  = null;
            fInv = null;
            inv  = null;
            maxN = 0;
        }

        /// <summary>
        /// a^n mod.Mod を計算する
        /// </summary>
        public static long ModPow(long a, long n)
        {
            long res = 1;
            while (n > 0)
            {
                if ((n & 1) != 0) res = res * a % Mod;
                a =   a * a % Mod;
                n >>= 1;
            }

            return res;
        }

        /// <summary>
        /// mod.Mod での a の逆元 a^{-1} を求める
        /// </summary>
        public static long ModInv(long a)
        {
            long b = Mod;
            long u = 1;
            long v = 0;

            while (b > 0)
            {
                long t = a / b;
                a -= t * b;
                Swap(ref a, ref b);
                u -= t * v;
                Swap(ref u, ref v);
            }

            u %= Mod;
            if (u < 0) u += Mod;
            return u;
        }

        public static long Gcd(long a, long b)
        {
            while (a != 0 && b != 0)
            {
                if (a > b)
                    a %= b;
                else
                    b %= a;
            }

            return a == 0 ? b : a;
        }

        public static long Lcm(long a, long b)
        {
            return a / Gcd(a, b) * b;
        }

        // 返り値: a と b の最大公約数
        // a * x + b * y = Gcd(a, b) を満たす (x, y) を格納する
        public static long ExtGcd(long a, long b, out long x, out long y)
        {
            long g = a;
            x = 1;
            y = 0;
            if (b > 0)
            {
                g =  ExtGcd(b, a % b, out y, out x);
                y -= a / b * x;
            }

            return g;
        }

        // TODO
        // 返り値k: x^k = y (mod. Mod) O(sqrt(Mod))
        // 存在しなければ-1を返す
        public static long ModLog(long x, long y)
        {
            if (y == 1) return 0;
            long h    = (long)Math.Sqrt(Mod) + 1;
            var  dict = new Dictionary<long, long>();
            for (long b = 0, xby = y; b < h; b++, xby = (xby * x) % Mod)
            {
                dict[xby] = b;
            }

            long xH                        = 1;
            for (int i = 0; i < h; ++i) xH = xH * x % Mod;
            for (long a = 1, xaH = xH; a <= h; a++, xaH = (xaH * xH) % Mod)
                if (dict.ContainsKey(xaH))
                    return a * h - dict[xaH];

            return -1;
        }

        // https://mathtrain.jp/remainder
        // x = b[i] (mod.m[i]) を満たす 0 <= x < lcm(m[0],m[1],..,m[k])
        // 返り値: 解が存在するか
        // modはlcm(m[0],m[1],...,m[k])となる
        public static bool ChineseRemainderTheorem(IList<long> b, IList<long> m, out long x, out long mod)
        {
            long r = 0, M = 1;
            for (int i = 0; i < b.Count; ++i)
            {
                long p, q;
                long d = ExtGcd(M, m[i], out p, out q); // p is inv of M/d (mod. m[i]/d)
                if ((b[i] - r) % d != 0)
                {
                    x   = 0;
                    mod = -1;
                    return false;
                }

                long tmp = (b[i] - r) / d * p % (m[i] / d);
                r += M * tmp;
                M *= m[i] / d;
            }

            x   = (r % M + M) % M;
            mod = M;
            return true;
        }

        public static bool IsPrime(long n)
        {
            if (n <= 1) return false;
            if (n == 2) return true;
            if (n % 2 == 0) return false;

            double boundary = Math.Sqrt(n);

            for (int i = 3; i <= boundary; i += 2)
            {
                if (n % i == 0) return false;
            }

            return true;
        }

        public static bool[] Sieve(int n)
        {
            bool[] isPrime = new bool[n + 1];

            for (int i = 0; i <= n; i++)
            {
                isPrime[i] = true;
            }

            isPrime[0] = isPrime[1] = false;

            for (int i = 2; i * i <= n; i++)
            {
                if (isPrime[i])
                {
                    for (int j = i * i; j <= n; j += i)
                    {
                        isPrime[j] = false;
                    }
                }
            }

            return isPrime;
        }

        // n以下の素数の配列を得る
        public static int[] GetPrimes(int n)
        {
            List<int> primes  = new List<int>();
            bool[]    isPrime = new bool[n + 1];

            for (int i = 0; i <= n; i++)
            {
                isPrime[i] = true;
            }

            isPrime[0] = isPrime[1] = false;

            for (int i = 2; i * i <= n; i++)
            {
                if (isPrime[i])
                {
                    primes.Add(i);
                    for (int j = i * i; j <= n; j += i)
                    {
                        isPrime[j] = false;
                    }
                }
            }

            return primes.ToArray();
        }

        /// <summary>
        /// [a, b)の整数に対してエラトステネスの篩を作る
        /// isPrime[i - a] = true <=> iが素数
        /// </summary>
        public static bool[] SegmentSieve(long a, long b)
        {
            if (b - a > int.MaxValue)
            {
                throw new InvalidOperationException("aとbが離れすぎ");
            }

            int len = (int)(b - a);

            int sqrtB = (int)(Math.Sqrt(b) + 2); // 誤差の対応のため+2

            bool[] isPrime      = new bool[len];
            bool[] isPrimeSmall = new bool[sqrtB];

            for (int i = 2; (long)i * i < b; i++)
            {
                isPrimeSmall[i] = true;
            }

            for (int i = 0; i < len; i++)
            {
                isPrime[i] = true;
            }

            for (int i = 2; (long)i * i < b; i++)
            {
                if (isPrimeSmall[i])
                {
                    for (int j = i * i; (long)j * j < b; j += i)
                    {
                        isPrimeSmall[j] = false; // [2, root(b)) の篩
                    }

                    for (long j = Math.Max(2L, (a + i - 1) / i) * i; j < b; j += i)
                    {
                        isPrime[j - a] = false; // [a, b) の篩
                    }
                }
            }

            return isPrime;
        }

        // ============
        // 階乗を扱う処理
        // ============

        public static long[] fac;  // fac[i]  := iの階乗
        public static long[] fInv; // fInv[i] := 1 / (iの階乗)
        public static long[] inv;  // inv[i]  := 1 / i

        public static int maxN; // 計算対象のNの最大値

        // maxN:  1000000 で  90ms 
        // maxN: 10000000 で 900ms かかる
        public static void InitFac(int maxN)
        {
            if (fac != null) throw new InvalidOperationException("設定済み");

            Util.maxN = maxN;

            fac  = new long[maxN + 1];
            fInv = new long[maxN + 1];
            inv  = new long[maxN + 1];

            // 事前計算
            fac[0]  = fac[1]  = 1;
            fInv[0] = fInv[1] = 1;
            inv[1]  = 1;

            for (int i = 2; i < Util.maxN + 1; i++)
            {
                fac[i]  = fac[i - 1] * i % Mod;
                inv[i]  = Mod - inv[Mod % i] * (Mod / i) % Mod;
                fInv[i] = fInv[i - 1] * inv[i] % Mod;
            }
        }

        public static long Fact(long n)
        {
            if (n < 0) return 0;
            if (fac != null)
            {
                if (maxN < n) throw new InvalidOperationException($"n is larger than MaxN! maxN{maxN} n:{n}");
                return fac[n];
            }

            long numer = 1;
            for (long i = 0; i <= n; i++)
            {
                numer = numer * (i % Mod) % Mod;
            }

            return numer;
        }

        // nPk
        public static long Perm(long n, long k)
        {
            if (n < k) return 0;
            if (n < 0 || k < 0) return 0;

            if (fac != null)
            {
                if (maxN < n) throw new InvalidOperationException($"n is larger than MaxN! maxN{maxN} n:{n}");
                return fac[n] * fInv[n - k] % Mod;
            }

            long numer = 1;
            for (long i = 0; i < k; i++)
            {
                numer = numer * ((n - i) % Mod) % Mod;
            }

            return numer;
        }

        // nCk
        public static long Comb(int n, int k)
        {
            if (n < k) return 0;
            if (n < 0 || k < 0) return 0;

            if (fac != null)
            {
                if (maxN < n) throw new InvalidOperationException($"n is larger than MaxN! maxN{maxN} n:{n}");
                return fac[n] * (fInv[k] * fInv[n - k] % Mod) % Mod;
            }

            if (n - k < k) k = n - k;

            long numer = 1;
            long denom = 1;

            for (long i = 0; i < k; i++)
            {
                numer = numer * ((n - i) % Mod) % Mod;
                denom = denom * ((i + 1) % Mod) % Mod;
            }

            return numer * ModInv(denom) % Mod;
        }

        // nHk
        public static long MultiChoose(int n, int k)
        {
            return Comb(n + k - 1, k);
        }

        // ============
        // 累乗を扱う処理
        // ============

        public static Mint[] mpows;

        // baseValue ^ exponent までの配列を用意する
        public static void InitMpows(int baseValue, int exponent)
        {
            mpows    = new Mint[exponent + 1];
            mpows[0] = 1;
            for (int i = 1; i <= exponent; i++)
            {
                mpows[i] = mpows[i - 1] * baseValue;
            }
        }

        public static long[] pows;

        // baseValue ^ exponent までの配列を用意する
        public static void InitPows(int baseValue, int exponent)
        {
            pows    = new long[exponent + 1];
            pows[0] = 1;
            for (int i = 1; i <= exponent; i++)
            {
                pows[i] =  pows[i - 1] * baseValue;
                pows[i] %= Mod;
            }
        }
    }


    // ================
    // @formatter:off
    // ================

    public partial class Program
    {
#if !TOPCODER
        public static void Main()
        {
#if UTAKA_LOCAL
// #if false
            new TestCaseCheckerForAtCoder().TestProblems();
#else
            cin = new ConsoleInput(System.Console.In); cou = new MyConsole(); new Program().Solve(); cou.Flush();
#endif
        }
#endif
    }

    public static partial class Util
    {
        static partial void InitializeUtilMath();
        
        public static void InitializeUtil()
        {
            InitializeUtilMath();
        }
        
        public static ConsoleInput cin;
        public static IConsole cou;
        
        public static T[] Array1D<T>(int a, T defaultValue) where T : struct { var ret = new T[a]; for (int i = 0; i < a; i++) { ret[i] = defaultValue; } return ret; }
        public static T[] Array1D<T>(int a) where T : struct { var ret = new T[a]; return ret; }
        public static T[,] Array2D<T>(int a, int b, T defaultValue) where T : struct { var ret = new T[a, b]; for (int i = 0; i < a; i++) { for (int j = 0; j < b; j++) { ret[i, j] = defaultValue; } } return ret; }
        public static T[,,] Array3D<T>(int a, int b, int c, T defaultValue) where T : struct { T[,,] ret = new T[a, b, c]; for (int i = 0; i < a; i++) { for (int j = 0; j < b; j++) { for (int k = 0; k < c; k++) { ret[i, j, k] = defaultValue; } } } return ret; }
        public static T[][] JagArray2D<T>(int a, int b, T defaultValue) where T : struct { var ret = new T[a][]; for (int i = 0; i < a; i++) { var row = new T[b]; ret[i] = row; for (int j = 0; j < b; j++) { row[j] = defaultValue; } } return ret; }
        public static T[][] JagArray2D<T>(int a, int b) where T : struct { var ret = new T[a][]; for (int i = 0; i < a; i++) { ret[i] = new T[b]; } return ret; }
        public static T[][][] JagArray3D<T>(int a, int b, int c, T defaultValue) where T : struct { var ret = new T[a][][]; for (int i = 0; i < a; i++) { T[][] aRow = new T[b][]; ret[i] = aRow; for (int j = 0; j < b; j++) { T[] bRow = new T[c]; aRow[j] = bRow; for (int k = 0; k < c; k++) { bRow[k] = defaultValue; } } } return ret; }
        public static T[][][] JagArray3D<T>(int a, int b, int c) where T : struct { var ret = new T[a][][]; for (int i = 0; i < a; i++) { T[][] aRow = new T[b][]; ret[i] = aRow; for (int j = 0; j < b; j++) { T[] bRow = new T[c]; aRow[j] = bRow; } } return ret; }
        public static T[][][][] JagArray4D<T>(int a, int b, int c, int d, T defaultValue) where T : struct { var ret = new T[a][][][]; for (int i = 0; i < a; i++) { T[][][] aRow = new T[b][][]; ret[i] = aRow; for (int j = 0; j < b; j++) { T[][] bRow = new T[c][]; aRow[j] = bRow; for (int k = 0; k < c; k++) { T[] cRow = new T[d]; bRow[k] = cRow; for (int l = 0; l < d; l++) { cRow[l] = defaultValue; } } } } return ret; } 
        public static T[][][][] JagArray4D<T>(int a, int b, int c, int d) where T : struct { var ret = new T[a][][][]; for (int i = 0; i < a; i++) { T[][][] aRow = new T[b][][]; ret[i] = aRow; for (int j = 0; j < b; j++) { T[][] bRow = new T[c][]; aRow[j] = bRow; for (int k = 0; k < c; k++) { T[] cRow = new T[d]; bRow[k] = cRow; } } } return ret; }
        public static T[][][][][] JagArray5D<T>(int a, int b, int c, int d, int e, T defaultValue) where T : struct { var ret = new T[a][][][][]; for (int i = 0; i < a; i++) { T[][][][] aRow = new T[b][][][]; ret[i] = aRow; for (int j = 0; j < b; j++) { T[][][] bRow = new T[c][][]; aRow[j] = bRow; for (int k = 0; k < c; k++) { T[][] cRow = new T[d][]; bRow[k] = cRow; for (int l = 0; l < d; l++) { T[] dRow = new T[e]; cRow[l] = dRow; for (int m = 0; m < e; m++) { dRow[m] = defaultValue; } } } } } return ret; }
        public static T[][][][][] JagArray5D<T>(int a, int b, int c, int d, int e) where T : struct { var ret = new T[a][][][][]; for (int i = 0; i < a; i++) { T[][][][] aRow = new T[b][][][]; ret[i] = aRow; for (int j = 0; j < b; j++) { T[][][] bRow = new T[c][][]; aRow[j] = bRow; for (int k = 0; k < c; k++) { T[][] cRow = new T[d][]; bRow[k] = cRow; for (int l = 0; l < d; l++) { T[] dRow = new T[e]; cRow[l] = dRow; } } } } return ret; }

        // IListを配列をコピーして配列を返す
        public static T[] CopyArray<T>(IList<T> a) { T[] ret = new T[a.Count]; for (int i = 0; i < a.Count; i++) ret[i] = a[i]; return ret; }

        // ジャグ配列をコピーして返す。
        public static T[][] CopyJagArray2D<T>(T[][] source) where T : struct { int   len  = source.Length; T[][] dest = new T[len][]; for (int i = 0; i < len; i++) { T[] inner       = source[i]; int innerLength = inner.Length; T[] newer       = new T[innerLength]; Array.Copy(inner, newer, innerLength); dest[i] = newer; } return dest; }
        
        public static void Swap<T>(ref T a, ref T b)
        {
            T c = a;
            a = b;
            b = c;
        }
        
        public static void WriteEnumerable<T>(IEnumerable<T> A, string delimiter = " ")
        {
            var sb = new StringBuilder();
            foreach (T v in A)
            {
                sb.Append(v);
                sb.Append(delimiter);
            }

            if (sb.Length > 0)
            {
                sb.Length--;
            }

            cou.WriteLine(sb.ToString());
        }
        
        public class IntLargeComparer : IComparer<int>
        {
            public static IntLargeComparer Instance = new IntLargeComparer();

            public int Compare(int x, int y)
            {
                return y - x;
            }
        }

        public class LongLargeComparer : IComparer<long>
        {
            public static LongLargeComparer Instance = new LongLargeComparer();

            public int Compare(long x, long y)
            {
                if (x > y) return -1;
                if (x < y) return 1;
                return 0;
            }
        }
        
        [DebuggerDisplay("({First}, {Second})")]
        public class Pair<T1, T2> : IComparable<Pair<T1, T2>>, IEquatable<Pair<T1, T2>>
            where T1 : IComparable<T1>
            where T2 : IComparable<T2>
        {
            public T1 First;
            public T2 Second;
            
            public Pair() :this(default(T1), default(T2)) { }
            public Pair(T1 first, T2 second) { First  = first; Second = second; }

            public int CompareTo(Pair<T1, T2> other)
            {
                var firstComparison = First.CompareTo(other.First);
                return firstComparison != 0 ? firstComparison : Second.CompareTo(other.Second);
            }

            public override string ToString() => $"({First}, {Second})";

            public bool Equals(Pair<T1, T2> other)
            {
                return EqualityComparer<T1>.Default.Equals(First, other.First) &&
                       EqualityComparer<T2>.Default.Equals(Second, other.Second);
            }

            public override bool Equals(object obj)
            {
                return obj.GetType() == this.GetType() && Equals((Pair<T1, T2>)obj);
            }

            public override int GetHashCode()
            {
                unchecked
                {
                    return (EqualityComparer<T1>.Default.GetHashCode(First) * 397) ^
                           EqualityComparer<T2>.Default.GetHashCode(Second);
                }
            }
        }
        
        public struct Mint
        {
            public const int MintMod = ModInt;
            public const long PositiveAddition = ((long)MintMod) << 31;
            public long Value;
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public Mint(long value) { if ((Value = value % MintMod) < 0) { Value += MintMod; } } 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator long(Mint mint) => mint.Value; 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Mint(long val) => new Mint(val); 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator +(Mint a, int b) => new Mint() {Value = (a.Value + b + PositiveAddition) % MintMod}; 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator +(Mint a, long b) => new Mint(a.Value + b); 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator +(Mint a, Mint b) { long res = a.Value + b.Value; return new Mint() {Value = res >= MintMod ? res - MintMod : res}; } 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator -(Mint a, int b) => new Mint() {Value = (a.Value - b + PositiveAddition) % MintMod}; 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator -(Mint a, long b) => new Mint(a.Value - b); 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator -(Mint a, Mint b) { long res = a.Value - b.Value; return new Mint() {Value = res < 0 ? res + MintMod : res}; } 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator *(Mint a, int b) => new Mint(a.Value * b); 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator *(Mint a, long b) => a * new Mint(b); 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator *(Mint a, Mint b) => new Mint() {Value = a.Value * b.Value % MintMod}; 
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Mint operator /(Mint a, Mint b) => new Mint() {Value = a.Value * GetInverse(b) % MintMod};
            [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() => Value.ToString();
            [MethodImpl(MethodImplOptions.AggressiveInlining)] static long GetInverse(long a) { long p  = MintMod; long x1 = 1; long y1 = 0; long x2 = 0; long y2 = 1; while (true) { if (p == 1) return x2 + MintMod; var div = a / p; x1 -= x2 * div; y1 -= y2 * div; a  %= p; if (a == 1) return x1 + MintMod; div =  p / a; x2  -= x1 * div; y2  -= y1 * div; p   %= a; } } 
        }
    }

    public class ConsoleInput { private readonly char  _separator; private readonly TextReader  _stream; private readonly Queue<string> inputStream; public ConsoleInput(TextReader stream, char separator = ' ') { _separator  = separator; _stream     = stream; inputStream = new Queue<string>(); } public string Read { get { if (inputStream.Count != 0) { return inputStream.Dequeue(); } var tmp = _stream.ReadLine().Split(_separator); for (var i = 0; i < tmp.Length; ++i) { inputStream.Enqueue(tmp[i]); } return inputStream.Dequeue(); } } public string ReadLine   => _stream.ReadLine(); public int    ReadInt    => int.Parse(Read); public long   ReadLong   => long.Parse(Read); public double ReadDouble => double.Parse(Read); public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) { ret[i] = Read; } return ret; } public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) { ret[i] = ReadInt; } return ret; } public int[] ReadIntArrayMinus1(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) { ret[i] = ReadInt - 1; } return ret; } public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) { ret[i] = ReadLong; } return ret; } } 
    // ReSharper disable once UnusedMemberInSuper.Global
    public interface IConsole { void Flush(); void Write(object obj); void Write(string str); void WriteLine(object obj); void WriteLine(string str); void WriteLine(); }
    public class MyConsole : IConsole { public MyConsole() { var sw = new StreamWriter(Console.OpenStandardOutput()) {AutoFlush = false}; Console.SetOut(sw); } public void Flush() { Console.Out.Flush(); } public void Write(object obj) { Write(obj.ToString()); } public void Write(string str) { Console.Write(str); } public void WriteLine(object obj) { WriteLine(obj.ToString()); } public void WriteLine(string str) { Console.WriteLine(str); } public void WriteLine() { Console.WriteLine(); } }

#if UTAKA_LOCAL
    public class DebugConsole : IConsole { private readonly StringBuilder mSb; public DebugConsole() { mSb = new StringBuilder(); } public void Flush() { } public void Write(object obj) { Write(obj.ToString()); } public void Write(string str) { mSb.Append(str); } public void WriteLine(object obj) { WriteLine(obj.ToString()); } public void WriteLine(string str) { mSb.AppendLine(str); } public void WriteLine() { mSb.AppendLine(); } public string GetAllOutput() { return mSb.ToString(); } }
    
    public class TestCaseCheckerForAtCoder
    {
        private string GetDirectoryPath() { var problemPart = string.IsNullOrEmpty(Program.ProblemName) ? "" : $"/{Program.ProblemName}"; return $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}/AlgorithmPrac/{Program.SiteName}/{Program.ContestName}{problemPart}"; }
        private string GetInputFilePath(int testCaseNumber) { return $"{GetDirectoryPath()}/sample-{testCaseNumber}.in"; }
        private string GetOutputFilePath(int testCaseNumber) { return $"{GetDirectoryPath()}/sample-{testCaseNumber}.out"; }
        public bool TestProblem(int testCaseNumber)
        {
            var inputFilePath      = GetInputFilePath(testCaseNumber); var outputFilePath     = GetOutputFilePath(testCaseNumber); var inputStream        = new StreamReader(inputFilePath); var cin                = new ConsoleInput(inputStream); var debugConsoleWriter = new DebugConsole(); Util.cin = cin; Util.cou = debugConsoleWriter;
            InitializeUtil();
            new Program().Solve(); var        output       = debugConsoleWriter.GetAllOutput(); TextReader outputStream = new StreamReader(outputFilePath); var        outputAnswer = outputStream.ReadToEnd(); Dbg.WriteLine(output); Dbg.WriteLine(outputAnswer); var isCorrect = output == outputAnswer; return isCorrect;
        }
        public void TestProblems(int targetTestCaseNumber = -1) { if (targetTestCaseNumber >= 0) { Console.WriteLine($"!!!!!!!!!!!! Check TestCase {targetTestCaseNumber} !!!!!!!!!!"); } bool isSuccessAll   = true; int  testCaseNumber = 0; while (true) { testCaseNumber++; bool foundTargetTest = targetTestCaseNumber == testCaseNumber; if (targetTestCaseNumber >= 0 && !foundTargetTest) { continue; } var inputFileName = GetInputFilePath(testCaseNumber); if (!File.Exists(inputFileName)) { break; } Console.WriteLine($"TestCase {testCaseNumber} ====================================================="); var result = TestProblem(testCaseNumber); if (result) { Console.WriteLine("Success"); } else { isSuccessAll = false; Console.WriteLine("Failure *****"); } if (foundTargetTest) { break; } } if (isSuccessAll) { Console.WriteLine("!!!!!!!!! All Success !!!!!!!!!"); } }
    }
#endif

    public static class Dbg
    {
        [Conditional("UTAKA_DEBUG")] public static void WriteLine(string str) { Console.WriteLine(str); }
        [Conditional("UTAKA_DEBUG")] public static void WriteLine() { Console.WriteLine(); }
        [Conditional("UTAKA_DEBUG")] public static void Write(string str) { Console.Write(str); }
    }
    
    // ================
    // @formatter:on 
    // ================
}


Measured memory_bytes: 31068