You are given a directed weighted graph with n nodes and 2n - 2 edges. The nodes are labeled from 1 to n, while the edges are labeled from 1 to 2n - 2. The graph's edges can be split into two parts.

  * The first n - 1 edges will form a rooted spanning tree, with node 1 as the root. All these edges will point away from the root. 
  * The last n - 1 edges will be from node i to node 1, for all 2 ≤ i ≤ n. 



You are given q queries. There are two types of queries

  * 1 i w: Change the weight of the i-th edge to w
  * 2 u v: Print the length of the shortest path between nodes u to v



Given these queries, print the shortest path lengths.

Input

The first line of input will contain two integers n, q (2 ≤ n, q ≤ 200 000), the number of nodes, and the number of queries, respectively.

The next 2n - 2 integers will contain 3 integers ai, bi, ci, denoting a directed edge from node ai to node bi with weight ci.

The first n - 1 of these lines will describe a rooted spanning tree pointing away from node 1, while the last n - 1 of these lines will have bi = 1.

More specifically, 

  * The edges (a1, b1), (a2, b2), ... (an - 1, bn - 1) will describe a rooted spanning tree pointing away from node 1. 
  * bj = 1 for n ≤ j ≤ 2n - 2. 
  * an, an + 1, ..., a2n - 2 will be distinct and between 2 and n. 



The next q lines will contain 3 integers, describing a query in the format described in the statement.

All edge weights will be between 1 and 106.

Output

For each type 2 query, print the length of the shortest path in its own line.

Example

Input

5 9
1 3 1
3 2 2
1 4 3
3 5 4
5 1 5
3 1 6
2 1 7
4 1 8
2 1 1
2 1 3
2 3 5
2 5 2
1 1 100
2 1 3
1 8 30
2 4 2
2 2 4


Output

0
1
4
8
100
132
10
#include <bits/stdc++.h>
using namespace std;
long long dist[200001];
int ord[200001], ed[200001], cnt, w2[200001], w1[200001], dep[200001],
    par[20][200001], u[400001], v[200001];
vector<pair<int, int>> mp[200001];
struct segment_tree {
  long long v[524288], lazy[524288];
  long long query(int id, int il, int ir, int l, int r) {
    if (il >= l && ir <= r) return v[id];
    if ((l >= il && l < ir) || (r > il && r <= ir))
      return min(query(id << 1, il, (il + ir) >> 1, l, r),
                 query((id << 1) ^ 1, (il + ir) >> 1, ir, l, r)) +
             lazy[id];
    return 1e18;
  }
  void up_propgate(int id) {
    v[id] = lazy[id];
    if (id < 262144) v[id] += min(v[id << 1], v[(id << 1) ^ 1]);
  }
  void add(int id, int il, int ir, int l, int r, int v) {
    if (il >= l && ir <= r)
      lazy[id] += v;
    else if ((l >= il && l < ir) || (r > il && r <= ir)) {
      add(id << 1, il, (il + ir) >> 1, l, r, v);
      add((id << 1) ^ 1, (il + ir) >> 1, ir, l, r, v);
    }
    up_propgate(id);
  }
  void build() {
    for (int i = 524288 - 1; i; --i) up_propgate(i);
  }
};
segment_tree seg1, seg2;
void dfs(int k, long long curd, int curdep) {
  dist[k] = curd;
  ord[k] = ++cnt;
  dep[k] = curdep;
  for (size_t i = 0; i < mp[k].size(); ++i)
    dfs(mp[k][i].first, curd + mp[k][i].second, curdep + 1);
  ed[k] = cnt;
}
int lca(int a, int b) {
  if (dep[a] < dep[b]) swap(a, b);
  for (int i = 0; i < 20; ++i)
    if ((dep[a] - dep[b]) & (1 << i)) a = par[i][a];
  if (a == b) return a;
  return -1;
}
int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 1; i < n; ++i) {
    scanf("%d%d%d", u + i, v + i, w1 + i);
    mp[u[i]].push_back(make_pair(v[i], w1[i]));
    par[0][v[i]] = u[i];
  }
  for (int i = 1; i < 20; ++i)
    for (int j = 1; j <= n; ++j) par[i][j] = par[i - 1][par[i - 1][j]];
  for (int i = n; i < 2 * n - 1; ++i) {
    int t2, w;
    scanf("%d%d%d", u + i, &t2, &w);
    w2[u[i]] = w;
  }
  dfs(1, 0, 0);
  seg1.lazy[262144] = seg2.lazy[262144] = 1e18;
  for (int i = 1; i <= n; ++i) {
    seg1.lazy[262144 + ord[i]] = dist[i];
    seg2.lazy[262144 + ord[i]] = dist[i] + w2[i];
  }
  for (int i = n + 1; i < 262144; ++i)
    seg1.lazy[i + 262144] = seg2.lazy[i + 262144] = 1e18;
  seg1.build();
  seg2.build();
  while (q--) {
    int tp, t1, t2;
    scanf("%d%d%d", &tp, &t1, &t2);
    if (tp == 1) {
      if (t1 < n) {
        seg1.add(1, 0, 262144, ord[v[t1]], ed[v[t1]] + 1, t2 - w1[t1]);
        seg2.add(1, 0, 262144, ord[v[t1]], ed[v[t1]] + 1, t2 - w1[t1]);
        w1[t1] = t2;
      } else {
        seg2.add(1, 0, 262144, ord[u[t1]], ord[u[t1]] + 1, t2 - w2[u[t1]]);
        w2[u[t1]] = t2;
      }
    } else {
      long long tt2 = seg1.query(1, 0, 262144, ord[t2], ord[t2] + 1),
                tt1 = seg1.query(1, 0, 262144, ord[t1], ord[t1] + 1);
      long long ans = seg2.query(1, 0, 262144, ord[t1], ed[t1] + 1) - tt1 + tt2;
      if (dep[t1] <= dep[t2] && lca(t1, t2) != -1) ans = min(ans, tt2 - tt1);
      printf("%lld\n", ans);
    }
  }
  return 0;
}
