#include <bits/stdc++.h>
#define N (1<<17)
#define int long long
using namespace std;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}


class HLD{
public:
  int V;                     //???????????°
  int root;                  //??????????????????
  vector<vector<int> >G;     //Grapth
  vector<int> par;           //parent: par[??????????????????]
  vector<int> Hedge;         //???????????????????????????Heavy Child???????????????: Hedge[??????????????????]
  vector<int> number;        //???????????????????????????????????????????????????: number[??????????????????]->????????´??????????????????
  vector<int> id;            //??????????????´????????°???????????????????????????: id[????????´??????????????????]->??????????????????
  vector<int> group;         //???????????????????±?????????°???????????????: group[??????????????????]
  vector<int> depth;         //?????????????????????????????±???: depth[??????????????????]
  bool ok;                   //build()???????????§?????????
  
  HLD(){root = V = -1;}
  HLD(int V,int root = 0):V(V++), root(), G(V), par(V,-1), Hedge(V,-1), 
                          number(V,-1),id(V,-1),group(V,-1),depth(V,0),ok(0){}
  
  void add_edge(int a,int b){
    assert(a<V && b<V);
    G[a].push_back(b);
    G[b].push_back(a);
  }
  
  void build(){
    ok = 1;
    HLD(V);
    buildWeight(); // weight and parent
    int num = 0;
    numbering(num);
    buildDepthAndGroup();
  }
  
  int buildWeight(int pos = -1,int pre = -1){
    if(pos == -1) pos = root;
    par[pos] = pre;

    int mx = -1, weight = 1;
    for(int nx:G[pos]){
      if(nx == pre) continue;
      int cweight = buildWeight(nx,pos);
      weight += cweight;
      if(mx < cweight) Hedge[pos] = nx, mx = cweight;
    }
    return weight;
  }
  
  void buildDepthAndGroup(int pos=-1,int pre=-1,int dep=0,int g=0){
    if(pos == -1) pos = root;
    depth[pos] = dep;
    group[pos] = g;
    for(int nx:G[pos]) if(nx!=pre) buildDepthAndGroup(nx,pos,dep+1,Hedge[pos]==nx? g:nx);
  }

  void numbering(int &cnt,int pos=-1){
    if(pos == -1) pos = root;
    number[pos] = cnt++;
    id[number[pos]] = pos;
    if(Hedge[pos]>=0) numbering(cnt,Hedge[pos]);
    for(int nx:G[pos])if(nx!=par[pos] && nx!=Hedge[pos]) numbering(cnt,nx);
  }
  
  typedef pair<int,int> P;
  vector<P> paths;
  void buildPaths(int u,int v,int init = 1){
    if(init) paths.clear();
    assert(ok);
    int nu=number[u], nv=number[v];
    if(same(u,v)){ paths.push_back(P(min(nu,nv),max(nu,nv)));return;} 
    if(depth[group[u]] < depth[group[v]]) swap(u,v);// ??±???????????????????????????????????????
    buildPaths(par[group[u]],v,0);
    paths.push_back(P(number[group[u]],number[u]));
  }
  
  //same(???????????????????????????????????????)
  bool same(int a,int b){return group[a] == group[b];}
};

typedef pair<int,int> P;
class Stree{
public:
  struct data{int sum,l,r;};
  HLD H;
  int K;
  int n;
  bool ok;
  unordered_map<int,unordered_map<int,int> >G; 
  vector<data> dat;
  unordered_map<int,int> x;
  //?????????
  Stree(){
    ok = 0;
    K = -1;
    n=N;
    dat.resize(2*n-1,(data){0,-1,-1});
  }
  
  void pr(data a){cout<<"("<<a.sum<<" "<<a.l<<" "<<a.r<<")"<<endl;}
  bool same(int a,int b){return H.same(a,b);}

  void build(HLD &H){
    this->H = H;
    ok = 1;
    assert(K > 0);
    for(int i=0;i<n-1;i++){
      if(!same(H.id[i],H.id[i+1])) continue;
      dat[i+n-1].r = H.id[i+1];
      dat[i+1+n-1].l = H.id[i];
    }
    for(int i=0;i<n;i++) add(i,0);
  }

  data merge(data a,data b,int flg=0){
    if(flg)cout<<"a=("<<a.sum<<","<<a.l<<","<<a.r<<")";
    if(flg)cout<<" b=("<<b.sum<<","<<b.l<<","<<b.r<<")"<<endl;
    int l = b.l,r = a.r;
    if(a.sum == -1) return b;
    if(b.sum == -1) return a;
    if(!same(r,l)) return a;
    int sum = a.sum + b.sum;
    int d = G[r][l] + x[r] + x[l];
    if(d % K ) sum += d;
    if(flg)cout<<"res=("<<sum<<","<<a.l<<","<<b.r<<")"<<endl;
    return (data){sum,a.l,b.r};
  }

  void add(int k,int a){         //k???????????????a?????????
    assert(ok);
    x[k] += a;
    k = H.number[k];
    k+=n-1;
    while(k>0){
      k=(k-1)/2;
      dat[k] =  merge(dat[k*2+1],dat[k*2+2]);
    }
  }
  
  //[a,b)???????°????????±??????? query(a,b,0,0,n)
  data sum(int a,int b,int k=0,int l=0,int r=N){
    if(r<=a||b<=l) return (data){-1,-1,-1};
    if(a<=l&&r<=b) return dat[k];

    data vl=sum(a,b,k*2+1,l,(l+r)/2);
    data vr=sum(a,b,k*2+2,(l+r)/2,r);
    
    return merge(vl ,vr,0);
  }

  int sum(int a,int b,HLD &H){
    assert(ok);
    int res = 0;
    //for(int i=0;i<10;i++)cout<<H.number[i]<<" ";cout<<endl;
    //for(int i=0;i<10;i++)cout<<H.group[i]<<" ";cout<<endl;
    
    
    H.buildPaths(a,b);
    set<int> group;
    for(P p:H.paths){
      //cout<<"path="<<p.first<<" "<<p.second;
      //cout<<" res="<<sum(p.first,p.second+1).sum<<endl;
      res += sum(p.first,p.second+1).sum;
      group.insert(H.group[H.id[p.first]]);
    }
    
    for(P p:H.paths){
      int g = H.group[H.id[p.first]];
      int par = H.par[g];
      if(par == -1) continue;
      //cout<<"g:par "<<g<<" "<<par<<endl;
      //if(group.count(H.group[par])) cout<<(G[g][par])<<" "<<x[g]<<" "<<x[par]<<endl;
      if(group.count(H.group[par])) res += (G[g][par]+ x[g]+x[par])%K? G[g][par] + x[g] + x[par]:0;
         
    }
    
    return res;
  }
};

signed main(){
  int n,K;
  cin>>n>>K;
  Stree T; T.K = K;
  HLD H(T.n);
  
  for(int i=0;i<n-1;i++){
    int a,b,c;
    scanf("%lld %lld %lld",&a,&b,&c);
    H.add_edge(a,b);
    T.G[a][b] = c;
    T.G[b][a] = c;
  }
  
  int q;
  cin>>q;
  H.build();

  
  T.build(H);
  while(q--){
    char str[10];
    int a,b;
    scanf("%s %lld %lld",str,&a,&b);
    //cout<<str<<" "<<a<<" "<<b<<endl;
    if(str[0] == 'a') T.add(a,b);
    if(str[0] == 's') printf("%lld\n",T.sum(a,b,H));
  }

  return 0;
}

Measured memory_bytes: 85612