/*
* Problem :: 9251 / LCS
*
* Kind :: Dynamic Programming
*
* Insight
* - LCS = 전형적인 DP 문제
* + 문자열 A, B
* 문자열길이 al = len(A), bl = len(B)
* dp[i][j] = len(LCS(문자열 A의 i번째 문자까지, 문자열 B의 j번째 문자까지))
* # A의 i번째 문자와 B의 j번째 문자가 같으면
* dp[i][j] = dp[i-1][j-1]+1
* # A의 i번째 문자와 B의 j번째 문자가 다르면
* dp[i][j] = max(dp[i-1][j], dp[j][i-1])
*
* Point
* - 원래는 자세한 설명을 추가하고 싶었는데...
* 지식의 저주인가, 알고나니 너무 당연하다
* + A abcde
* B fghie
* # dp[5][5] = dp[4][4]+1
* (abcde, fghie) = (abcd, fghi)+(e)
* # dp[4][4] = max(dp[3][4], dp[4][3])
* (abcd, fghi) = max((abc, fghi), (abcd, fgh))
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
string A; cin >> A;
string B; cin >> B;
// Process
int al = A.length();
int bl = B.length();
int dp[al+1][bl+1]; /* dp[i][j] = len(LCS(
* 문자열 A의 i번째 문자까지, 문자열 B의 j번째 문자까지)) */
memset(dp, 0, sizeof(dp));
for (int i=1; i<=al; i++) {
for (int j=1; j<=bl; j++) {
/* 문자열 A의 i번째 문자와 문자열 B의 j번째 문자가 같으면 */
if (A[i-1] == B[j-1]) {
dp[i][j] = dp[i-1][j-1]+1;
/* 문자열 A의 i번째 문자와 문자열 B의 j번째 문자가 다르면 */
} else {
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
}
// Control : Output
cout << dp[al][bl] << endl;
}
// Helper Functions
/* None */