using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Text;
using System.Diagnostics;
using System.Numerics;
using static System.Console;
using static System.Convert;
using static System.Math;
using static Template;
using SC = Scanner;

public partial class Solver
{
    public void Solve()
    {
        int N, K;
        sc.Make(out N, out K);
        var A = sc.ArrInt;
        int[] ct = new int[2];
        var o = 0; ModInt al = 1 / ((ModInt)N * (N - 1) / 2);
        for (int i = 0; i < N; i++)
        {
            ct[A[i]]++;
        }
        for (int i = ct[0]; i < N; i++)
        {
            if (A[i] == 0) o++;
        }
        var len = ct.Min() + 1;
        var F = Create(len, () => new ModInt[len]);
        for (int i = 0; i < len; i++)
        {
            F[i][i] = al * (ct[0] * (ct[0] - 1) / 2 + ct[1] * (ct[1] - 1) / 2 + (N - i * 2) * i);
        }
        for (int i = 0; i < len - 1; i++)
        {
            F[i][i + 1] = (i + 1) * (i + 1) * al;
        }
        for (int i = 1; i < len; i++)
        {
            F[i][i - 1] = (ModInt)(ct[0] - i + 1) * (ct[1] - i + 1) * al;
        }
        Console.WriteLine(matpow(F, K)[0][o]);
    }

    ModInt[][] matpow(ModInt[][] A, long k)
    {
        var res = Create(A.Length, () => new ModInt[A.Length]);
        for (int i = 0; i < A.Length; i++) res[i][i] = 1;
        while (k != 0)
        {
            if (k % 2 == 1) res = matmul(res, A);
            k >>= 1;
            A = matmul(A, A);
        }
        return res;
    }
    ModInt[][] matmul(ModInt[][] A, ModInt[][] B)
    {
        var rt = Create(A.Length, () => new ModInt[B[0].Length]);
        for (int i = 0; i < A.Length; i++)
            for (int j = 0; j < B[0].Length; j++)
            {
                for (int k = 0; k < B.Length; k++)
                    rt[i][j] += A[i][k] * B[k][j];
            }
        return rt;
    }
    ModInt[] matdot(ModInt[][] A, ModInt[] B)
    {
        var rt = new ModInt[A.Length];
        for (int i = 0; i < A.Length; i++)
        {
            ModInt now = 0;
            for (int j = 0; j < B.Length; j++)
            {
                now += A[i][j] * B[j];
            }
            rt[i] = now;
        }
        return rt;
    }
}

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

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

    public static void Build(int n)
    {
        fac = new ModInt[n + 1];
        facinv = new ModInt[n + 1];
        inv = new ModInt[n + 1];
        inv[1] = fac[0] = fac[1] = facinv[0] = facinv[1] = 1;
        for (var i = 2; i <= n; i++)
        {
            fac[i] = fac[i - 1] * i;
            inv[i] = MOD - inv[MOD % i] * (MOD / i);
            facinv[i] = facinv[i - 1] * inv[i];
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Fac(int n) => fac[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Inv(int n) => inv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt FacInv(int n) => facinv[n];
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static ModInt Comb(int n, int r)
    {
        if (n < r) return 0;
        if (n == r) return 1;
        return fac[n] * facinv[r] * facinv[n - r];
    }
    public static ModInt Perm(int n, int r)
    {
        if (n < r) return 0;
        return fac[n] * facinv[n - r];
    }

}
#region Template
public partial class Solver
{
    public SC sc = new SC();
    static void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        var sol = new Solver();
        int testcase = 1;
        //testcase = sol.sc.Int;
        //var th = new Thread(sol.Solve, 1 << 26);th.Start();th.Join();
        while (testcase-- > 0)
            sol.Solve();
        Console.Out.Flush();
    }
}
public static class Template
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void swap<T>(this IList<T> A, int i, int j) { var t = A[i]; A[i] = A[j]; A[j] = t; }
    public static T[] Create<T>(int n, Func<T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(); return rt; }
    public static T[] Create<T>(int n, Func<int, T> f) { var rt = new T[n]; for (var i = 0; i < rt.Length; ++i) rt[i] = f(i); return rt; }
    public static void Out<T>(this IList<T> A, out T a) => a = A[0];
    public static void Out<T>(this IList<T> A, out T a, out T b) { a = A[0]; b = A[1]; }
    public static void Out<T>(this IList<T> A, out T a, out T b, out T c) { A.Out(out a, out b); c = A[2]; }
    public static void Out<T>(this IList<T> A, out T a, out T b, out T c, out T d) { A.Out(out a, out b, out c); d = A[3]; }
    public static string Concat<T>(this IEnumerable<T> A, string sp) => string.Join(sp, A);
    public static char ToChar(this int s, char begin = '0') => (char)(s + begin);
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> A) => A.OrderBy(v => Guid.NewGuid());
    public static int CompareTo<T>(this T[] A, T[] B, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; for (var i = 0; i < Min(A.Length, B.Length); i++) { int c = cmp(A[i], B[i]); if (c > 0) return 1; else if (c < 0) return -1; } if (A.Length == B.Length) return 0; if (A.Length > B.Length) return 1; else return -1; }
    public static string ToStr<T>(this T[][] A) => A.Select(a => a.Concat(" ")).Concat("\n");
    public static int ArgMax<T>(this IList<T> A, Comparison<T> cmp = null) { cmp = cmp ?? Comparer<T>.Default.Compare; T max = A[0]; int rt = 0; for (int i = 1; i < A.Count; i++) if (cmp(max, A[i]) < 0) { max = A[i]; rt = i; } return rt; }
    public static T PopBack<T>(this List<T> A) { var v = A[A.Count - 1]; A.RemoveAt(A.Count - 1); return v; }
    public static void Fail<T>(T s) { Console.WriteLine(s); Console.Out.Close(); Environment.Exit(0); }
}
public class Scanner
{
    public string Str => Console.ReadLine().Trim();
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public int[] ArrInt => Str.Split(' ').Select(int.Parse).ToArray();
    public long[] ArrLong => Str.Split(' ').Select(long.Parse).ToArray();
    public char[][] Grid(int n) => Create(n, () => Str.ToCharArray());
    public int[] ArrInt1D(int n) => Create(n, () => Int);
    public long[] ArrLong1D(int n) => Create(n, () => Long);
    public int[][] ArrInt2D(int n) => Create(n, () => ArrInt);
    public long[][] ArrLong2D(int n) => Create(n, () => ArrLong);
    private Queue<string> q = new Queue<string>();
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public T Next<T>() { if (q.Count == 0) foreach (var item in Str.Split(' ')) q.Enqueue(item); return (T)Convert.ChangeType(q.Dequeue(), typeof(T)); }
    public void Make<T1>(out T1 v1) => v1 = Next<T1>();
    public void Make<T1, T2>(out T1 v1, out T2 v2) { v1 = Next<T1>(); v2 = Next<T2>(); }
    public void Make<T1, T2, T3>(out T1 v1, out T2 v2, out T3 v3) { Make(out v1, out v2); v3 = Next<T3>(); }
    public void Make<T1, T2, T3, T4>(out T1 v1, out T2 v2, out T3 v3, out T4 v4) { Make(out v1, out v2, out v3); v4 = Next<T4>(); }
    public void Make<T1, T2, T3, T4, T5>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5) { Make(out v1, out v2, out v3, out v4); v5 = Next<T5>(); }
    public void Make<T1, T2, T3, T4, T5, T6>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6) { Make(out v1, out v2, out v3, out v4, out v5); v6 = Next<T6>(); }
    public void Make<T1, T2, T3, T4, T5, T6, T7>(out T1 v1, out T2 v2, out T3 v3, out T4 v4, out T5 v5, out T6 v6, out T7 v7) { Make(out v1, out v2, out v3, out v4, out v5, out v6); v7 = Next<T7>(); }
    public (T1, T2) Make<T1, T2>() { Make(out T1 v1, out T2 v2); return (v1, v2); }
    public (T1, T2, T3) Make<T1, T2, T3>() { Make(out T1 v1, out T2 v2, out T3 v3); return (v1, v2, v3); }
    public (T1, T2, T3, T4) Make<T1, T2, T3, T4>() { Make(out T1 v1, out T2 v2, out T3 v3, out T4 v4); return (v1, v2, v3, v4); }
}

#endregion

using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Text;
using System;
using System.Numerics;

class Solution
{
    public class GCD
    {
        public static int Euclidean(int n1, int n2)
        {
            if (n1 == n2) return n1;
            else if (n1 < n2)
            {
                var tmp = n1;
                n1 = n2;
                n2 = tmp;
            }

            while (n1 % n2 > 0)
            {
                var tmp = n2;
                n2 = n1 % n2;
                n1 = tmp;
            }
            return n2;
        }
        public static long Euclidean(long n1, long n2)
        {
            if (n1 == n2) return n1;
            else if (n1 < n2)
            {
                var tmp = n1;
                n1 = n2;
                n2 = tmp;
            }

            while (n1 % n2 > 0)
            {
                var tmp = n2;
                n2 = n1 % n2;
                n1 = tmp;
            }
            return n2;
        }

        public static long Inverse(long a, long n)
        {
            long x, y = 0;
            EuclideanExt(a, n, out x, out y);
            return x < 0 ? n + x : x;
        }

        public static long EuclideanExt(long n1, long n2, out long x, out long y)
        {
            x = 0;
            y = 1;

            bool r = false;
            if (n1 == n2) return n1;

            else if (n1 < n2)
            {
                r = true;
                var tmp = n1;
                n1 = n2;
                n2 = tmp;
            }
            long q = 0;
            long xl = 1;
            long yl = 0;

            while (n2 > 0)
            {
                q = n1 / n2;

                var tmp = n2;
                n2 = n1 % n2;
                n1 = tmp;

                tmp = x;
                x = xl - q * x;
                xl = tmp;

                tmp = y;
                y = yl - q * y;
                yl = tmp;

            }
            x = xl;
            y = yl;
            if (r)
            {
                x = yl;
                y = xl;
            }
            return x * n1 + y * n2;
        }
    }

    public static Tuple<long, long>[,] multiply(Tuple<long, long>[,] m1, Tuple<long, long>[,] m2)
    {
        Tuple<long, long>[,] ret = new Tuple<long, long>[m1.GetLength(0), m2.GetLength(1)];
        for (int i = 0; i < ret.GetLength(0); i++)
            for (int j = 0; j < ret.GetLength(1); j++)
            {
                ret[i, j] = new Tuple<long, long>(0, 0);
                for (int k = 0; k < m1.GetLength(1); k++)
                    ret[i, j] = sum(ret[i, j], prod(m1[i, k], m2[k, j]));
            }
        return ret;
    }

    public static Tuple<long, long>[,] recPow(Tuple<long, long>[,] m, long pow)
    {
        if (pow == 1)
            return m;

        var powered = recPow(m, pow / 2);
        var mult = multiply(powered, powered);
        if (pow % 2 == 1)
        {

            mult = multiply(mult, m);
        }
        return mult;
    }

    static Tuple<long, long> sum(Tuple<long, long> a, Tuple<long, long> b)
    {
        if (a.Item1 == 0)
            return b;
        if (b.Item1 == 0)
            return a;
        return Tuple.Create(
            ((a.Item1 * b.Item2) % mod + (b.Item1 * a.Item2) % mod) % mod,
            (a.Item2 * b.Item2) % mod
        );
    }

    static Tuple<long, long> prod(Tuple<long, long> a, Tuple<long, long> b)
    {
        return Tuple.Create(
            (a.Item1 * b.Item1) % mod,
            (a.Item2 * b.Item2) % mod
        );
    }

    static Tuple<long, long> PInOneSide(long cnt, long totalcnt)
    {
        return Tuple.Create(
            cnt * (cnt - 1) + (totalcnt - cnt) * (totalcnt - cnt - 1),
            totalcnt * (totalcnt - 1)
        );
    }

    static Tuple<long, long> PIncreaseLeftA(long leftCnt, long leftACnt, long totalcnt)
    {
        return Tuple.Create(
             (leftCnt - leftACnt) * (leftCnt - leftACnt),
            (totalcnt * (totalcnt - 1)) / 2
        );
    }

    static Tuple<long, long> PDecreaseLeftA(long leftCnt, long leftACnt, long totalcnt)
    {
        return Tuple.Create(
            leftACnt * (totalcnt - 2 * leftCnt + leftACnt),
            (totalcnt * (totalcnt - 1)) / 2
        );
    }

    static void CalcCashe(long lowerBnd, long leftCnt, long totalcnt)
    {
        PInOneSideCache = PInOneSide(leftCnt, totalcnt);

        PIncreaseLeftACache = new Tuple<long, long>[leftCnt - lowerBnd + 1];
        PDecreaseLeftACache = new Tuple<long, long>[leftCnt - lowerBnd + 1];
        PSameInBothSideCache = new Tuple<long, long>[leftCnt - lowerBnd + 1];

        for (long i = lowerBnd; i <= leftCnt; i++)
        {
            PIncreaseLeftACache[(int)(i - lowerBnd)] = PIncreaseLeftA(leftCnt, i, totalcnt);
            PDecreaseLeftACache[(int)(i - lowerBnd)] = PDecreaseLeftA(leftCnt, i, totalcnt);
            PSameInBothSideCache[(int)(i - lowerBnd)] = PSameInBothSide(leftCnt, i, totalcnt);
        }
    }
    static Tuple<long, long> PInOneSideCache;
    static Tuple<long, long>[] PSameInBothSideCache;
    static Tuple<long, long>[] PIncreaseLeftACache;
    static Tuple<long, long>[] PDecreaseLeftACache;
    static Tuple<long, long> PSameInBothSide(long leftCnt, long leftACnt, long totalcnt)
    {

        return Tuple.Create(
             (leftCnt - leftACnt) * (totalcnt + 2 * leftACnt - 2 * leftCnt),
            (totalcnt * (totalcnt - 1)) / 2
        );
    }

    const long mod = 1000000007L;
    static void Main(string[] args)
    {

        // var n = int.Parse( Console.ReadLine());
        var tmp = Array.ConvertAll(Console.ReadLine().Trim().Split(), Convert.ToInt64);
        var n = (long)tmp[0];
        var k = tmp[1];

        var arr = Array.ConvertAll(Console.ReadLine().Trim().Split(), Convert.ToByte);

        var leftcnt = (long)arr.Count(el => el == 0);
        var leftAcnt = (long)arr.Where((el, i) => el == 0 && i < leftcnt).Count();
        if (k < (leftcnt - leftAcnt))
        {
            Console.WriteLine("0");
            return;
        }
        if (leftcnt == n || leftcnt == 0)
        {
            Console.WriteLine("1");
            return;
        }

        var lowerBnd = (long)Math.Max(0, (int)(2 * (int)leftcnt - (int)n));

        Tuple<long, long>[,] A = new Tuple<long, long>[(int)(leftcnt - lowerBnd + 1), (int)(leftcnt - lowerBnd + 1)];

        CalcCashe(lowerBnd, leftcnt, n);

        for (int i = 0; i < A.GetLength(0); i++)
        {
            for (int j = 0; j < A.GetLength(0); j++)
            {
                if (i == j)
                {
                    A[i, j] = sum(PInOneSideCache, PSameInBothSideCache[i]);
                }
                else if (i == j + 1)
                {
                    A[i, j] = PIncreaseLeftACache[i - 1];
                }
                else if (i == j - 1)
                {
                    A[i, j] = PDecreaseLeftACache[i + 1];
                }
                else
                {
                    A[i, j] = Tuple.Create<long, long>(0, 0);
                }
            }
        }

        A = recPow(A, k);

        Tuple<long, long>[,] F = new Tuple<long, long>[leftcnt - lowerBnd + 1, 1];
        for (int i = 0; i < F.GetLength(0); i++)
        {
            if (i == leftAcnt - lowerBnd)
            {
                F[i, 0] = Tuple.Create(1l, 1L);
            }
            else
            {
                F[i, 0] = new Tuple<long, long>(0, 0);
            }
        }
        F = multiply(A, F);
        var tpl = F[F.GetLength(0) - 1, 0];
        if (tpl.Item1 == 0)
        {
            Console.WriteLine("0");
            return;
        }
        var gcd = GCD.Euclidean(tpl.Item1, tpl.Item2);
        var ret = Tuple.Create(tpl.Item1 / gcd, tpl.Item2 / gcd);

        var ret2 = ((long)ret.Item1 * GCD.Inverse((long)ret.Item2, (long)mod)) % (long)mod;

        Console.WriteLine($"{ret2}");

    }
}

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using Number = System.Int64;
using N = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			//
			//dp[i,a,b] = i 回操作したあと、0 が来るべき箇所にある 1 の個数、1 が来るべき箇所にある 0 の個数
			//dp[i+1,a-1,b-1]+=dp[i,a,b]*a*b/n^2;
			//dp[i+1,a,b]+=dp[i,a,b]*(A*A+B*B + a*(B-b) + b*(A-a))/n^2
			//dp[i+1,a+1,b+1]+=dp[i,a,b]*(A-a)*(B-b)/n^2

			var n = ri; var k = ri;
			var A = Enumerate(n, x => ri);
			var K = n - A.Sum();
			var M = n - K;
			var B = Enumerate(n, x => x < K ? 0 : 1);
			var p = Enumerate(n, x => x).Count(x => A[x] != B[x]) / 2;
			var coef = ModInt.Inverse(n * (n - 1) / 2);
			var mat = new Matrix(n + 1, n + 1);
			//mat[i,j] = j->i
			for (int j = 0; j <= n; j++) {
				if (j != 0) mat[j - 1, j] += j * j * coef.num;
				mat[j, j] += (K * (K - 1) / 2 + M * (M - 1) / 2 + j * (M - j) + j * (K - j)) * coef.num;
				if (j != n) mat[j + 1, j] += (K - j) * (M - j) * coef.num;
			}
			for (int i = 0; i <= n; i++)
				for (int j = 0; j <= n; j++)
					mat[i, j] %= ModInt.Mod;
			var res = Matrix.Pow(mat, k);
			var vec = new Matrix(n + 1, 1); vec[p, 0] = 1;
			var ans = (res * vec)[0, 0];
			Console.WriteLine(ans);
		}
		const long INF = 1L << 60;
		static int[] dx = { -1, 0, 1, 0 };
		static int[] dy = { 0, 1, 0, -1 };
		int ri { get { return sc.Integer(); } }
		long rl { get { return sc.Long(); } }
		double rd { get { return sc.Double(); } }
		string rs { get { return sc.Scan(); } }
		public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

		static T[] Enumerate<T>(int n, Func<int, T> f) {
			var a = new T[n];
			for (int i = 0; i < a.Length; ++i) a[i] = f(i);
			return a;
		}
		static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
	}
}

#region main
static class Ex {
	static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
	static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
		return string.Join(st, ie);
	}
	static public void Main() {
		//Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
		var solver = new Program.Solver();
		solver.Solve();
		Console.Out.Flush();
	}
}
#endregion
#region Ex
namespace Program.IO {
	using System.IO;
	using System.Text;
	using System.Globalization;

	public class Printer : StreamWriter {
		public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
		public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	}

	public class StreamScanner {
		public StreamScanner(Stream stream) { str = stream; }

		public readonly Stream str;
		private readonly byte[] buf = new byte[1024];
		private int len, ptr;
		public bool isEof = false;
		public bool IsEndOfStream { get { return isEof; } }

		private byte read() {
			if (isEof) return 0;
			if (ptr >= len) {
				ptr = 0;
				if ((len = str.Read(buf, 0, 1024)) <= 0) {
					isEof = true;
					return 0;
				}
			}
			return buf[ptr++];
		}

		public char Char() {
			byte b = 0;
			do b = read(); while ((b < 33 || 126 < b) && !isEof);
			return (char)b;
		}
		public string Scan() {
			var sb = new StringBuilder();
			for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
			return sb.ToString();
		}
		public string ScanLine() {
			var sb = new StringBuilder();
			for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
			return sb.ToString();
		}
		public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
		public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
		public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
	}
}

#endregion

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

	/// <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 Matrix
public class Matrix {
	int row, col;
	public N[] mat;
	/// <summary>
	/// <paramref name="r"/> 行 <paramref name="c"/> 列目の要素へのアクセスを提供します。
	/// </summary>
	/// <param name="r">行の番号</param>
	/// <param name="c">列の番号</param>
	public N this[int r, int c] {
		get { return mat[r * col + c]; }
		set { mat[r * col + c] = value; }
	}
	public Matrix(int r, int c) {
		row = r; col = c;
		mat = new N[row * col];
	}
	public static Matrix operator *(Matrix l, Matrix r) {
		System.Diagnostics.Debug.Assert(l.col == r.row);
		var ret = new Matrix(l.row, r.col);
		for (int i = 0; i < l.row; i++)
			for (int k = 0; k < l.col; k++)
				for (int j = 0; j < r.col; j++)
					ret.mat[i * r.col + j] = (ret.mat[i * r.col + j] + l.mat[i * l.col + k] * r.mat[k * r.col + j]) % ModInt.Mod;
		return ret;
	}
	/// <summary>
	/// <paramref name="m"/>^<paramref name="n"/> を O(<paramref name="m"/>^3 log <paramref name="n"/>) で計算します。
	/// </summary>
	public static Matrix Pow(Matrix m, long n) {
		var ret = new Matrix(m.row, m.col);
		for (int i = 0; i < m.row; i++)
			ret.mat[i * m.col + i] = 1;
		for (; n > 0; m *= m, n >>= 1)
			if ((n & 1) == 1)
				ret = ret * m;
		return ret;

	}
	public N[][] Items {
		get {
			var a = new N[row][];
			for (int i = 0; i < row; i++) {
				a[i] = new N[col];
				for (int j = 0; j < col; j++)
					a[i][j] = mat[i * col + j];
			}
			return a;
		}
	}
}
#endregion

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

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            const long MOD = 1000000000 + 7;

            int n = ReadInt();
            long k = ReadLong();
            int[] a = ReadIntArray();

            int m = a.Sum();

            if (m == n)
            {
                Writer.WriteLine(1);
                return;
            }

            long[,] b = new long[m + 1, m + 1];
            for (int i = 0; i < m + 1; i++)
            {
                long l = Math.Max(0, 2 * i * (n + i - 2 * m));
                long r = 2 * (m - i) * (m - i);
                long e = n * (n - 1) - l - r;
                long inv = Inv(n * (n - 1), MOD);
                if (l > 0)
                {
                    b[i, i - 1] = l * inv % MOD;
                }
                b[i, i] = e * inv % MOD;
                if (r > 0)
                {
                    b[i, i + 1] = r * inv % MOD;
                }
            }

            long[,] c = MatrixBinPower(m + 1, b, k, MOD);

            int st = 0;
            for (int i = 0; i < m; i++)
            {
                st += a[n - i - 1];
            }

            long ans = c[st, m];

            Writer.WriteLine(ans);
        }

        public static long Inv(long a, long mod)
        {
            return BinPower(a, mod - 2, mod);
        }

        public static long BinPower(long a, long n, long mod)
        {
            long result = 1;

            while (n > 0)
            {
                if ((n & 1) != 0)
                {
                    result = (result * a) % mod;
                }

                a = (a * a) % mod;
                n >>= 1;
            }

            return result;
        }

        public static long[,] MatrixBinPower(int n, long[,] a, long p, long mod)
        {
            long[,] result = new long[n, n];
            for (int i = 0; i < n; i++)
            {
                result[i, i] = 1;
            }

            while (p > 0)
            {
                if ((p & 1) != 0)
                {
                    result = MatrixMult(n, result, a, mod);
                }

                a = MatrixMult(n, a, a, mod);
                p >>= 1;
            }

            return result;
        }

        public static long[,] MatrixMult(int n, long[,] a, long[,] b, long mod)
        {
            long[,] c = new long[n, n];

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    for (int k = 0; k < n; k++)
                    {
                        c[i, j] = (c[i, j] + a[i, k] * b[k, j]) % mod;
                    }
                }
            }

            return c;
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

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

#if DEBUG
            sw.Stop();
            Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

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

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

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

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

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

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

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

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

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

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

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

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

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

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

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

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

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

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

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

        #endregion
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SB = System.Text.StringBuilder;
//using System.Threading.Tasks;
//using System.Text.RegularExpressions;
//using System.Globalization;
//using System.Diagnostics;
using static System.Console;
using System.Numerics;
using static System.Math;
using pair = Pair<int, int>;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    readonly Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;
    readonly int dom = 998244353;
    bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (b.CompareTo(a) < 0) { a = b; return true; } return false; }

    void solve()
    {
        int N = cin.nextint;
        int K = cin.nextint;
        var A = cin.scanint;

        int zero = A.Count(i => i == 0);
        int one = N - zero;
        int NG = 0;
        for (int i = zero; i < N; i++)
        {
            if (A[i] == 0)
            {
                NG++;
            }
        }

        var nc2 = N * (N - 1) * ModInt.Inverse(2);
        var inv = ModInt.Inverse(nc2);
        var dp = new ModInt[zero + 1][];
        for (int i = 0; i < dp.Length; i++)
        {
            dp[i] = new ModInt[zero + 1];
            int zero_ok = zero - i;
            int one_ok = one - i;
            dp[i][i] = inv * (nc2 - zero_ok * one_ok - i * i);

            if (i > 0)
            {
                zero_ok = zero - (i - 1);
                one_ok = one - (i - 1);
                dp[i][i - 1] = inv * zero_ok * one_ok;
            }

            if (i < zero)
            {
                dp[i][i + 1] = inv * (i + 1) * (i + 1);
            }

        }

        var M = matpow(dp, K);

        WriteLine(M[0][NG]);

    }

    ModInt[][] matpow(ModInt[][] m, long a)
    {
        if (a == 0)
        {
            int N = m.Length;
            ModInt[][] ret = new ModInt[N][];
            for (int i = 0; i < N; i++)
            {
                ret[i] = new ModInt[N];
                ret[i][i] = 1;
            }
            return ret;
        }
        if (a % 2 == 0)
        {
            ModInt[][] ret = matpow(m, a / 2);
            return matmul(ret, ret);
        }
        else
        {
            return matmul(m, matpow(m, a - 1));
        }
    }
    ModInt[][] matmul(ModInt[][] ma, ModInt[][] mb)
    {
        int p = ma.Length;
        int q = mb[0].Length;
        int r = ma[0].Length;
        ModInt[][] ret = new ModInt[p][];
        for (int i = 0; i < p; i++)
        {
            ret[i] = new ModInt[q];
            for (int j = 0; j < q; j++)
            {
                for (int k = 0; k < r; k++)
                {
                    ret[i][j] += ma[i][k] * mb[k][j];
                }
            }
        }
        return ret;
    }
}

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

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

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

static class Ex
{
    public static void join<T>(this IEnumerable<T> values, string sep = " ") => WriteLine(string.Join(sep, values));
    public static string concat<T>(this IEnumerable<T> values) => string.Concat(values);
    public static string reverse(this string s) { var t = s.ToCharArray(); Array.Reverse(t); return t.concat(); }

    public static int lower_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) < 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
    public static int upper_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) <= 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
}

class Pair<T, U> : IComparable<Pair<T, U>> where T : IComparable<T> where U : IComparable<U>
{
    public T f; public U s;
    public Pair(T f, U s) { this.f = f; this.s = s; }
    public int CompareTo(Pair<T, U> a) => f.CompareTo(a.f) != 0 ? f.CompareTo(a.f) : s.CompareTo(a.s);
    public override string ToString() => $"{f} {s}";
}

class Scanner
{
    string[] s; int i;
    readonly char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan => ReadLine().Split();
    public int[] scanint => Array.ConvertAll(scan, int.Parse);
    public long[] scanlong => Array.ConvertAll(scan, long.Parse);
    public double[] scandouble => Array.ConvertAll(scan, double.Parse);
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint => int.Parse(next);
    public long nextlong => long.Parse(next);
    public double nextdouble => double.Parse(next);
}