#include <bits/stdc++.h>
using namespace std;
#define ri register int
typedef long long ll;
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;
	// getchar
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	// print the remaining part
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	// putchar
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	// input a signed integer
	template <class I>
	inline void gi (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = (x << 1) + (x << 3) + (c & 15); x *= f;
	}
	// input a letter
	template <class I>
	inline void get (I &x) {
		for (c = gc(); c < 'A' || c > 'Z'; c = gc()) ;
		x = c;
	}
	// input a string
	inline void read (char *s){
		for(c = gc(); c < 'a' || c > 'z'; c = gc()) ;
		for(; c >= 'a' && c <= 'z'; c = gc()) *++s = c;
		*++s = '\0';
	}
	// print a signed integer
	template <class I>
	inline void print (I x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
	}
	//no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi;
using io :: get;
using io :: read;
using io :: putc;
using io :: print;
const int N=2e3+5,mod=1e9+7;
char s[2][N],w[N];
int f[2][N][N],g[2][N][N];
inline int _add(ri x,ri y){
	return (x+=y)>=mod?x-mod:x;
}
inline int _del(ri x,ri y){
	return (x-=y)<0?x+mod:x;
}
inline void add(int &x,ri y){
	x=(x+=y)>=mod?x-mod:x;
}
inline void del(int &x,ri y){
	x=(x-=y)<0?x+mod:x;
}
struct modint{
	int x;
	inline modint(int _x = 0) : x(_x) {}
	inline modint operator +(const modint &rhs)const{
		return modint(_add(x,rhs.x));
	}
	inline modint operator -(const modint &rhs)const{
		return modint(_del(x,rhs.x));
	}
	inline modint operator *(const modint &rhs)const{
		return modint((ll)x*rhs.x%mod);
	}
	inline bool operator ==(const modint &rhs)const{
		return x==rhs.x;
	}
};
#define fi first
#define se second
#define mp make_pair
#define Hash pair<modint,modint>
const Hash B = mp((modint)131,(modint)13331);
inline Hash operator + (Hash a,Hash b){
	return mp(a.fi+b.fi,a.se+b.se);
}
inline Hash operator - (Hash a,Hash b){
	return mp(a.fi-b.fi,a.se-b.se);
}
inline Hash operator * (Hash a,Hash b){
	return mp(a.fi*b.fi,a.se*b.se);
}
Hash p[N],pre[2][N],suf[2][N],prew[N];
inline Hash calc(ri dir,ri i,ri x,ri l){
	return dir?suf[i][x-l+1]-suf[i][x+1]*p[l]:pre[i][x+l-1]-pre[i][x-1]*p[l];
}
inline Hash calcw(ri x,ri l){
	return prew[x+l-1]-prew[x-1]*p[l];
}
int n,m;
inline int solve(){
	ri i,j,k,res,len,half,ans;
	for(j=0;j<=1;++j){
		for(i=1;i<=n;++i)
			pre[j][i]=pre[j][i-1]*B+mp(s[j][i],s[j][i]);
		for(i=n;i;--i)
			suf[j][i]=suf[j][i+1]*B+mp(s[j][i],s[j][i]);
	}
	for(i=1;i<=n;++i)
		prew[i]=prew[i-1]*B+mp(w[i],w[i]);
	memset(g,0,sizeof(g));
	memset(f,0,sizeof(f));
	for(i=1;i<=n;++i){
		g[0][i][1]=s[0][i]==w[1];
		g[1][i][1]=s[1][i]==w[1];
		for(j=1;j<=i&&j<<1<=m;++j)
			g[0][i][j<<1]=calc(1,1,i,j)*p[j]+calc(0,0,i-j+1,j)==calcw(1,j<<1),
			g[1][i][j<<1]=calc(1,0,i,j)*p[j]+calc(0,1,i-j+1,j)==calcw(1,j<<1);
	}
	for(k=1;k<m;++k)
		for(j=1;j<=n;++j)
			for(i=0;i<=1;++i){
				if(res=f[i][j][k]){
					if(j+1<=n&&s[i][j+1]==w[k+1])
						add(f[i][j+1][k+1],res);
					if(s[i^1][j]==w[k+1])
						add(g[i^1][j][k+1],res);
				}
				if(res=g[i][j][k]){
					if(j+1<=n&&s[i][j+1]==w[k+1])
						add(f[i][j+1][k+1],res);
				}
			}
	ans=0;
	for(k=1;k<m;++k)
		for(j=1;j<n;++j){
			res=_add(f[0][j][k],g[0][j][k]);
			if(res){
				len=m-k;
				if(len==1){
					if(s[0][j+1]==w[m])
						add(ans,res);
				}
				else if(~len&1){
					half=len>>1;
					if(j+1+half-1<=n&&calc(0,0,j+1,half)*p[half]+calc(1,1,j+1+half-1,half)==calcw(k+1,len))
						add(ans,res);
				}
			}
			res=_add(f[1][j][k],g[1][j][k]);
			if(res){
				len=m-k;
				if(len==1){
					if(s[1][j+1]==w[m])
						add(ans,res);
				}
				else if(~len&1){
					half=len>>1;
					if(j+1+half-1<=n&&calc(0,1,j+1,half)*p[half]+calc(1,0,j+1+half-1,half)==calcw(k+1,len))
						add(ans,res);
				}
			}
		}
	return ans;
}
int main(){
	ri i,j,half,ans;
	read(s[0]);
	read(s[1]);
	n=strlen(s[0]+1);
	read(w);
	m=strlen(w+1);
	if(m==1){
		ans=0;
		for(i=0;i<=1;++i)
			for(j=1;j<=n;++j)
				if(s[i][j]==w[1])
					++ans;
		printf("%d\n",ans);
		return 0;
	}
	p[0]=mp(modint(1),modint(1));
	for(i=1;i<=n;++i) p[i]=p[i-1]*B;
	ans=0;
	if(~m&1){
		half=m>>1;
		for(j=0;j<=1;++j){
			for(i=1;i<=n;++i)
				pre[j][i]=pre[j][i-1]*B+mp(s[j][i],s[j][i]);
			for(i=n;i;--i)
				suf[j][i]=suf[j][i+1]*B+mp(s[j][i],s[j][i]);
		}
		for(i=1;i<=n;++i)
			prew[i]=prew[i-1]*B+mp(w[i],w[i]);
		for(i=1;i<=n;++i){
			if(i>=half)
				ans+=calc(1,1,i,half)*p[half]+calc(0,0,i-half+1,half)==calcw(1,m),
				ans+=calc(1,0,i,half)*p[half]+calc(0,1,i-half+1,half)==calcw(1,m);
			if(half!=1&&i+half-1<=n)
				ans+=calc(0,1,i,half)*p[half]+calc(1,0,i+half-1,half)==calcw(1,m),
				ans+=calc(0,0,i,half)*p[half]+calc(1,1,i+half-1,half)==calcw(1,m);
		}
	}
	add(ans,solve());
	reverse(w+1,w+1+m);
	add(ans,solve());
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ri register int
typedef long long ll;
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;
	// getchar
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	// print the remaining part
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	// putchar
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	// input a signed integer
	template <class I>
	inline void gi (I &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = (x << 1) + (x << 3) + (c & 15); x *= f;
	}
	// input a letter
	template <class I>
	inline void get (I &x) {
		for (c = gc(); c < 'A' || c > 'Z'; c = gc()) ;
		x = c;
	}
	// input a string
	inline void read (char *s){
		for(c = gc(); c < 'a' || c > 'z'; c = gc()) ;
		for(; c >= 'a' && c <= 'z'; c = gc()) *++s = c;
		*++s = '\0';
	}
	// print a signed integer
	template <class I>
	inline void print (I x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
	}
	//no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: gi;
using io :: get;
using io :: read;
using io :: putc;
using io :: print;
const int N=2e3+5,mod=1e9+7;
char s[2][N],w[N];
int f[2][N][N],g[2][N][N];
inline int _add(ri x,ri y){
	return (x+=y)>=mod?x-mod:x;
}
inline int _del(ri x,ri y){
	return (x-=y)<0?x+mod:x;
}
inline void add(int &x,ri y){
	x=(x+=y)>=mod?x-mod:x;
}
inline void del(int &x,ri y){
	x=(x-=y)<0?x+mod:x;
}
struct modint{
	int x;
	inline modint(int _x = 0) : x(_x) {}
	inline modint operator +(const modint &rhs)const{
		return modint(_add(x,rhs.x));
	}
	inline modint operator -(const modint &rhs)const{
		return modint(_del(x,rhs.x));
	}
	inline modint operator *(const modint &rhs)const{
		return modint((ll)x*rhs.x%mod);
	}
	inline bool operator ==(const modint &rhs)const{
		return x==rhs.x;
	}
};
#define fi first
#define se second
#define mp make_pair
#define Hash pair<modint,modint>
const Hash B = mp((modint)131,(modint)13331);
inline Hash operator + (Hash a,Hash b){
	return mp(a.fi+b.fi,a.se+b.se);
}
inline Hash operator - (Hash a,Hash b){
	return mp(a.fi-b.fi,a.se-b.se);
}
inline Hash operator * (Hash a,Hash b){
	return mp(a.fi*b.fi,a.se*b.se);
}
Hash p[N],pre[2][N],suf[2][N],prew[N];
inline Hash calc(ri dir,ri i,ri x,ri l){
	return dir?suf[i][x-l+1]-suf[i][x+1]*p[l]:pre[i][x+l-1]-pre[i][x-1]*p[l];
}
inline Hash calcw(ri x,ri l){
	return prew[x+l-1]-prew[x-1]*p[l];
}
int n,m;
inline int solve(){
	ri i,j,k,res,len,half,ans;
	for(j=0;j<=1;++j){
		for(i=1;i<=n;++i)
			pre[j][i]=pre[j][i-1]*B+mp(s[j][i],s[j][i]);
		for(i=n;i;--i)
			suf[j][i]=suf[j][i+1]*B+mp(s[j][i],s[j][i]);
	}
	for(i=1;i<=n;++i)
		prew[i]=prew[i-1]*B+mp(w[i],w[i]);
	memset(g,0,sizeof(g));
	memset(f,0,sizeof(f));
	for(i=1;i<=n;++i){
		g[0][i][1]=s[0][i]==w[1];
		g[1][i][1]=s[1][i]==w[1];
		for(j=1;j<=i&&j<<1<=m;++j)
			g[0][i][j<<1]=calc(1,1,i,j)*p[j]+calc(0,0,i-j+1,j)==calcw(1,j<<1),
			g[1][i][j<<1]=calc(1,0,i,j)*p[j]+calc(0,1,i-j+1,j)==calcw(1,j<<1);
	}
	for(k=1;k<m;++k)
		for(j=1;j<=n;++j)
			for(i=0;i<=1;++i){
				if(res=f[i][j][k]){
					if(j+1<=n&&s[i][j+1]==w[k+1])
						add(f[i][j+1][k+1],res);
					if(s[i^1][j]==w[k+1])
						add(g[i^1][j][k+1],res);
				}
				if(res=g[i][j][k]){
					if(j+1<=n&&s[i][j+1]==w[k+1])
						add(f[i][j+1][k+1],res);
				}
			}
	ans=0;
	for(k=1;k<m;++k)
		for(j=1;j<n;++j){
			res=_add(f[0][j][k],g[0][j][k]);
			if(res){
				len=m-k;
				if(len==1){
					if(s[0][j+1]==w[m])
						add(ans,res);
				}
				else if(~len&1){
					half=len>>1;
					if(j+1+half-1<=n&&calc(0,0,j+1,half)*p[half]+calc(1,1,j+1+half-1,half)==calcw(k+1,len))
						add(ans,res);
				}
			}
			res=_add(f[1][j][k],g[1][j][k]);
			if(res){
				len=m-k;
				if(len==1){
					if(s[1][j+1]==w[m])
						add(ans,res);
				}
				else if(~len&1){
					half=len>>1;
					if(j+1+half-1<=n&&calc(0,1,j+1,half)*p[half]+calc(1,0,j+1+half-1,half)==calcw(k+1,len))
						add(ans,res);
				}
			}
		}
	return ans;
}
int main(){
	ri i,j,half,ans;
	read(s[0]);
	read(s[1]);
	n=strlen(s[0]+1);
	read(w);
	m=strlen(w+1);
	if(m==1){
		ans=0;
		for(i=0;i<=1;++i)
			for(j=1;j<=n;++j)
				if(s[i][j]==w[1])
					++ans;
		printf("%d\n",ans);
		return 0;
	}
	p[0]=mp(modint(1),modint(1));
	for(i=1;i<=n;++i) p[i]=p[i-1]*B;
	ans=0;
	if(~m&1){
		half=m>>1;
		for(j=0;j<=1;++j){
			for(i=1;i<=n;++i)
				pre[j][i]=pre[j][i-1]*B+mp(s[j][i],s[j][i]);
			for(i=n;i;--i)
				suf[j][i]=suf[j][i+1]*B+mp(s[j][i],s[j][i]);
		}
		for(i=1;i<=m;++i)
			prew[i]=prew[i-1]*B+mp(w[i],w[i]);
		for(i=1;i<=n;++i){
			if(i>=half)
				ans+=calc(1,1,i,half)*p[half]+calc(0,0,i-half+1,half)==calcw(1,m),
				ans+=calc(1,0,i,half)*p[half]+calc(0,1,i-half+1,half)==calcw(1,m);
			Hash o=calc(1,1,i,half)*p[half]+calc(0,0,i-half+1,half);
			if(half!=1&&i+half-1<=n)
				ans+=calc(0,1,i,half)*p[half]+calc(1,0,i+half-1,half)==calcw(1,m),
				ans+=calc(0,0,i,half)*p[half]+calc(1,1,i+half-1,half)==calcw(1,m);
		}
	}
	add(ans,solve());
	reverse(w+1,w+1+m);
	add(ans,solve());
	printf("%d\n",ans);
	return 0;
}


#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>

typedef long long ll;
typedef double ld;
typedef unsigned long long ull;

using namespace std;

const int MAXN = 2100;
const ull P = 23917;

const int MOD = 1000000007;
ull pw[MAXN];
char s[2][MAXN];
char t[MAXN];
ull hss[2][MAXN];
ull bhss[2][MAXN];
ull hst[MAXN];
int n, m;
int ans = 0;
int dp[2][MAXN][MAXN];

void ad(int &a, int b) {
	a += b;
	if (a >= MOD)
		a -= MOD;
}

void initHash() {
	pw[0] = 1;
	for (int i = 1; i < MAXN; ++i)
		pw[i] = pw[i - 1] * P;
	for (int i = 0; i < 2; ++i) {
		hss[i][0] = 0;
		for (int j = 0; j < n; ++j)
			hss[i][j + 1] = hss[i][j] * P + s[i][j];
		bhss[i][n] = 0;
		for (int j = n - 1; j >= 0; --j)
			bhss[i][j] = bhss[i][j + 1] * P + s[i][j];
	}
	hst[0] = 0;
	for (int j = 0; j < m; ++j)
		hst[j + 1] = hst[j] * P + t[j];
}

ull getHs(int x, int l, int r) {
	if (x == 0 || x == 1) {
		return hss[x][r] - hss[x][l] * pw[r - l];
	}
	return hst[r] - hst[l] * pw[r - l];
}

ull getBHs(int x, int l, int r) {
	return bhss[x][l] - bhss[x][r] * pw[r - l];
}

void solve() {
	initHash();
	for (int i = 0; i < 2; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 0; k <= m; ++k)
				dp[i][j][k] = 0;
	dp[0][n][0] = 1;
	dp[1][n][0] = 1;
	for (int i = n - 1; i >= 0; --i) {
		dp[0][i][0] = 1;
		dp[1][i][0] = 1;
		if (s[0][i] == t[m - 1])
			dp[0][i][1] = 1;
		if (s[1][i] == t[m - 1])
			dp[1][i][1] = 1;
		for (int k = 2; k <= m; ++k) {
			if ((n - i) * 2 < k)
				break;
			if (s[0][i] == t[m - k]) {
				if (s[1][i] == t[m - k + 1])
					ad(dp[0][i][k], dp[1][i + 1][k - 2]);
				ad(dp[0][i][k], dp[0][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(0, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(1, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[0][i][k], 1);
				}
			}
			if (s[1][i] == t[m - k]) {
				if (s[0][i] == t[m - k + 1])
					ad(dp[1][i][k], dp[0][i + 1][k - 2]);
				ad(dp[1][i][k], dp[1][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(1, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(0, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[1][i][k], 1);
				}
			}
		}
		for (int k = 1; k <= m; ++k) {
			if (k == m) {
				ad(ans, dp[0][i][k]);
				ad(ans, dp[1][i][k]);
			}
			if (2 * i >= m - k && m - k > 2 && (m - k) % 2 == 0) {
				int x = (m - k);
				if (getHs(0, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(1, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[0][i][k]);
				if (getHs(1, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(0, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[1][i][k]);
			}
		}
	}
}

int main() {
	scanf(" %s %s %s", s[0], s[1], t);
	n = strlen(s[0]);
	m = strlen(t);
	solve();
	if (m != 1) {
	//	reverse(t, t + m);
		reverse(s[0], s[0] + n);
		reverse(s[1], s[1] + n);
		solve();
	}
	if (m == 2) {
		for (int i = 0; i < n; ++i) {
			if (s[0][i] == t[0] && s[1][i] == t[1])
				--ans;
			if (s[1][i] == t[0] && s[0][i] == t[1])
				--ans;
		}
	}
	ad(ans, MOD);
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>

typedef long long ll;
typedef double ld;
//typedef unsigned long long ull;

using namespace std;
const ll M1 = 1000000007;
const ll M2 = 1000000009;

struct ull {
	ll a, b;
	ull() {
		a = b = 0;
	}
	ull(ll x) {
		a = b = x;
	}
	ull operator+(ull x) {
		ull ans;
		ans.a = a + x.a;
		ans.b = b + x.b;
		if (ans.a >= M1)
			ans.a -= M1;
		if (ans.b >= M2)
			ans.b -= M2;
		return ans;
	}
	ull operator-(ull x) {
		ull ans;
		ans.a = a - x.a;
		ans.b = b - x.b;
		if (ans.a < 0)
			ans.a += M1;
		if (ans.b < 0)
			ans.b += M2;
		return ans;
	}
	ull operator*(ull x) {
		ull ans;
		ans.a = (a * x.a) % M1;
		ans.b = (b * x.b) % M2;
		return ans;
	}
	bool operator==(ull x) {
		return a == x.a && b == x.b;
	}

};

const int MAXN = 2100;
const ull P = 23917;

const int MOD = 1000000007;
ull pw[MAXN];
char s[2][MAXN];
char t[MAXN];
ull hss[2][MAXN];
ull bhss[2][MAXN];
ull hst[MAXN];
int n, m;
int ans = 0;
int dp[2][MAXN][MAXN];

void ad(int &a, int b) {
	a += b;
	if (a >= MOD)
		a -= MOD;
}

void initHash() {
	pw[0] = 1;
	for (int i = 1; i < MAXN; ++i)
		pw[i] = pw[i - 1] * P;
	for (int i = 0; i < 2; ++i) {
		hss[i][0] = 0;
		for (int j = 0; j < n; ++j)
			hss[i][j + 1] = hss[i][j] * P + s[i][j];
		bhss[i][n] = 0;
		for (int j = n - 1; j >= 0; --j)
			bhss[i][j] = bhss[i][j + 1] * P + s[i][j];
	}
	hst[0] = 0;
	for (int j = 0; j < m; ++j)
		hst[j + 1] = hst[j] * P + t[j];
}

ull getHs(int x, int l, int r) {
	if (x == 0 || x == 1) {
		return hss[x][r] - hss[x][l] * pw[r - l];
	}
	return hst[r] - hst[l] * pw[r - l];
}

ull getBHs(int x, int l, int r) {
	return bhss[x][l] - bhss[x][r] * pw[r - l];
}

void solve() {
	initHash();
	for (int i = 0; i < 2; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 0; k <= m; ++k)
				dp[i][j][k] = 0;
	dp[0][n][0] = 1;
	dp[1][n][0] = 1;
	for (int i = n - 1; i >= 0; --i) {
		dp[0][i][0] = 1;
		dp[1][i][0] = 1;
		if (s[0][i] == t[m - 1])
			dp[0][i][1] = 1;
		if (s[1][i] == t[m - 1])
			dp[1][i][1] = 1;
		for (int k = 2; k <= m; ++k) {
			if ((n - i) * 2 < k)
				break;
			if (s[0][i] == t[m - k]) {
				if (s[1][i] == t[m - k + 1])
					ad(dp[0][i][k], dp[1][i + 1][k - 2]);
				ad(dp[0][i][k], dp[0][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(0, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(1, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[0][i][k], 1);
				}
			}
			if (s[1][i] == t[m - k]) {
				if (s[0][i] == t[m - k + 1])
					ad(dp[1][i][k], dp[0][i + 1][k - 2]);
				ad(dp[1][i][k], dp[1][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(1, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(0, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[1][i][k], 1);
				}
			}
		}
		for (int k = 1; k <= m; ++k) {
			if (k == m) {
				ad(ans, dp[0][i][k]);
				ad(ans, dp[1][i][k]);
			}
			if (2 * i >= m - k && m - k > 2 && (m - k) % 2 == 0) {
				int x = (m - k);
				if (getHs(0, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(1, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[0][i][k]);
				if (getHs(1, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(0, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[1][i][k]);
			}
		}
	}
}

int main() {
	scanf(" %s %s %s", s[0], s[1], t);
	n = strlen(s[0]);
	m = strlen(t);
	solve();
	if (m != 1) {
		reverse(t, t + m);
		solve();
	}
	if (m == 2) {
		for (int i = 0; i < n; ++i) {
			if (s[0][i] == t[0] && s[1][i] == t[1])
				--ans;
			if (s[1][i] == t[0] && s[0][i] == t[1])
				--ans;
		}
	}
	ad(ans, MOD);
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>

typedef long long ll;
typedef double ld;
typedef unsigned long long ull;

using namespace std;
const ll M1 = 1000000007;
const ll M2 = 1000000009;

/*struct ull {
	ll a, b;
	ull() {
		a = b = 0;
	}
	ull(ll x) {
		a = b = x;
	}
	ull operator+(ull x) {
		ull ans;
		ans.a = a + x.a;
		ans.b = b + x.b;
		if (ans.a >= M1)
			ans.a -= M1;
		if (ans.b >= M2)
			ans.b -= M2;
		return ans;
	}
	ull operator-(ull x) {
		ull ans;
		ans.a = a - x.a;
		ans.b = b - x.b;
		if (ans.a < 0)
			ans.a += M1;
		if (ans.b < 0)
			ans.b += M2;
		return ans;
	}
	ull operator*(ull x) {
		ull ans;
		ans.a = (a * x.a) % M1;
		ans.b = (b * x.b) % M2;
		return ans;
	}
	bool operator==(ull x) {
		return a == x.a && b == x.b;
	}

};*/

const int MAXN = 2100;
const ull P = 23917;

const int MOD = 1000000007;
ull pw[MAXN];
char s[2][MAXN];
char t[MAXN];
ull hss[2][MAXN];
ull bhss[2][MAXN];
ull hst[MAXN];
int n, m;
int ans = 0;
int dp[2][MAXN][MAXN];

void ad(int &a, int b) {
	a += b;
	if (a >= MOD)
		a -= MOD;
}

void initHash() {
	pw[0] = 1;
	for (int i = 1; i < MAXN; ++i)
		pw[i] = pw[i - 1] * P;
	for (int i = 0; i < 2; ++i) {
		hss[i][0] = 0;
		for (int j = 0; j < n; ++j)
			hss[i][j + 1] = hss[i][j] * P + s[i][j];
		bhss[i][n] = 0;
		for (int j = n - 1; j >= 0; --j)
			bhss[i][j] = bhss[i][j + 1] * P + s[i][j];
	}
	hst[0] = 0;
	for (int j = 0; j < m; ++j)
		hst[j + 1] = hst[j] * P + t[j];
}

ull getHs(int x, int l, int r) {
	if (x == 0 || x == 1) {
		return hss[x][r] - hss[x][l] * pw[r - l];
	}
	return hst[r] - hst[l] * pw[r - l];
}

ull getBHs(int x, int l, int r) {
	return bhss[x][l] - bhss[x][r] * pw[r - l];
}

void solve() {
	initHash();
	for (int i = 0; i < 2; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 0; k <= m; ++k)
				dp[i][j][k] = 0;
	dp[0][n][0] = 1;
	dp[1][n][0] = 1;
	for (int i = n - 1; i >= 0; --i) {
		dp[0][i][0] = 1;
		dp[1][i][0] = 1;
		if (s[0][i] == t[m - 1])
			dp[0][i][1] = 1;
		if (s[1][i] == t[m - 1])
			dp[1][i][1] = 1;
		for (int k = 2; k <= m; ++k) {
			if ((n - i) * 2 < k)
				break;
			if (s[0][i] == t[m - k]) {
				if (s[1][i] == t[m - k + 1])
					ad(dp[0][i][k], dp[1][i + 1][k - 2]);
				ad(dp[0][i][k], dp[0][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(0, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(1, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[0][i][k], 1);
				}
			}
			if (s[1][i] == t[m - k]) {
				if (s[0][i] == t[m - k + 1])
					ad(dp[1][i][k], dp[0][i + 1][k - 2]);
				ad(dp[1][i][k], dp[1][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(1, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(0, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[1][i][k], 1);
				}
			}
		}
		for (int k = 1; k <= m; ++k) {
			if (k == m) {
				ad(ans, dp[0][i][k]);
				ad(ans, dp[1][i][k]);
			}
			if (2 * i >= m - k && m - k > 2 && (m - k) % 2 == 0) {
				int x = (m - k);
				if (getHs(0, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(1, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[0][i][k]);
				if (getHs(1, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(0, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[1][i][k]);
			}
		}
	}
}

int main() {
	scanf(" %s %s %s", s[0], s[1], t);
	n = strlen(s[0]);
	m = strlen(t);
	solve();
	if (m != 1) {
	//	reverse(t, t + m);
		reverse(s[0], s[0] + n);
		reverse(s[1], s[1] + n);
		solve();
	}
	if (m == 2) {
		for (int i = 0; i < n; ++i) {
			if (s[0][i] == t[0] && s[1][i] == t[1])
				--ans;
			if (s[1][i] == t[0] && s[0][i] == t[1])
				--ans;
		}
	}
	ad(ans, MOD);
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>

typedef long long ll;
typedef double ld;
typedef unsigned long long ull;

using namespace std;

const int MAXN = 2100;
const ull P = 23917;

const int MOD = 1000000007;
ull pw[MAXN];
char s[2][MAXN];
char t[MAXN];
ull hss[2][MAXN];
ull bhss[2][MAXN];
ull hst[MAXN];
int n, m;
int ans = 0;
int dp[2][MAXN][MAXN];

void ad(int &a, int b) {
	a += b;
	if (a >= MOD)
		a -= MOD;
}

void initHash() {
	pw[0] = 1;
	for (int i = 1; i < MAXN; ++i)
		pw[i] = pw[i - 1] * P;
	for (int i = 0; i < 2; ++i) {
		hss[i][0] = 0;
		for (int j = 0; j < n; ++j)
			hss[i][j + 1] = hss[i][j] * P + s[i][j];
		bhss[i][n] = 0;
		for (int j = n - 1; j >= 0; --j)
			bhss[i][j] = bhss[i][j + 1] * P + s[i][j];
	}
	hst[0] = 0;
	for (int j = 0; j < m; ++j)
		hst[j + 1] = hst[j] * P + t[j];
}

ull getHs(int x, int l, int r) {
	if (x == 0 || x == 1) {
		return hss[x][r] - hss[x][l] * pw[r - l];
	}
	return hst[r] - hst[l] * pw[r - l];
}

ull getBHs(int x, int l, int r) {
	return bhss[x][l] - bhss[x][r] * pw[r - l];
}

void solve() {
	initHash();
	for (int i = 0; i < 2; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 0; k <= m; ++k)
				dp[i][j][k] = 0;
	dp[0][n][0] = 1;
	dp[1][n][0] = 1;
	for (int i = n - 1; i >= 0; --i) {
		dp[0][i][0] = 1;
		dp[1][i][0] = 1;
		if (s[0][i] == t[m - 1])
			dp[0][i][1] = 1;
		if (s[1][i] == t[m - 1])
			dp[1][i][1] = 1;
		for (int k = 2; k <= m; ++k) {
			if ((n - i) * 2 < k)
				break;
			if (s[0][i] == t[m - k]) {
				if (s[1][i] == t[m - k + 1])
					ad(dp[0][i][k], dp[1][i + 1][k - 2]);
				ad(dp[0][i][k], dp[0][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(0, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(1, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[0][i][k], 1);
				}
			}
			if (s[1][i] == t[m - k]) {
				if (s[0][i] == t[m - k + 1])
					ad(dp[1][i][k], dp[0][i + 1][k - 2]);
				ad(dp[1][i][k], dp[1][i + 1][k - 1]);
				if (k > 2 && k % 2 == 0) {
					if (getHs(1, i, i + k / 2) == getHs(2, m - k, m - k + k / 2) && getBHs(0, i, i + k / 2) == getHs(2, m - k + k / 2, m))
						ad(dp[1][i][k], 1);
				}
			}
		}
		for (int k = 1; k <= m; ++k) {
			if (k == m) {
				ad(ans, dp[0][i][k]);
				ad(ans, dp[1][i][k]);
			}
			if (2 * i >= m - k && m - k > 2 && (m - k) % 2 == 0) {
				int x = (m - k);
				if (getHs(0, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(1, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[0][i][k]);
				if (getHs(1, i - x / 2, i) == getHs(2, x / 2, x) && getBHs(0, i - x / 2, i) == getHs(2, 0, x / 2))
					ad(ans, dp[1][i][k]);
			}
		}
	}
}

int main() {
	scanf(" %s %s %s", s[0], s[1], t);
	n = strlen(s[0]);
	m = strlen(t);
	solve();
	if (m != 1) {
		reverse(t, t + m);
		solve();
	}
	if (m == 2) {
		for (int i = 0; i < n; ++i) {
			if (s[0][i] == t[0] && s[1][i] == t[1])
				--ans;
			if (s[1][i] == t[0] && s[0][i] == t[1])
				--ans;
		}
	}
	ad(ans, MOD);
	cout << ans << "\n";
	return 0;
}


#include <bits/stdc++.h>

template<typename T> struct xgcd_s { T m, n, gcd; }; template<typename T> xgcd_s<T> xgcd(T a, T b) { T m[] = {1,0}, n[] = {0,1}, q[] = {0,0}; for(int i = 0; ; i^=1) { m[i] -= m[i^1] * q[i]; n[i] -= n[i^1] * q[i]; if(!b) return xgcd_s<T>{m[i],n[i],a}; q[i] = a/b; a %= b; std::swap(a,b); } } template<unsigned M()> struct _intmod { private: struct _p {unsigned x; }; _intmod(_p x) { n = x.x; } public: unsigned n; _intmod() {n = 0;} _intmod(int x) { n = x<0? M()+x%(int)M(): x%M(); } _intmod(unsigned x) {n = x%M(); } _intmod(long long x) {n = unsigned(x<0? M()+x%(long long)M(): x%M()); } _intmod operator+(_intmod b) {return {n+b.n}; } _intmod operator*(_intmod b) {return {_p{unsigned((unsigned long long)n * b.n % M())}}; } _intmod operator-(_intmod b) {return {_p{n>=b.n? n-b.n : M()+n-b.n }}; } _intmod operator-() {return {_p{n?M()-n:0U}}; } _intmod& operator+=(_intmod b) { return(*this = *this + b); } _intmod& operator-=(_intmod b) { return(*this = *this - b); } _intmod& operator/=(_intmod b) { return(*this = *this / b); } _intmod& operator*=(_intmod b) { return(*this = *this * b); } static _intmod mulinv(_intmod n) { xgcd_s<signed> x = xgcd<signed>(n.n, M()); assert(x.gcd == 1); return x.m; } _intmod operator/(_intmod b) { return *this * mulinv(b); } bool operator==(_intmod b) { return n == b.n; } bool operator!=(_intmod b) { return n != b.n; } explicit operator int() { return n; } }; template<unsigned M()> std::ostream& operator<<(std::ostream& o, _intmod<M> n) { return o<<n.n; } template<unsigned M()> std::istream& operator>>(std::istream& i, _intmod<M>& n) { long long x; i>>x; n = x; return i; } template<unsigned M> unsigned intmod_unsignedconst() { static_assert(M>0 && M<(1U<<31), "modulus bad"); return M; } template<unsigned*M> unsigned intmod_unsignedptr() { return *M; } template<unsigned M> using intmod = _intmod<intmod_unsignedconst<M> >; template<unsigned*M> using intmodv = _intmod<intmod_unsignedptr<M> >; static_assert(std::is_trivially_copyable<intmod<3> >::value, "");
template<typename ChIter> struct kmp { ChIter pattern; size_t len; int* t = nullptr; ~kmp() { delete t; } kmp() {} kmp(ChIter a, size_t length) { init(a, length); } void compute_table() { t[0] = -1; for(size_t i = 0; i < len; i++) { int v = t[i] + 1; while(v && pattern[i] != pattern[v - 1]) v = t[v - 1] + 1; t[i+1] = v; } } void init(const ChIter a, size_t length) { delete t; pattern = a; len = length; t = new int[length + 1]; compute_table(); } struct scanner_s { size_t matchedLen = 0; const kmp& k; scanner_s(const kmp& k): k(k) { assert(k.len > 0); } bool operator()(const decltype(*pattern)& c) { while(matchedLen && !(c == k.pattern[matchedLen])) matchedLen = k.t[matchedLen]; bool mnext = matchedLen || c == k.pattern[0]; if(mnext) { matchedLen++; if (matchedLen == k.len) { matchedLen = k.t[matchedLen]; return true; } } return false; } }; scanner_s scanner() { return scanner_s{*this}; } };

using namespace std;

#define N 2001

typedef intmod<1000000007> I;

char grid[2][N];
char word[N*2];

I l[2][N][2*N],
  m[2][N][2*N],
  h[2][N][N];

int n,q;

int B(int i, int j, int k) {
    return word[k-1] == grid[i][j];
}

#define Z(A) memset(A, 0, sizeof(A))

I count() {
    for(int p = 2; 2*p < q; p++) {
        kmp<char*> k0(word + q - 2*p, p);
        kmp<reverse_iterator<char*>> k1(reverse_iterator<char*>{word + q}, p);
        for(int i: {0,1}) {
            auto s0 = k0.scanner();
            auto s1 = k1.scanner();
            for(int j = 0; j < n; j++) {
                if(s0(grid[i][j]) & s1(grid[i^1][j]))
                    h[i][j][p] = 1;
            }
        }
    }

    for(int p = 2; 2*p <= q; p++) {
        kmp<reverse_iterator<char*>> k0(reverse_iterator<char*>{word + p}, p);
        kmp<char*> k1(word + p, p);
        for(int i: {0,1}) {
            auto s0 = k0.scanner();
            auto s1 = k1.scanner();
            for(int j = 0; j < n; j++) {
                if(s0(grid[i^1][j]) & s1(grid[i][j]))
                    m[i][j][2*p] = 1;
            }
        }
    }

    for(int j = 0; j < n; j++) {
        for(int i: {0,1}) {
            l[i][j][1] = B(i,j,1);
            if(j) {
                for(int c = 2; c <= q; c++)
                    l[i][j][c] = (l[i][j-1][c-1] + m[i][j-1][c-1]) * B(i,j,c);
            }
        }
        for(int i: {0, 1}) {
            for(int c = 2; c <= q; c++)
                m[i][j][c] += l[i^1][j][c-1] * B(i,j,c);
        }
    }
    I a = 0;
    for(int j = 0; j < n; j++)
        for(int i: {0,1})
            a += l[i][j][q] + m[i][j][q];
    for(int p = 2; 2*p < q; p++) {
        for(int j = 0; j + p < n; j++) {
            for(int i: {0,1}) {
                a += (l[i][j][q - 2*p] + m[i][j][q - 2*p]) * h[i][j+1][p];
            }
        }
    }
    return a;
}

int main()
{
    ios_base::sync_with_stdio(0);

    scanf("%s %s %s", grid[0], grid[1], word);
    n = strlen(grid[0]);
    q = strlen(word);

    if(q == 2) {
        I a = 0;
        for(int j = 0; j < n; j++) {
            a += B(0,j,1) && B(1,j,2);
            a += B(1,j,1) && B(0,j,2);
        }
        for(int i: {0,1} )
            for(int j = 1; j < n; j++) {
                a += B(i,j-1,1) && B(i,j,2);
                a += B(i,j,1) && B(i,j-1,2);
            }
        cout << a;
        return 0;
    }

    I ans = count();

    if(q > 2) {
        Z(l); Z(m); Z(h);
        reverse(grid[0], grid[0]+n);
        reverse(grid[1], grid[1]+n);
        ans += count();
    }

    cout << ans;

    return 0;
}


#include <bits/stdc++.h>

template<typename T> struct xgcd_s { T m, n, gcd; }; template<typename T> xgcd_s<T> xgcd(T a, T b) { T m[] = {1,0}, n[] = {0,1}, q[] = {0,0}; for(int i = 0; ; i^=1) { m[i] -= m[i^1] * q[i]; n[i] -= n[i^1] * q[i]; if(!b) return xgcd_s<T>{m[i],n[i],a}; q[i] = a/b; a %= b; std::swap(a,b); } } template<unsigned M()> struct _intmod { private: struct _p {unsigned x; }; _intmod(_p x) { n = x.x; } public: unsigned n; _intmod() {n = 0;} _intmod(int x) { n = x<0? M()+x%(int)M(): x%M(); } _intmod(unsigned x) {n = x%M(); } _intmod(long long x) {n = unsigned(x<0? M()+x%(long long)M(): x%M()); } _intmod operator+(_intmod b) {return {n+b.n}; } _intmod operator*(_intmod b) {return {_p{unsigned((unsigned long long)n * b.n % M())}}; } _intmod operator-(_intmod b) {return {_p{n>=b.n? n-b.n : M()+n-b.n }}; } _intmod operator-() {return {_p{n?M()-n:0U}}; } _intmod& operator+=(_intmod b) { return(*this = *this + b); } _intmod& operator-=(_intmod b) { return(*this = *this - b); } _intmod& operator/=(_intmod b) { return(*this = *this / b); } _intmod& operator*=(_intmod b) { return(*this = *this * b); } static _intmod mulinv(_intmod n) { xgcd_s<signed> x = xgcd<signed>(n.n, M()); assert(x.gcd == 1); return x.m; } _intmod operator/(_intmod b) { return *this * mulinv(b); } bool operator==(_intmod b) { return n == b.n; } bool operator!=(_intmod b) { return n != b.n; } explicit operator int() { return n; } }; template<unsigned M()> std::ostream& operator<<(std::ostream& o, _intmod<M> n) { return o<<n.n; } template<unsigned M()> std::istream& operator>>(std::istream& i, _intmod<M>& n) { long long x; i>>x; n = x; return i; } template<unsigned M> unsigned intmod_unsignedconst() { static_assert(M>0 && M<(1U<<31), "modulus bad"); return M; } template<unsigned*M> unsigned intmod_unsignedptr() { return *M; } template<unsigned M> using intmod = _intmod<intmod_unsignedconst<M> >; template<unsigned*M> using intmodv = _intmod<intmod_unsignedptr<M> >; static_assert(std::is_trivially_copyable<intmod<3> >::value, "");
template<typename ChIter> struct kmp { ChIter pattern; size_t len; int* t = nullptr; ~kmp() { delete t; } kmp() {} kmp(ChIter a, size_t length) { init(a, length); } void compute_table() { t[0] = -1; for(size_t i = 0; i < len; i++) { int v = t[i] + 1; while(v && pattern[i] != pattern[v - 1]) v = t[v - 1] + 1; t[i+1] = v; } } void init(const ChIter a, size_t length) { delete t; pattern = a; len = length; t = new int[length + 1]; compute_table(); } struct scanner_s { size_t matchedLen = 0; const kmp& k; scanner_s(const kmp& k): k(k) { assert(k.len > 0); } bool operator()(const decltype(*pattern)& c) { while(matchedLen && !(c == k.pattern[matchedLen])) matchedLen = k.t[matchedLen]; bool mnext = matchedLen || c == k.pattern[0]; if(mnext) { matchedLen++; if (matchedLen == k.len) { matchedLen = k.t[matchedLen]; return true; } } return false; } }; scanner_s scanner() { return scanner_s{*this}; } };

using namespace std;

#define N 2001

typedef intmod<1000000007> I;

char grid[2][N];
char word[N*2];

I l[2][N][2*N],
  m[2][N][2*N],
  h[2][N][N];

int n,q;

int B(int i, int j, int k) {
    return word[k-1] == grid[i][j];
}

#define Z(A) memset(A, 0, sizeof(A))

I count() {
    for(int p = 2; 2*p < q; p++) {
        kmp<char*> k0(word + q - 2*p, p);
        kmp<reverse_iterator<char*>> k1(reverse_iterator<char*>{word + q}, p);
        for(int i: {0,1}) {
            auto s0 = k0.scanner();
            auto s1 = k1.scanner();
            for(int j = 0; j < n; j++) {
                if(s0(grid[i][j]) & s1(grid[i^1][j]))
                    h[i][j][p] = 1;
            }
        }
    }

    for(int p = 2; 2*p <= q; p++) {
        kmp<reverse_iterator<char*>> k0(reverse_iterator<char*>{word + p}, p);
        kmp<char*> k1(word + p, p);
        for(int i: {0,1}) {
            auto s0 = k0.scanner();
            auto s1 = k1.scanner();
            for(int j = 0; j < n; j++) {
                if(s0(grid[i^1][j]) & s1(grid[i][j]))
                    m[i][j][2*p] = 1;
            }
        }
    }

    for(int j = 0; j < n; j++) {
        for(int i: {0,1}) {
            l[i][j][1] = B(i,j,1);
            for(int c = 2; c <= q; c++) {
                if(j)
                    l[i][j][c] = l[i][j-1][c-1] * B(i,j,c);
                m[i][j][c] += l[i^1][j][c-1] * B(i,j,c);
            }
        }
    }
    I a = 0;
    for(int j = 0; j < n; j++)
        for(int i: {0,1})
            a += l[i][j][q] + m[i][j][q];
    for(int p = 2; 2*p < q; p++) {
        for(int j = 0; j + p < n; j++) {
            for(int i: {0,1}) {
                a += (l[i][j][q - 2*p] + m[i][j][q - 2*p]) * h[i][j+1][p];
            }
        }
    }
    return a;
}

int main()
{
    ios_base::sync_with_stdio(0);

    scanf("%s %s %s", grid[0], grid[1], word);
    n = strlen(grid[0]);
    q = strlen(word);

    if(q == 2) {
        I a = 0;
        for(int j = 0; j < n; j++) {
            a += B(0,j,1) && B(1,j,2);
            a += B(1,j,1) && B(0,j,2);
        }
        for(int i: {0,1} )
            for(int j = 1; j < n; j++) {
                a += B(i,j-1,1) && B(i,j,2);
                a += B(i,j,1) && B(i,j-1,2);
            }
        cout << a;
        return 0;
    }

    I ans = count();

    if(q > 2) {
        Z(l); Z(m); Z(h);
        reverse(grid[0], grid[0]+n);
        reverse(grid[1], grid[1]+n);
        ans += count();
    }

    cout << ans;

    return 0;
}


#include <bits/stdc++.h>

template<typename T> struct xgcd_s { T m, n, gcd; }; template<typename T> xgcd_s<T> xgcd(T a, T b) { T m[] = {1,0}, n[] = {0,1}, q[] = {0,0}; for(int i = 0; ; i^=1) { m[i] -= m[i^1] * q[i]; n[i] -= n[i^1] * q[i]; if(!b) return xgcd_s<T>{m[i],n[i],a}; q[i] = a/b; a %= b; std::swap(a,b); } } template<unsigned M()> struct _intmod { private: struct _p {unsigned x; }; _intmod(_p x) { n = x.x; } public: unsigned n; _intmod() {n = 0;} _intmod(int x) { n = x<0? M()+x%(int)M(): x%M(); } _intmod(unsigned x) {n = x%M(); } _intmod(long long x) {n = unsigned(x<0? M()+x%(long long)M(): x%M()); } _intmod operator+(_intmod b) {return {n+b.n}; } _intmod operator*(_intmod b) {return {_p{unsigned((unsigned long long)n * b.n % M())}}; } _intmod operator-(_intmod b) {return {_p{n>=b.n? n-b.n : M()+n-b.n }}; } _intmod operator-() {return {_p{n?M()-n:0U}}; } _intmod& operator+=(_intmod b) { return(*this = *this + b); } _intmod& operator-=(_intmod b) { return(*this = *this - b); } _intmod& operator/=(_intmod b) { return(*this = *this / b); } _intmod& operator*=(_intmod b) { return(*this = *this * b); } static _intmod mulinv(_intmod n) { xgcd_s<signed> x = xgcd<signed>(n.n, M()); assert(x.gcd == 1); return x.m; } _intmod operator/(_intmod b) { return *this * mulinv(b); } bool operator==(_intmod b) { return n == b.n; } bool operator!=(_intmod b) { return n != b.n; } explicit operator int() { return n; } }; template<unsigned M()> std::ostream& operator<<(std::ostream& o, _intmod<M> n) { return o<<n.n; } template<unsigned M()> std::istream& operator>>(std::istream& i, _intmod<M>& n) { long long x; i>>x; n = x; return i; } template<unsigned M> unsigned intmod_unsignedconst() { static_assert(M>0 && M<(1U<<31), "modulus bad"); return M; } template<unsigned*M> unsigned intmod_unsignedptr() { return *M; } template<unsigned M> using intmod = _intmod<intmod_unsignedconst<M> >; template<unsigned*M> using intmodv = _intmod<intmod_unsignedptr<M> >; static_assert(std::is_trivially_copyable<intmod<3> >::value, "");
template<typename ChIter> struct kmp { ChIter pattern; size_t len; int* t = nullptr; ~kmp() { delete t; } kmp() {} kmp(ChIter a, size_t length) { init(a, length); } void compute_table() { t[0] = -1; for(size_t i = 0; i < len; i++) { int v = t[i] + 1; while(v && pattern[i] != pattern[v - 1]) v = t[v - 1] + 1; t[i+1] = v; } } void init(const ChIter a, size_t length) { delete t; pattern = a; len = length; t = new int[length + 1]; compute_table(); } struct scanner_s { size_t matchedLen = 0; const kmp& k; scanner_s(const kmp& k): k(k) { assert(k.len > 0); } bool operator()(const decltype(*pattern)& c) { while(matchedLen && !(c == k.pattern[matchedLen])) matchedLen = k.t[matchedLen]; bool mnext = matchedLen || c == k.pattern[0]; if(mnext) { matchedLen++; if (matchedLen == k.len) { matchedLen = k.t[matchedLen]; return true; } } return false; } }; scanner_s scanner() { return scanner_s{*this}; } };

using namespace std;

#define N 2001

typedef intmod<1000000007> I;

char grid[2][N];
char word[N];

I l[2][N][2*N],
  m[2][N][2*N],
  h[2][N][N];

int n,q;

int B(int i, int j, int k) {
    return word[k-1] == grid[i][j];
}

#define Z(A) memset(A, 0, sizeof(A))

I count() {
    for(int p = 2; 2*p < q; p++) {
        kmp<char*> k0(word + q - 2*p, p);
        kmp<reverse_iterator<char*>> k1(reverse_iterator<char*>{word + q}, p);
        for(int i: {0,1}) {
            auto s0 = k0.scanner();
            auto s1 = k1.scanner();
            for(int j = 0; j < n; j++) {
                if(s0(grid[i][j]) & s1(grid[i^1][j]))
                    h[i][j-p+1][p] = 1;
            }
        }
    }

    for(int p = 2; 2*p <= q; p++) {
        kmp<reverse_iterator<char*>> k0(reverse_iterator<char*>{word + p}, p);
        kmp<char*> k1(word + p, p);
        for(int i: {0,1}) {
            auto s0 = k0.scanner();
            auto s1 = k1.scanner();
            for(int j = 0; j < n; j++) {
                if(s0(grid[i^1][j]) & s1(grid[i][j]))
                    m[i][j][2*p] = 1;
            }
        }
    }

    for(int j = 0; j < n; j++) {
        for(int i: {0,1}) {
            l[i][j][1] = B(i,j,1);
            if(j) {
                for(int c = 2; c <= q; c++)
                    l[i][j][c] = (l[i][j-1][c-1] + m[i][j-1][c-1]) * B(i,j,c);
            }
        }
        for(int i: {0, 1}) {
            for(int c = 2; c <= q; c++)
                m[i][j][c] += l[i^1][j][c-1] * B(i,j,c);
        }
    }
    I a = 0;
    for(int j = 0; j < n; j++)
        for(int i: {0,1})
            a += l[i][j][q] + m[i][j][q];
    for(int p = 2; 2*p < q; p++) {
        for(int j = 0; j + p < n; j++) {
            for(int i: {0,1}) {
                a += (l[i][j][q - 2*p] + m[i][j][q - 2*p]) * h[i][j+1][p];
            }
        }
    }
    return a;
}

int main()
{
    ios_base::sync_with_stdio(0);

    scanf("%s %s %s", grid[0], grid[1], word);
    n = strlen(grid[0]);
    q = strlen(word);

    if(q == 2) {
        I a = 0;
        for(int j = 0; j < n; j++) {
            a += B(0,j,1) && B(1,j,2);
            a += B(1,j,1) && B(0,j,2);
        }
        for(int i: {0,1} )
            for(int j = 1; j < n; j++) {
                a += B(i,j-1,1) && B(i,j,2);
                a += B(i,j,1) && B(i,j-1,2);
            }
        cout << a;
        return 0;
    }

    I ans = count();

    if(q > 2) {
        Z(l); Z(m); Z(h);
        reverse(grid[0], grid[0]+n);
        reverse(grid[1], grid[1]+n);
        ans += count();
    }

    cout << ans;

    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    modint()
    {
        v = 0;
    }
    modint(int V)
    {
        v = (V % MOD + MOD) % MOD;
    }
    modint operator+(const modint &__Val) const
    {
        modint res;
        res.v = v + __Val.v;
        if (res.v >= MOD)
        {
            res.v -= MOD;
        }
        return res;
    }
    modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    modint operator*(const modint &__Val) const
    {
        modint res;
        res.v = v * __Val.v % MOD;
        return res;
    }
    modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    modint &operator-=(const modint &__Val)
    {
        return *this = *this - __Val;
    }
    modint &operator++()
    {
        return *this += 1;
    }
    modint &operator--()
    {
        return *this -= 1;
    }
    bool operator==(const modint &__Val) const
    {
        return v == __Val.v;
    }
    friend ostream &operator<<(ostream &ost, const modint &__Val)
    {
        return ost << __Val.v;
    }
};
modint ans, p[2005];
modint power(modint A, int B)
{
    modint res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A;
        }
        A = A * A;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len;
    modint hsh;
    str operator+(const str &__Val) const
    {
        return {len + __Val.len, hsh * p[__Val.len] + __Val.hsh};
    }
    str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * p[len - __Val.len]};
    }
    bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = hsh * 128 + __Val[i];
        }
    }
    str(int A, modint B)
    {
        len = A;
        hsh = B;
    }
    str()
    {
        len = 0;
        hsh = 0;
    }
} C[4005];
str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work(bool flag)
{
#define print                                        \
    for (int k = 0; k < 2; ++k)                      \
    {                                                \
        for (int i = 0; i < Map->length(); ++i)      \
        {                                            \
            for (int j = 0; j <= goal.length(); ++j) \
            {                                        \
                cout << dp[k][i][j] << ' ';          \
            }                                        \
            cout << endl;                            \
        }                                            \
        cout << endl;                                \
    }
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = Map[0].substr(0, i);
        B[0][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = Map[0].substr(0, i);
        B[1][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    // print;
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= goal.length(); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // print;
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 1; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                // cout << i << ' ' << j << ' ' << i + v << endl;
                if (i + v >= Map->length() || v == 1)
                {
                    continue;
                }
                if (substr(A[0], i + 2, i + v + 1) + substr(B[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 0 << ' ' << i << " " << j << endl;
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 2, i + v + 1) + substr(A[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 1 << ' ' << i << " " << j << endl;
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    // ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    p[0] = 1;
    for (int i = 1; i <= 2000; ++i)
    {
        p[i] = p[i - 1] * 128;
    }
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[0] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work(false);
    // cout << ans << endl;
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work(true);
    cout << ans << endl;
    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    modint()
    {
        v = 0;
    }
    modint(int V)
    {
        v = (V % MOD + MOD) % MOD;
    }
    modint operator+(const modint &__Val) const
    {
        return v + __Val.v;
    }
    modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    modint operator*(const modint &__Val) const
    {
        return v * __Val.v;
    }
    modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    modint &operator-=(const modint &__Val)
    {
        return *this = *this - __Val;
    }
    modint &operator++()
    {
        return *this += 1;
    }
    modint &operator--()
    {
        return *this -= 1;
    }
    bool operator==(const modint &__Val) const
    {
        return v == __Val.v;
    }
    friend ostream &operator<<(ostream &ost, const modint &__Val)
    {
        return ost << __Val.v;
    }
};
modint ans;
modint power(modint A, int B)
{
    modint res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A;
        }
        A = A * A;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len;
    modint hsh;
    str operator+(const str &__Val) const
    {
        return {len + __Val.len, hsh * power(128, __Val.len) + __Val.hsh};
    }
    str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * power(128, len - __Val.len)};
    }
    bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = hsh * 128 + __Val[i];
        }
    }
    str(int A, modint B)
    {
        len = A;
        hsh = B;
    }
    str()
    {
        len = 0;
        hsh = 0;
    }
} C[4005];
str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work(bool flag)
{
#define print                                        \
    for (int k = 0; k < 2; ++k)                      \
    {                                                \
        for (int i = 0; i < Map->length(); ++i)      \
        {                                            \
            for (int j = 0; j <= goal.length(); ++j) \
            {                                        \
                cout << dp[k][i][j] << ' ';          \
            }                                        \
            cout << endl;                            \
        }                                            \
        cout << endl;                                \
    }
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = Map[0].substr(0, i);
        B[0][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = Map[0].substr(0, i);
        B[1][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    // print;
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= goal.length(); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // print;
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 1; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                // cout << i << ' ' << j << ' ' << i + v << endl;
                if (i + v >= Map->length() || v == 1)
                {
                    continue;
                }
                if (substr(A[0], i + 2, i + v + 1) + substr(B[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 0 << ' ' << i << " " << j << endl;
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 2, i + v + 1) + substr(A[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 1 << ' ' << i << " " << j << endl;
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    // ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[0] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work(false);
    // cout << ans << endl;
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work(true);
    cout << ans << endl;
    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    modint()
    {
        v = 0;
    }
    modint(int V)
    {
        v = (V % MOD + MOD) % MOD;
    }
    modint operator+(const modint &__Val) const
    {
        return v + __Val.v;
    }
    modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    modint operator*(const modint &__Val) const
    {
        return v * __Val.v;
    }
    modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    modint &operator-=(const modint &__Val)
    {
        return *this = *this - __Val;
    }
    modint &operator++()
    {
        return *this += 1;
    }
    modint &operator--()
    {
        return *this -= 1;
    }
    bool operator==(const modint &__Val) const
    {
        return v == __Val.v;
    }
    friend ostream &operator<<(ostream &ost, const modint &__Val)
    {
        return ost << __Val.v;
    }
};
modint ans, p[2005];
modint power(modint A, int B)
{
    modint res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A;
        }
        A = A * A;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len;
    modint hsh;
    str operator+(const str &__Val) const
    {
        return {len + __Val.len, hsh * p[__Val.len] + __Val.hsh};
    }
    str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * p[len - __Val.len]};
    }
    bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = hsh * 128 + __Val[i];
        }
    }
    str(int A, modint B)
    {
        len = A;
        hsh = B;
    }
    str()
    {
        len = 0;
        hsh = 0;
    }
} C[4005];
str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work(bool flag)
{
#define print                                        \
    for (int k = 0; k < 2; ++k)                      \
    {                                                \
        for (int i = 0; i < Map->length(); ++i)      \
        {                                            \
            for (int j = 0; j <= goal.length(); ++j) \
            {                                        \
                cout << dp[k][i][j] << ' ';          \
            }                                        \
            cout << endl;                            \
        }                                            \
        cout << endl;                                \
    }
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = Map[0].substr(0, i);
        B[0][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = Map[0].substr(0, i);
        B[1][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    // print;
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= goal.length(); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // print;
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 1; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                // cout << i << ' ' << j << ' ' << i + v << endl;
                if (i + v >= Map->length() || v == 1)
                {
                    continue;
                }
                if (substr(A[0], i + 2, i + v + 1) + substr(B[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 0 << ' ' << i << " " << j << endl;
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 2, i + v + 1) + substr(A[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 1 << ' ' << i << " " << j << endl;
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    // ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    p[0] = 1;
    for (int i = 1; i <= 2000; ++i)
    {
        p[i] = p[i - 1] * 128;
    }
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[0] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work(false);
    // cout << ans << endl;
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work(true);
    cout << ans << endl;
    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    inline modint()
    {
        v = 0;
    }
    inline modint(int V)
    {
        v = (V % MOD + MOD) % MOD;
    }
    inline modint operator+(const modint &__Val) const
    {
        modint res;
        res.v = (v + __Val.v);
        res.v -= res.v >= MOD ? MOD : 0;
        return res;
    }
    inline modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    inline modint operator*(const modint &__Val) const
    {
        return v * __Val.v;
    }
    inline modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    inline modint &operator-=(const modint &__Val)
    {
        return *this = *this - __Val;
    }
    inline modint &operator++()
    {
        return *this += 1;
    }
    inline modint &operator--()
    {
        return *this -= 1;
    }
    inline bool operator==(const modint &__Val) const
    {
        return v == __Val.v;
    }
    inline friend ostream &operator<<(ostream &ost, const modint &__Val)
    {
        return ost << __Val.v;
    }
};
modint ans, p[2005];
inline modint power(modint A, int B)
{
    modint res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A;
        }
        A = A * A;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len;
    modint hsh;
    inline str operator+(const str &__Val) const
    {
        return {len + __Val.len, hsh * p[__Val.len] + __Val.hsh};
    }
    inline str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * p[len - __Val.len]};
    }
    inline bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    inline str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = hsh * 128 + __Val[i];
        }
    }
    inline str(int A, modint B)
    {
        len = A;
        hsh = B;
    }
    inline str()
    {
        len = 0;
        hsh = 0;
    }
} C[4005];
inline str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work(bool flag)
{
#define print                                        \
    for (int k = 0; k < 2; ++k)                      \
    {                                                \
        for (int i = 0; i < Map->length(); ++i)      \
        {                                            \
            for (int j = 0; j <= goal.length(); ++j) \
            {                                        \
                cout << dp[k][i][j] << ' ';          \
            }                                        \
            cout << endl;                            \
        }                                            \
        cout << endl;                                \
    }
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = {i, A[0][i - 1].hsh * 128 + Map[0][i]};
        B[0][i] = {i, B[0][i - 1].hsh * 128 + Map[1][i]};
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = {i, A[1][i - 1].hsh * 128 + Map[0][i]};
        B[1][i] = {i, B[1][i - 1].hsh * 128 + Map[1][i]};
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    // print;
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= min(i << 1, goal.length() * 1ll); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // print;
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 1; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                // cout << i << ' ' << j << ' ' << i + v << endl;
                if (i + v >= Map->length() || v == 1)
                {
                    continue;
                }
                if (substr(A[0], i + 2, i + v + 1) + substr(B[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 0 << ' ' << i << " " << j << endl;
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 2, i + v + 1) + substr(A[1], Map->length() - i - v, Map->length() - i - 1) ==
                    substr(C, j + 1, goal.length()))
                {
                    // cout << 1 << ' ' << i << " " << j << endl;
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    // ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    p[0] = 1;
    for (int i = 1; i <= 2000; ++i)
    {
        p[i] = p[i - 1] * 128;
    }
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[0] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work(false);
    // cout << ans << endl;
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work(true);
    cout << ans << endl;
    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    modint()
    {
        v = 0;
    }
    modint(int V)
    {
        v = (V + MOD) % MOD;
    }
    modint operator+(const modint &__Val) const
    {
        return v + __Val.v;
    }
    modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    modint operator*(const modint &__Val) const
    {
        return v * __Val.v;
    }
    modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    modint &operator++()
    {
        return *this += 1;
    }
    friend ostream &operator<<(ostream &ost, const modint &__Val)
    {
        return ost << __Val.v;
    }
};
modint ans;
int power(int A, int B)
{
    int res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A % MOD;
        }
        A = A * A % MOD;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len, hsh;
    str operator+(const str &__Val) const
    {
        return {len + __Val.len, (hsh * power(128, __Val.len) + __Val.hsh) % MOD};
    }
    str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * power(128, len - __Val.len)};
    }
    bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = (hsh * 128 + __Val[i]) % MOD;
        }
    }
    str(int A, int B)
    {
        len = A;
        hsh = B;
    }
    str()
    {
        len = hsh = 0;
    }
} C[4005];
str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work()
{
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = Map[0].substr(0, i);
        B[0][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = Map[0].substr(0, i);
        B[1][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= goal.length(); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // for (int k = 0; k < 2; ++k)
    // {
    //     for (int i = 0; i < Map->length(); ++i)
    //     {
    //         for (int j = 0; j <= goal.length(); ++j)
    //         {
    //             cout << dp[k][i][j] << ' ';
    //         }
    //         cout << endl;
    //     }
    //     cout << endl;
    // }
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                if (i + v > goal.length())
                {
                    continue;
                }
                if (substr(A[0], i + 1, i + v) + substr(B[1], Map->length() - i - v, Map->length() - i) ==
                    substr(C, j + 1, goal.length()))
                {
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 1, i + v) + substr(A[1], Map->length() - i - v, Map->length() - i) ==
                    substr(C, j + 1, goal.length()))
                {
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[0] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work();
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work();
    cout << ans << endl;
    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    modint()
    {
        v = 0;
    }
    modint(int V)
    {
        v = (V + MOD) % MOD;
    }
    modint operator+(const modint &__Val) const
    {
        return v + __Val.v;
    }
    modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    modint operator*(const modint &__Val) const
    {
        return v * __Val.v;
    }
    modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    modint &operator++()
    {
        return *this += 1;
    }
    friend ostream &operator<<(ostream &ist, const modint &__Val)
    {
        return ist << __Val.v;
    }
};
modint ans;
int power(int A, int B)
{
    int res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A % MOD;
        }
        A = A * A % MOD;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len, hsh;
    str operator+(const str &__Val) const
    {
        return {len + __Val.len, (hsh * power(128, __Val.len) + __Val.hsh) % MOD};
    }
    str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * power(128, len - __Val.len)};
    }
    bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = (hsh * 128 + __Val[i]) % MOD;
        }
    }
    str(int A, int B)
    {
        len = A;
        hsh = B;
    }
    str()
    {
        len = hsh = 0;
    }
} C[4005];
str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work()
{
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = Map[0].substr(0, i);
        B[0][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = Map[0].substr(0, i);
        B[1][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= goal.length(); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // for (int k = 0; k < 2; ++k)
    // {
    //     for (int i = 0; i < Map->length(); ++i)
    //     {
    //         for (int j = 0; j <= goal.length(); ++j)
    //         {
    //             cout << dp[k][i][j] << ' ';
    //         }
    //         cout << endl;
    //     }
    //     cout << endl;
    // }
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                if (i + v > goal.length())
                {
                    continue;
                }
                if (substr(A[0], i + 1, i + v) + substr(B[1], Map->length() - i - v, Map->length() - i) ==
                    substr(C, j + 1, goal.length()))
                {
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 1, i + v) + substr(A[1], Map->length() - i - v, Map->length() - i) ==
                    substr(C, j + 1, goal.length()))
                {
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[1] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work();
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work();
    cout << ans << endl;
    return 0;
}


//This Code was made by Chinese_zjc_.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <bitset>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <ctime>
// #include<windows.h>
#define int long long
#define double long double
using namespace std;
const double PI = acos(-1);
const double eps = 0.0000000001;
const int INF = 0x3fffffffffffffff;
const int MOD = 1000000007;
string Map[2], goal;
const int xx[] = {0, 1, 0, -1}, yy[] = {1, 0, -1, 0};
struct modint
{
    int v;
    modint()
    {
        v = 0;
    }
    modint(int V)
    {
        v = (V + MOD) % MOD;
    }
    modint operator+(const modint &__Val) const
    {
        return v + __Val.v;
    }
    modint operator-(const modint &__Val) const
    {
        return v - __Val.v;
    }
    modint operator*(const modint &__Val) const
    {
        return v * __Val.v;
    }
    modint &operator+=(const modint &__Val)
    {
        return *this = *this + __Val;
    }
    modint &operator++()
    {
        return *this += 1;
    }
    friend ostream &operator<<(ostream &ost, const modint &__Val)
    {
        return ost << __Val.v;
    }
};
modint ans;
int power(int A, int B)
{
    int res = 1;
    while (B)
    {
        if (B & 1)
        {
            res = res * A % MOD;
        }
        A = A * A % MOD;
        B >>= 1;
    }
    return res;
}
struct str
{
    int len, hsh;
    str operator+(const str &__Val) const
    {
        return {len + __Val.len, (hsh * power(128, __Val.len) + __Val.hsh) % MOD};
    }
    str operator-(const str &__Val) const
    {
        return {len - __Val.len, hsh - __Val.hsh * power(128, len - __Val.len)};
    }
    bool operator==(const str &__Val) const
    {
        return len == __Val.len && hsh == __Val.hsh;
    }
    str(string __Val)
    {
        len = __Val.length();
        hsh = 0;
        for (int i = 0; i < (int)__Val.length(); ++i)
        {
            hsh = (hsh * 128 + __Val[i]) % MOD;
        }
    }
    str(int A, int B)
    {
        len = A;
        hsh = B;
    }
    str()
    {
        len = hsh = 0;
    }
} C[4005];
str substr(str tmp[], int l, int r)
{
    if (l == 0)
    {
        return tmp[r];
    }
    return tmp[r] - tmp[l - 1];
}
void work()
{
    str A[2][4005], B[2][4005];
    modint dp[2][2005][2005];
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[0][i] = Map[0].substr(0, i);
        B[0][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 1; i <= Map->length(); ++i)
    {
        A[1][i] = Map[0].substr(0, i);
        B[1][i] = Map[1].substr(0, i);
    }
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (substr(A[1], Map->length() - i, Map->length() - j) + substr(B[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[1][i][(i - j + 1) << 1] = 1;
            }
            if (substr(B[1], Map->length() - i, Map->length() - j) + substr(A[0], j + 1, i + 1) == C[(i - j + 1) << 1])
            {
                dp[0][i][(i - j + 1) << 1] = 1;
            }
        }
        dp[0][i][0] = dp[1][i][0] = 1;
    }
    if (goal[0] == Map[0][0])
    {
        dp[0][0][1] = 1;
    }
    if (goal[0] == Map[1][0])
    {
        dp[1][0][1] = 1;
    }
    if (goal[0] == Map[0][0] && goal[1] == Map[1][0])
    {
        dp[1][0][2] = 1;
    }
    if (goal[0] == Map[1][0] && goal[1] == Map[0][0])
    {
        dp[0][0][2] = 1;
    }
    for (int i = 1; i < Map->length(); ++i)
    {
        if (goal[0] == Map[0][i])
        {
            dp[0][i][1] += dp[0][i - 1][0];
        }
        if (goal[0] == Map[1][i])
        {
            dp[1][i][1] += dp[1][i - 1][0];
        }
        for (int j = 2; j <= goal.length(); ++j)
        {
            if (goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[0][i - 1][j - 1];
            }
            if (goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[1][i - 1][j - 1];
            }
            if (goal[j - 2] == Map[0][i] && goal[j - 1] == Map[1][i])
            {
                dp[1][i][j] += dp[0][i - 1][j - 2];
            }
            if (goal[j - 2] == Map[1][i] && goal[j - 1] == Map[0][i])
            {
                dp[0][i][j] += dp[1][i - 1][j - 2];
            }
        }
    }
    // for (int k = 0; k < 2; ++k)
    // {
    //     for (int i = 0; i < Map->length(); ++i)
    //     {
    //         for (int j = 0; j <= goal.length(); ++j)
    //         {
    //             cout << dp[k][i][j] << ' ';
    //         }
    //         cout << endl;
    //     }
    //     cout << endl;
    // }
    for (int i = 0; i < Map->length(); ++i)
    {
        for (int j = 0; j <= goal.length(); ++j)
        {
            if (j == goal.length())
            {
                ans += dp[0][i][j] + dp[1][i][j];
                continue;
            }
            if ((j & 1) == (goal.length() & 1))
            {
                int v = (goal.length() - j) >> 1;
                // cout << i << ' ' << j << ' ' << i + v << endl;
                if (i + v >= Map->length())
                {
                    continue;
                }
                if (substr(A[0], i + 1, i + v) + substr(B[1], Map->length() - i - v, Map->length() - i) ==
                    substr(C, j + 1, goal.length()))
                {
                    ans += dp[0][i][j];
                }
                if (substr(B[0], i + 1, i + v) + substr(A[1], Map->length() - i - v, Map->length() - i) ==
                    substr(C, j + 1, goal.length()))
                {
                    ans += dp[1][i][j];
                }
            }
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin >> Map[0] >> Map[1] >> goal;
    if (goal.length() == 1)
    {
        for (int i = 0; i < (int)Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                ++ans;
            }
            if (goal[0] == Map[1][i])
            {
                ++ans;
            }
        }
        cout << ans << endl;
        return 0;
    }
    if (goal.length() == 2)
    {
        for (int i = 0; i < Map->length(); ++i)
        {
            if (goal[0] == Map[0][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 0 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
            if (goal[0] == Map[1][i])
            {
                for (int j = 0; j < 4; ++j)
                {
                    int x = 1 + xx[j], y = i + yy[j];
                    if (x < 0 || y < 0 || x >= 2 || y >= Map->length())
                    {
                        continue;
                    }
                    if (goal[1] == Map[x][y])
                    {
                        ++ans;
                    }
                }
            }
        }
        cout << ans << endl;
        return 0;
    }
    for (int i = 1; i <= goal.length(); ++i)
    {
        C[i] = goal.substr(0, i);
    }
    work();
    reverse(Map[0].begin(), Map[0].end());
    reverse(Map[1].begin(), Map[1].end());
    work();
    cout << ans << endl;
    return 0;
}