#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, LOGN = 18;
vector<pair<int, int> > adj[N];
int h[N][20], par[N], p[N], my_edge[N], node[N], depth[N];
long long w[N];
void dfs(int u, int prev, int prev_edge, int height) {
  h[u][0] = prev;
  depth[u] = height;
  my_edge[u] = prev_edge;
  node[prev_edge] = u;
  for (int i = 0; i < adj[u].size(); i++) {
    int v = adj[u][i].first, edge = adj[u][i].second;
    if (v != prev) {
      par[edge] = prev_edge;
      dfs(v, u, edge, height + 1);
    }
  }
}
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 <= LOGN; i++)
    if (((1 << i) & diff) != 0) u = h[u][i];
  if (v == u) return u;
  for (int i = LOGN; i >= 0; i--) {
    if (h[v][i] != h[u][i]) v = h[v][i], u = h[u][i];
  }
  return h[v][0];
}
int parent(int u) {
  if (p[u] != u) p[u] = parent(p[u]);
  return p[u];
}
long long traverse(int u, int ancestor, long long x) {
  while (depth[node[u]] > depth[node[ancestor]] and x != 0 and u != 0) {
    if (w[u] == 1)
      u = parent(u);
    else {
      x /= w[u];
      u = par[u];
    }
  }
  return x;
}
int main() {
  iostream::sync_with_stdio(false);
  cin.tie(NULL);
  int n, m, u, v, type;
  long long x;
  cin >> n >> m;
  for (int i = 1; i < n; i++) {
    p[i] = i;
    cin >> u >> v >> x;
    w[i] = x;
    adj[u].push_back({v, i});
    adj[v].push_back({u, i});
  }
  dfs(1, 0, 0, 0);
  for (int i = 1; i < n; i++)
    if (w[i] == 1) p[i] = p[par[i]];
  for (int i = 1; i <= LOGN; i++)
    for (int j = 1; j <= n; j++) h[j][i] = h[h[j][i - 1]][i - 1];
  while (m--) {
    cin >> type;
    if (type == 1) {
      cin >> u >> v >> x;
      int nd = lca(u, v);
      x = traverse(my_edge[u], my_edge[nd], x);
      x = traverse(my_edge[v], my_edge[nd], x);
      cout << x << '\n';
    } else {
      cin >> u >> x;
      w[u] = x;
      if (w[u] == 1) p[u] = p[par[u]];
    }
  }
}
