#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=101,mod=1e9+7;
int n,l;
ll a[N],dp[N][N][1001][3];
//dp[i][j][k][t]:前i个数中,有j个连续段(这是连续段DP中常用的概念,此处不多叙述),总和为k,有t个碰到边界
int main(){
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n>>l;
for(int i=1;i<=n;i++) cin>>a[i];
if(n==1){
//特判
cout<<1<<'\n';
return 0;
}
sort(a+1,a+1+n);//排序去掉绝对值
dp[0][0][0][0]=1;//初始化
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
for(int k=0;k<=l;k++)
for(int t=0;t<=2;t++){
ll val=(2*j-t)*(a[i+1]-a[i]);
//计算插入这个数对于总和的贡献:当前有j个连续段,每个段有两个端点,扣除t个后,共2j-t个端点可累加差
//这意味着它们最终必须和某个“更大的数”(从小到大插入a[i+1])相连,即对于每个端点,最后都会“连上”一个>=a[i+1]的数,对和的贡献必然有且仅有一个a[i+1]-a[i]
/*
如:
段1: a_1 — a_3 段2: a_2
↑ ↑ ↑ ↑
端点 端点 端点 端点
(没有点在端点上)
共 2*j-t=4 个悬空端点。
现在插入 a4,贡献为a4−a3。
这 4 个端点未来都要连向 ≥a4 的数,每条边都跨过(a3,a4]。所以这一步贡献:4*(a4-a3)
(假设a2最后右边与a6相连,则对和的贡献相当于a6-a2,即(a6-a5)+(a5-a4)+(a4-a3))
*/
if(!dp[i][j][k][t] || val+k>l || 2*j<t) continue;
//接下来分类讨论对方案的贡献
dp[i+1][j][k+val][t]=(dp[i+1][j][k+val][t]+dp[i][j][k][t]*(2*j-t)%mod)%mod;//接在某个段的端点(不碰边界)
if(t<2) dp[i+1][j][k+val][t+1]=(dp[i+1][j][k+val][t+1]+dp[i][j][k][t]*(2-t)%mod)%mod;//接在某个段的端点(碰边界)
if(j>0) dp[i+1][j-1][k+val][t]=(dp[i+1][j-1][k+val][t]+dp[i][j][k][t]*(j-1)%mod)%mod;//将两个段合并
dp[i+1][j+1][k+val][t]=(dp[i+1][j+1][k+val][t]+dp[i][j][k][t]*(j+1-t))%mod;//单独成段,不碰边界
if(t<2) dp[i+1][j+1][k+val][t+1]=(dp[i+1][j+1][k+val][t+1]+dp[i][j][k][t]*(2-t)%mod)%mod;//单独成段,在边界
}
ll ans=0;
for(int i=0;i<=l;i++) (ans+=dp[n][1][i][2])%=mod;//累加答案
cout<<ans<<'\n';
return 0;
}