%%%LargestJN
令
fi
表示点
i
子树的答案,
假如点
i
不在环上,答案就是
假如点
#include<bits/stdc++.h>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
char c=nc();
for(;c<'0'||c>'9';c=nc());
for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
}
#define N 200010
#define M 20
vector<int>g[N],a[N];
int i,j,k,n,m,p,c[N];
int f[N];
int s[N],t[N],w[N];
int L[N],R[N],num,F[N][M],d[N];
inline void Dfs(int x){
L[x]=++num;d[x]=d[F[x][0]]+1;
for(int j=1;j<M;j++)F[x][j]=F[F[x][j-1]][j-1];
for(int i=0;i<g[x].size();i++)Dfs(g[x][i]);
R[x]=num;
}
inline int Lca(int x,int y){
if(d[x]<d[y])swap(x,y);
for(int i=M-1;i>=0;i--)if(d[F[x][i]]>=d[y])x=F[x][i];
if(x==y)return x;
for(int i=M-1;i>=0;i--)
if(F[x][i]!=F[y][i])x=F[x][i],y=F[y][i];
return F[x][0];
}
inline void Update(int x,int y){
for(;x<=n;x+=x&-x)c[x]+=y;
}
inline void Merge(int x,int y,int z){
Update(x,z);Update(y+1,-z);
}
inline int Query(int x){
int Ans=0;
for(;x;x-=x&-x)Ans+=c[x];
return Ans;
}
inline void Solve(int x){
int S=0;
for(int i=0;i<g[x].size();i++){
Solve(g[x][i]);
S+=f[g[x][i]];
}
f[x]=S;
for(int i=0;i<a[x].size();i++){
int y=a[x][i];
f[x]=max(f[x],Query(L[s[y]])+Query(L[t[y]])+S+w[y]);
}
Merge(L[x],R[x],S-f[x]);
}
int main(){
Read(n);Read(m);
for(i=2;i<=n;i++)Read(F[i][0]),g[F[i][0]].push_back(i);
Dfs(1);
for(i=1;i<=m;i++)Read(s[i]),Read(t[i]),Read(w[i]),a[Lca(s[i],t[i])].push_back(i);
Solve(1);
cout<<f[1]<<endl;
return 0;
}