#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void checkMin(T &a, T b) {
  if (a > b) a = b;
}
template <typename T>
inline void checkMax(T &a, T b) {
  if (a < b) a = b;
}
const int MAX_NODE = 1234;
const int CHAR_SET = 26;
struct TrieNode;
TrieNode *root, *pend;
struct TrieNode {
  TrieNode *fail, *go[CHAR_SET];
  bool flag;
  void init() {
    flag = false;
    fail = root;
    fill(go, go + CHAR_SET, root);
  }
} pool[MAX_NODE];
void init() {
  pend = pool;
  root = pend++;
  root->init();
}
void insert(char *s) {
  TrieNode *p;
  for (p = root; *s; ++s) {
    if (p->go[*s - 'A'] == root) {
      (p->go[*s - 'A'] = pend++)->init();
    }
    p = p->go[*s - 'A'];
  }
  p->flag = true;
}
void init_fail() {
  static TrieNode *q[MAX_NODE], *u, *v, *fa;
  int f = 0, b = 0;
  for (int ch = 0, n_ = int(CHAR_SET); ch < n_; ++ch) {
    if (root->go[ch] != root) {
      q[b++] = root->go[ch];
    }
  }
  while (f < b) {
    u = q[f++], fa = u->fail;
    for (int ch = 0, n_ = int(CHAR_SET); ch < n_; ++ch) {
      if ((v = u->go[ch]) != root) {
        q[b++] = v;
        v->fail = fa->go[ch];
        v->flag |= fa->go[ch]->flag;
      } else {
        u->go[ch] = fa->go[ch];
      }
    }
  }
}
const int MAX_N = 105;
char s[MAX_N], t[MAX_N], v[MAX_N];
int a, b, c, ms;
inline int nxt(int i, int c) { return pool[i].go[c] - pool; }
int dp[MAX_N][MAX_N][MAX_N];
void dfs(int i, int j, int k, int len) {
  if (i == 0 || j == 0 || len == 0) {
    return;
  }
  if (dp[i][j][k] == dp[i - 1][j][k]) {
    dfs(i - 1, j, k, len);
    return;
  }
  if (dp[i][j][k] == dp[i][j - 1][k]) {
    dfs(i, j - 1, k, len);
    return;
  }
  if (s[i] == t[j]) {
    for (int kk = 0, n_ = int(ms - 1); kk < n_; ++kk) {
      if (nxt(kk, s[i] - 'A') == k && dp[i][j][k] == dp[i - 1][j - 1][kk] + 1) {
        dfs(i - 1, j - 1, kk, len - 1);
        printf("%c", s[i]);
        return;
      }
    }
  }
}
int main() {
  cin >> &s[1] >> &t[1] >> v;
  a = strlen(s + 1), b = strlen(t + 1), c = strlen(v);
  init();
  insert(v);
  init_fail();
  ms = pend - pool;
  for (int k = 0, n_ = int(ms - 1); k < n_; ++k) {
  }
  dp[0][0][0] = 0;
  for (int i = 1; i <= a; ++i) {
    for (int j = 1; j <= b; ++j) {
      if (s[i] == t[j]) {
        for (int k = 0, n_ = int(ms - 1); k < n_; ++k) {
          if (dp[i - 1][j - 1][k] < 0) {
            continue;
          }
          int to = nxt(k, s[i] - 'A');
          if (i == j) {
          }
          if (pool[to].flag) {
          } else {
            checkMax(dp[i][j][to], dp[i - 1][j - 1][k] + 1);
          }
        }
      }
      for (int k = 0, n_ = int(ms - 1); k < n_; ++k) {
        checkMax(dp[i][j][k], dp[i - 1][j][k]);
        checkMax(dp[i][j][k], dp[i][j - 1][k]);
      }
    }
  }
  int ans = *max_element(&dp[a][b][0], &dp[a][b][ms]);
  if (ans <= 0) {
    printf("0\n");
    return 0;
  }
  for (int k = 0, n_ = int(ms - 1); k < n_; ++k) {
    if (dp[a][b][k] == ans) {
      dfs(a, b, k, ans);
      printf("\n");
      break;
    }
  }
  return 0;
}
