#include <bits/stdc++.h>
using namespace std;
const int NN = 200010;
int n, Q, tot, head[NN], sz;
struct Tree {
  int tag;
  long long val;
} tr[NN << 2];
int size[NN], son[NN], deep[NN], pos[NN], belong[NN], fa[NN];
struct E {
  int ne, v;
} e[NN << 1];
struct EDGE {
  int x, y;
  long long z;
} edge[NN];
void Build(int xx, int yy) {
  e[++tot].ne = head[xx], head[xx] = tot, e[tot].v = yy;
  e[++tot].ne = head[yy], head[yy] = tot, e[tot].v = xx;
}
void DFS1(int xx) {
  size[xx] = 1;
  for (int i = head[xx]; i; i = e[i].ne)
    if (e[i].v != fa[xx]) {
      deep[e[i].v] = deep[xx] + 1;
      fa[e[i].v] = xx;
      DFS1(e[i].v);
      size[xx] += size[e[i].v];
      if (size[e[i].v] > size[son[xx]]) son[xx] = e[i].v;
    }
}
void DFS2(int xx, int chain) {
  belong[xx] = chain, pos[xx] = ++sz;
  if (son[xx]) DFS2(son[xx], chain);
  for (int i = head[xx]; i; i = e[i].ne)
    if (e[i].v != son[xx] && e[i].v != fa[xx]) DFS2(e[i].v, e[i].v);
}
void push_up(int p) {
  if (tr[p << 1].tag | tr[p << 1 | 1].tag)
    tr[p].tag = 1;
  else {
    double tmp1 = tr[p << 1].val, tmp2 = tr[p << 1 | 1].val;
    if (tmp1 * tmp2 > 1e18)
      tr[p].tag = 1;
    else
      tr[p].val = tr[p << 1].val * tr[p << 1 | 1].val, tr[p].tag = 0;
  }
}
void Update(int p, int l, int r, int pos, long long v) {
  if (l == r)
    tr[p].val = v;
  else {
    int mid = (l + r) >> 1;
    if (pos <= mid)
      Update(p << 1, l, mid, pos, v);
    else
      Update(p << 1 | 1, mid + 1, r, pos, v);
    push_up(p);
  }
}
long long Query(int p, int l, int r, int L, int R) {
  int mid = (l + r) >> 1;
  long long tmp1 = 1, tmp2 = 1;
  if (L <= l && R >= r) return tr[p].tag ? -1 : tr[p].val;
  if (L <= mid) tmp1 = Query(p << 1, l, mid, L, R);
  if (R > mid) tmp2 = Query(p << 1 | 1, mid + 1, r, L, R);
  if (tmp1 < 0 || tmp2 < 0) return -1;
  double t1 = tmp1, t2 = tmp2;
  if (t1 * t2 > 1e18) return -1;
  return tmp1 * tmp2;
}
long long Solve(int x, int y) {
  long long ans = 1, flag;
  int fx = belong[x], fy = belong[y];
  for (; fx != fy; x = fa[fx], fx = belong[x]) {
    if (deep[fx] < deep[fy]) swap(fx, fy), swap(x, y);
    flag = Query(1, 1, n, pos[fx], pos[x]);
    if (flag < 0) return -1;
    double t1 = flag, t2 = ans;
    if (t1 * t2 > 1e18) return -1;
    ans *= flag;
  }
  if (x == y)
    return ans;
  else if (deep[x] < deep[y])
    swap(x, y);
  flag = Query(1, 1, n, pos[y] + 1, pos[x]);
  if (flag < 0) return -1;
  double t1 = flag, t2 = ans;
  if (t1 * t2 > 1e18) return -1;
  ans *= flag;
  return ans;
}
int main() {
  scanf("%d%d", &n, &Q);
  for (int i = 1; i < n; ++i)
    scanf("%d%d%I64d", &edge[i].x, &edge[i].y, &edge[i].z),
        Build(edge[i].x, edge[i].y);
  DFS1(1), DFS2(1, 1);
  for (int i = 1; i < n; ++i) {
    int &x = edge[i].x, &y = edge[i].y;
    if (deep[x] > deep[y]) swap(x, y);
    Update(1, 1, n, pos[y], edge[i].z);
  }
  for (int _ = 1, op; _ <= Q; ++_) {
    int x, y;
    long long z;
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d%I64d", &x, &y, &z);
      long long tmp = Solve(x, y);
      if (tmp < 0)
        puts("0");
      else
        printf("%I64d\n", z / tmp);
    } else {
      scanf("%d%I64d", &x, &z);
      Update(1, 1, n, pos[edge[x].y], z);
    }
  }
  return 0;
}
