#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
// typedef complex<double> point;
ll mod = 1e9 + 7;
#define EPS 1e-1
#define PI 3.141592653589
#define point complex<ld>
#define dot(a, b) (conj(a) * b).real()
#define cross(a, b) (conj(a) * b).imag()
#define line tuple<ll, ll, ll>
#define X real()
#define Y imag()
#define MAXN 100001
int spf[MAXN];

// int dx[] = { 0, 0, 1, -1 };
// int dy[] = { 1, -1, 0, 0 };

#define iofile                                                                 \
  freopen("input.txt", "r", stdin);                                            \
  freopen("output.txt", "w", stdout);
#define fastio ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;

void primeFactors(ll n, vector<ll> &vec)
{

    while (n % 2 == 0)
    {
        vec.push_back(2);
        n = n / 2;
    }
    for (ll i = 3; i <= sqrt(n); i = i + 2)
    {
        while (n % i == 0)
        {
            vec.push_back(i);
            n = n / i;
        }
    }

    if (n > 2)
    {
        vec.push_back(n);
    }
}

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

ll Lcm(ll a, ll b)
{
    return ((a * b) / gcd(a, b));
}

line getL(point p1, point p2)
{
    ll a, b, c;
    a = p2.Y - p1.Y;
    b = p1.X - p2.X;
    c = -a * p1.X - b * p1.Y;
    ll gcdres = abs(gcd(a, gcd(b, c)));
    if (a < 0 || a == 0 && b < 0)
    {
        gcdres *= -1;
    }
    a /= gcdres;
    b /= gcdres;
    c /= gcdres;
    return line(a, b, c);
}

ll fastpow(ll base, ll pow)
{
    if (!base)
        return 0;
    if (!pow)
        return 1;
    if (pow == 1)
        return base;
    ll x = fastpow(base, pow / 2) % mod;
    x *= x;
    x %= mod;
    if (pow % 2)
        x *= base;
    return x % mod;
}

ll inverse(ll x)
{
    return fastpow(x, mod - 2) % mod;
}

ld disty(pair<double, double> a, pair<double, double> b)
{
    return sqrt(pow(b.second - a.second, 2.0) + pow(b.first - a.first, 2.0));
}

/*ll fact[(int)1e6 + 5], inv[(int)1e6 + 5];
void init()
{
    fact[0] = inv[0] = 1;
    for (int i = 1; i <= 1e6; i++)
    {
        fact[i] = (i * fact[i - 1]) % mod;
        inv[i] = inverse(fact[i]);
    }
}*/

void factorize(ll x, set<ll> &ss)
{
    while (x % 2 == 0)
        ss.insert(2), x /= 2;
    for (int i = 3; i <= sqrt(x); i += 2)
        while (x % i == 0)
            ss.insert(i), x /= i;
    if (x > 2)
        ss.insert(x);
}

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

void SieveOfEratosthenes(ll n, bool prime[])
{

    for (int p = 2; p * p <= n; p++)
    {

        if (prime[p] == true)
        {
            for (int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
}
void divisors(ll n, vector<ll> &vec)
{
    for (ll i = 2; i <= sqrt(n); ++i)
    {
        if (n % i == 0 && i != sqrt(n))
        {
            vec.push_back(i);
            vec.push_back(n / i);
        }
        else if (n % i == 0)
        {
            vec.push_back(i);
        }
    }
}

bool isprime(ll n)
{
    if (n == 1)
    {
        return false;
    }
    for (int i = 2; i <= sqrt(n); ++i)
    {
        if (n % i == 0)
        {
            return false;
        }
    }
    return true;
}

point rot(point p, ld angle)
{
    return (p * polar((ld)1.0, angle));
}

point rotA(point p, point A, ld angle)
{
    return (((p - A) * polar((ld)1, angle)) + A);
}

ld distance(point a, point b)
{
    ld x1 = a.X, y1 = a.Y, x2 = b.X, y2 = b.Y;
    return pow(y2 - y1, 2) + pow(x2 - x1, 2);
}

int distSq(pair<ll, ll> p, pair<ll, ll> q)
{
    return (p.first - q.first) * (p.first - q.first) +
           (p.second - q.second) * (p.second - q.second);
}

bool isSquare(pair<ll, ll> p1, pair<ll, ll> p2, pair<ll, ll> p3,
              pair<ll, ll> p4)
{
    ll d2 = distSq(p1, p2);
    ll d3 = distSq(p1, p3);
    ll d4 = distSq(p1, p4);
    if (d2 == d3 && 2 * d2 == d4 && 2 * d2 == distSq(p2, p3))
    {
        int d = distSq(p2, p4);
        return (d == distSq(p3, p4) && d == d2);
    }

    // The below two cases are similar to above case
    if (d3 == d4 && 2 * d3 == d2 && 2 * d3 == distSq(p3, p4))
    {
        int d = distSq(p2, p3);
        return (d == distSq(p2, p4) && d == d3);
    }
    if (d2 == d4 && 2 * d2 == d3 && 2 * d2 == distSq(p2, p4))
    {
        int d = distSq(p2, p3);
        return (d == distSq(p3, p4) && d == d2);
    }

    return false;
}

ll FP(ll base, ll power, ll m)
{

    if (power == 0)
    {
        return 1;
    }
    else if (power % 2 == 0)
    {
        ll res = FP(base, power / 2, m);
        return (res % m * res % m) % m;
    }
    else
    {
        ll res = FP(base, power / 2, m);
        return ((((base % m * (res % m)) % m) * (res % m) % m) % m);
    }
}
ll EGCD(ll a, ll b, ll &x, ll &y)
{

    if (b == 0)
    {
        x = 0;
        y = 1;
        return a;
    }
    else
    {
        ll ans = EGCD(b, a % b, x, y);
        ll tmp = x;
        x = y - (a / b) * x;
        y = tmp;
        return ans;
    }
}
// ll f[(int)1e7+7],in[(int)1e7+7];
/*void prec(ull n){
f[0]=1;
in[0]=1;
for(int i=1;i<=n;++i){
    f[i]=(f[i-1]*i)%mod;
    in[i]=FP(f[i],mod-2,mod);
}
}
ll npr(ll n,ll r){
    return (f[n]*in[n-r])%mod;
}
ll NCR(ll n,ll r){
return (((f[n]*in[n-r])%mod)*in[r])%mod;
}*/
void sieve()
{
    spf[1] = 1;
    for (int i=2; i<MAXN; i++)


        spf[i] = i;

    for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {

        if (spf[i] == i)
        {

            for (int j=i*i; j<MAXN; j+=i)

                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}

set<int> getFactorization(int x)
{
    set<int> ret;
    while (x != 1)
    {
        ret.insert(spf[x]);
        x = x / spf[x];
    }
    return ret;
}
string s,g;

ll memo[3005][3005];

ll solve(int idx,int idy){

if(idx==s.size() ||idy==g.size()){return 0;}

if(memo[idx][idy]!=-1){return memo[idx][idy];}

if(s[idx]==g[idy]){return memo[idx][idy]=1+solve(idx+1,idy+1);}

else{return memo[idx][idy]=max(solve(idx+1,idy),solve(idx,idy+1));}

}
void build(int idx,int idy){
if(idx>=s.size() ||idy>=g.size()){return;}
if(s[idx]==g[idy]){cout<<s[idx]; build(idx+1,idy+1);}
else{
    if(solve(idx,idy+1)==memo[idx][idy]){build(idx,idy+1);}
    else{build(idx+1,idy);}
    return;
}
}
int main(){
    //fastio
    cin>>s>>g;
    memset(memo,-1,sizeof memo);
    solve(0,0);
    build(0,0);

    return 0;
}


Measured memory_bytes: 71168