#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "math.h"
#include "utility"
#include "string"
#include "map"
#include "unordered_map"
#include "iomanip"
#include "random"

using namespace std;
const long long int MOD = 1000000007;

int N, M;
string S;
string T;
int dp[2002][2002][2];
int ans;

int main() {
	ios::sync_with_stdio(false);
	cin >> N >> M;
	cin >> S;
	cin >> T;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			dp[i][j][0] = -1;
			dp[i][j][1] = -1;
		}
	}
	reverse(S.begin(), S.end());
	reverse(T.begin(), T.end());
	//cout << S << endl;
	//cout << T << endl;
	S = '(' + S;
	T = 'T' + T;
	if (S[1] == 'I')dp[1][0][1] = 1;
	if (T[1] == 'I')dp[0][1][1] = 1;
	for (int i = 1; i < N + M; i++) {
		for (int j = max(0, i - M); j <= min(i, N); j++) {
			//	cout << i << " " << j << endl;
			if (S[j + 1] == 'O')dp[j + 1][i - j][0] = max({ dp[j + 1][i - j][0], dp[j][i - j][1] + 1 ,0 });
			else dp[j + 1][i - j][1] = max({ 1, dp[j + 1][i - j][1], dp[j][i - j][0] + 1 });
			if (T[i - j + 1] == 'O')dp[j][i - j + 1][0] = max({ dp[j][i - j + 1][0], dp[j][i - j][1] + 1 ,0 });
			else dp[j][i - j + 1][1] = max({ 1, dp[j][i - j + 1][1] ,dp[j][i - j][0] + 1 });
		}
	}
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= M; j++) {
			ans = max(ans, dp[i][j][1]);
		}
	}
	cout << ans << endl;
	return 0;
}