#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int maxe = maxn * 2;
const long long inf = 1e18 + 10000;
struct divTree {
  void add_edge(int u, int v, long long c) {
    edges[cnt_edge] = Edge(u, v, c, fir[u]);
    fir[u] = cnt_edge++;
  }
  void init() {
    memset(fir, -1, sizeof(fir));
    cnt_edge = 0;
  }
  void dfs1(int u) {
    sz[u] = 1;
    son[u] = 0;
    for (int e = fir[u]; e != -1; e = edges[e].x) {
      int v = edges[e].v;
      if (v == fa[u]) continue;
      dep[v] = dep[u] + 1;
      fa[v] = u;
      dfs1(v);
      sz[u] += sz[v];
      if (sz[son[u]] < sz[v]) {
        son[u] = v;
      }
    }
  }
  void dfs2(int u) {
    if (son[u]) {
      faEdge[son[u]] = ++no;
      train[son[u]] = train[u];
      dfs2(son[u]);
    }
    for (int e = fir[u]; e != -1; e = edges[e].x) {
      int v = edges[e].v;
      if (v == fa[u]) continue;
      if (v == son[u]) {
        val[faEdge[v]] = edges[e].c;
        mp[e / 2 + 1] = faEdge[v];
      } else {
        faEdge[v] = ++no;
        val[no] = edges[e].c;
        mp[e / 2 + 1] = no;
        train[v] = v;
        dfs2(v);
      }
    }
  }
  void pushUp(int o) {
    if (inf / sum[o << 1] < sum[o << 1 | 1])
      sum[o] = inf;
    else
      sum[o] = sum[o << 1] * sum[o << 1 | 1];
  }
  void build(int o, int l, int r) {
    if (l == r) {
      sum[o] = val[l];
      return;
    }
    int m = (l + r) >> 1;
    build(o << 1, l, m);
    build(o << 1 | 1, m + 1, r);
    pushUp(o);
  }
  void run(int rt) {
    dep[rt] = 1;
    fa[rt] = rt;
    dfs1(rt);
    no = 0;
    train[rt] = rt;
    dfs2(rt);
    build(1, 1, no);
  }
  void update(int p, long long v, int o, int l, int r) {
    if (l == r) {
      sum[o] = v;
      return;
    }
    int m = (l + r) >> 1;
    if (p <= m)
      update(p, v, o << 1, l, m);
    else
      update(p, v, o << 1 | 1, m + 1, r);
    pushUp(o);
  }
  long long query(int a, int b, int o, int l, int r) {
    if (a <= l && b >= r) {
      return sum[o];
    }
    int m = (l + r) >> 1;
    if (a <= m && b > m) {
      long long v1 = query(a, b, o << 1, l, m),
                v2 = query(a, b, o << 1 | 1, m + 1, r);
      if (inf / v1 < v2)
        return inf;
      else
        return v1 * v2;
    } else if (a <= m)
      return query(a, b, o << 1, l, m);
    else
      return query(a, b, o << 1 | 1, m + 1, r);
  }
  long long gao(int u, int v) {
    long long ret = 1;
    for (int fu = train[u], fv = train[v]; fu != fv;
         fu = train[u], fv = train[v]) {
      if (dep[fu] < dep[fv]) {
        swap(u, v);
        swap(fu, fv);
      }
      long long now = query(faEdge[fu], faEdge[u], 1, 1, no);
      if (inf / now < ret)
        ret = inf;
      else
        ret = ret * now;
      u = fa[fu];
    }
    if (u == v) return ret;
    if (dep[u] > dep[v]) swap(u, v);
    long long now = query(faEdge[son[u]], faEdge[v], 1, 1, no);
    if (inf / now < ret)
      ret = inf;
    else
      ret = ret * now;
    return ret;
  }
  struct Edge {
    int u, v, x;
    long long c;
    Edge(int u = 0, int v = 0, long long c = 0, int x = 0)
        : u(u), v(v), c(c), x(x) {}
  } edges[maxe];
  int fir[maxn], cnt_edge, no;
  int dep[maxn], sz[maxn], fa[maxn], son[maxn];
  int train[maxn], mp[maxn], faEdge[maxn];
  long long val[maxn], sum[maxn << 2];
} divt;
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  divt.init();
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    long long c;
    scanf("%d%d%I64d", &u, &v, &c);
    divt.add_edge(u, v, c);
    divt.add_edge(v, u, c);
  }
  divt.run(1);
  for (int i = 0; i < m; i++) {
    int cmd;
    scanf("%d", &cmd);
    if (cmd == 1) {
      int a, b;
      long long v;
      scanf("%d%d%I64d", &a, &b, &v);
      long long now = divt.gao(a, b);
      printf("%I64d\n", v / now);
    } else {
      int p;
      long long v;
      scanf("%d%I64d", &p, &v);
      divt.update(divt.mp[p], v, 1, 1, divt.no);
    }
  }
  return 0;
}
