#include <bits/stdc++.h>
using namespace std;
using namespace std;
class LCA {
  vector<vector<int> > M;
  int N;
  void bfs(const vector<vector<int> >& adj, int src) {
    const int INF = 1000000000;
    L = vector<int>(N, INF);
    L[src] = 0;
    P = vector<int>(N, -1);
    queue<int> q;
    q.push(src);
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int j = 0; j < (int)adj[u].size(); ++j) {
        int v = adj[u][j];
        if (L[v] > L[u] + 1) {
          L[v] = L[u] + 1;
          P[v] = u;
          q.push(v);
        }
      }
    }
  }
  void preprocess() {
    int LOGN = N > 1 ? 1 + (sizeof(int) * 8 - 1 - __builtin_clz((N))) : 1;
    M = vector<vector<int> >(LOGN, vector<int>(N, -1));
    for (int i = 0; i < N; ++i) M[0][i] = P[i];
    for (int j = 1; (1 << j) < N; ++j)
      for (int i = 0; i < N; ++i)
        if (M[j - 1][i] != -1) M[j][i] = M[j - 1][M[j - 1][i]];
  }

 public:
  vector<int> P;
  vector<int> L;
  LCA(const vector<vector<int> >& adj, int root = 0) {
    N = adj.size();
    if (N <= 0) return;
    bfs(adj, root);
    preprocess();
  }
  int query(int p, int q) {
    if (L[p] < L[q]) swap(p, q);
    int LOGLp = L[p] > 0 ? (sizeof(int) * 8 - 1 - __builtin_clz((L[p]))) : 0;
    for (int j = LOGLp; j >= 0; --j)
      if (L[p] - (1 << j) >= L[q]) p = M[j][p];
    if (p == q) return p;
    for (int j = LOGLp; j >= 0; --j)
      if (M[j][p] != -1 && M[j][p] != M[j][q]) p = M[j][p], q = M[j][q];
    return P[p];
  }
  int ancestor(int u, int d) {
    if (L[u] < d) return -1;
    int p = u;
    for (int j = (sizeof(int) * 8 - 1 - __builtin_clz((d))); j >= 0; --j)
      if (d & (1 << j)) p = M[j][p];
    return p;
  }
};
struct Edge {
  int u, v;
  long long x;
  Edge(int _u, int _v, long long _x) : u(_u), v(_v), x(_x) {}
};
int N, Q;
vector<vector<int> > adj;
vector<vector<int> > adjE;
vector<Edge> edges;
vector<int> par2;
vector<int> par_edge;
void dfs2(int u, int ex = -1) {
  par_edge[u] = ex;
  for (int e : adjE[u]) {
    int v = edges[e].u == u ? edges[e].v : edges[e].u;
    if (v == par2[u]) continue;
    par2[v] = u;
    dfs2(v, edges[e].x > 1 ? e : ex);
  }
}
long long query(LCA& lca, int u, int v, long long y) {
  int w = lca.query(u, v);
  vector<long long> mult1;
  for (int z = u, t = 0; z >= 0 && lca.L[z] > lca.L[w] && t <= 60; ++t) {
    int e = par_edge[z];
    vector<int> upd;
    for (int zz = z; e >= 0 && edges[e].x <= 1;) {
      upd.push_back(zz);
      zz = edges[e].v;
      e = par_edge[zz];
    }
    for (int zz : upd) {
      par_edge[zz] = e;
    }
    if (e < 0 || lca.L[edges[e].v] <= lca.L[w]) break;
    mult1.push_back(edges[e].x);
    z = edges[e].u;
  }
  for (long long x : mult1) {
    y /= x;
  }
  if (y <= 0) return y;
  vector<long long> mult2;
  for (int z = v, t = 0; z >= 0 && lca.L[z] > lca.L[w] && t <= 60; ++t) {
    int e = par_edge[z];
    vector<int> upd;
    for (int zz = z; e >= 0 && edges[e].x <= 1;) {
      upd.push_back(zz);
      zz = edges[e].v;
      e = par_edge[zz];
    }
    for (int zz : upd) {
      par_edge[zz] = e;
    }
    if (e < 0 || lca.L[edges[e].v] <= lca.L[w]) break;
    mult2.push_back(edges[e].x);
    z = edges[e].u;
  }
  reverse(mult2.begin(), mult2.end());
  for (long long x : mult2) {
    y /= x;
  }
  return y;
}
int main(int argc, char* argv[]) {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> N >> Q;
  adj = vector<vector<int> >(N);
  adjE = vector<vector<int> >(N);
  for (int j = 1; j < N; ++j) {
    int u, v;
    long long x;
    cin >> u >> v >> x;
    --u, --v;
    adj[u].push_back(v);
    adj[v].push_back(u);
    adjE[u].push_back(edges.size());
    adjE[v].push_back(edges.size());
    edges.push_back(Edge(u, v, x));
  }
  par2 = vector<int>(N, -1);
  par_edge = vector<int>(N, -1);
  dfs2(0);
  for (Edge& e : edges) {
    if (par2[e.u] == -1) continue;
    if (par2[e.v] == -1)
      swap(e.u, e.v);
    else if (par2[e.u] == e.v)
      swap(e.u, e.v);
  }
  LCA lca(adj, 0);
  for (int q = 0; q < Q; ++q) {
    int cmd;
    cin >> cmd;
    if (cmd == 1) {
      int u, v;
      long long y;
      cin >> u >> v >> y;
      --u, --v;
      long long res = query(lca, u, v, y);
      cout << res << '\n';
    } else {
      int e;
      long long x;
      cin >> e >> x;
      --e;
      int v = edges[e].v;
      if (edges[e].x > 1 && x <= 1) par_edge[v] = par_edge[edges[e].u];
      edges[e].x = x;
    }
  }
  return 0;
}
