#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);
    }
  }
}
