// 最长子序列
int main(){
string a;
string b;
cin>>a>>b;
string::size_type alen = a.size();
string::size_type blen = b.size();
int f[alen+1][blen+1];
for(int i = 0; i <= alen; i++){
for(int j = 0; j <= blen; j++){
if(i == 0 || j == 0){
f[i][j] = 0;
}else if(a[i - 1] == b[j-1]){
f[i][j] = f[i-1][j-1] + 1;
}else{
f[i][j] = max(f[i-1][j], f[i][j-1]);
}
}
}
for(int i = 0; i <= alen; i++){
for(int j = 0; j <= blen; j++){
cout<<f[i][j]<<" ";
}
cout<< endl;
}
cout<< f[alen][blen]<<endl;
return 0;
}
// 利用滚动数组
int main(){
string a;
string b;
cin>>a>>b;
string::size_type alen = a.size();
string::size_type blen = b.size();
int now = 0;
int f[2][blen+1];
for(int i = 0; i <= alen; i++){
for(int j = 0; j <= blen; j++){
if(i == 0 || j == 0){
f[(now+1)%2][j] = 0;
}else if(a[i - 1] == b[j-1]){
f[(now+1)%2][j] = f[now%2][j-1] + 1;
}else{
f[(now+1)%2][j] = max(f[now%2][j], f[(now+1)%2][j-1]);
}
}
now = (now+1)%2;
}
cout<< f[now][blen]<<endl;
return 0;
}