#include <bits/stdc++.h>
using namespace std;
vector<int> adj[200100], indexx[200100];
vector<unsigned long long int> costs[200100];
unsigned long long int baseArray[200100];
int ptr;
int chainNo, chainInd[200100], chainHead[200100], posInBase[200100];
int depth[200100], pa[20][200100], otherEnd[200100], subsize[200100];
unsigned long long int st[200100 * 6], qt[200100 * 6];
void make_tree(int cur, int s, int e) {
  if (s == e - 1) {
    st[cur] = (baseArray[s]);
    return;
  }
  int c1 = (cur << 1), c2 = c1 | 1, m = (s + e) >> 1;
  make_tree(c1, s, m);
  make_tree(c2, m, e);
  if ((st[c1] * st[c2]) / st[c2] != st[c1])
    st[cur] = 1e18 + 1;
  else
    st[cur] = st[c1] * st[c2];
}
void update_tree(int cur, int s, int e, int x, unsigned long long int val) {
  if (s > x || e <= x) return;
  if (s == x && s == e - 1) {
    st[cur] = val;
    return;
  }
  int c1 = (cur << 1), c2 = c1 | 1, m = (s + e) >> 1;
  update_tree(c1, s, m, x, val);
  update_tree(c2, m, e, x, val);
  if ((st[c1] * st[c2]) / st[c2] != st[c1])
    st[cur] = 1e19;
  else
    st[cur] = st[c1] * st[c2];
}
void query_tree(int cur, int s, int e, int S, int E) {
  if (s >= E || e <= S) {
    qt[cur] = 1;
    return;
  }
  if (s >= S && e <= E) {
    qt[cur] = st[cur];
    return;
  }
  int c1 = (cur << 1), c2 = c1 | 1, m = (s + e) >> 1;
  query_tree(c1, s, m, S, E);
  query_tree(c2, m, e, S, E);
  if ((qt[c1] * qt[c2]) / qt[c2] != qt[c1])
    qt[cur] = 1e19;
  else
    qt[cur] = qt[c1] * qt[c2];
}
unsigned long long int query_up(int u, int v) {
  if (u == v) return 1;
  int uchain, vchain = chainInd[v];
  unsigned long long int ans = 1;
  while (1) {
    uchain = chainInd[u];
    if (uchain == vchain) {
      if (u == v) break;
      query_tree(1, 0, ptr, posInBase[v] + 1, posInBase[u] + 1);
      if ((ans * qt[1]) / qt[1] != ans)
        ans = 1e18 + 1;
      else
        ans *= qt[1];
      break;
    }
    query_tree(1, 0, ptr, posInBase[chainHead[uchain]], posInBase[u] + 1);
    if ((ans * qt[1]) / qt[1] != ans)
      ans = 1e19;
    else
      ans *= qt[1];
    u = chainHead[uchain];
    u = pa[0][u];
  }
  return ans;
}
int LCA(int u, int v) {
  if (depth[u] < depth[v]) swap(u, v);
  int diff = depth[u] - depth[v];
  for (int i = 0; i < 20; i++)
    if ((diff >> i) & 1) u = pa[i][u];
  if (u == v) return u;
  for (int i = 20 - 1; i >= 0; i--)
    if (pa[i][u] != pa[i][v]) {
      u = pa[i][u];
      v = pa[i][v];
    }
  return pa[0][u];
}
void query(int u, int v, unsigned long long int y) {
  int lca = LCA(u, v);
  unsigned long long int ans = query_up(u, lca);
  unsigned long long int mm = query_up(v, lca);
  if ((ans * mm) / mm != ans)
    ans = 1e19;
  else
    ans *= mm;
  if (ans > y)
    printf("0\n");
  else {
    printf("%lld\n", y / ans);
  }
}
void change(int i, unsigned long long int val) {
  int u = otherEnd[i];
  update_tree(1, 0, ptr, posInBase[u], val);
}
void HLD(int curNode, unsigned long long int cost, int prev) {
  if (chainHead[chainNo] == -1) {
    chainHead[chainNo] = curNode;
  }
  chainInd[curNode] = chainNo;
  posInBase[curNode] = ptr;
  baseArray[ptr++] = cost;
  int sc = -1;
  unsigned long long int ncost;
  for (int i = 0; i < adj[curNode].size(); i++)
    if (adj[curNode][i] != prev) {
      if (sc == -1 || subsize[sc] < subsize[adj[curNode][i]]) {
        sc = adj[curNode][i];
        ncost = costs[curNode][i];
      }
    }
  if (sc != -1) {
    HLD(sc, ncost, curNode);
  }
  for (int i = 0; i < adj[curNode].size(); i++)
    if (adj[curNode][i] != prev) {
      if (sc != adj[curNode][i]) {
        chainNo++;
        HLD(adj[curNode][i], costs[curNode][i], curNode);
      }
    }
}
void dfs(int cur, int prev, int _depth = 0) {
  pa[0][cur] = prev;
  depth[cur] = _depth;
  subsize[cur] = 1;
  for (int i = 0; i < adj[cur].size(); i++)
    if (adj[cur][i] != prev) {
      otherEnd[indexx[cur][i]] = adj[cur][i];
      dfs(adj[cur][i], cur, _depth + 1);
      subsize[cur] += subsize[adj[cur][i]];
    }
}
int main() {
  for (int i = 0; i <= 6 * 200100 - 1; i++) qt[i] = 1, st[i] = 1;
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);
  ptr = 0;
  for (int i = 0; i <= n - 1; i++) {
    adj[i].clear();
    costs[i].clear();
    indexx[i].clear();
    chainHead[i] = -1;
    for (int j = 0; j < 20; j++) pa[j][i] = -1;
  }
  for (int i = 1; i <= n - 1; i++) {
    int u, v;
    unsigned long long int c;
    scanf("%d %d %lld", &u, &v, &c);
    u--;
    v--;
    adj[u].push_back(v);
    costs[u].push_back((c));
    indexx[u].push_back(i - 1);
    adj[v].push_back(u);
    costs[v].push_back((c));
    indexx[v].push_back(i - 1);
  }
  chainNo = 0;
  dfs(0, -1);
  HLD(0, 0, -1);
  make_tree(1, 0, ptr);
  for (int i = 1; i < 20; i++)
    for (int j = 0; j < n; j++)
      if (pa[i - 1][j] != -1) pa[i][j] = pa[i - 1][pa[i - 1][j]];
  while (m--) {
    int qq;
    scanf("%d", &qq);
    if (qq == 1) {
      int a, b;
      unsigned long long int y;
      scanf("%d", &a);
      scanf("%d", &b);
      scanf("%lld", &y);
      query(a - 1, b - 1, y);
    } else {
      int pp;
      unsigned long long int cc;
      scanf("%d", &pp);
      scanf("%lld", &cc);
      change(pp - 1, (cc));
    }
  }
  return 0;
}
