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

#define INF_LL (int64)1e18
#define INF (int32)1e9
#define REP(i, n) for(int i = 0;i < (n);i++)
#define FOR(i, a, b) for(int i = (a);i < (b);i++)
#define all(x) x.begin(),x.end()
#define fs first
#define sc second

using int32 = int_fast32_t;
using uint32 = uint_fast32_t;
using int64 = int_fast64_t;
using uint64 = uint_fast64_t;
using PII = pair<int32, int32>;
using PLL = pair<int64, int64>;

const double eps = 1e-10;

template<typename A, typename B>inline void chmin(A &a, B b){if(a > b) a = b;}
template<typename A, typename B>inline void chmax(A &a, B b){if(a < b) a = b;}

class HLDecomposition{
private:
	vector<vector<int32>> G;
	vector<int32> vid, inv, dep, hvy, par, typ, sub, head;
	int32 n, pos;
public:
	HLDecomposition(){}
	HLDecomposition(int32 n):
		n(n), pos(0), G(n), vid(n), inv(n), dep(n, -1),
		hvy(n, -1), par(n), typ(n), sub(n, 1), head(n){}

	void add_edge(int32 u, int32 v){
		G[u].push_back(v);
		G[v].push_back(u);
	}

	void build(){
		int32 type = 0;
		for(int32 i = 0;i < n;i++){
			if(dep[i] == -1){
				dfs(i);
				bfs(i, type++);
			}
		}
	}

	void dfs(int32 v){
		using T = pair<int32, int32>;
		dep[v] = 0;
		par[v] = -1;
		stack<T> st;
		st.emplace(v, 0);
		while(st.size()){
			v = st.top().first;
			int32 &i = st.top().second;
			if(i<G[v].size()){
				int32 u = G[v][i++];
				if(u == par[v]) continue;
				par[u] = v;
				dep[u] = dep[v]+1;
				st.emplace(u, 0);
			}else{
				st.pop();
				for(int32 u : G[v]){
					if(u == par[v]) continue;
					sub[v] += sub[u];
					if(hvy[v] == -1 || sub[u] > sub[hvy[v]]) hvy[v] = u;
				}
			}
		}
	}

	void bfs(int32 v, int32 t){
		queue<int32> q({v});
		while(q.size()){
			v = q.front(); q.pop();
			for(int32 i = v;i != -1;i=hvy[i]){
				typ[i] = t;
				vid[i] = pos++;
				inv[vid[i]] = i;
				head[i] = v;
				for(int32 u : G[i])
					if(u != par[i] && u != hvy[i]) q.push(u);
			}
		}
	}

	void for_each(int32 u, int32 v, const function<void(int32, int32)>& f){
		while(1){
			if(vid[u] > vid[v]) swap(u, v);
			f(max(vid[head[v]], vid[u]), vid[v]);
			if(head[u] != head[v]) v=par[head[v]];
			else break;
		}
	}

	void for_each_edge(int32 u, int32 v, const function<void(int32, int32)>& f){
		while(1){
			if(vid[u] > vid[v]) swap(u, v);
			if(head[u] != head[v]){
				f(vid[head[v]], vid[v]);
				v = par[head[v]];
			}else{
				if(u!=v) f(vid[u]+1, vid[v]);
				break;
			}
		}
	}

	int32 lca(int32 u, int32 v){
		while(1){
			if(vid[u] > vid[v]) swap(u, v);
			if(head[u] != head[v]) v = par[head[v]];
			else return u;
		}
	}

	int32 distance(int32 u, int32 v){
		return dep[u]+dep[v]-2*dep[lca(u, v)];
	}

	int32 getvid(int32 v){
		return vid[v];
	}
};

template<typename T, typename E>
class SegTree{
private:
	using F = function<T(T, T)>;
	using G = function<T(T, E)>;
	int32 n;
	F f;
	G g;
	T ti; // e0:F
	vector<T> node;
public:
	SegTree(){}
	SegTree(int32 _n, F f, G g, T ti):f(f), g(g), ti(ti){
		init(_n);
	}
	SegTree(vector<T> v, F f, G g, T ti):f(f), g(g), ti(ti){
		init(v.size());
		for(int32 i = 0;i < v.size();i++) node[i+n-1] = v[i];
		for(int32 i = n-2;i >= 0;i--) node[i] = merge(node[i*2+1], node[i*2+2]);
	}

	inline void init(int32 _n){
		n = 1;
		while(n < _n) n *= 2;
		node.resize(2*n-1, ti);
	}

	inline T merge(T lhs, T rhs){
		if(lhs == ti) return rhs;
		else if(rhs == ti) return lhs;
		return f(lhs, rhs);
	}

	void update(int32 k, E x){
		k += n-1;
		node[k] = g(node[k], x);
		while(k){
			k = (k-1)/2;
			node[k] = merge(node[k*2+1], node[k*2+2]);
		}
	}

	T query(int32 a, int32 b, int32 k=0, int32 l=0, int32 r=-1){
		if(r < 0) r = n;
		if(b <= l || r <= a) return ti;
		if(a <= l && r <= b) return node[k];
		return merge(query(a, b, k*2+1, l, (l+r)/2), query(a, b, k*2+2, (l+r)/2, r));
	}
};

int64 N, K, Q;
map<int64, int64> e[112345];
vector<int64> w;

int main(void){
	cin >> N >> K;
	w.resize(N, 0);
	HLDecomposition hld(N);
	REP(i, N-1){
		int64 a, b, c;
		cin >> a >> b >> c;
		e[a][b] = c; e[b][a] = c;
		hld.add_edge(a, b);
	}
	hld.build();

	auto wei = [&](int64 u, int64 v){
		if((w[u]+w[v]+e[u][v])%K == 0) return (int64)0;
		else return w[u]+w[v]+e[u][v];
	};

	using T = tuple<int64, int64, int64>;

	auto f = [&](T a, T b){
		int64 al, ar, av, bl, br, bv;
		if(a > b) swap(a, b);
		tie(al, ar, av) = a;
		tie(bl, br, bv) = b;
		if(al < 0 || ar < 0) return b;
		if(e[al].count(bl) || e[al].count(br)) swap(al, ar);
		if(e[ar].count(br)) swap(bl, br);
		if(!e[ar].count(bl)) return T(-1, -1, 0);
		T x = T(al, br, av+bv+wei(ar, bl));
		return x;
	};

	auto g = [&](T a, int64 b){ return T(b, b, 0); };

	SegTree<T, int64> sg(N, f, g, T(-1, -1, 0));
	REP(i, N) sg.update(hld.getvid(i), i);
	cin >> Q;

	REP(i, Q){
		string s; int64 x, y;
		cin >> s >> x >> y;
		if(s == "add"){
			w[x] += y;
			sg.update(hld.getvid(x), x);
		}else{
			vector<T> v;
			auto merge = [&](T x){
				if(v.size() <= 0){v.push_back(x); return;}
				REP(i, v.size()){
					T a = f(x, v[i]);
					if(get<0>(a) == -1) continue;
					v[i] = a;
					return;
				}
				v.push_back(x);
			};
			hld.for_each(x, y, [&](int64 u, int64 v){merge(sg.query(u, v+1));});
			while(v.size() > 1){
				T a = v[v.size()-1];
				v.pop_back();
				merge(a);
			}
			cout << get<2>(v[0]) << endl;
		}
	}
}


Measured memory_bytes: 40752