#include <bits/stdc++.h>
using namespace std;
template <int N>
struct tree {
  vector<pair<int, int> > conn[N];
  int nedges, edgesub[N];
  long long edgex[N];
  tree() { nedges = 0; }
  void addEdge(int a, int b, long long nval) {
    conn[a].push_back(make_pair(b, nedges));
    conn[b].push_back(make_pair(a, nedges));
    edgex[nedges++] = nval;
  }
  int depth[N], paredge[N], parent[N], master[N];
  void init(int pos = 0, int prev = -1, int preve = -1, int curdepth = 0) {
    depth[pos] = curdepth;
    paredge[pos] = preve;
    if (preve != -1) edgesub[preve] = pos;
    parent[pos] = prev;
    for (auto next : conn[pos])
      if (next.first != prev) init(next.first, pos, next.second, curdepth + 1);
    master[pos] = pos;
    if (preve != -1 && edgex[preve] == 1) master[pos] = prev;
  }
  int getmaster(int pos) {
    if (master[pos] == pos) return pos;
    int ret = getmaster(master[pos]);
    master[pos] = ret;
    return ret;
  }
  long long query(int a, int b, long long todiv) {
    a = getmaster(a);
    b = getmaster(b);
    while (a != b && todiv > 0) {
      if (depth[b] > depth[a]) swap(a, b);
      todiv /= edgex[paredge[a]];
      a = getmaster(parent[a]);
    }
    return todiv;
  }
  void update(int ind, long long nval) {
    edgex[ind] = nval;
    if (nval == 1) master[edgesub[ind]] = parent[edgesub[ind]];
  }
};
int n, m;
int p1, p2;
long long p3;
tree<200000> t;
int main() {
  cin.sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 0; i < n - 1; i++) {
    cin >> p1 >> p2 >> p3;
    t.addEdge(p1 - 1, p2 - 1, p3);
  }
  t.init();
  for (int i = 0; i < m; i++) {
    cin >> p1;
    if (p1 == 1) {
      cin >> p1 >> p2 >> p3;
      cout << t.query(p1 - 1, p2 - 1, p3) << '\n';
    } else {
      cin >> p2 >> p3;
      t.update(p2 - 1, p3);
    }
  }
  return 0;
}
