#include <bits/stdc++.h>
#pragma optmize("O2")
using namespace std;
inline long long lread() {
  long long x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch <= '9' && ch >= '0') {
    x = (x << 3) + (x << 1) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void print(long long x) {
  if (x < 0ll) putchar('-'), x = -x;
  if (x > 9ll) print(x / 10ll);
  putchar(x % 10ll + '0');
}
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch <= '9' && ch >= '0') {
    x = (x << 3) + (x << 1) + ch - '0';
    ch = getchar();
  }
  return x * f;
}
struct BCJ {
  int bfa[200005];
  inline void init(int n) {
    for (register int i = 1; i <= n; ++i) bfa[i] = i;
  }
  int find(int i) {
    if (bfa[i] == i) {
      return i;
    } else {
      return (bfa[i] = find(bfa[i]));
    }
  }
  inline void union_set(int i, int j) { bfa[find(i)] = find(j); }
} Set;
struct edge {
  int to;
  long long cost;
};
vector<edge> G[200005];
inline void add_edge(int u, int v, long long w) {
  edge temp;
  temp.cost = w;
  temp.to = v;
  G[u].push_back(temp);
}
long long anc[200005][18], fa[200005], d[200005], len[200005];
void dfs(int u, int father) {
  anc[u][0] = fa[u];
  for (register int i = 1; i < 18; ++i) {
    anc[u][i] = anc[anc[u][i - 1]][i - 1];
  }
  for (register int i = 0; i < G[u].size(); ++i) {
    if (G[u][i].to != father) {
      d[G[u][i].to] = d[u] + 1;
      fa[G[u][i].to] = u;
      dfs(G[u][i].to, u);
      len[G[u][i].to] = G[u][i].cost;
      if (G[u][i].cost == 1) {
        Set.union_set(G[u][i].to, u);
      }
    }
  }
}
inline void swap(int &a, int &b) {
  int t = a;
  a = b;
  b = t;
}
inline int LCA(int u, int v) {
  if (d[u] < d[v]) {
    swap(u, v);
  }
  for (register int i = 18 - 1; i >= 0; --i) {
    if (d[anc[u][i]] >= d[v]) {
      u = anc[u][i];
    }
  }
  if (u == v) return u;
  for (register int i = 18 - 1; i >= 0; --i) {
    if (anc[u][i] != anc[v][i]) {
      u = anc[u][i];
      v = anc[v][i];
    }
  }
  return fa[u];
}
int U[200005], V[200005];
int main() {
  int n = read();
  register int m = read();
  for (register int i = 1; i < n; ++i) {
    int u = read(), v = read();
    long long w = lread();
    U[i] = u;
    V[i] = v;
    add_edge(u, v, w);
    add_edge(v, u, w);
  }
  Set.init(n);
  dfs(1, 1);
  while (m--) {
    int opr = read();
    if (opr == 1) {
      int a = read();
      int b = read();
      long long y = lread();
      int lca = LCA(a, b);
      while (d[a] > d[lca]) {
        y /= len[a];
        a = fa[a];
        if (!y) {
          putchar('0');
          putchar('\n');
          break;
        }
        if (len[a] == 1) {
          a = Set.find(a);
        }
      }
      if (y == 0) {
        continue;
      }
      while (d[b] > d[lca]) {
        y /= len[b];
        b = fa[b];
        if (!y) {
          putchar('0');
          putchar('\n');
          break;
        }
        if (len[b] == 1) {
          b = Set.find(b);
        }
      }
      if (y == 0) {
        continue;
      }
      print(y);
      putchar('\n');
    } else if (opr == 2) {
      int p = read();
      long long c = lread();
      int v = (d[U[p]] > d[V[p]] ? U[p] : V[p]);
      len[v] = c;
      if (len[v] == 1) {
        Set.union_set(v, fa[v]);
      }
    }
  }
}
