#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
const int mo = 1e9 + 7;
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {-1, 1, 0, 0};
char a[5][10005];
int dp[10005][10], p[10005];
int cx[10], cy[10];
int ox, oy;
int e[10][10];

void dfs(int i, int from, int x, int to){
    if (x > 3){
        dp[i+1][to] = (dp[i+1][to] + dp[i][from]) % mo;
        //printf("%d %d %d\n", i, from, to);
        return;
    }
    if (from & (1 << (x - 1))){
        dfs(i, from, x + 1, to);
    } else {
        if (x < 3 && a[x][i+1] == '.' && a[x+1][i+1] == '.' && !(from & (1 << x))){
            dfs(i, from, x + 2, to);
        }
        if (a[x][i+1] != '.'){
            dfs(i, from, x + 1, to);
        } else {
            dfs(i, from, x + 1, to + (1 << (x - 1)));
        }
    }
}

int get(){
    memset(p, 0, sizeof(p));
    for (int i = 1; i <= 3; ++ i){
        for (int j = 1; j <= n; ++ j){
            if (a[i][j] == 'X'){
                p[j] += (1 << (i - 1));
            }
        }
    }
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 0; i < n; ++ i){
        for (int from = 0; from < 8; ++ from){
            if (dp[i][from] == 0) continue;
            if (p[i+1] & from) continue;
            dfs(i, from, 1, 0);
        }
    }
    return dp[n][0];
}

int main(){
    //freopen("in", "r", stdin);
    scanf("%d", &n);
    for (int i = 1; i <= 3; ++ i){
        scanf("%s", a[i] + 1);
        for (int j = 1; j <= n; ++ j){
            if (a[i][j] == 'O'){
                ox = i; oy = j;
            }
        }
    }
    //printf("%d\n", get());
    int ans = 0;
    for (int ost = 1; ost < 16; ++ ost){
        int flag = 1, tot = 0, sign = -1;
        for (int i = 0; i < 4; ++ i){
            if (ost & (1 << i)){
                for (int d = 1; d <= 2; ++ d){
                    int tx = ox + d * dx[i];
                    int ty = oy + d * dy[i];
                    if (tx < 1 || ty < 1 || tx > 3 || ty > n || a[tx][ty] != '.'){
                        flag = 0;
                        break;
                    }
                    cx[tot] = tx; cy[tot] = ty;
                    tot ++;
                }
                sign = (sign == 1) ? -1 : 1;
            }
        }
        if (flag == 0) continue;
        for (int i = 0; i < tot; ++ i){
            a[cx[i]][cy[i]] = 'X';
        }

        ans = (ans + sign * get()) % mo;

        for (int i = 0; i < tot; ++ i){
            a[cx[i]][cy[i]] = '.';
        }
    }
    if (ans < 0) ans += mo;
    printf("%d\n", (int) ans);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
const int mo = 1e9 + 7;
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {-1, 1, 0, 0};
char a[5][10005];
int dp[10005][10], p[10005];
int cx[10], cy[10];
int ox, oy;
int e[10][10];

void dfs(int i, int from, int x, int to){
    if (x > 3){
        dp[i+1][to] = (dp[i+1][to] + dp[i][from]) % mo;
        printf("%d %d %d\n", i, from, to);
        return;
    }
    if (from & (1 << (x - 1))){
        dfs(i, from, x + 1, to);
    } else {
        if (x < 3 && a[x][i+1] == '.' && a[x+1][i+1] == '.' && !(from & (1 << x))){
            dfs(i, from, x + 2, to);
        }
        if (a[x][i+1] != '.'){
            dfs(i, from, x + 1, to);
        } else {
            dfs(i, from, x + 1, to + (1 << (x - 1)));
        }
    }
}

int get(){
    memset(p, 0, sizeof(p));
    for (int i = 1; i <= 3; ++ i){
        for (int j = 1; j <= n; ++ j){
            if (a[i][j] == 'X'){
                p[j] += (1 << (i - 1));
            }
        }
    }
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 0; i < n; ++ i){
        for (int from = 0; from < 8; ++ from){
            if (dp[i][from] == 0) continue;
            if (p[i+1] & from) continue;
            dfs(i, from, 1, 0);
        }
    }
    return dp[n][0];
}

int main(){
    //freopen("in", "r", stdin);
    scanf("%d", &n);
    for (int i = 1; i <= 3; ++ i){
        scanf("%s", a[i] + 1);
        for (int j = 1; j <= n; ++ j){
            if (a[i][j] == 'O'){
                ox = i; oy = j;
            }
        }
    }
    //printf("%d\n", get());
    int ans = 0;
    for (int ost = 1; ost < 16; ++ ost){
        int flag = 1, tot = 0, sign = -1;
        for (int i = 0; i < 4; ++ i){
            if (ost & (1 << i)){
                for (int d = 1; d <= 2; ++ d){
                    int tx = ox + d * dx[i];
                    int ty = oy + d * dy[i];
                    if (tx < 1 || ty < 1 || tx > 3 || ty > n || a[tx][ty] != '.'){
                        flag = 0;
                        break;
                    }
                    cx[tot] = tx; cy[tot] = ty;
                    tot ++;
                }
                sign = (sign == 1) ? -1 : 1;
            }
        }
        if (flag == 0) continue;
        for (int i = 0; i < tot; ++ i){
            a[cx[i]][cy[i]] = 'X';
        }

        ans = (ans + sign * get()) % mo;

        for (int i = 0; i < tot; ++ i){
            a[cx[i]][cy[i]] = '.';
        }
    }
    if (ans < 0) ans += mo;
    printf("%d\n", (int) ans);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
const int mo = 1e9 + 7;
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {-1, 1, 0, 0};
char a[5][10005];
int dp[10005][10], p[10005];
int cx[10], cy[10];
int ox, oy;
int e[10][10];

void dfs(int i, int from, int x, int to){
    if (x > 3){
        dp[i+1][to] = (dp[i+1][to] + dp[i][from]) % mo;
        return;
    }
    if (from & (1 << (x - 1))){
        dfs(i, from, x + 1, to);
    } else {
        if (x < 3 && a[x][i+1] == '.' && a[x+1][i+1] == '.'){
            dfs(i, from, x + 2, to);
        }
        if (a[x][i+1] != '.'){
            dfs(i, from, x + 1, to);
        } else {
            dfs(i, from, x + 1, to + (1 << (x - 1)));
        }
    }
}

int get(){
    memset(p, 0, sizeof(p));
    for (int i = 1; i <= 3; ++ i){
        for (int j = 1; j <= n; ++ j){
            if (a[i][j] == 'X'){
                p[j] += (1 << (i - 1));
            }
        }
    }
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 0; i < n; ++ i){
        for (int from = 0; from < 8; ++ from){
            if (dp[i][from] == 0) continue;
            if (p[i+1] & from) continue;
            dfs(i, from, 1, 0);
        }
    }
    return dp[n][0];
}

int main(){
   // freopen("in", "r", stdin);
    scanf("%d", &n);
    for (int i = 1; i <= 3; ++ i){
        scanf("%s", a[i] + 1);
        for (int j = 1; j <= n; ++ j){
            if (a[i][j] == 'O'){
                ox = i; oy = j;
            }
        }
    }
    //printf("%d\n", get());
    int ans = 0;
    for (int ost = 1; ost < 16; ++ ost){
        int flag = 1, tot = 0, sign = -1;
        for (int i = 0; i < 4; ++ i){
            if (ost & (1 << i)){
                for (int d = 1; d <= 2; ++ d){
                    int tx = ox + d * dx[i];
                    int ty = oy + d * dy[i];
                    if (tx < 1 || ty < 1 || tx > 3 || ty > n || a[tx][ty] != '.'){
                        flag = 0;
                        break;
                    }
                    cx[tot] = tx; cy[tot] = ty;
                    tot ++;
                }
                sign = (sign == 1) ? -1 : 1;
            }
        }
        if (flag == 0) continue;
        for (int i = 0; i < tot; ++ i){
            a[cx[i]][cy[i]] = 'X';
        }

        ans = (ans + sign * get()) % mo;

        for (int i = 0; i < tot; ++ i){
            a[cx[i]][cy[i]] = '.';
        }
    }
    if (ans < 0) ans += mo;
    printf("%d\n", (int) ans);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cassert>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<string>
#include<sstream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
#include<algorithm>
#pragma comment(linker, "/STACK:640000000")
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define ll long long
#define bit __builtin_popcountll
#define sqr(x) (x) * (x)
#define forit(it,S) for(__typeof((S).begin()) it = (S).begin(); it != (S).end(); it++)
#define f first
#define s second
using namespace std;
typedef pair<int, int> pii;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int mod = (int)1e9 + 7;
const int maxn = (int)1e4 + 10;
char s[3][maxn];
int dp[maxn][1 << 3];
int n;
void add(int &x, int y) {
    x += y;
    if (x >= mod) x -= mod;
}
void go(int i, int mask, int j, int sub) {
    if (j == 3) {
        add(dp[i + 1][sub],dp[i][mask]);
        return;
    }
    if (s[j][i] != '.' || (mask & (1 << j))) {
        go(i,mask,j + 1,sub);
        return;
    }
    if (j + 1 < 3 && s[j + 1][i] == '.' && (mask & (1 << (j + 1))) == 0) {
        go(i,mask,j + 2,sub);
    }
    if (i + 1 < n && s[j][i + 1] == '.') {
        go(i,mask,j + 1,sub | (1 << j));
    }
}
int calc() {
    memset(dp,0,sizeof(dp));
    dp[0][0] = 1;
    for (int i = 0; i < n; i++) {
        for (int mask = 0; mask < (1 << 3); mask++) if (dp[i][mask]) {
            go(i,mask,0,0);
        }
    }
    return dp[n][0];
}
int main() {
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    cin >> n;
    int x = -1;
    int y = -1;
    for (int i = 0; i < 3; i++) {
        scanf("%s",s[i]);
        for (int j = 0; j < n; j++) if (s[i][j] == 'O') {
            x = i;
            y = j;
        }
    }
    vector< pair<pii, pii> > v;
    if (x == 2 && s[0][y] == '.') {
        v.pb(mp(mp(0,y),mp(1,y)));
    }
    if (x == 0 && s[2][y] == '.') {
        v.pb(mp(mp(1,y),mp(2,y)));
    }
    if (y >= 2 && s[x][y - 2] == '.') {
        v.pb(mp(mp(x,y - 2),mp(x,y - 1)));
    }
    if (n - y >= 3 && s[x][y + 2] == '.') {
        v.pb(mp(mp(x,y + 1),mp(x,y + 2)));
    }
    int res = 0;
    for (int mask = 1; mask < (1 << (sz(v))); mask++) {
        for (int i = 0; i < sz(v); i++) if (mask & (1 << i)) {
            s[v[i].f.f][v[i].f.s] = 'X';
            s[v[i].s.f][v[i].s.s] = 'X';
        }
        if (bit(mask) % 2 == 0) {
            add(res,mod - calc());
        } else {
            add(res,calc());
        }
        for (int i = 0; i < sz(v); i++) if (mask & (1 << i)) {
            s[v[i].f.f][v[i].f.s] = '.';
            s[v[i].s.f][v[i].s.s] = '.';
        }
    }
    cout << res << endl;
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cassert>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<string>
#include<sstream>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
#include<algorithm>
#pragma comment(linker, "/STACK:640000000")
#define pb push_back
#define ppb pop_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define ll long long
#define bit __builtin_popcountll
#define sqr(x) (x) * (x)
#define forit(it,S) for(__typeof((S).begin()) it = (S).begin(); it != (S).end(); it++)
#define f first
#define s second
using namespace std;
typedef pair<int, int> pii;
const double eps = 1e-9;
const double pi = acos(-1.0);
const int mod = (int)1e9 + 7;
const int maxn = (int)1e4 + 10;
char s[3][maxn];
int dp[maxn][1 << 3];
int n;
void add(int &x, int y) {
    x += y;
    if (x >= mod) x -= mod;
}
void go(int i, int mask, int j, int sub) {
    if (j == 3) {
        add(dp[i + 1][sub],dp[i][mask]);
        return;
    }
    if (s[j][i] != '.' || (mask & (1 << j))) {
        go(i,mask,j + 1,sub);
        return;
    }
    if (j + 1 < 3 && s[j + 1][i] == '.') {
        go(i,mask,j + 2,sub);
    }
    if (i + 1 < n && s[j][i + 1] == '.') {
        go(i,mask,j + 1,sub | (1 << j));
    }
}
int calc() {
    memset(dp,0,sizeof(dp));
    dp[0][0] = 1;
    for (int i = 0; i < n; i++) {
        for (int mask = 0; mask < (1 << 3); mask++) if (dp[i][mask]) {
            go(i,mask,0,0);
        }
    }
    return dp[n][0];
}
int main() {
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    cin >> n;
    int x = -1;
    int y = -1;
    for (int i = 0; i < 3; i++) {
        scanf("%s",s[i]);
        for (int j = 0; j < n; j++) if (s[i][j] == 'O') {
            x = i;
            y = j;
        }
    }
    vector< pair<pii, pii> > v;
    if (x == 2 && s[1][y] == '.') {
        v.pb(mp(mp(0,y),mp(1,y)));
    }
    if (x == 0 && s[2][y] == '.') {
        v.pb(mp(mp(1,y),mp(2,y)));
    }
    if (y >= 2 && s[x][y - 2] == '.') {
        v.pb(mp(mp(x,y - 2),mp(x,y - 1)));
    }
    if (n - y >= 3 && s[x][y + 2] == '.') {
        v.pb(mp(mp(x,y + 1),mp(x,y + 2)));
    }
    int res = 0;
    for (int mask = 1; mask < (1 << (sz(v))); mask++) {
        for (int i = 0; i < sz(v); i++) if (mask & (1 << i)) {
            s[v[i].f.f][v[i].f.s] = 'X';
            s[v[i].s.f][v[i].s.s] = 'X';
        }
        if (bit(mask) % 2 == 0) {
            add(res,mod - calc());
        } else {
            add(res,calc());
        }
        for (int i = 0; i < sz(v); i++) if (mask & (1 << i)) {
            s[v[i].f.f][v[i].f.s] = '.';
            s[v[i].s.f][v[i].s.s] = '.';
        }
    }
    cout << res << endl;
    return 0;
}


#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

#define INF 0x3f3f3f3f3f3f3f3fLL

#define MOD 1000000007

#define pb push_back

#define sq(x) ((x)*(x))

#define x first

#define y second

#define eps 1e-8

#define bpt(x) (__builtin_popcount(x))

#define bptl(x) (__builtin_popcountll(x))

#define bit(x, y) (((x)>>(y))&1)

#define bclz(x) (__builtin_clz(x))

#define bclzl(x) (__builtin_clzll(x))

#define bctz(x) (__builtin_ctz(x))

#define bctzl(x) (__builtin_ctzll(x))

using namespace std;

typedef long long INT;

typedef vector<int> VI;

typedef pair<int, int> pii;

typedef pair<pii, int> pi3;

typedef double DO;

template<typename T, typename U> inline void smin(T &a, U b) {if (a>b) a=b;}

template<typename T, typename U> inline void smax(T &a, U b) {if (a<b) a=b;}

template<typename T> inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}

template<class T, class T1>inline void gn(T &x, T1 &y) {gn(x); gn(y);}

template<class T, class T1, class T2>inline void gn(T &x, T1 &y, T2 &z) {gn(x); gn(y); gn(z);}

template<typename T> inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}

template<typename T> inline void println(T x) {print(x), putchar('\n');}

template<typename T> inline void printsp(T x) {print(x), putchar(' ');}

template<class T, class T1> inline void print(T x, T1 y) {printsp(x), println(y);}

template<class T, class T1, class T2> inline void print(T x, T1 y, T2 z) {printsp(x), printsp(y), println(z);}

int power(int a, int b, int m, int ans=1) {

	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;

	return ans;

}

#define NN 10010

#define out(x, y) (x<0 || y<0 || x>=3 || y>=n)

char s[3][NN];

pii p[4][2];

int dp[8][NN], B[NN];

void add(int &a, int b){

	a+=b;

	if(a>=MOD) a-=MOD;

}

int can[]={1, 0, 0, 1, 0, 0, 1, 0};

int calc(int n){

	for(int j=0; j<n; j++){

		B[j]=0;

		for(int i=0; i<3; i++) B[j]=(B[j]<<1)+(s[i][j]=='.');

	}

	B[n]=0;

	for(int j=0; j<=n; j++) for(int i=0; i<8; i++) dp[i][j]=0;

	dp[0][0]=1;

	for(int j=0; j<n; j++){

		for(int i=B[j]; ; i=(i-1)&B[j]){

			if(dp[i][j]){

				int r=B[j]^i;

				for(int x=r&B[j+1], k=x; ; k=(k-1)&x){

					int rem=r^k;

					if(can[rem]) add(dp[k][j+1], dp[i][j]);

					if(!k) break;

				}

			}

			if(!i) break;

		}

	}

	return dp[0][n];

}

int main() {

#ifndef ONLINE_JUDGE

	freopen("in.in", "r", stdin);

	freopen("out.out", "w", stdout);

#endif

	int n;

	gn(n);

	for(int i=0; i<3; i++) scanf("%s", s[i]);

	int x, y;

	for(int i=0; i<3; i++) for(int j=0; j<n; j++) if(s[i][j]=='O') x=i, y=j;

	int m=0;

	if(!out(x, y+1) && s[x][y+1]=='.' && !out(x, y+2) && s[x][y+2]=='.') p[m][0]=pii(x, y+1), p[m][1]=pii(x, y+2), m++;

	if(!out(x, y-1) && s[x][y-1]=='.' && !out(x, y-2) && s[x][y-2]=='.') p[m][0]=pii(x, y-1), p[m][1]=pii(x, y-2), m++;

	if(!out(x+1, y) && s[x+1][y]=='.' && !out(x+2, y) && s[x+2][y]=='.') p[m][0]=pii(x+1, y), p[m][1]=pii(x+2, y), m++;

	if(!out(x-1, y) && s[x-1][y]=='.' && !out(x-2, y) && s[x-2][y]=='.') p[m][0]=pii(x-1, y), p[m][1]=pii(x-2, y), m++;

	int ans=0;

	for(int i=1; i<1<<m; i++){

		for(int j=0; j<m; j++) if(bit(i, j)){

			for(int k=0; k<2; k++) s[p[j][k].x][p[j][k].y]='X';

		}

		if(bpt(i)&1) ans+=calc(n);

		else ans=(ans-calc(n)+MOD)%MOD;

		for(int j=0; j<m; j++) if(bit(i, j)){

			for(int k=0; k<2; k++) s[p[j][k].x][p[j][k].y]='.';

		}

	}

	println(ans);

	return 0;

}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <sstream>
#include <iostream>
#include <algorithm>
#include<cstdlib>
#include<queue>

using namespace std;

#define N 10005
#define L(x) x<<1
#define R(x) x<<1|1
#define M(x,y) (x + y)>>1
#define MOD 1000000007
#define MODD 1000000006
#define inf 0x7fffffff
#define llinf 0x7fffffffffffffff
#define LL long long

LL s[N][5];
LL dp[N][10];
LL bin[10][4] = {{0,0,0,0},{0,1,0,0},{0,0,1,0},{0,1,1,0},{0,0,0,1},{0,1,0,1},{0,0,1,1},{0,1,1,1}};
LL b[4] = {0,1,2,4};
LL i_e[10],num;
LL comb[5];

void dfs(LL x,LL y,LL th,LL len)
{
	if(th == 4)
	{
		dp[len][y] = (dp[len][y] + dp[len - 1][x])%MOD;
		return ;
	}
	if(bin[y][th] == 1 && bin[x][th] == 0)
		return ;
	if(bin[y][th] == 1 && bin[x][th] == 1)
		dfs(x,y,th + 1,len);
	if(bin[y][th] == 0 && bin[x][th] == 0)
		dfs(x,y + b[th],th + 1,len);
	if(bin[y][th] == 0 && bin[x][th] == 1)
		dfs(x,y,th + 1,len);
	if(th > 1 && bin[y][th] + bin[y][th - 1] == 0 && bin[x][th] + bin[x][th - 1] == 2)
		dfs(x,y + b[th] + b[th - 1],th + 1,len);
}

LL cntdp(LL n)
{
	memset(dp,0,sizeof(dp));
	dp[0][7] = 1;
	for(LL i = 1;i <= n;i++)
	{
		for(LL j = 0;j < 8;j++)
		{
			if(dp[i - 1][j] == 0)
				continue;
			LL cnt = 0;
			for(LL k = 1;k <= 3;k++)
			{
				if(s[i][k] != 0)
				{
					cnt += b[k];
				}
			}
			dfs(j,cnt,1,i);
		}
	}
	return dp[n][7];
}

void updata(LL n,LL x,LL y)
{
	if(n == 1)
	{
		s[y - 1][x] = s[y - 2][x] = 1;
	}
	else if(n == 2)
	{
		s[y + 2][x] = s[y + 1][x] = 1;
	}
	else if(n == 3)
	{
		s[y][1] = s[y][2] = 1;
	}
	else
	{
		s[y][2] = s[y][3] = 1;
	}
}

void dowmdata(LL n,LL x,LL y)
{
	if(n == 1)
	{
		s[y - 1][x] = s[y - 2][x] = 0;
	}
	else if(n == 2)
	{
		s[y + 2][x] = s[y + 1][x] = 0;
	}
	else if(n == 3)
	{
		s[y][1] = s[y][2] = 0;
	}
	else
	{
		s[y][2] = s[y][3] = 0;
	}
}

LL dfs1(LL n,LL m,LL x,LL y,LL number)
{
	if(m > n)
	{
		for(LL i = 1;i <= n;i++)
		{
			updata(comb[i],x,y);
		}
		LL sum = cntdp(number);
		for(LL i = 1;i <= n;i++)
		{
			dowmdata(comb[i],x,y);
		}
		return sum;
	}
	LL sum = 0;
	for(LL i = 1;i <= num;i++)
	{
		if(comb[m - 1] >= i_e[i] && m != 1)
			continue;
		comb[m] = i_e[i];
		sum = (sum + dfs1(n,m + 1,x,y,number))%MOD;
	}
	return sum;
}

int main()
{
	LL i,j,k,l;
	LL n,x,y;
	while(cin>>n)
	{
		for(i = 1;i <= 3;i++)
		{
			for(j = 1;j <= n;j++)
			{
				char c;
				cin>>c;
				if(c == '.')
					s[j][i] = 0;
				else if(c == 'X')
					s[j][i] = 1;
				else
				{
					y = j;
					x = i;
					s[j][i] = 1;
				}
			}
		}
		num = 0;
		LL ans = 0;
		if(y > 2 && s[y - 2][x] + s[y - 1][x] == 0)
		{
			i_e[++num] = 1;
		}
		if(y < n - 2 && s[y + 2][x] + s[y + 1][x] == 0)
		{
			i_e[++num] = 2;
		}
		if(x == 3 && s[y][1] + s[y][2] == 0)
		{
			i_e[++num] = 3;
		}
		if(x == 1 && s[y][2] + s[y][3] == 0)
		{
			i_e[++num] = 4;
		}
		for(i = 1;i <= num;i++)
		{
			ans = (ans + dfs1(i,1,x,y,n)*(i%2 == 0?-1:1))%MOD;
		}
		cout<<ans<<endl;
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <sstream>
#include <iostream>
#include <algorithm>
#include<cstdlib>
#include<queue>

using namespace std;

#define N 10005
#define L(x) x<<1
#define R(x) x<<1|1
#define M(x,y) (x + y)>>1
#define MOD 1000000007
#define MODD 1000000006
#define inf 0x7fffffff
#define llinf 0x7fffffffffffffff
#define LL long long

LL s[N][5];
LL dp[N][10];
LL bin[10][4] = {{0,0,0,0},{0,1,0,0},{0,0,1,0},{0,1,1,0},{0,0,0,1},{0,1,0,1},{0,0,1,1},{0,1,1,1}};
LL b[4] = {0,1,2,4};
LL i_e[10],num;
LL comb[5];

void dfs(LL x,LL y,LL th,LL len)
{
	if(th == 4)
	{
		dp[len][y] = (dp[len][y] + dp[len - 1][x])%MOD;
		return ;
	}
	if(bin[y][th] == 1 && bin[x][th] == 0)
		return ;
	if(bin[y][th] == 1 && bin[x][th] == 1)
		dfs(x,y,th + 1,len);
	if(bin[y][th] == 0 && bin[x][th] == 0)
		dfs(x,y + b[th],th + 1,len);
	if(bin[y][th] == 0 && bin[x][th] == 1)
		dfs(x,y,th + 1,len);
	if(th > 1 && bin[y][th] + bin[y][th - 1] == 0 && bin[x][th] + bin[x][th - 1] == 2)
		dfs(x,y + b[th] + b[th - 1],th + 1,len);
}

LL cntdp(LL n)
{
	memset(dp,0,sizeof(dp));
	dp[0][7] = 1;
	for(LL i = 1;i <= n;i++)
	{
		for(LL j = 0;j < 8;j++)
		{
			if(dp[i - 1][j] == 0)
				continue;
			LL cnt = 0;
			for(LL k = 1;k <= 3;k++)
			{
				if(s[i][k] != 0)
				{
					cnt += b[k];
				}
			}
			dfs(j,cnt,1,i);
		}
	}
	return dp[n][7];
}

void updata(LL n,LL x,LL y)
{
	if(n == 1)
	{
		s[y - 1][x] = s[y - 2][x] = 1;
	}
	else if(n == 2)
	{
		s[y + 2][x] = s[y + 1][x] = 1;
	}
	else if(n == 3)
	{
		s[y][1] = s[y][2] = 1;
	}
	else
	{
		s[y][2] = s[y][3] = 1;
	}
}

void dowmdata(LL n,LL x,LL y)
{
	if(n == 1)
	{
		s[y - 1][x] = s[y - 2][x] = 0;
	}
	else if(n == 2)
	{
		s[y + 2][x] = s[y + 1][x] = 0;
	}
	else if(n == 3)
	{
		s[y][1] = s[y][2] = 0;
	}
	else
	{
		s[y][2] = s[y][3] = 0;
	}
}

LL dfs1(LL n,LL m,LL x,LL y,LL number)
{
	if(m > n)
	{
		for(LL i = 1;i <= n;i++)
		{
			updata(comb[i],x,y);
		}
		LL sum = cntdp(number);
		for(LL i = 1;i <= n;i++)
		{
			dowmdata(comb[i],x,y);
		}
		return sum;
	}
	LL sum = 0;
	for(LL i = 1;i <= num;i++)
	{
		if(comb[m - 1] >= i_e[i] && m != 1)
			continue;
		comb[m] = i_e[i];
		sum = (sum + dfs1(n,m + 1,x,y,number))%MOD;
	}
	return sum;
}

int main()
{
	LL i,j,k,l;
	LL n,x,y;
	while(cin>>n)
	{
		for(i = 1;i <= 3;i++)
		{
			for(j = 1;j <= n;j++)
			{
				char c;
				cin>>c;
				if(c == '.')
					s[j][i] = 0;
				else if(c == 'X')
					s[j][i] = 1;
				else
				{
					y = j;
					x = i;
					s[j][i] = 1;
				}
			}
		}
		num = 0;
		LL ans = 0;
		if(y > 2 && s[y - 2][x] + s[y - 1][x] == 0)
		{
			i_e[++num] = 1;
		}
		if(y < n - 2 && s[y + 2][x] + s[y + 1][x] == 0)
		{
			i_e[++num] = 2;
		}
		if(x == 3 && s[y][1] + s[y][2] == 0)
		{
			i_e[++num] = 3;
		}
		if(x == 1 && s[y][2] + s[y][3] == 0)
		{
			i_e[++num] = 4;
		}
		for(i = 1;i <= num;i++)
		{
			ans = (ans + dfs1(i,1,x,y,n)*(i%2 == 0?-1:1))%MOD;
		}
		ans = (ans + MOD)%MOD;
		cout<<ans<<endl;
	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

const int maxn = 10100;
const int MOD = 1000000007;
const int phx[] = {1, -1, 0, 0};
const int phy[] = {0, 0, 1, -1};

int n;
int f[maxn][3][8];
char board[maxn][3];
bool filled[maxn][3];

string buffer;

bool check(int x, int y) {
    return (x >= 0 && x < n && y >= 0 && y < 3 && !filled[x][y]);
}

bool contain(int k, int t) {
    return (k & (1 << t));
}

void update(int &a, int b) {
    a = ((long long)a + b) % MOD;
}

int calc(int state) {
    int x = 0, y = 0;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            if (board[i][j] == 'O') {
                x = i;
                y = j;
            }

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            filled[i][j] = (board[i][j] != '.');

    for (int i = 0; i < 4; ++i)
        if (state & (1 << i)) {
            int tx1 = x + phx[i];
            int ty1 = y + phy[i];
            int tx2 = tx1 + phx[i];
            int ty2 = ty1 + phy[i];
            if (check(tx1, ty1) && check(tx2, ty2)) {
                if (state == 1)
                filled[tx1][ty1] = filled[tx2][ty2] = 1;
            }
            else {
                return 0;
            }
        }

    for (int i = 0; i <= n; i++)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 8; ++k)
                f[i][j][k] = 0;
    f[0][0][0] = 1;

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 8; ++k)
                if (f[i][j][k] != 0) {
                    int x = i;
                    int y = j + 1;
                    if (y == 3) {
                        x++;
                        y = 0;
                    }

                    int val = f[i][j][k];

                    if (filled[i][j]) {
                        if (!contain(k, j)) update(f[x][y][k], val);
                    }
                    else {
                        if (contain(k, j)) {
                            update(f[x][y][k ^ (1 << j)], val);
                        }
                        else {
                            update(f[x][y][k | (1 << j)], val);
                            if (j + 1 < 3 && !contain(k, j + 1))
                                update(f[x][y][k | (2 << j)], val);
                        }
                    }
                }

    return f[n][0][0];
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < 3; ++i) {
        cin>>buffer;
        for (int j = 0; j < n; ++j)
            board[j][i] = buffer[j];
    }

    int ans = 0;
    for (int i = 0; i < 16; ++i)
        if (i != 0) {
            int tmp = calc(i);
            if (__builtin_popcount(i) % 2 == 1) ans = (ans + tmp) % MOD;
            else ans = (ans - tmp + MOD) % MOD;
        }

    printf("%d\n", int(((long long)ans + MOD) % MOD));

}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

const int maxn = 10100;
const int MOD = 1000000007;
const int phx[] = {1, -1, 0, 0};
const int phy[] = {0, 0, 1, -1};

int n;
int f[maxn][3][8];
char board[maxn][3];
bool filled[maxn][3];

string buffer;

bool check(int x, int y) {
    return (x >= 0 && x < n && y >= 0 && y < 3 && !filled[x][y]);
}

bool contain(int k, int t) {
    return (k & (1 << t));
}

void update(int &a, int b) {
    a = ((long long)a + b) % MOD;
}

int calc(int state) {
    int x = 0, y = 0;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            if (board[i][j] == 'O') {
                x = i;
                y = j;
            }

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            filled[i][j] = (board[i][j] != '.');

    for (int i = 0; i < 4; ++i)
        if (state & (1 << i)) {
            int tx1 = x + phx[i];
            int ty1 = y + phy[i];
            int tx2 = tx1 + phx[i];
            int ty2 = ty1 + phy[i];
            if (check(tx1, ty1) && check(tx2, ty2)) {
                if (state == 1)
                filled[tx1][ty1] = filled[tx2][ty2] = 1;
            }
            else {
                return 0;
            }
        }

    for (int i = 0; i <= n; i++)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 8; ++k)
                f[i][j][k] = 0;
    f[0][0][0] = 1;

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 8; ++k)
                if (f[i][j][k] != 0) {
                    int x = i;
                    int y = j + 1;
                    if (y == 3) {
                        x++;
                        y = 0;
                    }

                    int val = f[i][j][k];

                    if (filled[i][j]) {
                        if (!contain(k, j)) update(f[x][y][k], val);
                    }
                    else {
                        if (contain(k, j)) {
                            update(f[x][y][k ^ (1 << j)], val);
                        }
                        else {
                            update(f[x][y][k | (1 << j)], val);
                            if (j + 1 < 3 && !contain(k, j + 1))
                                update(f[x][y][k | (2 << j)], val);
                        }
                    }
                }

    return f[n][0][0];
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < 3; ++i) {
        cin>>buffer;
        for (int j = 0; j < n; ++j)
            board[j][i] = buffer[j];
    }

    int ans = 0;
    for (int i = 0; i < 16; ++i)
        if (i != 0) {
            int tmp = calc(i);
            if (__builtin_popcount(i) % 2 == 1) ans = (ans + tmp) % MOD;
            else ans = (ans - tmp + MOD) % MOD;
        }

    printf("%d\n", (ans + MOD) % MOD);
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

const int maxn = 10100;
const int MOD = 1000000007;
const int phx[] = {1, -1, 0, 0};
const int phy[] = {0, 0, 1, -1};

int n;
int f[maxn][3][8];
char board[maxn][3];
bool filled[maxn][3];

string buffer;

bool check(int x, int y) {
    return (x >= 0 && x < n && y >= 0 && y < 3 && !filled[x][y]);
}

bool contain(int k, int t) {
    return (k & (1 << t));
}

void update(int &a, int b) {
    a = ((long long)a + b) % MOD;
}

int calc(int state) {
    int x = 0, y = 0;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            if (board[i][j] == 'O') {
                x = i;
                y = j;
            }

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            filled[i][j] = (board[i][j] != '.');

    for (int i = 0; i < 4; ++i)
        if (state & (1 << i)) {
            int tx1 = x + phx[i];
            int ty1 = y + phy[i];
            int tx2 = tx1 + phx[i];
            int ty2 = ty1 + phy[i];
            if (check(tx1, ty1) && check(tx2, ty2)) {
                filled[tx1][ty1] = filled[tx2][ty2] = 1;
            }
            else {
                return 0;
            }
        }

    for (int i = 0; i <= n; i++)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 8; ++k)
                f[i][j][k] = 0;
    f[0][0][0] = 1;

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < 3; ++j)
            for (int k = 0; k < 8; ++k)
                if (f[i][j][k] != 0) {
                    int x = i;
                    int y = j + 1;
                    if (y == 3) {
                        x++;
                        y = 0;
                    }

                    int val = f[i][j][k];

                    if (filled[i][j]) {
                        if (!contain(k, j)) update(f[x][y][k], val);
                    }
                    else {
                        if (contain(k, j)) {
                            update(f[x][y][k ^ (1 << j)], val);
                        }
                        else {
                            update(f[x][y][k | (1 << j)], val);
                            if (j + 1 < 3 && !contain(k, j + 1))
                                update(f[x][y][k | (2 << j)], val);
                        }
                    }
                }

    return f[n][0][0];
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < 3; ++i) {
        cin>>buffer;
        for (int j = 0; j < n; ++j)
            board[j][i] = buffer[j];
    }

    int ans = 0;
    for (int i = 0; i < 16; ++i)
        if (i != 0) {
            int tmp = calc(i);
            if (__builtin_popcount(i) % 2 == 1) ans = (ans + tmp) % MOD;
            else ans = (ans - tmp + MOD) % MOD;
        }

    printf("%d\n", ans);

}


#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef long long LL;
typedef unsigned long long ULL;
//const
const int N=30;
const int INF=0x3f3f3f3f;
const int MOD=1000000007,STA=8000010;
const LL LNF=1LL<<60;
const double EPS=1e-8;
const double OO=1e15;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End

char ma[3][10010];
int sta[N],f[2][N],vis[N];
int cnt,xo,yo;
int n;

void debug(int sta)
{
    for(int q=2;q>=0;q--){
        printf("%d",(sta&(3<<(q<<1)))>>(q<<1));
    }
}

void dfs(int cur,int a,int ok)
{
    if(cur==3){
        if(ok)f[0][cnt]=1;
        sta[cnt++]=a;
        return ;
    }
    dfs(cur+1,a,ok);
    dfs(cur+1,a|(1<<(cur<<1)),0);
    if(cur<2)dfs(cur+2,a|(10<<(cur<<1)),ok&(ma[cur][0]=='X'?0:1)&(ma[cur+1][0]=='X'?0:1));
}

bool iscover(int sta,int x)
{
    int i;
    for(i=0;i<3;i++)
        if( ma[i][x]=='X' && (sta&(3<<(i<<1))) )return true;
    return false;
}

bool match(int sta1,int sta2,int x)
{
    if(iscover(sta1,x-1) || iscover(sta2,x))return false;
    int i;
    for(i=0;i<3;i++){
        if(ma[i][x-1]=='.' && !(sta1&(3<<(i<<1))) && !(sta2&(1<<(i<<1))) )return false;
        if((ma[i][x-1]=='X' || (sta1&(3<<(i<<1)))) && (sta2&(1<<(i<<1))) )return false;
    }
    return true;
}

int main(){
 //   freopen("in.txt","r",stdin);
    int i,j,k,p,ans,ok;
    while(~scanf("%d",&n))
    {
        xo=-1;
        for(i=0;i<3;i++){
            scanf("%s",ma[i]);
            for(j=0;j<n && xo==-1;j++)
                if(ma[i][j]=='O')xo=j,yo=i,ma[i][j]='X';
        }
        if(xo==n-1){
            ma[0][n]=ma[1][n]=ma[2][n]='X';
            n++;
        }

        cnt=0;
        mem(f[p=0],0);
        dfs(0,0,1);
        mem(f[p=!p],0);
        for(i=1;i<n;i++,mem(f[p=!p],0)){
            if(i!=xo){
                for(j=0;j<cnt;j++){
                    if(!f[!p][j])continue;
                    for(k=0;k<cnt;k++){
                        if(match(sta[j],sta[k],i))
                            f[p][k]=(f[p][k]+f[!p][j])%MOD;
                    }
                }
            }
            else {
                mem(vis,0);
                for(j=0;j<cnt;j++){
                    if(!f[!p][j])continue;
                    for(k=0;k<cnt;k++){
                        if(match(sta[j],sta[k],i)){
                            f[p][k]=(f[p][k]+f[!p][j])%MOD;
                            if( sta[j]&(1<<(yo<<1)) )vis[k]=1;
                            if( yo!=1 && (sta[k]&(2<<2)) )vis[k]=1;
                        }
                    }
                }

                i++,mem(f[p=!p],0);
                for(j=0;j<cnt;j++){
                    if(!f[!p][j])continue;
                    for(k=0;k<cnt;k++){
                        if(match(sta[j],sta[k],i)){
                            if( vis[j] || (!(sta[k]&(3<<(yo<<1))) && ma[yo][i]!='X') )f[p][k]=(f[p][k]+f[!p][j])%MOD;
                        }
                    }
                }
            }
        }
        ans=0;p=!p;n--;
        for(i=0;i<cnt;i++){
            ok=1;
            for(j=0;j<3;j++){
                if( (ma[j][n]=='.' && !(sta[i]&(3<<(j<<1))))
                   || (ma[j][n]=='X' && (sta[i]&(3<<(j<<1)))) ){
                    ok=0;break;
                }
            }
            if(ok)ans=(ans+f[p][i])%MOD;
        }

        printf("%d\n",ans);
    }
    return 0;
}


#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef long long LL;
typedef unsigned long long ULL;
//const
const int N=30;
const int INF=0x3f3f3f3f;
const int MOD=1000000007,STA=8000010;
const LL LNF=1LL<<60;
const double EPS=1e-8;
const double OO=1e15;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End

char ma[3][10010];
int sta[N],f[2][N],vis[N];
int cnt,xo,yo;
int n;

void debug(int sta)
{
    for(int q=2;q>=0;q--){
        printf("%d",(sta&(3<<(q<<1)))>>(q<<1));
    }
}

void dfs(int cur,int a,int ok)
{
    if(cur==3){
        if(ok)f[0][cnt]=1;
        sta[cnt++]=a;
        return ;
    }
    dfs(cur+1,a,ok);
    dfs(cur+1,a|(1<<(cur<<1)),0);
    if(cur<2)dfs(cur+2,a|(10<<(cur<<1)),ok&((ma[cur][0]=='X' || ma[cur+1][0]=='X')?0:1));
}

bool iscover(int sta,int x)
{
    int i;
    for(i=0;i<3;i++)
        if( ma[i][x]=='X' && (sta&(3<<(i<<1))) )return true;
    return false;
}

bool match(int sta1,int sta2,int x)
{
    if(iscover(sta1,x-1) || iscover(sta2,x))return false;
    int i;
    for(i=0;i<3;i++){
        if(ma[i][x-1]=='.' && !(sta1&(3<<(i<<1))) && !(sta2&(1<<(i<<1))) )return false;
        if((ma[i][x-1]=='X' || (sta1&(3<<(i<<1)))) && (sta2&(1<<(i<<1))) )return false;
    }
    return true;
}

int main(){
 //   freopen("in.txt","r",stdin);
    int i,j,k,p,ans,ok;
    while(~scanf("%d",&n))
    {
        xo=-1;
        for(i=0;i<3;i++){
            scanf("%s",ma[i]);
            for(j=0;j<n && xo==-1;j++)
                if(ma[i][j]=='O')xo=j,yo=i,ma[i][j]='X';
        }
        if(xo==n-1){
            ma[0][n]=ma[1][n]=ma[2][n]='X';
            n++;
        }

        cnt=0;
        mem(f[p=0],0);
        dfs(0,0,1);
        mem(f[p=!p],0);
        for(i=1;i<n;i++,mem(f[p=!p],0)){
            if(i!=xo){
                for(j=0;j<cnt;j++){
                    if(!f[!p][j])continue;
                    for(k=0;k<cnt;k++){
                        if(match(sta[j],sta[k],i))
                            f[p][k]=(f[p][k]+f[!p][j])%MOD;
                    }
                }
            }
            else {
                mem(vis,0);
                int ft[N];mem(ft,0);
                for(j=0;j<cnt;j++){
                    if(!f[!p][j])continue;
                    for(k=0;k<cnt;k++){
                        if(match(sta[j],sta[k],i)){
                            f[p][k]=(f[p][k]+f[!p][j])%MOD;
                            if( (sta[j]&(1<<(yo<<1))) || (yo!=1 && (sta[k]&(2<<2))) ){
                                vis[k]=1;
                                ft[k]=(ft[k]+f[!p][j])%MOD;
                            }
                        }
                    }
                }
                i++,mem(f[p=!p],0);
                for(j=0;j<cnt;j++){
                    if(!f[!p][j] && !ft[j])continue;
                    for(k=0;k<cnt;k++){
                        if(match(sta[j],sta[k],i)){
                            if(!(sta[k]&(3<<(yo<<1))) && ma[yo][i]!='X')f[p][k]=(f[p][k]+f[!p][j])%MOD;
                            else if(vis[j])f[p][k]=(f[p][k]+ft[j])%MOD;
                        }
                    }
                }
            }
        }
        ans=0;p=!p;n--;
        for(i=0;i<cnt;i++){
            ok=1;
            for(j=0;j<3;j++){
                if( (ma[j][n]=='.' && !(sta[i]&(3<<(j<<1))))
                   || (ma[j][n]=='X' && (sta[i]&(3<<(j<<1)))) ){
                    ok=0;break;
                }
            }
            if(ok)ans=(ans+f[p][i])%MOD;
        }

        printf("%d\n",ans);
    }
    return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

const int mod = 1000000007;
const int Maxn = 10005;
const int Maxd = 3;

int n;
char B[Maxd][Maxn];
int ways[Maxn][1 << Maxd][2];

int Get2(int c, int r, int mask, int flag);

int Get(int c, int mask, int flag)
{
	if (c == n) return flag == 1;
	if (ways[c][mask][flag] == -1)
		ways[c][mask][flag] = Get2(c, 0, mask, flag);
	return ways[c][mask][flag];
}

bool Empty(int r, int c)
{
	return 0 <= r && r < Maxd && 0 <= c && c < n && B[r][c] == 'O';
}

int Get2(int c, int r, int mask, int flag)
{
	if (r == Maxd) return Get(c + 1, mask, flag);
	if (mask & 1 << r) return Get2(c, r + 1, mask ^ 1 << r, flag);
	if (B[r][c] != '.') return Get2(c, r + 1, mask, flag);
	int res = 0;
	if (r + 1 < Maxd && !(mask & 1 << r + 1) && B[r + 1][c] == '.') {
		int nflag = flag || Empty(r - 1, c) || Empty(r + 2, c);
		res = (res + Get2(c, r + 2, mask, nflag));
	}
	if (c + 1 < n && B[r][c + 1] == '.') {
		int nflag = flag || Empty(r, c - 1) || Empty(r, c + 2);
		res = (res + Get2(c, r + 1, mask | 1 << r, nflag));
	}
	return res;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < Maxd; i++)
		for (int j = 0; j < n; j++)
			scanf(" %c", &B[i][j]);
	fill((int*)ways, (int*)ways + Maxn * (1 << Maxd) * 2, -1);
	printf("%d\n", Get(0, 0, 0));
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

const int mod = 1000000007;
const int Maxn = 10005;
const int Maxd = 3;

int n;
char B[Maxd][Maxn];
int ways[Maxn][1 << Maxd][2];

int Get2(int c, int r, int mask, int flag);

int Get(int c, int mask, int flag)
{
	if (c == n) return flag == 1;
	if (ways[c][mask][flag] == -1)
		ways[c][mask][flag] = Get2(c, 0, mask, flag);
	return ways[c][mask][flag];
}

bool Empty(int r, int c)
{
	return 0 <= r && r < Maxd && 0 <= c && c < Maxn && B[r][c] == 'O';
}

int Get2(int c, int r, int mask, int flag)
{
	if (r == Maxd) return Get(c + 1, mask, flag);
	if (mask & 1 << r) return Get2(c, r + 1, mask ^ 1 << r, flag);
	if (B[r][c] != '.') return Get2(c, r + 1, mask, flag);
	int res = 0;
	if (r + 1 < Maxd && !(mask & 1 << r + 1) && B[r + 1][c] == '.') {
		int nflag = flag || Empty(r - 1, c) || Empty(r + 2, c);
		res = (res + Get2(c, r + 2, mask, nflag));
	}
	if (c + 1 < n && B[r][c + 1] == '.') {
		int nflag = flag || Empty(r, c - 1) || Empty(r, c + 2);
		res = (res + Get2(c, r + 1, mask | 1 << r, nflag));
	}
	return res;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < Maxd; i++)
		for (int j = 0; j < n; j++)
			scanf(" %c", &B[i][j]);
	fill((int*)ways, (int*)ways + Maxn * (1 << Maxd) * 2, -1);
	printf("%d\n", Get(0, 0, 0));
	return 0;
}


#include <cstdio>
#include <algorithm>
using namespace std;

const int mod = 1000000007;
const int Maxn = 10005;
const int Maxd = 3;

int n;
char B[Maxd][Maxn];
int ways[Maxn][1 << Maxd][2];

int Get2(int c, int r, int mask, int flag);

int Get(int c, int mask, int flag)
{
	if (c == n) return flag == 1;
	if (ways[c][mask][flag] == -1)
		ways[c][mask][flag] = Get2(c, 0, mask, flag);
	return ways[c][mask][flag];
}

bool Empty(int r, int c)
{
	return 0 <= r && r < Maxd && 0 <= c && c < n && B[r][c] == 'O';
}

int Get2(int c, int r, int mask, int flag)
{
	if (r == Maxd) return Get(c + 1, mask, flag);
	if (mask & 1 << r) return Get2(c, r + 1, mask ^ 1 << r, flag);
	if (B[r][c] != '.') return Get2(c, r + 1, mask, flag);
	int res = 0;
	if (r + 1 < Maxd && !(mask & 1 << r + 1) && B[r + 1][c] == '.') {
		int nflag = flag || Empty(r - 1, c) || Empty(r + 2, c);
		res = (res + Get2(c, r + 2, mask, nflag)) % mod;
	}
	if (c + 1 < n && B[r][c + 1] == '.') {
		int nflag = flag || Empty(r, c - 1) || Empty(r, c + 2);
		res = (res + Get2(c, r + 1, mask | 1 << r, nflag)) % mod;
	}
	return res;
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < Maxd; i++)
		for (int j = 0; j < n; j++)
			scanf(" %c", &B[i][j]);
	fill((int*)ways, (int*)ways + Maxn * (1 << Maxd) * 2, -1);
	printf("%d\n", Get(0, 0, 0));
	return 0;
}


#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) ((x)&(-(x)))
#define jsb 1000000007
using namespace std;
int n;
char str[5][11000];
bool mp[5][11000];
int f[11000][8][2];int pang[11000];
int cx,cy;
inline void A(int &x,int y){x+=y;if(x>=jsb)x-=jsb;}
inline bool put(int x1,int y1,int x2,int y2)
{
	if(x1>3||x2>3||y1>n||y2>n)return 0;
	if(x1==x2)
	{
		if(y2<y1)swap(y1,y2);
		if(y1-1==cy||y2+1==cy)return 1;else return 0;
	}
	if(y1==y2)
	{
		if(cx==2)return 0;
		if(x1+x2==7-cx)return 1;else return 0;
	}
}
int dfs(int now,int zt,int flag)
{
	#define orz f[now][zt][flag]
	if(now==n+1)return (!zt)&&flag;
	if(orz!=-1)return orz;
	orz=0;
	//321
	//OOX
	if(zt==1)
	{
		A(orz,dfs(now+1,pang[now+1],flag|put(2,now,3,now)));
		if(!(6&pang[now+1]))A(orz,dfs(now+1,pang[now+1]|6,flag|put(2,now,2,now+1)|put(3,now,3,now+1)));
		}
	//XOX
	if(zt==5)
	{
		if(!(2&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|2,flag|put(2,now,2,now+1)));
	}
	//XXX
	if(zt==7)return orz=dfs(now+1,pang[now+1],flag);
	//XOO
	if(zt==4)
	{
		A(orz,dfs(now+1,pang[now+1],flag|put(2,now,1,now)));
		if(!(3&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|3,flag|put(2,now,2,now+1)|put(1,now,1,now+1)));
	}
	//OXX
	if(zt==3)
	{
		if(!(4&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|4,flag|put(3,now,3,now+1)));
	}
	//XXO
	if(zt==6)
	{
		if(!(1&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|1,flag|put(1,now,1,now+1)));
	}
	//OOO
	if(zt==0)
	{
		if(!(7&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|7,flag|put(1,now,1,now+1)|put(2,now,2,now+1)|put(3,now,3,now+1)));
		if(!(1&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|1,flag|put(2,now,2,now+1)|put(3,now,3,now+1)));
		if(!(4&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|4,flag|put(1,now,1,now+1)|put(2,now,2,now+1)));
	}
	return orz;
}
#undef orz
int main()
{
	scanf("%d",&n);rep(i,1,3)scanf("%s",str[i]+1);int ans=0;
	rep(i,1,3)rep(j,1,n)if(str[i][j]=='O'){mp[i][j]=0;cx=i;cy=j;}else mp[i][j]=(str[i][j]=='.');
	memset(f,-1,sizeof f);rep(i,1,n)rep(j,1,3)pang[i]+=(1<<(j-1))*(!mp[j][i]);
	printf("%d\n",dfs(1,pang[1],0));return 0;
}


#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) ((x)&(-(x)))
#define jsb 1000000007
using namespace std;
int n;
char str[5][11000];
bool mp[5][11000];
int f[11000][8][2];int pang[11000];
int cx,cy;
inline void A(int &x,int y){x+=y;if(x>=jsb)x-=jsb;}
inline bool put(int x1,int y1,int x2,int y2)
{
	if(x1>3||x2>3||y1>n||y2>n)return 0;
	if(x1==x2)
	{
		if(y2<y1)swap(y1,y2);
		if(y1-1==cy||y2+1==cy)return 1;else return 0;
	}
	if(y1==y2)
	{
		if(cx==2)return 0;
		if(y1!=cy)return 0;
		if(x1+x2==7-cx)return 1;else return 0;
	}
}
int dfs(int now,int zt,int flag)
{
	//printf("_%d %d %d\n",now,zt,flag);
	#define orz f[now][zt][flag]
	if(now==n+1)return (!zt)&&flag;
	if(orz!=-1)return orz;
	orz=0;
	//321
	//OOX
	if(zt==1)
	{
		A(orz,dfs(now+1,pang[now+1],flag|put(2,now,3,now)));
		if(!(6&pang[now+1]))A(orz,dfs(now+1,pang[now+1]|6,flag|put(2,now,2,now+1)|put(3,now,3,now+1)));
		}
	//XOX
	if(zt==5)
	{
		if(!(2&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|2,flag|put(2,now,2,now+1)));
	}
	//XXX
	if(zt==7)return orz=dfs(now+1,pang[now+1],flag);
	//XOO
	if(zt==4)
	{
		A(orz,dfs(now+1,pang[now+1],flag|put(2,now,1,now)));
		if(!(3&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|3,flag|put(2,now,2,now+1)|put(1,now,1,now+1)));
	}
	//OXX
	if(zt==3)
	{
		if(!(4&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|4,flag|put(3,now,3,now+1)));
	}
	//XXO
	if(zt==6)
	{
		if(!(1&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|1,flag|put(1,now,1,now+1)));
	}
	//OOO
	if(zt==0)
	{
		if(!(7&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|7,flag|put(1,now,1,now+1)|put(2,now,2,now+1)|put(3,now,3,now+1)));
		if(!(1&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|1,flag|put(2,now,2,now+1)|put(3,now,3,now+1)));
		if(!(4&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|4,flag|put(1,now,1,now+1)|put(2,now,2,now+1)));
	}
	//OXO
	if(zt==2)
	{
		if(!(5&pang[now+1]))
		A(orz,dfs(now+1,pang[now+1]|5,flag|put(1,now,1,now+1)|put(3,now,3,now+1)));
	}
	return orz;
}
#undef orz
void DEBUG()
{
	//--------just for debug
	printf("__%d\n",dfs(3,2,1));
}
int main()
{
	scanf("%d",&n);rep(i,1,3)scanf("%s",str[i]+1);int ans=0;
	rep(i,1,3)rep(j,1,n)if(str[i][j]=='O'){mp[i][j]=0;cx=i;cy=j;}else mp[i][j]=(str[i][j]=='.');
	memset(f,-1,sizeof f);rep(i,1,n)rep(j,1,3)pang[i]+=(1<<(j-1))*(!mp[j][i]);
	//DEBUG();
	printf("%d\n",dfs(1,pang[1],0));return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define MOD 1000000007
int N;
LL dp[10010][1<<3][2];
int Marked[10010];
char Board[3][10010];
LL calc(int idx,int mask,int flag)
{
	if(idx==N)
	{
		return flag==1&&mask==0;
	}
	LL &Res = dp[idx][mask][flag];
	if(Res==-1)
	{
		Res = 0;
		if(mask==7){
			Res = calc(idx+1,0,flag);
		}
		else
		{
			if(((mask&3)==0)&&((Marked[idx]&3)==0))
				Res+=calc(idx,mask|3,Board[2][idx]=='O'|flag);
			if(((mask&6)==0)&&((Marked[idx]&6)==0))
				Res+=calc(idx,mask|6,Board[0][idx]=='O'|flag);
			int idy = -1,Mask = 0,f = 0;
			for(int i = 0;i<3;i++)
			{
				if((mask&(1<<i))||(Marked[idx]&(1<<i)))
					continue;
				if(idx>=1&&Board[i][idx-1]=='O')
					f = 1;
				if(Board[i][idx+2]=='O')
					f = 1;
				if((Marked[idx+1]&(1<<i)))
					idy = i;
				Mask|=(1<<i);
			}
			if(idy==-1){
				Res+=calc(idx+1,Mask,flag|f);
			}
		}
		Res%=MOD;
	}
	return Res;
}
int main()
{
	cin>>N;
	for(int i = 0;i<3;i++)
	{
		cin>>Board[i];
		Board[i][N] = 'X';
		Board[i][N+1] = 'X';
	}
	for(int i = 0;i<=N+1;i++)
	{
		Marked[i] = 7;
		for(int j = 0;j<3;j++)
		{
			if(Board[j][i]=='.')
				Marked[i]-=(1<<j);
		}
	}
	memset(dp,-1,sizeof(dp));
	cout<<calc(0,0,0)<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define MOD 1000000007
int N;
LL dp[10010][1<<3][2];
int Marked[10010];
char Board[3][10010];
LL calc(int idx,int mask,int flag)
{
	if(idx==N)
	{
		return flag==1&&mask==0;
	}
	LL &Res = dp[idx][mask][flag];
	if(Res==-1)
	{
		Res = 0;
		if(mask==7){
			Res = calc(idx+1,0,flag);
		}
		else
		{
			if(((mask&3)==0)&&((Marked[idx]&3)==0))
				Res+=calc(idx,mask|3,Board[2][idx]=='O'|flag);
			if(((mask&6)==0)&&((Marked[idx]&6)==0))
				Res+=calc(idx,mask|6,Board[0][idx]=='O'|flag);
			int idy = -1,Mask = 0,f = 0;
			for(int i = 0;i<3;i++)
			{
				if((mask&(1<<i))||(Marked[idx]&(1<<i)))
					continue;
				if(idx>=1&&Board[i][idx-1]=='O')
					f = 1;
				if(Board[i][idx+2]=='O')
					f = 1;
				if((Marked[idx+1]&(1<<i)))
					idy = i;
				Mask|=(1<<i);
			}
			if(idy==-1){
				Res+=calc(idx+1,Mask,flag|f);
			}
		}
		Res%=MOD;
	}
	return Res;
}
int main()
{
	cin>>N;
	for(int i = 0;i<3;i++)
	{
		cin>>Board[i];
		Board[i][N] = 'X';
		Board[i][N+1] = 'X';
	}
	for(int i = 0;i<=N+1;i++)
	{
		Marked[i] = 7;
		for(int j = 0;j<3;j++)
		{
			if(Board[j][i]=='.')
				Marked[i]-=(1<<j);
		}
		cout<<Marked[i]<<endl;
	}
	memset(dp,-1,sizeof(dp));
	cout<<calc(0,0,0)<<endl;
	return 0;
}


#include <cstdio>
#include <cstring>

typedef long long LL;

const int P = 1000000007;
const int N = 10007;

#define __buitin_popcount popcnt

inline LL add(LL a, LL b) { return (a+b)%P; }
inline LL sub(LL a, LL b) { return (a-b+P)%P; }
inline LL mul(LL a, LL b) { return a*b%P; }

int n, f[N][8];
char s[3][N];

int gao(bool flag) {
	memset(f, 0, sizeof f);
	f[0][7] = 1;
	int cidx = 0, cmsk = 0;
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < 3; ++j) {
			if(s[j][i] == 'O') {
				cidx = i;
				cmsk = 1<<j;
			}
		}
	}
	for(int i = 0; i < n; ++i) {
		int vld = 0;
		for(int j = 0; j < 3; ++j) {
			if(s[j][i] == '.') vld |= 1<<j;
		}
		for(int x = 0; x < 8; ++x) if(f[i][x]) {
			int y = x ^ 7;
			if((vld & y) != y) continue;
			y |= vld ^ 7;
			if(flag) {
				f[i+1][y] = add(f[i+1][y], f[i][x]);
				if(!(y & 3)) f[i+1][y|3] = add(f[i+1][y|3], f[i][x]);
				if(!(y & 6)) f[i+1][y|6] = add(f[i+1][y|6], f[i][x]);
			} else {
				if(i+2 == cidx && !(y & cmsk)) continue;
				if(i-1 == cidx) {
					if(y & cmsk) f[i+1][y] = add(f[i+1][y], f[i][x]);
					if(!(y & 3) && ((y|3) & cmsk))
						f[i+1][y|3] = add(f[i+1][y|3], f[i][x]);
					if(!(y & 6) && ((y|6) & cmsk))
						f[i+1][y|6] = add(f[i+1][y|6], f[i][x]);
				} else if(i == cidx) {
					f[i+1][y] = add(f[i+1][y], f[i][x]);
				} else {
					f[i+1][y] = add(f[i+1][y], f[i][x]);
					if(!(y & 3)) f[i+1][y|3] = add(f[i+1][y|3], f[i][x]);
					if(!(y & 6)) f[i+1][y|6] = add(f[i+1][y|6], f[i][x]);
				}
			}
		}
	}
	return f[n][7];
}

int main() {
	scanf("%d", &n);
	for(int i = 0; i < 3; ++i) scanf("%s", s[i]);
	int ans = sub(gao(true), gao(false));
	printf("%d\n", ans);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

const int P = 1000000007;
const int N = 10007;

inline LL add(LL a, LL b) { return (a+b)%P; }
inline LL sub(LL a, LL b) { return (a-b+P)%P; }
inline LL mul(LL a, LL b) { return a*b%P; }

int n, f[N][8], vld[N], cidx, cmsk;
char s[3][N];

int gao(bool flag) {
	memset(f, 0, sizeof f);
	f[0][7] = 1;
	for(int i = 0; i < n; ++i) {
		for(int x = 0; x < 8; ++x) if(f[i][x]) {
			int y = x^7;
			if((vld[i]&y) != y) continue;
			y |= vld[i]^7;
			bool f1 = !flag && (i+2==cidx || i-1==cidx) && !(y&cmsk);
			bool f2 = (y&3) || !flag && ((i+2==cidx || i-1==cidx) && ((y|3)&cmsk) || i==cidx);
			bool f3 = (y&6) || !flag && ((i+2==cidx || i-1==cidx) && ((y|6)&cmsk) || i==cidx);
			if(!f1) f[i+1][y] = add(f[i+1][y], f[i][x]);
			if(!f2) f[i+1][y|3] = add(f[i+1][y|3], f[i][x]);
			if(!f3) f[i+1][y|6] = add(f[i+1][y|6], f[i][x]);
		}
	}
	return f[n][7];
}

int main() {
	scanf("%d", &n);
	for(int i = 0; i < 3; ++i) scanf("%s", s[i]);
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < 3; ++j) {
			if(s[j][i] == '.') vld[i] |= 1<<j;
			if(s[j][i] == 'O') cmsk = 1<<j, cidx = i;
		}
	}
	int ans = sub(gao(true), gao(false));
	printf("%d\n", ans);
}


#include <cstdio>
#include <cstring>

typedef long long LL;

const int P = 1000000007;
const int N = 10007;

inline LL add(LL a, LL b) { return (a+b)%P; }
inline LL sub(LL a, LL b) { return (a-b+P)%P; }
inline LL mul(LL a, LL b) { return a*b%P; }

int n, f[N][8], vld[N], cidx, cmsk;
char s[3][N];

int gao(bool flag) {
	memset(f, 0, sizeof f);
	f[0][7] = 1;
	for(int i = 0; i < n; ++i) {
		for(int x = 0; x < 8; ++x) if(f[i][x]) {
			int y = x^7;
			if((vld[i]&y) != y) continue;
			y |= vld[i]^7;
			bool f1 = !flag && (i+2==cidx || i-1==cidx) && !(y&cmsk);
			bool f2 = (y&3) || (!flag && (((i+2==cidx || i-1==cidx) && !((y|3)&cmsk)) || i==cidx));
			bool f3 = (y&6) || (!flag && (((i+2==cidx || i-1==cidx) && !((y|6)&cmsk)) || i==cidx));
			if(!f1) f[i+1][y] = add(f[i+1][y], f[i][x]);
			if(!f2) f[i+1][y|3] = add(f[i+1][y|3], f[i][x]);
			if(!f3) f[i+1][y|6] = add(f[i+1][y|6], f[i][x]);
		}
	}
	return f[n][7];
}

int main() {
	scanf("%d", &n);
	for(int i = 0; i < 3; ++i) scanf("%s", s[i]);
	for(int i = 0; i < n; ++i) {
		for(int j = 0; j < 3; ++j) {
			if(s[j][i] == '.') vld[i] |= 1<<j;
			if(s[j][i] == 'O') cmsk = 1<<j, cidx = i;
		}
	}
	int ans = sub(gao(true), gao(false));
	printf("%d\n", ans);
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 10005
#define mod 1000000007
#define Ask(xx, yy) ( map[yy][xx] == 0 && (xx==i || ((st>>yy-1)&1)==0) )
using namespace std ;
typedef long long LL ;

int N, M ;
int map[5][MAXN] ;
LL dp[MAXN][8][2] ;
char ss[MAXN] ;

void Work(int i, int now, int nst, int st, int flag, LL ad)
{
	if(now > 3)
	{
		dp[i][nst][flag] = (dp[i][nst][flag]+ad)%mod ;
		return ;
	}
	if(!Ask(i, now))
		if(!Ask(i-1, now)) Work(i, now+1, nst, st, flag, ad) ;
		else ;
	else
	{
		if(Ask(i-1, now))
			if(Ask(i, now))
				Work(i, now+1, nst+(1<<now-1), st, flag|(map[i+1][now] == 2 || map[i-2][now] == 2), ad) ;
			else ;
		else
		{
			if(Ask(i, now) && Ask(i, now+1) && (!Ask(i-1, now+1)))
				Work(i, now+2, nst+(3<<now-1), st, flag|(map[i+1][now-1] == 2 || map[i][now+2] == 2), ad) ;
			Work(i, now+1, nst, st, flag, ad) ;
		}
	}
}

int main()
{
	int i, j, t ;
	scanf("%d", &N) ;
	for(i = 1; i <= 3; i ++)
	{
		scanf("%s", ss) ;
		for(j = 1; j <= N; j ++)
			map[i][j] = ((ss[j-1]=='.')?0:(ss[j-1]=='X'?1:2)) ;
		map[i][0] = map[i][N+1] = 1 ;
	}
	for(i = 1; i <= N; i ++)
		map[0][i] = map[4][i] = 1 ;
	dp[0][7][0] = 1 ;
	for(i = 1; i <= N+1; i ++)
		for(j = 0; j <= 7; j ++)
			for(t = 0; t <= 1; t ++)
				if(dp[i-1][j][t])
					Work(i, 1, 0, j, t, dp[i-1][j][t]) ;
	printf("%I64d\n", dp[N+1][0][1]) ;
	//system("pause") ;
	return 0 ;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 10005
#define mod 1000000007
#define Ask(xx, yy) ( map[yy][xx] == 0 && (xx==i || ((st>>yy-1)&1)==0) )
using namespace std ;
typedef long long LL ;

int N, M ;
int map[10][MAXN] ;
LL dp[MAXN][10][4] ;
char ss[MAXN] ;

void Work(int i, int now, int nst, int st, int flag, LL ad)
{
	if(now > 3)
	{
		dp[i][nst][flag] = (dp[i][nst][flag]+ad)%mod ;
		return ;
	}
	if(!Ask(i, now))
		if(!Ask(i-1, now)) Work(i, now+1, nst, st, flag, ad) ;
		else ;
	else
	{
		if(Ask(i-1, now))
			if(Ask(i, now))
				Work(i, now+1, nst+(1<<now-1), st, flag|(map[i+1][now] == 2 || map[i-2][now] == 2), ad) ;
			else ;
		else
		{
			if(Ask(i, now) && Ask(i, now+1) && (!Ask(i-1, now+1)))
				Work(i, now+2, nst+(3<<now-1), st, flag|(map[i+1][now-1] == 2 || map[i][now+2] == 2), ad) ;
			Work(i, now+1, nst, st, flag, ad) ;
		}
	}
}

int main()
{
	int i, j, t ;
	scanf("%d", &N) ;
	for(i = 1; i <= 3; i ++)
	{
		scanf("%s", ss) ;
		for(j = 1; j <= N; j ++)
			map[i][j] = ((ss[j-1]=='.')?0:(ss[j-1]=='X'?1:2)) ;
		map[i][0] = map[i][N+1] = 1 ;
	}
	for(i = 1; i <= N; i ++)
		map[0][i] = map[4][i] = 1 ;
	dp[0][7][0] = 1 ;
	for(i = 1; i <= N+1; i ++)
		for(j = 0; j <= 7; j ++)
			for(t = 0; t <= 1; t ++)
				if(dp[i-1][j][t])
					Work(i, 1, 0, j, t, dp[i-1][j][t]) ;
	printf("%I64d\n", dp[N+1][0][1]) ;
	//system("pause") ;
	return 0 ;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 10005
#define mod 1000000007
#define Ask(xx, yy) ( map[yy][xx] == 0 && (xx==i || ((st>>yy-1)&1)==0) )
using namespace std ;
typedef long long LL ;

int N, M ;
int map[10][MAXN] ;
LL dp[MAXN][10][4] ;
char ss[MAXN] ;

void Work(int i, int now, int nst, int st, int flag, LL ad)
{
	if(now > 3)
	{
		dp[i][nst][flag] = (dp[i][nst][flag]+ad)%mod ;
		return ;
	}
	if(!Ask(i, now))
		if(!Ask(i-1, now)) Work(i, now+1, nst, st, flag, ad) ;
		else ;
	else
	{
		if(Ask(i-1, now))
			if(Ask(i, now))
				Work(i, now+1, nst+(1<<now-1), st, flag|(map[now][i+1] == 2 || map[now][i-2] == 2), ad) ;
			else ;
		else
		{
			if(Ask(i, now) && Ask(i, now+1) && (!Ask(i-1, now+1)))
				Work(i, now+2, nst+(3<<now-1), st, flag|(map[now-1][i] == 2 || map[now+2][i] == 2), ad) ;
			Work(i, now+1, nst, st, flag, ad) ;
		}
	}
}

int main()
{
	int i, j, t ;
	scanf("%d", &N) ;
	for(i = 1; i <= 3; i ++)
	{
		scanf("%s", ss) ;
		for(j = 1; j <= N; j ++)
			map[i][j] = ((ss[j-1]=='.')?0:(ss[j-1]=='X'?1:2)) ;
		map[i][0] = map[i][N+1] = 1 ;
	}
	for(i = 1; i <= N; i ++)
		map[0][i] = map[4][i] = 1 ;
	dp[0][7][0] = 1 ;
	for(i = 1; i <= N+1; i ++)
		for(j = 0; j <= 7; j ++)
			for(t = 0; t <= 1; t ++)
				if(dp[i-1][j][t])
					Work(i, 1, 0, j, t, dp[i-1][j][t]) ;
	printf("%I64d\n", dp[N+1][0][1]) ;
	//system("pause") ;
	return 0 ;
}


#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MOD 1000000007
using namespace std;
typedef long long ll;

int n,x,y;
char inp[3][11000];
ll dp[10005][8],G[8][10005],g[8][10005];

int _dp(){
	memset(dp,0,sizeof dp);
	dp[0][7]=1;
	for (int i=1;i<=n;++i){
		int now=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
		for (int j=0;j<(1<<3);++j){
			if (j&now) continue;
			dp[i][j|now]=dp[i-1][7-j];
			if (j==3 || j==6) dp[i][j|now]=(dp[i][j|now]+dp[i-1][7])%MOD;
			if (j==7){
				dp[i][j|now]=(dp[i][j|now]+dp[i-1][6])%MOD;
				dp[i][j|now]=(dp[i][j|now]+dp[i-1][3])%MOD;
			}
		}
	}
	return dp[n][7];
}

int solve(){
	vector <int> dir;
	const int dx[]={1,-1,0,0};
	const int dy[]={0,0,1,-1};
	for (int i=0;i<4;++i){
		bool flag=1;
		if (dx[i]*2+x>0 && dx[i]*2+x<=n && dy[i]*2+y>=0 && dy[i]*2+y<3)
			for (int j=1;j<=2;j++)
				if (g[x+dx[i]*j][y+dy[i]*j]) flag=0;
		else flag=0;
		if (flag) dir.push_back(i);
	}
	ll res=0;
	for (int i=1;i<(1<<dir.size());++i){
		memcpy(G,g,sizeof g);
		for (int j=0;j<dir.size();++j)
			if (1&(i>>j))
				for (int k=1;k<=2;++k)
					G[x+dx[dir[j]]*k][y+dy[dir[j]]*k]=1;
		if (__builtin_popcount(i)&1) res=(res+_dp())%MOD;
		else res=(res-_dp()+MOD)%MOD;
	}
	return res%MOD;
}

int main(){
	cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.') g[i+1][j]=0;
            else if (inp[j][i]=='X') g[i+1][j]=1;
            else if (inp[j][i]=='O') g[i+1][j]=1,x=i+1,y=j;
    	}
	cout<<solve()<<endl;
}


#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const long long MOD=1e9+7;
int g[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){
    vector <int> dir;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0 && x+dx[i]*2<=n && y+dy[i]*2>=0 && y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (g[x+dx[i]*j][y+dy[i]*j]) can=0;
        else can=0;
        if (can) dir.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<dir.size());++i){
        memcpy(G,g,sizeof g);
        for (int j=0;j<dir.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[dir[j]]*k][y+dy[dir[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')g[i+1][j]=0;
            else if (inp[j][i]=='X') g[i+1][j]=1;
            else if (inp[j][i]=='O') g[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;

#define N 10005
#define M 3
#define mod 1000000007
struct node{
	int x,y;
}start;
int n,m,i,j,k,ans,top,tx,ty,lis,turn;
int map[5][N],state[N],dx[5],dy[5],dir[5],list[10],next[(1<<M)+10],old[(1<<M)+10],f[N][(1<<M)+10];
char s[N];

void read(){
	scanf("%d",&n);
	for(i=1;i<=3;++i){
		scanf("%s",s+1);
		for(j=1;j<=n;++j)
		if(s[j]=='.'){
			map[i][j]=0;
		}else
		if(s[j]=='O'){
			map[i][j]=1;
			start.x=i; start.y=j;
		}else{
			map[i][j]=1;
		}
	}
	dx[1]=-2; dy[1]=0;
	dx[2]=2; dy[2]=0;
	dx[3]=0; dy[3]=2;
	dx[4]=0; dy[4]=-2;
	return ;
}

void dfs(int len,int now,int pre){
	if(len>4) return ;
	if(len>3){
		turn++; next[turn]=now; old[turn]=pre;
		return ;
	}
	dfs(len+1,(now<<1)|1,pre<<1);			//考虑如果竖过来放
	dfs(len+2,(now<<2)|3,(pre<<2)|3);		//考虑如果横过来放
	dfs(len+1,now<<1,(pre<<1)|1);			//如果不放
	return ;
}

int dp(){//f[i][j]表示前i行，第i行状态为j，1..i-1行都被填满的方案
	int i,j,k;
	for(i=1;i<=lis;++i){
		map[start.x+(dx[list[i]]/2)][start.y+(dy[list[i]]/2)]=1;
		map[start.x+dx[list[i]]][start.y+dy[list[i]]]=1;
	}
	for(i=1;i<=n;++i){
		state[i]=0;
	 	for(j=1;j<=3;++j)
		 if(map[j][i]){
		 	state[i]+=(1<<(j-1));
	 	}
	}
	memset(f,0,sizeof(f));
	f[0][(1<<3)-1]=1;	//第0行当做被填满来看
	for(i=1;i<=n;++i)
	 for(j=1;j<=turn;++j)
	 if(!(state[i]&next[j])){
	 	f[i][next[j]|state[i]]+=f[i-1][old[j]];
	 	f[i][next[j]|state[i]]%=mod;
	 }
	for(i=1;i<=lis;++i){
		map[start.x+(dx[list[i]]/2)][start.y+(dy[list[i]]/2)]=0;
		map[start.x+dx[list[i]]][start.y+dy[list[i]]]=0;
	}
	return f[n][(1<<3)-1];
}

void work(){
	for(i=1;i<=4;++i){
		tx=start.x+dx[i]; ty=start.y+dy[i];
		if((tx>=1) && (tx<=3) && (ty>=1) && (ty<=n))
		 if(!map[start.x+(dx[i]/2)][start.y+(dy[i]/2)] && !map[start.x+dx[i]][start.y+dy[i]]){
			top++;
			dir[top]=i;
		 }
	}
	if(top==3){
		for(i=1;i<=top;++i){
			lis=1; list[lis]=dir[i];
			ans=(ans+dp())%mod;
		}
		for(i=1;i<=top;++i)
		 for(j=i+1;j<=top;++j){
		 	lis=2; list[1]=dir[i]; list[2]=dir[j];
		 	ans=(ans-dp()+mod)%mod;
		 }
		lis=3; list[1]=dir[1]; list[2]=dir[2]; list[3]=dir[3];
		ans=(ans+dp())%mod;
	}else
	if(top==2){
		for(i=1;i<=top;++i){
			lis=1; list[lis]=dir[i];
			ans=(ans+dp())%mod;
		}
		for(i=1;i<=top;++i)
		 for(j=i+1;j<=top;++j){
		 	lis=2; list[1]=dir[i]; list[2]=dir[j];
		 	ans=(ans-dp()+mod)%mod;
		 }
	}else
	if(top==1){
		for(i=1;i<=top;++i){
			lis=1; list[lis]=dir[i];
			ans=(ans+dp())%mod;
		}
	}else{
		ans=0;
	}
	return ;
}

int main(){
	read();
	dfs(1,0,0);
	work();
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const long long MOD=1e9+7;
int G1[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){//有1表示没放
    vector<int> avail;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (G1[x+dx[i]*j][y+dy[i]*j]) can=0;
        else can=0;
        if (can) avail.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<avail.size());++i){
        memcpy(G,G1,sizeof G1);
        for (int j=0;j<avail.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[avail[j]]*k][y+dy[avail[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')G1[i+1][j]=0;
            else if (inp[j][i]=='X') G1[i+1][j]=1;
            else if (inp[j][i]=='O') G1[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const long long MOD=1e9+7;
int G1[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){
    vector <int> dir;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (G1[x+dx[i]*j][y+dy[i]*j]) can=0;
        else can=0;
        if (can) dir.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<dir.size());++i){
        memcpy(G,G1,sizeof G1);
        for (int j=0;j<dir.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[dir[j]]*k][y+dy[dir[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')G1[i+1][j]=0;
            else if (inp[j][i]=='X') G1[i+1][j]=1;
            else if (inp[j][i]=='O') G1[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const long long MOD=1e9+7;
int G1[10000+100][3];
int G[10000+100][3];
int x,y;
long long dp[11000][1<<3];
char inp[3][11000];
int n;

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){
    vector<int> avail;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3){
            for (int j=1;j<=2;++j)
                if (G1[x+dx[i]*j][y+dy[i]*j]) can=0;
        }
        else can=0;
        if (can) avail.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<avail.size());++i){
        memcpy(G,G1,sizeof G1);
        for (int j=0;j<avail.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[avail[j]]*k][y+dy[avail[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.') G1[i+1][j]=0;
            else if (inp[j][i]=='X') G1[i+1][j]=1;
            else if (inp[j][i]=='O'){
                G1[i+1][j]=1;x=i+1;y=j;
            }
        }
    cout<<solve()<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const long long MOD=1e9+7;
int G1[10000+100][3];
int G[10000+100][3];
int x,y;
long long dp[11000][1<<3];
char inp[3][11000];
int n;

long long cal_dp()
{
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for(int i=1;i<=n;++i)
    {
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for(int j=0;j<(1<<3);++j)
        {
            if(j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if(j==3||j==6)
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if(j==7)
            {
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve()
{
    vector<int> avail;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for(int i=0;i<4;++i)
    {
        bool can=1;
        if(x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3)
        {
            for(int j=1;j<=2;++j)
                if(G1[x+dx[i]*j][y+dy[i]*j])
                    can=0;
        }
        else
            can=0;
        if(can)
            avail.push_back(i);
    }
    long long res=0;
    for(int i=1;i<(1<<avail.size());++i)
    {
        memcpy(G,G1,sizeof G1);
        for(int j=0;j<avail.size();++j)
            if(1&(i>>j))
                for(int k=1;k<=2;++k)
                    G[x+dx[avail[j]]*k][y+dy[avail[j]]*k]=1;
        if(__builtin_popcount(i)&1)
            res=(res+cal_dp())%MOD;
        else
            res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main()
{
    cin>>n;
    for(int i=0;i<3;++i)
        scanf("%s",inp[i]);
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<3;++j)
        {
            if(inp[j][i]=='.')
                G1[i+1][j]=0;
            else if(inp[j][i]=='X')
                G1[i+1][j]=1;
            else if(inp[j][i]=='O')
            {
                G1[i+1][j]=1;
                x=i+1;
                y=j;
            }
        }
    }
    cout<<solve()<<endl;
    /*cout<<x<<" "<<y<<endl;
    for(int i=0;i<=n;++i)
    {
        cout<<i<<": ";
        for(int j=0;j<8;++j)
            cout<<dp[i][j]<<" ";
        cout<<endl;
    }*/
    return 0;
}


#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const long long MOD=1e9+7;
int g[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){
    vector <int> avail;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (g[x+dx[i]*j][y+dy[i]*j]) can=0;
        else can=0;
        if (can) avail.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<avail.size());++i){
        memcpy(G,g,sizeof g);
        for (int j=0;j<avail.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[avail[j]]*k][y+dy[avail[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')g[i+1][j]=0;
            else if (inp[j][i]=='X') g[i+1][j]=1;
            else if (inp[j][i]=='O') g[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const long long MOD=1e9+7;
int g[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){
    vector<int> dir;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool flag=1;
        if (x+dx[i]*2>0 && x+dx[i]*2<=n && y+dy[i]*2>=0 && y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (g[x+dx[i]*j][y+dy[i]*j]) flag=0;
        else flag=0;
        if (flag) dir.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<dir.size());++i){
        memcpy(G,g,sizeof g);
        for (int j=0;j<dir.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[dir[j]]*k][y+dy[dir[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')g[i+1][j]=0;
            else if (inp[j][i]=='X') g[i+1][j]=1;
            else if (inp[j][i]=='O') g[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MOD 1000000007
using namespace std;
typedef long long ll;

int n,x,y;
char inp[3][11000];
ll dp[10005][8],G[8][10005],g[8][10005];

int _dp(){
	memset(dp,0,sizeof dp);
	dp[0][7]=1;
	for (int i=1;i<=n;++i){
		int now=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
		for (int j=0;j<(1<<3);++j){
			if (j&now) continue;
			dp[i][j|now]=dp[i-1][7-j];
			if (j==3 || j==6) dp[i][j|now]=(dp[i][j|now]+dp[i-1][7])%MOD;
			if (j==7){
				dp[i][j|now]=(dp[i][j|now]+dp[i-1][6])%MOD;
				dp[i][j|now]=(dp[i][j|now]+dp[i-1][3])%MOD;
			}
		}
	}
	return dp[n][7];
}

int solve(){
	vector <int> dir;
	const int dx[]={1,-1,0,0};
	const int dy[]={0,0,1,-1};
	for (int i=0;i<4;++i){
		bool flag=1;
		if (dx[i]*2+x>0 && dx[i]*2+x<=n && dy[i]*2+y>=0 && dy[i]*2+y<3)
			for (int j=1;j<=2;j++)
				if (g[x+dx[i]*j][y+dy[i]*j]) flag=0;
		else flag=0;
		if (flag) dir.push_back(i);
	}
	ll res=0;
	for (int i=1;i<(1<<dir.size());++i){
		memcpy(G,g,sizeof g);
		for (int j=0;j<dir.size();++j)
			if (1&(i>>j))
				for (int k=1;k<=2;++k)
					G[x+dx[dir[j]]*k][y+dy[dir[j]]*k]=1;
		if (__builtin_popcount(i)&1) res=(res+_dp())%MOD;
		else res=(res-_dp()+MOD)%MOD;
	}
	return res%MOD;
}

int main(){
	cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.') g[i+1][j]=0;
            else if (inp[j][i]=='X') g[i+1][j]=1;
            else if (inp[j][i]=='O') g[i+1][j]=1,x=i+1,y=j;
        }
    system("pause");
	cout<<solve()<<endl;
}


#include <bits/stdc++.h>
using namespace std;

const long long MOD=1e9+7;
int G1[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){//有1表示
    vector<int> avail;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (G1[x+dx[i]*j][y+dy[i]*j]) can=0;
        else can=0;
        if (can) avail.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<avail.size());++i){
        memcpy(G,G1,sizeof G1);
        for (int j=0;j<avail.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[avail[j]]*k][y+dy[avail[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')G1[i+1][j]=0;
            else if (inp[j][i]=='X') G1[i+1][j]=1;
            else if (inp[j][i]=='O') G1[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const long long MOD=1e9+7;
int G1[10000+100][3],G[10000+100][3],x,y,n;
long long dp[11000][1<<3];
char inp[3][11000];

long long cal_dp(){
    memset(dp,0,sizeof dp);
    dp[0][7]=1;
    for (int i=1;i<=n;++i){
        int cur=G[i][0]+(G[i][1]<<1)+(G[i][2]<<2);
        for (int j=0;j<(1<<3);++j){
            if (j&cur) continue;
            dp[i][j|cur]=dp[i-1][7-j];
            if (j==3||j==6) dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][7])%MOD;
            if (j==7){
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][6])%MOD;
                dp[i][j|cur]=(dp[i][j|cur]+dp[i-1][3])%MOD;
            }
        }
    }
    return dp[n][7];
}

long long solve(){
    vector <int> dir;
    const int dx[]={1,-1,0,0};
    const int dy[]={0,0,1,-1};
    for (int i=0;i<4;++i){
        bool can=1;
        if (x+dx[i]*2>0&&x+dx[i]*2<=n&&y+dy[i]*2>=0&&y+dy[i]*2<3)
            for (int j=1;j<=2;++j)
                if (G1[x+dx[i]*j][y+dy[i]*j]) can=0;
        else can=0;
        if (can) dir.push_back(i);
    }
    long long res=0;
    for (int i=1;i<(1<<dir.size());++i){
        memcpy(G,G1,sizeof G1);
        for (int j=0;j<dir.size();++j)
            if (1&(i>>j))
                for (int k=1;k<=2;++k)
                    G[x+dx[dir[j]]*k][y+dy[dir[j]]*k]=1;
        if (__builtin_popcount(i)&1) res=(res+cal_dp())%MOD;
        else res=(res-cal_dp()+MOD)%MOD;
    }
    return res%MOD;
}

int main(){
    cin>>n;
    for (int i=0;i<3;++i) scanf("%s",inp[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<3;++j){
            if (inp[j][i]=='.')G1[i+1][j]=0;
            else if (inp[j][i]=='X') G1[i+1][j]=1;
            else if (inp[j][i]=='O') G1[i+1][j]=1,x=i+1,y=j;
        }
    cout<<solve()<<endl;
    return 0;
}


// srm 449 div1 500pt is recomended
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
#define rev(i,b) for(int i=b;i>=0;i--)
const int mod = 1000000007;
const int m = 3;
char buf[3][10010];
int n,f[2][1<<m][2];
void Add(int &x,int y) {
    x += y;
    if(x >= mod)x-=mod;
}
void solve() {
    int cur=0,nxt=1,lim=1<<m;
    int st=0;
    rep(i,3)if(buf[i][0]!='.')st|=1<<(2-i);
    f[0][st][0] = 1;
    rep(i,n) rev(j,m-1){
        memset(f[nxt],0,sizeof(f[nxt]));
        rep(mask,lim){
            rep(G,2)if(f[cur][mask][G]){
                int add = f[cur][mask][G],g;
                int to = mask;
                if(buf[j][i+1]!='.') to |= 1<<m;
                if(mask&1) { Add(f[nxt][to>>1][G],add);continue;}
                g = G;
                if(j-1 >= 0 && !(mask&2)) {
                    if(j+1 < m)  g |= (buf[j+1][i] == 'O');
                    if(j-2 >= 0) g |= (buf[j-2][i] == 'O');
                    Add(f[nxt][(to|2)>>1][g],add);
                }
                g = G;
                if(i-1 >= 0) g |= (buf[j][i-1] == 'O');
                if(i+2 < n)  g |= (buf[j][i+2] == 'O');
                if(buf[j][i+1]=='.')
                    Add(f[nxt][(mask|1<<m)>>1][g],add);
            }
        }
        std::swap(cur,nxt);
    }
    printf("%d\n",f[cur][lim-1][1]);
}
int main() {
    scanf("%d",&n);
    for(int i = 0; i < 3; i++) scanf("%s",buf[i]);
    solve();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
const int mod = 1000000007;
const int m = 3;
char buf[3][10000];
int n,dp[2][1<<m][2];
void Add(int &x,int y) {
    x += y;
    if(x >= mod) x -= mod;
}
void solve() {
    int cur = 0, nxt = 1, lim = 1<<3;
    int start = 0;
    for(int i = 0; i < 3; i++) if(buf[i][0]!='.') start |= 1<<(2-i);
    dp[0][start][0] = 1;
    for(int i = 0; i < n; i++) {
        for(int j = m-1; j >= 0; j--) {
            memset(dp[nxt],0,sizeof(dp[nxt]));
            for(int mask = 0; mask < lim; mask++){
               for(int GG = 0; GG < 2; GG++) if(dp[cur][mask][GG]){
                    int add = dp[cur][mask][GG],gg;
                    int to = mask;
                    if(buf[j][i+1]!='.') to |= 1<<m;
                    if(mask&1) {
                        Add(dp[nxt][to>>1][GG],add);
                        continue;
                    } else {
                        gg = GG;
                        if(j-1 >= 0 && !(mask&2)) {
                            if(j+1 < m)  gg |= (buf[j+1][i] == 'O');
                            if(j-2 >= 0) gg |= (buf[j-2][i] == 'O');
                            Add(dp[nxt][(to|2)>>1][gg],add);
                        }
                        gg = GG;
                        if(i-1 >= 0) gg |= (buf[j][i-1] == 'O');
                        if(i+2 < n)  gg |= (buf[j][i+2] == 'O');
                        if(buf[j][i+1]=='.'){
                            Add(dp[nxt][(mask|1<<m)>>1][gg],add);
                        }
                    }
               }
            }
            std::swap(cur,nxt);
        }
    }
    printf("%d\n",dp[cur][7][1]);
}
int main() {
    memset(buf,0,sizeof(buf));
    scanf("%d",&n);
    for(int i = 0; i < 3; i++) scanf("%s",buf[i]);
    solve();
    return 0;
}


// srm 449 div1 500pt is recomended
#include <cstdio>
#include <cstring>
#include <algorithm>
const int mod = 1000000007;
const int m = 3;
char buf[3][10010];
int n,f[2][1<<m][2];
void Add(int &x,int y) {
    x += y;
    if(x >= mod) x -= mod;
}
void solve() {
    int cur = 0, nxt = 1, lim = 1<<m;
    int st = 0;
    for(int i = 0; i < 3; i++) if(buf[i][0]!='.') st |= 1<<(2-i);
    f[0][st][0] = 1;
    for(int i = 0; i < n; i++) {
        for(int j = m-1; j >= 0; j--) {
            memset(f[nxt],0,sizeof(f[nxt]));
            for(int mask = 0; mask < lim; mask++){
                for(int G = 0; G < 2; G++) if(f[cur][mask][G]){
                    int add = f[cur][mask][G],g;
                    int to = mask;
                    if(buf[j][i+1]!='.') to |= 1<<m;
                    if(mask&1) { Add(f[nxt][to>>1][G],add);continue;}
                    g = G;
                    if(j-1 >= 0 && !(mask&2)) {
                        if(j+1 < m)  g |= (buf[j+1][i] == 'O');
                        if(j-2 >= 0) g |= (buf[j-2][i] == 'O');
                        Add(f[nxt][(to|2)>>1][g],add);
                    }
                    g = G;
                    if(i-1 >= 0) g |= (buf[j][i-1] == 'O');
                    if(i+2 < n)  g |= (buf[j][i+2] == 'O');
                    if(buf[j][i+1]=='.')
                        Add(f[nxt][(mask|1<<m)>>1][g],add);
                }
            }
            std::swap(cur,nxt);
        }
    }
    printf("%d\n",f[cur][lim-1][1]);
}
int main() {
    scanf("%d",&n);
    for(int i = 0; i < 3; i++) scanf("%s",buf[i]);
    solve();
    return 0;
}


//#pragma comment(linker, "/STACK:16777216")
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <numeric>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <iterator>
#include <memory>
#include <utility>
#include <string>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define mset(a) memset(a,0,sizeof(a))
#define mmset(a) memset(a,-1,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

typedef double lf;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<lf,lf> pdd;
typedef pair<int,pii> pip;
typedef pair<pii,int> ppi;
typedef vector<int> vi;
typedef vector<pii> vpii;

const int inf=1000000007;
const ll linf=1LL<<62;
const ull ulinf=1ULL<<63;
const lf eps=0.000001;
const lf pi=3.14159265358979323846;

template <class T> T abs(T a){return a>=0?a:-a;}
template <class T> T sqr(T a){return a*a;}
template <class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template <class T> T mod(T a,T b){return (a%b+b)%b;}
ll powmod(ll a,ll b,ll c){if(b==0)return 1;ll ret=powmod(a,b>>1,c);ret=ret*ret%c;if(b&1)ret=ret*a%c;return ret;}
template <class T> void maxe(T &a,T b){if(a<b)a=b;}
template <class T> void mine(T &a,T b){if(a>b)a=b;}
int iszero(lf a){return abs(a)<=eps;}

template <class T> void geti(T &a){a=0;T b=1;char c=getchar();if(c=='-')b=-1;else a=c-48;while((c=getchar())!=' '&&c!='\n')a=a*10+c-48;a*=b;}

void fileio_in_out(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
void fileio_txt(){freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);}

//==================================================

#define DEBUG(X)

const int N=111111;
const int M=111111;

int test;
int n,m,k;
ll ans;
ll dp[N][8];
char s[3][N];
int x,y;
const ll md=(ll)inf;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

int f(int st)
{
    int ret=0;
    for(int i=0;i<4;i++)
        if(st&(1<<i))
            ret++;
    return ret&1;
}

ll calc(int st)
{
    for(int i=0;i<4;i++)
        if(st&(1<<i))
            s[x+dx[i]][y+dy[i]]=s[x+2*dx[i]][y+2*dy[i]]='X';
    dp[0][7]=1;
    for(int i=1;i<=n;i++)
    {
        int t=(s[0][i]!='.')+(s[1][i]!='.')*2+(s[2][i]!='.')*4;
        //printf("%d\n",t);
        for(int j=0;j<8;j++)
        {
            if((j&t)!=t)
            {
                dp[i][j]=0;
                continue;
            }
            if(j==0)
                dp[i][j]=dp[i-1][7];
            if(j==1)
                dp[i][j]=(t&1)?dp[i-1][7]:dp[i-1][6];
            if(j==2)
                dp[i][j]=(t&2)?dp[i-1][7]:dp[i-1][5];
            if(j==3)
            {
                if(t==0)
                    dp[i][j]=(dp[i][0]+dp[i-1][4])%md;
                if(t==1)
                    dp[i][j]=dp[i-1][5];
                if(t==2)
                    dp[i][j]=dp[i-1][6];
                if(t==3)
                    dp[i][j]=dp[i-1][7];
            }
            if(j==4)
                dp[i][j]=(t&4)?dp[i-1][7]:dp[i-1][3];
            if(j==5)
            {
                if(t==0)
                    dp[i][j]=dp[i-1][2];
                if(t==1)
                    dp[i][j]=dp[i-1][3];
                if(t==4)
                    dp[i][j]=dp[i-1][6];
                if(t==5)
                    dp[i][j]=dp[i-1][7];
            }
            if(j==6)
            {
                if(t==0)
                    dp[i][j]=(dp[i][0]+dp[i-1][1])%md;
                if(t==2)
                    dp[i][j]=dp[i-1][3];
                if(t==4)
                    dp[i][j]=dp[i-1][5];
                if(t==6)
                    dp[i][j]=dp[i-1][7];
            }
            if(j==7)
            {
                if(t==0)
                    dp[i][j]=(dp[i-1][0]+dp[i][1]+dp[i][4])%md;
                if(t==1)
                    dp[i][j]=(dp[i][1]+dp[i-1][1])%md;
                if(t==2)
                    dp[i][j]=(dp[i][2]+dp[i-1][2])%md;
                if(t==3)
                    dp[i][j]=dp[i-1][3];
                if(t==4)
                    dp[i][j]=(dp[i][4]+dp[i-1][4])%md;
                if(t==5)
                    dp[i][j]=dp[i-1][5];
                if(t==6)
                    dp[i][j]=dp[i-1][6];
                if(t==7)
                    dp[i][j]=dp[i-1][7];
            }
        }
    }
    /*
    for(int i=0;i<3;i++)
        printf("%s\n",s[i]+1);
    for(int i=1;i<=n;i++){
        for(int j=0;j<8;j++)
            printf("%I64d ",dp[i][j]);puts("");}
    */
    for(int i=0;i<4;i++)
        if(st&(1<<i))
            s[x+dx[i]][y+dy[i]]=s[x+2*dx[i]][y+2*dy[i]]='.';

    return dp[n][7];
}

int main()
{
    //fileio_in_out();
    //fileio_txt();
    //ios::sync_with_stdio(false);

    scanf("%d",&n);
    for(int i=0;i<3;i++)
    {
        scanf("%s",s[i]+1);
        for(int j=1;j<=n;j++)
            if(s[i][j]=='O')
            {
                x=i;
                y=j;
            }
    }

    if(x<=2&&s[x+1][y]=='.'&&s[x+2][y]=='.')
        k+=1;
    if(y<=n-2&&s[x][y+1]=='.'&&s[x][y+2]=='.')
        k+=2;
    if(x>=2&&s[x-1][y]=='.'&&s[x-2][y]=='.')
        k+=4;
    if(y>=1+2&&s[x][y-1]=='.'&&s[x][y-2]=='.')
        k+=8;
    //printf("%d %d\n",x,y);
    for(int i=1;i<16;i++)
        if((k&i)==i)
        {
            ll t=calc(i);
            if(f(i))
                ans=mod(ans+t,md);
            else
                ans=mod(ans-t,md);
        }

    printf("%I64d\n",ans);

    //system("pause");
    return 0;
}


//#pragma comment(linker, "/STACK:16777216")
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <numeric>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <iterator>
#include <memory>
#include <utility>
#include <string>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define mset(a) memset(a,0,sizeof(a))
#define mmset(a) memset(a,-1,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

typedef double lf;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<lf,lf> pdd;
typedef pair<int,pii> pip;
typedef pair<pii,int> ppi;
typedef vector<int> vi;
typedef vector<pii> vpii;

const int inf=1000000007;
const ll linf=1LL<<62;
const ull ulinf=1ULL<<63;
const lf eps=0.000001;
const lf pi=3.14159265358979323846;

template <class T> T abs(T a){return a>=0?a:-a;}
template <class T> T sqr(T a){return a*a;}
template <class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template <class T> T mod(T a,T b){return (a%b+b)%b;}
ll powmod(ll a,ll b,ll c){if(b==0)return 1;ll ret=powmod(a,b>>1,c);ret=ret*ret%c;if(b&1)ret=ret*a%c;return ret;}
template <class T> void maxe(T &a,T b){if(a<b)a=b;}
template <class T> void mine(T &a,T b){if(a>b)a=b;}
int iszero(lf a){return abs(a)<=eps;}

template <class T> void geti(T &a){a=0;T b=1;char c=getchar();if(c=='-')b=-1;else a=c-48;while((c=getchar())!=' '&&c!='\n')a=a*10+c-48;a*=b;}

void fileio_in_out(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
void fileio_txt(){freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);}

//==================================================

#define DEBUG(X)

const int N=111111;
const int M=111111;

int test;
int n,m,k;
ll ans;
ll dp[N][8];
char s[3][N];
int x,y;
const ll md=(ll)inf;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

int f(int st)
{
    int ret=0;
    for(int i=0;i<4;i++)
        if(st&(1<<i))
            ret++;
    return ret&1;
}

ll calc(int st)
{
    for(int i=0;i<4;i++)
        if(st&(1<<i))
            s[x+dx[i]][y+dy[i]]=s[x+2*dx[i]][y+2*dy[i]]='X';
    dp[0][7]=1;
    for(int i=1;i<=n;i++)
    {
        int t=(s[0][i]!='.')+(s[1][i]!='.')*2+(s[2][i]!='.')*4;
        //printf("%d\n",t);
        for(int j=0;j<8;j++)
        {
            if((j&t)!=t)
            {
                dp[i][j]=0;
                continue;
            }
            if(j==0)
                dp[i][j]=dp[i-1][7];
            if(j==1)
                dp[i][j]=(t==1)?dp[i-1][7]:dp[i-1][6];
            if(j==2)
                dp[i][j]=(t==2)?dp[i-1][7]:dp[i-1][5];
            if(j==3)
            {
                if(t==0)
                    dp[i][j]=(dp[i-1][7]+dp[i-1][4])%md;
                if(t==1)
                    dp[i][j]=dp[i-1][5];
                if(t==2)
                    dp[i][j]=dp[i-1][6];
                if(t==3)
                    dp[i][j]=dp[i-1][7];
            }
            if(j==4)
                dp[i][j]=(t==4)?dp[i-1][7]:dp[i-1][3];
            if(j==5)
            {
                if(t==0)
                    dp[i][j]=dp[i-1][2];
                if(t==1)
                    dp[i][j]=dp[i-1][3];
                if(t==4)
                    dp[i][j]=dp[i-1][6];
                if(t==5)
                    dp[i][j]=dp[i-1][7];
            }
            if(j==6)
            {
                if(t==0)
                    dp[i][j]=(dp[i-1][7]+dp[i-1][1])%md;
                if(t==2)
                    dp[i][j]=dp[i-1][3];
                if(t==4)
                    dp[i][j]=dp[i-1][5];
                if(t==6)
                    dp[i][j]=dp[i-1][7];
            }
            if(j==7)
            {
                if(t==0)
                    dp[i][j]=(dp[i-1][0]+dp[i-1][3]+dp[i-1][6])%md;
                if(t==1)
                    dp[i][j]=(dp[i-1][7]+dp[i-1][1])%md;
                if(t==2)
                    dp[i][j]=dp[i-1][2];
                if(t==3)
                    dp[i][j]=dp[i-1][3];
                if(t==4)
                    dp[i][j]=(dp[i-1][7]+dp[i-1][4])%md;
                if(t==5)
                    dp[i][j]=dp[i-1][5];
                if(t==6)
                    dp[i][j]=dp[i-1][6];
                if(t==7)
                    dp[i][j]=dp[i-1][7];
            }
        }
    }
    /*
    for(int i=0;i<3;i++)
        printf("%s\n",s[i]+1);
    for(int i=1;i<=n;i++){
        for(int j=0;j<8;j++)
            printf("%I64d ",dp[i][j]);puts("");}
    */
    for(int i=0;i<4;i++)
        if(st&(1<<i))
            s[x+dx[i]][y+dy[i]]=s[x+2*dx[i]][y+2*dy[i]]='.';

    return dp[n][7];
}

int main()
{
    //fileio_in_out();
    //fileio_txt();
    //ios::sync_with_stdio(false);

    scanf("%d",&n);
    for(int i=0;i<3;i++)
    {
        scanf("%s",s[i]+1);
        for(int j=1;j<=n;j++)
            if(s[i][j]=='O')
            {
                x=i;
                y=j;
            }
    }

    if(x<=2&&s[x+1][y]=='.'&&s[x+2][y]=='.')
        k+=1;
    if(y<=n-2&&s[x][y+1]=='.'&&s[x][y+2]=='.')
        k+=2;
    if(x>=2&&s[x-1][y]=='.'&&s[x-2][y]=='.')
        k+=4;
    if(y>=1+2&&s[x][y-1]=='.'&&s[x][y-2]=='.')
        k+=8;
    //printf("%d %d\n",x,y);
    for(int i=1;i<16;i++)
        if((k&i)==i)
        {
            ll t=calc(i);
            if(f(i))
                ans=mod(ans+t,md);
            else
                ans=mod(ans-t,md);
        }

    printf("%I64d\n",ans);

    //system("pause");
    return 0;
}