#include <bits/stdc++.h>

using namespace std;

#define MAXN 200001

int deg[MAXN];
vector<pair<int,int>> adj[MAXN];
long long dp[MAXN];

void dfs(int node,int pret)
{
    if ((int)adj[node].size()==1) return;
    for (pair<int,int> edge:adj[node])
    {
        int sled=edge.first,w=edge.second;
        if (sled==pret) continue;
        dfs(sled,node);dp[node]=max(dp[node],dp[sled]+w);
    }
}

long long newdp[2][MAXN];
long long kandidat=0;

void newdfs(int node,int pret)
{
    if ((int)adj[node].size()==1) return;
    for (pair<int,int> edge:adj[node])
    {
        int sled=edge.first,w=edge.second;
        if (sled==pret) continue;
        newdfs(sled,node);int value=newdp[0][sled]+w;
        if (value>=newdp[0][node]) {newdp[1][node]=newdp[0][node];newdp[0][node]=value;}
        else newdp[1][node]=value;
    }
}

void reroot(int node,int pret)
{
    if ((int)adj[node].size()>=3)
    {
        long long max1=0,max2=0,max3=0;
        for (pair<int,int> edge:adj[node])
        {
            int sled=edge.first,w=edge.second;
            if (newdp[0][sled]+w>=max1) {max3=max2;max2=max1;max1=newdp[0][sled]+w;}
            else if (newdp[0][sled]+w>=max2) {max3=max2;max2=newdp[0][sled]+w;}
            else if (newdp[0][sled]+w>max3) max3=newdp[0][sled]+w;
        }
        kandidat=max(kandidat,max1+max2+max3);
    }
    for (pair<int,int> edge:adj[node])
    {
        int sled=edge.first,w=edge.second;if (sled==pret) continue;
        long long value=newdp[0][sled]+w;pair<long long,long long> pamtinode={newdp[0][node],newdp[1][node]};
        if (value==newdp[0][node]) {newdp[0][node]=newdp[1][node];newdp[1][node]=0;}
        else if (value==newdp[1][node]) newdp[1][node]=0;
        pair<long long,long long> pamtisled={newdp[0][sled],newdp[1][sled]};
        if (newdp[0][node]+w>=newdp[0][sled]) {newdp[1][sled]=newdp[0][sled];newdp[0][sled]=newdp[0][node]+w;}
        else if (newdp[0][node]+w>newdp[1][sled]) newdp[1][sled]=newdp[0][node]+w;
        reroot(sled,node);newdp[0][node]=pamtinode.first;newdp[1][node]=pamtinode.second;newdp[0][sled]=pamtisled.first;newdp[1][sled]=pamtisled.second;
    }
}

void Bumerang(int n, int q, int* p, int* w, int* s, int* k, long long* ans)
{
    for (int i=2;i<=n;i++) {deg[i]++;deg[p[i]]++;}
    bool subtask2=false;
    for (int node=1;node<=n;node++)
    {
        if (deg[node]==n-1) {subtask2=true;break;}
    }
    if (subtask2)
    {
        multiset<int> weights;for (int node=2;node<=n;node++) weights.insert(w[node]);
        for (int i=1;i<=q;i++)
        {
            weights.erase(weights.find(w[s[i]]));weights.insert(k[i]);w[s[i]]=k[i];
            auto it=weights.end();long long answer=0;
            it--;answer+=(*it);it--;answer+=(*it);it--;answer+=(*it);ans[i]=answer;
        }
        return;
    }
    if (n<=200 and q<=200)
    {
        for (int i=1;i<=q;i++)
        {
            w[s[i]]=k[i];for (int i=2;i<=n;i++) {adj[i].push_back({p[i],w[i]});adj[p[i]].push_back({i,w[i]});}
            long long answer=0;
            for (int node=1;node<=n;node++)
            {
                if ((int)adj[node].size()<3) continue;
                vector<long long> sumice;for (int node=1;node<=n;node++) dp[node]=0;
                for (pair<int,int> edge:adj[node]) {dfs(edge.first,node);sumice.push_back(dp[edge.first]+edge.second);}
                sort(sumice.begin(),sumice.end());reverse(sumice.begin(),sumice.end());
                answer=max(answer,sumice[0]+sumice[1]+sumice[2]);sumice.clear();
            }
            ans[i]=answer;for (int node=1;node<=n;node++) adj[node].clear();
        }
        return;
    }
    if (q==1)
    {
        /// rerooting ne radi provericemo zasto ne radi al mislim da sam jako blizu od togqa da ga izdebugujem da radi
        w[s[1]]=k[1];for (int i=2;i<=n;i++) {adj[i].push_back({p[i],w[i]});adj[p[i]].push_back({i,w[i]});}
        long long answer=0;for (int node=1;node<=n;node++) {newdp[0][node]=0;newdp[1][node]=0;}
        newdfs(1,0);reroot(1,0);ans[1]=kandidat;return;
    }
};