#include <bits/stdc++.h>   using namespace std;   const int N = 200010;   const int LOGN = 20;   const long long LLMAX = 9223372036854775807ll;   vector<long long> adj[N], indexx[N];   vector<long long> costs[N];   long long baseArray[N], ptr;   long long chainNo, chainInd[N], chainHead[N], posInBase[N];   long long depth[N], par[LOGN][N], otherEnd[N], subTreeSize[N];   long long st[N * 10], qt[N * 10];   long long mrg(long long a, long long b) {     long long tmp = LLMAX / a;     if (b > tmp)       return LLMAX;     else       return a * b;   }   void make_tree(long long cur, long long s, long long e) {     if (s == e - 1) {       st[cur] = baseArray[s];       return;     }     long long c1 = (cur << 1), c2 = c1 | 1, m = (s + e) >> 1;     make_tree(c1, s, m);     make_tree(c2, m, e);     st[cur] = mrg(st[c1], st[c2]);   }   void update(long long cur, long long s, long long e, long long x,               long long val) {     if (s > x || e <= x) return;     if (s == x && s == e - 1) {       st[cur] = val;       return;     }     long long c1 = (cur << 1), c2 = c1 | 1, m = (s + e) >> 1;     update(c1, s, m, x, val);     update(c2, m, e, x, val);     st[cur] = mrg(st[c1], st[c2]);   }   void query(long long cur, long long s, long long e, long long S, long long E) {     if (s >= E || e <= S) {       qt[cur] = 1;       return;     }     if (s >= S && e <= E) {       qt[cur] = st[cur];       return;     }     long long c1 = (cur << 1), c2 = c1 | 1, m = (s + e) >> 1;     query(c1, s, m, S, E);     query(c2, m, e, S, E);     qt[cur] = mrg(qt[c1], qt[c2]);   }   long long query_up(long long u, long long v) {     if (u == v) return 1;     long long uchain, vchain = chainInd[v];     long long ans = 1;     while (1) {       uchain = chainInd[u];       if (uchain == vchain) {         if (u == v) break;         query(1, 0, ptr, posInBase[v] + 1, posInBase[u] + 1);         ans = mrg(ans, qt[1]);         break;       }       query(1, 0, ptr, posInBase[chainHead[uchain]], posInBase[u] + 1);       ans = mrg(ans, qt[1]);       u = chainHead[uchain];       u = par[0][u];     }     return ans;   }   long long LCA(long long u, long long v) {     if (depth[u] < depth[v]) swap(u, v);     long long diff = depth[u] - depth[v];     for (long long i = 0; i < LOGN; i++)       if ((diff >> i) & 1) u = par[i][u];     if (u == v) return u;     for (long long i = LOGN - 1; i >= 0; i--)       if (par[i][u] != par[i][v]) {         u = par[i][u];         v = par[i][v];       }     return par[0][u];   }   void change(long long i, long long val) {     long long u = otherEnd[i];     update(1, 0, ptr, posInBase[u], val);   }   void HLD(long long curNode, long long cost, long long prev) {     if (chainHead[chainNo] == -1) {       chainHead[chainNo] = curNode;     }     chainInd[curNode] = chainNo;     posInBase[curNode] = ptr;     baseArray[ptr++] = cost;     long long sc = -1, ncost;     for (long long i = 0; i < adj[curNode].size(); i++)       if (adj[curNode][i] != prev) {         if (sc == -1 || subTreeSize[sc] < subTreeSize[adj[curNode][i]]) {           sc = adj[curNode][i];           ncost = costs[curNode][i];         }       }     if (sc != -1) {       HLD(sc, ncost, curNode);     }     for (long long i = 0; i < adj[curNode].size(); i++)       if (adj[curNode][i] != prev) {         if (sc != adj[curNode][i]) {           chainNo++;           HLD(adj[curNode][i], costs[curNode][i], curNode);         }       }   }   void dfs(long long cur, long long prev, long long _depth) {     par[0][cur] = prev;     depth[cur] = _depth;     subTreeSize[cur] = 1;     for (long long i = 0; i < adj[cur].size(); i++)       if (adj[cur][i] != prev) {         otherEnd[indexx[cur][i]] = adj[cur][i];         dfs(adj[cur][i], cur, _depth + 1);         subTreeSize[cur] += subTreeSize[adj[cur][i]];       }   }   int main() {     ptr = 0;     long long n, m;     scanf( %lld%lld , &n, &m);     for (long long i = 0; i < n; i++) {       chainHead[i] = -1;       for (long long j = 0; j < LOGN; j++) par[j][i] = -1;     }     for (long long i = 1; i < n; i++) {       long long u, v, w;       cin >> u >> v >> w;       u--;       v--;       adj[u].push_back(v);       costs[u].push_back(w);       indexx[u].push_back(i - 1);       adj[v].push_back(u);       costs[v].push_back(w);       indexx[v].push_back(i - 1);     }     chainNo = 0;     dfs(0, -1, 0);     HLD(0, -1, -1);     make_tree(1, 0, ptr);     for (long long i = 1; i < LOGN; i++)       for (long long j = 0; j < n; j++) {         if (par[i - 1][j] != -1) par[i][j] = par[i - 1][par[i - 1][j]];       }     for (long long i = 0; i < m; i++) {       long long type;       scanf( %lld , &type);       if (type == 1) {         long long u, v;         long long w;         scanf( %lld %lld %lld , &u, &v, &w);         u--, v--;         long long lc = LCA(u, v);         long long ans = mrg(query_up(u, lc), query_up(v, lc));         printf( %lld n , w / ans);       } else {         long long e;         long long nc;         scanf( %lld%lld , &e, &nc);         e--;         change(e, nc);       }     }   }