Problem:
Score : 1100 points

Problem Statement

Niwango bought a piece of land that can be represented as a half-open interval [0, X).

Niwango will lay out N vinyl sheets on this land. The sheets are numbered 1,2, \ldots, N, and they are distinguishable.
For Sheet i, he can choose an integer j such that 0 \leq j \leq X - L_i and cover [j, j + L_i) with this sheet.

Find the number of ways to cover the land with the sheets such that no point in [0, X) remains uncovered, modulo (10^9+7).
We consider two ways to cover the land different if and only if there is an integer i (1 \leq i \leq N) such that the region covered by Sheet i is different.

Constraints

1 \leq N \leq 100

1 \leq L_i \leq X \leq 500

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N X
L_1 L_2 \ldots L_N

Output

Print the answer.

Sample Input 1

3 3
1 1 2

Sample Output 1

10

If we ignore whether the whole interval is covered, there are 18 ways to lay out the sheets.

Among them, there are 4 ways that leave [0, 1) uncovered, and 4 ways that leave [2, 3) uncovered.

Each of the other ways covers the whole interval [0,3), so the answer is 10.

Sample Input 2

18 477
324 31 27 227 9 21 41 29 50 34 2 362 92 11 13 17 183 119

Sample Output 2

134796357

Find the number of ways modulo (10^9+7).

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
#define exp exp69
using namespace std;
const int N=102;
const int VAL=502;
const int mod=1e9+7;
int exp[VAL][VAL],cnt[VAL],dp[VAL][VAL],inv[VAL],fact[VAL],ndp[VAL][VAL];
int mul(int x,int y){
	return (1ll*x*y)%mod;
}
void add(int &x,int y){
	x+=y;
	if(x>=mod){
		x-=mod;
	}
}
void sub(int &x,int y){
	x-=y;
	if(x<0){
		x+=mod;
	}
}
int binpow(int x,int y){
	int tich=1;
	while(y){
		if(y&1){
			tich=mul(tich,x);
		}
		x=mul(x,x);
		y>>=1;
	}
	return tich;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n,sum,i,j,k,l,ans=1,z;
	cin>>n>>sum;
	for(i=1;i<=n;i++){
		cin>>j;
		cnt[j]++;
		ans=mul(ans,sum-j+1);
	}
	fact[0]=inv[0]=1;
	for(i=1;i<=sum;i++){
		fact[i]=mul(fact[i-1],i);
		inv[i]=binpow(fact[i],mod-2);
		exp[i][0]=1;
		for(j=1;j<=sum;j++){
			exp[i][j]=mul(exp[i][j-1],i);
		}
	}
	for(i=1;i<sum;i++){		//i blank space
		dp[i+1][sum-i]=fact[i+1];
		if(!(i&1)){
			dp[i+1][sum-i]=mod-dp[i+1][sum-i];
		}
	}
	for(i=0;i<=sum;i++){		//value
		for(j=0;j<=sum;j++){	//number of val
			if(j*i>sum){
				break;
			}
			for(k=j*i;k<=sum;k++){		//sum left
				for(l=j;l<=sum;l++){	//element left
					if(l*i>k){
						break;
					}
					z=mul(dp[l][k],inv[j]);
					if(cnt[i]){
						assert(k-l*(i-1)>=0);
						z=mul(z,exp[k-l*(i-1)][cnt[i]]);
					}
					assert(l-j>=0&&k-i*j>=0);
					add(ndp[l-j][k-i*j],z);
				}
			}
		}
		for(j=0;j<=sum;j++){		//sum left
			for(k=0;k<=sum;k++){		//element left
				if(k*i>j){
					break;
				}
				dp[k][j]=ndp[k][j];
				ndp[k][j]=0;
			}
		}
	}
	sub(ans,dp[0][0]);
	cout<<ans;
}