//https://dwacon6th-prelims.contest.atcoder.jp/tasks/dwacon6th_prelims_e

// :(

#ifndef LOCAL
#define NDEBUG 1
#endif
#include<bits/stdc++.h>

#define MODULAR_LESS_EFFICIENT_BUT_EASIER_TO_CODE 1
int const MOD=1000000007;
struct modular {
	int val;
	explicit constexpr operator int() const { return val; }
	constexpr modular():val(){}
#if MODULAR_LESS_EFFICIENT_BUT_EASIER_TO_CODE
	constexpr modular(auto v):val(int(v%MOD)){ if(val<0)val+=MOD; }
#else
	constexpr modular(int v):val(v){
		assert(0<=v and v<MOD);
	}
#endif

#define COMPAREOP(OP) bool constexpr operator OP(modular b) const { return val OP b.val; }
	COMPAREOP(==) COMPAREOP(!=) COMPAREOP(<) COMPAREOP(>) COMPAREOP(<=) COMPAREOP(>=)
#undef COMPAREOP

	friend modular constexpr operator-(modular x) { x.val=x.val?MOD-x.val:0; return x; }
	modular constexpr& operator+=(modular m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
	modular constexpr& operator-=(modular m) { if ((val -= m.val) < 0) val += MOD; return *this; }
	modular constexpr& operator*=(modular m) {
		if(__builtin_constant_p(m.val)){
			switch(m.val){
				case 1: return *this;
				case 2: return *this+=*this;
				case 3: return *this+=*this+*this;
				case 0: return *this=0;
				case -1: return *this=-*this;
			}
		}else if(__builtin_constant_p(val)){
			*this=m**this;
		}
		val = int((int64_t)val*m.val%MOD);
		return *this;
	}
	modular constexpr pow(int p) const {
		modular a=*this;
		modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	modular constexpr inv() const {
		int a=val,b=MOD, ax=1,bx=0;
		while(b){
			int q=a/b, t=a%b;
			a=b; b=t;
			t=ax-bx*q; ax=bx; bx=t;
		}
		assert(a==1);
		if(ax<0)ax+=MOD;
		return ax;
	}
	modular constexpr& operator/=(modular m) { return (*this) *= m.inv(); }

#define ARITHBINARYOP(OP) friend modular constexpr operator OP(modular a, modular b) { return a OP##= b; }
	ARITHBINARYOP(+) ARITHBINARYOP(-) ARITHBINARYOP(*) ARITHBINARYOP(/)
#undef ARITHBINARYOP
};

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int number, len; std::cin>>number>>len;
	std::vector<int> segments(number);for(auto & x: segments) std::cin>>x;
	std::sort(begin(segments),end(segments), std::greater<>());
	std::vector<std::vector<modular>> f(1, std::vector<modular>{1});
	// f[number of segments][total segments length] = number of combinations
	// (the order/placement of different segments does not matter)
	for(auto x: segments){
		std::vector<std::vector<modular>> g(1+f.size(), std::vector<modular>(len+1)); // value of f int next iteration

		for(int numSegment=0;numSegment<(int)f.size();++numSegment)
			for(int totalLen=0;totalLen<(int)f[numSegment].size();++totalLen) {
				auto const cur=f[numSegment][totalLen];
				auto const update=[&](int numSegment, int totalLen, modular multiple){
					if(totalLen+numSegment-1<=len)
						g[numSegment][totalLen]+=cur*multiple;
				};

				update(numSegment+1, totalLen+x, 1);
				for(int extra=1;extra<=x;++extra) {
					if(numSegment)
						update(numSegment, totalLen+extra, numSegment*2);
					if(numSegment>1)
						update(numSegment-1, totalLen+extra, numSegment*(numSegment-1)*(x-extra+1)); // can't overflow
				}
				if(numSegment!=0)
					update(numSegment, totalLen, totalLen-numSegment*(x-1));
			}

		f=std::move(g);
	}

	std::cout<<(int)f[1][len]<<'\n';
}



Measured memory_bytes: 640