#include <bits/stdc++.h>
using namespace std;
long long read() {
  long long x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = (x << 3) + (x << 1) + f * (c - '0'), c = getchar();
  return x;
}
const long long MAXN = 2 * 1e5 + 10, inf = 1e18;
long long n, m, root;
long long u[MAXN * 2], v[MAXN * 2], first[MAXN], net[MAXN * 2], val[MAXN * 2];
long long uu[MAXN], vv[MAXN];
long long dep[MAXN], value[MAXN], son[MAXN], fa[MAXN], size[MAXN], top[MAXN];
long long dfn[MAXN], a[MAXN];
long long shu[MAXN * 4];
void ycl() {
  for (long long i = 1; i <= n; i++) first[i] = 0;
}
long long cnt;
void add(long long x, long long y, long long z) {
  cnt++;
  u[cnt] = x;
  v[cnt] = y;
  val[cnt] = z;
  net[cnt] = first[x];
  first[x] = cnt;
}
void dfs1(long long x) {
  son[x] = -1;
  size[x] = 1;
  for (long long i = first[x]; i; i = net[i]) {
    if (dep[v[i]]) continue;
    fa[v[i]] = x;
    value[v[i]] = val[i];
    dep[v[i]] = dep[x] + 1;
    uu[(i - 1) / 2 + 1] = u[i];
    vv[(i - 1) / 2 + 1] = v[i];
    dfs1(v[i]);
    size[x] += size[v[i]];
    if (son[x] == -1 || size[son[x]] < size[v[i]]) son[x] = v[i];
  }
}
long long tot = 0;
void dfs2(long long x, long long y) {
  top[x] = y;
  tot++;
  dfn[x] = tot;
  a[tot] = x;
  if (son[x] == -1) return;
  dfs2(son[x], y);
  for (long long i = first[x]; i; i = net[i])
    if (v[i] != son[x] && v[i] != fa[x]) dfs2(v[i], v[i]);
}
void update(long long x) {
  if (shu[x * 2] < 0 || shu[x * 2 + 1] < 0 ||
      (long double)shu[x * 2] * (long double)shu[x * 2 + 1] > inf) {
    shu[x] = -1;
    return;
  }
  shu[x] = shu[x * 2] * shu[x * 2 + 1];
}
void build(long long now, long long l, long long r) {
  if (l == r) {
    shu[now] = value[a[l]];
    return;
  }
  long long mid = (l + r) >> 1;
  build(now * 2, l, mid);
  build(now * 2 + 1, mid + 1, r);
  update(now);
}
void change(long long now, long long l, long long r, long long x, long long y) {
  if (l == r) {
    shu[now] = y;
    return;
  }
  long long mid = (l + r) >> 1;
  if (x <= mid)
    change(now * 2, l, mid, x, y);
  else
    change(now * 2 + 1, mid + 1, r, x, y);
  update(now);
}
long long query2(long long now, long long l, long long r, long long x,
                 long long y) {
  if (l >= x && r <= y) {
    return shu[now];
  }
  long long mid = (l + r) >> 1;
  long long ans1 = 1, ans2 = 1;
  if (mid >= x) ans1 *= query2(now * 2, l, mid, x, y);
  if (ans1 < 0) return -1;
  if (mid + 1 <= y) ans2 *= query2(now * 2 + 1, mid + 1, r, x, y);
  if (ans2 < 0) return -1;
  if ((long double)ans1 * (long double)ans2 > inf) return -1;
  return ans1 * ans2;
}
long long query(long long x, long long y, long long c) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    long long z;
    z = query2(1, 1, n, dfn[top[x]], dfn[x]);
    if (z < 0 || c == 0) {
      return 0;
    } else
      c /= z;
    x = fa[top[x]];
  }
  if (dfn[x] > dfn[y]) swap(x, y);
  long long z = query2(1, 1, n, dfn[x] + 1, dfn[y]);
  if (z < 0)
    return 0;
  else
    return c / z;
}
signed main() {
  n = read();
  m = read();
  ycl();
  for (long long i = 1; i <= n - 1; i++) {
    long long x, y, z;
    x = read();
    y = read();
    z = read();
    add(x, y, z);
    add(y, x, z);
  }
  root = 1;
  dep[root] = 1;
  dfs1(root);
  dfs2(root, root);
  build(1, 1, n);
  for (long long i = 1; i <= m; i++) {
    long long opt;
    opt = read();
    if (opt == 1) {
      long long x, y, z;
      x = read();
      y = read();
      z = read();
      printf("%lld\n", query(x, y, z));
    } else {
      long long p, c;
      p = read();
      c = read();
      change(1, 1, n, dfn[vv[p]], c);
    }
  }
  return 0;
}
