// Problem: E - Spread of Information
// Contest: AtCoder - AtCoder Regular Contest 116
// URL: https://atcoder.jp/contests/arc116/tasks/arc116_e
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

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

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}

const int N=5e5+5;

int n,m,cnt,f[N],g[N],is[N],head[N],ans,gs;

struct nood
{
	int nex,to;
};
nood e[N*2];

inline void jia(int u,int v)
{
	e[++cnt].nex=head[u];
	head[u]=cnt;
	e[cnt].to=v;
}

inline void dfs(int u,int fa,int x)
{
	f[u]=1e9;
	g[u]=-1e9;
	for ( int i=head[u];i;i=e[i].nex )
	{
		int v=e[i].to;
		if(v==fa) continue;
		dfs(v,u,x);
		f[u]=min(f[v]+1,f[u]);
		g[u]=max(g[v]+1,g[u]);
	}
	if(is[u]&&f[u]>x) g[u]=max(g[u],0);
	if(g[u]+f[u]<=x) g[u]=-1e9;
	if(g[u]==x)
		gs++,g[u]=-1e9,f[u]=0;
}

inline bool check(int mid)
{
	gs=0;
	dfs(1,0,mid);
	gs+=(g[1]>=0);
	return gs<=m;
}

int main()
{
	n=read();
	m=read();
	for ( int i=1;i<=n;i++ ) 
		is[i]=1;
	for ( int i=1;i<n;i++ )
	{
		int x,y;
		x=read(),y=read();
		jia(x,y);
		jia(y,x);
	}
	int l=0,r=n;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	printf("%d\n",ans);
	return 0;
}
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
#define REP(i, n) for(int i=0; i<n; i++)
#define REPi(i, a, b) for(int i=int(a); i<int(b); i++)
#define MEMS(a,b) memset(a,b,sizeof(a))
#define mp make_pair
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
const ll MOD = 1e9+7;

ll C[200100];

class UnionFind{
    public:
        vector<int> par;
        vector<set<int>> child;
        vector<int> rank;
        vector<map<int, int>> num;

        UnionFind(int n){
            child.resize(n);
            num.resize(n);
            for(int i = 0; i < n; i++){
                par.push_back(i);
                rank.push_back(0);
                num[i][C[i]] = 1;
            }
        }

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

        void unite(int x, int y){
            x = find(x);
            y = find(y);
            if(x == y) return;

            if(rank[x] < rank[y]){
                par[x] = y;
                child[y].insert(x);
                for(auto&& p : num[x]){
                    num[y][p.first] += p.second;
                }
            }
            else{
                par[y] = x;
                child[x].insert(y);
                if(rank[x] == rank[y]) rank[x]++;
                for(auto&& p : num[y]){
                    num[x][p.first] += p.second;
                }
            }
        }

        bool same(int x, int y){
            return find(x) == find(y);
        }

        ll get_num(int x, int y){
            x = find(x);
            return num[x][y];
        }
};

int main(){
    ll N, Q;
    cin >> N >> Q;
    REP(i,N){
        ll c;
        cin >> c;
        C[i] = c-1;
    }

    UnionFind uni(N);
    REP(q,Q){
        ll a, x ,y;
        cin >> a >> x >> y;
        x--, y--;
        if(a == 1){
            uni.unite(x, y);
        }
        else{
            ll ans = 0;
            ans = uni.get_num(x, y);
            cout << ans << endl;
        }
    }
    return 0;
}
