#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
using pii = pair<int, int>;
 
template <typename T> T inf;
template <> constexpr int inf<int> = 1e9;
template <> constexpr ll inf<ll> = 1e18;

struct edge {
    int from, to;
};

using edges = std::vector<edge>;
using graph = std::vector<edges>;

void add_edge(graph& g, int from, int to) {
    g[from].push_back((edge){from, to});
    g[to].push_back((edge){to, from});
}

class lca {
public:
    lca(graph& g, int root)
        : V(g.size()),
          log_V(0),
          depth_(V, 0)
    {
        for(int v=V; v>0; v /= 2) {
            ++log_V;
        }
        parent.assign(log_V, std::vector<int>(V, 0));
        dfs(g, root, -1, 0);
        for(int k=0; k+1 < log_V; ++k) {
            for(int v=0; v<V; ++v) {
                if(parent[k][v] < 0) {
                    parent[k+1][v] = -1;
                } else {
                    parent[k+1][v] = parent[k][parent[k][v]];
                }
            }
        }
    }

    void dfs(graph const& g, int v, int p, int d) {
        parent[0][v] = p;
        depth_[v] = d;
        for(int i=0; i<g[v].size(); ++i) {
            if(g[v][i].to != p) {
                dfs(g, g[v][i].to, v, d+1);
            }
        }
    }

    int depth(int v) const {
        return depth_[v];
    }

    int query(int u, int v) {
        if(depth_[u] > depth_[v]) {
            std::swap(u, v);
        }
        for(int k=0; k<log_V; ++k) {
            if((depth_[v] - depth_[u]) >> k & 1) {
                v = parent[k][v];
            }
        }
        if(u == v) {
            return u;
        }
        for(int k=log_V - 1; k>=0; --k) {
            if(parent[k][u] != parent[k][v]) {
                u = parent[k][u];
                v = parent[k][v];
            }
        }
        return parent[0][u];
    }

private:
    int V, log_V;
    std::vector<vector<int>> parent;
    std::vector<int> depth_;
};


vector<int> contract(graph const& g, vector<bool> const& used, int root) {
    vector<int> parent(g.size());
    queue<tuple<int, int, int>> que; // (v, prev, par)
    que.push(make_tuple(root, -1, -1));
    while(!que.empty()) {
        int v, prev, par;
        tie(v, prev, par) = que.front();
        que.pop();
        if(used[v]) {
            parent[v] = par;
            par = v;
        }
        for(auto& e : g[v]) {
            if(e.to != prev) {
                que.push(make_tuple(e.to, v, par));
            }
        }
    }
    return parent;
}

int main() {
    int N, Q;
    scanf("%d %d", &N, &Q);
    graph g(N);
    for(int i = 0; i < N - 1; ++i) {
        int a, b;
        scanf("%d %d", &a, &b);
        add_edge(g, a, b);
    }
    lca lca_(g, 0);

    int const QB = 1200;
    vector<ll> add(N);
    for(int q = 0; q < Q; q += QB) {
        vector<bool> used(N);
        vector<int> t(QB), u(QB), v(QB);
        for(int i = 0; i + q < Q && i < QB; ++i) {
            scanf("%d %d %d", &t[i], &u[i], &v[i]);
            if(t[i] == 0) {
                used[u[i]] = used[v[i]] = used[lca_.query(u[i], v[i])] = true;
            } else {
                used[u[i]] = true;
            }
        }
        auto parent = contract(g, used, 0);
        vector<ll> add_lazy(N);

        auto calc_weight = [&](int v) {
            ll res = add[v];
            for(int now = v; now != -1; now = parent[now]) {
                res += add_lazy[now] * (lca_.depth(v) - lca_.depth(now));
            }
            return res;
        };
        for(int i = 0; i + q < Q && i < QB; ++i) {
            if(t[i] == 0) {
                printf("%lld\n", calc_weight(u[i]) + calc_weight(v[i]) - 2 * calc_weight(lca_.query(u[i], v[i])));
            } else {
                add_lazy[u[i]] += v[i];
            }
        }

        queue<tuple<int, int, ll, ll>> que; // (v, prev, add_sum, add_diff)
        que.push(make_tuple(0, -1, 0, 0));
        while(!que.empty()) {
            int v, prev;
            ll add_sum, add_diff;
            tie(v, prev, add_sum, add_diff) = que.front();
            que.pop();
            add[v] += add_sum;
            for(auto& e : g[v]) {
                if(e.to != prev) {
                    que.emplace(e.to, v, add_sum + add_diff + add_lazy[v], add_diff + add_lazy[v]);
                }
            }
        }
    }
}


Measured memory_bytes: 30048