#include <bits/stdc++.h>
using namespace std;
struct edge {
  long long from, to, next, w;
} e[200002 << 1];
long long head[200002], cnte;
void add(long long u, long long v, long long w) {
  e[++cnte].to = v;
  e[cnte].from = u;
  e[cnte].w = w;
  e[cnte].next = head[u];
  head[u] = cnte;
}
long long n, fa[200002], son[200002], dep[200002], sz[200002], dfn[200002],
    num[200002], rig[200002], cntdfn, top[200002], a[200002];
void clear() {
  for (long long i = 1; i <= n; i++) head[i] = -1;
  cnte = 0;
}
namespace SEG {
long long t[200002 << 2];
void pushup(long long p) {
  if (t[p << 1] > 1000000000000000000ll / t[p << 1 | 1])
    t[p] = 1000000000000000001ll;
  else
    t[p] = t[p << 1] * t[p << 1 | 1];
}
void build(long long p, long long l, long long r) {
  if (l == r) {
    t[p] = a[num[l]];
    return;
  }
  long long mid = (l + r) >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  pushup(p);
}
void change(long long p, long long l, long long r, long long pos, long long k) {
  if (l == r) {
    t[p] = k;
    return;
  }
  long long mid = (l + r) >> 1;
  if (pos <= mid)
    change(p << 1, l, mid, pos, k);
  else
    change(p << 1 | 1, mid + 1, r, pos, k);
  pushup(p);
}
long long query(long long p, long long l, long long r, long long seg_l,
                long long seg_r) {
  if (seg_l <= l && r <= seg_r) {
    return t[p];
  }
  long long mid = (l + r) >> 1, ret = 1, tmp;
  if (seg_l <= mid) {
    tmp = query(p << 1, l, mid, seg_l, seg_r);
    if (ret > 1000000000000000000ll / tmp)
      ret = 1000000000000000001ll;
    else
      ret *= tmp;
  }
  if (seg_r > mid) {
    tmp = query(p << 1 | 1, mid + 1, r, seg_l, seg_r);
    if (ret > 1000000000000000000ll / tmp)
      ret = 1000000000000000001ll;
    else
      ret *= tmp;
  }
  return ret;
}
}  // namespace SEG
void initdep(long long u, long long last, long long depth) {
  fa[u] = last;
  dep[u] = depth;
  sz[u] = 1;
  long long mxsz = 0;
  for (long long i = head[u]; ~i; i = e[i].next) {
    long long v = e[i].to;
    if (v == fa[u]) continue;
    initdep(v, u, depth + 1);
    sz[u] += sz[v];
    if (sz[v] > mxsz) mxsz = sz[v], son[u] = v;
    a[v] = e[i].w;
  }
}
void initdfn(long long u, long long tp) {
  dfn[u] = ++cntdfn;
  num[cntdfn] = u;
  top[u] = tp;
  if (son[u]) {
    initdfn(son[u], tp);
    for (long long i = head[u]; ~i; i = e[i].next) {
      long long v = e[i].to;
      if (v == fa[u] || v == son[u]) continue;
      initdfn(v, v);
    }
  }
  rig[u] = cntdfn;
}
void change(long long x, long long w) { SEG::change(1, 1, n, dfn[x], w); }
long long query(long long x, long long y) {
  long long ans = 1, tmp;
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    tmp = SEG::query(1, 1, n, dfn[top[x]], dfn[x]);
    if (ans > 1000000000000000000ll / tmp)
      ans = 1000000000000000001ll;
    else
      ans *= tmp;
    x = fa[top[x]];
  }
  if (dep[x] == dep[y]) return ans;
  if (dep[x] < dep[y]) swap(x, y);
  tmp = SEG::query(1, 1, n, dfn[son[y]], dfn[x]);
  if (ans > 1000000000000000000ll / tmp)
    ans = 1000000000000000001ll;
  else
    ans *= tmp;
  return ans;
}
void init() {
  for (long long i = 1; i <= n; i++) fa[i] = son[i] = 0;
  a[1] = 1;
  initdep(1, 0, 0);
  cntdfn = 0;
  initdfn(1, 1);
}
int main() {
  long long Q;
  scanf("%lld%lld", &n, &Q);
  clear();
  for (long long i = 1; i < n; i++) {
    long long u, v, w;
    scanf("%lld%lld%lld", &u, &v, &w);
    add(u, v, w);
    add(v, u, w);
  }
  init();
  SEG::build(1, 1, n);
  while (Q--) {
    long long mo, x, y;
    scanf("%lld%lld%lld", &mo, &x, &y);
    if (mo == 2) {
      change(
          dep[e[x * 2].from] > dep[e[x * 2].to] ? e[x * 2].from : e[x * 2].to,
          y);
    } else {
      long long z;
      scanf("%lld", &z);
      long long ans = query(x, y);
      printf("%lld\n", ans == 1000000000000000001ll ? 0 : z / ans);
    }
  }
  return 0;
}
