/*
动态规划题
也许是刚刚接触动态规划的缘故
发现他真的是奇妙无穷
许多看似无法可解的问题用它就可以很轻易地解决
此题是求最长公共子串的问题
状态转移方程
dp[i][j]=dp[i-1][j-1]+1; (str1[i]==str2[j])
dp[i][j]=MAX{dp[i-1][j],dp[i][j-1]}; (str1[i]!=str2[j])
最后输出dp[i][j]即可
对于字符串
str1="X1X2...Xi...Xm";
str2="Y1Y2...Yj...Yn";
若Xi==Yj
则str1,str2的最长公共子序列长一定等于"X1X2...Xi-1" ,"Y1Y2...Yj-1"
的最长公共子序列长度+1
同理若Xi!=Xj,则str1,str2的最长公共子序列长
一定等于"X1X2...Xi-1"和"Y1Y2...Yj" ,"Y1Y2...Yj-1"和"X1X2...Xi"中较长的公共子序列长度
*/
#define LOCAL
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<string>
#include<algorithm>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#define N 1005
using namespace std;
int dp[N][N];
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
string str1,str2;
int strlen1,strlen2,i,j;
while(cin>>str1>>str2)
{
memset(dp,0,sizeof(dp));
strlen1=str1.size();strlen2=str2.size();
for(i=1;i<=strlen1;i++)
{
for(j=1;j<=strlen2;j++)
{
if(str1[i-1]==str2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=(dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1]);
}
}
cout<<dp[strlen1][strlen2]<<endl;
}
return 0;
}