#include <bits/stdc++.h>
using namespace std;

#define int long long

#define swap(i,j) { int tmp = i; i = j; j = tmp; }
int k;


struct Data{
    int num;
    int cost;
    int d;
    bool x;

    Data(int a, int b, bool xx){
        num = a;
        cost = 0;
        d = b;
        x = xx;
    }

    Data(){
        num = 0;
        cost = 0;
        d = 0;
        x = false;
    }

};

template <class type> class SegmentTree{
public:
    int size;
    vector<type> tree;
    type def;
    type (*marge)(type, type);

    SegmentTree(){
        return;
    }

    void init(int n, type d, type (*m)(type, type)){
        size = 1;
        def = d;
        marge = m;
        n++;

        while(size < n){
            size *= 2;
        }

        tree.resize(2*size);

        for(int i = 0;i < size;i++){
            tree[size-1+i] = def;
        }

        for(int i = size-2;i >= 0;i--){
            tree[i] = marge(tree[i*2+1], tree[i*2+2]);
        }

        return;
    }

    void update(int i, type val){
        i = size-1+i;
        tree[i].num += val.num;
        tree[i].d += val.d;
        tree[i].cost = 0;
        tree[i].x |= val.x;

        while(i > 0){
            i = (i-1)/2;
            tree[i] = marge(tree[i*2+1], tree[i*2+2]);
        }

        return; }
    type get(int a, int b, int k, int l, int r){
        if(r <= a || b <= l) return def;
        if(a <= l && r <= b) return tree[k];

        type vl = get(a, b, 2*k+1, l, (l+r)/2);
        type vr = get(a, b, 2*k+2, (l+r)/2, r);

        return marge(vl, vr);
    }

    type get(int a, int b){
        return get(a, b, 0, 0, size);
    }
};


Data marge(Data a, Data b){
    Data d;
    if(!b.x) return a;
    if(!a.x) return b;

    d.cost = a.cost + b.cost;

    if((a.d + b.num) % k != 0){
        d.cost += (a.d + b.num);
    }

    d.num = a.num;
    d.d = b.d;
    d.x = true;

    return d;
}

vector<pair<int, int> > treeGraph[100010];

vector<int> tree[100010];

vector<int> subtree[100010];

int par[100010] = {};
int num[100010] = {};
int vid[100010];
int nid[100010];
int head[100010];
int team[100010];
int size[100010] = {};
int b = 0;
bool used[100010] = {};
int dist[100010];
int oya[100010];


SegmentTree<Data> segTree;

void maketree(int i){
    used[i] = true;
    for(int x = 0;x < treeGraph[i].size();x++){
        if(!used[treeGraph[i][x].first]){
            par[treeGraph[i][x].first] = i;
            dist[treeGraph[i][x].first] = treeGraph[i][x].second;
            tree[i].push_back(treeGraph[i][x].first);
            maketree(treeGraph[i][x].first);
        }
    }
}

int setnum(int i){
    int ret = 1;
    for(int x = 0;x < tree[i].size();x++){
        ret += setnum(tree[i][x]);
    }
    return num[i] = ret;
}

void dis(int n){
    memset(team,-1,sizeof(team));
    priority_queue<pair<int, int> > que;
    for(int i = 0;i < n;i++){
        que.push(make_pair(num[i], i));
    }
    int gnum = 0;
    int next;
    int pos = 0;
    int i;
    while(!que.empty()){
        i = que.top().second; que.pop();
        if(team[i] != -1) continue;
        team[i] = gnum;
        size[gnum]++;
        subtree[gnum].push_back(i);
        nid[i] = 0;
        int nn = 1;
        head[i] = i;
        vid[i] = pos;
        pos++;
        next = i;
        while(tree[next].size() != 0){
            int maxi = 0;
            for(int j = 1;j < tree[next].size();j++){
                if(num[tree[next][maxi]] < num[tree[next][j]]){
                    maxi = j;
                }
            }
            subtree[gnum].push_back(tree[next][maxi]);
            team[tree[next][maxi]] = gnum;
            head[tree[next][maxi]] = i;
            vid[tree[next][maxi]] = pos;
            nid[tree[next][maxi]] = nn;
            size[gnum]++;
            pos++;
            nn++;
            next = tree[next][maxi];
        }
        gnum++;
    }
    return;
}

long long subDist[100010];

SegmentTree<Data> seg;

void build(int n){
    maketree(0);
    setnum(0);
    dis(n);

    seg.init(n, Data(0, 0, false), marge);

    for(int i = 0;i < n;i++){
        seg.update(vid[i], Data(dist[i], 0, true));
    }

    return;
}

int so(int i, int j){
    if(vid[i] >vid[j]) swap(i, j);
    if(head[i] == head[j]) return i;
    return so(i, par[head[j]]);
}

Data get(int i, int j){
    //if(i == j) return Data();
    if(vid[i] > vid[j]) swap(i, j);
    if(head[i] == head[j]){
        return seg.get(vid[i], vid[j]+1);
    }
    return marge(get(i, par[head[j]]), seg.get(vid[head[j]], vid[j]+1));
}

signed main(){
    int n, m;
    cin >> n >> k;

    int a, b, c;
    for(int i = 0;i < n-1;i++){
        cin >> a >> b >> c;
        treeGraph[a].push_back(make_pair(b, c));
        treeGraph[b].push_back(make_pair(a, c));
    }

    build(n);


    cin >> m;
    string s;
    for(int p = 0;p < m;p++){
        cin >> s >> a >> b;
        if(s == "send"){
            int ss = so(a, b);
            cout << get(a, ss).cost + get(b, ss).cost << endl;
        }else{
            seg.update(vid[a], Data(b, b, true));
        }
    }

    return 0;
}


Measured memory_bytes: 38052