Problem: Take the'IOI'train

A new railway has been laid in IOI. Trains running on railways in IOI are a combination of several vehicles, and there are two types of vehicles, I and O. Vehicles can only be connected to different types of vehicles. Also, because the train has a driver's seat, the cars at both ends of the train must be of type I. A train is represented by a character string in which characters indicating the type of vehicle are connected in order, and the length of the train is assumed to be the length of the character string. For example, if vehicles are connected in the order of IOIOI, a train with a length of 5 can be formed, and vehicle I is a train with a length of 1 alone. Trains cannot be formed by arranging vehicles in the order of OIOI or IOOI.

Some vehicles are stored in two garages. Vehicles are lined up in a row in each garage. When forming a train, take out the train from the garage and connect it in front of the garage. Only the vehicle closest to the entrance of the garage can be taken out of the garage, but the order of taking out the vehicle from which garage is arbitrary.

Before forming a train, you can take as many cars out of the garage as you like and move them to another waiting rail. Vehicles that have been moved to the standby rails cannot be used to organize trains in the future. Also, once the train formation is started, the vehicle cannot be moved from the garage to the standby rail until the formation is completed.

When organizing a train, it is not necessary to use up all the cars in the garage. That is, after the train formation is completed, unused cars may remain in the garage.

It is believed that there are so many people on the railroad in IOI, so I want to organize the longest possible train.

<image>


Figure: The train is being organized, and the vehicle in the garage cannot be moved to the standby rail at this time. This figure corresponds to I / O example 1.

Task

Create a program to find the maximum length of trains that can be organized given the information of the cars stored in the garage. The row of vehicles stored in each garage is represented by a string consisting of only two types of letters I and O, and the information in the two garages is represented by the string S of length M and the string T of length N, respectively. Given. Each letter represents one vehicle, the letter of which is the same as the type of vehicle. The first letter of the string represents the vehicle closest to the entrance to the garage, and the last letter represents the vehicle closest to the garage.

Limits

* 1 ≤ M ≤ 2000 Length of string S
* 1 ≤ N ≤ 2000 Length of string T



input

Read the following data from standard input.

* In the first line, M and N are written separated by blanks.
* The character string S is written on the second line.
* The character string T is written on the third line.



output

Output an integer representing the maximum train length that can be organized to the standard output on one line. If no train can be organized, output 0.

Input / output example

Input example 1


5 5
OIOOI
OOIOI


Output example 1


7


Let the garage represented by S be the garage S and the garage represented by T be the garage T. At this time, for example, the first vehicle from the garage S, the first two vehicles from the garage T are put out and put on standby, and then the garage S, the garage S, the garage T, the garage S, the garage S, the garage T, and the garage T are placed in this order. If you take out the vehicle, you can form a train IOIOIOI with a length of 7.

In addition, after the first vehicle from garage S and the first two vehicles from garage T are put out and put on standby, the order is garage T, garage T, garage S, garage S, garage T, garage S, and garage S. You can also organize a 7-length train by putting out a vehicle. Since it is not possible to form a train longer than this, 7 is output.




Input example 2


5 9
IIIII
IIIIIIIII


Output example 2


1


Note that train I, which consists of only one car, also meets the conditions for a train.

The question text and the data used for the automatic referee are the question text and the test data for scoring, which are created and published by the Japan Committee for Information Olympics.





Example

Input

5 5
OIOOI
OOIOI


Output

7

Solution (in CPP):

Solution:
   #include <bits/stdc++.h>
 
//    #include <boost/multiprecision/cpp_int.hpp>
 #define int long long
 #define inf  1000000007
 #define pa pair<int,int>
 #define ll long long
 #define pal pair<double,double>
 #define ppap pair<pa,int>
  #define PI 3.14159265358979323846
  #define paa pair<int,char>
  #define  mp make_pair
  #define  pb push_back
  #define EPS (1e-8)
                                          
    int dx[8]={0,1,0,-1,1,1,-1,-1};
    int dy[8]={1,0,-1,0,-1,1,1,-1};
                                            using namespace std;
                                   			class pa3{
                                            	public:
                                            	int x;
                                   				int y,z;
                                            	pa3(int x=0,int y=0,int z=0):x(x),y(y),z(z) {}
                                            	bool operator < (const pa3 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		 return z<p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                   				bool operator > (const pa3 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		 return z>p.z;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa3 &p) const{
                                            		return x==p.x && y==p.y && z==p.z;
                                            	}
                                            		bool operator != (const pa3 &p) const{
                                            			return !( x==p.x && y==p.y && z==p.z);
                                            	}
                                            
                                            };
                                            
                                            class pa4{
                                            	public:
                                            	int x;
                                            	int y,z,w;
                                            	pa4(int x=0,int y=0,int z=0,int w=0):x(x),y(y),z(z),w(w) {}
                                            	bool operator < (const pa4 &p) const{
                                            		if(x!=p.x) return x<p.x;
                                            		if(y!=p.y) return y<p.y;
                                            		if(z!=p.z)return z<p.z;
                                            		return w<p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator > (const pa4 &p) const{
                                            		if(x!=p.x) return x>p.x;
                                            		if(y!=p.y) return y>p.y;
                                            		if(z!=p.z)return z>p.z;
                                            		return w>p.w;
                                            		//return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa4 &p) const{
                                            		return x==p.x && y==p.y && z==p.z &&w==p.w;
                                            	}
                                            		
                                            
                                            };
                                            class pa2{
                                            	public:
                                            	int x,y;
                                            	pa2(int x=0,int y=0):x(x),y(y) {}
                                            	pa2 operator + (pa2 p) {return pa2(x+p.x,y+p.y);}
                                            	pa2 operator - (pa2 p) {return pa2(x-p.x,y-p.y);}
                                            	bool operator < (const pa2 &p) const{
                                            		return y != p.y ? y<p.y: x<p.x;
                                            	}
                                            	bool operator > (const pa2 &p) const{
                                            		return x != p.x ? x<p.x: y<p.y;
                                            	}
                                            	bool operator == (const pa2 &p) const{
                                            		return abs(x-p.x)==0 && abs(y-p.y)==0;
                                            	}
                                            	bool operator != (const pa2 &p) const{
                                            		return !(abs(x-p.x)==0 && abs(y-p.y)==0);
                                            	}
                                            		
                                            
                                            };
                                            
 
                      
                                string itos( int i ) {
                                ostringstream s ;
                                s << i ;
                                return s.str() ;
                                }
                                 
                                int gcd(int v,int b){
                                	if(v==0) return b;
                                	if(b==0) return v;
                                	if(v>b) return gcd(b,v);
                                	if(v==b) return b;
                                	if(b%v==0) return v;
                                	return gcd(v,b%v);
                                }
                 
                            
                                int mod;
int extgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    int d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
pa operator+(const pa & l,const pa & r) {   
    return {l.first+r.first,l.second+r.second};                                    
}    
pa operator-(const pa & l,const pa & r) {   
    return {l.first-r.first,l.second-r.second};                                    
}  
                                
                int pr[10000100];
                int inv[10000010];
                
                int beki(int wa,int rr,int warukazu){
                	if(rr==0) return 1%warukazu;
                	if(rr==1) return wa%warukazu;
                	wa%=warukazu;
                	if(rr%2==1) return ((ll)beki(wa,rr-1,warukazu)*(ll)wa)%warukazu;
                	ll zx=beki(wa,rr/2,warukazu);
                	return (zx*zx)%warukazu;
                }
 
                
    			int comb(int nn,int rr){
    				if(rr<0 || rr>nn || nn<0) return 0;
    				int r=pr[nn]*inv[rr];
    				r%=mod;
    				r*=inv[nn-rr];
    				r%=mod;
    				return r;
    			}
               
                void gya(int ert){
                	pr[0]=1;
                	for(int i=1;i<=ert;i++){
                		pr[i]=(pr[i-1]*i)%mod;
                	}
                		inv[ert]=beki(pr[ert],mod-2,mod);
                	for(int i=ert-1;i>=0;i--){
                		inv[i]=inv[i+1]*(i+1)%mod;
                	}
                }
                
              //   cin.tie(0);
    		//	ios::sync_with_stdio(false);
    			//priority_queue<pa3,vector<pa3>,greater<pa3>> pq;            
                 //sort(ve.begin(),ve.end(),greater<int>());
 //   mt19937(clock_per_sec);
  //  mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()) ;
      
       



int dp[2020][2020][2]={};


int l1,l2;
string s,t;
int solve(int x,int y,int d){
	if(dp[x][y][d]>=0) return dp[x][y][d];
	int p=0;
	if(d==0){
		if(x!=l1 && s[x]=='O')p=max(p,solve(x+1,y,1)+1);
		if(y!=l2 && t[y]=='O')p=max(p,solve(x,y+1,1)+1);
		
	}
	else{
		if(x!=l1 && s[x]=='I')p=max(p,solve(x+1,y,0)+1);
		if(y!=l2 && t[y]=='I')p=max(p,solve(x,y+1,0)+1);		
	}
	dp[x][y][d]=p;
	return p;
}

signed main(){
	
	
   cin.tie(0);
	ios::sync_with_stdio(false);

	//int l1,l2;
	cin>>l1>>l2;
	//string s,t;
	cin>>s>>t;
	
	for(int i=0;i<=l1;i++)for(int j=0;j<=l2;j++){
		dp[i][j][0]=-1;
		dp[i][j][1]=-1;
		
	}
	dp[l1][l2][0]=0;
	dp[l1][l2][1]=0;
	
	int ans=0;
	for(int i=0;i<=l1;i++)for(int j=0;j<=l2;j++){
		ans=max(ans,solve(i,j,1));
		solve(i,j,0);
	}
	
	if(ans>0 && ans%2==0)ans--;
	cout<<ans<<endl;
	
	return 0;
	

 
 }