//============================================================================
// Name        : competitive_programing.cpp
// Author      : .Data_Nerd.
// Description : problem solving training
//============================================================================

#include <iostream>
#include <bits/stdc++.h>
#define PI acos(-1)
#define dot(a, b) (conj(a) * (b)).real()
#define cross(a, b) (conj(a) * (b)).imag()
#define Data_Nerd ios_base::sync_with_stdio(); cin.tie(0); cout.tie(0);
#define Y imag()
#define X real()
#define EPS 1e-7
#define mod 1000000007
#define OO 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef complex <ld> point;
typedef vector <point> polygon;
typedef tuple <ld, ld, ld> line;
typedef vector <point> spolygon;

line lineeq(point x, point y){
	ll a = y.Y - x.Y;
	ll b = x.X - y.X;
	ll c = -a * x.X - b * x.Y;
	ll gcd = abs(__gcd(a, __gcd(b, c)));
	if(a < 0 || (a == 0 && b < 0)) gcd *= -1;
	a /= gcd; b /= gcd; c /= gcd;
	return line(a, b, c);
}

point getpoint(line l1, line l2){
	ld y = (get<0>(l1) * get<2>(l2) - get<0>(l2) * get<2>(l1)) / (get<0>(l2) * get<1>(l1) - get<0>(l1) * get<1>(l2));
	ld x = (get<2>(l1) * get<1>(l2) - get<2>(l2) * get<1>(l1)) / (get<0>(l2) * get<1>(l1) - get<0>(l1) * get<1>(l2));
	return point(x, y);
}

bool onray(point a, point b, point c){
	return dot(b - a, c - a) > -EPS;
}

ll fact(ll n){
	if(n == 0) return 1;
	return n * fact(n - 1);
}

bool isPrime(ll q){
	if(q == 0 || q == 1) return false;
	for(ll i = 2; i * i <= q; i++) if(q % i == 0) return false;
	return true;
}

point rotate(point p, ld a){
	return p * polar((ld)1, a * PI / 180);
}

bool canBe(line l1, line l2){
	if(get<0>(l2) * get<1>(l1) - get<0>(l1) * get<1>(l2) != 0) return true;
	return false;
}

ld getangle(point p){
	return arg(p) * 180 / PI;
}

ll fp(ll base, ll x){
	if(x == 0) return 1;
	ll ans = fp(base, x / 2);
	ans = (ans * ans) % mod;
	if(x % 2)
		ans = ((base % mod) * ans) % mod;
	return ans;
}

ll GCD(ll a, ll b){
	if(b == 0) return a;
	if(a == 0) return b;
	return GCD(b, a % b);
}

ll LCM(ll a, ll b){
	return (a * b) / GCD(a, b);
}

ll fac[(int)1e4 + 7], inv[(int)1e4 + 7];

void calcFacAndInv(ll n){
    fac[0] = inv[0] = 1;
    for (ll i = 1; i <= n; i++)
    {
        fac[i] = (i * fac[i - 1]) % mod;
        inv[i] = fp(fac[i], (ll)mod - 2);
    }
}

ll ncr(ll n, ll r){
    return ((fac[n] * inv[r]) % mod * inv[n - r]) % mod;
}

ll npr(ll n, ll r){
    return (fac[n] * inv[n - r]) % mod;
}

ll p[55][55] = {};

void pascal(){
    p[0][0] = 1;
    for(int i = 1; i < 55; i++) {
        p[i][0] = 1;
        for(int j = 1; j <= i; j++) p[i][j] = p[i - 1][j] + p[i - 1][j - 1];
    }
}

string s, t;
ll dp[3005][3005];

ll solve(ll i, ll j){
	if(i == s.size() || j == t.size())
		return 0;
	if(dp[i][j] != -1)
		return dp[i][j];
	if(s[i] == t[j])
		dp[i][j] = solve(i + 1, j + 1) + 1;
	else
		dp[i][j] = max(solve(i + 1, j), solve(i, j + 1));
	return dp[i][j];
}

void build(ll i, ll j){
	if(i == s.size() || j == t.size())
		return;
	if(s[i] == t[j]){
		cout << s[i];
		build(i + 1, j + 1);
	}
	else{
		if(solve(i + 1, j) == dp[i][j]){
			build(i + 1, j);
		}
		else if(solve(i, j + 1) == dp[i][j]){
			build(i, j + 1);
		}
	}
}

int main() {
	Data_Nerd
	memset(dp, -1, sizeof dp);
	cin >> s >> t;
	solve(0, 0);
	build(0, 0);
  	return 0;
}


Measured memory_bytes: 71168