#include <iostream>
#include <vector>
#include <array>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>

struct Section {
	int from, until;
	bool has_intersection(const Section that) const { return from < that.until && that.from < until; }
	bool contain_all(const Section that) const { return from <= that.from && that.until <= until; }
	bool contains(const int position) const { return from <= position && position < until; }
	int length() const { return until - from; }
	Section intersection(const Section that) const { return Section{ std::max(from, that.from), std::min(until, that.until) }; }
};
class SumBit {
	std::vector<long long int> vec;
public:
	SumBit(const int size) : vec(size, 0) {};
	void add(int position, const long long int value) {
		while (position < vec.size()) {
			vec[position] += value;
			position += ~position & (position + 1);
		}
	}
	long long int sum_below(int position) const {
		long long int result = 0;
		while (position >= 0) {
			result += vec[position];
			position -= ~position & (position + 1);
		}
		return result;
	}
	int size() const { return vec.size(); }
};
class LinearBit {
public:
	SumBit a_bit, b_bit;
	LinearBit(const int size) : a_bit(size), b_bit(size) {};
	void add(const int from, const int until, const long long int value) {
		b_bit.add(from, -(from - 1) * value);
		a_bit.add(from, value);
		if (until < b_bit.size()) b_bit.add(until, (until - 1) * value);
		if (until < a_bit.size()) a_bit.add(until, -value);
	}
	long long int sum_of(const int until) const {
		if (until == 0) return 0;
		return a_bit.sum_below(until - 1) * (until - 1) + b_bit.sum_below(until - 1);
	}
};
std::vector<std::vector<int>> calc_doubling(const std::vector<std::vector<int>>& nodes) {
	std::vector<std::vector<int>> ancestor(nodes.size());
	std::stack<int> stack; stack.push(0);
	while (!stack.empty()) {
		auto top = stack.top(); stack.pop();
		for (auto next : nodes[top]) {
			ancestor[next].push_back(top);
			while (ancestor[ancestor[next].back()].size() >= ancestor[next].size()) {
				ancestor[next].push_back(ancestor[ancestor[next].back()][ancestor[next].size() - 1]);
			}
			stack.push(next);
		}
	}
	return ancestor;
}
std::vector<int> calc_depth(const std::vector<std::vector<int>>& nodes) {
	std::vector<int> depth(nodes.size()); depth[0] = 0;
	std::stack<int> stack; stack.push(0);
	while (!stack.empty()) {
		auto top = stack.top(); stack.pop();
		for (const auto next : nodes[top]) {
			depth[next] = depth[top] + 1;
			stack.push(next);
		}
	}
	return depth;
}
int ancestor_of(int a, int count, const std::vector<std::vector<int>>& doubling) {
	for (auto i = 0; (1 << i) <= count; ++i) {
		if (((1 << i) & count) != 0) {
			count -= 1 << i;
			a = doubling[a][i];
		}
	}
	return a;
}
int calc_mlca(int a, int b, const std::vector<int>& depth, const std::vector<std::vector<int>>& doubling) {
	while (a != b) {
		if (depth[a] < depth[b]) {
			b = ancestor_of(b, depth[b] - depth[a], doubling);
		}
		else if (depth[a] > depth[b]) {
			a = ancestor_of(a, depth[a] - depth[b], doubling);
		}
		else {
			int i = 1;
			while (i < doubling[a].size() && doubling[a][i] != doubling[b][i]) ++i;
			a = doubling[a][i - 1];
			b = doubling[b][i - 1];
		}
	}
	return a;
}
int main() {
	std::cin.tie(0); std::cin.sync_with_stdio(false);
	int n, q; std::cin >> n >> q;
	std::vector<std::vector<int>> nodes(n);
	for (auto i = 0; i < n - 1; ++i) {
		int a, b; std::cin >> a >> b;
		nodes[a].push_back(b);
	}
	auto depth = calc_depth(nodes);
	auto doubling = calc_doubling(nodes);
	std::vector<Section> section_forward(n), section_backward(n);
	std::stack<std::pair<int, bool>> stack; stack.emplace(0, true);
	int forward = 0, backward = 0;
	while (!stack.empty()) {
		auto top = stack.top(); stack.pop();
		if (top.second) {
			stack.emplace(top.first, false);
			section_forward[top.first].from = forward;
			section_backward[top.first].from = backward;
			++forward;
			for (const auto next : nodes[top.first]) {
				stack.emplace(next, true);
			}
		}
		else {
			++backward;
			section_forward[top.first].until = forward;
			section_backward[top.first].until = backward;
		}
	}
	LinearBit forward_bit(forward);
	LinearBit backward_bit(backward);
	for (auto i = 0; i < q; ++i) {
		int o, u, v; std::cin >> o >> u >> v;
		switch (o) {
		case 0: {
			auto mlca = calc_mlca(u, v, depth, doubling);
			auto to_u = forward_bit.sum_of(section_forward[u].from) + backward_bit.sum_of(section_backward[u].from);
			auto to_v = forward_bit.sum_of(section_forward[v].from) + backward_bit.sum_of(section_backward[v].from);
			auto to_mlca = forward_bit.sum_of(section_forward[mlca].from) + backward_bit.sum_of(section_backward[mlca].from);
			std::cout << to_u + to_v - 2 * to_mlca << '\n';
		}
			break;
		case 1:
			forward_bit.add(section_forward[u].from, section_forward[u].until, v);
			backward_bit.add(section_backward[u].from, section_backward[u].until, -v);
			break;
		default: throw "???";
		}
	}
}


Measured memory_bytes: 40248