#include <bits/stdc++.h>
#define int long long
using namespace std;
vector<int> adj[800005];
int ar[800005];
int n, q, w;
struct path
{
    int l, d, mxpre, mxsuf;
    path(int x = 0)
    {
        l = d = mxpre = mxsuf = x;
    }
    friend path operator+(path &a, path &b)
    {
        path c;
        c.l = a.l + b.l;
        c.mxsuf = max(b.mxsuf, a.mxsuf + b.l);
        c.mxpre = max(a.mxpre, b.mxpre + a.l);
        c.d = max({a.d, b.d, a.mxsuf + b.mxpre});
        return c;
    }
} paths[1000005];
struct point
{
    int mx, d;
    point(int x = 0)
    {
        mx = d = x;
    }
    friend point operator+(point &a, point &b)
    {
        point c;
        c.mx = max(a.mx, b.mx);
        c.d = max({a.d, b.d, a.mx + b.mx});
        return c;
    }
} points[1000005];
vector<pair<int, int>> l, r;
struct sttttree
{
    int sz[800005], hv[800005], l[800005], r[800005], p[800005], type[800005], pa[800005];
    int cur = 0, rt;
    void dfs(int u, int p)
    {
        pa[u] = p;
        sz[u] = 1;
        for (auto x : adj[u])
        {
            if (x == p)
                continue;
            dfs(x, u);
            sz[u] += sz[x];
            if (sz[x] > sz[hv[u]])
                hv[u] = x;
        }
    }
    void build(int x)
    {
        dfs(x, 0);
        cur = n + n - 1;
        rt = compress(x).first;
    }
    int add(int t, int lch, int rch, int ty)
    {
        if (t == 0)
            t = ++cur;
        type[t] = ty;
        // cerr<<t<<" "<<lch<<"\n";
        if (lch)
            p[lch] = t;
        if (rch)
            p[rch] = t;
        l[t] = lch, r[t] = rch;
        return t;
    }
    pair<int, int> merge(vector<pair<int, int>> &v, int type)
    {
        if (v.size() == 1)
            return v[0];
        int sz = 0;
        vector<pair<int, int>> l, r;
        for (auto x : v)
        {
            sz += x.second;
        }
        for (auto x : v)
        {
            if (x.second <= sz)
                l.push_back(x);
            else
                r.push_back(x);
            sz -= 2 * x.second;
        }
        auto a = merge(l, type);
        auto b = merge(r, type);
        l.clear();
        r.clear();
        return {add(0, a.first, b.first, type), a.second + b.second};
    }
    pair<int, int> compress(int x)
    {
        // cerr<<"compress:"<<x<<"\n";
        vector<pair<int, int>> v;
        for (; x; x = hv[x])
            v.push_back(add_vertex(x));
        // for(auto x:v)cerr<<x.first<<" "<<x.second<<"\n";
        // cerr<<"compress con:"<<v[0].first<<"\n";
        return merge(v, 1);
    }
    pair<int, int> add_vertex(int x)
    {
        // cerr<<"add_vertex:"<<x<<"\n";
        pair<int, int> v = rake(x);
        // cerr<<"add vertex con:"<<v.first<<" "<<v.second<<"\n";
        pair<int, int> ans = {add(x, v.first, 0, v.second == 0 ? 3 : 2), v.second + 1};
        // cerr<<"added ver:"<<ans.first<<" "<<ans.second<<"\n";
        return ans;
    }
    pair<int, int> rake(int x)
    {
        // cerr<<"rake:"<<x<<"\n";
        vector<pair<int, int>> v;
        for (auto a : adj[x])
            if (a != hv[x] && a != pa[x])
                v.push_back(add_edge(a));
        if (v.size() == 0)
            return {0, 0};
        return merge(v, 4);
    }
    pair<int, int> add_edge(int x)
    {
        // cerr<<"add edge"<<x<<"\n";
        pair<int, int> v = compress(x);
        return {add(0, v.first, 0, 5), v.second};
    }
} tr;
path compress(path a, path b)
{
    return a + b;
}
path add_vertex(point x, int val)
{
    path a;
    a.l = val;
    a.mxpre = a.mxsuf = x.mx + val;
    a.d = max(x.d, val + x.mx);
    return a;
}
path vertex(int x)
{
    path a(x);
    return a;
}
point rake(point a, point b)
{
    return a + b;
}
point add_edge(path a)
{
    point x;
    x.mx = a.mxpre, x.d = a.d;
    return x;
}
void upd(int u, int t)
{
    if (t == 1)
    {
        paths[u] = compress(paths[tr.l[u]], paths[tr.r[u]]);
    }
    else if (t == 2)
    {
        paths[u] = add_vertex(points[tr.l[u]], ar[u]);
    }
    else if (t == 3)
    {
        paths[u] = vertex(ar[u]);
    }
    else if (t == 4)
    {
        points[u] = rake(points[tr.l[u]], points[tr.r[u]]);
    }
    else
    {
        points[u] = add_edge(paths[tr.l[u]]);
    }
}
void change(int u)
{
    for (; u; u = tr.p[u])
        upd(u, tr.type[u]);
}
void dfs(int u)
{
    if (tr.l[u])
        dfs(tr.l[u]);
    if (tr.r[u])
        dfs(tr.r[u]);
    upd(u, tr.type[u]);
    // cout<<u<<" ";
    /*if(tr.type[u]<=3){
        cout<<"paths:"<<paths[u].d<<" "<<paths[u].l<<" "<<paths[u].mxpre<<" "<<paths[u].mxsuf<<"\n";
    }else{
        cout<<"points:"<<points[u].d<<" "<<points[u].mx<<"\n";
    }
    if(u==11)cout<<"11:"<<tr.l[u]<<" "<<tr.r[u]<<" "<<tr.type[u]<<"\n";*/
}
int32_t main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q >> w;
    int cur = n;
    for (int i = 1; i < n; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        adj[a].push_back(++cur);
        adj[cur].push_back(a);
        adj[b].push_back(cur);
        adj[cur].push_back(b);
        ar[cur] = c;
    }
    // cerr<<"work\n";
    tr.build(1);
    // printt(tr.rt);
    // cerr<<"work\n";
    dfs(tr.rt);
    // cerr<<"ANS:\n";
    // cerr<<paths[tr.rt].d<<"\n";
    int last = 0;
    // cerr<<"still work\n";
    for (int i = 0; i < q; i++)
    {
        int d, e;
        cin >> d >> e;
        d = (d + last) % (n - 1);
        e = (e + last) % w;
        ar[d + n + 1] = e;
        change(d + n + 1);
        // dfs(tr.rt);
        cout << (last = paths[tr.rt].d) << "\n";
    }
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |