#include"bits/stdc++.h"
using namespace std; 
#define pb push_back
#define eb emplace_back
#define ins insert
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define repr(i,a,b) for(int i=a;i>=b;i--)
#define lb lower_bound
#define ub upper_bound
#define sz(x) (int)x.size()
#define pii pair<int,int>
#define fir first
#define sec second
#define popcount __builtin_popcount 
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using ll=long long int;
using ld=long double;
#define mp make_pair
#define mt make_tuple
#define bit(x,j) (((ll)x>>j)&1)
#define um unordered_map 
#define mem(a,val) memset(a,val,sizeof(a))
void __print(int x) {cerr << x;} 
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;} 
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x){cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;} 
void __print(double x) {cerr << x;}
void __print(ld x){cerr << x;} 
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x){cerr<<'\"'<<x<<'\"';}
void __print(const string &x) {cerr<<'\"'<<x<<'\"';}
void __print(bool x){cerr<<(x?"true":"false");}
template<typename T, typename V>
void __print(const pair<T, V> &x){cerr<<'{'; __print(x.first);cerr<<','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) 
{ return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";}
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) 
{ return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")"; } 
void debug_out() { cerr << endl; } 
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) 
{
  cerr << " " << to_string(H);
  debug_out(T...);
}
#ifndef ONLINE_JUDGE 
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
#ifndef ONLINE_JUDGE 
#define debugt(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debugt(...) 42
#endif
constexpr ll inf=2223372036854775807;
constexpr int mod1=(1e9+7);
constexpr int mod2=(998244353);
constexpr int MAX=(1e4+3); 
constexpr int N=2e5+5; 
void solve()
{
 string s; cin>>s; int cnt=0;  
 for(int i=0;i<=8;i++)
 {
   if(s[i]=='Z' and s[i+1]=='O' and s[i+2]=='N' and s[i+3]=='e') cnt++; 
 }
 cout<<cnt<<"\n"; 
}
int main()
{
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  #endif   
  ios_base::sync_with_stdio(false);
  cin.tie(0); 
  int t=1; int c=1; 
  while(t--)
  { 
    solve(); c++; 
  }  
}
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, q;
    cin >> n >> q;

    vector<int> studentClass(n + 1);
    vector<int> nodeParent(n + 1);
    vector<int> nodeRank(n + 1);
    vector< vector<int> > classStudents(n + 1); // position of students belonging to this class

    for (int i = 1; i <= n; ++i) {
        cin >> studentClass[i];

        classStudents[studentClass[i]].push_back(i);

        nodeParent[i] = i;
        nodeRank[i] = 1;
    }

    const int SQ = sqrt(n + .0);
    int bigClassesCount = 0;
    vector<int> classPosition(n + 1);

    for (int i = 1; i <= n; ++i) {
        if (classStudents[i].size() >= SQ) {
            classPosition[i] = bigClassesCount;
            ++bigClassesCount;
        }
    }

    vector< vector<int> > nodeData(n + 1, vector<int>(bigClassesCount));
    for (int i = 1; i <= n; ++i) {
        if (classStudents[studentClass[i]].size() >= SQ) {
            nodeData[i][classPosition[studentClass[i]]] = 1;
        }
    }

    // dsu stuff
    function<int(int)> findParent = [&nodeParent, &findParent](int node)->int {
        if (nodeParent[node] == node) {
            return node;
        }
        else {
            return nodeParent[node] = findParent(nodeParent[node]);
        }
    };

    // dsu stuff
    auto mergeNodes = [&nodeParent, &nodeRank, &findParent, &nodeData, &bigClassesCount](int firstNode, int secondNode) {
        int firstParent = findParent(firstNode);
        int secondParent = findParent(secondNode);

        if (firstParent == secondParent) {
            return;
        }

        if (nodeRank[firstParent] > nodeRank[secondParent]) {
            swap(firstParent, secondParent);
        }
        else if (nodeRank[firstParent] == nodeRank[secondParent]) {
            ++nodeRank[secondParent];
        }

        for (int i = 0; i < bigClassesCount; ++i) {
            nodeData[secondParent][i] += nodeData[firstParent][i];
        }

        nodeParent[firstParent] = secondParent;
    };

    while (q--) {
        int op;
        cin >> op;

        if (op == 1) {
            int a, b;
            cin >> a >> b;

            mergeNodes(a, b);
        }
        else {
            int x, y;
            cin >> x >> y;

            if (classStudents[y].size() < SQ) {
                int answer = 0;
                for (int i = 0; i < classStudents[y].size(); ++i) {
                    int studentIndex = classStudents[y][i];
                    answer += (findParent(studentIndex) == findParent(x));
                }

                cout << answer << "\n";
            }
            else {
                int groupParent = findParent(x);
                cout << nodeData[groupParent][classPosition[y]] << "\n";
            }
        }
    }

    return 0;
}
