#include<bits/stdc++.h>
using namespace std;

const int N=5e3+5;
const int MOD=998244353;

int ADD(int x,int y){return (x+=y)>=MOD?x-MOD:x;}
int SUB(int x,int y){return (x-=y)<0?x+MOD:x;}
int TIME(int x,int y){return (int)(1ll*x*y%MOD);}
int ksm(int x,int k=MOD-2){int res=1;for(;k;k>>=1,x=TIME(x,x))if(k&1)res=TIME(res,x);return res;}

int fact[N],ifact[N];
void init(){
    fact[0]=1;
    for(int i=1;i<N;++i) fact[i]=TIME(fact[i-1],i);
    ifact[N-1]=ksm(fact[N-1]);
    for(int i=N-1;i>=1;--i) ifact[i-1]=TIME(ifact[i],i);
}

int n,rt,a[N];
struct Edge{int nxt,to;}e[N*2];int fir[N];
void add(int u,int v,int i){e[i]=(Edge){fir[u],v},fir[u]=i;}

int fa[N],sub[N];
void dfs(int u){
    sub[u]=a[u];
    for(int i=fir[u];i;i=e[i].nxt){
        int v=e[i].to;if(v==fa[u]) continue;
        fa[v]=u,dfs(v),sub[u]=min(sub[u],sub[v]);
    }
}

bool vis[N];int dis[N][N],res=0;

void walk(int rt,int u,int pos,int mn){
    mn=min(mn,a[u]),dis[rt][u]=ADD(dis[rt][u],TIME(pos,mn));
    vector<int> bag,id;
    for(int i=fir[u];i;i=e[i].nxt){
        int v=e[i].to;if(v==fa[u]) continue;
        id.push_back(bag.size()),bag.push_back(v);
    }
    while(1){
        int tmp=1e9+7;
        for(auto x:id){
            walk(rt,bag[x],TIME(pos,ifact[(int)bag.size()]),min(mn,tmp));
            tmp=min(tmp,sub[bag[x]]);
        }
        
        bool flag=false;
        for(int i=1;i<(int)id.size();++i) if(id[i-1]<id[i]) flag=true;
        if(!flag) break;
        next_permutation(id.begin(),id.end());
    }
}

int solve(){
    cin>>n>>rt;
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);

    for(int i=1;i<=n;++i) fir[i]=0;
    for(int i=1;i<n;++i){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v,i<<1),add(v,u,i<<1|1);
    }

    fa[rt]=0,dfs(rt),res=0;
    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) dis[i][j]=0;
    for(int i=1;i<=n;++i) walk(i,i,1,1e9+7);
    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) res=ADD(res,dis[i][j]);
    
    printf("%d\n",res);

    return 0;
}

int main(){
    freopen("dfs.in","r",stdin);
    freopen("dfs.out","w",stdout);

    init();

    int T;cin>>T;
    while(T--) solve();
}

/*
我们先考虑一个节点向一个方向移动的情况。
如果走向了错误的方向，那么显然会走完整棵树，所以我们直接考虑求出每一个子树中的最小值。
如果走向了正确的方向，那么显然不会走回来。

再考虑，如果你知道了在当前子树走了一趟的最小值。

我们好像可以尝试枚举最小值，然后求出此最小值对应的方案数，
*/