#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
using namespace std;

template <typename T>
inline void read(T&x){
    x=0; char temp=getchar(); bool f=false;
    while(!isdigit(temp)){if(temp=='-') f=true; temp=getchar();}
    while(isdigit(temp)){x=(x<<1)+(x<<3)+temp-'0'; temp=getchar();}
    if(f) x=-x;
}
template <typename T>
void print(T x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

typedef long long ll;
const int MAXN = 2e5+5;
const ll mod = 998244353;

inline ll ksm(ll base,ll b){
    ll res=1;
    while(b){
        if(b&1) res=res*base%mod;
        base=base*base%mod,b>>=1;
    }
    return res;
}

//basic
int n;

//Union-Find Set
int pre[MAXN],cnt;

inline void Init(){for(register int i=1;i<=n;i++) pre[i]=i;}
int FindRoot(int id){return pre[id]==id? id:pre[id]=FindRoot(pre[id]);}
inline void Unite(int id1,int id2){id1=FindRoot(id1),id2=FindRoot(id2); if(id1!=id2) pre[id2]=id1;}

int main(){
    read(n);
    Init();
    for(register int i=1,x;i<=n;i++) read(x),Unite(i,x);
    for(register int i=1;i<=n;i++) cnt+=(FindRoot(i)==i);
    print((ksm(2,cnt)+mod-1)%mod);
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
#ifdef tabr
#include "library/debug.cpp"
#else
#define debug(...)
#endif

struct dsu {
    vector<int> p;
    vector<int> sz;
    vector<map<int, int>> c;
    int n;

    dsu(int _n) : n(_n) {
        p.resize(n);
        iota(p.begin(), p.end(), 0);
        c.resize(n);
        sz.assign(n, 1);
    }

    inline int get(int x) {
        if (p[x] == x) {
            return x;
        } else {
            return p[x] = get(p[x]);
        }
    }
    inline bool unite(int x, int y) {
        x = get(x);
        y = get(y);
        if (x == y) {
            return false;
        }
        if (sz[x] > sz[y]) {
            swap(x, y);
        }
        p[x] = y;
        sz[y] += sz[x];
        for (auto e : c[x]) {
            c[y][e.first] += e.second;
        }
        return true;
    }
    inline bool same(int x, int y) {
        return (get(x) == get(y));
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, q;
    cin >> n >> q;
    vector<int> c(n);
    dsu uf(n);
    for (int i = 0; i < n; i++) {
        cin >> c[i];
        uf.c[i][c[i]] = 1;
    }
    while (q--) {
        int t, x, y;
        cin >> t >> x >> y;
        if (t == 1) {
            x--, y--;
            uf.unite(x, y);
        } else {
            x--;
            x = uf.get(x);
            cout << uf.c[x][y] << '\n';
        }
    }
    return 0;
}