//#include <atcoder/all>
#include <bits/stdc++.h>
#include <cassert>
#include <numeric>
using namespace std;
//using namespace atcoder;
typedef  long long LONG;
const int MOD = 1000000007;



int gcd(int x, int y) {
	if (x % y == 0) {
		return y;
	}
	else {
		return gcd(y, x % y);
		//x%y==0でないときはユーグリットの互除法を使って再帰的に関数を呼び出す。
	}
}
LONG pow2(long long x, long long n) {
	long long ret = 1;
	while (n > 0) {
		if (n & 1) ret = ret * x % MOD;  // n の最下位bitが 1 ならば x^(2^i) をかける
		x = x * x % MOD;
		n >>= 1;  // n を1bit 左にずらす
	}
	return (int)ret;
}
void printVector(const vector<int>& vec) {
	for (int value : vec) {
		cout << value << " ";
	}
	cout << endl;
}
int count(vector<int>&a, int s) {
	int result = 0;
	for (int i = 0; i < a.size(); i++) {
		if (a[i] == s) {
			result++;
		}
	}
	return result;
}

LONG kaizyo(int N) {
	LONG result = 1;
	LONG mod = 998244353;

	for (LONG i = 2; i <= N; i++) {
		result *= i;
		result = result % mod;
	}
	return result;
}
class Point {
public:
	int x;
	int y;
};
LONG stock[3500][3500];
LONG test(int N, int task) {
	LONG mod = 998244353;
	if (N < task)return 0;
	if (N < 0)return 0;
	if (task == 0) {
		if (N == 0) {
			return 1;
		}
		else {
			return 0;
		}

	}


	if (stock[N][task] > 0)return stock[N][task];
	stock[N][task] = (test(N - 1, task - 1) + test(N, task * 2)) % mod;

	return stock[N][task] % mod;
}
class DP {
public:
	DP() {

	}
	DP(int a, int b) {
		other = a;
		path = b;

	}
	int other;
	int path;
};

void dp(vector<vector<DP>>& list, vector<int> &able, int pos, int limit) {
	for (int i = 0; i < list[pos].size(); i++) {
		if (list[pos][i].path <= limit) {
			if (able[list[pos][i].other] == 0) {
				able[list[pos][i].other] = 1;
				dp(list, able, list[pos][i].other, limit);
			}
		}
	}
}
LONG max(deque<LONG>q) {
	LONG r = -1;
	for (int i = 0; i < q.size(); i++) {
		if (r < q[i]) {
			r = q[i];
		}
	}
	return r;
}
LONG min(deque<LONG>q) {
	LONG r = LLONG_MAX;
	for (int i = 0; i < q.size(); i++) {
		if (r > q[i]) {
			r = q[i];
		}
	}
	return r;
}
LONG P(int N,int k) {
	LONG result = 1;
	for (int i = N; i >N-k; i--) {
		result *= i;
	}
	return result;
}
LONG P2(int N, int k,LONG A) {
	LONG result = 1;
	for (int i = N; i > N - k; i--) {
		result *= i;
		int a = gcd(result, A);
		result /= a;
		A /= a;
	}
	return result;
}
int main() {
	int N, M;
	cin >> N >> M;
	vector<int>A(N);
	vector<int>B(M);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	for (int i = 0; i < M; i++) {
		cin >> B[i];
	}
	vector<vector<int>>T(N + 1, vector<int>(M + 1));
	for (int i = 0; i < N + 1;i++) {
		T[i][0] = i;
	}
	for (int i = 0; i < M + 1; i++) {
		T[0][i] = i;
	}
	for (int i = 1; i < N + 1; i++) {
		for (int j = 1; j < M + 1; j++) {
			int a = T[i - 1][j]+1;
			a = min(a, T[i][j - 1]+1);
			int b = 0;
			if (A[i-1] != B[j-1]) {
				b++;
			}
			a = min(a, T[i - 1][j - 1] + b);
			T[i][j] = a;
		}
	}
	cout << T[N][M];
	return 0;


}
#include <algorithm>
#include <iostream>
#include <vector>

#include <string.h>
#include <limits.h>

using namespace std;

typedef long long ll;

template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const int MAX_S = 1000;

int dp[MAX_S + 1][MAX_S + 1];

int solve(const vector<int> &s1, const int l1, const vector<int> &s2, const int l2) {
    for (int i = 0; i <= l1; i++) {
        dp[i][0] = i;
        for (int j = 1; j <= l2; j++) {
            if (i == 0) {
                dp[i][j] = j;
                continue;
            }
            if (s1[i - 1] == s2[j - 1]) {
                chmin(dp[i][j], dp[i - 1][j - 1]);
            } else {
                chmin(dp[i][j], dp[i - 1][j - 1] + 1);
            }
            chmin(dp[i][j], dp[i - 1][j] + 1);
            chmin(dp[i][j], dp[i][j - 1] + 1);
        }
    }
    return dp[l1][l2];
}

vector<int> as;
vector<int> bs;

int main(void) {
    int N, M;
    cin >> N >> M;

    as.resize(N);
    for (int i = 0; i < N; i++) {
        cin >> as[i];
    }

    bs.resize(M);
    for (int i = 0; i < M; i++) {
        cin >> bs[i];
    }

    reverse(as.begin(), as.end());
    reverse(bs.begin(), bs.end());

    for (int i = 0; i < MAX_S + 1; i++) {
        for (int j = 0; j < MAX_S + 1; j++) {
            dp[i][j] = INT_MAX / 2;
        }
    }

    if (N < M) {
        cout << solve(as, N, bs, M) << endl;
    } else {
        cout << solve(bs, M, as, N) << endl;
    }
    
    return 0;
}
