#include <bits/stdc++.h>
using namespace std::literals::string_literals;
using i64 = long long;
using std::cout;
using std::endl;
using std::cin;

template<typename T>
std::vector<T> make_v(size_t a){return std::vector<T>(a);}

template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts){
  return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}

template<typename Monoid>
class segment_tree {
	using value_type = Monoid;
	using size_type = size_t;

	using binary_function = std::function<value_type(value_type, value_type)>;
	using checker = std::function<bool(value_type)>;
	
	const size_type size_;
	size_type height_;

	const value_type id;
	const binary_function bi_func;
	std::vector<value_type> data;
	
	private:
	const size_type get_height(const size_type& size) const {
		size_type height = 1;
		while(1 << height < size) height++;
		return height;
	}
	const size_type base_size() const {
		return 1 << height_;
	}
	void meld(const size_type& index) {
		data[index] = bi_func(data[index << 1 ^ 0], data[index << 1 ^ 1]);
	}
	
	public:
	segment_tree(const size_type& size, const binary_function& bi_func, const value_type& id)
		: size_(size),
		  bi_func(bi_func),
		  id(id) {
		height_ = get_height(size);
		data.assign(base_size() << 1, id);
	}
	value_type fold(size_type left, size_type right) {
		value_type l_value = id,
				   r_value = id;

		for(left += base_size(), right += base_size();
			left < right;
			left >>= 1, right >>= 1) {
			if(left & 1)  l_value = bi_func(l_value, data[left++]);
			if(right & 1) r_value = bi_func(data[--right], r_value); 
		}
		return bi_func(std::move(l_value), std::move(r_value));
	}
	void update(size_type index) {
		index += base_size();
		while(index >>= 1) meld(index);
	}
	void change(size_type index, const value_type& value) {
		index += base_size();
		data[index] = value;

		while(index >>= 1) meld(index);
	}
	const size_type search(const size_type & left, const checker & check) {
		value_type val = id;
		size_t base_size_ = base_size();
		auto find = [&](auto&& find, size_type k, size_type l, size_type r) -> int {
			if(l + 1 == r) {
				val = bi_func(val, data[k]);
				
				return (check(val) ? k - base_size_ : -1);
			}

			const size_type mid = (l + r) >> 1;
			if(mid <= left) return find(find, k << 1 ^ 1, mid, r);
			if(left <= l and !check(bi_func(val, data[k]))) {
				val = bi_func(val, data[k]);
				return -1;
			}

			const int left_ret = find(find, k << 1 ^ 0, l, mid);
			if(left_ret == -1) return find(find, k << 1 ^ 1, mid, r);
			return left_ret;
		};

		return find(find, 1, 0, base_size_); 
	}
	
	value_type operator[](const size_type& index) const {
		return data[index + base_size()];
	}
	const size_type size() const {
		return size_;
	}
	const bool empty() const {
		return data.empty();
	}
};

// build: you have to run it before you use
// for_each: process [l, r]
// for_each_edge: process [l, r]
// distance: returns the dist (l, r)
class heavy_light_decomposition {
	using size_type = size_t;

	using F = std::function<void (int, int)>;

	public:
	std::vector<std::vector<int>> g;
	std::vector<int> vid, inv;

	private:
	std::vector<int> head, sz, heavy, par, dep;

	void dfs(int root) {
		using P = std::pair<int, int>;
		
		par[root] = -1;
		dep[root] = 0;
		std::stack<P> st;
		st.push({root, 0});
		while(!st.empty()) {
			int v = st.top().first;
			int & i = st.top().second;
		
			if(i < g[v].size()) {
				int u = g[v][i++];
				if(u == par[v]) continue;
				par[u] = v;
				dep[u] = dep[v] + 1;
				st.push({u, 0});
			} else {
				st.pop();
				int tmp = 0;
				for(auto e: g[v]) {
					if(e == par[v]) continue;
					sz[v] += sz[e];
					if(tmp < sz[e]) {
						tmp = sz[e];
						heavy[v] = e;
					}
				}
			}
		}
	}
	void bfs(int root, int c, int & k) {
		std::queue<int> qu({root});
		while(!qu.empty()) {
			int h = qu.front(); qu.pop();

			for(int v = h; v != -1; v = heavy[v]) {
				vid[v] = k++;
				inv[vid[v]] = v;
				head[v] = h;
				for(int e: g[v])
					if(e != par[v] and e != heavy[v]) qu.push(e);
			}
		}
	}

	public:
	heavy_light_decomposition() {}
	heavy_light_decomposition(int n) :
		g(n), vid(n, -1), head(n), sz(n, 1), heavy(n, -1),
		par(n), dep(n), inv(n) {}
	void add_edge(int a, int b) {
		g[a].push_back(b);
		g[b].push_back(a);
	}
	void build(std::vector<int> rs = std::vector<int>(1, 0)) {
		int c = 0, k = 0;
		for(int r: rs) {
			dfs(r);
			bfs(r, c++, k);
		}
	}
	int lca(int u, int v) {
		while(true) {
			if(vid[u] > vid[v]) std::swap(u, v);
			if(head[u] == head[v]) return u;
			v = par[head[v]];
		}
	}
	void for_each(int u, int v, const F & f) {
		while(true) {
			if(vid[u] > vid[v]) std::swap(u, v);
			f(std::max(vid[head[v]], vid[u]), vid[v]);
			if(head[u] != head[v]) v = par[head[v]];
			else break;
		}
	}
	void for_each_edge(int u, int v, const F & f) {
		while(true) {
			if(vid[u] > vid[v]) std::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;
			}
		}
	}

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

struct node {
	int l, r;
	i64 val;

	node() : l(-1), r(-1), val(0) {}
	node(int l, int r, i64 val) : l(l), r(r), val(val) {}
	void rotate() {
		std::swap(l, r);
	}
	void print() {
		cout << "node: " << l << " " << r << " " << val << endl;
	}
};

const int N = 1e5;
std::vector<std::map<int, i64>> cost(N);

heavy_light_decomposition hld(N);

bool uni(node a) {
	return a.l == a.r;
};
int chain(node a, node b) {
	if(cost[a.l][b.l]) return 1;
	if(cost[a.r][b.l]) return 2;
	if(cost[a.l][b.r]) return 3;
	if(cost[a.r][b.r]) return 4;
	return 0;
};

int main() {
	int n, k; scanf("%d%d", &n, &k);
	for(int i = 0; i < n - 1; i++) {
		int a, b, c; scanf("%d%d%d", &a, &b, &c);

		cost[a][b] = cost[b][a] = c;
		hld.add_edge(a, b);
	}
	hld.build();

	std::vector<i64> ver(n, 0);
	auto g = [&](node a, node b) {
		if(a.r == -1) return b;
		if(b.l == -1) return a;
		i64 val = ver[a.r] + cost[a.r][b.l] + ver[b.l];
		if(!(val % k)) val = 0;
		return node(a.l, b.r, a.val + val + b.val);
	};
	segment_tree<node> seg(N, g, node());
	for(int i = 0; i < n; i++) seg.change(i, node(hld.inv[i], hld.inv[i], 0));

	int q; scanf("%d", &q);
	std::vector<node> vec;
	while(q--) {
		std::string type; cin >> type;

		if(type == "add") {
			int x, d; scanf("%d%d", &x, &d);

			ver[x] += d;
			seg.update(hld.vid[x]);
		} else if(type == "send") {
			int x, y; scanf("%d%d", &x, &y);

			vec.clear();
			auto f = [&](int l, int r) {
				auto A = seg.fold(l, r + 1);
				for(auto & B: vec) {
					int tmp = chain(A, B);
					if(!tmp) continue;
					if(tmp == 1) A.rotate();
					if(tmp == 3) A.rotate(), B.rotate();
					if(tmp == 4) B.rotate();
					B = g(A, B);
					return;
				}
				vec.push_back(A);
			};
			hld.for_each(x, y, f);
			
			while(vec.size() > 1) {
				auto A = vec.back(); vec.pop_back();
				for(auto & B: vec) {
					int tmp = chain(A, B);
					if(!tmp) continue;
					if(tmp == 1) A.rotate();
					if(tmp == 3) A.rotate(), B.rotate();
					if(tmp == 4) B.rotate();
					B = g(A, B);
					break;
				}
			}
			printf("%lld\n", vec.front().val);
		}
	}
	return 0;
}



Measured memory_bytes: 118580