//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath>
const int N=1e5+7;
const int mod=1e9+7;
typedef long long LL;
using namespace std;
int rt,n,y,D,T,c,q,data[N][2][2],ch[N][2],col[N],lz[N];
LL ans;
template<typename T> void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
struct node{
int d[2];
friend bool operator <(const node &A,const node&B) {
return A.d[D]<B.d[D];
}
}a[N],tp;
int ecnt,fir[N],nxt[N],to[N],fa[N];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
}
int dfs_clock,dfn[N],low[N],R[N];
void dfs(int x) {
dfn[x]=low[x]=++dfs_clock;
R[x]=R[fa[x]]+1;
a[x].d[0]=dfn[x]; a[x].d[1]=R[x];
for(int i=fir[x];i;i=nxt[i]) {
dfs(to[i]);
low[x]=max(low[x],low[to[i]]);
}
}
void update(int x) {
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
data[x][i][j]=a[x].d[i];
for(int i=0;i<2;i++)
if(y=ch[x][i])
for(int j=0;j<2;j++)
data[x][j][0]=min(data[x][j][0],data[y][j][0]),
data[x][j][1]=max(data[x][j][1],data[y][j][1]);
}
#define lc ch[x][0]
#define rc ch[x][1]
int build(int l,int r,int k) {
if(l>r) return 0;
D=k;
int mid=((l+r)>>1);
nth_element(a+l,a+mid,a+r+1);
ch[mid][0]=build(l,mid-1,k^1);
ch[mid][1]=build(mid+1,r,k^1);
update(mid);
return mid;
}
void down(int x) {
if(!lz[x]) return;
if(lc) col[lc]=col[x],lz[lc]=1;
if(rc) col[rc]=col[x],lz[rc]=1;
lz[x]=0;
}
int in(int x) {
return data[x][0][0]<=tp.d[0]&&data[x][0][1]>=tp.d[0]
&&data[x][1][0]<=tp.d[1]&&data[x][1][1]>=tp.d[1];
}
int ok(int x,int l1,int r1,int l2,int r2) {
int f=1;
if(!((data[x][0][0]>=l1&&data[x][0][0]<=r1)
||(data[x][0][1]>=l1&&data[x][0][1]<=r1)||
(data[x][0][0]<=l1&&data[x][0][1]>=r1))) f=0;
if(!((data[x][1][0]>=l2&&data[x][1][0]<=r2)
||(data[x][1][1]>=l2&&data[x][1][1]<=r2)||
(data[x][1][0]<=l2&&data[x][1][1]>=r2))) f=0;
return f;
}
int find(int x) {
if(a[x].d[0]==tp.d[0]&&a[x].d[1]==tp.d[1]) return col[x];
down(x); int res=0;
if(in(lc)) res=find(lc);
if(!res&&in(rc)) res=find(rc);
return res;
}
void change(int x,int l1,int r1,int l2,int r2,int v) {
if(data[x][0][0]>=l1&&data[x][0][1]<=r1&&
data[x][1][0]>=l2&&data[x][1][1]<=r2) {
col[x]=v,lz[x]=1; return;
}
down(x);
if(a[x].d[0]>=l1&&a[x].d[0]<=r1&&
a[x].d[1]>=l2&&a[x].d[1]<=r2) col[x]=v;
if(ok(lc,l1,r1,l2,r2)) change(lc,l1,r1,l2,r2,v);
if(ok(rc,l1,r1,l2,r2)) change(rc,l1,r1,l2,r2,v);
}
void work() {
dfs(1);
for(int i=1;i<=n;i++) col[i]=1,lz[i]=0;
rt=build(1,n,0);
for(int i=1;i<=q;i++) {
int x,h,c;
read(x); read(h); read(c);
if(!c) {
tp.d[0]=dfn[x]; tp.d[1]=R[x];
(ans+=(LL)i*(find(rt)))%=mod;
}
else change(rt,dfn[x],low[x],R[x],R[x]+h,c);
}
printf("%lld\n",ans);
}
void init() {
read(T);
while(T--) {
read(n);
read(c);
read(q);
for(int i=2;i<=n;i++) {
read(fa[i]);
add(fa[i],i);
}
work();
ans=0; ecnt=0;
memset(fir,0,sizeof(fir));
memset(data,0,sizeof(data));
memset(ch,0,sizeof(ch));
}
}
int main() {
init();
return 0;
}