#include <bits/stdc++.h>
using namespace std;
struct graph {
  int n = 0;
  int centroid;
  vector<vector<int>> e;
  vector<int> nodes;
  vector<int> leftint, rightint;
  vector<int> comp, comproot;
  vector<long long> compbest;
  multiset<long long> m;
  int segSize = 1;
  vector<long long> seg, segOff;
  long long diam;
  long long diameter() {
    if (m.size() == 1)
      return diam = *m.begin();
    else
      return diam = *(--m.end()) + *(--(--m.end()));
  }
  void segUpdate(int a, int b, long long v, int i, int l, int r) {
    if (b < l || a > r) return;
    if (a <= l && b >= r) {
      seg[i] += v;
      segOff[i] += v;
      return;
    }
    int m = (l + r) / 2;
    segUpdate(a, b, v, (2 * (i) + 1), l, m);
    segUpdate(a, b, v, (2 * (i) + 2), m + 1, r);
    seg[i] = max(seg[(2 * (i) + 1)], seg[(2 * (i) + 2)]) + segOff[i];
  }
  long long segQuery(int a, int b, int i, int l, int r) {
    if (b < l || a > r) return 0;
    if (a <= l && b >= r) return seg[i];
    int m = (l + r) / 2;
    return max(segQuery(a, b, (2 * (i) + 1), l, m),
               segQuery(a, b, (2 * (i) + 2), m + 1, r)) +
           segOff[i];
  }
};
int n, q;
long long w;
int f1[100000], f2[100000];
long long f3[100000];
map<pair<int, int>, int> edgeIndex;
vector<int> edgeGraphs[100000];
vector<int> virtualF1[100000];
vector<int> virtualF2[100000];
vector<graph> graphs;
int counter = 1;
long long last = 0;
multiset<long long> ds;
int edge(int u, int v) { return edgeIndex[{min(u, v), max(u, v)}]; }
int splitDfs(graph &g, vector<int> &size, int u, int p) {
  bool good = true;
  for (int v : g.e[u]) {
    if (v == p) continue;
    int r = splitDfs(g, size, v, u);
    if (r != -1) return r;
    size[u] += size[v];
    good &= size[v] <= g.n / 2;
  }
  good &= g.n - size[u] <= g.n / 2;
  if (good)
    return u;
  else
    return -1;
}
int splitDfs2(graph &g, graph &h, int u, int p) {
  int x = h.n++;
  h.e.push_back(vector<int>());
  h.nodes.push_back(g.nodes[u]);
  for (int v : g.e[u])
    if (v != p) {
      int w = splitDfs2(g, h, v, u);
      h.e[w].push_back(x);
      h.e[x].push_back(w);
    }
  return x;
}
void dfs(graph &g, int u, int p) {
  int e = edge(g.nodes[u], g.nodes[p]);
  edgeGraphs[e].push_back(graphs.size() - 1);
  virtualF1[e].push_back(u);
  virtualF2[e].push_back(p);
  g.comp[u] = g.comproot.size() - 1;
  g.leftint[u] = counter;
  int children = 0;
  for (int v : g.e[u]) {
    if (v == p) continue;
    dfs(g, v, u);
    children++;
  }
  if (children == 0) counter++;
  g.rightint[u] = counter - 1;
  g.segUpdate(g.leftint[u], g.rightint[u], f3[edge(g.nodes[u], g.nodes[p])], 0,
              0, g.segSize - 1);
}
void split(graph &g) {
  if (g.n <= 1) return;
  vector<int> size(g.n, 1);
  int centroid = splitDfs(g, size, 0, -1);
  g.centroid = centroid;
  g.leftint = vector<int>(g.n);
  g.rightint = vector<int>(g.n);
  g.comp = vector<int>(g.n);
  g.comproot = vector<int>();
  g.compbest = vector<long long>();
  while (g.segSize < g.n) g.segSize *= 2;
  g.seg = vector<long long>(g.segSize * 2 - 1, 0);
  g.segOff = vector<long long>(g.segSize * 2 - 1, 0);
  counter = 1;
  g.leftint[centroid] = 0;
  g.rightint[centroid] = g.n - 1;
  for (int u : g.e[centroid]) {
    g.comproot.push_back(u);
    dfs(g, u, centroid);
    g.compbest.push_back(
        g.segQuery(g.leftint[u], g.rightint[u], 0, 0, g.segSize - 1));
    g.m.insert(g.compbest.back());
  }
  ds.insert(g.diameter());
  int gi = graphs.size() - 1;
  for (int u : graphs[gi].e[centroid]) {
    graphs.emplace_back();
    splitDfs2(graphs[gi], graphs.back(), u, centroid);
    split(graphs.back());
  }
}
int main() {
  cin >> n >> q >> w;
  graphs.push_back(graph());
  graph &g = graphs.back();
  g.n = n;
  g.e = vector<vector<int>>(n);
  for (int i = 0; i < n; ++i) g.nodes.push_back(i);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    long long ww;
    cin >> u >> v >> ww;
    u--;
    v--;
    f1[i] = u, f2[i] = v, f3[i] = ww;
    edgeIndex[{min(u, v), max(u, v)}] = i;
    g.e[u].push_back(v);
    g.e[v].push_back(u);
  }
  split(g);
  for (int i = 0; i < q; ++i) {
    int d;
    long long ee;
    cin >> d >> ee;
    d = (d + last) % (n - 1);
    ee = (ee + last) % w;
    int u = f1[d], v = f2[d];
    for (int z = 0; z < edgeGraphs[d].size(); ++z) {
      int gi = edgeGraphs[d][z];
      graph &g = graphs[gi];
      ds.erase(ds.lower_bound(g.diam));
      int uu = virtualF1[d][z], vv = virtualF2[d][z];
      int comp = g.comp[uu == g.centroid ? vv : uu];
      g.m.erase(g.m.lower_bound(g.compbest[comp]));
      g.segUpdate(max(g.leftint[uu], g.leftint[vv]),
                  min(g.rightint[uu], g.rightint[vv]), ee - f3[d], 0, 0,
                  g.segSize - 1);
      g.compbest[comp] =
          g.segQuery(g.leftint[g.comproot[comp]], g.rightint[g.comproot[comp]],
                     0, 0, g.segSize - 1);
      g.m.insert(g.compbest[comp]);
      ds.insert(g.diameter());
    }
    f3[d] = ee;
    last = *(--ds.end());
    cout << last << "\n";
  }
}
