#include<bits/stdc++.h>
#define ll long long int
#define pb push_back
#define ff first
#define ss second
#define mp make_pair
#define inf 100000000000000LL
#define fast_io ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
#define mod 1000000007
#define range 1000000
#define lg 22
#define range2 1000000000
#define pp pair<ll,ll>
//#define endl "\n"
using namespace std;
string s1,s2;
ll dp[ 5001 ] [ 5001 ] [ 2 ] [ 2 ] ;
//ll dp[p1][p2][f][k]-> p1, p2 is index of string s1,s2 respectcivegly, f-> 0 matlab abhi tak ek bhi add nhi kiya char-> 1 matlab ek daal diya // aur 1 daalna zaruri h. k-> [0]->max length ab tak, [1] -> uska count ab tak
pp calc( ll p1,ll p2,ll f) //returns (new_max_len,count)
{
if ( p1== - 1 || p2== - 1 )
{
pp x;
x.ff = 0 ,x.ss = 0 ; // by default if boo criteria satisfy toh count and len 0,
if ( f== 1 ) // agar ek char daal liya toh count=1 return //self explanatory
x= mp( 0 ,1 ) ;
else
if ( p1== - 1 && p2! = - 1 ) // manlo ki s1 khatam ho gya , par s2 k kuch character bache h-> aur f=0 h, toh ek char add kr skte h-> one of any of those left hence count= p2+1, max_len=1 coz 1 char le liya LCS mein
x= mp( 1 ,p2+ 1 ) ;
return x;
// cout<<p1<<" "<<p2<<" "<<f<<" "<<x.ff<<" "<<x.ss<<endl;
}
if ( dp[ p1] [ p2] [ f] [ 1 ] ! = - 1 )
return mp( dp[ p1] [ p2] [ f] [ 0 ] ,dp[ p1] [ p2] [ f] [ 1 ] ) ;
pp x1,x2,x3,ans;
ll xn;
x1.ff = x2.ff = x3.ff = ans.ff = 0 ;
x1.ss = x2.ss = x3.ss = ans.ss = 0 ;
if ( s1[ p1] == s2[ p2] )
{
x1= calc( p1- 1 ,p2- 1 ,f) ; // normal jaisa hota same h toh length+1
x1.ff ++ ;
if ( f< 1 ) // special case// agar naya char s1 ke p1 k right mein daal diya aur use aur s2[p2] ko le lia
{
x2= calc( p1,p2- 1 ,f+ 1 ) ; // toh p1 vaisa hi rahega, p2-1 ho jaega
x2.ff ++ ; // coz humne s2[p2] ko match kara diya inserted char se toh length+1 ho gyi
}
xn= max( x1.ff ,x2.ff ) ; // max length ab tak kitni h?
ans.ff = xn;
// jis jis ki uske equal h, unke counts add karlo
if ( xn== x1.ff )
ans.ss + = x1.ss ;
if ( xn== x2.ff )
ans.ss + = x2.ss ;
}
else
{
x1= calc( p1- 1 ,p2,f) ; // normal
x2= calc( p1,p2- 1 ,f) ; // normal
if ( f< 1 ) // special case// agar naya char s1 ke p1 k right mein daal diya aur use aur s2[p2] ko le lia
{
x3= calc( p1,p2- 1 ,f+ 1 ) ; // toh p1 vaisa hi rahega, p2-1 ho jaega
x3.ff ++ ; // coz humne s2[p2] ko match kara diya inserted char se toh length+1 ho gyi
}
// max length ab tak kitni h?
xn= max( x1.ff ,max( x2.ff ,x3.ff ) ) ;
ans.ff = xn;
// jis jis ki uske equal h, unke counts add karlo
if ( xn== x1.ff )
ans.ss + = x1.ss ;
if ( xn== x2.ff )
ans.ss + = x2.ss ;
if ( xn== x3.ff )
ans.ss + = x3.ss ;
// cout<<xn<<endl;
// cout<<p1<<" "<<p2<<" "<<f<<" x1 "<<x1.ff<<" "<<x1.ss<<endl;
// cout<<p1<<" "<<p2<<" "<<f<<" x2 "<<x2.ff<<" "<<x2.ss<<endl;
// cout<<p1<<" "<<p2<<" "<<f+1<<" x3 "<<x3.ff<<" "<<x3.ss<<endl;
// cout<<p1<<" "<<p2<<" "<<f<<" x4 "<<ans.ff<<" "<<ans.ss<<endl;
}
// cout<<p1<<" "<<p2<<" "<<f<<" "<<ans.ff<<" "<<ans.ss<<endl;
// inka pair bana k store karlo
dp[ p1] [ p2] [ f] [ 0 ] = ans.ff ;
dp[ p1] [ p2] [ f] [ 1 ] = ans.ss ;
return mp( ans.ff ,ans.ss ) ;
}
int main( )
{
ll n1,n2;
memset ( dp,- 1 ,sizeof ( dp) ) ;
cin >> s1>> s2;
n1= s1.length ( ) - 1 ;
n2= s2.length ( ) - 1 ;
pp x= calc( n1,n2,0 ) ;
// cout<<x.ff<<" "<<x.ss<<endl;
cout << x.ss << endl;
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI2RlZmluZSBsbCAgIGxvbmcgbG9uZyBpbnQKI2RlZmluZSBwYiBwdXNoX2JhY2sKI2RlZmluZSBmZiBmaXJzdAojZGVmaW5lIHNzIHNlY29uZAojZGVmaW5lIG1wIG1ha2VfcGFpcgojZGVmaW5lIGluZiAxMDAwMDAwMDAwMDAwMDBMTAojZGVmaW5lIGZhc3RfaW8JaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7IGNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpCiNkZWZpbmUgbW9kIDEwMDAwMDAwMDcgCiNkZWZpbmUgcmFuZ2UgMTAwMDAwMAojZGVmaW5lIGxnIDIyCiNkZWZpbmUgcmFuZ2UyIDEwMDAwMDAwMDAKI2RlZmluZSBwcCBwYWlyPGxsLGxsPgovLyNkZWZpbmUgZW5kbCAiXG4iCgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKc3RyaW5nIHMxLHMyOwpsbCBkcFs1MDAxXVs1MDAxXVsyXVsyXTsKLy9sbCBkcFtwMV1bcDJdW2ZdW2tdLT4gcDEsIHAyIGlzIGluZGV4IG9mIHN0cmluZyBzMSxzMiByZXNwZWN0Y2l2ZWdseSwgZi0+IDAgbWF0bGFiIGFiaGkgdGFrIGVrIGJoaSBhZGQgbmhpIGtpeWEgY2hhci0+IDEgbWF0bGFiIGVrIGRhYWwgZGl5YSAvLyBhdXIgMSBkYWFsbmEgemFydXJpIGguIGstPiBbMF0tPm1heCBsZW5ndGggYWIgdGFrLCBbMV0gLT4gdXNrYSBjb3VudCBhYiB0YWsKCiAKcHAgY2FsYyhsbCBwMSxsbCBwMixsbCBmKQkJLy9yZXR1cm5zIChuZXdfbWF4X2xlbixjb3VudCkKewoJCgkKCWlmKHAxPT0tMXx8cDI9PS0xKQoJewoJCXBwIHg7CgkJeC5mZj0wLHguc3M9MDsgLy8gYnkgZGVmYXVsdCBpZiBib28gY3JpdGVyaWEgc2F0aXNmeSB0b2ggY291bnQgYW5kIGxlbiAwLAoJCQoJCWlmKGY9PTEpIC8vIGFnYXIgZWsgY2hhciBkYWFsIGxpeWEgdG9oIGNvdW50PTEgcmV0dXJuIC8vc2VsZiBleHBsYW5hdG9yeQoJCXg9IG1wKDAsMSk7CgkJZWxzZQoJCWlmKHAxPT0tMSYmcDIhPS0xKSAvLyBtYW5sbyBraSBzMSBraGF0YW0gaG8gZ3lhICwgcGFyIHMyIGsga3VjaCBjaGFyYWN0ZXIgYmFjaGUgaC0+IGF1ciBmPTAgaCwgdG9oIGVrIGNoYXIgYWRkIGtyIHNrdGUgaC0+IG9uZSBvZiBhbnkgb2YgdGhvc2UgbGVmdCBoZW5jZSBjb3VudD0gcDIrMSwgbWF4X2xlbj0xIGNveiAxIGNoYXIgbGUgbGl5YSBMQ1MgbWVpbgoJCQl4PSBtcCgxLHAyKzEpOwoJCgkJcmV0dXJuIHg7Ci8vCQljb3V0PDxwMTw8IiAiPDxwMjw8IiAiPDxmPDwiCSI8PHguZmY8PCIgIjw8eC5zczw8ZW5kbDsKCQkKCQkKCX0KCWlmKGRwW3AxXVtwMl1bZl1bMV0hPS0xKQoJcmV0dXJuIG1wKGRwW3AxXVtwMl1bZl1bMF0sZHBbcDFdW3AyXVtmXVsxXSk7CglwcCB4MSx4Mix4MyxhbnM7CglsbCB4bjsJCgoJeDEuZmY9eDIuZmY9eDMuZmY9YW5zLmZmPTA7Cgl4MS5zcz14Mi5zcz14My5zcz1hbnMuc3M9MDsKCWlmKHMxW3AxXT09czJbcDJdKQoJewoJCXgxPWNhbGMocDEtMSxwMi0xLGYpOyAvLyBub3JtYWwgamFpc2EgaG90YSBzYW1lIGggdG9oIGxlbmd0aCsxCgkJeDEuZmYrKzsKCQkKCQlpZihmPDEpIC8vIHNwZWNpYWwgY2FzZS8vIGFnYXIgbmF5YSBjaGFyIHMxIGtlIHAxIGsgcmlnaHQgbWVpbiBkYWFsIGRpeWEgYXVyIHVzZSBhdXIgczJbcDJdIGtvIGxlIGxpYQoJCXsKCQkJeDI9Y2FsYyhwMSxwMi0xLGYrMSk7Ly8gdG9oIHAxIHZhaXNhIGhpIHJhaGVnYSwgcDItMSBobyBqYWVnYQoJCQl4Mi5mZisrOyAvLyBjb3ogaHVtbmUgczJbcDJdIGtvIG1hdGNoIGthcmEgZGl5YSBpbnNlcnRlZCBjaGFyIHNlIHRvaCBsZW5ndGgrMSBobyBneWkKCQl9CgkJCgkJCgkJCgkJeG49bWF4KHgxLmZmLHgyLmZmKTsgLy8gbWF4IGxlbmd0aCBhYiB0YWsga2l0bmkgaD8KCQlhbnMuZmY9eG47CgkJLy8gamlzIGppcyBraSB1c2tlIGVxdWFsIGgsIHVua2UgY291bnRzIGFkZCBrYXJsbwoJCWlmKHhuPT14MS5mZikKCQlhbnMuc3MrPXgxLnNzOwoJCQoJCWlmKHhuPT14Mi5mZikKCQlhbnMuc3MrPXgyLnNzOwoJCQoJfQoJZWxzZQoJewoJCXgxPWNhbGMocDEtMSxwMixmKTsgLy8gbm9ybWFsCgkJeDI9Y2FsYyhwMSxwMi0xLGYpOyAvLyBub3JtYWwKCQkKCQlpZihmPDEpIC8vIHNwZWNpYWwgY2FzZS8vIGFnYXIgbmF5YSBjaGFyIHMxIGtlIHAxIGsgcmlnaHQgbWVpbiBkYWFsIGRpeWEgYXVyIHVzZSBhdXIgczJbcDJdIGtvIGxlIGxpYQoJCXsKCQkJeDM9Y2FsYyhwMSxwMi0xLGYrMSk7IC8vIHRvaCBwMSB2YWlzYSBoaSByYWhlZ2EsIHAyLTEgaG8gamFlZ2EKCQkJeDMuZmYrKzsgLy8gY296IGh1bW5lIHMyW3AyXSBrbyBtYXRjaCBrYXJhIGRpeWEgaW5zZXJ0ZWQgY2hhciBzZSB0b2ggbGVuZ3RoKzEgaG8gZ3lpCgkJfQoJCS8vIG1heCBsZW5ndGggYWIgdGFrIGtpdG5pIGg/CgkJCgkJeG49bWF4KHgxLmZmLG1heCh4Mi5mZix4My5mZikpOwoJCWFucy5mZj14bjsKCQkKCQkvLyBqaXMgamlzIGtpIHVza2UgZXF1YWwgaCwgdW5rZSBjb3VudHMgYWRkIGthcmxvCgkJCgkJaWYoeG49PXgxLmZmKQoJCWFucy5zcys9eDEuc3M7CgkJCgkJaWYoeG49PXgyLmZmKQoJCWFucy5zcys9eDIuc3M7CgkJCgkJaWYoeG49PXgzLmZmKQoJCWFucy5zcys9eDMuc3M7Ci8vCQljb3V0PDx4bjw8ZW5kbDsKLy8JCWNvdXQ8PHAxPDwiICI8PHAyPDwiICI8PGY8PCIJeDEJIjw8eDEuZmY8PCIgIjw8eDEuc3M8PGVuZGw7Ci8vCQljb3V0PDxwMTw8IiAiPDxwMjw8IiAiPDxmPDwiCXgyCSI8PHgyLmZmPDwiICI8PHgyLnNzPDxlbmRsOwovLwkJY291dDw8cDE8PCIgIjw8cDI8PCIgIjw8ZisxPDwiCXgzCSI8PHgzLmZmPDwiICI8PHgzLnNzPDxlbmRsOwovLwkJY291dDw8cDE8PCIgIjw8cDI8PCIgIjw8Zjw8Igl4NAkiPDxhbnMuZmY8PCIgIjw8YW5zLnNzPDxlbmRsOwoJfQovLwljb3V0PDxwMTw8IiAiPDxwMjw8IiAiPDxmPDwiCSI8PGFucy5mZjw8IiAiPDxhbnMuc3M8PGVuZGw7CgkvLyBpbmthIHBhaXIgYmFuYSBrIHN0b3JlIGthcmxvCglkcFtwMV1bcDJdW2ZdWzBdPWFucy5mZjsKCWRwW3AxXVtwMl1bZl1bMV09YW5zLnNzOwoJCglyZXR1cm4gbXAoYW5zLmZmLGFucy5zcyk7CgkKfQoKCmludCBtYWluKCkKewoJbGwgbjEsbjI7CgltZW1zZXQoZHAsLTEsc2l6ZW9mKGRwKSk7CgljaW4+PnMxPj5zMjsKCW4xPXMxLmxlbmd0aCgpLTE7CgluMj1zMi5sZW5ndGgoKS0xOwoJcHAgeD1jYWxjKG4xLG4yLDApOwovLwljb3V0PDx4LmZmPDwiCSI8PHguc3M8PGVuZGw7Cgljb3V0PDx4LnNzPDxlbmRsOwoJCgkKfQ==