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.Generic;
using System.Linq;
using System.IO;
using System.Text;
using static System.Math;
using static System.Array;
using static AtCoder.Tool;
using static AtCoder.CalcL;
namespace AtCoder
{
    class AC
    {
        const int MOD = 1000000007;
        //const int MOD = 998244353;
        const int INF = int.MaxValue / 2;
        const long SINF = long.MaxValue / 2;
        const double EPS = 1e-8;
        static readonly int[] dI = { 0, 1, 0, -1 };
        static readonly int[] dJ = { 1, 0, -1, 0 };
        //static List<List<int>> G = new List<List<int>>();
        //static List<List<Edge>>G = new List<List<Edge>>();
        //static List<Edge> E = new List<Edge>();
        static void Main(string[] args)
        {
            //var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            //Console.SetOut(sw);
            var cin = new Scanner();

            var input = cin.ReadSplitInt();
            int N = input[0];
            int K = input[1];
            var a = cin.ReadSplitInt();
            var dp1 = new bool[N + 1, K + 1];
            var dp2 = new bool[N + 1, K + 1];
            dp1[0, 0] = true;
            dp2[0, 0] = true;

            for(var i = 0; i < N; i++)
            {
                for(var j = 0; j <= K; j++)
                {
                    if (j - a[i] >= 0) dp1[i + 1, j] |= dp1[i, j - a[i]];
                    dp1[i + 1, j] |= dp1[i, j];

                    if (j - a[N - 1 - i] >= 0) dp2[i + 1, j] |= dp2[i, j - a[N - 1 - i]];
                    dp2[i + 1, j] |= dp2[i, j];
                }
            }

            int ans = N;
            var f = new List<int>();
            var b = new List<int>();

            for(var i = 0; i < N; i++)
            {
                f.Clear();b.Clear();
                for(var j = 0; j <= K; j++)
                {
                    if (dp1[i, j]) f.Add(j);
                    if (dp2[N - i - 1, K - j]) b.Add(K - j);
                }

                int fi = 0;
                int bi = 0;
                while (true)
                {
                    if (f[fi] + b[bi] < K - a[i]) fi++;
                    else if (f[fi] + b[bi] >= K) bi++;
                    else
                    {
                        ans--;break;
                    }
                    if (fi >= f.Count() || bi >= b.Count()) break;
                }
            }
            Console.WriteLine(ans);


            //Console.Out.Flush();
        }
        struct Edge
        {
            public int from;

            public int to;
            public long dist;
            public Edge(int t, long c)
            {
                from = -1;
                to = t;
                dist = c;
            }
            public Edge(int f, int t, long c)
            {
                from = f;
                to = t;
                dist = c;
            }

        }
    }
    public class Scanner
    {
        public int[] ReadSplitInt()
        {
            return ConvertAll(Console.ReadLine().Split(), int.Parse);
        }
        public long[] ReadSplitLong()
        {
            return ConvertAll(Console.ReadLine().Split(), long.Parse);
        }
        public double[] ReadSplit_Double()
        {
            return ConvertAll(Console.ReadLine().Split(), double.Parse);
        }
    }
    public static class Tool
    {
        static public void Initialize<T>(ref T[] array, T initialvalue)
        {
            for (var i = 0; i < array.Length; i++)
            {
                array[i] = initialvalue;
            }
        }
        static public void Swap<T>(ref T a, ref T b)
        {
            T keep = a;
            a = b;
            b = keep;
        }

        static public void Display<T>(T[,] array2d, int n, int m)
        {
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < m; j++)
                {
                    Console.Write($"{array2d[i, j]} ");
                }
                Console.WriteLine();
            }
        }

        static public long LPow(int a, int b)
        {
            return (long)Pow(a, b);
        }
    }
    static public class CalcI
    {
        public static int Gcd(int a, int b)
        {
            if (a * b == 0) { return Max(a, b); }
            return a % b == 0 ? b : Gcd(b, a % b);
        }
        public static int Lcm(int a, int b)
        {
            int g = Gcd(a, b);
            return a / g * b;
        }
        public static int Ceil(int n, int div)
        {
            return (n + div - 1) / div;
        }
    }
    static public class CalcL
    {
        public static long Gcd(long a, long b)
        {
            if (a * b == 0) { return Max(a, b); }
            return a % b == 0 ? b : Gcd(b, a % b);
        }
        public static long Lcm(long a, long b)
        {
            long g = Gcd(a, b);
            return a / g * b;
        }
        public static long Ceil(long n, long div)
        {
            return (n + div - 1) / div;
        }
    }
    class Modulo
    {
        private const int M = 1000000007;
        private readonly int[] m_facs;
        public int Mul(int a, int b)
        {
            return (int)(Math.BigMul(a, b) % M);
        }
        public Modulo(int n)
        {
            m_facs = new int[n + 1];
            m_facs[0] = 1;
            for (int i = 1; i <= n; ++i)
            {
                m_facs[i] = Mul(m_facs[i - 1], i);
            }
        }
        public int Fac(int n)
        {
            return m_facs[n];
        }
        public int Pow(int a, int m)
        {
            switch (m)
            {
                case 0:
                    return 1;
                case 1:
                    return a;
                default:
                    int p1 = Pow(a, m / 2);
                    int p2 = Mul(p1, p1);
                    return ((m % 2) == 0) ? p2 : Mul(p2, a);
            }
        }
        public int Div(int a, int b)
        {
            return Mul(a, Pow(b, M - 2));
        }
        public int Ncr(int n, int r)
        {
            if (n < r) { return 0; }
            if (n == r) { return 1; }
            int res = Fac(n);
            res = Div(res, Fac(r));
            res = Div(res, Fac(n - r));
            return res;
        }
        public Modulo() { }
    }
}