#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cassert>
using namespace std;
typedef long long ll;

#define N_MAX 400000

class Edge{
public:
  int t;
  ll c;
  Edge(int t=-1, ll c=0): t(t), c(c){}
};

class Node{
public:
  ll l, r, c, e;
  Node(ll l=0, ll r=0, ll c=0, ll e=0):l(l), r(r), c(c), e(e){}
};

int N;
ll K;
vector<Edge> G[N_MAX];
int P[N_MAX], D[N_MAX], H[N_MAX];// parent, depth, height
int W[N_MAX]; // weight
ll C[N_MAX]; //cost toward parent
int LI[N_MAX]; // list index;
ll A[N_MAX];
int idx;

// seg tree
int n;
Node SN[2*N_MAX-1];

Node merge(Node a, Node b){
  if ( a.r == -1 ) return b;
  if ( b.r == -1 ) return a;
  Node p = Node(a.l, b.r, a.c + b.c, a.e);
  ll cost = a.r + b.l + b.e;
  p.c += (cost%K>0?cost:0);
  return p;
}

void init(int n_){
  n = 1;
  while( n < n_ ) n *= 2;
  for ( int i = 0; i < 2*n-1; i++ ) SN[i] = Node(0, 0, 0, 0);
}

void add(int k, ll val){
  k += n - 1;
  SN[k].l += val;
  SN[k].r += val;
  while( k > 0 ){
    k = (k - 1)/2;
    SN[k] = merge(SN[k*2+1], SN[k*2+2]);
  }
}

// sum of [a, b)
Node sum(int a, int b, int k, int l, int r){
  if ( r <= a || b <= l ) return Node(-1, -1, -1, -1);
  if ( a <= l && r <= b ) return SN[k];
  else{
    Node vl = sum(a, b, k*2+1, l, (l + r)/2);
    Node vr = sum(a, b, k*2+2, (l + r)/2, r);
    return merge(vl, vr);
  }
}

// [a, b]
ll getSum(int a, int b){
  Node t = sum(a, b+1, 0, 0, n);
  return t.c;
}

int lca(int a, int b){
  while(1){
    int A = H[a];
    int B = H[b];
    if ( A == B ){
      if (D[a] < D[b] ) return a;
      else return b;
    }
    if ( D[A] > D[B] ) a = P[A];
    else b = P[B];
  }
  assert(false);
}

int dfs(int u, int d, int p, ll e){
  D[u] = d;
  P[u] = p;
  W[u] = 1;
  C[u] = e;
  for (int i = 0; i < G[u].size(); i++)  {
    if ( G[u][i].t == p ) continue;
    W[u] += dfs(G[u][i].t, d+1, u, G[u][i].c);
  }
  return W[u];
}

void hld(int u, int h, int p){
  LI[u] = idx++;
  H[u] = h;
  int maxv = -1;
  int maxw = -1;
  for ( int i = 0; i < G[u].size(); i++ ){
    int v = G[u][i].t;
    if ( v == p ) continue;
    if ( W[v] > maxw){ maxw = W[v]; maxv = v; }
  }
  if ( maxv == -1 ) return;

  hld(maxv, h, u);

  for ( int i = 0; i < G[u].size(); i++ ){
    int v = G[u][i].t;
    if ( v == p || v == maxv) continue;
    hld(v, v, u);
  }
}

ll getCost(int u){ // cost from u to root
  ll sum = 0;
  while(1){
    ll s = getSum(LI[H[u]], LI[u]);
    sum += s;
    if ( H[u] == 0 ) break;
    ll cost = C[H[u]] + A[H[u]] + A[P[H[u]]];
    sum += (cost%K>0?cost:0);
    u = P[H[u]];
  }
  return sum;
}

ll send(int a, int b){
  ll A = getCost(a);
  ll B = getCost(b);
  ll C = getCost(lca(a, b));
  return A + B - 2*C;
}

main(){
  int Q, s, t;
  ll c;
  //  string com;
  char com[10];
  cin >> N >> K;
  for ( int i = 0; i< N-1; i++ ){
    scanf("%d %d %lld", &s, &t, &c);
    G[s].push_back(Edge(t, c));
    G[t].push_back(Edge(s, c));
  }

  dfs(0, 0, -1, -1); // make tree
  idx = 0;
  hld(0, 0, -1);

  init(N);

  for ( int i = 0; i < N; i++ ){
    int k = LI[i] + (n-1); // index to seg;
    SN[k].e = C[i];
    A[i] = 0;
  }
  for ( int i = 0; i < N; i++ ) add(i, 0); // construct
  
  cin >> Q;
  for ( int i = 0; i < Q; i++ ){
    //    scanf("%s %d %d", com, &s, &t);
    scanf("%s", com);
    if ( com[0] == 'a' ) {
      scanf("%d %lld", &s, &c);
      add (LI[s], c);
      A[s] += c;
    } else if ( com[0] == 's' ) {
      scanf("%d %d", &s, &t);
      printf("%lld\n", send(s, t));
    } else assert(false);
  }
}

Measured memory_bytes: 51984