#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int MAXN = 200005,INF = 1E9+1;
typedef long long LL;
int size[MAXN]; 
bool vis[MAXN];
vector<int> edge[MAXN];
vector<pair<int,int> > a;
map<int,int> Map;
vector<int> b;
int p[MAXN];
LL ans;
int n,d;
int root,totsize,maxSize;
class BITree{
public:
    static const int SIZE = 250010, BIAS = 5;
  	long long u[SIZE];
    void clear(){
        memset(u,0,sizeof(u));
    }
    void modify(int x, long long v){
        for(x+=BIAS;x<SIZE;x+=x&-x) u[x]+=v;
    }
    long long getsum(int x){
        long long s=0;
        for(x+=BIAS;x;x-=x&-x) s+=u[x];
        return s;
    }
    long long getsumR(int x)
    {
    	return getsum(SIZE-10) - getsum(x-1);
    }
} B;
void calc(int u,int fa)
{
	size[u] = 1;
	for (int v:edge[u])
	{
		if (v!=fa && vis[v]==false)
		{
			calc(v,u);
			size[u]+=size[v];
		}
	}
}
void getRoot(int u,int fa)
{
	int mx = -1;
	for (int v:edge[u])
	{
		if (v!=fa && vis[v]==false)
		{
			getRoot(v,u);
			mx = max(mx,size[v]);
		}
	}
	mx = max(mx,totsize - size[u]);
	if (mx < maxSize)
	{
		maxSize = mx;
		root = u;
	}
}
int search(int u,int fa)
{
	maxSize = 1e9; root = u;
	calc(u,fa);
	totsize = size[u];
	getRoot(u,fa);
	return root;
}
void dfs(int u,int fa,int Max,int Min)
{
	Max = max(Max,p[u]);
	Min = min(Min,p[u]);
	if (Max-Min<=d)a.push_back(make_pair(Min,Max));
	for (int v:edge[u])
		if (v!=fa && vis[v]==false) dfs(v,u,Max,Min);
}
void debug()
{
	
}
void solve(int u,int fa)
{
	if (fa!=-1) vis[fa] = true;
	int newroot = search(u,fa);
	//B.clear();
	a.clear();
	for (int v:edge[newroot])
		if (v!=fa && vis[v]==false) dfs(v,newroot,p[newroot],p[newroot]);
	a.push_back(make_pair(p[newroot],p[newroot]));
	sort(a.begin(),a.end());
	if (newroot==5) debug();
	for (int i=0;i<a.size();i++)
	{
		ans += B.getsumR(Map[a[i].second-d]);
		B.modify(Map[a[i].first],1);
	}
	for (int i=0;i<a.size();i++) B.modify(Map[a[i].first],-1);
	for (int v:edge[newroot])
	{
		if (v!=fa && vis[v]==false)
		{
			a.clear();
			dfs(v,newroot,p[newroot],p[newroot]);
			sort(a.begin(),a.end());
			for (int i=0;i<a.size();i++)
			{
				ans -= B.getsumR(Map[a[i].second-d]);
				B.modify(Map[a[i].first],1);
			}
			for (int i=0;i<a.size();i++) B.modify(Map[a[i].first],-1);
		}
	}
	for (int v:edge[newroot])
		if (v!=fa && vis[v]==false) solve(v,newroot);
}
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		memset(vis,0,sizeof(vis));
		scanf("%d%d",&n,&d);
		Map.clear();
		for (int i=1;i<=n;i++) 
		{
			scanf("%d",p+i);
			Map[p[i]]++;
			Map[p[i]-d]++;
		}
		int tot = 2;
		for (auto &x:Map)
		{
			tot++;
			x.second = tot;
		} 
		for (int i=1;i<=n;i++) edge[i].clear();
		for (int i=0;i<n-1;i++) 
		{
			int x,y;
			scanf("%d%d",&x,&y);
			edge[x].push_back(y);
			edge[y].push_back(x);
		}
		ans = 0;
		solve(1,-1);
		printf("%lld\n",ans*2);
	}
} 
