Problem: Oleg Petrov loves crossword puzzles and every Thursday he buys his favorite magazine with crosswords and other word puzzles. In the last magazine Oleg found a curious puzzle, and the magazine promised a valuable prize for it's solution. We give a formal description of the problem below.

The puzzle field consists of two rows, each row contains n cells. Each cell contains exactly one small English letter. You also are given a word w, which consists of k small English letters. A solution of the puzzle is a sequence of field cells c1, ..., ck, such that:

  * For all i from 1 to k the letter written in the cell ci matches the letter wi;
  * All the cells in the sequence are pairwise distinct;
  * For all i from 1 to k - 1 cells ci and ci + 1 have a common side.



Oleg Petrov quickly found a solution for the puzzle. Now he wonders, how many distinct solutions are there for this puzzle. Oleg Petrov doesn't like too large numbers, so calculate the answer modulo 109 + 7.

Two solutions ci and c'i are considered distinct if the sequences of cells do not match in at least one position, that is there is such j in range from 1 to k, such that cj ≠ c'j.

Input

The first two lines contain the state of the field for the puzzle. Each of these non-empty lines contains exactly n small English letters.

The next line is left empty.

The next line is non-empty and contains word w, consisting of small English letters.

The length of each line doesn't exceed 2 000.

Output

Print a single integer — the number of distinct solutions for the puzzle modulo 109 + 7.

Examples

Input

code
edoc

code


Output

4


Input

aaa
aaa

aa


Output

14

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
int inf;
const double eps = 1e-8;
const double pi = acos(-1.0);
template <class T, class T2>
int chkmin(T &a, T2 b) {
  return a > b ? a = b, 1 : 0;
}
template <class T, class T2>
int chkmax(T &a, T2 b) {
  return a < b ? a = b, 1 : 0;
}
template <class T>
T sqr(T a) {
  return a * a;
}
template <class T, class T2>
T mmin(T a, T2 b) {
  return a < b ? a : b;
}
template <class T, class T2>
T mmax(T a, T2 b) {
  return a > b ? a : b;
}
template <class T>
T aabs(T a) {
  return a < 0 ? -a : a;
}
template <class T>
int dcmp(T a, T b) {
  return a > b;
}
template <int *a>
int cmp_a(int first, int second) {
  return a[first] < a[second];
}
template <class T>
bool sort2(T &a, T &b) {
  return a > b ? swap(a, b), 1 : 0;
}
struct __INIT__ {
  __INIT__() {
    fill((unsigned char *)&inf, (unsigned char *)&inf + sizeof(inf), 0x3f);
  }
} __INIT___;
namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
inline void putc(char first) {
  *oS++ = first;
  if (oS == oT) flush();
}
template <typename A>
inline bool read(A &first) {
  for (f = 1, c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                              (iS == iT ? EOF : *iS++))
                            : *iS++);
       c < '0' || c > '9';
       c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    if (c == '-')
      f = -1;
    else if (c == EOF)
      return 0;
  for (first = 0; c <= '9' && c >= '0';
       c = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                       (iS == iT ? EOF : *iS++))
                     : *iS++))
    first = first * 10 + (c & 15);
  first *= f;
  return 1;
}
inline bool read(char &first) {
  while ((first = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                               (iS == iT ? EOF : *iS++))
                            : *iS++)) == ' ' ||
         first == '\n' || first == '\r')
    ;
  return first != EOF;
}
inline bool read(char *first) {
  while ((*first = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                                (iS == iT ? EOF : *iS++))
                             : *iS++)) == '\n' ||
         *first == ' ' || *first == '\r')
    ;
  if (*first == EOF) return 0;
  while (!(*first == '\n' || *first == ' ' || *first == '\r' || *first == EOF))
    *(++first) = (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),
                              (iS == iT ? EOF : *iS++))
                           : *iS++);
  *first = 0;
  return 1;
}
template <typename A, typename... B>
inline bool read(A &first, B &...second) {
  return read(first) && read(second...);
}
template <typename A>
inline bool write(A first) {
  if (!first) putc('0');
  if (first < 0) putc('-'), first = -first;
  while (first) qu[++qr] = first % 10 + '0', first /= 10;
  while (qr) putc(qu[qr--]);
  return 0;
}
inline bool write(char first) {
  putc(first);
  return 0;
}
inline bool write(const char *first) {
  while (*first) {
    putc(*first);
    ++first;
  }
  return 0;
}
inline bool write(char *first) {
  while (*first) {
    putc(*first);
    ++first;
  }
  return 0;
}
template <typename A, typename... B>
inline bool write(A first, B... second) {
  return write(first) || write(second...);
}
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_flusher_;
}  // namespace io
using io ::putc;
using io ::read;
using io ::write;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
const int p = 1000000007;
struct Z {
  unsigned first;
  Z() {}
  Z(unsigned a) { first = a; }
};
inline unsigned modp(const unsigned first) {
  return first < p ? first : first - p;
}
inline Z operator+(const Z x1, const Z x2) { return modp(x1.first + x2.first); }
inline Z operator-(const Z x1, const Z x2) {
  return modp(x1.first + p - x2.first);
}
inline Z operator-(const Z first) { return first.first ? p - first.first : 0; }
inline Z operator*(const Z x1, const Z x2) {
  return static_cast<unsigned long long>(x1.first) * x2.first % p;
}
void exgcd(int a, int b, int &first, int &second) {
  if (!b) {
    first = 1;
    second = 0;
    return;
  }
  exgcd(b, a % b, second, first);
  second -= (a / b) * first;
}
inline Z Inv(const Z a) {
  int first, second;
  exgcd(p, a.first, first, second);
  return second < 0 ? second += p : second;
}
inline Z operator/(const Z x1, const Z x2) { return x1 * Inv(x2); }
inline Z &operator++(Z &x1) {
  x1.first == p - 1 ? x1.first = 0 : ++x1.first;
  return x1;
}
inline Z &operator--(Z &x1) {
  x1.first ? --x1.first : x1.first = p - 1;
  return x1;
}
inline Z &operator+=(Z &x1, const Z x2) { return x1 = x1 + x2; }
inline Z &operator-=(Z &x1, const Z x2) { return x1 = x1 - x2; }
inline Z &operator*=(Z &x1, const Z x2) { return x1 = x1 * x2; }
inline Z &operator/=(Z &x1, const Z x2) { return x1 = x1 / x2; }
inline Z fpm(Z a, int b) {
  Z c(1);
  for (; b; b >>= 1, a *= a)
    if (b & 1) c *= a;
  return c;
}
Z ans;
int n, m;
char s0[2005], s1[2005], t[2005];
const int c = 3;
int xp[c], xq[c];
long long pw[c][4005], s0p[c][2005], s0s[c][2005], s1p[c][2005], s1s[c][2005],
    tp[c][2005], ts[c][2005];
int isp(int first) {
  if (first == 1) return 0;
  for (int i = 2; i * i <= first; ++i)
    if (!(first % i)) return 0;
  return 1;
}
int getp(int l, int r) {
  int w;
  while (!isp(w = rnd() % (r - l) + l))
    ;
  return w;
}
void init() {
  for (int i = 0; i < c; ++i) {
    xp[i] = getp(900000000, 1000000000);
    xq[i] = getp(1, 1000);
  }
  for (int i = 0; i < c; ++i) {
    long long p = xp[i], q = xq[i];
    for (int j = 1; j <= n; ++j) {
      s0p[i][j] = (s0p[i][j - 1] * q + (s0[j] - 'a')) % p;
      s1p[i][j] = (s1p[i][j - 1] * q + (s1[j] - 'a')) % p;
    }
    for (int j = 1; j <= m; ++j) {
      tp[i][j] = (tp[i][j - 1] * q + (t[j] - 'a')) % p;
    }
    for (int j = n; j; --j) {
      s0s[i][j] = (s0s[i][j + 1] * q + (s0[j] - 'a')) % p;
      s1s[i][j] = (s1s[i][j + 1] * q + (s1[j] - 'a')) % p;
    }
    for (int j = m; j; --j) {
      ts[i][j] = (ts[i][j + 1] * q + (t[j] - 'a')) % p;
    }
    pw[i][0] = 1;
    for (int j = 1; j <= n + n; ++j) pw[i][j] = pw[i][j - 1] * q % p;
  }
}
bool chkst0(int l, int r) {
  int L = r - l + 1;
  for (int i = 0; i < c; ++i) {
    long long p = xp[i];
    if ((s0p[i][r] + (s1s[i][l] - s0p[i][l - 1]) * pw[i][L] -
         s1s[i][r + 1] * pw[i][L << 1] - tp[i][L << 1]) %
        p)
      return 0;
  }
  return 1;
}
bool chkst1(int l, int r) {
  int L = r - l + 1;
  for (int i = 0; i < c; ++i) {
    long long p = xp[i];
    if ((s1p[i][r] + (s0s[i][l] - s1p[i][l - 1]) * pw[i][L] -
         s0s[i][r + 1] * pw[i][L << 1] - tp[i][L << 1]) %
        p)
      return 0;
  }
  return 1;
}
bool chked0(int l, int r) {
  int L = r - l + 1;
  for (int i = 0; i < c; ++i) {
    long long p = xp[i];
    if ((s0s[i][l] + (s1p[i][r] - s0s[i][r + 1]) * pw[i][L] -
         s1p[i][l - 1] * pw[i][L << 1] - ts[i][m - (L << 1) + 1]) %
        p)
      return 0;
  }
  return 1;
}
bool chked1(int l, int r) {
  int L = r - l + 1;
  for (int i = 0; i < c; ++i) {
    long long p = xp[i];
    if ((s1s[i][l] + (s0p[i][r] - s1s[i][r + 1]) * pw[i][L] -
         s0p[i][l - 1] * pw[i][L << 1] - ts[i][m - (L << 1) + 1]) %
        p)
      return 0;
  }
  return 1;
}
Z f[2005][2005][2];
void solve() {
  int k = (m - 1) >> 1;
  for (int i = 0; i <= n; ++i)
    for (int j = 0; j <= m; ++j) f[i][j][0] = f[i][j][1] = 0;
  for (int i = 0; i <= n; ++i) {
    ++f[i][0][0];
    ++f[i][0][1];
    for (int j = 2; j <= i && j <= k; ++j) {
      f[i][j << 1][0] += chkst0(i - j + 1, i);
      f[i][j << 1][1] += chkst1(i - j + 1, i);
    }
    ans += f[i][m][0] + f[i][m][1];
    for (int j = 2; j <= k && i + j <= n; ++j) {
      if (chked0(i + 1, i + j)) ans += f[i][m - (j << 1)][0];
      if (chked1(i + 1, i + j)) ans += f[i][m - (j << 1)][1];
    }
    for (int j = 0; j < m; ++j) {
      if (t[j + 1] == s0[i + 1]) f[i + 1][j + 1][0] += f[i][j][0];
      if (t[j + 1] == s1[i + 1]) f[i + 1][j + 1][1] += f[i][j][1];
      if (t[j + 1] == s0[i + 1] && t[j + 2] == s1[i + 1])
        f[i + 1][j + 2][1] += f[i][j][0];
      if (t[j + 1] == s1[i + 1] && t[j + 2] == s0[i + 1])
        f[i + 1][j + 2][0] += f[i][j][1];
    }
  }
}
signed main() {
  read(s0 + 1);
  read(s1 + 1);
  n = strlen(s0 + 1);
  read(t + 1);
  m = strlen(t + 1);
  if (m > n + n) return write("0");
  if (m == 1) {
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
      ans += t[1] == s0[i];
      ans += t[1] == s1[i];
    }
    return write(ans, '\n');
  }
  if (m == 2) {
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
      ans += (t[1] == s0[i] && t[2] == s1[i]);
      ans += (t[1] == s1[i] && t[2] == s0[i]);
      ans += (t[1] == s0[i] && t[2] == s0[i - 1]);
      ans += (t[1] == s1[i] && t[2] == s1[i - 1]);
      ans += (t[1] == s0[i] && t[2] == s0[i + 1]);
      ans += (t[1] == s1[i] && t[2] == s1[i + 1]);
    }
    return write(ans, '\n');
  }
  init();
  if (!(m & 1)) {
    int k = m >> 1;
    for (int i = 1; i + k - 1 <= n; ++i) {
      ans += chkst0(i, i + k - 1);
      ans += chkst1(i, i + k - 1);
      ans += chked0(i, i + k - 1);
      ans += chked1(i, i + k - 1);
    }
  }
  solve();
  reverse(s0 + 1, s0 + n + 1);
  reverse(s1 + 1, s1 + n + 1);
  init();
  solve();
  write(ans.first, '\n');
  return 0;
}