#include <bits/stdc++.h>
using namespace std;

void program(); 
int main() {
    cin.sync_with_stdio(0); cin.tie(0);
    cin.exceptions(cin.failbit);
    program();
}

#define INF 0x7fffffffffffffff
#define UINF 0xffffffffffffffff
#define MOD 1000000007

#define int long long
#define unsigned unsigned long long
#define double long double

#define endl "\n"

int pow(int a, int b, int m) {
    a %= m;
    int res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}

class UF{
public:
    int n;
    vector<int> par, sz;
    UF(int size) : n(size), par(size), sz(size){
        for(int i=0; i<n; i++){
            par[i] = i;
            sz[i] = 1;
        }
    }
    void join(int x, int y){
        if ((x = find(x)) == (y = find(y))) return;
        if (sz[y] < sz[x]) std::swap(x, y);
        par[x] = y;
        sz[y] += sz[x];
        sz[x] = 0;
    }
    int find(int x){ return par[x] = (x == par[x] ? x : find(par[x])); }
    bool connected(int x, int y){ return find(x) == find(y); }
};

template<class Iter> void _print_range(ostream& o, Iter s, Iter e){
    for(;s != e;s++) o << *s << " ";
} 
template<class T> std::ostream& operator<<(ostream& o, const std::vector<T> &ds)
{
    _print_range(o,ds.begin(),ds.end()); 
    return o;
}
template<class T> std::ostream& operator<<(ostream& o, const std::set<T> &ds)
{
    _print_range(o,ds.begin(),ds.end()); 
    return o;
}
template<class T, class U> std::ostream& operator<<(ostream& o, const std::pair<T,U> &ds)
{
    o << "<" << ds.first << "," << ds.second << ">" << endl;
    return o;
}
template<typename ...Args>
void print(Args&&... args) {
    for(auto&& x: {args...})
        cout << x << " ";
    cout << endl;
}

#define debug(x) cout << "DEBUG    " <<  #x << ": " << x << endl;

#define fr(i, a, b) for(int i = a; i != (b); i += (a<b ? 1 : -1))
#define rep(i, a) for(decltype(a) i = 0; i < (a); i++)

#define trav(x, a) for(auto& x : a)
#define all(a) a.begin(), a.end()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second

#define vi vector<int>
#define pii pair<int,int>

#define N 3005

int dp[N][N];
pii p[N][N];
void program(){
    string s,t;
    cin>>s>>t;
    s = "_" + s;
    t = "+" + t;
    rep(i,N) rep(j,N) p[i][j] = {i,j}, dp[i][j]=0;
    int n=s.size(),m=t.size();
    for(int i=1;i<n;i++) for(int j=1;j<m;j++){
        vector<tuple<int,int,int>> opts;
        opts.eb(dp[i-1][j-1]+(s[i]==t[j]),i-1,j-1);
        opts.eb(dp[i-1][j],i-1,j);
        opts.eb(dp[i][j-1],i,j-1);
        for(auto opt: opts){
            int v,si,tj;
            tie(v,si,tj) = opt;
            if(v>dp[i][j]){
                dp[i][j] = v;
                p[i][j] = {si,tj};
            }
        }
    }
    vector<char> res;
    int i=n-1, j=m-1;
    while(i>=0 && j>=0 && p[i][j] != make_pair(i,j)){
        if(p[i][j] == make_pair(i-1,j-1) && s[i]==t[j])
            res.pb(s[i]);
        tie(i,j)=p[i][j];
    }
    reverse(all(res));
    for(auto e: res) cout<<e;
    cout<<endl;
}

/*
WA:
-bounds on loops
-truncating
-intialization
-0 vs 1 indexing

TLE:
-might need unordered_set/map
-infinite while loop

Stuck:
-bruteforce?
-reduce dimensionality with problem contraints?
*/


Measured memory_bytes: 211968