#include<bits/stdc++.h>

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
using namespace std;
#define ll long long
#define endl "\n"
#define ar array
#define pb push_back
#define sz(X) ((int)(X).size())
#define ordered_set tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
#define sort_unique(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define get_pos(c, x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define all(X) (X).begin(), (X).end()
#define  No cout<<"NO"<<endl;
#define  Yes cout<<"YES"<<endl;
#define  nl cout<<endl;
#define gc getchar//_unlocked
#define pc putchar//_unlocked
template<typename T>
ostream &operator+(ostream &out, const vector<T> &vec) {
    for (const auto &x : vec) {
        out << x << " ";
    }
    out << "\n";
    return out;
}

template<typename T>
ostream &operator*(ostream &out, const vector<T> &vec) {
    for (const auto &x : vec) {
        out + x;
    }
    return out;
}

template<typename T>
istream &operator>>(istream &in, vector<T> &vec) {
    for (auto &x : vec) {
        in >> x;
    }
    return in;
}
// DEBUG
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
    cerr << ts(h); if (sizeof...(t)) cerr << ", ";
    DBG(t...); }

#ifdef _DEBUG // compile with -DLOCAL
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 0
#endif

template<class T>
bool ckmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }

template<class T>
bool ckmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }


const int mod = 1e9 + 7;
const int mod2 = 998244353;
const ll INF = 1e9 + 6;

ll add(ll a, ll b) {
    a += b;
    return a % mod;
}

ll mul(ll a, ll b) {
    a *= b;
    return a % mod;
}
inline void lprint( int a)
{	 // printf("%d ",a);
    ll i=0;
    char S[20];
    if (a==0) {
        pc('0');
        pc('\n');
        return;
    }
    while(a>0)
    {
        S[i++]=a%10+'0';
        a=a/10;
    }
    --i;
    while(i>=0)
        pc(S[i--]);
    pc('\n');
}
inline ll readInt () {
    register bool minus = false;
    ll result = 0;
    register char ch;
    ch = gc();
    while (true) {
        if (ch == '-') break;
        if (ch >= '0' && ch <= '9') break;
        ch = gc();
    }
    if (ch == '-') minus = true; else result = ch-'0';
    while (true) {
        ch = gc();
        if (ch < '0' || ch > '9') break;
        result = result*10 + (ch - '0');
    }
    if (minus)
        return -result;
    else
        return result;
}
inline ll power(ll x, ll y, ll p) {
    ll res = 1;
    x = x % p;
    while (y > 0) {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};

const int MXN = 3e3 + 5;
int dp[MXN][MXN];
void solve() {
    string a,b;
    cin>>a>>b;
    int n=sz(a);
    int m=sz(b);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
           if(a[i]==b[j]){
               dp[i+1][j+1]=dp[i][j]+1;
           }
           else{
               dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
    
           }
        }
    }
    string ans;
    while(n>0&&m>0){
        if(a[n-1]==b[m-1]){
            ans+=a[n-1];
            n--;
            m--;
            continue;
        }
        if(dp[n-1][m]>dp[n][m-1]){
            n--;
        }
        else{
            m--;
        }
    }
   reverse(all(ans));
   cout<<ans<<endl;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
#endif
    int t = 1;
   // cin>>t;
    while (t--)solve();
    // cerr <<endl<< "Time elapsed : " << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}
//look if it requires ll


Measured memory_bytes: 38828