Problem:
Score : 600 points

Problem Statement

AtCoDeer the deer has N cards with positive integers written on them. The number on the i-th card (1≤i≤N) is a_i.
Because he loves big numbers, he calls a subset of the cards good when the sum of the numbers written on the cards in the subset, is K or greater.

Then, for each card i, he judges whether it is unnecessary or not, as follows:

If, for any good subset of the cards containing card i, the set that can be obtained by eliminating card i from the subset is also good, card i is unnecessary.

Otherwise, card i is NOT unnecessary.

Find the number of the unnecessary cards. Here, he judges each card independently, and he does not throw away cards that turn out to be unnecessary.

Constraints

All input values are integers.

1≤N≤5000

1≤K≤5000

1≤a_i≤10^9 (1≤i≤N)

Partial Score

300 points will be awarded for passing the test set satisfying N,K≤400.

Input

The input is given from Standard Input in the following format:

N K
a_1 a_2 ... a_N

Output

Print the number of the unnecessary cards.

Sample Input 1

3 6
1 4 3

Sample Output 1

1

There are two good sets: {2,3} and {1,2,3}.

Card 1 is only contained in {1,2,3}, and this set without card 1, {2,3}, is also good. Thus, card 1 is unnecessary.

For card 2, a good set {2,3} without card 2, {3}, is not good. Thus, card 2 is NOT unnecessary.

Neither is card 3 for a similar reason, hence the answer is 1.

Sample Input 2

5 400
3 1 4 1 5

Sample Output 2

5

In this case, there is no good set. Therefore, all the cards are unnecessary.

Sample Input 3

6 20
10 4 3 10 25 2

Sample Output 3

3

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
//using System.Data.Odbc;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Proxies;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Schema;
namespace ConsoleApplication
{
    class MainClass
    {
        ////////////////////////////////////////////////////////////////////////////////        
        int N, K;
        int[] a;
        void Solve() {
            //input
            io.i(out N, out K);
            io.ini(out a, N);
            //cal            
            Func<int, bool> check = (index) => {
                if (a[index] >= K) return true;
                var dp = new bool[K];
                dp[0] = true;
                for (int i = 0; i < N; ++i) {
                    if (i == index) continue;
                    for (int j = K - 1; j >= 0; --j) {
                        var ti = j + a[i];
                        if (dp[j] && ti < K)
                            dp[ti] = true;
                    }
                }
                for (int i = K - a[index]; i < K; ++i) if (dp[i]) return true;
                return false;
            };
            a.Sort();
            var ans = a.BinarySearch(-1, N, check);
            //ret
            io.o(ans);
        }

        ////////////////////////////////////////////////////////////////////////////////
        public static void Main() => new MainClass().Stream();
        IO io = new IO();
        Mat mat = new Mat();
        void Stream() {
            Solve();
            //Test();
            io.Flush();
        }
        void Test() {

        }
        void FOR(int a, int b, Action<int> act) {
            for (int i = a; i < b; ++i) act(i);
        }
        void FORR(int a, int b, Action<int> act) {
            for (int i = a - 1; i >= b; --i) act(i);
        }
    }
    #region Default
    class IO
    {
        #region INPUT
        int _buffCnt;
        string[] _nextBuff;
        private readonly char[] _splitCharacter = new char[] { ' ' };
        private readonly StreamWriter _sw = new StreamWriter(Console.OpenStandardOutput()) {
            AutoFlush = false
        };
        public IO() {
            _nextBuff = new string[0];
            _buffCnt = 0;
            Console.SetOut(_sw);
        }
        private string Next() {
            if (_buffCnt < _nextBuff.Length) return _nextBuff[_buffCnt++];
            var str = Scan;
            while (str == "") str = Scan;
            _nextBuff = str.Split(_splitCharacter, StringSplitOptions.RemoveEmptyEntries);
            _buffCnt = 0;
            return _nextBuff[_buffCnt++];
        }
        private string Scan => Console.ReadLine();
        private string[] Arr => Scan.Split(' ');
        private void Read<T>(out T v) => v = SuitType<T>(Next());
        private T ConvertType<T, TU>(TU v) => (T)Convert.ChangeType(v, typeof(T));
        private bool TypeEqual<T, TU>() => typeof(T) == typeof(TU);
        private T SuitType<T>(string s)
            =>
                TypeEqual<T, int>()
                    ? ConvertType<T, int>(int.Parse(s))
                    : TypeEqual<T, long>()
                        ? ConvertType<T, long>(long.Parse(s))
                        : TypeEqual<T, double>()
                            ? ConvertType<T, double>(double.Parse(s))
                            : TypeEqual<T, char>() ? ConvertType<T, char>(char.Parse(s)) : ConvertType<T, string>(s);
        public string String => Next();
        public char Char => char.Parse(Next());
        public int Int => int.Parse(Next());
        public long Long => long.Parse(Next());
        public double Double => double.Parse(Next());
        public string[] ArrString => Arr;
        public char[] ArrChar => Array.ConvertAll(Arr, char.Parse);
        public int[] ArrInt => Array.ConvertAll(Arr, int.Parse);
        public long[] ArrLong => Array.ConvertAll(Arr, long.Parse);
        public double[] ArrDouble => Array.ConvertAll(Arr, double.Parse);
        public void Flush() => Console.Out.Flush();
        private T i<T>() { return SuitType<T>(String); }
        public void i<T>(out T v) => Read(out v);
        public void i<T, TU>(out T t, out TU u) {
            i(out t);
            i(out u);
        }
        public void i<T, TU, TV>(out T t, out TU u, out TV v) {
            i(out t, out u);
            i(out v);
        }
        public void i<T, TU, TV, TW>(out T t, out TU u, out TV v, out TW w) {
            i(out t, out u, out v);
            i(out w);
        }
        public void i<T, TU, TV, TW, TX>(out T t, out TU u, out TV v, out TW w, out TX x) {
            i(out t, out u, out v, out w);
            i(out x);
        }
        public void ini<T>(out T[] a, int n) {
            a = new T[n];
            for (int i = 0; i < n; ++i) a[i] = i<T>();
        }
        public void ini<T, TU>(out T[] a, out TU[] b, int n) {
            a = new T[n];
            b = new TU[n];
            for (int i = 0; i < n; ++i) {
                a[i] = i<T>();
                b[i] = i<TU>();
            }
        }
        public void ini<T, TU, TV>(out T[] a, out TU[] b, out TV[] c, int n) {
            a = new T[n];
            b = new TU[n];
            c = new TV[n];
            for (int i = 0; i < n; ++i) {
                a[i] = i<T>();
                b[i] = i<TU>();
                c[i] = i<TV>();
            }
        }
        public void ini<T>(out T[,] a, int h, int w) {
            a = new T[h, w];
            for (int i = 0; i < h; ++i) for (int j = 0; j < w; ++j) a[i, j] = i<T>();
        }
        public void ini<T, TU>(out Tuple<T, TU>[] t, int n) {
            t = new Tuple<T, TU>[n];
            for (int j = 0; j < n; ++j) {
                T i1;
                TU i2;
                i(out i1, out i2);
                t[j] = Tuple.Create(i1, i2);
            }
        }
        public void ini<T, TU, TV>(out Tuple<T, TU, TV>[] t, int n) {
            t = new Tuple<T, TU, TV>[n];
            for (int j = 0; j < n; ++j) {
                T i1;
                TU i2;
                TV i3;
                i(out i1, out i2, out i3);
                t[j] = Tuple.Create(i1, i2, i3);
            }
        }
        #endregion
        #region OUTPUT
        private void Out<T>(T v) => Console.Write(v);
        private void OutLine<T>(T v) => Console.WriteLine(v);
        public void o<T>(T v) => OutLine(v);
        public void o<T>(params T[] a) => Array.ForEach(a, OutLine);
        public void o<T>(T[,] a) {
            int a0 = a.GetLength(0), a1 = a.GetLength(1);
            for (int i = 0; i < a0; ++i) {
                for (int j = 0; j < a1 - 1; ++j) Out(a[i, j] + " ");
                OutLine(a[i, a1 - 1]);
            }
        }
        public void ol<T>(params T[] a) => OutLine(string.Join(" ", a));
        public void YN(bool f) => OutLine(f ? "YES" : "NO");
        public void Yn(bool f) => OutLine(f ? "Yes" : "No");
        public void yn(bool f) => OutLine(f ? "yes" : "no");
        #endregion
    }
    class Mat
    {
        public long mod = 1000000007; //10^9+7
        public long Pow(long a, long b) {
            if (b == 0) return 1;
            if (b % 2 == 1) return (a % mod * Pow(a % mod, b - 1) % mod) % mod;
            else return Pow(a * a % mod, b / 2) % mod;
        }
        public long Fact(long n) {
            long ret = 1;
            for (long i = 1; i <= n; i++) ret = (ret * i) % mod;
            return ret;
        }
        public long[,] CTable(int N) {
            long[,] Co = new long[N + 1, N + 1];
            (N + 1).REP(i => (i + 1).REP(j => Co[i, j] = (j == 0 || j == i) ? 1L : Co[i - 1, j - 1] + Co[i - 1, j]));
            return Co;
        }
        public long C(long n, long r) {
            if (r == 0 || n == r) return 1;
            if (n == 0) return 0;
            if (n < 0 || r < 0 || n < r) throw new ArgumentException("n or r invalid");
            else return (Fact(n) % mod * Pow((Fact(n - r) % mod * Fact(r) % mod) % mod, mod - 2) % mod) % mod;
        }
        public long NoModC(long n, long r) {
            var c = new long[r + 1];
            c[0] = 1;
            for (var i = 1; i <= n; ++i) for (var j = Math.Min(i, r); j > 0; j--) c[j] = c[j] + c[j - 1];
            return c[r];
        }
        public long H(long n, long r) => C(n + r - 1, r);
        public long P(long n, long r) => Fact(n) / Fact(n - r);
        public long Lcm(long a, long b) => a * (b / Gcd(a, b));
        public long Lcm(params long[] a) => a.Aggregate((v, n) => Lcm(v, n));
        public long Gcd(long a, long b) {
            if (a < b) Swap(ref a, ref b);
            return b == 0 ? a : Gcd(b, a % b);
        }
        public long Gcd(params long[] array) => array.Aggregate((v, n) => Gcd(v, n));
        public T Max<T>(params T[] a) => a.Max();
        public T Min<T>(params T[] a) => a.Min();
        public void Swap<T>(ref T a, ref T b) {
            T tmp = a;
            a = b;
            b = tmp;
        }
        public Dictionary<long, long> PrimeFactor(long n) {
            var ret = new Dictionary<long, long>();
            for (int i = 2; i * i <= n; ++i) {
                if (!ret.ContainsKey(i)) ret[i] = 0;
                while (n % i == 0) {
                    ++ret[i];
                    n /= i;
                }
            }
            return ret.Where(kp => kp.Value != 0).ToDictionary(kp => kp.Key, kp => kp.Value);
        }
    }
    #endregion
    #region MyEx
    static class StringEx
    {
        public static string Reversed(this string s) => string.Join("", s.Reverse());
        public static string Repeated(this string s, int n) => string.Concat(Enumerable.Repeat(s, n).ToArray());
        public static string toString(this char[] a) => new string(a);
        public static int toInt(this string s) {
            int n;
            return (int.TryParse(s.TrimStart('0'), out n)) ? n : 0;
        }
        public static int toInt(this char c) => toInt(c.ToString());
        public static int toInt(this char[] c) => toInt(c.toString());
        public static long toLong(this string s) {
            long n;
            return (long.TryParse(s.TrimStart('0'), out n)) ? n : 0L;
        }
        public static long toLong(this char c) => toLong(c.ToString());
        public static long toLong(this char[] c) => toLong(c.toString());
    }
    static class NumericEx
    {
        public static string toString(this double d) => d.ToString("R", CultureInfo.InvariantCulture);
        public static string Pad0<T>(this T s, int n) => s.ToString().PadLeft(n, '0');
        public static string RoundOff(this double v, int n)
            => Math.Round(v, n - 1, MidpointRounding.AwayFromZero).toString();
        public static string RoundUp(this double v) => Math.Ceiling(v).toString();
        public static string RoundDown(this double v) => Math.Floor(v).toString();
        public static bool Odd(this int v) => (v & 1) != 0;
        public static bool Odd(this long v) => (v & 1) != 0;
        public static void REP(this int v, Action<int> act) {
            for (int i = 0; i < v; ++i) act(i);
        }
        public static void REPR(this int v, Action<int> act) {
            for (int i = v - 1; i >= 0; --i) act(i);
        }
        public static void EREP(this int v, Action<int> act) => (v + 1).REP(act);
    }
    static class ArrayEx
    {
        public static T[] Sort<T>(this T[] a) {
            Array.Sort(a);
            return a;
        }
        public static T[] SortR<T>(this T[] a) {
            Array.Reverse(a.Sort());
            return a;
        }
        public static void Set<T>(this T[] a, T v) => a.Length.REP(i => a[i] = v);
        public static void Set<T>(this T[,] a, T v) => a.GetLength(0).REP(i => a.GetLength(1).REP(j => a[i, j] = v));
        public static void Set<T>(this T[,,] a, T v)
            => a.GetLength(0).REP(i => a.GetLength(1).REP(j => a.GetLength(2).REP(k => a[i, j, k] = v)));
        public static int BinarySearch<T>(this T[] a, int ng, int ok, Func<int, bool> check) {
            var isLowNg = Math.Min(ng, ok) == ng;
            int low = isLowNg ? ng : ok, high = isLowNg ? ok : ng;
            while (high - low > 1) {
                var mid = (high + low) >> 1;
                if (check(mid)) high = mid;
                else low = mid;
            }
            return isLowNg ? high : low;
        }
        public static int testLowerBound<T>(this T[] a, T x) where T : IComparable
            => BinarySearch(a, -1, a.Length, (mid) => a[mid].CompareTo(x) >= 0);
        public static int testUpperBound<T>(this T[] a, T x) where T : IComparable
            => BinarySearch(a, -1, a.Length, (mid) => a[mid].CompareTo(x) > 0);
        public static int LowerBound<T>(this T[] a, T x) where T : IComparable {
            int lb = -1, ub = a.Length;
            while (ub - lb > 1) {
                int mid = (ub + lb) >> 1;
                if (a[mid].CompareTo(x) >= 0) ub = mid;
                else lb = mid;
            }
            return ub;
        }
        public static int UpperBound<T>(this T[] a, T x) where T : IComparable {
            int lb = -1, ub = a.Length;
            while (ub - lb > 1) {
                int mid = (ub + lb) >> 1;
                if (a[mid].CompareTo(x) > 0) ub = mid;
                else lb = mid;
            }
            return ub;
        }
        public static int ItemsInRange<T>(this T[] a, T from, T to) where T : IComparable
            => a.UpperBound(to) - a.LowerBound(from);
    }
    public static class FunctionalEx
    {
        public static Func<T, TV> Compose<T, TU, TV>(this Func<TU, TV> f, Func<T, TU> g) { return x => f(g(x)); }
    }
    #endregion
}