#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define mt make_tuple
#define ll long long
#define eb emplace_back
#define fi first
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
#define scanVec(vec , n) for(int i = 0; i < n ; i++){ cin>>vec[i];}
#define printVec(vec , n) for(int i = 0; i < n ; i++){ cout<<vec[i]<<" ";}
#define mod(a,b) ((a%b +b)%b)
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define min(a,b) (a>b?b:a) 
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
#define IN(i,l,r) (l<i&&i<r)
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define lastEle(vec) vec[vec.size()-1] 
#define SZ(x) ((int)((x).size()))
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) 
#define ll long long 
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define INF 1001001001
#define PI 3.1415926535897932384626
 
using namespace std;
 using namespace __gnu_pbds;
 template <typename T>
 using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
 
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    err(++it, args...);
}
 
//----------------------------------------------------------------------------------------------------------------------
 
#define MOD 1000000007 
  
void swap(char &a, char & b){
    char temp = a;
    a = b;
    b = temp;
 
}
 
const ll md = 1e9 + 7;
const int MAXN = 2*1e5 + 50;
 
char str[MAXN];


ll count (string &s,int n){

    int right = n-1;
    vector< int > arr (n+1);
    for(int i = 0;i < n;i++){
        arr[i] = arr[i-1];
        if(s[i] == '(') arr[i]--;
        else arr[i]++;
    }
    ll cnt = 0;
    int op = 0;
    stack< char > st;
    st.push(s[right]);
    right--;
    while(right >= 0){
        char curr = s[right];
        if(st.size() == 0 || st.top() == curr){
            st.push(curr);
        }else{
            st.pop();
        }
        if(st.size() == 0){
            cnt++;
        }
        right--;
    }
    return cnt;
}

    // int n;
    // cin >> n;
    // string s;
    // cin >> s;

    // ll ans = 0;
    // //cout << "rame" << endl;
    // ll ansL = 0;
    // ll ansR = 0;
    // for(int i = 0;i < n;i++){
    //     for( int j = i + 1; j < n;j++){
    //         swap(s[i],s[j]);
    //         ll curr = count(s,n);
    //         if(curr > ans){
    //             ansL = i + 1;
    //             ansR = j + 1;
    //         }
    //         ans = max(ans,curr);
    //         swap(s[i],s[j]);
    //     }
    // }

    // cout << ans << endl;
    // cout << ansL << " " << ansR << endl;

ll inf = 1e18*1LL;

struct info {
    int fromI,fromJ;
    char c;
    int ans;
};

int main(){
    string s;
    string t;
    cin >> s >> t;
    vector< vector< info > > dp (s.size() + 1, vector<info> (t.size() + 1));

    for(int i = 1; i <= s.size();i++){
        for(int j = 1; j <= t.size();j++){
            if(s[i- 1 ] == t[j - 1]){
                dp[i][j].ans = dp[i-1][j-1].ans + 1;
                dp[i][j].fromI = i-1;
                dp[i][j].fromJ = j-1;
                dp[i][j].c = s[i-1];
            }else if(dp[i][j-1].ans > dp[i-1][j].ans){
                dp[i][j].ans = dp[i][j-1].ans;
                dp[i][j].fromI = i;
                dp[i][j].fromJ = j-1;
            }else {
                dp[i][j].ans = dp[i-1][j].ans;
                dp[i][j].fromI = i-1;
                dp[i][j].fromJ = j;
            }
        }
    }
    string anss;
    int i = s.size(); int j = t.size();
    if(dp[i][j].ans == 0) return 0;
    while(i >= 1 && j >= 1){
        int frI = dp[i][j].fromI;
        int frJ = dp[i][j].fromJ;
        //cout << frI << " " << frJ << dp[i][j].c << endl;
        if(frI  + 1 == i && frJ + 1 == j){
            //cout << "rame" << endl;
            anss = dp[i][j].c + anss;
        }
        i = frI;
        j = frJ;
    }
   // reverse(all(anss));
    cout << anss << endl;


    
    return 0;
}

Measured memory_bytes: 141184