#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <tuple>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <random>
#include <set>
#include <stack>
#include <time.h>
#include <unordered_map>

//#include <bits/stdc++.h>
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define repr(i, n) for (int i = (n) - 1; i >= 0; i--)
#define FOR(i,i0,n) for(int (i)=(i0);(i)<(n);(i)++)
#define FORR(i,i0,n) for(int (i)=(n)-1; (i)>=(i0);(i)--)
#define SORT(x) sort(x.begin(),x.end())
#define SORTR(x) sort(x.begin(),x.end(),greater<int>())

#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple

using namespace std;
using ll = long long;
typedef std::pair<int, int> pii;
typedef std::pair<int, double> pid;
typedef std::vector<int> vi;
typedef std::vector<pii> vii;
#define PI 3.14159265358979323846264338327950L

const int mod = 1000000007;


struct container{
    int bottom, top, id;
    container(int id, int bottom, int top): top(top), bottom(bottom),id(id){
    }
};


struct Data {
    int ind;
    ll time;
    Data(int ind,ll time): ind(ind),time(time){}
    bool operator<(const Data& a) const {
    return time > a.time;
    }
};





class UnionFind{
public:
    int uf[200005];
    
    unordered_map<int,unordered_map<int,int>> kids;
    
    UnionFind(vector<int>& a){
        int n = a.size();
        memset(uf,-1,sizeof uf);
        
        for(int i = 0; i < n; i++){
            kids[i+1][a[i]] = 1;
        }
    }
    
    int parent(int i){
        if (uf[i] < 0) return i;
        return uf[i] = parent(uf[i]);
    }
    
    void join(int i, int j){
        int pi = parent(i);
        int pj = parent(j);
        if (pi == pj) return;
        if (size(pi) < size(pj)) swap(pi,pj);
        for(auto e: kids[pj]){
            kids[pi][e.first] += e.second;
        }
        uf[pi] += uf[pj];
        uf[pj] = pi;
        
    }
    
    int size(int i){
        int pi = parent(i);
        return abs(uf[pi]);
    }
    
    void init(){
        memset(uf,-1,sizeof uf);
    }
};



void solve(){
    int n,q;
    cin >> n >> q;
    
    
    vector<int> c(n);
    rep(i,n) cin >> c[i];
    UnionFind uf(c);
    
    rep(i,q){
        int t;
        cin >> t;
        if (t==1){
            int a,b;
            cin >> a >> b;
            uf.join(a,b);
        }
        else{
            int x,y;
            cin >> x >> y;
            int p = uf.parent(x);
            cout << uf.kids[p][y] << endl;
        }
    }
    
}





int main() {
    int T = 1;
    //cin >> T;
    
    while (T--){
        solve();
        cout << endl;
    }
}





 
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> p_ll;

template<class T>
void debug(T itr1, T itr2) { auto now = itr1; while(now<itr2) { cout << *now << " "; now++; } cout << endl; }
#define repr(i,from,to) for (ll i=(ll)from; i<(ll)to; i++)
#define all(vec) vec.begin(), vec.end()
#define rep(i,N) repr(i,0,N)
#define per(i,N) for (ll i=(ll)N-1; i>=0; i--)
#define popcount __builtin_popcount

const ll LLINF = pow(2,61)-1;
const ll INF = pow(2,30)-1;

ll gcd(ll a, ll b) { if (a<b) swap(a,b); return b==0 ? a : gcd(b, a%b); }
ll lcm(ll a, ll b) { return a/gcd(a,b)*b; }
ll modpow(ll x, ll p, ll m) { ll result = 1, now = 1, pm = x; while (now<=p) { if (p&now) { result = result * pm % m; } now*=2; pm = pm*pm % m; } return result; }

int main() {
  ll A, B, C; cin >> A >> B >> C;
  ll bc = modpow(B,C,4); if (bc==0) bc = 4;
  ll abc = modpow(A,bc,10);
  cout << abc << endl;
  return 0;
}