//Program.cpp
//Author : Aaryan Srivastava 
#include <bits/stdc++.h>
#include <random>
#include <chrono>
#define pb push_back
#define popb pop_back
#define ull unsigned long long  
#define beg begin
#define mp make_pair
#define pii pair<int, int>
#define piii pair<pii,int>
#define rep(i,n) for(int (i) = 0 ; i < (n) ; i++)
#define repA(i,x,y) for(int i = (x) ; i <= (y) ; i++)
#define repD(i,x,y) for(int i = (x) ; i >= (y) ; i--)
#define all(c) (c).begin(),(c).end()
#define ff first
#define ss second 
#define fill(a,val) memset(a,val,sizeof(a))
#define Randomize mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
using ll = long long;
#define int ll
const int N = 1e5 + 5 ;
const int mod = 1e9 + 5 ;
const int inf = 1e18 ;
const int SZ = 101 ;
const double eps = 1e-9 ;
using namespace std;
#ifdef AaryanS
#define mycout cout
#define mycerr cerr 
#endif

#ifndef AaryanS
#define mycout if(false) cout
#define mycerr if(false) cerr
#define AaryanS 0 
#endif


#define debug(x) mycerr << #x << " "  << x << endl ;
//pair<int,pii> dp[3005][5005] ;
string s,t ;

// pii LCS (int r1, int r2) /* =  0,1,2*/
// {
// 	if(r1 == 0 || r2 == 0){
// 		return mp(0,0) ;
// 	}
// 	if(dp[r1][r2] != mp(0,0))
// 		return dp[r1][r2];
// 	int res = 0 ;
// 	int prev = -1 ;
// 	int t2 = 0 ;
// 	int t0 = LCS(r1-1,r2).ff ;
// 	if(res < t0){
// 		res = t0 ;
// 		prev = 0 ;
// 	}
// 	int t1 = LCS(r1,r2-1).ff ;
// 	if(res < t0){
// 		res = t1 ;
// 		prev = 1 ;
// 	}
// 	if(s[r1-1] == t[r2-1]){
// 		t2 = 1 +  LCS(r1,r2).ff ;
// 		if(res < t2) {
// 			res = t2;
// 			prev = 2 ;
// 			//mycerr << appendx(ans,s[r1]) << endl;
// 		} 
// 	} 
// 	return dp[r1][r2] = mp(res,prev);
//}

template <typename T> void max_self(T &a, T b){
	a = max(a,b) ;
}

void solve()
{
	cin >> s >> t ;
	int n = s.length(), m = t.length() ; 
	vector<vector<pair<int,pair<int,int>>>> dp(n + 1, 
			vector<pair<int,pair<int,int>>> (m+1, mp(-1,mp(0,0))) ) ;
	dp[0][0] = {0,{0,0}} ;

	rep(i,n){
		rep(j,m) {
			if(s[i] == t[j])
				max_self(dp[i+1][j+1],mp(dp[i][j].ff + 1,mp(i,j))) ;
			max_self(dp[i+1][j],mp(dp[i][j].ff,mp(i,j))) ;
			max_self(dp[i][j+1],mp(dp[i][j].ff,mp(i,j))) ;
		}	
	}
	//cout << dp[n][m].ff << endl ;
	auto answer = mp(0LL,mp(0LL,0LL)) ;
	repA(i,1,n){
		repA(j,1,m){
			max_self(answer,mp(dp[i][j].ff,mp(i,j))) ;
		}
	}
	mycout << answer.ff << endl ;
	mycerr << "(" << answer.ss.ff << "," << answer.ss.ss << ")\n" ;
	rep(i,n+1){
		rep(j,m+1){
			mycerr << "(" << dp[i][j].ss.ff << "," << dp[i][j].ss.ss << ") " ;
			mycout << dp[i][j].ff << " " ;
		}
		mycout << endl ;
		mycerr << endl ;
	}
	auto curr = answer.ss ;
	string abc ;
	while(curr.ff && curr.ss){
		int i = curr.ff ;
		int j = curr.ss ;
		pii prev = dp[i][j].ss ;
		if(prev == mp(i-1,j-1)){
			assert(s[i-1] == t[j-1]) ;
			abc += s[i-1] ;
		}
		curr = prev ;
	}
	reverse(all(abc)) ;
	cout << abc ;


	// cout << LCS(s.length() ,t.length()).ff << "\n" ; // << glob_ans << endl ;
	// repA(i,0,s.length()){
	// 	repA(j,0,t.length()){
	// 		cout << dp[i][j].ff << " " ;
	// 	}
	// 	cout << endl ;
	// }
}   

     
int32_t main(int32_t argc, char *argv[])
{
    double t1 = clock() ;
    ios::sync_with_stdio(0);    
    cin.tie(0); cout.tie(0);
    int TC = 1, tt = 0;
   // cin >> TC ;
    while(tt++ < TC)
    {
        //cout << "Case " << t << ":\n" ;
        solve();
    }
    mycerr << "Time : " << 1000 *(clock() - t1)/CLOCKS_PER_SEC << " ms\n" ;
    return 0;
}

Measured memory_bytes: 211456