#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}
const long long maxn = (long long)4e5 + 100;
const long long maxm = (long long)52;
const int logn = 22;
const long long INF = 2e18 + 100;
const long long MOD = 1000000007;
const double PI = acos(-1.0);
const double EPS = 1e-12;
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  while (cin >> n >> m) {
    vector<vector<int> > g(n + 1);
    vector<int> from;
    vector<int> to;
    vector<long long> c;
    for (int i = (0); i < ((n - 1)); ++i) {
      long long x, y, w;
      cin >> x >> y >> w;
      from.push_back(x);
      to.push_back(y);
      c.push_back(w);
      g[x].push_back(from.size() - 1);
      from.push_back(y);
      to.push_back(x);
      c.push_back(w);
      g[y].push_back(from.size() - 1);
    }
    function<long long(long long, long long)> Mul = [&](long long x,
                                                        long long y) {
      if (y != 0 && x > INF / y) return INF;
      return x * y;
    };
    vector<int> sz(n + 1);
    vector<long long> wi(n + 1, 1);
    vector<int> pre(n + 1);
    vector<int> dep(n + 1);
    function<void(int, int)> DfsSz = [&](int x, int fa) {
      dep[x] = dep[fa] + 1;
      pre[x] = fa;
      for (int i = (0); i < ((g[x].size())); ++i)
        if (to[g[x][i]] != fa) {
          int ind = g[x][i];
          int y = to[ind];
          wi[y] = c[ind];
          DfsSz(y, x);
          sz[x] += sz[y];
          if (sz[y] > sz[to[g[x][0]]]) {
            swap(g[x][0], g[x][i]);
          }
        }
      sz[x] += 1;
    };
    vector<int> st(n + 1);
    vector<int> ed(n + 1);
    int tot = 0;
    vector<int> anc(n + 1);
    function<void(int, int, int)> DfsHL = [&](int x, int fa, int chain) {
      st[x] = ++tot;
      anc[x] = chain;
      for (int i = (0); i < ((g[x].size())); ++i)
        if (to[g[x][i]] != fa) {
          int y = to[g[x][i]];
          if (i == 0) {
            DfsHL(y, x, chain);
          } else {
            DfsHL(y, x, y);
          }
        }
      ed[x] = tot;
    };
    vector<long long> a;
    function<void(int, int, int)> PushUp = [&](int root, int l, int r) {
      if (l == r) return;
      long long left = a[root << 1];
      long long right = a[root << 1 | 1];
      a[root] = Mul(left, right);
    };
    function<void(int, int, int, int, long long)> Update =
        [&](int root, int l, int r, int pos, long long v) {
          if (l == r) {
            assert(l == pos);
            a[root] = v;
            return;
          }
          int mid = (l + r) >> 1;
          if (pos <= mid) {
            Update(root << 1, l, mid, pos, v);
          } else {
            Update(root << 1 | 1, mid + 1, r, pos, v);
          }
          PushUp(root, l, r);
        };
    function<long long(int, int, int, int, int)> Query =
        [&](int root, int l, int r, int L, int R) {
          assert(L <= R);
          if (L <= l && r <= R) {
            return a[root];
          }
          long long left = 1;
          long long right = 1;
          int mid = (l + r) >> 1;
          if (L <= mid) {
            left = Query(root << 1, l, mid, L, R);
          }
          if (mid < R) {
            right = Query(root << 1 | 1, mid + 1, r, L, R);
          }
          return Mul(left, right);
        };
    DfsSz(1, 0);
    DfsHL(1, 0, 1);
    a.resize(tot * 4, 1);
    for (int i = (1); i <= (n); ++i) {
      Update(1, 1, tot, st[i], wi[i]);
    }
    for (int i = (0); i < ((m)); ++i) {
      int op;
      cin >> op;
      if (op == 1) {
        long long u, v, y;
        cin >> u >> v >> y;
        long long div = 1;
        while (anc[u] != anc[v]) {
          if (dep[anc[u]] < dep[anc[v]]) swap(u, v);
          int x = anc[u];
          int y = u;
          long long r = Query(1, 1, tot, st[x], st[y]);
          div = Mul(div, r);
          u = pre[x];
          if (dep[u] < dep[v]) swap(u, v);
        }
        if (st[u] < st[v]) swap(u, v);
        long long r = st[v] < st[u] ? Query(1, 1, tot, st[v] + 1, st[u]) : 1;
        div = Mul(div, r);
        cout << y / div << endl;
      } else {
        long long p, c;
        cin >> p >> c;
        int x = from[(p - 1) * 2];
        int y = to[(p - 1) * 2];
        if (pre[y] == x) swap(x, y);
        assert(pre[x] == y);
        wi[x] = c;
        Update(1, 1, tot, st[x], c);
      }
    }
  }
  return 0;
}
