// Problem: C - Keep Graph Connected
// Contest: AtCoder - AtCoder Regular Contest 108
// URL: https://atcoder.jp/contests/arc108/tasks/arc108_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long
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 p=998244353;
int qp(int x,int y)
{
	int res=1;
	for(int t=x; y; y>>=1,t=t*t%p) if(y&1) res=res*t%p;
	return res;
}
vector<pair<int,int> > v[100003];
#define pb push_back
#define mp make_pair
#define fi first
#define se second
int a[1000003];
int n=read(),m=read();
void dfs(int x)
{
	for(auto i:v[x]) if(!a[i.fi])
	{
		if(a[x]==i.se) if(a[x]==n)a[i.fi]=1;
		else a[i.fi]=n;
		else a[i.fi]=i.se;
		dfs(i.fi);
	}
	return ;
}
signed main()
{
    if(n==2)
    {
    	puts("1");
    	puts("2");
    	return 0;
    }
    for(int i=1; i<=m; ++i)
    {
    	int x=read(),y=read(),z=read();
    	v[x].pb(mp(y,z)),v[y].pb(mp(x,z));
    }
    a[1]=1;
    dfs(1);
	for(int i=1; i<=n; ++i) printf("%lld\n",a[i]);
	return 0;
}
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<>, rb_tree_tag,tree_order_statistics_node_update>

#define ll long long
#define FOR(i,a,b)  for(ll i=a;i<=b;i++)
#define FORR(i,a,b)  for(ll i=a;i>=b;i--)
#define vl vector<ll>
#define ld long double
#define vld vector<ld>
#define vvl vector<vector<long long>>
#define vvld vector<vector<ld>>
#define pll pair<long,long>
#define vpll vector<pll>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define lb(v,x) lower_bound(v.begin(),v.end(),x)
#define ub(v,x) upper_bound(v.begin(),v.end(),x)
#define d1(x) cout<<(x)<<endl
#define d2(x,y) cout<<(x)<<" "<<(y)<<endl
#define d3(x,y,z) cout<<(x)<<" "<<(y)<<" "<<(z)<<endl
#define d4(a,b,c,d) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<endl
#define PI 3.14159265358979323846264338327950288419716939937510
#define fix(f,n) fixed<<setprecision(n)<<f
#define all(x) x.begin(),x.end()
#define rev(p) reverse(p.begin(),p.end());
#define mset(a,val) memset(a,val,sizeof(a));
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define popcount(x) __builtin_popcountll(x)
#define sz(x) ((ll)x.size())
const ll M = 1000000007;
const ll MM = 998244353;
#define endl "\n"
ll begtime = clock();
#define end_routine() cout << "\n\nTime elapsed: " << (clock() - begtime)*1000/CLOCKS_PER_SEC << " ms\n\n";
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "


template<typename T, typename F>
void chmax( T &a, F b) {
  if (b > a)a = b;
}

template<typename T, typename F>
void chmin( T &a, F b) {
  if (b < a)a = b;
}

ll powM(ll a, ll b, ll m) {
  if (b < 0 || a <= 0)return 0;
  a %= m;
  ll ans = 1LL;
  while (b) {
    if (b & 1)ans = ans * a % m;
    a = a * a % m;
    b >>= 1;
  }
  return ans;
}

ll poww(ll a, ll b) {
  if (b < 0 || a <= 0)return 0;
  ll ans = 1LL;
  while (b) {
    if (b & 1)ans = ans * a;
    a = a * a;
    b >>= 1;
  }
  return ans;
}

const ll N = 2e5 + 5;

map<ll, map<ll, ll>>blah;


ll par[N];

ll find(ll x) {
  if (x == par[x])return x;
  return par[x] = find(par[x]);

}
ll ran[N];

void unio(ll a, ll  b) {
  a = find(a), b = find(b);
  if (a == b)return;
  if (ran[a] < ran[b])swap(a, b);
  ran[a] += ran[b];
  par[b] = a;
  ran[b] = 0;
  for (auto val : blah[b]) {
    blah[a][val.ff] += val.ss;
  }
}


int main() {

  IOS;

#ifndef ONLINE_JUDGE

  freopen("input1.txt", "r", stdin);
  freopen("output1.txt", "w", stdout);

#endif


  ll n, q;
  cin >> n >> q;
  vl c(n + 1);
  FOR(i, 1, n) {
    cin >> c[i];
    blah[i][c[i]]++;
    par[i] = i, ran[i] = 1;
  }

// cout << blah[3][1];




  while (q--) {
    ll type;
    cin >> type;
    ll a, b;
    cin >> a >> b;
    if (type == 1) {
      unio(a, b);
    } else {
      ll papa = find(a);
      ll ans = blah[papa][b];
      cout << ans << endl;
    }
  }



  return 0;

}
