#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <bitset>
#include <random>
#include <chrono>
#include <complex>
#include <algorithm>
#include <utility>
#include <functional>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iomanip> 

using namespace std;

#define sqr(x) ((x)*(x))
#define mp make_pair
#define pb push_back
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define RE(i, n) FOR(i,1,n)
#define REP(i,n) FOR(i, 0, (int)(n)-1)
#define fst first
#define snd second

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef tuple<int,int,int> iii;

string to_string(string s) {
    return '"' + s + '"';
}
    
string to_string(const char* s) {
    return to_string((string) s);
}
    
string to_string(bool b) {
    return (b ? "true" : "false");
}
    
template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
    
template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}

void fastIO() {
    cin.sync_with_stdio(false);
    cin.tie(0);
}


int XMOV[4] = {0, 0, 1, -1};
int YMOV[4] = {1, -1, 0, 0};

//#############################
const int MAXN = 3005;


string a,b;
int memo[MAXN][MAXN];
pii p[MAXN][MAXN];

// abxx yxabwxu

int dp(int n, int m) {
    if (n == 0 || m == 0) {
        return 0;
    }

    if (memo[n][m] != -1) {
        return memo[n][m];
    }

    if (a[n] == b[m]) {
        p[n-1][m-1] = pii(n, m);
        return memo[n][m] = dp(n-1, m-1) + 1;
    }
    else {
        int x = dp(n-1,m);
        int y = dp(n, m-1);
        if (x > y) 
            p[n-1][m] = pii(n, m);
        else
            p[n][m-1] = pii(n, m);
        return memo[n][m] = max(x, y);
    }
}

int main() {
    cin >> a >> b;
    a = ' '+a;
    b = ' '+b;
    int n, m;
    n = a.size();
    m = b.size();
    memset(memo, -1,sizeof(memo));
    for (int i = 0; i < n; i++){
        for (int j = 0; j < m; j++) {
            p[i][j] = pii(i, j);
        }
    }
    dp(n,m);
    pii x = pii(0, 0);
    string ans;
    // while(x.fst >= 0 && x.snd >= 0 && x != p[x.fst][x.snd]) {
    //     if (x.fst >= 0 && x.snd >= 0 && a[x.fst] == b[x.snd])
    //         ans.pb(a[x.fst]);
    //     x = p[x.fst][x.snd];
    // }
    // if (a[x.fst] == b[x.snd])
    //     ans.pb(a[x.fst]);
    int i, j;
    i = n, j = m;
    while(i >0 && j >0) {
        if (a[i] == b[j])
            ans.pb(a[i]), i--, j--;
        else{
            if (memo[i-1][j] > memo[i][j-1])
                i--;
            else
                j--;
        }
    }

    reverse(ans.begin(), ans.end());
    // cout << memo[n][m] << endl;
    ans.pop_back();
    cout << ans << endl;
    return 0;
}

Measured memory_bytes: 106496