#include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;
#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#endif
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep2(i, s, n) for (int i = s; i < (int)(n); ++i)
#define Clear(a) a = decltype(a)()
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define vec vector
typedef long long ll;
typedef pair<ll,ll> P;
typedef string::const_iterator state; //構文解析
const double PI=acos(-1);
//const ll big=998244353;
const ll big=1000000007LL;
const ll INF=1e18;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
ll max(ll x,ll y){
    if(x>y)return x;
    else return y;
}
ll min(ll x,ll y){
    if(x<y)return x;
    else return y;
}
ll expm(ll x,ll y,ll mod=big){
    if(y==0)return 1;//0^0=1
    if(x==1||x==0)return x;
    if(y%2==1)return (expm(x,y-1,mod)*x)%mod;
    ll t=expm(x,y/2,mod);
    return (t*t)%mod;
}
ll exp(ll x,ll y){
    if(y==0)return 1;//0^0=1
    if(x==1||y==0)return x;
    if(y%2==1)return exp(x,y-1)*x;
    ll t=exp(x,y/2);
    return t*t;
}
struct unionfind{
    vector<int> par;
    vector<int> high;
    vector<int> size;
    vector<map<int,int>> num;
    unionfind(int n):par(n,-1), high(n,1), size(n,1),num(n){
    }
    int find(const int x){
        if(par[x]==-1)return x;
        return par[x]=find(par[x]);
    }
    void unite(int x,int y){
        x=find(x);
        y=find(y);
        if(x==y)return;
        
        if(high[x]>high[y])swap(x,y);
        if(high[x]==high[y])high[y]++;
        for(auto i:num[x]){//xのグループに属すクラス全部 i.first=class i.secnod=人数
            num[y][i.first]+=i.second;
        }
        par[x]=y;
        size[y]+=size[x];
        return;
    }
    int getsize(const int i){
        return size[find(i)];
    }
    void get(const int m){
        rep(i,m){
            int a,b;cin >> a >> b;
            unite(a-1,b-1);
        }
        return;
    }
};


int main(){
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(10);
    /*--------------------------------*/
    
    int n;cin >> n;
    int q;cin >> q;
    unionfind uf2(n);
    rep(i,n){
        int cl;cin >> cl;
        uf2.num[i][cl-1]=1;
    }
    //各タイミングで,両方で連結しているのを求めないとだめ.
    rep(i,q){
        int com,a,b;cin >> com >> a >> b;
        if(com==1){
            uf2.unite(a-1,b-1);
            //このuniteで,同じクラスかつ連結になった個数を求めたい
        }else{
            a=uf2.find(a-1);
            cout << uf2.num[a][b-1] << '\n';
        }
    }
}
//・printデバッグ消した？・オーバーフローしない？
//・気づいた条件分岐書き忘れてない？.....よし出せ！
#include <bits/stdc++.h>

#define FAST ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
using namespace std;
using ll = long long;

#define N 1005
int dp[N][N];
vector<int> a, b;
int n, m;

int solve(int i, int j) {
    if (i >= n) return abs(m-j);
    if (j >= m) return abs(n-i);

    int& curr = dp[i][j];
    if (curr+1) return curr;
    curr = 1e6;

    curr = min(curr, 1 + solve(i+1, j));
    curr = min(curr, 1 + solve(i, j+1));
    curr = min(curr, 2 + solve(i+1, j+1));

    if (a[i] == b[j]) {
        curr = min(curr, solve(i+1, j+1));
    } else {
        curr = min(curr, 1 + solve(i+1, j+1));
    }

    return curr;
}

int main() {
    FAST;

    memset(dp, -1, sizeof(dp));

    cin >> n >> m;

    a = vector<int>(n);
    b = vector<int>(m);

    int i, j, k, x, y, sz;
    for (i = 0; i < n; ++i) cin >> a[i];
    for (i = 0; i < m; ++i) cin >> b[i];

    if (n < m) {
        swap(n, m);
        swap(a, b);
    }

    cout << solve(0,0);

    return 0;
}

