/*Heroes Never Die!*/
#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 200006
typedef long long ll;
ll top[MAXN] , siz[MAXN] , dep[MAXN] , pre[MAXN] , hea[MAXN] , tig[MAXN] , bac[MAXN] , cnt;
ll w[MAXN] , bc[MAXN]; // w_i == w from i to i's father
ll n , m;
struct edge{
	ll u,w , id;edge* next;
	edge( ll u = 0 , ll w = 0 , ll id = 0 , edge* next = NULL ):u(u),w(w),id(id),next(next) {}
	void insert( ll u , ll w , ll id ) {
		if( this->next == NULL ) this->next = new edge( u , w, id , NULL );
		else this->next = new edge( u , w , id , this->next );
	}
}e[MAXN];

void dfs( ll u , ll fa ) {
	siz[u] = 1 , dep[u] = dep[fa] + 1;
	for( edge* n = e[u].next;n!=NULL;n=n->next ) {
		ll v = n->u;
		if( v == fa ) continue;
		pre[v] = u , w[v] = n->w , bc[n->id] = v;
		dfs( v , u );
		if( !hea[u] || siz[v] > siz[hea[u]] ) hea[u] = v;
		siz[u] += siz[v];
	}
}
void dfs2( ll u , ll to ) {
	top[u] = to , tig[u] = ++cnt , bac[cnt] = u;
	if( !hea[u] ) return;
	dfs2( hea[u] , to );
	for( edge* n = e[u].next;n!=NULL;n=n->next ) {
		ll v = n->u;
		if( v == pre[u] || v == hea[u] ) continue;
		dfs2( v , v );
	}
}
ll sum[MAXN<<2];
inline void pushup( ll rt ) {
	if( sum[rt<<1|1] > 1e18/sum[rt<<1] ) sum[rt] = -1;
	sum[rt] = sum[rt<<1] * sum[rt<<1|1];
}
void build( ll rt, ll l ,ll r ) {
	if( l == r ) { sum[rt] = w[bac[l]]; return; }
	ll m = l + r >> 1;
	build( rt<<1 , l , m ) , build( rt<<1|1, m + 1 , r );
	pushup( rt );
}
void modify( ll rt,ll l, ll r , ll p , ll x ) {
	if( l == r ) { sum[rt] = x; return; }
	ll m = l + r >> 1;
	if( p <= m ) modify( rt<<1 , l , m , p , x );
	else modify( rt<<1|1, m + 1 , r , p , x );
	pushup( rt );
}
ll query( ll rt , ll l , ll r , ll L , ll R ) {
	if( L <= l && R >= r ) return sum[rt];
	ll m = l + r >> 1 , res = 1;
	if( L <= m ) res *= query( rt << 1 , l , m , L , R );
	if( R >  m ) {
		ll ret = query( rt << 1 | 1 , m + 1 , r, L , R );
		if( 1e18 / ret < res || res == -1 ) return res = -1;
		else res *= ret;
	}
	return res;
}
ll U( ll u , ll x ) {
	modify( 1 , 1 , n , tig[bc[u]] , x );
}
ll Q( ll u , ll v , ll y ) {
	while( top[u] != top[v] ) {
		if( dep[top[u]] < dep[top[v]] ) swap(u,v);
		ll res = query( 1,1,n, tig[top[u]] , tig[u] );
		if( res <= 0 ) return 0;
		//cout << res << endl;
		y /= res;
		if( y <= 0 ) return 0;
		u = pre[top[u]];
	}
	if( u == v ) return y;
	if( dep[u] > dep[v] ) swap( u , v );
	ll res = query( 1 , 1 , n , tig[u]-1 , tig[v] );
	if( res <= 0 ) return 0;
	y /= res;
	return y <= 0 ? 0 : y;
}

int  main() {
	//freopen("input","r",stdin);
	cin >> n >> m;
	for( ll i = 1 , u , v,w ; i <= n-1 ; ++ i )
		scanf("%lld%lld%lld",&u,&v,&w) , e[u].insert(v,w,i),e[v].insert(u,w,i);
	w[1] = 1;
	dfs(1,1) , dfs2(1,1);
	build( 1 , 1 , n );
	ll opt ,  u , v , c;
	while( m-- ) {
		scanf("%lld",&opt);
		if( opt == 1 ) scanf("%lld%lld%lld",&u,&v,&c) , printf("%lld\n",Q(u,v,c));
		else scanf("%lld%lld",&u,&v) , U( u , v );
	}
}
//qwq


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#define N 200005
using namespace std;
struct node{
	int v;
	long long w;
	node(){};
	node(int V,long long W){
		v = V,w = W;
	}
};
int n,m,dep[N],dp[N][21],fa[N],U[N],V[N];
long long cost[N];
vector<node>G[N];
void dfs(int u,int fa0){
	for (int i = 0;i < G[u].size();i ++){
		int v = G[u][i].v;
		if (v == fa0)
			continue;
		dep[v] = dep[u] + 1;
		dp[v][0] = u;
		dfs(v,u);
		cost[v] = G[u][i].w;
		fa[v] = v;
		if (G[u][i].w == 1 && fa0 != 0)
			fa[v] = u;
	}
}
void build(int root){
	dfs(root,0);
	for (int j = 1;j <= 20;j ++)
		for (int i = 1;j <= n;j ++)
			dp[i][j] = dp[dp[i][j - 1]][j - 1];
}
void mov(int &u,int v){
	for (int i = 20;i >= 0;i --)
		if (dep[dp[u][i]] >= dep[v])
			u = dp[u][i];
}
int getlca(int u,int v){
	if (dep[u] > dep[v])
		mov(u,v);
	if (dep[u] < dep[v])
		mov(v,u);
	if (u == v)
		return u;
	for (int i = 20;i >= 0;i --){
		if (dp[u][i] != dp[v][i]){
			u = dp[u][i];
			v = dp[v][i];
		}
	}
	return dp[u][0];
}
int findset(int x){
	if (fa[x] != x)
		fa[x] = findset(fa[x]);
	return fa[x];
}
void make(int l,int fuck,long long &c){
	while (c && dep[l] > dep[fuck]){
		c = c / cost[l];
		l = dp[l][0];
		l = findset(l);
	}
}
int main(){
	scanf ("%d%d",&n,&m);
	for (int i = 1;i < n;i ++){
		long long w;
		scanf ("%d%d",&U[i],&V[i]);
		scanf ("%lld",&w);
		G[U[i]].push_back(node(V[i],w));
		G[V[i]].push_back(node(U[i],w));
	}
	build(1);
	/*while (m --){
		int flag;
		scanf ("%d",&flag);
		if (flag == 1){
			int a,b;
			long long c;
			scanf ("%d%d%lld",&a,&b,&c);
			int lca = getlca(a,b);
			make(a,lca,c);
			make(b,lca,c);
			printf("%lld\n",c);
		}
		else {
			int p;
			long long c;
			scanf ("%d%lld",&p,&c);
			int u = U[p];
			int v = V[p];
			if (dep[U[p]] < dep[V[p]])
				swap(U[p],V[p]);
			cost[U[p]] = c;
			if (c == 1)
				fa[U[p]] = fa[V[p]];
		}
	}*/
	while (m --){
		int flag;
		scanf ("%d",&flag);
		if (flag == 1){
			int a,b;
			long long c;
			scanf ("%d%d%lld",&a,&b,&c);
			int lca = getlca(a,b);
			make(a,lca,c);
			make(b,lca,c);
			printf("%lld\n",c);
		}
		else {
			int a;
			long long b;
			scanf ("%d%lld",&a,&b);
			if (dep[U[a]] < dep[V[a]])
				swap(U[a],V[a]);
			cost[U[a]] = b;
			if (b == 1)
				fa[U[a]] = fa[V[a]];
		}
	}
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
    int a=0,fh=1LL;char c=getchar();
    while(c>57LL or c<48LL){if(c=='-')fh=-1LL;c=getchar();}
    while(47LL<c and c<58LL){
        a=a*10LL+c-48LL;
        c=getchar();
    }
    return a*fh;
}
#define MN 200005
int n,q,fa[19][MN],v[MN],F[MN],dep[MN];
struct data{
    int u,v,c;
}w[MN];
vector<int>edge[MN],cost[MN];
int Find(int a){
    if(F[a]==a)return a;
    return F[a]=Find(F[a]);
}
void dfs(int x){
    for(int i=0;i<edge[x].size();++i)
        if(fa[0][x]!=edge[x][i]){
            dep[edge[x][i]]=dep[x]+1;
            fa[0][edge[x][i]]=x;
            if(cost[x][i]==1) F[edge[x][i]]=Find(x);
            v[edge[x][i]]=cost[x][i];
            dfs(edge[x][i]);
        }
}
int LCA(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    for(int i=17;i>=0;--i)
        if(dep[fa[i][x]]>=dep[y])x=fa[i][x];
    if(x==y)return x;
    for(int i=17;i>=0;--i)
        if(fa[i][x]!=fa[i][y]) x=fa[i][x],y=fa[i][y];
    return fa[0][x];
}
signed main(){
    n=read();q=read();
    int a,b,c;
    for(int i=1;i<n;++i){
        a=read();b=read();c=read();
        w[i].u=a;w[i].v=b;w[i].c=c;
        edge[a].push_back(b);
        edge[b].push_back(a);
        cost[a].push_back(c);
        cost[b].push_back(c);
    }
    for(int i=1;i<=n;++i)F[i]=i;
    dep[1]=1;
    v[1]=1;
    dfs(1);
    for(int i=1;i<=17;++i)
        for(int j=1;j<=n;++j)
            fa[i][j]=fa[i-1][fa[i-1][j]];
    int op;
    for(int i=1;i<=q;++i){
        op=read();a=read();b=read();
        if(op==1){
            c=read();
            int lca=LCA(a,b);
            int x=a,y=b;
            while(dep[x]>dep[lca]&&c){
                if(v[x])c/=v[x];
                x=Find(fa[0][x]);
            }
            while(dep[y]>dep[lca]&&c){
                if(v[y])c/=v[y];
                y=Find(fa[0][y]);
            }
            printf("%lld\n",c);
        }
        else{
            int x;
            if(fa[0][w[a].u]==w[a].v)x=w[a].u;
                else x=w[a].v;
            v[x]=b;
            if(v[x]==1LL) F[x]=Find(fa[0][x]);
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define ll long long
#define N 500010

using namespace std;

ll fa[N];

ll f[N][20];

ll n,m;

ll x1,x2,x3,x4,x5;

ll sd[N],rb[N];

ll from[N];
ll ver[N],head[N],nex[N],e[N],nu;

inline ll read(){
	ll x=0,y=1;char c=getchar();
	for(;c<'0' || c>'9';c=getchar()) if(c=='-') y=0;
	for(;c>='0' && c<='9';c=getchar()) x=(x<<1)+(x<<3)+c-48;
	if(y) return x;
	return -x;
}

void add(ll x,ll y,ll z){
	from[++nu]=x,ver[nu]=y,e[nu]=z,nex[nu]=head[x],head[x]=nu;
}

ll Getf(ll x,ll y){
	if(sd[x]<sd[y]) {ll t=x;x=y;y=t;}

	if(sd[x]!=sd[y])
	for(int i=16;i>=0;i--)
		if(sd[f[x][i]]>=sd[y])	x=f[x][i];
	if(x==y) return y;

	for(int i=16;i>=0;i--)
		if(f[x][i]!=f[y][i])
		x=f[x][i],y=f[y][i];
	return f[y][0];
}

inline ll getf(ll x){
	return (x==fa[x]?x:fa[x]=getf(fa[x]));
}

void dfs(ll x,ll fx){
	f[x][0]=fx;
	sd[x]=sd[fx]+1;
	for(int j=1;j<=16;j++)
		f[x][j]=f[f[x][j-1]][j-1];
	for(int j=head[x];j;j=nex[j])
	{
		int y=ver[j];
		if(y==fx) continue;
		rb[y]=j;
		if(e[j]==1)	fa[y]=fa[getf(x)];
		dfs(y,x);
	}
	return;
}

inline void Work(ll x,ll y,ll &z){
	for(ll w=f[x][0];x!=1;x=w,w=f[x][0])
	{
		if(getf(x)!=x) x=fa[x],w=f[x][0];
		if(sd[y]>sd[w]) return;
		if(x!=1)
		z/=e[rb[x]];
		if(z==0) return;
	}
}

int main(){
	//freopen("walk.in","r",stdin);
	//freopen("walk.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n-1;i++)
	{
		x1=read(),x2=read(),x3=read();
		add(x1,x2,x3);
		add(x2,x1,x3);
	}
	for(int i=1;i<=n;i++)
	fa[i]=i;
	dfs(1,1);
	/*for(int i=1;i<=n;i++)
	{
		printf("%lld %d\n",fa[i],i);
	}*/
	for(int i=1;i<=m;i++)
	{
		x1=read();
		if(x1==1)
		{
			x2=read(),x3=read(),x4=read();
			x5=Getf(x2,x3);
			if(x2!=x5)
			Work(x2,x5,x4);
			if(x4!=0)
			if(x3!=x5)
			Work(x3,x5,x4);
			printf("%lld\n",x4);
		}
		if(x1==2)
		{
			x2=read(),x3=read();
			e[x2*2]=x3;
			e[x2*2-1]=x3;
			if(x3==1)
			{
				if(f[ver[x2*2-1]][0]==from[x2*2-1])
				{	fa[getf(ver[x2*2-1])]=fa[getf(from[x2*2-1])];continue; }
				fa[getf(from[x2*2-1])]=fa[getf(ver[x2*2-1])];
			}
		}
	}
	/*for(int i=1;i<=n;i++)
	{
		printf("%lld %d\n",fa[i],i);
	}*/
	return 0;
}


#include<bits/stdc++.h>
#define E 20009
#define ls (k<<1)
#define rs (k<<1|1)
#define mid ((l+r)>>1)
#define int unsigned long long
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-48,c=getchar();
	return x*f;
}
int head[E],nex[E],to[E],w[E],cnt,n,m;
inline void add(int u,int v,int cost){
	nex[++cnt]=head[u];
	head[u]=cnt;to[cnt]=v;
	w[cnt]=cost;
}
int dep[E],fa[E],siz[E],son[E];
void dfs1(int u,int depth){
	dep[u]=depth;siz[u]=1;
	for(int i=head[u];i;i=nex[i])
		if(!dep[to[i]]){
			fa[to[i]]=u;
			dfs1(to[i],depth+1);
			siz[u]+=siz[to[i]];
			if(siz[to[i]]>siz[son[u]])
				son[u]=to[i];
		}
}
int tid[E],dfn[E],top[E],val[E],num;
void dfs2(int u,int t){
	dfn[u]=++num;top[u]=t;
	if(!son[u]) return;
	dfs2(son[u],t);
	for(int i=head[u];i;i=nex[i]){
		if(!dfn[to[i]])
			dfs2(to[i],to[i]);
		tid[i]=dfn[to[i]];
		val[dfn[to[i]]]=w[i];
	}
}
int mul[E<<1];
void build(int k,int l,int r){
	mul[k]=1;
	if(l==r){
		mul[k]=val[l];
		return;
	}
	build(ls,l,mid);
	build(rs,mid+1,r);
	if(mul[ls]) mul[k]*=mul[ls];
	if(mul[rs]) mul[k]*=mul[rs];
}
void change(int k,int l,int r,int x,int v){
	if(l==r){mul[k]=v;return;}
	if(x<=mid) change(ls,l,mid,x,v);
	else change(rs,mid+1,r,x,v);
	mul[k]=mul[ls]*mul[rs];
}
int query(int k,int l,int r,int ll,int rr){
	if(ll<=l && r<=rr) return mul[k];
	int ret=1;
	if(ll<=mid) ret*=query(ls,l,mid,ll,rr);
	if(rr>mid) ret*=query(rs,mid+1,r,ll,rr);
	return ret;
}
int query_(int u,int v,int ret){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		ret=ret/query(1,1,n,dfn[top[u]],dfn[u]);
		if(ret==0) return ret;
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
	ret=ret/query(1,1,n,dfn[v]+1,dfn[u]);
	return ret;
}
signed main(){
//	freopen("walk.in","r",stdin);
//	freopen("walk.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read(),cost=read();
		add(u,v,cost);
	}
	dfs1(1,1);dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt=read();
		if(opt==1){
			int x=read(),y=read(),v=read();
			printf("%lld\n",query_(x,y,v));
		}else{
			int p=read(),c=read();
			change(1,1,n,tid[p],c);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define E 300009
#define ls (k<<1)
#define rs (k<<1|1)
#define mid ((l+r)>>1)
#define int unsigned long long
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-48,c=getchar();
	return x*f;
}
int head[E],nex[E],to[E],w[E],cnt,n,m;
inline void add(int u,int v,int cost){
	nex[++cnt]=head[u];
	head[u]=cnt;to[cnt]=v;
	w[cnt]=cost;
}
int dep[E],fa[E],siz[E],son[E];
void dfs1(int u,int depth){
	dep[u]=depth;siz[u]=1;
	for(int i=head[u];i;i=nex[i])
		if(!dep[to[i]]){
			fa[to[i]]=u;
			dfs1(to[i],depth+1);
			siz[u]+=siz[to[i]];
			if(siz[to[i]]>siz[son[u]])
				son[u]=to[i];
		}
}
int tid[E],dfn[E],top[E],val[E],num;
void dfs2(int u,int t){
	dfn[u]=++num;top[u]=t;
	if(!son[u]) return;
	dfs2(son[u],t);
	for(int i=head[u];i;i=nex[i]){
		if(!dfn[to[i]])
			dfs2(to[i],to[i]);
		tid[i]=dfn[to[i]];
		val[dfn[to[i]]]=w[i];
	}
}
int mul[E<<1];
void build(int k,int l,int r){
	mul[k]=1;
	if(l==r){
		mul[k]=val[l];
		return;
	}
	build(ls,l,mid);
	build(rs,mid+1,r);
	if(mul[ls]) mul[k]*=mul[ls];
	if(mul[rs]) mul[k]*=mul[rs];
}
void change(int k,int l,int r,int x,int v){
	if(l==r){mul[k]=v;return;}
	if(x<=mid) change(ls,l,mid,x,v);
	else change(rs,mid+1,r,x,v);
	mul[k]=mul[ls]*mul[rs];
}
int query(int k,int l,int r,int ll,int rr){
	if(ll<=l && r<=rr) return mul[k];
	int ret=1;
	if(ll<=mid) ret*=query(ls,l,mid,ll,rr);
	if(rr>mid) ret*=query(rs,mid+1,r,ll,rr);
	return ret;
}
int query_(int u,int v,int ret){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		ret=ret/query(1,1,n,dfn[top[u]],dfn[u]);
		if(ret==0) return ret;
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
	ret=ret/query(1,1,n,dfn[v]+1,dfn[u]);
	return ret;
}
signed main(){
//	freopen("walk.in","r",stdin);
//	freopen("walk.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read(),cost=read();
		add(u,v,cost);
	}
	dfs1(1,1);dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt=read();
		if(opt==1){
			int x=read(),y=read(),v=read();
			printf("%lld\n",query_(x,y,v));
		}else{
			int p=read(),c=read();
			change(1,1,n,tid[p],c);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,m,cnt=0;int head[N],fa[N],dep[N],f[N][26],val[N];

struct node{
	int to,from,nxt;long long w=0;
}e[N<<1];

void add(int u,int v,long long w){
	e[++cnt].nxt=head[u];e[cnt].from=u;e[cnt].to=v;e[cnt].w=w;head[u]=cnt;
}

int find(int x){
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

void sea(int u,int fath){
	f[u][0]=fath;dep[u]=dep[fath]+1;
	for(int i=1;i<=17;i++) f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to,dis=e[i].w;
		if(v!=fath){
			if(dis==1) fa[v]=find(u);
			val[v]=dis;
			sea(v,u);
		}
	}
}

int lca(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	for(int i=17;i>=0;i--) if(dep[f[u][i]]>=dep[v]) u=f[u][i];
	if(u==v) return u;
	for(int i=17;i>=0;i--){
		if(f[u][i]!=f[v][i]){
			u=f[u][i];v=f[v][i];
		}
	}
	return f[u][0];
}

signed main()
{
	cin>>n>>m;int u,v,opt,x,y;long long w,z;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<n;i++){
		scanf("%d %d %lld",&u,&v,&w);
		add(u,v,w);add(v,u,w);
	}
	sea(1,0);
	for(int i=1;i<=m;i++){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d %d %lld",&x,&y,&z);
			int anc=lca(x,y),a=x,b=y;
			while(dep[a]>dep[anc]&&z){

				if(val[a]) z=z/val[a];
				a=find(f[a][0]);
			}
			while(dep[b]>dep[anc]&&z){
				if(val[b]) z=z/val[b];
				b=find(f[b][0]);
			}
			printf("%lld\n",z);
		}
		else{
			scanf("%d %lld",&x,&z);int tmp;
			int u=e[x<<1].from,v=e[x<<1].to;
			if(f[u][0]==v) tmp=u;
			else tmp=v;
			val[tmp]=z;
			if(val[tmp]==1) fa[tmp]=find(f[tmp][0]);
		}
	}
	return 0;
}


#define FASTER
#ifdef FASTER
#pragma GCC diagnostic error "-std=c++11"
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#endif

#include <bits/stdc++.h>

#define ll long long
#define N 500010

using namespace std;

ll fa[N];

ll f[N][20];

ll n,m;

ll x1,x2,x3,x4,x5;

ll sd[N],rb[N];

ll from[N];
ll ver[N],head[N],nex[N],e[N],nu;

inline ll read(){
	ll x=0,y=1;char c=getchar();
	for(;c<'0' || c>'9';c=getchar()) if(c=='-') y=0;
	for(;c>='0' && c<='9';c=getchar()) x=(x<<1)+(x<<3)+c-48;
	if(y) return x;
	return -x;
}

void add(ll x,ll y,ll z){
	from[++nu]=x,ver[nu]=y,e[nu]=z,nex[nu]=head[x],head[x]=nu;
}

ll Getf(ll x,ll y){
	if(sd[x]<sd[y]) {ll t=x;x=y;y=t;}

	if(sd[x]!=sd[y])
	for(int i=17;i>=0;i--)
	{
		if(sd[f[x][i]]>sd[y])	x=f[x][i];
		if(sd[f[x][i]]==sd[y]) {x=f[x][i];break;}
	}
	if(x==y) return y;

	for(int i=17;i>=0;i--)
		if(f[x][i]!=f[y][i])
		x=f[x][i],y=f[y][i];
	return f[y][0];
}

void dfs(ll x,ll fx){
	f[x][0]=fx;
	sd[x]=sd[fx]+1;
	for(int j=1;j<=17;j++)
		f[x][j]=f[f[x][j-1]][j-1];
	for(int j=head[x];j;j=nex[j])
	{
		int y=ver[j];
		if(y==fx) continue;
		rb[y]=j;
		if(e[j]==1)	fa[y]=fa[x];
		dfs(y,x);
	}
	return;
}

void Work(ll x,ll y,ll &z){
	for(ll w=f[x][0];x!=1;x=w,w=f[x][0])
	{
		if(fa[x]!=x) x=fa[x],w=f[x][0];
		if(sd[y]>sd[w]) return;
		if(x!=1)
		z/=e[rb[x]];
		if(z==0) return;
	}
}

int main(){
	//freopen("walk.in","r",stdin);
	//freopen("walk.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n-1;i++)
	{
		x1=read(),x2=read(),x3=read();
		add(x1,x2,x3);
		add(x2,x1,x3);
	}
	for(int i=1;i<=n;i++)
	fa[i]=i;
	dfs(1,1);
	for(int i=1;i<=m;i++)
	{
		x1=read();
		if(x1==1)
		{
			x2=read(),x3=read(),x4=read();
			x5=Getf(x2,x3);
			Work(x2,x5,x4);
			if(x4!=0)
			Work(x3,x5,x4);
			printf("%lld\n",x4);
		}
		if(x1==2)
		{
			x2=read(),x3=read();
			e[x2*2]=x3;
			e[x2*2-1]=x3;
			if(x3==1)
			{
				if(f[ver[x2*2-1]][0]==from[x2*2-1])
				{	fa[ver[x2*2-1]]=fa[from[x2*2-1]];continue; }
				fa[from[x2*2-1]]=fa[ver[x2*2-1]];
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define MAXN 400005
//typedef long long LL;
typedef unsigned long long LL;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
int n,m,head[MAXN],tot,dep[MAXN];
int U[MAXN],V[MAXN],father[MAXN];
int dfn[MAXN],ltp[MAXN],pre[MAXN];
int wson[MAXN],siz[MAXN],cnt;
LL seg[MAXN<<2],val[MAXN];
struct edge{int to,nxt;LL paid;}e[MAXN<<1];
void addEdge(int u,int v,LL w){e[++tot]=(edge){v,head[u],w};head[u]=tot;}
void dfs1(int u){
	siz[u]=1;wson[u]=ltp[u]=0;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;if(v==father[u])continue;
		dep[v]=dep[u]+1;father[v]=u;val[v]=e[i].paid;
		dfs1(v);siz[u]+=siz[v];
		if(siz[wson[u]]<siz[v])wson[u]=v;
	}
}
void dfs2(int u,int tp){
	dfn[u]=++cnt;pre[cnt]=u;ltp[u]=tp;
	if(wson[u])dfs2(wson[u],tp);
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==father[u]||v==wson[u])
			continue;
		dfs2(v,v);
	}
}
void build(int rt,int l,int r){
	if(l==r)return (void)(seg[rt]=val[pre[l]]);
	int mid=l+r>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	if(1e19/seg[rt<<1]<seg[rt<<1|1])seg[rt]=1e19+1;
	else seg[rt]=seg[rt<<1]*seg[rt<<1|1];
}
void modify(int rt,int l,int r,int ai,LL aw){
	if(l==r)return (void)(seg[rt]=aw);int mid=l+r>>1;
	if(ai<=mid)modify(rt<<1,l,mid,ai,aw);
	else modify(rt<<1|1,mid+1,r,ai,aw);
	if(1e19/seg[rt<<1]<seg[rt<<1|1])seg[rt]=1e19+1;
	else seg[rt]=seg[rt<<1]*seg[rt<<1|1];
}
LL query(int rt,int l,int r,int al,int ar){
	if(l>r||al>r||ar<l)return 1;
	if(al<=l&&r<=ar)return seg[rt];
	int mid=l+r>>1;LL res=1;
	if(al<=mid){
		LL tmp=query(rt<<1,l,mid,al,ar);
		if(1e19/res<tmp)res=1e19+1;else res*=tmp;
	}
	if(mid<ar){
		LL tmp=query(rt<<1|1,mid+1,r,al,ar);
		if(1e19/res<tmp)res=1e19+1;else res*=tmp;
	}
	return res;
}
LL Chain_Query(int u,int v){
	if(u==v)return 1;LL res=1;
	for(int fu=ltp[u],fv=ltp[v];fu^fv;u=father[fu],fu=ltp[u]){
		if(dep[fu]<dep[fv])swap(u,v),swap(fu,fv);
		LL tmp=query(1,1,n,dfn[fu],dfn[u]);
		if(1e19/res<tmp)res=1e19+1;else res*=tmp;
	}
	if(dep[u]>dep[v])swap(u,v);
	LL tmp=query(1,1,n,dfn[u]+1,dfn[v]);
	if(1e19/res<tmp)res=1e19+1;else res*=tmp;
	return res;
}
signed main(){
	read(n);read(m);
	for(int i=1;i<n;i++){
		int u,v;LL w;read(u);read(v);read(w);
		addEdge(u,v,w);addEdge(v,u,w);
		U[i]=u;V[i]=v;
	}
	dfs1(1);dfs2(1,1);build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt;read(opt);
		if(opt==1){
			int a,b;LL c;read(a);read(b);read(c);
			printf("%llu\n",c/Chain_Query(a,b));
		}
		else{
			int p;LL c;read(p);read(c);
			modify(1,1,n,max(dfn[U[p]],dfn[V[p]]),c);
		}
	}
	return 0;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
const int maxn = 1000010, inf = 1e18, N = 5e5 + 7;
int ch[maxn][2], par[maxn], rev[maxn], sta[maxn], val[maxn], mul[maxn], n, q;
const int SZ=1<<19;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int in()
{
    G;while(*ip<'-')G;
    register int x=*ip&15;G;
    while(*ip>'-'){x*=10;x+=*ip&15;G;}
    return x;
}
bool chk(int x)
{
    return ch[par[x]][0] == x || ch[par[x]][1] == x;
}
bool safe(int x, int y)
{
    return inf / x >= y;
}
void update(int x)
{
	mul[x] = -1;
    if (safe(mul[ch[x][0]], mul[ch[x][1]]) && safe(mul[ch[x][0]] * mul[ch[x][1]], val[x])) mul[x] = mul[ch[x][0]] * mul[ch[x][1]] * val[x];
}
void reverse(int x)
{
    swap(ch[x][0], ch[x][1]);
    rev[x] ^= 1;
}
void pushdown(int x)
{
    if (rev[x])
    {
        reverse(ch[x][0]), reverse(ch[x][1]);
        rev[x] = 0;
    }
}
void rotate(int x)
{
	int y = par[x], z = par[y], k = (ch[y][1] == x), w = ch[x][k^1];
	if (chk(y)) ch[z][ch[z][1] == y] = x;
	ch[x][k ^ 1] = y,ch[y][k] = w;
	if (w) par[w] = y;
	par[y] = x,par[x] = z;
	update(x), update(y);
}
void pushall(int x)
{
	if (chk(x)) pushall(par[x]);
	pushdown(x);
}
void splay(int x)
{
	int y = x, z = 0;
	sta[++z] = y;
	while (chk(y)) sta[++z] = y = par[y];
	while (z) pushdown(sta[z--]);
	while (chk(x))
	{
		y = par[x], z = par[y];
		if (chk(y)) rotate((ch[y][0] == x) || (ch[z][0] == y) ? x : y);
		rotate(x);
	}
	update(x);
}
void access(int x)
{
	for (int y = 0; x; x = par[y = x])
		splay(x), ch[x][1] = y, update(x);
}
void makeroot(int x)
{
	access(x), splay(x), reverse(x);
}
void split(int x, int y)
{
	makeroot(x), access(y), splay(y);
}
void link(int x, int y)
{
	makeroot(x);
	par[x] = y;
}
void update_val(int x, int y)
{
    makeroot(x), val[x] = y, update(x);
}
int query(int x, int y)
{
    split(x, y);
    return mul[y];
}
signed main()
{
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
    n = in(), q = in();
    for (int i = 0; i <= n << 1; i++) val[i] = mul[i] = 1;
    for(int i=1;i<n;++i)
    {
        int u = in(), v = in();
        val[i + N] = in();
        link(u,i+N),link(i+N,v);
    }
    for (int i = 1; i <= q; i++)
    {
        int type = in();
        if(type==1)
        {
            int u = in(), v = in(), P = in();
            int V=query(u,v);
            if(~V) printf("%lld\n", P / V);
            else printf("0\n");
        }
        else
        {
            int u = in(), v = in();
            update_val(u+N,v);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define ull unsigned long long
#define PI acos(-1)
#define pb(x)   push_back(x)
#define il inline
#define re register
#define IO; ios::sync_with_stdio(0);cin.tie(0);
//#define ls (o<<1)
//#define rs (o<<1|1)
#define pii pair<int,int>
using namespace std;
//const double eps = 1e-10;
const int maxn = 2e5 + 10;
const int maxm = 4e5*26+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 3e17+1;
const int mod = 1e9+7;
const int MOD = 1e6+7;
inline ll read(){
    register ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return (f==1)?x:-x;
}
int n, m;
ll w;
struct edge
{
	int u,v,nxt;ll w;
}E[maxn<<1];
int head[maxn], eid, fa[maxn], f[maxn][21], dep[maxn];
ll val[maxn];
int find(int x)
{
	return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void add(int u, int v, ll w)
{
	E[++eid] = {u,v,head[u],w};
	head[u] = eid;
}
void dfs(int u, int ff)
{
	f[u][0] = ff;
	dep[u] = dep[ff] + 1;
	for (int i = 1; i <= 17; i++)
		f[u][i] = f[f[u][i-1]][i-1];
	for (int i = head[u]; i != -1; i = E[i].nxt)
	{
		int v = E[i].v;
		if (v == ff)	continue ;
		if (E[i].w == 1)
			fa[v] = find(u);
		val[v] = E[i].w;
		dfs(v,u);
	}
}
int LCA(int x, int y)
{
	if (dep[x] < dep[y])	swap(x,y);
	for (int i = 17; i >= 0; i--)
	{
		if (dep[f[x][i]] >= dep[y])
			x = f[x][i];
		if (x == y)	return x;
	}
	for (int i = 17; i >= 0; i--)
		if (f[x][i] != f[y][i])
			x = f[x][i], y = f[y][i];
	return f[x][0];
}
int main()
{
	n = read(), m = read();
	int u, v;
	for (int i = 1; i <= n; i++)
	{
		head[i] = -1;
		fa[i] = i;
	}
	for (int i = 1; i < n; i++)
	{
		u = read(), v = read(), w = read();
		add(u,v,w);add(v,u,w);
	}
	dfs(1,0);
	ll opt, x, y, z;
	while (m--)
	{
		opt = read();
		if (opt == 1)
		{
			x = read(), y = read(), z = read();
			int lca = LCA(x,y);
			while (dep[x] > dep[lca] && z)
			{
				z /= val[x];
				x = find(f[x][0]);
			}
			while (dep[y] > dep[lca] && z)
			{
				z /= val[y];
				y = find(f[y][0]);
			}
			printf("%lld\n", z);
		}
		else
		{
			x = read(), y = read();
			int u = E[x<<1].u, v = E[x<<1].v;
			z = f[u][0] == v ? u : v;
			val[z] = y;
			if (val[z] == 1)
				fa[z] = find(f[z][0]);
		}
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#define N 200005
using namespace std;
struct node{
	int v;
	long long w;
	node(){};
	node(int V,long long W){
		v = V,w = W;
	}
};
int n,m,fa[N],dep[N],dp[N][21],U[N],V[N];
long long cost[N];
vector<node>G[N];
void dfs(int u,int fa0){
	for (int i = 0;i < G[u].size();i ++){
		int v = G[u][i].v;
		if (v == fa0)
			continue;
		dep[v] = dep[u] + 1;
		dp[v][0] = u;
		dfs(v,u);
		fa[v] = v;
		cost[v] = G[u][i].w;//
		if (fa0 != 0 && G[u][i].w == 1)
			fa[v] = u;
	}
}
void build(int root){
	dfs(root,0);
	for (int j = 1;j <= 20;j ++)
		for (int i = 1;i <= n;i ++)
			dp[i][j] = dp[dp[i][j - 1]][j - 1];
}
void mov(int &u,int v){
	for (int i = 20;i >= 0;i --)
		if (dep[dp[u][i]] >= dep[v])
			u = dp[u][i];
}
int get_lca(int u,int v){
	if (dep[u] > dep[v])
		mov(u,v);
	if (dep[u] < dep[v])
		mov(v,u);
	if (u == v)
		return u;
	for (int i = 20;i >= 0;i --){
		if (dp[u][i] != dp[v][i]){
			u = dp[u][i];
			v = dp[v][i];
		}
	}
	return dp[u][0];
}
int findset(int x){
	if (fa[x] != x)
		fa[x] = findset(fa[x]);
	return fa[x];
}
void make(int u,int fuck,long long &x){
	while (x && dep[u] > dep[fuck]){
		x = x / cost[u];
		u = dp[u][0];
		u = findset(u);
	}
}
int main(){
	scanf ("%d%d",&n,&m);
	for (int i = 1;i < n;i ++){
		long long w;
		scanf ("%d%d",&U[i],&V[i]);
		scanf ("%lld",&w);
		G[U[i]].push_back(node(V[i],w));
		G[V[i]].push_back(node(U[i],w));
	}
	build(1);
	while (m --){
		int flag;
		scanf ("%d",&flag);
		if (flag == 1){
			int a,b;
			long long c;
			scanf ("%d%d%lld",&a,&b,&c);
			int lca = get_lca(a,b);
			make(a,lca,c);
			make(b,lca,c);
			printf("%lld\n",c);
		}
		else {
			int a;
			long long b;
			scanf ("%d%lld",&a,&b);
			if (dep[U[a]] < dep[V[a]])
				swap(U[a],V[a]);
			cost[U[a]] = b;
			if (b == 1)
				fa[U[a]] = fa[V[a]];
		}
	}
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define int long long
using namespace std;
const int MAXN=200000+5;
int n,q,tot,cnt;
int val[MAXN],id[MAXN],head[MAXN],fa[MAXN],dep[MAXN],son[MAXN],top[MAXN],siz[MAXN],num[MAXN],cx[MAXN];
struct Tree{
	int l,r;
	long double v;
}t[MAXN*4];
struct Edge{
	int next,to,dis;
}e[MAXN*2];
inline void add_edge(int from,int to,int dis){
	e[++tot].next=head[from];
	e[tot].to=to;
	e[tot].dis=dis;
	head[from]=tot;
}
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
void build(int x,int l,int r){
	t[x].l=l;t[x].r=r;
	if(l==r){
		t[x].v=num[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(ls(x),l,mid);
	build(rs(x),mid+1,r);
	t[x].v=t[ls(x)].v*t[rs(x)].v;
}
void hack(int x,int p,int num){
	if(t[x].l==p && t[x].r==p){
		t[x].v=num;
		return ;
	}
	int mid=(t[x].l+t[x].r)>>1;
	if(p<=mid) hack(ls(x),p,num);
	else hack(rs(x),p,num);
	t[x].v=t[ls(x)].v*t[rs(x)].v;
}
long double ask(int x,int l,int r){
	if(l<=t[x].l && r>=t[x].r) return t[x].v;
	int mid=(t[x].l+t[x].r)>>1;
	long double ans=1;
	if(l<=mid) ans*=ask(ls(x),l,r);
	if(r>mid) ans*=ask(rs(x),l,r);
	return ans;
}
void dfs1(int now,int faa){
	dep[now]=dep[faa]+1;
	fa[now]=faa;siz[now]=1;
	for(int i=head[now];i;i=e[i].next){
		int v=e[i].to;
		if(v==faa) continue;
		val[v]=e[i].dis;
		cx[(i+1)/2]=v;
		dfs1(v,now);
		siz[now]+=siz[v];
		if(siz[v]>siz[son[now]]) son[now]=v;
	}
}
void dfs2(int now,int tp){
	top[now]=tp;id[now]=++cnt;num[cnt]=val[now];
	if(!son[now]) return ;
	dfs2(son[now],tp);
	for(int i=head[now];i;i=e[i].next){
		int v=e[i].to;
		if(v!=son[now] && v!=fa[now]) dfs2(v,v);
	}
}
int work(int x,int y,int v){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
		v=(int)(floor((long double)v/ask(1,id[top[x]],id[x])));
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) std::swap(x,y);
	v=(int)(floor((long double)v/ask(1,id[x]+1,id[y])));
	return v;
}
signed main(){
	scanf("%lld%lld",&n,&q);
	int u,v,c;
	for(int i=1;i<n;i++){
		scanf("%lld%lld%lld",&u,&v,&c);
		add_edge(u,v,c);
		add_edge(v,u,c);
	}
	dfs1(1,0);
	val[1]=1;
	dfs2(1,1);
	build(1,1,n);
	int type,x,y,p;
	for(int i=1;i<=q;i++){
		scanf("%lld",&type);
		if(type==1){
			scanf("%lld%lld%lld",&x,&y,&c);
			printf("%lld\n",work(x,y,c));
		}
		else {
			scanf("%lld%lld",&p,&c);
			hack(1,id[cx[p]],c);
		}
	}
	return 0;
}


#define  REP(i, s, e) for (int i = s; i <= e; i++)
#define DREP(i, s, e) for (int i = s; i >= e; i--)
#define DEBUG fprintf(stderr, "Passing [%s] in Line %d\n", __FUNCTION__, __LINE__)

#define chkmax(a, b) a = max(a, (b))
#define chkmin(a, b) a = min(a, (b))

#include <iostream>
#include <cstdio>
#include <cmath>
#define int long long

using namespace std;
const int maxn = 100000 + 10, maxm = maxn + 10, maxnode = 1700000;
const double inf = 2e18, eps = 1e-8;
int bg[maxn], ne[maxm << 1], to[maxm << 1], w[maxm << 1], e;
void add(int x, int y, int z)
{
	e++;
	to[e] = y;
	ne[e] = bg[x];
	bg[x] = e;
	w[e] = z;
}

template <typename T> T read()
{
	T ans(0), flag(1);
	char c(getchar());
	while (!isdigit(c))
	{
		if (c == '-') flag = -1;
		c = getchar();
	}
	while (isdigit(c))
	{
		ans = ans * 10 + c - 48;
		c = getchar();
	}
	return ans * flag;
}

void file(string s)
{
	freopen((s + ".in").c_str(), "r", stdin);
	freopen((s + ".out").c_str(), "w", stdout);
#ifdef CraZYali
	freopen((s + ".err").c_str(), "w", stderr);
#endif
}

int n, q;

int depth[maxn], siz[maxn], hvy[maxn], fa[maxn];
long double W[maxn];

void dfs1(int x)
{
	siz[x] = 1;
	for (int i = bg[x]; i ; i = ne[i])
		if (to[i] ^ fa[x])
		{
			W[to[i]] = w[i];
			fa[to[i]] = x;
			depth[to[i]] = depth[x] + 1;
			dfs1(to[i]);
			siz[x] += siz[to[i]];
			if (siz[to[i]] > hvy[x]) hvy[x] = to[i];
		}
}
int top[maxn], dfn[maxn], dfs_clock, ww[maxn];
void dfs2(int x, int y)
{
	top[x] = y;
	ww[dfn[x] = ++dfs_clock] = W[x];
	if (hvy[x]) dfs2(hvy[x], y);
	for (int i = bg[x]; i ; i = ne[i])
		if (to[i] ^ fa[x] && to[i] ^ hvy[x]) dfs2(to[i], to[i]);
}

#define mid (l + r >> 1)
#define lson ls[p], l, mid
#define rson rs[p], mid + 1, r

int root, ls[maxnode], rs[maxnode], cur;
long double mul[maxnode];

void build(int &p, int l, int r)
{
	if (!p) p = ++cur;
	if (l == r) mul[p] = ww[l];
	else
	{
		build(lson);
		build(rson);
		mul[p] = mul[ls[p]] * mul[rs[p]];
	}
}
void pushup(int p, int l, int r)
{
	mul[p] = mul[ls[p]] * mul[rs[p]];
	if (mul[p] > inf) mul[p] = 0;
}
void update(int p, int l, int r, int pos, long double val)
{
	if (l == r) mul[p] = val;
	else
	{
		if (pos <= mid) update(lson, pos, val);
		else update(rson, pos, val);
		pushup(p, l, r);
	}
}
long double query(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R) return mul[p];
	else
	{
		long double res(1);
		if (L <= mid) res *= query(lson, L, R);
		if (R >  mid) res *= query(rson, L, R);
		return res > inf ? 0 : res;
	}
}
int query(int x, int y, long double v)
{
	long double res = 1;
	while (top[x] ^ top[y])
	{
		if (depth[top[x]] < depth[top[y]]) swap(x, y);
		res *= query(1, 1, n, dfn[top[x]], dfn[x]) ;
		if (res > v) return 0;
		x = fa[top[x]];
	}
	if (depth[x] > depth[y]) swap(x, y);
	res *= query(1, 1, n, dfn[x], dfn[y]) / W[x];
//	return res;
	return abs(res) < eps ? 0 : floor(v / res);
}
long double query(int x, int y)
{
	long double res = 1;
	while (top[x] ^ top[y])
	{
		if (depth[top[x]] < depth[top[y]]) swap(x, y);
		res *= query(1, 1, n, dfn[top[x]], dfn[x]);
		x = fa[top[x]];
	}
	if (depth[x] > depth[y]) swap(x, y);
	res *= query(1, 1, n, dfn[x], dfn[y]) / W[x];
	return res;
//	return abs(res) < eps ? 0 : floor(v / res);
}

int X[maxn], Y[maxn], Z[maxn];

signed main()
{
	file("walk");
	cin >> n >> q;
	REP(i, 1, n-1)
	{
		X[i] = read<int>();Y[i] = read<int>();Z[i] = read<int>();
		add(X[i], Y[i], Z[i]);add(Y[i], X[i], Z[i]);
	}
	mul[0] = 1;
	depth[1] = 1;
	dfs1(1);
	W[1] = 1;
	dfs2(1, 1);
	build(root, 1, n);
	while (q--)
	{
		int type(read<int>());
		int x, y;long double v;
		if (type == 1)
		{
			scanf("%lld%lld%LF", &x, &y, &v);
			printf("%lld\n", query(x, y, v));
		}
		else
		{
			scanf("%lld%LF", &x, &v);
			if (fa[X[x]] != Y[x]) swap(X[x], Y[x]);
			W[X[x]] = v;
			update(1, 1, n, dfn[X[x]], v);
		}
		/*
		fputs("--------\n", stderr);
		REP(i, 1, n)
			REP(j, i, n)
			fprintf(stderr, "%lld %lld %.2LF\n", i, j, query(i, j));
			*/
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lc x<<1
#define rc x<<1|1
const int N=2e5+6;
const ll maxx=1e18;
int n,m,opt,t1,t2,cnt=0,dfn=0,d[N],f[N],id[N],son[N],siz[N],num[N],top[N],head[N];
ll t3,v[N],o[N];
double w[N<<2],lazy[N<<2];
struct edge{int nxt,to,p; ll w;}e[N<<1];
inline void add(int u,int v,int p,ll w){e[++cnt].nxt=head[u],e[cnt].to=v,e[cnt].p=p,e[cnt].w=w,head[u]=cnt;}
inline double mul(double x,double y){return (!x||maxx/x<=y)?maxx:x*y;}
inline ll read(){
   ll T=0,F=1; char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
   while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
   return F*T;
}
void dfs(int x,int fa){
    siz[x]=1,d[x]=d[fa]+1,f[x]=fa; int maxt=0;
    for(int i=head[x];i;i=e[i].nxt)
        if(e[i].to!=fa){
           id[e[i].p]=e[i].to,dfs(e[i].to,x),siz[x]+=siz[e[i].to];
           if(siz[maxt]<siz[e[i].to]) maxt=e[i].to,o[x]=e[i].w;
        }
    son[x]=maxt;
}
void dfs2(int x,int topx,ll ww){
    num[x]=++dfn,top[x]=topx,v[dfn]=ww;
    if(son[x]) dfs2(son[x],topx,o[x]);
    for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=f[x]&&e[i].to!=son[x]) dfs2(e[i].to,e[i].to,e[i].w);
}
void build(int l,int r,int x){
    if(l==r){w[x]=v[l]; return;}
    int mid=l+r>>1;
    build(l,mid,lc),build(mid+1,r,rc);
    w[x]=mul(w[lc],w[rc]);
}
void update(int l,int r,int p,int x,ll y){
     if(l==r){w[x]=y; return;}
     int mid=l+r>>1;
     if(p<=mid) update(l,mid,p,lc,y);
     else update(mid+1,r,p,rc,y);
     w[x]=mul(w[lc],w[rc]);
}
double query(int l,int r,int p,int q,int x){
   if(p<=l&&r<=q) return w[x];
   int mid=l+r>>1; double ans=1;
   if(p<=mid) ans=query(l,mid,p,q,lc);
   if(q>mid) ans=mul(ans,query(mid+1,r,p,q,rc));
   return ans;
}
double lj_query(int x,int y){
   double ans=1;
   while(top[x]!=top[y]){
      if(d[top[x]]<d[top[y]]) swap(x,y);
      ans=mul(ans,query(1,n,num[top[x]],num[x],1));
      x=f[top[x]];
   }
   if(d[x]>d[y]) swap(x,y);
   if(x!=y) ans=mul(ans,query(1,n,num[x]+1,num[y],1));
   return ans;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<n;++i) t1=read(),t2=read(),t3=read(),add(t1,t2,i,t3),add(t2,t1,i,t3);
    dfs(1,0),dfs2(1,1,1),build(1,n,1);
    for(int i=1;i<=m;++i){
        opt=read(),t1=read();
        if(opt==1) t2=read(),t3=read(),printf("%lld\n",(ll)t3/lj_query(t1,t2));
        else t3=read(),update(1,n,num[id[t1]],1,t3);
    }
    return 0;
}


#define  REP(i, s, e) for (int i = s; i <= e; i++)
#define DREP(i, s, e) for (int i = s; i >= e; i--)
#define DEBUG fprintf(stderr, "Passing [%s] in Line %lld\n", __FUNCTION__, __LINE__)

#define chkmax(a, b) a = max(a, (b))
#define chkmin(a, b) a = min(a, (b))

#include <iostream>
#include <cstdio>
#include <cmath>
#define int long long
#define double long double

using namespace std;
const int maxn = 100000 + 10, maxm = maxn + 10, maxnode = 1700000;
const double inf = 2e18, eps = 1e-8;
int bg[maxn], ne[maxm << 1], to[maxm << 1], w[maxm << 1], e;
void add(int x, int y, int z)
{
	e++;
	to[e] = y;
	ne[e] = bg[x];
	bg[x] = e;
	w[e] = z;
}

template <typename T> T read()
{
	T ans(0), flag(1);
	char c(getchar());
	while (!isdigit(c))
	{
		if (c == '-') flag = -1;
		c = getchar();
	}
	while (isdigit(c))
	{
		ans = ans * 10 + c - 48;
		c = getchar();
	}
	return ans * flag;
}

void file(string s)
{
	freopen((s + ".in").c_str(), "r", stdin);
	freopen((s + ".out").c_str(), "w", stdout);
#ifdef CraZYali
	freopen((s + ".err").c_str(), "w", stderr);
#endif
}

int n, q;

int depth[maxn], siz[maxn], hvy[maxn], fa[maxn];
double W[maxn];

void dfs1(int x)
{
	siz[x] = 1;
	for (int i = bg[x]; i ; i = ne[i])
		if (to[i] ^ fa[x])
		{
			W[to[i]] = w[i];
			fa[to[i]] = x;
			depth[to[i]] = depth[x] + 1;
			dfs1(to[i]);
			siz[x] += siz[to[i]];
			if (siz[to[i]] > hvy[x]) hvy[x] = to[i];
		}
}
int top[maxn], dfn[maxn], dfs_clock, ww[maxn];
void dfs2(int x, int y)
{
	top[x] = y;
	ww[dfn[x] = ++dfs_clock] = W[x];
	if (hvy[x]) dfs2(hvy[x], y);
	for (int i = bg[x]; i ; i = ne[i])
		if (to[i] ^ fa[x] && to[i] ^ hvy[x]) dfs2(to[i], to[i]);
}

#define mid (l + r >> 1)
#define lson ls[p], l, mid
#define rson rs[p], mid + 1, r

int root, ls[maxnode], rs[maxnode], cur;
double mul[maxnode];

void build(int &p, int l, int r)
{
	if (!p) p = ++cur;
	if (l == r) mul[p] = ww[l];
	else
	{
		build(lson);
		build(rson);
		mul[p] = mul[ls[p]] * mul[rs[p]];
	}
}
void pushup(int p, int l, int r)
{
	mul[p] = mul[ls[p]] * mul[rs[p]];
	if (mul[p] > inf) mul[p] = 0;
}
void update(int p, int l, int r, int pos, double val)
{
	if (l == r) mul[p] = val;
	else
	{
		if (pos <= mid) update(lson, pos, val);
		else update(rson, pos, val);
		pushup(p, l, r);
	}
}
double query(int p, int l, int r, int L, int R)
{
	if (L <= l && r <= R) return mul[p];
	else
	{
		double res(1);
		if (L <= mid) res *= query(lson, L, R);
		if (R >  mid) res *= query(rson, L, R);
		return res > inf ? 0 : res;
	}
}
int query(int x, int y, double v)
{
	double res = 1;
	while (top[x] ^ top[y])
	{
		if (depth[top[x]] < depth[top[y]]) swap(x, y);
		res *= query(1, 1, n, dfn[top[x]], dfn[x]) ;
		if (res > v) return 0;
		x = fa[top[x]];
	}
	if (depth[x] > depth[y]) swap(x, y);
	res *= query(1, 1, n, dfn[x], dfn[y]) / W[x];
//	return res;
	return abs(res) < eps ? 0 : floor(v / res);
}
double query(int x, int y)
{
	double res = 1;
	while (top[x] ^ top[y])
	{
		if (depth[top[x]] < depth[top[y]]) swap(x, y);
		res *= query(1, 1, n, dfn[top[x]], dfn[x]);
		x = fa[top[x]];
	}
	if (depth[x] > depth[y]) swap(x, y);
	res *= query(1, 1, n, dfn[x], dfn[y]) / W[x];
	return res;
//	return abs(res) < eps ? 0 : floor(v / res);
}

int X[maxn], Y[maxn], Z[maxn];

signed main()
{
	cin >> n >> q;
	REP(i, 1, n-1)
	{
		X[i] = read<int>();Y[i] = read<int>();Z[i] = read<int>();
		add(X[i], Y[i], Z[i]);add(Y[i], X[i], Z[i]);
	}
	mul[0] = 1;
	depth[1] = 1;
	dfs1(1);
	W[1] = 1;
	dfs2(1, 1);
	build(root, 1, n);
	while (q--)
	{
		int type(read<int>());
		int x, y;double v;
		if (type == 1)
		{
			scanf("%lld%lld%LF", &x, &y, &v);
			//cout << query(x, y, v) << endl;
			printf("%lld\n", query(x, y, v));
		}
		else
		{
			scanf("%lld%LF", &x, &v);
			if (fa[X[x]] != Y[x]) swap(X[x], Y[x]);
			W[X[x]] = v;
			update(1, 1, n, dfn[X[x]], v);
		}
		/*
		fputs("--------\n", stderr);
		REP(i, 1, n)
			REP(j, i, n)
			fprintf(stderr, "%lld %lld %.2LF\n", i, j, query(i, j));
			*/
	}
//	while (1);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,cnt=0;int head[N],fa[N],dep[N],f[N][26],val[N];

struct node{
	int to,from,nxt;long long w=0;
}e[N<<1];

void add(int u,int v,long long w){
	e[++cnt].nxt=head[u];e[cnt].from=u;e[cnt].to=v;e[cnt].w=w;head[u]=cnt;
}

int find(int x){
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

void sea(int u,int fath){
	f[u][0]=fath;dep[u]=dep[fath]+1;
	for(int i=1;i<=17;i++) f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to,dis=e[i].w;
		if(v!=fath){
			if(dis==1) fa[v]=find(u);
			val[v]=dis;
			sea(v,u);
		}
	}
}

int lca(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	for(int i=17;i>=0;i--) if(dep[f[u][i]]>=dep[v]) u=f[u][i];
	if(u==v) return u;
	for(int i=17;i>=0;i--){
		if(f[u][i]!=f[v][i]){
			u=f[u][i];v=f[v][i];
		}
	}
	return f[u][0];
}

int main()
{
	cin>>n>>m;int u,v,opt,x,y;long long w,z;
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<n;i++){
		scanf("%d %d %lld",&u,&v,&w);
		add(u,v,w);add(v,u,w);
	}
	sea(1,0);
	for(int i=1;i<=m;i++){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d %d %lld",&x,&y,&z);
			int anc=lca(x,y),a=x,b=y;
			while(dep[a]>dep[anc]&&z){

				if(val[a]) z=z/val[a];
				a=find(f[a][0]);
			}
			while(dep[b]>dep[anc]&&z){
				if(val[b]) z=z/val[b];
				b=find(f[b][0]);
			}
			printf("%lld\n",z);
		}
		else{
			scanf("%d %lld",&x,&z);int tmp;
			int u=e[x<<1].from,v=e[x<<1].to;
			if(f[u][0]==v) tmp=u;
			else tmp=v;
			val[tmp]=z;
			if(val[tmp]==1) fa[tmp]=find(f[tmp][0]);
		}
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

#define M 200005
#define LL long long
#define MAXN 20

int n, m, f[M][MAXN + 5], dep[M], fa[M];
LL val[M];
struct node {
	int u, v;
	LL w;
	node (){};
	node (int V, LL W){
		v = V;
		w = W;
	}
}e[M];
vector <node> G[M];

void makeSet (int x){
	for (int i = 1; i <= x; i ++)
		fa[i] = i;
}
int findSet (int x){
	if (fa[x] != x)
		fa[x] = findSet (fa[x]);
	return fa[x];
}
void dfs (int x, int fath){
	dep[x] = dep[fath] + 1;
	for (int i = 0; i < G[x].size (); i ++){
		int tmp = G[x][i].v; LL tot = G[x][i].w;
		if (tmp != fath){
			val[tmp] = tot;
			f[tmp][0] = x;
			if (tot == 1)
				fa[tmp] = findSet (x);
			dfs (tmp, x);
		}
	}
}
void prepare (){
	for (int j = 1; j <= MAXN; j ++)
		for (int i = 1; i <= n; i ++)
			f[i][j] = f[f[i][j - 1]][j - 1];
}
void add (int &x, int maxdep){
	for (int i = MAXN; i >= 0; i --)
		if (dep[f[x][i]] >= maxdep)
			x = f[x][i];
}
int Doubly (int x, int y){
	if (dep[x] > dep[y])
		add (x, dep[y]);
	if (dep[x] < dep[y])
		add (y, dep[x]);
	if (x == y)
		return x;
	for (int i = MAXN; i >= 0; i --){
		if (f[x][i] != f[y][i])
			x = f[x][i], y = f[y][i];
	}
	return f[x][0];
}
int main (){
	scanf ("%d %d", &n, &m);
	makeSet (n);
	for (int i = 1; i < n; i ++){
		scanf ("%d %d %lld", &e[i].u, &e[i].v, &e[i].w);
		G[e[i].u].push_back(node (e[i].v, e[i].w));
		G[e[i].v].push_back(node (e[i].u, e[i].w));
	}
	dfs (1, 0);
	prepare ();
	while (m --){
		int k;
		scanf ("%d", &k);
		if (k == 1){
			int a, b;LL c;
			scanf ("%d %d %lld", &a, &b, &c);
			int lca = Doubly (a, b);
			while (dep[a] > dep[lca] && c){
				c /= val[a];
				a = findSet (f[a][0]);
			}
			while (dep[b] > dep[lca] && c){
				c /= val[b];
				b = findSet (f[b][0]);
			}
			printf ("%lld\n", c);
		}
		else{
			int p, a; LL c;
			scanf ("%d %lld", &p, &c);
			if (f[e[p].u][0] == e[p].v)
				a = e[p].u;
			else
				a = e[p].v;
			val[a] = c;
			if (val[a] == 1)
				fa[a] = findSet (f[a][0]);
		}
	}
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
const int maxn = 1000010, inf = 1e18, N = 5e5 + 7;
int ch[maxn][2], par[maxn], rev[maxn], sta[maxn], val[maxn], mul[maxn], n, q;
bool chk(int x)
{
    return ch[par[x]][0] == x || ch[par[x]][1] == x;
}
bool safe(int x, int y)
{
    return inf / x >= y;
}
void update(int x)
{
	mul[x] = -1;
    if (safe(mul[ch[x][0]], mul[ch[x][1]]) && safe(mul[ch[x][0]] * mul[ch[x][1]], val[x])) mul[x] = mul[ch[x][0]] * mul[ch[x][1]] * val[x];
}
void reverse(int x)
{
    swap(ch[x][0], ch[x][1]);
    rev[x] ^= 1;
}
void pushdown(int x)
{
    if (rev[x])
    {
        reverse(ch[x][0]), reverse(ch[x][1]);
        rev[x] = 0;
    }
}
void rotate(int x)
{
	int y = par[x], z = par[y], k = (ch[y][1] == x), w = ch[x][k^1];
	if (chk(y)) ch[z][ch[z][1] == y] = x;
	ch[x][k ^ 1] = y,ch[y][k] = w;
	if (w) par[w] = y;
	par[y] = x,par[x] = z;
	update(x), update(y);
}
void pushall(int x)
{
	if (chk(x)) pushall(par[x]);
	pushdown(x);
}
void splay(int x)
{
	int y = x, z = 0;
	sta[++z] = y;
	while (chk(y)) sta[++z] = y = par[y];
	while (z) pushdown(sta[z--]);
	while (chk(x))
	{
		y = par[x], z = par[y];
		if (chk(y)) rotate((ch[y][0] == x) || (ch[z][0] == y) ? x : y);
		rotate(x);
	}
	update(x);
}
void access(int x)
{
	for (int y = 0; x; x = par[y = x])
		splay(x), ch[x][1] = y, update(x);
}
void makeroot(int x)
{
	access(x), splay(x), reverse(x);
}
void split(int x, int y)
{
	makeroot(x), access(y), splay(y);
}
void link(int x, int y)
{
	makeroot(x);
	par[x] = y;
}
void update_val(int x, int y)
{
    makeroot(x), val[x] = y, update(x);
}
int query(int x, int y)
{
    split(x, y);
    return mul[y];
}

signed main()
{
    scanf("%lld%lld", &n, &q);
    for (int i = 0; i <= n << 1; i++) val[i] = mul[i] = 1;
    for(int i=1;i<n;++i)
    {
        int u, v;
        scanf("%lld%lld", &u, &v);
        scanf("%lld", &val[i + N]);
        link(u,i+N),link(i+N,v);
    }
    for (int i = 1; i <= q; i++)
    {
        int type;
        scanf("%lld", &type);
        if(type==1)
        {
            int u, v;
            scanf("%lld%lld", &u, &v);
            int P;
            scanf("%lld", &P);
            long long V=query(u,v);
            if(~V)printf("%lld\n", P / V);
            else printf("0\n");
        }
        else
        {
            int u, v;
            scanf("%lld%lld", &u, &v);
            update_val(u+N,v);
        }
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int N=2e5+10;
const ll INF=1e18+5000;
int tot,cnt;
ll w[N],tmp[N];
int u[N],v[N],fir[N],fa[N],son[N],size[N],dep[N],top[N],id[N];
struct edge
{
	int to;
	int nxt;
}e[2*N];
inline void add(int x,int y)
{
	e[++tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot;
	e[++tot].to=x; e[tot].nxt=fir[y]; fir[y]=tot;
}
inline void dfs1(int p)
{
	size[p]=1;
	for(int i=fir[p];i;i=e[i].nxt)
	{
		int q=e[i].to;
		if(q==fa[p]) continue;
		fa[q]=p,dep[q]=dep[p]+1;
		dfs1(q);
		size[p]+=size[q];
		if(size[q]>size[son[p]]) son[p]=q;
	}
}
inline void dfs2(int p)
{
	id[p]=++cnt;
	if(son[p]) top[son[p]]=top[p],dfs2(son[p]);
	for(int i=fir[p];i;i=e[i].nxt)
	{
		int q=e[i].to;
		if(q==fa[p]||q==son[p]) continue;
		top[q]=q,dfs2(q);
	}
}
struct tree
{
	int left,right;
	ll val;
}t[4*N];
inline ll merge(ll x,ll y)
{
	if(max(x,y)==INF||x>=INF/y) return INF;
	else return x*y;
}
inline void build(int p,int l,int r)
{
	t[p].left=l,t[p].right=r;
	if(l==r){ t[p].val=tmp[l]; return; }
	int mid=(t[p].left+t[p].right)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].val=merge(t[p*2].val,t[p*2+1].val);
}
inline void change(int p,int pos,ll num)
{
	if(t[p].left==t[p].right){ t[p].val=num; return; }
	int mid=(t[p].left+t[p].right)/2;
	if(pos<=mid) change(p*2,pos,num);
	else change(p*2+1,pos,num);
	t[p].val=merge(t[p*2].val,t[p*2+1].val);
}
inline ll query(int p,int l,int r)
{
	if(l>r) return 1;
	if(l<=t[p].left&&r>=t[p].right) return t[p].val;
	int mid=(t[p].left+t[p].right)/2; ll ans=1;
	if(l<=mid) ans=merge(ans,query(p*2,l,r));
	if(r>mid) ans=merge(ans,query(p*2+1,l,r));
	return ans;
}
inline ll tree_query(int x,int y)
{
	ll ans=1;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=merge(ans,query(1,id[top[x]],id[x]));
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	ans=merge(ans,query(1,id[y]+1,id[x]));
	return ans;
}
int main()
{
	int n,m,opt,a,b; ll c;
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++)
	{
		scanf("%d%d%lld",&u[i],&v[i],&w[i]);
		add(u[i],v[i]);
	}
	dep[1]=1,dfs1(1);
	top[1]=1,dfs2(1);
	for(int i=1;i<n;i++)
	{
		if(dep[u[i]]>dep[v[i]]) swap(u[i],v[i]);
		tmp[id[v[i]]]=w[i];
	}
	tmp[1]=1;
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&opt,&a);
		if(opt==1)
		{
			scanf("%d%lld",&b,&c);
			ll ans=tree_query(a,b);
			if(c<ans) printf("0\n");
			else printf("%lld\n",c/ans);
		}
		else
		{
			scanf("%lld",&c);
			change(1,id[v[a]],c);
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define N 200100
using namespace std;
int n,q,h[N],tot,pos[N],fa[N],dep[N];
ll v[N];
struct QAQ{
	int to,next,num;
	ll val;
}e[N<<1];
inline ll read(){
	ll w=0;
	char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch<='9'&&ch>='0'){
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w;
}
inline void add(int x,int y,ll z,int i){
	e[++tot].to=y;e[tot].next=h[x],e[tot].val=z;e[tot].num=i;h[x]=tot;
	e[++tot].to=x;e[tot].next=h[y],e[tot].val=z;e[tot].num=i;h[y]=tot;
}
void dfs(int x,int f){
	dep[x]=dep[f]+1;
	for(register int i=h[x];i;i=e[i].next){
		int y=e[i].to;
		if(y==f) continue;
		fa[y]=x;v[y]=e[i].val;pos[e[i].num]=y;
		dfs(y,x);
	}
}
inline ll work(int x,int y,ll z){
	if(dep[x]>dep[y]) swap(x,y);
	while(dep[x]!=dep[y]&&z){
		z/=v[y];y=fa[y];
	}
	if(x==y||!z) return z;
	while(x!=y&&z){
		z/=v[x];z/=v[y];
		x=fa[x];y=fa[y];
	}
	return z;
}
int main(){
//	freopen("walk.in","r",stdin);
//	freopen("walk.out","w",stdout);
	n=read();q=read();
	for(register int i=1;i<n;i++){
		int x=read(),y=read();ll z=read();
		add(x,y,z,i);
	}
	dfs(1,0);
	while(q--){
		int opt=read();
		if(opt==2){
			int x=read();ll y=read();
			v[pos[x]]=y;
		}
		else{
			int x=read(),y=read();ll z=read();
			printf("%lld\n",work(x,y,z));
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
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...);
}

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int > vi;
typedef vector<ll> vll;
typedef vector<pll> vpll;
typedef vector<pii> vpii;

#define ALL(x) (x).begin(), (x).end()
#define RESET(x) memset((x), 0, sizeof (x))
#define FOR(i, b, e) for ( int i = (b); i < (e); ++i)
#define RE(i, n) FOR(i, 0, (n))
#define FOREACH(i, x, y) for ( int i = (x); i <= (y); ++i)
#define two(X) (1<<(X))//NOTES:two(
#define contain(S,X) (((S)&two(X))!=0)//NOTES:contain(
#define chkmin(X, Y) (X) = min((X), (Y))
#define chkmax(X, Y) (X) = max((X), (Y))
#define sqr(X) ((X) * (X))

const ll maxn = (ll) 4e5 + 100;
const ll maxm = (ll) 52;
const int logn = 22;
const ll INF = 2e18 + 100;
const ll MOD = 1000000007;
const double PI = acos(-1.0);
const double EPS = 1e-12;

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n, m;
    while (cin >> n >> m) {
        vector<vi> g(n + 1);
        vi from;
        vi to;
        vll c;
        RE(i, n - 1) {
            ll 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<ll(ll, ll)> Mul = [&] (ll x, ll y) {
            if (y != 0 && x > INF / y)
                return INF;
            return x * y;
        };
        // sz, big child, node weight
        vi sz(n + 1);
        vll wi(n + 1, 1);
        vi pre(n + 1);
        vi dep(n + 1);
        function<void(int, int)> DfsSz = [&] (int x, int fa) {
            dep[x] = dep[fa] + 1;
            pre[x] = fa;
            RE(i, g[x].size()) 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;
        };
        // heavy-light, st, ed, acc
        vi st(n + 1);
        vi ed(n + 1);
        int tot = 0;
        vi anc(n + 1);
        function<void(int, int, int)> DfsHL = [&] (int x, int fa, int chain) {
            st[x] = ++tot;
            anc[x] = chain;
            RE(i, g[x].size()) if (to[g[x][i]] != fa) {
                int y = to[g[x][i]];
                if (i == 0) {
                    // big
                    DfsHL(y, x, chain);
                } else {
                    DfsHL(y, x, y);
                }
            }
            ed[x] = tot;
        };

        // build tree
        vll a;
        function<void(int, int, int)> PushUp = [&] (int root, int l, int r) {
            if (l == r)
                return;
            ll left = a[root << 1];
            ll right = a[root << 1 | 1];
            a[root] = Mul(left, right);
        };
        function<void(int, int, int, int, ll)> Update = [&] (int root, int l, int r, int pos, ll 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<ll (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];
            }
            ll left = 1;
            ll 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);
        FOREACH(i, 1, n) {
            Update(1, 1, tot, st[i], wi[i]);
        }

        // queries
        RE(i, m) {
            int op;
            cin >> op;
            if (op == 1) {
                ll u, v, y;
                cin >> u >> v >> y;
                ll div = 1;
                while (anc[u] != anc[v]) {
                    if (anc[u] < anc[v])
                        swap(u, v);
                    int x = anc[u];
                    int y = u;
                    ll 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);
                ll r = st[v] < st[u] ? Query(1, 1, tot, st[v] + 1, st[u]) : 1;
                div = Mul(div, r);
                cout << y / div << endl;
            } else {
                ll p, c;
                cin >> p >> c;
                int x = from[(p - 1) * 2];
                int y = to[(p - 1) * 2];
                if (pre[y] == x)
                    swap(x, y);
                wi[x] = c;
                Update(1, 1, tot, st[x], c);
            }
        }
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
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...);
}

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int > vi;
typedef vector<ll> vll;
typedef vector<pll> vpll;
typedef vector<pii> vpii;

#define ALL(x) (x).begin(), (x).end()
#define RESET(x) memset((x), 0, sizeof (x))
#define FOR(i, b, e) for ( int i = (b); i < (e); ++i)
#define RE(i, n) FOR(i, 0, (n))
#define FOREACH(i, x, y) for ( int i = (x); i <= (y); ++i)
#define two(X) (1<<(X))//NOTES:two(
#define contain(S,X) (((S)&two(X))!=0)//NOTES:contain(
#define chkmin(X, Y) (X) = min((X), (Y))
#define chkmax(X, Y) (X) = max((X), (Y))
#define sqr(X) ((X) * (X))

const ll maxn = (ll) 4e5 + 100;
const ll maxm = (ll) 52;
const int logn = 22;
const ll INF = 1e18 + 100;
const ll MOD = 1000000007;
const double PI = acos(-1.0);
const double EPS = 1e-12;

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n, m;
    while (cin >> n >> m) {
        vector<vi> g(n + 1);
        vi from;
        vi to;
        vll c;
        RE(i, n - 1) {
            ll 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<ll(ll, ll)> Mul = [&] (ll x, ll y) {
            if ((long double)x * y <= INF)
                return x * y;
            return INF;
        };
        // sz, big child, node weight
        vi sz(n + 1);
        vll wi(n + 1, 1);
        vi pre(n + 1);
        vi dep(n + 1);
        function<void(int, int)> DfsSz = [&] (int x, int fa) {
            dep[x] = dep[fa] + 1;
            pre[x] = fa;
            RE(i, g[x].size()) 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;
        };
        // heavy-light, st, ed, acc
        vi st(n + 1);
        vi ed(n + 1);
        int tot = 0;
        vi anc(n + 1);
        function<void(int, int, int)> DfsHL = [&] (int x, int fa, int chain) {
            st[x] = ++tot;
            anc[x] = chain;
            RE(i, g[x].size()) if (to[g[x][i]] != fa) {
                int y = to[g[x][i]];
                if (i == 0) {
                    // big
                    DfsHL(y, x, chain);
                } else {
                    DfsHL(y, x, y);
                }
            }
            ed[x] = tot;
        };

        // build tree
        vll a;
        function<void(int, int, int)> PushUp = [&] (int root, int l, int r) {
            if (l == r)
                return;
            ll left = a[root << 1];
            ll right = a[root << 1 | 1];
            a[root] = Mul(left, right);
        };
        function<void(int, int, int, int, ll)> Update = [&] (int root, int l, int r, int pos, ll 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<ll (int, int, int, int, int)> Query = [&] (int root, int l, int r, int L, int R) {
            assert(L <= R);
            if (L == R)
                return 1LL;
            if (L <= l && r <= R) {
                return a[root];
            }
            ll left = 1;
            ll 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);
        FOREACH(i, 1, n) {
            Update(1, 1, tot, st[i], wi[i]);
        }

        // queries
        RE(i, m) {
            int op;
            cin >> op;
            if (op == 1) {
                ll u, v, y;
                cin >> u >> v >> y;
                if (dep[u] < dep[v])
                    swap(u, v);
                ll div = 1;
                while (anc[u] != anc[v]) {
                    int x = anc[u];
                    int y = u;
                    ll r = Query(1, 1, tot, st[x], st[y]);
                    div = Mul(div, r);
                    u = pre[x];
                    div = Mul(div, wi[x]);
                    if (dep[u] < dep[v])
                        swap(u, v);
                }
                ll r = Query(1, 1, tot, st[v], st[u]);
                div = Mul(div, r);
                cout << y / div << endl;
            } else {
                ll p, c;
                cin >> p >> c;
                int x = from[(p - 1) * 2];
                int y = to[(p - 1) * 2];
                if (pre[y] == x)
                    swap(x, y);
                wi[x] = c;
                Update(1, 1, tot, st[x], c);
            }
        }
    }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
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...);
}

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int > vi;
typedef vector<ll> vll;
typedef vector<pll> vpll;
typedef vector<pii> vpii;

#define ALL(x) (x).begin(), (x).end()
#define RESET(x) memset((x), 0, sizeof (x))
#define FOR(i, b, e) for ( int i = (b); i < (e); ++i)
#define RE(i, n) FOR(i, 0, (n))
#define FOREACH(i, x, y) for ( int i = (x); i <= (y); ++i)
#define two(X) (1<<(X))//NOTES:two(
#define contain(S,X) (((S)&two(X))!=0)//NOTES:contain(
#define chkmin(X, Y) (X) = min((X), (Y))
#define chkmax(X, Y) (X) = max((X), (Y))
#define sqr(X) ((X) * (X))

const ll maxn = (ll) 4e5 + 100;
const ll maxm = (ll) 52;
const int logn = 22;
const ll INF = 1e18 + 100;
const ll MOD = 1000000007;
const double PI = acos(-1.0);
const double EPS = 1e-12;

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n, m;
    while (cin >> n >> m) {
        vector<vi> g(n + 1);
        vi from;
        vi to;
        vll c;
        RE(i, n - 1) {
            int 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);
        }

        // sz, big child, node weight
        vi sz(n + 1);
        vll wi(n + 1, 1);
        vi pre(n + 1);
        vi dep(n + 1);
        function<void(int, int)> DfsSz = [&] (int x, int fa) {
            dep[x] = dep[fa] + 1;
            pre[x] = fa;
            RE(i, g[x].size()) 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;
        };
        // heavy-light, st, ed, acc
        vi st(n + 1);
        vi ed(n + 1);
        int tot = 0;
        vi anc(n + 1);
        function<void(int, int, int)> DfsHL = [&] (int x, int fa, int chain) {
            st[x] = ++tot;
            anc[x] = chain;
            RE(i, g[x].size()) if (to[g[x][i]] != fa) {
                int y = to[g[x][i]];
                if (i == 0) {
                    // big
                    DfsHL(y, x, chain);
                } else {
                    DfsHL(y, x, y);
                }
            }
            ed[x] = tot;
        };

        // build tree
        vll a;
        function<void(int, int, int)> PushUp = [&] (int root, int l, int r) {
            if (l == r)
                return;
            ll left = a[root << 1];
            ll right = a[root << 1 | 1];
            if (left == INF || right == INF || left >= INF / right) {
                a[root] = INF;
            } else {
                a[root] = left * right;
            }
        };
        function<void(int, int, int, int, ll)> Update = [&] (int root, int l, int r, int pos, ll 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<ll (int, int, int, int, int)> Query = [&] (int root, int l, int r, int L, int R) {
            assert(L <= R);
            if (L == R)
                return 1LL;
            if (L <= l && r <= R) {
                return a[root];
            }
            ll left = 1;
            ll 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);
            }
            if (left == INF || right == INF || left >= INF / right)
                return INF;
            return left * right;
        };

        DfsSz(1, 0);
        DfsHL(1, 0, 1);
        a.resize(tot * 6, 1);
        FOREACH(i, 1, n) {
            Update(1, 1, tot, st[i], wi[i]);
        }
        function<ll(ll, ll)> Mul = [&] (ll x, ll y) {
            if (x == INF || y == INF || x >= INF / y)
                return INF;
            return x * y;
        };
        // queries
        RE(i, m) {
            int op;
            cin >> op;
            if (op == 1) {
                ll u, v, y;
                cin >> u >> v >> y;
                if (dep[u] < dep[v])
                    swap(u, v);
                ll div = 1;
                while (anc[u] != anc[v]) {
                    int x = anc[u];
                    int y = u;
                    ll r = Query(1, 1, tot, st[x], st[y]);
                    div = Mul(div, r);
                    u = pre[x];
                    div = Mul(div, wi[x]);
                    if (dep[u] < dep[v])
                        swap(u, v);
                }
                ll r = Query(1, 1, tot, st[v], st[u]);
                div = Mul(div, r);
                cout << y / div << endl;
            } else {
                ll p, c;
                cin >> p >> c;
                int x = from[(p - 1) * 2];
                int y = to[(p - 1) * 2];
                if (pre[y] == x)
                    swap(x, y);
                wi[x] = c;
                Update(1, 1, tot, st[x], c);
            }
        }
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    int maxi =0,ind=0;
	    cin>>n>>k;
	    map<int,int> m;
	    vector<int> a(n);
	    for(int i=0;i<n;i++){
	        cin>>a[i];
	        m[a[i]]++;
	        if(m[a[i]] > maxi){
	            maxi = m[a[i]];
	            ind = a[i];
	        }
	    }
	    int cnt=0,f=0,ans=0;
	    int diff = k-1;
	    for(int i=0;i<n;i++){
	        if(a[i] != ind && f == 0){
	            f=1;
	            cnt = 1;
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            cnt =0;
	            f=0;
	            ans++;
	        }
	    }
	    if(cnt != 0 && f == 1){
	        ans++;
	    }

	    cnt=0,f=-1;
	    int ans2 =0;
	    int sz=1;
	    for(int i=0;i<n;i++){
	        if(a[i] == ind && f == -1){
	            f=1;
	            cnt=1;
	        }
	        else if(f == 1){
	            cnt++;
	            if(a[i] != ind){
	                m[a[i]]--;
	            }
	            if(m[a[i]] == 0){
	                sz++;
	            }
	        }
	        if(cnt == diff+1){
	            ans2++;
	            cnt=0;
	            f=-1;
	        }
	    }
	    if(cnt != 0 && f != -1){
	        ans2++;
	    }
	    if(m.size() - sz == 1){
	    cout<<min(ans,ans2)<<"\n";
	    }
	    else{
	        cout<<ans<<"\n";
	    }
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    int maxi =0,ind=0;
	    cin>>n>>k;
	    map<int,int> m;
	    vector<int> a(n);
	    for(int i=0;i<n;i++){
	        cin>>a[i];
	        m[a[i]]++;
	        if(m[a[i]] > maxi){
	            maxi = m[a[i]];
	            ind = a[i];
	        }
	    }
	    int cnt=0,f=0,ans=0;
	    int diff = k-1;
	    for(int i=0;i<n;i++){
	        if(a[i] != ind && f == 0){
	            f=1;
	            cnt = 1;
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            cnt =0;
	            f=0;
	            ans++;
	        }
	    }
	    if(cnt != 0 && f == 1){
	        ans++;
	    }
	    cout<<ans<<"\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    int maxi =0,ind=0;
	    cin>>n>>k;
	    map<int,int> m;
	    vector<int> a(n);
	    for(int i=0;i<n;i++){
	        cin>>a[i];
	        m[a[i]]++;
	        if(m[a[i]] > maxi){
	            maxi = m[a[i]];
	            ind = a[i];
	        }
	    }
	    if(m.size() == 1){
	        cout<<"0"<<"\n";
	        continue;
	    }
	    int cnt=0,f=0,ans=0;
	    int diff = k-1;
	    for(int i=0;i<n;i++){
	        if(a[i] != ind && f == 0){
	            f=1;
	            cnt = 1;
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            cnt =0;
	            f=0;
	            ans++;
	        }
	    }
	    if(cnt != 0 && f == 1){
	        ans++;
	    }

	    cnt=0,f=0;
	    int ans2 =0;
	    int sz=1;
	    for(int i=0;i<n;i++){
	        if(a[i] == ind && f == 0){
	            f=1;
	            cnt=1;
	        }
	        else if(f == 1){
	            cnt++;
	            if(a[i] != ind){
	                m[a[i]]--;
	            }
	            if(m[a[i]] == 0){
	                sz++;
	            }
	        }
	        if(cnt == diff+1){
	            ans2++;
	            cnt=0;
	            f=0;
	        }
	    }
	    if(cnt != 0 && f != 1){
	        ans2++;
	    }
	    if(m.size() - sz == 1){
	    cout<<min(ans,ans2)<<"\n";
	    }
	    else{
	        cout<<ans<<"\n";
	    }
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    int maxi =0,ind=0;
	    cin>>n>>k;
	    map<int,int> m;
	    vector<int> a(n);
	    for(int i=0;i<n;i++){
	        cin>>a[i];
	        m[a[i]]++;
	        if(m[a[i]] > maxi){
	            maxi = m[a[i]];
	            ind = a[i];
	        }
	    }
	    if(m.size() == 1){
	        cout<<"0"<<"\n";
	        continue;
	    }
	    int cnt=0,f=0,ans=0;
	    int diff = k-1;
	    for(int i=0;i<n;i++){
	        if(a[i] != ind && f == 0){
	            f=1;
	            cnt = 1;
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            cnt =0;
	            f=0;
	            ans++;
	        }
	    }
	    if(cnt != 0 && f == 1){
	        ans++;
	    }

	    cnt=0,f=0;
	    int ans2 =0;
	    int sz=1;
	    for(int i=0;i<n;i++){
	        if(a[i] == ind && f == 0){
	            f=1;
	            cnt=1;
	        }
	        else if(f == 1){
	            cnt++;
	            if(a[i] != ind){
	                m[a[i]]--;
	            }
	            if(m[a[i]] == 0){
	                sz++;
	            }
	        }
	        if(cnt == diff+1){
	            ans2++;
	            cnt=0;
	            f=0;
	        }
	    }
	    if(cnt != 0 && f != 1){
	        ans2++;
	    }
	    if(m.size() - sz <= 1){
	    cout<<min(ans,ans2)<<"\n";
	    }
	    else{
	        cout<<ans<<"\n";
	    }
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    int maxi =0,ind=0;
	    cin>>n>>k;
	    map<int,int> m;
	    vector<int> a(n+1);
	    for(int i=1;i<=n;i++){
	        cin>>a[i];
	        m[a[i]]++;
	        if(m[a[i]] > maxi){
	            maxi = m[a[i]];
	            ind = a[i];
	        }
	    }
	    int cnt=0,f=0,ans=0,cnt2=0,back=1;
	    int diff = k-1;
	    for(int i=1;i<=n;i++){
	        if(a[i] != ind && f == 0){
	            f=1;
	            cnt = 1;
	            cnt2 += (i-back+1)/k;
	            if((i-back)%k != 0){
	                cnt2++;
	            }
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            cnt =0;
	            f=0;
	            ans++;
	            back = i+1;
	        }
	    }
	    if(cnt != 0 && f == 1){
	        ans++;
	    }
	    cout<<min(ans,cnt2)<<"\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    cin>>n>>k;
	    vector<int> a(n),b(101,0);
	    int maxi = 0;
	    for(int i=0;i<n;i++){
	        cin>>a[i];
	        if(a[i] > maxi){
	            maxi = a[i];
	        }
	    }
	    int ans=1e6;
	    for(int i=0;i<=maxi;i++){
	        int j=0,cnt=0;
	        while(j<n){
	            if(a[j] != i){
	                cnt++;
	                j += k;
	            }
	            else{
	                j++;
	            }
	        }
	        ans = min(ans,cnt);
	    }
	    cout<<ans<<"\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

int main() {
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
	int t;
	cin>>t;
	while(t--){
	    int n,k;
	    int maxi =0,ind=0;
	    cin>>n>>k;
	    map<int,int> m;
	    vector<int> a(n);
	    for(int i=0;i<n;i++){
	        cin>>a[i];
	        m[a[i]]++;
	        if(m[a[i]] > maxi){
	            maxi = m[a[i]];
	            ind = a[i];
	        }
	    }
	    int cnt=0,f=0,ans=0;
	    int diff = k-1;
	    for(int i=0;i<n;i++){
	        if(a[i] != ind && f == 0){
	            f=1;
	            cnt = 1;
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            cnt =0;
	            f=0;
	            ans++;
	        }
	    }
	    if(cnt != 0 && f == 1){
	        ans++;
	    }
	    if(m.size() != 2){
	        cout<<ans<<"\n";
	        continue;
	    }
	    cnt=0,f=-1;
	    int ans2 =0;
	    for(int i=0;i<n;i++){
	        if(a[i] == ind && f == -1){
	            f=1;
	            cnt=1;
	        }
	        else if(f == 1){
	            cnt++;
	        }
	        if(cnt == diff+1){
	            ans2++;
	            cnt=0;
	            f=-1;
	        }
	    }
	    if(cnt != 0 && f != -1){
	        ans2++;
	    }
	    cout<<min(ans,ans2)<<"\n";
	}
	return 0;
}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll sopw(ll a[],ll n,ll o,ll k)
{
string s="";
for(ll i=0;i<n;i++)
{

if(a[i]==o)
s+='1';
else
s+='0';
}

ll ans=0;
for(ll i=0;i<n;)
{
    if(s[i]=='0')
    {
        ans++;
        for(ll j=0;j<k;j++)
        {
		if(s[i+j]=='0')
        s[i+j]=(char)((s[i+j]-'0')+49);
    }
        i+=k;

	}

    else
    i++;
}
 return ans;
}
void s()
{
 ll n,k,ans=0;
 cin>>n>>k;
 ll arr[n];

 for(ll i=0;i<n;i++)
  cin>>arr[i];

 if(n==1)
 {
     cout<<"0\n";

 }
 ll an=INT_MAX;
 for(ll i=1;i<=100;i++)
 {
     ll o=sopw(arr,n,i,k);
     an=min(an,o);
 }
 cout<<an<<"\n";
}

int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;

void s()
{
 ll n=0;
 cin>>n;
 ll k=0;
 cin>>k;

ll arr[n],brr[n];

for(ll i=0;i<n;i++)
{
	cin>>arr[i];
brr[i]=arr[i];
}

////wefffffffffffffffffffffffffffffffffffffffffffffffffffffff
///effffffffffffffffffffffffff
//feeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

//feeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
ll mini=101,maxi=0;
        for(ll i=0;i<n;i++)
        {

            if(arr[i]>maxi)
            maxi=arr[i];
            if(arr[i]<mini)
            mini=arr[i];
        }
        ll s=100000000;
        for(ll i=mini;i<=maxi;i++){
            ll temp=0;
            ll g=0;
            while(g<n){
                if(arr[g]!=i)
                {temp++;
                g+=k;}
                else
                g++;
            }
            s=min( s,temp);
        }
        cout<< s<<endl;

 }
int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;

void s()
{
 ll n=0;
 cin>>n;
 ll k=0;
 cin>>k;

ll arr[n],brr[n];

for(ll i=0;i<n;i++)
{
	cin>>arr[i];
brr[i]=arr[i];
}
ll m=0;ll h=0;
sort(brr,brr+n);
for(ll i=0;i<n-1;i++)
{
	ll l=1;
	while(brr[i+1]==brr[i])
	{
		l++;
		i++;
	}
	m=max(m,l);
	h=arr[i];
}
//cout<<h<<" ";

 ll s=0;
 for(int i=0;i<n;i++)
 {ll j=0;
 ll p=k;
 	while(arr[i]!=h &&i<n  )
 	{

	j++;i++;

	 }
	  // cout<<j<<" ";

		 s+=(j%k)+(j/k);

 }
 if(n==1)
 cout<<"0\n";
 else
 cout<<s<<"\n";
 }
int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll sopw(ll a[],ll n,ll o,ll k)
{
string s="";
for(ll i=0;i<n;i++)
{

if(a[i]==o)
s+='1';
else
s+='0';
}

ll ans=0;
for(ll i=0;i<n;)
{
    if(s[i]=='0')
    {
        ans++;
        for(ll j=0;j<k;j++)
        {
		if(s[i+j]=='0')
        s[i+j]=(char)((s[i+j]-'0')+49);

        i+=k;
        }
	}

    else
    i++;
}
 return ans;
}
void s()
{
 ll n,k,ans=0;
 cin>>n>>k;
 ll arr[n];

 for(int i=0;i<n;i++)
  cin>>arr[i];

 if(n==1)
 {
     cout<<"0\n";

 }
 ll an=INT_MAX;
 for(int i=1;i<=100;i++)
 {
     ll o=sopw(arr,n,i,k);
     an=min(an,o);
 }
 cout<<an<<"\n";
}

int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll sopw(ll a[],ll n,ll o,ll k)
{
string s="";
for(ll i=0;i<n;i++)
{

if(a[i]==o)
s+='1';
else
s+='0';
}

ll ans=0;
for(ll i=0;i<n;i++)
{
    if(s[i]=='0')
    {
        ans++;
        for(ll j=0;j<k;j++)
        {
		if(s[i+j]=='0')
        s[i+j]=(char)((s[i+j]-'0')+49);
        i+=k;
    }
	}

    else
    i++;
}
 return ans;
}
void s()
{
 ll n,k,ans=0;
 cin>>n>>k;
 ll arr[n];

 for(int i=0;i<n;i++)
  cin>>arr[i];

 if(n==1)
 {
     cout<<"0\n";

 }
 ll an=INT_MAX;
 for(int i=0;i<n;i++)
 {
     ll j=sopw(arr,n,i,k);
     an=min(an,j);
 }
 cout<<an<<"\n";
}

int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;

void s()
{
 ll n=0;
 cin>>n;
 ll k=0;
 cin>>k;

ll arr[n],brr[n];

for(ll i=0;i<n;i++)
{
	cin>>arr[i];
brr[i]=arr[i];
}

////wefffffffffffffffffffffffffffffffffffffffffffffffffffffff
///effffffffffffffffffffffffff
//feeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

//feeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
ll mini=101,maxi=0;
        for(ll i=0;i<n;i++)
        {

            if(arr[i]>maxi)
            maxi=arr[i];
            if(arr[i]<mini)
            mini=arr[i];
        }
        ll s=100000000;
        for(ll i=mini;i<=maxi;i++){
            ll temp=0;
            ll g=0;
            while(g<n){
                if(arr[g]!=i)
                {temp++;
                g+=k;}
                else
                ++;
            }
            s=min( s,temp);
        }
        cout<< s<<endl;

 }
int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;

void s()
{
 ll n=0;
 cin>>n;
 ll k=0;
 cin>>k;

ll arr[n],brr[n];

for(ll i=0;i<n;i++)
{
	cin>>arr[i];
brr[i]=arr[i];
}
ll m=0;ll h=0;
sort(brr,brr+n);
for(ll i=0;i<n-1;i++)
{
	ll l=1;
	while(brr[i+1]==brr[i])
	{
		l++;
		i++;
	}
	m=max(m,l);
	h=arr[i];
}
//cout<<h<<" ";

 ll s=0;
 for(int i=0;i<n;i++)
 {ll j=0;
 ll p=k;
 	while(arr[i]!=h &&i<n  )
 	{

	j++;i++;

	 }
	  // cout<<j<<" ";

		 s+=(j%k)+(j/k);

 }
 cout<<s<<"\n";
 }
int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll sopw(ll a[],ll n,ll o,ll k)
{
string s="";
for(ll i=0;i<n;i++)
{

if(a[i]==o)
s+='1';
else
s+='0';
}

ll ans=0;
for(ll i=0;i<n;)
{
    if(s[i]=='0')
    {
        ans++;
        for(ll j=0;j<k;j++)
        {
		if(s[i+j]=='0')
        s[i+j]=(char)((s[i+j]-'0')+49);
    }
        i+=k;

	}

    else
    i++;
}
 return ans;
}
void s()
{
 ll n,k,ans=0;
 cin>>n>>k;
 ll arr[n];

 for(int i=0;i<n;i++)
  cin>>arr[i];

 if(n==1)
 {
     cout<<"0\n";

 }
 ll an=INT_MAX;
 for(int i=1;i<=100;i++)
 {
     ll o=sopw(arr,n,i,k);
     an=min(an,o);
 }
 cout<<an<<"\n";
}

int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll sopw(ll a[],ll n,ll o,ll k)
{
string s="";
for(ll i=0;i<n;i++)
{

if(a[i]==o)
s+='1';
else
s+='0';
}

ll ans=0;
for(ll i=0;i<n;)
{
    if(s[i]=='0')
    {
        ans++;
        for(ll j=0;j<k;j++)
        {
		if(s[i+j]=='0')
        s[i+j]=(char)((s[i+j]-'0')+49);
    }
        i+=k;

	}

    else
    i++;
}
 return ans;
}
void s()
{
 ll n,k,ans=0;
 cin>>n>>k;
 ll arr[n];

 for(int i=0;i<n;i++)
  cin>>arr[i];

 if(n==1)
 {
     cout<<"0\n";

 }
 ll an=INT_MAX;
 for(int i=1;i<100;i++)
 {
     ll o=sopw(arr,n,i,k);
     an=min(an,o);
 }
 cout<<an<<"\n";
}

int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;

void s()
{
 ll n=0;
 cin>>n;
 ll k=0;
 cin>>k;

ll arr[n],brr[n];

for(ll i=0;i<n;i++)
{
	cin>>arr[i];
brr[i]=arr[i];
}
ll m=0;ll h=0;
sort(brr,brr+n);
for(ll i=0;i<n-1;i++)
{
	ll l=1;
	while(brr[i+1]==brr[i])
	{
		l++;
		i++;
	}
	m=max(m,l);
	h=arr[i];
}

//cout<<m<<" ";

ll s=0;
if((n-m)%k ==0)
cout<<(n-m)/k;
else
{
	cout<<(n-m)/k  +1;
}

 }
int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
ll sopw(ll a[],ll n,ll o,ll k)
{
string s="";
for(ll i=0;i<n;i++)
{

if(a[i]==o)
s+='1';
else
s+='0';
}

ll ans=0;
for(ll i=0;i<n;)
{
    if(s[i]=='0')
    {
        ans++;
        for(ll j=0;j<k;j++)
		if(s[i+j]=='0')
        s[i+j]=(char)((s[i+j]-'0')+49);
        i+=k;

	}

    else
    i++;
}
 return ans;
}
void s()
{
 ll n,k,ans=0;
 cin>>n>>k;
 ll arr[n];

 for(int i=0;i<n;i++)
  cin>>arr[i];

 if(n==1)
 {
     cout<<"0\n";

 }
 ll an=INT_MAX;
 for(int i=1;i<=100;i++)
 {
     ll o=sopw(arr,n,i,k);
     an=min(an,o);
 }
 cout<<an<<"\n";
}

int main()
{

	ll  t=0;
  cin>>t;
  while(t--)
	{

	s();
	}

	return  0;

}


#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//#define  mod 4294967296
#define mod 1000000007
using namespace std;
bool isprime(ll n)
{
    //if(n<2)
    //return false;
    if(n==1)
    return true;
    if(n==2 || n==3)
    return true;
    if(n%2==0)return false;
    for(ll i=3;i*i<=n;i+=2)
    {
        if(n%i==0)
        return false;

    }
    return true;
}
bool checkpalindrome(ll c)
{
    string p=to_string(c);
       int j = p.size() - 1;

    for (int i = 0; i < j; i++, j--)
    {
        if (p[i] != p[j])
        {
            return false;
        }
    }

    return true;
}
int gcd(ll a,ll b)
{
    if(a==0)
    return b;
    return gcd(b%a,a);
}
int lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}
 set<ll> fac;
void allFactors(ll n)
{
   // set<ll> fac;
    for(ll i=1;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            fac.insert(i);
            if(i!=n/i)
            {
                fac.insert(n/i);
            }
        }
    }
    //return fac.size();
}
bool threefactors(ll n)//when you have need of a no which is divisible by 1,itself,any other one no.
{
    ll p=sqrt(n);
    if(p*p==n)
    {
        if(isprime(p))
        return 1;
        else
        return 0;
    }
    else
    return 0;
}
unsigned int countSetBits(unsigned int n) //no. of 1's in a binary representation of a number
{
    unsigned int count = 0;
    while (n) {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
int computeXOR(int n)
{
  if(n%4==0)
  return n;                        //TO CALCULATE XOR FROM 1 TO N
  if(n%4==1)
  return 1;
  if(n%4==2)
  return n+1;
  else
  return 0;
}
ll largest_power(ll N)
    {                                              //LARGEST POWER OF 2 JUST LESS THAN OR EQUAL TO A GIVEN 16 BIT NUMBER
        //changing all right side bits to 1.
        N = N| (N>>1);
        N = N| (N>>2);
        N = N| (N>>4);
        N = N| (N>>8);
        N = N| (N>>16);

    //as now the number is 2 * x-1, where x is required answer, so adding 1 and dividing it by
                return (N+1)>>1;

    }
ll fibo(ll n)
{
    long double him=(1+sqrt(5))/2;
  return round(pow(him,n)/sqrt(5));
}
/*               Yhi patak ke chod denge
                 Chal nikal madarch*d                            */

int main()
{
     IOS
     int testcases=1;
     cin>>testcases;
     while(testcases--)
     {
        int n,k;
        cin>>n>>k;
        int a[n];
        int p,m=0;
        for(int i=0;i<n;i++)
        {
           cin>>a[i];
        }
       int ans=1000000;
       for(int c=1;c<=100;c++)
       {
           p=0;
       for(int i=0;i<n;i+=k)
       {
           m=0;
           while( i<n && a[i]==c)
           i++;
           if(i<n)
          p++;
       }
       ans=min(ans,p);
       }
       cout<<ans<<endl;

     }
     return 0;
}
//ascii of a=97
//ascii of A=65
//ascii of 0=48
//lower_bound and upper_bound


#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//#define  mod 4294967296
#define mod 1000000007
using namespace std;
bool isprime(ll n)
{
    //if(n<2)
    //return false;
    if(n==1)
    return true;
    if(n==2 || n==3)
    return true;
    if(n%2==0)return false;
    for(ll i=3;i*i<=n;i+=2)
    {
        if(n%i==0)
        return false;

    }
    return true;
}
bool checkpalindrome(ll c)
{
    string p=to_string(c);
       int j = p.size() - 1;

    for (int i = 0; i < j; i++, j--)
    {
        if (p[i] != p[j])
        {
            return false;
        }
    }

    return true;
}
int gcd(ll a,ll b)
{
    if(a==0)
    return b;
    return gcd(b%a,a);
}
int lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}
 set<ll> fac;
void allFactors(ll n)
{
   // set<ll> fac;
    for(ll i=1;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            fac.insert(i);
            if(i!=n/i)
            {
                fac.insert(n/i);
            }
        }
    }
    //return fac.size();
}
bool threefactors(ll n)//when you have need of a no which is divisible by 1,itself,any other one no.
{
    ll p=sqrt(n);
    if(p*p==n)
    {
        if(isprime(p))
        return 1;
        else
        return 0;
    }
    else
    return 0;
}
unsigned int countSetBits(unsigned int n) //no. of 1's in a binary representation of a number
{
    unsigned int count = 0;
    while (n) {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
int computeXOR(int n)
{
  if(n%4==0)
  return n;                        //TO CALCULATE XOR FROM 1 TO N
  if(n%4==1)
  return 1;
  if(n%4==2)
  return n+1;
  else
  return 0;
}
ll largest_power(ll N)
    {                                              //LARGEST POWER OF 2 JUST LESS THAN OR EQUAL TO A GIVEN 16 BIT NUMBER
        //changing all right side bits to 1.
        N = N| (N>>1);
        N = N| (N>>2);
        N = N| (N>>4);
        N = N| (N>>8);
        N = N| (N>>16);

    //as now the number is 2 * x-1, where x is required answer, so adding 1 and dividing it by
                return (N+1)>>1;

    }
ll fibo(ll n)
{
    long double him=(1+sqrt(5))/2;
  return round(pow(him,n)/sqrt(5));
}
/*               Yhi patak ke chod denge
                 Chal nikal madarch*d                            */

int main()
{
     IOS
     int testcases=1;
     cin>>testcases;
     while(testcases--)
     {
        int n,k;
        cin>>n>>k;
        vector<int> v[n+1];
        int a[n];
        int p,c=0,m=0;
        for(int i=0;i<n;i++)
        {
            cin>>p;
            a[i]=p;
            v[p].pb(i+1);
        }
       for(int i=1;i<=n;i++)
       {
           if(v[i].size()>m)
           {
               m=v[i].size();
               c=i;
           }
       }
      // cout<<c<<" ";
       p=0;
       for(int i=0;i<n;i+=k)
       {
           m=0;
           for(int j=i;j<i+k && j<n;j++)
           {
               if(a[j]!=c)
               m=1;
           }
           if(m)
           {
               p++;
           }
           while(a[i+k]==c)
           i++;
       }
       cout<<p<<endl;

     }
     return 0;
}
//ascii of a=97
//ascii of A=65
//ascii of 0=48
//lower_bound and upper_bound


#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//#define  mod 4294967296
#define mod 1000000007
using namespace std;
bool isprime(ll n)
{
    //if(n<2)
    //return false;
    if(n==1)
    return true;
    if(n==2 || n==3)
    return true;
    if(n%2==0)return false;
    for(ll i=3;i*i<=n;i+=2)
    {
        if(n%i==0)
        return false;

    }
    return true;
}
bool checkpalindrome(ll c)
{
    string p=to_string(c);
       int j = p.size() - 1;

    for (int i = 0; i < j; i++, j--)
    {
        if (p[i] != p[j])
        {
            return false;
        }
    }

    return true;
}
int gcd(ll a,ll b)
{
    if(a==0)
    return b;
    return gcd(b%a,a);
}
int lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}
 set<ll> fac;
void allFactors(ll n)
{
   // set<ll> fac;
    for(ll i=1;i<=sqrt(n);i++)
    {
        if(n%i==0)
        {
            fac.insert(i);
            if(i!=n/i)
            {
                fac.insert(n/i);
            }
        }
    }
    //return fac.size();
}
bool threefactors(ll n)//when you have need of a no which is divisible by 1,itself,any other one no.
{
    ll p=sqrt(n);
    if(p*p==n)
    {
        if(isprime(p))
        return 1;
        else
        return 0;
    }
    else
    return 0;
}
unsigned int countSetBits(unsigned int n) //no. of 1's in a binary representation of a number
{
    unsigned int count = 0;
    while (n) {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
int computeXOR(int n)
{
  if(n%4==0)
  return n;                        //TO CALCULATE XOR FROM 1 TO N
  if(n%4==1)
  return 1;
  if(n%4==2)
  return n+1;
  else
  return 0;
}
ll largest_power(ll N)
    {                                              //LARGEST POWER OF 2 JUST LESS THAN OR EQUAL TO A GIVEN 16 BIT NUMBER
        //changing all right side bits to 1.
        N = N| (N>>1);
        N = N| (N>>2);
        N = N| (N>>4);
        N = N| (N>>8);
        N = N| (N>>16);

    //as now the number is 2 * x-1, where x is required answer, so adding 1 and dividing it by
                return (N+1)>>1;

    }
ll fibo(ll n)
{
    long double him=(1+sqrt(5))/2;
  return round(pow(him,n)/sqrt(5));
}
/*               Yhi patak ke chod denge
                 Chal nikal madarch*d                            */

int main()
{
     IOS
     int testcases=1;
     cin>>testcases;
     while(testcases--)
     {
        int n,k;
        cin>>n>>k;
        vector<int> v(n+1);
        int a[n];
        int p,m=0;
        for(int i=0;i<n;i++)
        {
            cin>>p;
            a[i]=p;
            v[p]++;
        }
      /* for(int i=1;i<=n;i++)
       {
           if(v[i]>m)
           {
               m=v[i];
               c=i;
           }
       }*/
      // cout<<c<<" ";
       int ans=1000000;
       for(int c=1;c<=100;c++)
       {
           p=0;
       for(int i=0;i<n;i+=k)
       {
           m=0;
           while( i<n && a[i]==c)
           i++;
           for(int j=i;j<i+k && j<n;j++)
           {
               if(a[j]!=c)
               m=1;
           }
           if(m)
           {
               p++;
           }
       }
       ans=min(ans,p);
       }
       cout<<ans<<endl;

     }
     return 0;
}
//ascii of a=97
//ascii of A=65
//ascii of 0=48
//lower_bound and upper_bound