// eddy1021
#include <bits/stdc++.h>
using namespace std;
typedef double D;
#define N 102100
D stl[ N << 2 ] , str[ N << 2 ];
int n , q , a[ N ] , b[ N ];
#define L(X) (X<<1)
#define R(X) (1+(X<<1))
#define mid ((l+r)>>1)
inline D Lft( D ll , D lr , D rl , D rr ){
  return ( ll * rl ) / ( 1.0 + lr * ( rl - 1.0 ) );
}
inline D Rgt( D ll , D lr , D rl , D rr ){
  return rr + ( lr * rl * ( 1.0 - rr ) ) / ( 1.0 - lr * ( 1.0 - rl ) );
}
void build_st( int no , int l , int r ){
  if( l == r ){
    stl[ no ] = str[ no ] = (D)a[ l ] / b[ l ];
    return;
  }
  build_st( L( no ) , l , mid );
  build_st( R( no ) , mid + 1 , r );
  stl[ no ] = Lft( stl[ L( no ) ] , str[ L( no ) ] ,
                   stl[ R( no ) ] , str[ R( no ) ] );
  str[ no ] = Rgt( stl[ L( no ) ] , str[ L( no ) ] ,
                   stl[ R( no ) ] , str[ R( no ) ] );
}
void modify( int no , int l , int r , int p , int qa , int qb ){
  if( l == r ){
    stl[ no ] = str[ no ] = (D)qa / qb;
    return;
  }
  if( p <= mid ) modify( L( no ) , l , mid , p , qa , qb );
  else modify( R( no ) , mid + 1 , r , p , qa , qb );
  stl[ no ] = Lft( stl[ L( no ) ] , str[ L( no ) ] ,
                   stl[ R( no ) ] , str[ R( no ) ] );
  str[ no ] = Rgt( stl[ L( no ) ] , str[ L( no ) ] ,
                   stl[ R( no ) ] , str[ R( no ) ] );
}
pair<D,D> query( int no , int l , int r , int ql , int qr ){
  if( l == ql && r == qr ) return { stl[ no ] , str[ no ] };
  if( qr <= mid ) return query( L( no ) , l , mid , ql , qr );
  if( mid < ql ) return query( R( no ) , mid + 1 , r , ql , qr );
  pair<D,D> lft = query( L( no ) , l , mid , ql , mid );
  pair<D,D> rgt = query( R( no ) , mid + 1 , r , mid + 1 , qr );
  D lv = Lft( lft.first , lft.second ,
              rgt.first , rgt.second );
  D rv = Rgt( lft.first , lft.second ,
              rgt.first , rgt.second );
  return { lv , rv };
}
void init(){
  scanf( "%d%d" , &n , &q );
  for( int i = 1 ; i <= n ; i ++ )
    scanf( "%d%d" , &a[ i ] , &b[ i ] );
  build_st( 1 , 1 , n );
}
void solve(){
  while( q -- ){
    int cmd , qa , qb , qi;
    scanf( "%d" , &cmd );
    if( cmd == 1 ){
      scanf( "%d%d%d" , &qi , &qa , &qb );
      modify( 1 , 1 , n , qi , qa , qb );
    }else{
      scanf( "%d%d" , &qa , &qb );
      pair<D,D> tp = query( 1 , 1 , n , qa , qb );
      printf( "%.9f\n" , tp.first );
    }
  }
}
int main(){
  init();
  solve();
}


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

#define LL long long
#define DB double
#define Pr pair<DB,DB>
#define X first
#define Y second
#define MAXN 100000
#define INF 1000000000
#define MOD 998244353
#define mem(x,v) memset(x,v,sizeof(x));

LL read(){
	LL x=0,F=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')F=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*F;
}

int n,q;
Pr merge(Pr p1,Pr p2){
	Pr tmp;
	tmp.X=p1.X*p2.X/(1-(1-p1.Y)*(1-p2.X));
	tmp.Y=p1.Y*p2.Y/(1-(1-p1.Y)*(1-p2.X));
	return tmp;
}

//Seg_tree
	#define mid (l+r>>1)
	#define pl (x<<1)
	#define pr (x<<1|1)
	Pr p[(MAXN<<2)+5];
	void Build(int x,int l,int r){
		if(l==r){
			int a=read(),b=read();
			p[x].X=1.0*a/b,p[x].Y=1-p[x].X;return ;
		}
		Build(pl,l,mid),Build(pr,mid+1,r);
		p[x]=merge(p[pl],p[pr]);
	}
	void Insert(int x,int l,int r,int pos,DB np){
		if(l==r){p[x].X=np,p[x].Y=1-np;return ;}
		if(pos<=mid)Insert(pl,l,mid,pos,np);
		else Insert(pr,mid+1,r,pos,np);
		p[x]=merge(p[pl],p[pr]);
	}
	Pr Query(int x,int l,int r,int L,int R){
		if(L<=l&&r<=R)return p[x];
		if(R<=mid)return Query(pl,l,mid,L,R);
		else if(L>mid)return Query(pr,mid+1,r,L,R);
		else return merge(Query(pl,l,mid,L,R),Query(pr,mid+1,r,L,R));
	}

int main(){
	n=read(),q=read();
	Build(1,1,n);
	while(q--){
		int op=read();
		if(op==1){
			int x=read(),a=read(),b=read();
			Insert(1,1,n,x,1.0*a/b);
		}else{
			int l=read(),r=read();
			printf("%.10f\n",Query(1,1,n,l,r).X);
		}
	}
}


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

#define LL long long
#define DB double
#define Pr pair<DB,DB>
#define X first
#define Y second
#define MAXN 100000
#define INF 1000000000
#define MOD 998244353
#define mem(x,v) memset(x,v,sizeof(x));

LL read(){
	LL x=0,F=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')F=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*F;
}

int n,q;
Pr merge(Pr p1,Pr p2){
	Pr tmp;
	tmp.X=p1.X*p2.X/(1-(1-p1.Y)*(1-p2.X));
	tmp.Y=p1.Y*p2.Y/(1-(1-p1.Y)*(1-p2.X));
	return tmp;
}

struct Seg_tree{
	#define mid (l+r>>1)
	#define pl (x<<1)
	#define pr (x<<1|1)
	Pr p[(MAXN<<2)+5];
	void Build(int x,int l,int r){
		if(l==r){
			int a=read(),b=read();
			p[x].X=1.0*a/b,p[x].Y=1-p[x].X;return ;
		}
		Build(pl,l,mid),Build(pr,mid+1,r);
		p[x]=merge(p[pl],p[pr]);
	}
	void Insert(int x,int l,int r,int pos,DB np){
		if(l==r){p[x].X=np,p[x].Y=1-np;return ;}
		if(pos<=mid)Insert(pl,l,mid,pos,np);
		else Insert(pr,mid+1,r,pos,np);
		p[x]=merge(p[pl],p[pr]);
	}
	Pr Query(int x,int l,int r,int L,int R){
		if(L<=l&&r<=R)return p[x];
		if(R<=mid)return Query(pl,l,mid,L,R);
		else if(L>mid)return Query(pr,mid+1,r,L,R);
		else return merge(Query(pl,l,mid,L,R),Query(pr,mid+1,r,L,R));
	}
}T;

int main(){
	n=read(),q=read();
	T.Build(1,1,n);
	while(q--){
		int op=read();
		if(op==1){
			int x=read(),a=read(),b=read();
			T.Insert(1,1,n,x,1.0*a/b);
		}else{
			int l=read(),r=read();
			printf("%.10f\n",T.Query(1,1,n,l,r).X);
		}
	}
}


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

#define LL long long
#define DB double
#define Pr pair<DB,DB>
#define X first
#define Y second
#define MAXN 100000
#define INF 1000000000
#define MOD 998244353
#define mem(x,v) memset(x,v,sizeof(x));

LL read(){
	LL x=0,F=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')F=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*F;
}

int n,q;
Pr merge(Pr p1,Pr p2){
	Pr tmp;
	tmp.X=p1.X*p2.X/(1-(1-p1.Y)*(1-p2.X));
	tmp.Y=p1.Y*p2.Y/(1-(1-p1.Y)*(1-p2.X));
	return tmp;
}

struct Seg_tree{
	#define mid (l+r>>1)
	#define pl (x<<1)
	#define pr (x<<1|1)
	Pr p[(MAXN<<2)+5];
	void Build(int x,int l,int r){
		if(l==r){
			int a=read(),b=read();
			p[x].X=1.0*a/b,p[x].Y=1-p[x].X;return ;
		}
		Build(pl,l,mid),Build(pr,mid+1,r);
		p[x]=merge(p[pl],p[pr]);
	}
	void Insert(int x,int l,int r,int pos,DB np){
		if(l==r){p[x].X=np,p[x].Y=1-np;return ;}
		if(pos<=mid)Insert(pl,l,mid,pos,np);
		else Insert(pr,mid+1,r,pos,np);
		p[x]=merge(p[pl],p[pr]);
	}
	Pr Query(int x,int l,int r,int L,int R){
		if(L<=l&&r<=R)return p[x];
		if(R<=mid)return Query(pl,l,mid,L,R);
		else if(L>mid)return Query(pr,mid+1,r,L,R);
		else return merge(Query(pl,l,mid,L,R),Query(pr,mid+1,r,L,R));
	}
}T;

int main(){//
	n=read(),q=read();
	T.Build(1,1,n);
	while(q--){
		int op=read();
		if(op==1){
			int x=read(),a=read(),b=read();
			T.Insert(1,1,n,x,1.0*a/b);
		}else{
			int l=read(),r=read();
			printf("%.10f\n",T.Query(1,1,n,l,r).X);
		}
	}
}


/* ***********************************************
Author        :yuanzhaolin
Created Time  :2016年09月23日 星期五 13时59分04秒
File Name     :e.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <queue>
#include <utility>
using namespace std;
#define repp(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=0;i<a;i++)
#define REP(i,a) for(int i=1;i<=a;i++)
#define per(i,a,b) for(int i=a-1;i>=b;i--)
#define foreach(i,a) for(int i=head[a];i>=0;i=ee[i].next)
#define Foreach(i,a) for(__typeof((a).begin())i=(a).begin();i!=(a).end();i++)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mp make_pair
#define m0(x) memset(x,0,sizeof(x))
#define mff(x) memset(x,0xff,sizeof(x))
#define fi first
#define se second
#define lson k<<1,l,(l+r)/2
#define rson k<<1|1,(l+r)/2+1,r
#define chl (k<<1)
#define chr (k<<1|1)
#define SZ(x) ((int)(x).size())
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define sqr(x) ((x)*(x))
#define C1(x) cout<<x<<endl
#define C2(x,y) cout<<x<<" "<<y<<endl
#define C3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
typedef long long ll;
typedef vector<int> VI;
typedef pair<double,double> PII;
typedef vector< pair<int,int> > VPII;
const ll mod=1e9+7;
const ll maxn=1e5+7;
const ll maxe=1e6+7;
const ll INF=1e9+7;
const double PI=acos(-1);
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
inline void Max(int &a,int b){
   if(b>a)a=b;
}
inline void Min(int &a,int b){
  if(a==-1||b<a)a=b;
}
int n;
double p[maxn];
double mov[maxn];
PII seg[maxn*4];
PII merge(PII p,PII q)
{
	PII res;
	res.fi=(p.fi*q.fi)/(1+p.se*q.fi-p.se);
	res.se=(q.se-p.se*q.se+q.fi*p.se)/(1+p.se*q.fi-p.se);
	return res;
}
void push_up(int k)
{
	seg[k]=merge(seg[chl],seg[chr]);
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		seg[k]=mp(p[l],p[l]);
		return ;
	}
	build(lson);
	build(rson);
	push_up(k);
}
void update(int k,int l,int r,int pos)
{
	if(pos>r||pos<l) return ;
	if(l==r)
	{
		seg[k]=mp(p[pos],p[pos]);
		return ;
	}
	update(lson,pos);
	update(rson,pos);
	push_up(k);
}
PII query(int k,int l,int r,int a,int b)
{
	if(l>=a&&r<=b) return seg[k];
	//cout<<l<<" "<<r<<endl;
	int m=(l+r)/2;
	if(m>=b) return query(lson,a,b);
	else if(m<a) return query(rson,a,b);
	else
	{
		PII t1=query(lson,a,b);
		PII t2=query(rson,a,b);
	//	cout<<t1.fi<<" "<<t2.fi<<" "<<t1.se<<" "<<t2.se<<endl;
		return merge(t1,t2);
	}
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int q;
    cin>>n>>q;
	int u,v;
    for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&u,&v);
		p[i]=1.0*u/v;
	}
   	build(1,1,n);
   	/*
   	for(int i=1;i<=5;i++)
	{
		PII t=seg[i];
		cout<<t.fi<<" "<<t.se<<endl;
	}
	*/
	//query(1,1,n,2,3);
	while(q--)
	{
		int ty;
		scanf("%d",&ty);
		if(ty==1)
		{
			int i;
			scanf("%d%d%d",&i,&u,&v);
			p[i]=1.0*u/v;
			update(1,1,n,i);
		}
		else if(ty==2)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			PII t=query(1,1,n,l,r);
			printf("%.7f\n",t.fi);
		}
	}
    return 0;
}


/* ***********************************************
Author        :yuanzhaolin
Created Time  :2016年09月23日 星期五 13时59分04秒
File Name     :e.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <queue>
#include <utility>
using namespace std;
#define repp(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=0;i<a;i++)
#define REP(i,a) for(int i=1;i<=a;i++)
#define per(i,a,b) for(int i=a-1;i>=b;i--)
#define foreach(i,a) for(int i=head[a];i>=0;i=ee[i].next)
#define Foreach(i,a) for(__typeof((a).begin())i=(a).begin();i!=(a).end();i++)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mp make_pair
#define m0(x) memset(x,0,sizeof(x))
#define mff(x) memset(x,0xff,sizeof(x))
#define fi first
#define se second
#define lson k<<1,l,(l+r)/2
#define rson k<<1|1,(l+r)/2+1,r
#define chl (k<<1)
#define chr (k<<1|1)
#define SZ(x) ((int)(x).size())
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define sqr(x) ((x)*(x))
#define C1(x) cout<<x<<endl
#define C2(x,y) cout<<x<<" "<<y<<endl
#define C3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
typedef long long ll;
typedef vector<int> VI;
typedef pair<double,double> PII;
typedef vector< pair<int,int> > VPII;
const ll mod=1e9+7;
const ll maxn=1e5+7;
const ll maxe=1e6+7;
const ll INF=1e9+7;
const double PI=acos(-1);
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
inline void Max(int &a,int b){
   if(b>a)a=b;
}
inline void Min(int &a,int b){
  if(a==-1||b<a)a=b;
}
int n;
double p[maxn];
double mov[maxn];
PII seg[maxn*4];
PII merge(PII p,PII q)
{
	PII res;
	res.fi=(p.fi*q.fi)/(1+p.se*q.fi-p.se);
	res.se=(q.se-p.se*q.se+q.fi*p.se)/(1+p.se*q.fi-p.se);
	return res;
}
void push_up(int k)
{
	seg[k]=merge(seg[chl],seg[chr]);
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		seg[k]=mp(p[l],p[l]);
		return ;
	}
	build(lson);
	build(rson);
	push_up(k);
}
void update(int k,int l,int r,int pos)
{
	if(pos>r||pos<l) return ;
	if(l==r)
	{
		seg[k]=mp(p[pos],p[pos]);
		return ;
	}
	update(lson,pos);
	update(rson,pos);
	push_up(k);
}
PII query(int k,int l,int r,int a,int b)
{
	if(l>=a&&r<=b) return seg[k];
	//cout<<l<<" "<<r<<endl;
	int m=(l+r)/2;
	if(m>=b) return query(lson,a,b);
	else if(m<a) return query(rson,a,b);
	else
	{
		PII t1=query(lson,a,b);
		PII t2=query(rson,a,b);
	//	cout<<t1.fi<<" "<<t2.fi<<" "<<t1.se<<" "<<t2.se<<endl;
		return merge(query(lson,a,b),query(rson,a,b));
	}
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int q;
    cin>>n>>q;
	int u,v;
    for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&u,&v);
		p[i]=1.0*u/v;
	}
   	build(1,1,n);
   	/*
   	for(int i=1;i<=5;i++)
	{
		PII t=seg[i];
		cout<<t.fi<<" "<<t.se<<endl;
	}
	*/
	//query(1,1,n,2,3);
	while(q--)
	{
		int ty;
		scanf("%d",&ty);
		if(ty==1)
		{
			int i;
			scanf("%d%d%d",&i,&u,&v);
			p[i]=1.0*u/v;
			update(1,1,n,i);
		}
		else if(ty==2)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			PII t=query(1,1,n,l,r);
			printf("%.7f\n",t.fi);
		}
	}
    return 0;
}


/* ***********************************************
Author        :yuanzhaolin
Created Time  :2016年09月23日 星期五 13时59分04秒
File Name     :e.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <queue>
#include <utility>
using namespace std;
#define repp(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=0;i<a;i++)
#define REP(i,a) for(int i=1;i<=a;i++)
#define per(i,a,b) for(int i=a-1;i>=b;i--)
#define foreach(i,a) for(int i=head[a];i>=0;i=ee[i].next)
#define Foreach(i,a) for(__typeof((a).begin())i=(a).begin();i!=(a).end();i++)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mp make_pair
#define m0(x) memset(x,0,sizeof(x))
#define mff(x) memset(x,0xff,sizeof(x))
#define fi first
#define se second
#define lson k<<1,l,(l+r)/2
#define rson k<<1|1,(l+r)/2+1,r
#define chl (k<<1)
#define chr (k<<1|1)
#define SZ(x) ((int)(x).size())
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define sqr(x) ((x)*(x))
#define C1(x) cout<<x<<endl
#define C2(x,y) cout<<x<<" "<<y<<endl
#define C3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
typedef long long ll;
typedef vector<int> VI;
typedef pair<double,double> PII;
typedef vector< pair<int,int> > VPII;
const ll mod=1e9+7;
const ll maxn=1e5+7;
const ll maxe=1e6+7;
const ll INF=1e9+7;
const double PI=acos(-1);
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
inline void Max(int &a,int b){
   if(b>a)a=b;
}
inline void Min(int &a,int b){
  if(a==-1||b<a)a=b;
}
int n;
double p[maxn];
double mov[maxn];
PII seg[maxn*4];
PII merge(PII p,PII q)
{
	PII res;
	res.fi=(p.fi*q.fi)/(1+p.se*q.fi-p.se);
	res.se=(q.se-p.se*q.se+q.fi*p.se)/(1+p.se*q.fi-p.se);
	return res;
}
void push_up(int k)
{
	seg[k]=merge(seg[chl],seg[chr]);
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		seg[k]=mp(p[l],p[l]);
		return ;
	}
	build(lson);
	build(rson);
	push_up(k);
}
void update(int k,int l,int r,int pos)
{
	if(pos>r||pos<l) return ;
	if(l==r)
	{
		seg[k]=mp(p[pos],p[pos]);
		return ;
	}
	update(lson,pos);
	update(rson,pos);
	push_up(k);
}
PII query(int k,int l,int r,int a,int b)
{
	if(l>=a&&r<=b) return seg[k];
	//cout<<l<<" "<<r<<endl;
	int m=(l+r)/2;
	if(m>=b) return query(lson,a,b);
	else if(m<a) return query(rson,a,b);
	else
	{
		PII t1=query(lson,a,b);
		PII t2=query(rson,a,b);
	//	cout<<t1.fi<<" "<<t2.fi<<" "<<t1.se<<" "<<t2.se<<endl;
		return merge(query(lson,a,b),query(rson,a,b));
	}
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int q;
    cin>>n>>q;
	double u,v;
    for(int i=1;i<=n;i++)
	{
		scanf("%lf%lf",&u,&v);
		p[i]=u/v;
	}
   	build(1,1,n);
   	/*
   	for(int i=1;i<=5;i++)
	{
		PII t=seg[i];
		cout<<t.fi<<" "<<t.se<<endl;
	}
	*/
	//query(1,1,n,2,3);
	while(q--)
	{
		int ty;
		scanf("%d",&ty);
		if(ty==1)
		{
			int i;
			scanf("%d%lf%lf",&i,&u,&v);
			p[i]=u/v;
			update(1,1,n,i);
		}
		else if(ty==2)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			PII t=query(1,1,n,l,r);
			printf("%.7f\n",t.fi);
		}
	}
    return 0;
}


/* ***********************************************
Author        :yuanzhaolin
Created Time  :2016年09月29日 星期四 11时03分49秒
File Name     :e2.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <queue>
#include <utility>
using namespace std;
#define repp(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=0;i<a;i++)
#define REP(i,a) for(int i=1;i<=a;i++)
#define per(i,a,b) for(int i=a-1;i>=b;i--)
#define foreach(i,a) for(int i=head[a];i>=0;i=ee[i].next)
#define Foreach(i,a) for(__typeof((a).begin())i=(a).begin();i!=(a).end();i++)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mp make_pair
#define m0(x) memset(x,0,sizeof(x))
#define mff(x) memset(x,0xff,sizeof(x))
#define fi first
#define se second
#define lson k<<1,l,(l+r)/2
#define rson k<<1|1,(l+r)/2+1,r
#define chl (k<<1)
#define chr (k<<1|1)
#define SZ(x) ((int)(x).size())
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#define sqr(x) ((x)*(x))
#define C1(x) cout<<x<<endl
#define C2(x,y) cout<<x<<" "<<y<<endl
#define C3(x,y,z) cout<<x<<" "<<y<<" "<<z<<endl
typedef long long ll;
typedef vector<int> VI;
typedef pair<double,double> PII;
typedef vector< pair<int,int> > VPII;
const ll mod=1e9+7;
const ll maxn=1e5+7;
const ll maxe=1e6+7;
const ll INF=1e9+7;
const double PI=acos(-1);
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
inline void Max(int &a,int b){
   if(b>a)a=b;
}
inline void Min(int &a,int b){
  if(a==-1||b<a)a=b;
}
int n;
double a[maxn*4];
double b[maxn*4];
double p[maxn];
double m1(double a1,double b1,double a2,double b2)
{
	return a1*a2/(1+a2*b1-b1);
}
double m2(double a1,double b1,double a2,double b2)
{
	return (b2-b1*b2+b1*a2)/(1+a2*b1-b1);
}
void push_up(int k)
{
	a[k]=m1(a[chl],b[chl],a[chr],b[chr]);
	b[k]=m2(a[chl],b[chl],a[chr],b[chr]);
}
void build(int k,int l,int r)
{
	if(l==r)
	{
		a[k]=p[l];
		b[k]=p[l];
		return ;
	}
	build(lson);
	build(rson);
	push_up(k);
}
void update(int k,int l,int r,int pos)
{
	if(l>pos||r<pos) return ;
	if(l==r)
	{
		a[k]=p[pos];
		b[k]=p[pos];
		return ;
	}
	update(lson,pos);
	update(rson,pos);
	push_up(k);
}
PII query(int k,int l,int r,int x,int y)
{
	if(l>=x&r<=y) return mp(a[k],b[k]);
	int m=(l+r)/2;
	if(m>=y) return query(lson,x,y);
	else if(m<x) return query(rson,x,y);
	else
	{
		PII res;
		PII t1=query(lson,x,y);
		PII t2=query(rson,x,y);
		res.fi=m1(t1.fi,t1.se,t2.fi,t2.se);
		res.se=m2(t1.fi,t1.se,t2.fi,t2.se);
		return res;
	}
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int q;
	cin>>n>>q;
	int u,v;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&u,&v);
		p[i]=1.0*u/v;
	}
	build(1,1,n);
	while(q--)
	{
		int ty;
		scanf("%d",&ty);
		int a;
		if(ty==1)
		{
			scanf("%d%d%d",&a,&u,&v);
			p[a]=1.0*u/v;
			update(1,1,n,a);
		}
		else if(ty==2)
		{
			scanf("%d%d",&u,&v);
			PII res=query(1,1,n,u,v);
			printf("%.7f\n",res.fi);
		}
	}
    return 0;
}


#include <cstdio>
#include <utility>

#define Int register int

using namespace std;

typedef pair<double, double> pdd;

const int MAXN = 1e5;
int n, q;
double p[MAXN + 5] = {};

class Segment_Tree {
private:
	struct Node {
		int l, r;
		double f, g;
	} Tree[MAXN << 2];

public:
	inline void Push_up ( const int i ) {
		double f1 = Tree[i << 1].f, f2 = Tree[i << 1 | 1].f;
		double g1 = Tree[i << 1].g, g2 = Tree[i << 1 | 1].g;
		Tree[i].f = f1 * f2 / ( 1 - ( 1 - f2 ) * ( 1 - g1 ) );
		Tree[i].g = g1 * g2 / ( 1 - ( 1 - f2 ) * ( 1 - g1 ) );
	}
	inline void Build ( const int i, const int l, const int r, double* p ) {
		Tree[i] = { l, r, 0.0, 0.0 };
		if ( l == r ) { Tree[i].f = p[l], Tree[i].g = 1 - p[l]; return ; }
		int mid = l + r >> 1;
		Build ( i << 1, l, mid, p ), Build ( i << 1 | 1, mid + 1, r, p );
		Push_up ( i );
	}
	inline void Update ( const int i, const int Indx, const double p ) {
		if ( Tree[i].r < Indx || Indx < Tree[i].l ) return ;
		if ( Tree[i].l == Indx && Tree[i].r == Indx ) {
			Tree[i].f = p, Tree[i].g = 1 - p;
			return ;
		}
		Update ( i << 1, Indx, p ), Update ( i << 1 | 1, Indx, p );
		Push_up ( i );
	}
	inline pdd Query ( const int i, const int l, const int r ) {
		Node &now = Tree[i];
		if ( l <= Tree[i].l && Tree[i].r <= r ) return { Tree[i].f, Tree[i].g };
		int mid = Tree[i].l + Tree[i].r >> 1;
		if ( r <= mid ) return Query ( i << 1, l, r );
		else if ( mid < l ) return Query ( i << 1 | 1, l, r );
		pdd lret = Query ( i << 1, l, mid ), rret = Query ( i << 1 | 1, mid + 1, r );
		return { lret.first * rret.first / ( 1 - ( 1 - rret.first ) * ( 1 - lret.second ) ),
				lret.second * rret.second / ( 1 - ( 1 - rret.first ) * ( 1 - rret.second ) ) };
	}
} SegTree;

inline int rint () {
	int x = 0, f = 1; char s = getchar ();
	for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = ( x << 3 ) + ( x << 1 ) + ( s ^ '0' );
	return x * f;
}

inline void Work () {
	n = rint (), q = rint ();
	for ( Int i = 1; i <= n; ++ i ) p[i] = 1.0 * rint () / rint ();
	SegTree.Build ( 1, 1, n, p );
	for ( Int opt, i, a, b; q --; ) {
		opt = rint ();
		if ( opt & 1 ) {
			scanf ( "%d %d %d", &i, &a, &b );
			SegTree.Update ( 1, i, 1.0 * a / b );
		} else {
			scanf ( "%d %d", &a, &b );
			printf ( "%.10lf\n", SegTree.Query ( 1, a, b ).first );
		}
	}
}

int main () {
	Work ();
	return 0;
}

/*
3 1
1 3
1 2
2 3
2 2 3
*/


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 100000 + 5;
const int mod = 998244353;

int n, m;
double x[maxn], y[maxn], b[maxn];
double p[maxn];

double tag_add[maxn * 4], tag_mul[maxn * 4];
void inline pushdown(int id) {
	if(tag_mul[id] == 1 && tag_add[id] == 0) return;
	tag_mul[id << 1] = tag_mul[id << 1] * tag_mul[id];
	tag_mul[id << 1 | 1] = tag_mul[id << 1 | 1] * tag_mul[id];
	tag_add[id << 1] = tag_add[id << 1] * tag_mul[id] + tag_add[id];
	tag_add[id << 1 | 1] = tag_add[id << 1 | 1] * tag_mul[id] + tag_add[id];
	tag_mul[id] = 1, tag_add[id] = 0;
}
void radd(int id, int l, int r, int s, int t, double v)
{
	if(s <= l && t >= r) {
		tag_add[id] = tag_add[id] + v;
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(id);
	if(s <= mid) radd(id << 1, l, mid, s, t, v);
	if(t > mid) radd(id << 1 | 1, mid + 1, r, s, t, v);
}
void rmul(int id, int l, int r, int s, int t, double v)
{
	if(s <= l && t >= r) {
		tag_mul[id] = tag_mul[id] * v;
		tag_add[id] = tag_add[id] * v;
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(id);
	if(s <= mid) rmul(id << 1, l, mid, s, t, v);
	if(t > mid) rmul(id << 1 | 1, mid + 1, r, s, t, v);
}
void build(int id, int l, int r)
{
	tag_mul[id] = 1, tag_add[id] = 0;
	if(l == r) return;
	int mid = (l + r) >> 1;
	build(id << 1, l, mid);
	build(id << 1 | 1, mid + 1, r);
}
double inline pquery(int i)
{
	int id = 1, l = 1, r = n + 1;
	while(l < r) {
		pushdown(id);
		int mid = (l + r) >> 1;
		if(i <= mid) r = mid, id = id << 1;
		else l = mid + 1, id = id << 1 | 1;
	}
	p[i] = p[i] * tag_mul[id] + tag_add[id];
	tag_mul[id] = 1, tag_add[id] = 0;
	return p[i];
}

void inline Init()
{
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; ++i) {
		scanf("%lf %lf", x + i, y + i);
	}
	p[0] = 0, p[1] = 1;
	for(int i = 1; i <= n; ++i) {
		p[i + 1] = (p[i] - p[i - 1]) * y[i] / x[i] + p[i - 1];
	}
	build(1, 1, n + 1);
}

int opt, l, r, d;
double nx, ny;

void inline Solve()
{
	while(m--)
	{
		scanf("%d", &opt);
		if(opt == 1) {
			scanf("%d", &d); scanf("%lf %lf", x + d, y + d);
			pquery(d), pquery(d - 1), pquery(d + 1);
			double np = (p[d] - p[d - 1]) * y[d] / x[d] + p[d - 1];
			double mul = (np - p[d]) / (p[d + 1] - p[d]);
			double add = p[d];

			radd(1, 1, n + 1, d + 1, n + 1, -add);
			rmul(1, 1, n + 1, d + 1, n + 1, mul);
			radd(1, 1, n + 1, d + 1, n + 1, add);

		} else {
			scanf("%d %d", &l, &r);
			pquery(l), pquery(l - 1), pquery(r + 1);
			printf("%.10lf\n", (p[l] - p[l - 1]) / (p[r + 1] - p[l - 1]));
		}
	}
}

int main()
{
	Init();
	Solve();
	return 0;
}


#include <bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
#define ll long long
template <class T> void read(T &x) {
    x = 0;
    int f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f;
}
int n,m;
double jl[100005],tree1[400005],tree2[400005];
void build(int l,int r,int rt)
{
    if(l==r)
    {
        tree1[rt]=jl[l];
        tree2[rt]=jl[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);build(rson);
    tree1[rt]=tree1[rt<<1]*tree1[rt<<1|1];
    tree2[rt]=tree2[rt<<1]+1.0*(tree2[rt<<1|1])*tree1[rt<<1];
}
void update(int to,double x,int l,int r,int rt)
{
    if(l==r)
    {
        tree1[rt]=x;
        tree2[rt]=x;
        return ;
    }
    int mid=(l+r)>>1;
    if(to<=mid)update(to,x,lson);
    else update(to,x,rson);
    tree1[rt]=tree1[rt<<1]*tree1[rt<<1|1];
    tree2[rt]=tree2[rt<<1]+1.0*(tree2[rt<<1|1])*tree1[rt<<1];
}
double query1(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)return tree1[rt];
    int mid=(l+r)>>1;
    double ans=1.0;
    if(L<=mid)ans=1.0*ans*query1(L,R,lson);
    if(R>mid)ans=1.0*ans*query1(L,R,rson);
    return ans;
}
double query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)return tree2[rt];
    int mid=(l+r)>>1;
    double ans=0.0;
    if(L<=mid)ans+=1.0*query(L,R,lson);
    if(R>mid)ans+=1.0*query(L,R,rson)*query1(L,mid,lson);
    return ans;
}
int main()
{
    int a,b,c,qwq;
    read(n);read(m);
    for(int i=1;i<=n;++i)
    {
        read(a);read(b);
        jl[i]=1.0*(b-a)/a;
    }
    build(1,n,1);
    while(m--)
    {
         read(qwq);
         if(qwq==1)
         {
            read(a);read(b);read(c);/*令a变为b/c*/
            jl[a]=1.0*(c-b)/b;
            update(a,jl[a],1,n,1);
         }
         if(qwq==2)
         {
            read(a);read(b);
            printf("%.10f\n",1.0/(query(a,b,1,n,1)+1.0));
         }
    }
}


#include <bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
#define ll long long
template <class T> void read(T &x) {
    x = 0;
    int f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f;
}
/*ti=(1/pi)/pi=(b-a)/a
ANS=1/(1+t1+t1t2+t1t2t3+t1t2t3t4+...+t1t2t3t4...tn-1)*/
/*线段树维护t1t2t3t4...tn
ANS=(t1+t1t2+t1t2t3+t1t2t3t4+...+t1t2t3t4...tmid)+(t1t2t3t4...tmid)*(tmid+tmidtmid+1.....-1)
*/
int n,m;
double jl[100005],tree1[400005],tree2[400005];
void build(int l,int r,int rt)
{
    if(l==r)
    {
        tree1[rt]=jl[l];
        tree2[rt]=jl[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);build(rson);
    tree1[rt]=tree1[rt<<1]*tree1[rt<<1|1];
    tree2[rt]=tree2[rt<<1]+1.0*(tree2[rt<<1|1])*tree1[rt<<1];
}
void update(int to,double x,int l,int r,int rt)
{
    if(l==r)
    {
        tree1[rt]=x;
        tree2[rt]=x;
        return ;
    }
    int mid=(l+r)>>1;
    if(to<=mid)update(to,x,lson);
    else update(to,x,rson);
    tree1[rt]=tree1[rt<<1]*tree1[rt<<1|1];
    tree2[rt]=tree2[rt<<1]+1.0*(tree2[rt<<1|1])*tree1[rt<<1];
}
double query1(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)return tree1[rt];
    int mid=(l+r)>>1;
    double ans=1.0;
    if(L<=mid)ans=1.0*ans*query1(L,R,lson);
    if(R>mid)ans=1.0*ans*query1(L,R,rson);
    return ans;
}
double query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)return tree2[rt];
    int mid=(l+r)>>1;
    double ans=0.0;
    if(L<=mid)ans+=1.0*query(L,R,lson);
    if(R>mid)ans+=1.0*query(L,R,rson)*query1(L,mid,lson);
    return ans;
}
int main()
{
    int a,b,c,qwq;
    read(n);read(m);
    for(int i=1;i<=n;++i)
    {
        read(a);read(b);
        jl[i]=1.0*(b-a)/a;
    }
    build(1,n,1);
    while(m--)
    {
         read(qwq);
         if(qwq==1)
         {
            read(a);read(b);read(c);/*令a变为b/c*/
            jl[a]=1.0*(c-b)/b;
            update(a,jl[a],1,n,1);
         }
         if(qwq==2)
         {
            read(a);read(b);
            printf("%.10f\n",1.0/(query(a,b,1,n,1)+1.0));
         }
    }
}


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

const int Maxn = 100005;
int n, q;
struct Tree
{
	int lt, rt;
	double prod, sum;
} tree[4 * Maxn];
void build(int root, int lt, int rt)
{
	tree[root] = (Tree){lt, rt, 0, 0};
	if (lt + 1 != rt)
	{
		int mid = (lt + rt) >> 1;
		build(root << 1, lt, mid);
		build(root << 1 | 1, mid, rt);
	}
}
void modify(int root, int pos, double val)
{
	if (tree[root].lt + 1 == tree[root].rt)
		tree[root].prod = tree[root].sum = val;
	else
	{
		int mid = (tree[root].lt + tree[root].rt) >> 1;
		if (pos >= mid) modify(root << 1 | 1, pos, val);
		else modify(root << 1, pos, val);
		tree[root].prod = tree[root << 1].prod * tree[root << 1 | 1].prod;
		tree[root].sum = tree[root << 1].sum + tree[root << 1].prod * tree[root << 1 | 1].sum;
	}
}
pair <double, double> ask(int root, int lt, int rt)
{
	if (tree[root].lt == lt && tree[root].rt == rt)
		return make_pair(tree[root].prod, tree[root].sum);
	else
	{
		int mid = (tree[root].lt + tree[root].rt) >> 1;
		if (lt >= mid) return ask(root << 1 | 1, lt, rt);
		else if (rt <= mid) return ask(root << 1, lt, rt);
		else
		{
			pair <double, double> tmp1 = ask(root << 1, lt, mid), tmp2 = ask(root << 1 | 1, mid, rt);
			return make_pair(tmp1.first * tmp2.first, tmp1.second + tmp1.first * tmp2.second);
		}
	}
}
int main()
{
	scanf("%d%d", &n, &q);
	build(1, 1, n + 1);
	for (int i = 1; i <= n; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		double w = x / (double) y;
		modify(1, i, (1 - w) / w);
	}
	while (q--)
	{
		int opt;
		scanf("%d", &opt);
		if (opt == 1)
		{
			int pos, x, y;
			scanf("%d%d%d", &pos, &x, &y);
			double w = x / (double) y;
			modify(1, pos, (1 - w) / w);
		}
		else
		{
			int l, r;
			scanf("%d%d", &l, &r);
			printf("%.10lf\n", 1 / (1 + ask(1, l, r + 1).second));
		}
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e5+3,M=4e5+3;
struct T{
	double x,y;
}s[M];
double g[N];
int u,v;
T up(T a,T b){
	return(T){a.x*b.x,a.y+a.x*b.y};
}
void build(int k,int l,int r){
	if(l==r){
		s[k].x=s[k].y=g[l];
		return;
	}
	int m=l+r>>1;
	build(k*2,l,m),build(k*2+1,m+1,r);
	s[k]=up(s[k*2],s[k*2+1]);
}
void upd(int k,int l,int r){
	if(l==r){
		s[k].x=s[k].y=g[l];
		return;
	}
	int m=l+r>>1;
	if(u<=m)upd(k*2,l,m);else upd(k*2+1,m+1,r);
	s[k]=up(s[k*2],s[k*2+1]);
}
T qry(int k,int l,int r){
	if(u<=l&&r<=v)return s[k];
	int m=l+r>>1;
	if(u<=m&&m<v)return up(qry(k*2,l,m),qry(k*2+1,m+1,r));
	if(u<=m)return qry(k*2,l,m);
	return qry(k*2+1,m+1,r);
}
int main(){
	int n,q,i,j,k;
	scanf("%d%d",&n,&q);
	for(i=1;i<=n;++i){
		scanf("%d%d",&j,&k);
		g[i]=(k-j)*1.0/j;
	}
	build(1,1,n);
	while(q--){
		scanf("%d%d%d",&i,&j,&k);
		if(i==1){
			scanf("%d",&i);
			g[j]=(i-k)*1.0/k,u=j;
			upd(1,1,n);
		}else{
			u=j,v=k;
			printf("%lf\n",1/(1+qry(1,1,n).y));
		}
	}
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
#define ll long long
const int NUM=100050;
double p[NUM];
int n,m;
struct node
{
int l;
int r;
double w1;
double w2;
}tre[NUM*4];
void build(int l,int r,int k)
{
tre[k].l=l;
tre[k].r=r;
if(l==r)
{
    tre[k].w1=tre[k].w2=p[l];
    return;
}
int mid=(l+r)>>1;
build(1,mid,k<<1);
build(mid+1,r,k<<1|1);
tre[k].w1=tre[k<<1].w1*tre[k<<1|1].w1;
tre[k].w2=tre[k<<1].w2+tre[k<<1].w1*tre[k<<1|1].w2;
}
void change(int u,int k,double a)
{
if(tre[k].l>u||tre[k].r<u)
return;
if(tre[k].l==tre[k].r)
{
tre[k].w1=tre[k].w2=a;
return ;
}
change(u,k<<1,a);
change(u,k<<1|1,a);
tre[k].w1=tre[k<<1].w1*tre[k<<1|1].w1;
tre[k].w2=tre[k<<1].w2+tre[k<<1].w1*tre[k<<1|1].w2;
}
double ask(int l,int r,int k)
{
if(l>tre[k].r||tre[k].l>r)
return 1;
if(l<=tre[k].l&&tre[k].r<=r)
return tre[k].w1;
double res=1;
res=res*ask(l,r,k<<1);
res=res*ask(l,r,k<<1|1);
return res;
}
double query(int l,int r,int k)
{
if(l>tre[k].r||r<tre[k].l)
return 0;
if(l<=tre[k].l&&r>=tre[k].r)
return tre[k].w2;
double res=0;
res+=query(l,r,k<<1);
if(r>((tre[k].l+tre[k].r)>>1))
res+=query(l,r,k<<1|1)*ask(l,(tre[k].l+tre[k].r)>>1,k<<1);
return res;
}
int main()
{
ios::sync_with_stdio(false);
int op;int a,b,c;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a>>b;
p[i]=(1.0)*(b-a)/a;
}
build(1,n,1);
for(int i=1;i<=m;i++)
{
cin>>op;
if(op==1)
{
cin>>a>>b>>c;
p[a]=(1.0)*(c-b)/b;
change(a,1,p[a]);
}
else
{
cin>>a>>b;
cout<<1/(query(a,b,1)+1)<<"\n";
}
}
}


#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
#define ll long long
const int NUM=100050;
double p[NUM];
int n,m;
struct node
{
    int l;
    int r;
    double w1;
    double w2;
}tre[NUM*4];
void build(int l,int r,int k)
{
    tre[k].l=l;
    tre[k].r=r;
    if(l==r)
    {
        tre[k].w1=tre[k].w2=p[l];
        return;
    }
    int mid=(l+r)>>1;
    build(1,mid,k<<1);
    build(mid+1,r,k<<1|1);
    tre[k].w1=tre[k<<1].w1*tre[k<<1|1].w1;
    tre[k].w2=tre[k<<1].w2+tre[k<<1].w1*tre[k<<1|1].w2;

}
void change(int u,int k,double a)
{
    if(tre[k].l>u||tre[k].r<u)
        return;
    if(tre[k].l==tre[k].r)
    {
        tre[k].w1=tre[k].w2=a;
        return ;
    }
    change(u,k<<1,a);
    change(u,k<<1|1,a);
    tre[k].w1=tre[k<<1].w1*tre[k<<1|1].w1;
    tre[k].w2=tre[k<<1].w2+tre[k<<1].w1*tre[k<<1|1].w2;
}
double ask(int l,int r,int k)
{
    if(l>tre[k].r||tre[k].l>r)
        return 1;
     if(l<=tre[k].l&&tre[k].r<=r)
        return tre[k].w1;
    double res=1;
    res=res*ask(l,r,k<<1);
    res=res*ask(l,r,k<<1|1);
    return res;
}
double query(int l,int r,int k)
{
    if(l>tre[k].r||r<tre[k].l)
        return 0;
    if(l<=tre[k].l&&r>=tre[k].r)
        return tre[k].w2;
    double res=0;
    res+=query(l,r,k<<1);
    if(r>((tre[k].l+tre[k].r)>>1))
        res+=query(l,r,k<<1|1)*ask(l,(tre[k].l+tre[k].r)>>1,k<<1);
    return res;
}

int main()
{
    ios::sync_with_stdio(false);
    int op;int a,b,c;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b;
        p[i]=(1.0)*(b-a)/a;
    }
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        cin>>op;
        if(op==1)
        {
            cin>>a>>b>>c;
            p[a]=(1.0)*(c-b)/b;
            change(a,1,p[a]);
        }
        else
        {
            cin>>a>>b;
            cout<<1/(query(a,b,1)+1)<<"\n";
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
const int N=10005,mod=1e9+7;
int n,x,y;
char s[5][N];
int check(int dx,int dy){
	for (int i=1;i<=2;i++)
		if (s[x+dx*i][y+dy*i]!='.')
			return 0;
	return 1;
}
void cover(int dx,int dy){
	for (int i=1;i<=2;i++)
		s[x+dx*i][y+dy*i]='*';
}
void uncover(int dx,int dy){
	for (int i=1;i<=2;i++)
		s[x+dx*i][y+dy*i]='.';
}
int dp[N][8];
int solve(){
	memset(dp,0,sizeof dp);
	dp[0][7]=1;
	for (int i=1;i<=n;i++){
		int k=0;
		for (int x=1;x<=3;x++)
			k|=(s[x][i]!='.')<<(x-1);
		for (int j=0;j<8;j++){
			if (j&k)
				continue;
			int _j=j|k;
			dp[i][_j]=dp[i-1][j^7];
			if (j==3||j==6)//001 100
				dp[i][_j]=(1LL*dp[i][_j]+dp[i-1][7])%mod;
			else if (j==7)//111
				dp[i][_j]=(1LL*dp[i][_j]+dp[i-1][6]+dp[i-1][3])%mod;
		}
	}
	return dp[n][7];
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=3;i++)
		scanf("%s",s[i]+1);
	for (int i=1;i<=3;i++)
		for (int j=1;j<=n;j++)
			if (s[i][j]=='O')
				x=i,y=j;
	if (x==3)
		swap(s[1],s[3]),x=1;
	int ans=0;
	#define A 1,0
	#define B 0,1
	#define C 0,-1
	#define ck check
	#define cv cover
	#define uc uncover
	#define up ans=(ans+solve())%mod
	#define um ans=(ans-solve())%mod
	if (ck(A))
		cv(A),up,uc(A);
	if (ck(B))
		cv(B),up,uc(B);
	if (ck(C))
		cv(C),up,uc(C);
	if (ck(A)*ck(B))
		cv(A),cv(B),um,uc(A),uc(B);
	if (ck(A)*ck(C))
		cv(A),cv(C),um,uc(A),uc(C);
	if (ck(C)*ck(B))
		cv(C),cv(B),um,uc(C),uc(B);
	if (ck(A)*ck(B)*ck(C))
		cv(A),cv(B),cv(C),up,uc(A),uc(B),uc(C);
	printf("%d",(ans+mod)%mod);
	return 0;
}


#include<iostream>
#include<memory.h>
#include<vector>
#include<algorithm>

#define mod 1000000007

using namespace std;

string s[7];
int n;
int mem[10010][10][10][10];
int solve(int col,int row,int curr,int next)
{
    if (mem[col][row][curr][next] != -1)
        return mem[col][row][curr][next];
    if (col == n + 2)
        return mem[col][row][curr][next] = 1;
    if (row == 3)
        return mem[col][row][curr][next] = solve(col + 1, 0, next, 0);
    int ans = 0;
    if ((curr & (1<<row)) || s[row + 2][col] != '.')
        ans += solve(col, row + 1, curr, next);
    if (s[row + 2][col] == '.' && s[row + 2][col + 1] == '.' && (curr & (1<<row)) == 0)
        ans += solve(col, row + 1, curr, next | (1<<row));
    if (ans >= mod)
        ans %= mod;
    if (row < 2 && s[row + 2][col] == '.' && s[row + 3][col] == '.')
        ans += solve(col, row + 2, curr, next);
    return mem[col][row][curr][next] = (ans % mod);
}

void print()
{
    for (int j=0;j<7;j++,cout<<endl)
    for (int i=0;i<n+4;i++)
        cout<<s[j][i];

}

bool can(int x,int y,int b)
{
    if (b == 0)
        return s[x][y + 1] == '.' && s[x][y + 2] == '.';
    if (b == 1)
        return s[x][y - 1] == '.' && s[x][y - 2] == '.';
    if (b == 2)
        return s[x + 1][y] == '.' && s[x + 2][y] == '.';
    if (b == 3)
        return s[x - 1][y] == '.' && s[x - 2][y] == '.';
}

void fill(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = 'X';
        s[x][y + 2] = 'X';
    }
    if (b == 1)
    {
        s[x][y - 1] = 'X';
        s[x][y - 2] = 'X';
    }
    if (b == 2)
    {
        s[x + 1][y] = 'X';
        s[x + 2][y] = 'X';
    }
    if (b == 3)
    {
        s[x - 1][y] = 'X';
        s[x - 2][y] = 'X';
    }
}

void free(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = '.';
        s[x][y + 2] = '.';
    }
    if (b == 1)
    {
        s[x][y - 1] = '.';
        s[x][y - 2] = '.';
    }
    if (b == 2)
    {
        s[x + 1][y] = '.';
        s[x + 2][y] = '.';
    }
    if (b == 3)
    {
        s[x - 1][y] = '.';
        s[x - 2][y] = '.';
    }
}

bool subset(int mask,int sub)
{
    for (int i=0;i<4;i++)
        if ((mask & (1<<i)) == 0 && (sub & (1<<i)))
            return false;
    return true;
}

main()
{
    cin>>n;
    for (int i=2;i<=4;i++)
        cin>>s[i];
    int ox , oy;
    s[0] = string(n + 4, 'X');
    s[1] = string(n + 4, 'X');
    s[5] = string(n + 4, 'X');
    s[6] = string(n + 4, 'X');

    for (int i=2;i<=4;i++)
    {
        s[i] = "XX" + s[i] + "XX";
        for (int j=0;j<n+4;j++)
            if (s[i][j] == 'O')
            {
                ox = i;
                oy = j;
            }
    }
    int ans = 0;
    s[ox][oy] = 'X';
    int msk = 0;
    for (int i=0;i<4;i++)
        if (can(ox,oy,i))
            msk |= (1 << i);
    //cout<<msk<<endl;
    for (int i=1;i<(1<<4);i++)
    {
        if (subset(msk,i))
        {
            int neg = __builtin_popcount(i) % 2 ? 1 : -1;
            memset(mem,-1,sizeof mem);
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    fill(ox,oy,j);
            int t = solve(2, 0, 0, 0);
//            print();

            if (neg == -1)
                ans = (ans + mod - t) % mod;
            else
                ans = (ans + t) % mod;
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    free(ox,oy,j);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<memory.h>
#include<vector>
#include<algorithm>

#define mod 1000000007

using namespace std;

string s[7];
int n;
int mem[10010][10][10][10];
int solve(int col,int row,int curr,int next)
{
    if (mem[col][row][curr][next] != -1)
        return mem[col][row][curr][next];
    if (col == n + 2)
        return mem[col][row][curr][next] = 1;
    if (row == 3)
        return mem[col][row][curr][next] = solve(col + 1, 0, next, 0);
    int ans = 0;
    if ((curr & (1<<row)) || s[row + 2][col] != '.')
        ans += solve(col, row + 1, curr, next);
    if (s[row + 2][col] == '.' && s[row + 2][col + 1] == '.' && (curr & (1<<row)) == 0)
        ans += solve(col, row + 1, curr, next | (1<<row));
    if (ans >= mod)
        ans %= mod;
    if (row < 2 && s[row + 2][col] == '.' && s[row + 3][col] == '.')
        ans += solve(col, row + 2, curr, next);
    return mem[col][row][curr][next] = (ans % mod);
}

void print()
{
    for (int j=0;j<7;j++,cout<<endl)
    for (int i=0;i<n+4;i++)
        cout<<s[j][i];

}

bool can(int x,int y,int b)
{
    if (b == 0)
        return s[x][y + 1] == '.' && s[x][y + 2] == '.';
    if (b == 1)
        return s[x][y - 1] == '.' && s[x][y - 2] == '.';
    if (b == 2)
        return s[x + 1][y] == '.' && s[x + 2][y] == '.';
    if (b == 3)
        return s[x - 1][y] == '.' && s[x - 2][y] == '.';
}

void fill(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = 'X';
        s[x][y + 2] = 'X';
    }
    if (b == 1)
    {
        s[x][y - 1] = 'X';
        s[x][y - 2] = 'X';
    }
    if (b == 2)
    {
        s[x + 1][y] = 'X';
        s[x + 2][y] = 'X';
    }
    if (b == 3)
    {
        s[x - 1][y] = 'X';
        s[x - 2][y] = 'X';
    }
}

void free(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = '.';
        s[x][y + 2] = '.';
    }
    if (b == 1)
    {
        s[x][y - 1] = '.';
        s[x][y - 2] = '.';
    }
    if (b == 2)
    {
        s[x + 1][y] = '.';
        s[x + 2][y] = '.';
    }
    if (b == 3)
    {
        s[x - 1][y] = '.';
        s[x - 2][y] = '.';
    }
}

bool subset(int mask,int sub)
{
    for (int i=0;i<4;i++)
        if ((mask & (1<<i)) == 0 && (sub & (1<<i)))
            return false;
    return true;
}

main()
{
    cin>>n;
    for (int i=2;i<=4;i++)
        cin>>s[i];
    int ox , oy;
    s[0] = string(n + 4, 'X');
    s[1] = string(n + 4, 'X');
    s[5] = string(n + 4, 'X');
    s[6] = string(n + 4, 'X');

    for (int i=2;i<=4;i++)
    {
        s[i] = "XX" + s[i] + "XX";
        for (int j=0;j<n+4;j++)
            if (s[i][j] == 'O')
            {
                ox = i;
                oy = j;
            }
    }
    int ans = 0;
    s[ox][oy] = 'X';
    int msk = 0;
    for (int i=0;i<4;i++)
        if (can(ox,oy,i))
            msk |= (1 << i);
    cout<<msk<<endl;
    for (int i=1;i<(1<<4);i++)
    {
        if (subset(msk,i))
        {
            int neg = __builtin_popcount(i) % 2 ? 1 : -1;
            memset(mem,-1,sizeof mem);
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    fill(ox,oy,j);
            int t = solve(2, 0, 0, 0);
//            print();

            if (neg == -1)
                ans = (ans + mod - t) % mod;
            else
                ans = (ans + t) % mod;
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    free(ox,oy,j);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<memory.h>
#include<vector>
#include<algorithm>
#include<bitset>
#define mod 1000000007

using namespace std;

string s[7];

int n;
int mem[10010][10][10][10];
int solve(int col,int row,int curr,int next)
{
 //   cout<<col<<" "<<row<<" "<<curr<<" "<<next<<endl;
    if (mem[col][row][curr][next] != -1)
        return mem[col][row][curr][next];
    if (col == n + 2)
        return mem[col][row][curr][next] = 1;
    if (row == 3)
        return mem[col][row][curr][next] = solve(col + 1, 0, next, 0);
    int ans = 0;
    if ((curr & (1<<row)) || s[row + 2][col] != '.')
        return solve(col, row + 1, curr, next);
    if (s[row + 2][col] == '.' && s[row + 2][col + 1] == '.' && (curr & (1<<row)) == 0)
        ans += solve(col, row + 1, curr | (1<<row), next | (1<<row));
    if (row < 2 && s[row + 2][col] == '.' && s[row + 3][col] == '.' && (curr & (1<<(row + 1))) == 0)
        ans += solve(col, row + 1, curr | (1<<(row + 1)), next);
    return mem[col][row][curr][next] = (ans % mod);
}

void print()
{
    for (int j=0;j<7;j++,cout<<endl)
    for (int i=0;i<n+4;i++)
        cout<<s[j][i];

}

bool can(int x,int y,int b)
{
    if (b == 0)
        return s[x][y + 1] == '.' && s[x][y + 2] == '.';
    if (b == 1)
        return s[x][y - 1] == '.' && s[x][y - 2] == '.';
    if (b == 2)
        return s[x + 1][y] == '.' && s[x + 2][y] == '.';
    if (b == 3)
        return s[x - 1][y] == '.' && s[x - 2][y] == '.';
}

void fill(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = 'X';
        s[x][y + 2] = 'X';
    }
    if (b == 1)
    {
        s[x][y - 1] = 'X';
        s[x][y - 2] = 'X';
    }
    if (b == 2)
    {
        s[x + 1][y] = 'X';
        s[x + 2][y] = 'X';
    }
    if (b == 3)
    {
        s[x - 1][y] = 'X';
        s[x - 2][y] = 'X';
    }
}

void free(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = '.';
        s[x][y + 2] = '.';
    }
    if (b == 1)
    {
        s[x][y - 1] = '.';
        s[x][y - 2] = '.';
    }
    if (b == 2)
    {
        s[x + 1][y] = '.';
        s[x + 2][y] = '.';
    }
    if (b == 3)
    {
        s[x - 1][y] = '.';
        s[x - 2][y] = '.';
    }
}

bool subset(int mask,int sub)
{
    for (int i=0;i<4;i++)
        if ((mask & (1<<i)) == 0 && (sub & (1<<i)))
            return false;
    return true;
}

main()
{
    cin>>n;
    for (int i=2;i<=4;i++)
        cin>>s[i];
    int ox , oy;
    s[0] = string(n + 4, 'X');
    s[1] = string(n + 4, 'X');
    s[5] = string(n + 4, 'X');
    s[6] = string(n + 4, 'X');

    for (int i=2;i<=4;i++)
    {
        s[i] = "XX" + s[i] + "XX";
        for (int j=0;j<n+4;j++)
            if (s[i][j] == 'O')
            {
                ox = i;
                oy = j;
            }
    }
    int ans = 0;
    s[ox][oy] = 'X';
    int msk = 0;
    for (int i=0;i<4;i++)
        if (can(ox,oy,i))
            msk |= (1 << i);
    //cout<<msk<<endl;
    for (int i=1;i<(1<<4);i++)
    {
        if (subset(msk,i))
        {
            int neg = __builtin_popcount(i) % 2 ? 1 : -1;
            memset(mem,-1,sizeof mem);
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    fill(ox,oy,j);
            int t = solve(2, 0, 0, 0);
            //print();
           // cout<<i<<" "<<t<<endl<<endl;
            if (neg == -1)
                ans = (ans + mod - t) % mod;
            else
                ans = (ans + t) % mod;
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    free(ox,oy,j);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include<iostream>
#include<memory.h>
#include<vector>
#include<algorithm>

#define mod 1000000007

using namespace std;

string s[7];
int n;
int mem[10010][10][10][10];
int solve(int col,int row,int curr,int next)
{
    if (mem[col][row][curr][next] != -1)
        return mem[col][row][curr][next];
    if (col == n + 2)
        return mem[col][row][curr][next] = 1;
    if (row == 3)
        return mem[col][row][curr][next] = solve(col + 1, 0, next, 0);
    int ans = 0;
    if ((curr & (1<<row)) || s[row + 2][col] != '.')
        return solve(col, row + 1, curr, next);
    if (s[row + 2][col] == '.' && s[row + 2][col + 1] == '.' && (curr & (1<<row)) == 0)
        ans += solve(col, row + 1, curr | (1<<row), next | (1<<row));
    if (ans >= mod)
        ans %= mod;
    if (row < 2 && s[row + 2][col] == '.' && s[row + 3][col] == '.')
        ans += solve(col, row + 2, curr, next);
    return mem[col][row][curr][next] = (ans % mod);
}

void print()
{
    for (int j=0;j<7;j++,cout<<endl)
    for (int i=0;i<n+4;i++)
        cout<<s[j][i];

}

bool can(int x,int y,int b)
{
    if (b == 0)
        return s[x][y + 1] == '.' && s[x][y + 2] == '.';
    if (b == 1)
        return s[x][y - 1] == '.' && s[x][y - 2] == '.';
    if (b == 2)
        return s[x + 1][y] == '.' && s[x + 2][y] == '.';
    if (b == 3)
        return s[x - 1][y] == '.' && s[x - 2][y] == '.';
}

void fill(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = 'X';
        s[x][y + 2] = 'X';
    }
    if (b == 1)
    {
        s[x][y - 1] = 'X';
        s[x][y - 2] = 'X';
    }
    if (b == 2)
    {
        s[x + 1][y] = 'X';
        s[x + 2][y] = 'X';
    }
    if (b == 3)
    {
        s[x - 1][y] = 'X';
        s[x - 2][y] = 'X';
    }
}

void free(int x,int y,int b)
{
    if (b == 0)
    {
        s[x][y + 1] = '.';
        s[x][y + 2] = '.';
    }
    if (b == 1)
    {
        s[x][y - 1] = '.';
        s[x][y - 2] = '.';
    }
    if (b == 2)
    {
        s[x + 1][y] = '.';
        s[x + 2][y] = '.';
    }
    if (b == 3)
    {
        s[x - 1][y] = '.';
        s[x - 2][y] = '.';
    }
}

bool subset(int mask,int sub)
{
    for (int i=0;i<4;i++)
        if ((mask & (1<<i)) == 0 && (sub & (1<<i)))
            return false;
    return true;
}

main()
{
    cin>>n;
    for (int i=2;i<=4;i++)
        cin>>s[i];
    int ox , oy;
    s[0] = string(n + 4, 'X');
    s[1] = string(n + 4, 'X');
    s[5] = string(n + 4, 'X');
    s[6] = string(n + 4, 'X');

    for (int i=2;i<=4;i++)
    {
        s[i] = "XX" + s[i] + "XX";
        for (int j=0;j<n+4;j++)
            if (s[i][j] == 'O')
            {
                ox = i;
                oy = j;
            }
    }
    int ans = 0;
    s[ox][oy] = 'X';
    int msk = 0;
    for (int i=0;i<4;i++)
        if (can(ox,oy,i))
            msk |= (1 << i);
    //cout<<msk<<endl;
    for (int i=1;i<(1<<4);i++)
    {
        if (subset(msk,i))
        {
            int neg = __builtin_popcount(i) % 2 ? 1 : -1;
            memset(mem,-1,sizeof mem);
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    fill(ox,oy,j);
            int t = solve(2, 0, 0, 0);
            //print();
            //cout<<t<<endl;
            if (neg == -1)
                ans = (ans + mod - t) % mod;
            else
                ans = (ans + t) % mod;
            for (int j=0;j<4;j++)
                if (i & (1<<j))
                    free(ox,oy,j);
        }
    }
    cout<<ans<<endl;
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <iomanip>
#include <string>
#include <list>
#include <map>
#include <set>
#include <ctime>
#include <functional>
#include <bitset>

#define pb push_back
#define mk make_pair
#define sqr(N) ((N)*(N))
#define F first
#define S second
#define maxn 101010

using namespace std;

typedef long long ll;

const int md = 1e9 + 7;

char d[4][11111];
int i, j, k, n, dp[11111][8][2];

void inc(int *x, int *y){
 *x += *y;
 if(*x >= md) *x-= md;
}

int main(){
#ifndef ONLINE_JUDGE
 freopen("input.txt", "r", stdin);
 freopen("output.txt", "w", stdout);
#endif
  scanf("%d", &n);
  for(i = 1; i <= 3; i++){
    scanf("%*c");
    for(j = 1; j <= n; j++) scanf("%c", &d[i][j]);
  }
  dp[1][0][0] = 1;
  for(i = 1; i <= n; i++)
    for(j = 0; j < 8; j++)
     for(k = 0; k < 2; k++)if(dp[i][j][k]){
       int b1, b2, b3, nx = 0;
       b1 = j & 1;
       b2 = j & 2;
       b3 = j & 4;
       if(d[1][i + 1] != '.')nx |= 1;
       if(d[2][i + 1] != '.')nx |= 2;
       if(d[3][i + 1] != '.')nx |= 4;
       if(!b1 && !b2)
         if((!b3 && d[3][i + 1] == '.')){
           int cc = k;
	   if(d[3][i + 2] == 'O')cc = 1;
	   inc(&dp[i + 1][nx | 4][cc], &dp[i][j][k]);
	 }
	 else if(d[3][i] == 'O')inc(&dp[i + 1][nx][1], &dp[i][j][k]);
	 else if(d[3][i] == 'X' || b3)inc(&dp[i + 1][nx][k], &dp[i][j][k]);
       if(!b2 && !b3)
         if(!b1 && d[i + 1][1] == '.'){
           int cc = k;
           if(d[1][i + 2] == 'O')cc = 1;
           inc(&dp[i + 1][nx | 1][cc], &dp[i][j][k]);
         }
         else if(d[1][i] == 'O')inc(&dp[i + 1][nx][1], &dp[i][j][k]);
         else if(d[1][i] == 'X' || b1)inc(&dp[i + 1][nx][k], &dp[i][j][k]);
       int cc = k;
       if(!b1 && d[1][i + 1] != '.')continue;
       if(!b2 && d[2][i + 1] != '.')continue;
       if(!b3 && d[3][i + 1] != '.')continue;
       if(!b1 && (d[1][i + 2] == 'O' || d[1][i - 1] == 'O'))cc = 1;
       if(!b2 && (d[2][i + 2] == 'O' || d[2][i - 1] == 'O'))cc = 1;
       if(!b3 && (d[3][i + 2] == 'O' || d[3][i - 1] == 'O'))cc = 1;
       inc(&dp[i + 1][j ^ 7 | nx][cc], &dp[i][j][k]);
     }
  printf("%d\n", dp[n + 1][7][1]);
  return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <iomanip>
#include <string>
#include <list>
#include <map>
#include <set>
#include <ctime>
#include <functional>
#include <bitset>

#define pb push_back
#define mk make_pair
#define sqr(N) ((N)*(N))
#define F first
#define S second
#define maxn 101010

using namespace std;

typedef long long ll;

const int md = 1e9 + 7;

char d[4][11111];
int i, j, k, n, dp[11111][8][2];

void inc(int *x, int *y){
 *x += *y;
 if(*x >= md) *x-= md;
}

int main(){
#ifndef ONLINE_JUDGE
 freopen("input.txt", "r", stdin);
 freopen("output.txt", "w", stdout);
#endif
  scanf("%d", &n);
  for(i = 1; i <= 3; i++){
    scanf("%*c");
    for(j = 1; j <= n; j++) scanf("%c", &d[i][j]);
  }
  dp[1][0][0] = 1;
  for(i = 1; i <= n; i++)
    for(j = 0; j < 8; j++)
     for(k = 0; k < 2; k++)if(dp[i][j][k]){
       int b1, b2, b3, nx = 0;
       b1 = j & 1;
       b2 = j & 2;
       b3 = j & 4;
       if(d[1][i + 1] != '.')nx |= 1;
       if(d[2][i + 1] != '.')nx |= 2;
       if(d[3][i + 1] != '.')nx |= 4;
       if(!b1 && !b2)
         if((!b3 && d[3][i + 1] == '.')){
           int cc = k;
	   if(d[3][i + 2] == 'O')cc = 1;
	   inc(&dp[i + 1][nx | 4][cc], &dp[i][j][k]);
	 }
	 else if(d[3][i] == 'O')inc(&dp[i + 1][nx][1], &dp[i][j][k]);
	 else if(d[3][i] == 'X' || b3)inc(&dp[i + 1][nx][k], &dp[i][j][k]);
       if(!b2 && !b3)
         if(!b1 && d[1][i + 1] == '.'){
           int cc = k;
           if(d[1][i + 2] == 'O')cc = 1;
           inc(&dp[i + 1][nx | 1][cc], &dp[i][j][k]);
         }
         else if(d[1][i] == 'O')inc(&dp[i + 1][nx][1], &dp[i][j][k]);
         else if(d[1][i] == 'X' || b1)inc(&dp[i + 1][nx][k], &dp[i][j][k]);
       int cc = k;
       if(!b1 && d[1][i + 1] != '.')continue;
       if(!b2 && d[2][i + 1] != '.')continue;
       if(!b3 && d[3][i + 1] != '.')continue;
       if(!b1 && (d[1][i + 2] == 'O' || d[1][i - 1] == 'O'))cc = 1;
       if(!b2 && (d[2][i + 2] == 'O' || d[2][i - 1] == 'O'))cc = 1;
       if(!b3 && (d[3][i + 2] == 'O' || d[3][i - 1] == 'O'))cc = 1;
       inc(&dp[i + 1][j ^ 7 | nx][cc], &dp[i][j][k]);
     }
  printf("%d\n", dp[n + 1][7][1]);
  return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <iomanip>
#include <string>
#include <list>
#include <map>
#include <set>
#include <ctime>
#include <functional>
#include <bitset>

#define pb push_back
#define mk make_pair
#define sqr(N) ((N)*(N))
#define F first
#define S second
#define maxn 101010

using namespace std;

typedef long long ll;

const int md = 1e9 + 7;

char d[4][11111];
int i, j, k, n, dp[11111][8][2];

void inc(int *x, int *y){
 *x += *y;
 if(*x >= md) *x-= md;
}

int main(){
#ifndef ONLINE_JUDGE
 freopen("input.txt", "r", stdin);
 freopen("output.txt", "w", stdout);
#endif
  scanf("%d", &n);
  for(i = 1; i <= 3; i++){
    scanf("%*c");
    for(j = 1; j <= n; j++) scanf("%c", &d[i][j]);
  }
  i = 0;
  if(d[1][1] != '.')i |= 1;
  if(d[2][1] != '.')i |= 2;
  if(d[3][1] != '.')i |= 4;
  dp[1][i][0] = 1;
  for(i = 1; i <= n; i++)
    for(j = 0; j < 8; j++)
     for(k = 0; k < 2; k++)if(dp[i][j][k]){
       int b1, b2, b3, nx = 0;
       b1 = j & 1;
       b2 = j & 2;
       b3 = j & 4;
       if(d[1][i + 1] != '.')nx |= 1;
       if(d[2][i + 1] != '.')nx |= 2;
       if(d[3][i + 1] != '.')nx |= 4;
       if(!b1 && !b2)
         if((!b3 && d[3][i + 1] == '.')){
           int cc = k;
	   if(d[3][i + 2] == 'O')cc = 1;
	   inc(&dp[i + 1][nx | 4][cc], &dp[i][j][k]);
	 }
	 else if(d[3][i] == 'O')inc(&dp[i + 1][nx][1], &dp[i][j][k]);
	 else if(d[3][i] == 'X' || b3)inc(&dp[i + 1][nx][k], &dp[i][j][k]);
       if(!b2 && !b3)
         if(!b1 && d[1][i + 1] == '.'){
           int cc = k;
           if(d[1][i + 2] == 'O')cc = 1;
           inc(&dp[i + 1][nx | 1][cc], &dp[i][j][k]);
         }
         else if(d[1][i] == 'O')inc(&dp[i + 1][nx][1], &dp[i][j][k]);
         else if(d[1][i] == 'X' || b1)inc(&dp[i + 1][nx][k], &dp[i][j][k]);
       int cc = k;
       if(!b1 && d[1][i + 1] != '.')continue;
       if(!b2 && d[2][i + 1] != '.')continue;
       if(!b3 && d[3][i + 1] != '.')continue;
       if(!b1 && (d[1][i + 2] == 'O' || d[1][i - 1] == 'O'))cc = 1;
       if(!b2 && (d[2][i + 2] == 'O' || d[2][i - 1] == 'O'))cc = 1;
       if(!b3 && (d[3][i + 2] == 'O' || d[3][i - 1] == 'O'))cc = 1;
       inc(&dp[i + 1][j ^ 7 | nx][cc], &dp[i][j][k]);
     }
  printf("%d\n", dp[n + 1][7][1]);
  return 0;
}


/* Created Time: 2013年09月13日 星期五 21时38分27秒 */
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
char mark[3][10010];
const int MOD = 1e9+7;
int dp[2][8][2];
int n, cur, nex, val, s, cen;
void add(int &a, int b) {
    a += b;
    if(a >= MOD) a -= MOD;
}
void dfs(int ns, int pos, int ed) {
    if(pos >= 3) {
        add(dp[nex][ns][ed], val);
        return ;
    }
    if(!(s&(1<<pos))) {
        dfs(ns, pos+1, ed);
        if(pos < 2 && !(s&(1<<pos)) && (ns&(1<<(pos+1))) && (ns&(1<<pos))) {
            if(ed == 0) {
                if((pos && mark[pos][cen] == 'O') || (!pos && mark[pos+2][cen] == 'O')) {
                    dfs(ns^(3<<pos), pos+2, 1);
                } else dfs(ns^(3<<pos), pos+2, 0);
            } else {
                dfs(ns^(3<<pos), pos+2, 1);
            }
        }
    }
    else {
        if(ns&(1<<pos)) {
            if(ed == 0) {
                if((cen > 1 && mark[pos][cen-2] == 'O') || (cen < n-1 && mark[pos][cen+1] == 'O')) {
                    dfs(ns^(1<<pos), pos+1, 1);
                } else dfs(ns^(1<<pos), pos+1, 0);
            } else {
                dfs(ns^(1<<pos), pos+1, 1);
            }
        }
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 0; i < 3; i ++) scanf("%s", mark[i]);
    dp[0][0][0] = 1;
    cur = 0, nex = 1;
    for(int i = 0; i < n; i ++) {
        cen = i;
        for(s = 0; s < 8; s ++) {
            int ns = 0;
            for(int j = 0; j < 3; j ++) if(mark[j][i] == '.') ns ^= (1<<j);
            for(int k = 0; k < 2; k ++) if(dp[cur][s][k]) {
                val = dp[cur][s][k];
                dfs(ns, 0, k);
                dp[cur][s][k] = 0;
            }
        }
        cur = nex, nex = !cur;
/*        for(int k = 0; k < 2; k ++) {
            for(int s = 0; s < 8; s ++) {
                printf("%d ", dp[cur][s][k]);
            }
            printf("\n");
        }
        puts("");*/
    }
    printf("%d\n", dp[cur][0][1]);
    return 0;
}


/* Created Time: 2013年09月13日 星期五 21时38分27秒 */
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
char mark[3][10010];
const int MOD = 1e9+7;
int dp[2][8][2];
int n, cur, nex, val, s, cen;
void add(int &a, int b) {
    a += b;
    if(a >= MOD) a -= MOD;
}
void dfs(int ns, int pos, int ed) {
    if(pos >= 3) {
        add(dp[nex][ns][ed], val);
        return ;
    }
    if(!(s&(1<<pos))) {
        dfs(ns, pos+1, ed);
        if(pos < 2 && !(s&(1<<(pos+1))) && (ns&(1<<(pos+1))) && (ns&(1<<pos))) {
            if(ed == 0) {
                if((pos && mark[pos][cen] == 'O') || (!pos && mark[pos+2][cen] == 'O')) {
                    dfs(ns^(3<<pos), pos+2, 1);
                } else dfs(ns^(3<<pos), pos+2, 0);
            } else {
                dfs(ns^(3<<pos), pos+2, 1);
            }
        }
    }
    else {
        if(ns&(1<<pos)) {
            if(ed == 0) {
                if((cen > 1 && mark[pos][cen-2] == 'O') || (cen < n-1 && mark[pos][cen+1] == 'O')) {
                    dfs(ns^(1<<pos), pos+1, 1);
                } else dfs(ns^(1<<pos), pos+1, 0);
            } else {
                dfs(ns^(1<<pos), pos+1, 1);
            }
        }
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 0; i < 3; i ++) scanf("%s", mark[i]);
    dp[0][0][0] = 1;
    cur = 0, nex = 1;
    for(int i = 0; i < n; i ++) {
        cen = i;
        for(s = 0; s < 8; s ++) {
            int ns = 0;
            for(int j = 0; j < 3; j ++) if(mark[j][i] == '.') ns ^= (1<<j);
            for(int k = 0; k < 2; k ++) if(dp[cur][s][k]) {
                val = dp[cur][s][k];
                dfs(ns, 0, k);
                dp[cur][s][k] = 0;
            }
        }
        cur = nex, nex = !cur;
/*        for(int k = 0; k < 2; k ++) {
            for(int s = 0; s < 8; s ++) {
                printf("%d ", dp[cur][s][k]);
            }
            printf("\n");
        }
        puts("");*/
    }
    printf("%d\n", dp[cur][0][1]);
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int Maxn = 1e4 + 10, Mod = 1e9 + 7;
#define L(x) (1 << (x))
int dp[Maxn][L(3)];
char str[3][Maxn];
int n;
int ox, oy;
int dirx[] = {-1, 0, 1, 0};
int diry[] = {0, 1, 0, -1};
bool valid(int x, int y)
{
	return x >= 0 && x < 3 && y >= 1 && y <= n;
}
bool check(int dx, int dy)
{
	for (int i = 1; i <= 2; ++i)
	{
		if (!valid(ox + dx * i, oy + dy * i)) return false;
		if (str[ox + dx * i][oy + dy * i] != '.') return false;
	}
	return true;
}
void update(int dx, int dy)
{
	for (int i = 1; i <= 2; ++i)
	{
		str[ox + dx * i][oy +dy * i] = 'X';
	}
}
void resume(int dx, int dy)
{
	for (int i = 1; i <= 2; ++i)
	{
		str[ox + dx * i][oy + dy *i] = '.';
	}
}
bool check(int col, int s1, int s2)
{
	int s = 0;
	for (int i = 0; i < 3; ++i)
	{
		if (str[i][col] != 'X') s |= L(i);
	}
	if ((s2 | s) != s) return false;
	//if (col == 2) cout <<"asdf" <<s1 << " " << s2 << endl;
	for (int i = 0; i < 3; ++i)
	{
		if ((L(i) & s1) == 0 && str[i][col - 1] == '.' && (L(i) & s2) == 0) return false;
	}
	//if (col == 5) cout <<s1 <<"asdfasdfd" << s2 << endl;
	int c = s2 - (s1 & s2);
	return  (c == 0 || c == 3 || c == 6);
}
int solve()
{
	memset(dp, 0, sizeof(dp));
	dp[0][7] = 1;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 0; j < L(3); ++j)
		{
			if (dp[i - 1][j] == 0) continue;
			for (int k = 0; k < L(3); ++k)
			{
				if (!check(i, j, k)) continue;
			//	cout << i <<" " <<j <<" " <<k <<" ";
				dp[i][k] = (dp[i][k] + dp[i - 1][j]) % Mod;
				//cout <<dp[i][k] <<endl;
			}
		}
	}
	int s = 0;
	for (int i = 0; i < 3; ++i)
	{
		if (str[i][n] == '.') s |= L(i);
	}
	return dp[n][s];
}
int count(int x)
{
	int ret = 0;
	for (int i = 0; L(i) <= x; ++i)
		if (L(i) & x) ret++;
	return ret;
}
int main()
{
	scanf("%d", &n);
	for (int i = 0; i < 3; ++i)
	{
		scanf("%s", str[i] + 1);
		for (int j = 1; j <= n; ++j)
			if (str[i][j] == 'O')
			{
				ox = i, oy = j;
				str[i][j] = 'X';
			}

	}
	int ans = 0;
	for (int s = 1; s < 16; ++s)
	{
		bool ok = 1;
		for (int i = 0; i < 4; ++i)
		{
			if ((s & L(i)) == 0) continue;
			if (!check(dirx[i], diry[i]))
			{
				ok = 0;
				break;

			}
		}
		if (!ok) continue;
		//cout << s << endl;
		for (int i = 0; i < 4; ++i)
		{
			if ((s & L(i)) == 0) continue;
			update(dirx[i], diry[i]);

		}
		if (count(s) % 2 == 1) ans = (ans + solve()) % Mod;
		else ans = (ans - solve() + Mod) % Mod;
		for (int i = 0; i < 4; ++i)
		{
			if ((s & L(i)) == 0) continue;
			resume(dirx[i], diry[i]);
		}
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int Maxn = 1e4 + 10, Mod = 1e9 + 7;
#define L(x) (1 << (x))
int dp[Maxn][L(3)];
char str[3][Maxn];
int n;
int ox, oy;
int dirx[] = {-1, 0, 1, 0};
int diry[] = {0, 1, 0, -1};
bool valid(int x, int y)
{
	return x >= 0 && x < 3 && y >= 1 && y <= n;
}
bool check(int dx, int dy)
{
	for (int i = 1; i <= 2; ++i)
	{
		if (!valid(ox + dx * i, oy + dy * i)) return false;
		if (str[ox + dx * i][oy + dy * i] != '.') return false;
	}
	return true;
}
void update(int dx, int dy)
{
	for (int i = 1; i <= 2; ++i)
	{
		str[ox + dx * i][oy +dy * i] = 'X';
	}
}
void resume(int dx, int dy)
{
	for (int i = 1; i <= 2; ++i)
	{
		str[ox + dx * i][oy + dy *i] = '.';
	}
}
bool check(int col, int s1, int s2)
{
	int s = 0;
	for (int i = 0; i < 3; ++i)
	{
		if (str[i][col] != 'X') s |= L(i);
	}
	if ((s2 | s) != s) return false;
	//if (col == 2) cout <<"asdf" <<s1 << " " << s2 << endl;
	for (int i = 0; i < 3; ++i)
	{
		if ((L(i) & s1) == 0 && str[i][col - 1] == '.' && (L(i) & s2) == 0) return false;
	}
	//if (col == 5) cout <<s1 <<"asdfasdfd" << s2 << endl;
	int c = 0;
	for (int i = 0; i < 3; ++i)
	{
		if ((L(i) & s2) && ((L(i) & s1) != 0 || str[i][col - 1] == 'X')) c |= L(i);
	}
	return  (c == 0 || c == 3 || c == 6);
}
int solve()
{
	memset(dp, 0, sizeof(dp));
	dp[0][7] = 1;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = 0; j < L(3); ++j)
		{
			if (dp[i - 1][j] == 0) continue;
			for (int k = 0; k < L(3); ++k)
			{
				if (!check(i, j, k)) continue;
			//	cout << i <<" " <<j <<" " <<k <<" ";
				dp[i][k] = (dp[i][k] + dp[i - 1][j]) % Mod;
				//cout <<dp[i][k] <<endl;
			}
		}
	}
	int s = 0;
	for (int i = 0; i < 3; ++i)
	{
		if (str[i][n] == '.') s |= L(i);
	}
	return dp[n][s];
}
int count(int x)
{
	int ret = 0;
	for (int i = 0; L(i) <= x; ++i)
		if (L(i) & x) ret++;
	return ret;
}
int main()
{
	scanf("%d", &n);
	for (int i = 0; i < 3; ++i)
	{
		scanf("%s", str[i] + 1);
		for (int j = 1; j <= n; ++j)
			if (str[i][j] == 'O')
			{
				ox = i, oy = j;
				str[i][j] = 'X';
			}

	}
	int ans = 0;
	for (int s = 1; s < 16; ++s)
	{
		bool ok = 1;
		for (int i = 0; i < 4; ++i)
		{
			if ((s & L(i)) == 0) continue;
			if (!check(dirx[i], diry[i]))
			{
				ok = 0;
				break;

			}
		}
		if (!ok) continue;
		//cout << s << endl;
		for (int i = 0; i < 4; ++i)
		{
			if ((s & L(i)) == 0) continue;
			update(dirx[i], diry[i]);

		}
		if (count(s) % 2 == 1) ans = (ans + solve()) % Mod;
		else ans = (ans - solve() + Mod) % Mod;
		for (int i = 0; i < 4; ++i)
		{
			if ((s & L(i)) == 0) continue;
			resume(dirx[i], diry[i]);
		}
	}
	printf("%d\n", ans);
	return 0;
}


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

const int Maxn=1e4+19,Mod=1e9+7;
char Map[3][Maxn];
int Dp[Maxn][8][2],tmp[Maxn];
int n;

inline int is_0(int x,int Dis) {return ((x>>Dis)&1)==0;}
inline int Get_Dp(int x,int now,int Flag)
{
	int &A=Dp[x][now][Flag];
	if (A^-1) return A;A=0;
	if (x==n) return A=(!now&&Flag);
	now|=tmp[x];
	if (now==7) return A=Get_Dp(x+1,0,Flag);
	if (is_0(now,0)&&is_0(now,1)) A+=Get_Dp(x,now|3,Flag||Map[2][x]=='O');
	if (is_0(now,1)&&is_0(now,2)) A+=Get_Dp(x,now|6,Flag||Map[0][x]=='O');
	int can=1,nxt_Flag=0,nxt_now=0;
	for (int i=0;i<3;i++)
	{
		if (is_0(now,i)&&!is_0(tmp[x+1],i)) {can=0;break;}
		if (x&&Map[i][x-1]=='O'||Map[i][x+2]=='O') nxt_Flag=1;
		if (is_0(now,i)) nxt_now|=(1<<i);
	}
	if (can) A+=Get_Dp(x+1,nxt_now,Flag||nxt_Flag);
	A%=Mod;
	return A;
}

int main()
{
	scanf("%d",&n);
	for (int i=0;i<3;i++) scanf("%s",Map[i]);
	for (int i=0;i<n;i++)
	{
		tmp[i]=7;
		for (int j=0;j<3;j++)
			if (Map[j][i]=='.') tmp[i]-=(1<<j);
	}
	memset(Dp,-1,sizeof(Dp));
	printf("%d\n",Get_Dp(0,0,0));
}


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

const int Maxn=1e4+19,Mod=1e9+7;
char Map[3][Maxn];
int Dp[Maxn][8][2],tmp[Maxn];
int n;

inline int is_0(int x,int Dis) {return ((x>>Dis)&1)==0;}
inline int Get_Dp(int x,int now,int Flag)
{
	int &A=Dp[x][now][Flag];
	if (A^-1) return A;A=0;
	if (x==n) return A=(!now&&Flag);
	now|=tmp[x];
	if (now==7) return A=Get_Dp(x+1,0,Flag);
	if (is_0(now,0)&&is_0(now,1)) A=(A+Get_Dp(x,now|3,Flag||Map[2][x]=='O'))%Mod;
	if (is_0(now,1)&&is_0(now,2)) A=(A+Get_Dp(x,now|6,Flag||Map[0][x]=='O'))%Mod;
	int can=1,nxt_Flag=0,nxt_now=0;
	for (int i=0;i<3;i++)
	{
		if (is_0(now,i)&&!is_0(tmp[x+1],i)) {can=0;break;}
		if (x&&Map[i][x-1]=='O'||Map[i][x+2]=='O') nxt_Flag=1;
		if (is_0(now,i)) nxt_now|=(1<<i);
	}
	if (can) A=(A+Get_Dp(x+1,nxt_now,Flag||nxt_Flag))%Mod;
	return A;
}

int main()
{
	scanf("%d",&n);
	for (int i=0;i<3;i++) scanf("%s",Map[i]);
	for (int i=0;i<n;i++)
	{
		tmp[i]=7;
		for (int j=0;j<3;j++)
			if (Map[j][i]=='.') tmp[i]-=(1<<j);
	}
	memset(Dp,-1,sizeof(Dp));
	printf("%d\n",Get_Dp(0,0,0));
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long LL;

const int maxn = 10000, max0 = 1000;

const int Mod = 1e9 + 7;

pair<int, int> f[max0 + 5];

int fn = 0;

int g[maxn + 5][3];

int n;

int xx, yy;

void init()
{
	scanf("%d", &n);
	REP(i, 0, 3)
	{
		scanf("\n");
		REP(j, 0, n)
		{
			static char c;
			scanf("%c", &c);
			g[j][i] = c == 'X' ? 1 : 0;
			if (c == 'O') g[j][i] = 1, xx = j, yy = i;
		}
	}
}

int get(int S, const int &x, const int &y, const int &kind)
{
	if (g[x][y] && kind) return -1;
	if (!g[x][y] && !kind) return -1;
	bool deg[3];
	REP(i, 0, 3) deg[i] = S & 1, S >>= 1;
	if (y == -1)
	{
		REP(i, 0, 3) if (deg[i]) return 0;
		return 1;
	}
	if (kind == 1)
	{
		if (!deg[y]) return -1;
		deg[y] = 0;
	}
	else if (deg[y]) return -1;
	if (kind == 2)
	{
		if (!y || !deg[y - 1]) return -1;
		deg[y - 1] = deg[y] = 0;
	}
	if (kind == 3) deg[y] = 1;
	S = 0;
	for (int i = 2; i >= 0; --i) (S <<= 1) |= deg[i];
	return S;
}

int work()
{
	int ret = 0;
	fn = 0;
	f[fn++] = mp(0, 1);
	REP(i, 0, n)
	{
		REP(j, 0, 3)
		{
			static pair<int, int> ff[max0 + 5];
			int ffn = 0;
			REP(k, 0, fn)
			{
				REP(l, 0, 4)
				{
					int tmp = get(f[k].x, i, j, l);
					if (tmp == -1) continue;
					ff[ffn++] = mp(tmp, f[k].y);
				}
			}
			sort(ff, ff + ffn);
			fn = 0;
			for (int i = 0; i < ffn; )
			{
				f[fn].x = ff[i].x, f[fn].y = 0;
				while (i < ffn && ff[i].x == f[fn].x) (f[fn].y += ff[i++].y) %= Mod;
				++fn;
			}
		}
	}
	REP(k, 0, fn)
		if (get(f[k].x, n, -1, -1)) (ret += f[k].y) %= Mod;
	return ret;
}

int walk[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	init();
	int jcvb = 0;
	static int gg[maxn + 5][3];
	memcpy(gg, g, sizeof gg);
	REP(i, 1, 16)
	{
		int cnt = -1;
		memcpy(g, gg, sizeof g);
		REP(j, 0, 4)
		{
			if ((i >> j) & 1)
			{
				cnt *= -1;
				REP(k, 1, 3)
				{
					int x = xx + walk[j][0] * k, y = yy + walk[j][1] * k;
					if (x < 0 || y < 0 || x >= n || y >= 3 || g[x][y]) goto lyc;
					g[x][y] = 1;
				}
			}
		}
		(jcvb += cnt * work() % Mod) %= Mod;
lyc:;
	}
	(jcvb += Mod) %= Mod;
	printf("%d\n", jcvb);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long LL;

const int maxn = 10000, max0 = 1000;

const int Mod = 1e9 + 7;

pair<int, int> f[max0 + 5];

int fn = 0;

int g[maxn + 5][3];

int n;

int xx, yy;

void init()
{
	scanf("%d", &n);
	REP(i, 0, 3)
	{
		scanf("\n");
		REP(j, 0, n)
		{
			static char c;
			scanf("%c", &c);
			g[j][i] = c == 'X' ? 1 : 0;
			if (c == 'O') g[j][i] = 1, xx = j, yy = i;
		}
	}
}

int get(int S, const int &x, const int &y, const int &kind)
{
	if (g[x][y] && kind > 0) return -1;
	if (!g[x][y] && !kind) return -1;
	bool deg[3];
	REP(i, 0, 3) deg[i] = S & 1, S >>= 1;
	if (kind == -1)
	{
		REP(i, 0, 3) if (deg[i]) return 0;
		return 1;
	}
	if (kind == 1)
	{
		if (!deg[y]) return -1;
		deg[y] = 0;
	}
	else if (deg[y]) return -1;
	if (kind == 2)
	{
		if (!y || !deg[y - 1]) return -1;
		deg[y - 1] = deg[y] = 0;
	}
	if (kind == 3) deg[y] = 1;
	S = 0;
	for (int i = 2; i >= 0; --i) (S <<= 1) |= deg[i];
	return S;
}

int work()
{
	int ret = 0;
	fn = 0;
	f[fn++] = mp(0, 1);
	REP(i, 0, n)
	{
		REP(j, 0, 3)
		{
			static pair<int, int> ff[max0 + 5];
			int ffn = 0;
			REP(k, 0, fn)
			{
				REP(l, 0, 4)
				{
					int tmp = get(f[k].x, i, j, l);
					if (tmp == -1) continue;
					ff[ffn++] = mp(tmp, f[k].y);
				}
			}
			sort(ff, ff + ffn);
			fn = 0;
			for (int i = 0; i < ffn; )
			{
				f[fn].x = ff[i].x, f[fn].y = 0;
				while (i < ffn && ff[i].x == f[fn].x) (f[fn].y += ff[i++].y) %= Mod;
				++fn;
			}
		}
	}
	REP(k, 0, fn)
		if (get(f[k].x, n, -1, -1)) (ret += f[k].y) %= Mod;
	return ret;
}

int walk[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	init();
	int jcvb = 0;
	static int gg[maxn + 5][3];
	memcpy(gg, g, sizeof gg);
	REP(i, 1, 16)
	{
		int cnt = -1;
		memcpy(g, gg, sizeof g);
		REP(j, 0, 4)
		{
			if ((i >> j) & 1)
			{
				cnt *= -1;
				REP(k, 1, 3)
				{
					int x = xx + walk[j][0] * k, y = yy + walk[j][1] * k;
					if (x < 0 || y < 0 || x >= n || y >= 3 || g[x][y]) goto lyc;
					g[x][y] = 1;
				}
			}
		}
		(jcvb += cnt * work() % Mod) %= Mod;
lyc:;
	}
	(jcvb += Mod) %= Mod;
	printf("%d\n", jcvb);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second

using namespace std;

const int maxn = 10000, max0 = 1000;

const int Mod = 1e9 + 7;

pair<int, int> f[max0 + 5];

int fn = 0;

int g[maxn + 5][3];

int n;

int xx, yy;

void init()
{
	scanf("%d", &n);
	REP(i, 0, 3)
	{
		scanf("\n");
		REP(j, 0, n)
		{
			static char c;
			scanf("%c", &c);
			g[j][i] = c == 'X' ? 1 : 0;
			if (c == 'O') g[j][i] = 1, xx = i, yy = j;
		}
	}
}

int get(int S, const int &x, const int &y, const int &kind)
{
	if (g[x][y] && kind) return -1;
	if (!g[x][y] && !kind) return -1;
	bool deg[3];
	REP(i, 0, 3) deg[i] = S & 1, S >>= 1;
	if (y == -1)
	{
		REP(i, 0, 3) if (deg[i]) return 0;
		return 1;
	}
	if (kind == 1)
	{
		if (!deg[y]) return -1;
		deg[y] = 0;
	}
	else if (deg[y]) return -1;
	if (kind == 2)
	{
		if (!y || !deg[y - 1]) return -1;
		deg[y - 1] = deg[y] = 0;
	}
	if (kind == 3) deg[y] = 1;
	S = 0;
	for (int i = 2; i >= 0; --i) (S <<= 1) |= deg[i];
	return S;
}

int work()
{
	int ret = 0;
	fn = 0;
	f[fn++] = mp(0, 1);
	REP(i, 0, n)
	{
		REP(j, 0, 3)
		{
			static pair<int, int> ff[max0 + 5];
			int ffn = 0;
			REP(k, 0, fn)
			{
				REP(l, 0, 4)
				{
					int tmp = get(f[k].x, i, j, l);
					if (tmp == -1) continue;
					ff[ffn++] = mp(tmp, f[k].y);
				}
			}
			sort(ff, ff + ffn);
			fn = 0;
			for (int i = 0; i < ffn; )
			{
				f[fn].x = ff[i].x, f[fn].y = 0;
				while (i < ffn && ff[i].x == f[fn].x) (f[fn].y += ff[i++].y) %= Mod;
				++fn;
			}
		}
	}
	REP(k, 0, fn)
		if (get(f[k].x, n, -1, -1)) (ret += f[k].y) %= Mod;
	return ret;
}

int walk[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	init();
	int jcvb = 0;
	static int gg[maxn + 5][3];
	memcpy(gg, g, sizeof gg);
	REP(i, 1, 16)
	{
		int cnt = -1;
		memcpy(g, gg, sizeof g);
		REP(j, 0, 4)
		{
			if ((i >> j) & 1)
			{
				cnt *= -2;
				REP(k, 1, 3)
				{
					int x = xx + walk[j][0] * k, y = yy + walk[j][1] * k;
					if (x < 0 || y < 0 || x >= n || y >= 3 || g[x][y]) goto lyc;
					g[x][y] = 1;
				}
			}
		}
		cnt >>= 1;
		(jcvb += cnt * work()) %= Mod;
lyc:;
	}
	(jcvb += Mod) %= Mod;
	printf("%d\n", jcvb);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second

using namespace std;

const int maxn = 10000, max0 = 1000;

const int Mod = 1e9 + 7;

pair<int, int> f[max0 + 5];

int fn = 0;

int g[maxn + 5][3];

int n;

int xx, yy;

void init()
{
	scanf("%d", &n);
	REP(i, 0, 3)
	{
		scanf("\n");
		REP(j, 0, n)
		{
			static char c;
			scanf("%c", &c);
			g[j][i] = c == 'X' ? 1 : 0;
			if (c == 'O') g[j][i] = 1, xx = i, yy = j;
		}
	}
}

int get(int S, const int &x, const int &y, const int &kind)
{
	if (g[x][y] && kind) return -1;
	if (!g[x][y] && !kind) return -1;
	bool deg[3];
	REP(i, 0, 3) deg[i] = S & 1, S >>= 1;
	if (y == -1)
	{
		REP(i, 0, 3) if (deg[i]) return 0;
		return 1;
	}
	if (kind == 1)
	{
		if (!deg[y]) return -1;
		deg[y] = 0;
	}
	else if (deg[y]) return -1;
	if (kind == 2)
	{
		if (!y || !deg[y - 1]) return -1;
		deg[y - 1] = deg[y] = 0;
	}
	if (kind == 3) deg[y] = 1;
	S = 0;
	for (int i = 2; i >= 0; --i) (S <<= 1) |= deg[i];
	return S;
}

int work()
{
	int ret = 0;
	fn = 0;
	f[fn++] = mp(0, 1);
	REP(i, 0, n)
	{
		REP(j, 0, 3)
		{
			static pair<int, int> ff[max0 + 5];
			int ffn = 0;
			REP(k, 0, fn)
			{
				REP(l, 0, 4)
				{
					int tmp = get(f[k].x, i, j, l);
					if (tmp == -1) continue;
					ff[ffn++] = mp(tmp, f[k].y);
				}
			}
			sort(ff, ff + ffn);
			fn = 0;
			for (int i = 0; i < ffn; )
			{
				f[fn].x = ff[i].x, f[fn].y = 0;
				while (i < ffn && ff[i].x == f[fn].x) (f[fn].y += ff[i++].y) %= Mod;
				++fn;
			}
		}
	}
	REP(k, 0, fn)
		if (get(f[k].x, n, -1, -1)) (ret += f[k].y) %= Mod;
	return ret;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	init();
	int lyc, ydc, vfk;
	if (yy > 1 && !g[yy - 1][xx] && !g[yy - 2][xx])
	{
		g[yy - 1][xx] = g[yy - 2][xx] = 1;
		lyc = work();
		g[yy - 1][xx] = g[yy - 2][xx] = 0;
	}
	else lyc = 0;
	if (yy < n - 2 && !g[yy + 1][xx] && !g[yy + 2][xx])
	{
		g[yy + 1][xx] = g[yy + 2][xx] = 1;
		ydc = work();
		g[yy + 1][xx] = g[yy + 2][xx] = 0;
	}
	else ydc = 0;
	if ((yy > 1 && !g[yy - 1][xx] && !g[yy - 2][xx]) && (yy < n - 2 && !g[yy + 1][xx] && !g[yy + 2][xx]))
	{
		g[yy - 1][xx] = g[yy - 2][xx] = 1;
		g[yy + 1][xx] = g[yy + 2][xx] = 1;
		vfk = work();
	}
	else vfk = 0;
	debug("%d %d %d\n", lyc, ydc, vfk);
	printf("%d\n", (((lyc + ydc) % Mod - vfk) % Mod + Mod) % Mod);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second

using namespace std;

typedef long long LL;

const int maxn = 10000, max0 = 1000;

const int Mod = 1e9 + 7;

pair<int, int> f[max0 + 5];

int fn = 0;

int g[maxn + 5][3];

int n;

int xx, yy;

void init()
{
	scanf("%d", &n);
	REP(i, 0, 3)
	{
		scanf("\n");
		REP(j, 0, n)
		{
			static char c;
			scanf("%c", &c);
			g[j][i] = c == 'X' ? 1 : 0;
			if (c == 'O') g[j][i] = 1, xx = j, yy = i;
		}
	}
}

int get(int S, const int &x, const int &y, const int &kind)
{
	if (g[x][y] && kind) return -1;
	if (!g[x][y] && !kind) return -1;
	bool deg[3];
	REP(i, 0, 3) deg[i] = S & 1, S >>= 1;
	if (y == -1)
	{
		REP(i, 0, 3) if (deg[i]) return 0;
		return 1;
	}
	if (kind == 1)
	{
		if (!deg[y]) return -1;
		deg[y] = 0;
	}
	else if (deg[y]) return -1;
	if (kind == 2)
	{
		if (!y || !deg[y - 1]) return -1;
		deg[y - 1] = deg[y] = 0;
	}
	if (kind == 3) deg[y] = 1;
	S = 0;
	for (int i = 2; i >= 0; --i) (S <<= 1) |= deg[i];
	return S;
}

int work()
{
	int ret = 0;
	fn = 0;
	f[fn++] = mp(0, 1);
	REP(i, 0, n)
	{
		REP(j, 0, 3)
		{
			static pair<int, int> ff[max0 + 5];
			int ffn = 0;
			REP(k, 0, fn)
			{
				REP(l, 0, 4)
				{
					int tmp = get(f[k].x, i, j, l);
					if (tmp == -1) continue;
					ff[ffn++] = mp(tmp, f[k].y);
				}
			}
			sort(ff, ff + ffn);
			fn = 0;
			for (int i = 0; i < ffn; )
			{
				f[fn].x = ff[i].x, f[fn].y = 0;
				while (i < ffn && ff[i].x == f[fn].x) (f[fn].y += ff[i++].y) %= Mod;
				++fn;
			}
		}
	}
	REP(k, 0, fn)
		if (get(f[k].x, n, -1, -1)) (ret += f[k].y) %= Mod;
	return ret;
}

int walk[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	init();
	int jcvb = 0;
	static int gg[maxn + 5][3];
	memcpy(gg, g, sizeof gg);
	REP(i, 1, 16)
	{
		int cnt = -1;
		memcpy(g, gg, sizeof g);
		REP(j, 0, 4)
		{
			if ((i >> j) & 1)
			{
				cnt *= -2;
				REP(k, 1, 3)
				{
					int x = xx + walk[j][0] * k, y = yy + walk[j][1] * k;
					if (x < 0 || y < 0 || x >= n || y >= 3 || g[x][y]) goto lyc;
					g[x][y] = 1;
				}
			}
		}
		cnt >>= 1;
		(jcvb += (LL)cnt * work() % Mod) %= Mod;
lyc:;
	}
	(jcvb += Mod) %= Mod;
	printf("%d\n", jcvb);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second

using namespace std;

const int maxn = 10000, max0 = 1000;

const int Mod = 1e9 + 7;

pair<int, int> f[max0 + 5];

int fn = 0;

int g[maxn + 5][3];

int n;

int xx, yy;

void init()
{
	scanf("%d", &n);
	REP(i, 0, 3)
	{
		scanf("\n");
		REP(j, 0, n)
		{
			static char c;
			scanf("%c", &c);
			g[j][i] = c == 'X' ? 1 : 0;
			if (c == 'O') g[j][i] = 1, xx = j, yy = i;
		}
	}
}

int get(int S, const int &x, const int &y, const int &kind)
{
	if (g[x][y] && kind) return -1;
	if (!g[x][y] && !kind) return -1;
	bool deg[3];
	REP(i, 0, 3) deg[i] = S & 1, S >>= 1;
	if (y == -1)
	{
		REP(i, 0, 3) if (deg[i]) return 0;
		return 1;
	}
	if (kind == 1)
	{
		if (!deg[y]) return -1;
		deg[y] = 0;
	}
	else if (deg[y]) return -1;
	if (kind == 2)
	{
		if (!y || !deg[y - 1]) return -1;
		deg[y - 1] = deg[y] = 0;
	}
	if (kind == 3) deg[y] = 1;
	S = 0;
	for (int i = 2; i >= 0; --i) (S <<= 1) |= deg[i];
	return S;
}

int work()
{
	int ret = 0;
	fn = 0;
	f[fn++] = mp(0, 1);
	REP(i, 0, n)
	{
		REP(j, 0, 3)
		{
			static pair<int, int> ff[max0 + 5];
			int ffn = 0;
			REP(k, 0, fn)
			{
				REP(l, 0, 4)
				{
					int tmp = get(f[k].x, i, j, l);
					if (tmp == -1) continue;
					ff[ffn++] = mp(tmp, f[k].y);
				}
			}
			sort(ff, ff + ffn);
			fn = 0;
			for (int i = 0; i < ffn; )
			{
				f[fn].x = ff[i].x, f[fn].y = 0;
				while (i < ffn && ff[i].x == f[fn].x) (f[fn].y += ff[i++].y) %= Mod;
				++fn;
			}
		}
	}
	REP(k, 0, fn)
		if (get(f[k].x, n, -1, -1)) (ret += f[k].y) %= Mod;
	return ret;
}

int walk[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	init();
	int jcvb = 0;
	static int gg[maxn + 5][3];
	memcpy(gg, g, sizeof gg);
	REP(i, 1, 16)
	{
		int cnt = -1;
		memcpy(g, gg, sizeof g);
		REP(j, 0, 4)
		{
			if ((i >> j) & 1)
			{
				cnt *= -2;
				REP(k, 1, 3)
				{
					int x = xx + walk[j][0] * k, y = yy + walk[j][1] * k;
					if (x < 0 || y < 0 || x >= n || y >= 3 || g[x][y]) goto lyc;
					g[x][y] = 1;
				}
			}
		}
		cnt >>= 1;
		(jcvb += cnt * work()) %= Mod;
lyc:;
	}
	(jcvb += Mod) %= Mod;
	printf("%d\n", jcvb);
	return 0;
}


#include <iostream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define XINF INT_MAX
#define INF 0x3f3f3f3f
#define MAXN 0x7fffffff
#define eps 1e-10
#define zero(a) fabs(a)<eps
#define sqr(a) ((a)*(a))
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define PF(X) push_front(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
#define PI  acos(-1.0)
#define test puts("OK");
#define lowbit(X) (X&(-X))
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
typedef long long ll;
typedef pair<int,int> PII;
typedef priority_queue<int,vector<int>,greater<int> > PQI;
typedef vector<PII> VII;
typedef vector<int> VI;
#define X first
#define Y second

const ll mod=1000000007LL;

inline void inc(ll &x,ll y)
{
	x+=y;
	if(x>=mod)
		x-=mod;
}

inline void sub(ll &x,ll y)
{
	x-=y;
	if(x<0)
		x+=mod;
}

int n;
bool maps[10010][5];
ll dp[2][8];
ll ans[8];
VI act;
int pi,pj;

inline bool judge(int i,int j)
{
	return 	i>=0 && i<n && j>=0 && j<3 && !maps[i][j];
}

ll solve()
{
	CLR(dp,0);
	ll *crt=dp[0],*next=dp[1];
	crt[0]=1LL;
	for(int i=n-1;i>=0;i--)
	{
		for(int j=2;j>=0;j--)
		{
			for(int used=0;used<8;used++)
			{
				if((used>>j&1) || maps[i][j])
					next[used]=crt[used&~(1<<j)];
				else
				{
					ll res=0LL;
					if(j+1<3 && !(used>>(j+1)&1) && !maps[i][j+1])
						inc(res,crt[used|1<<(j+1)]);
					if(i+1<n && !maps[i+1][j])
						inc(res,crt[used|1<<j]);
					next[used]=res;
				}
			}
			swap(crt,next);
		}
	}
	return crt[0];
}

int d[4][2]={{0,-1},{0,1},{-1,0},{1,0}};

void opt(int i,int k)
{
	maps[pi+d[i][0]][pj+d[i][1]]=k;
	maps[pi+2*d[i][0]][pj+2*d[i][1]]=k;
}

int main()
{_
	//freopen("in.txt","r",stdin);
	while(cin>>n)
	{
		REP(i,3)
			REP(j,n)
			{
				char c;
				cin>>c;
				if(c=='X')
					maps[j][i]=1;
				else if(c=='O')
				{
					pi=j,pj=i;
					maps[j][i]=1;
				}
				else
					maps[j][i]=0;
			}
		act.clear();
		REP(i,4)
			if(judge(pi+d[i][0],pj+d[i][1])&&judge(pi+2*d[i][0],pj+2*d[i][1]))
				act.PB(i);
		int len=act.size();
		ll ans=0LL;
		for(int i=1;i<(1<<len);i++)
		{
			int cnt=0;
			ll temp=0LL;
			for(int j=0;j<len;j++)
			{
				if(i>>j&1)
				{
					opt(act[j],1);
					cnt++;
				}
			}
			inc(temp,solve());
			for(int j=0;j<len;j++)
				if(i>>j&1)
					opt(act[j],0);
			if(cnt&1)
				inc(ans,temp);
			else
				sub(ans,temp);
		}
		cout<<ans<<endl;
	}
	return 0;
}


#include <iostream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <climits>
using namespace std;
#define XINF INT_MAX
#define INF 0x3f3f3f3f
#define MAXN 0x7fffffff
#define eps 1e-10
#define zero(a) fabs(a)<eps
#define sqr(a) ((a)*(a))
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define PF(X) push_front(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
#define PI  acos(-1.0)
#define test puts("OK");
#define lowbit(X) (X&(-X))
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
typedef long long ll;
typedef pair<int,int> PII;
typedef priority_queue<int,vector<int>,greater<int> > PQI;
typedef vector<PII> VII;
typedef vector<int> VI;
#define X first
#define Y second

const ll mod=1000000007LL;

inline void inc(ll &x,ll y)
{
	x+=y;
	if(x>=mod)
		x-=mod;
}

inline void sub(ll &x,ll y)
{
	x-=y;
	if(x<0)
		x+=mod;
}

int n;
bool maps[1010][5];
ll dp[2][8];
ll ans[8];
VI act;
int pi,pj;

inline bool judge(int i,int j)
{
	return 	i>=0 && i<n && j>=0 && j<3 && !maps[i][j];
}

ll solve()
{
	CLR(dp,0);
	ll *crt=dp[0],*next=dp[1];
	crt[0]=1LL;
	for(int i=n-1;i>=0;i--)
	{
		for(int j=2;j>=0;j--)
		{
			for(int used=0;used<8;used++)
			{
				if((used>>j&1) || maps[i][j])
					next[used]=crt[used&~(1<<j)];
				else
				{
					ll res=0LL;
					if(j+1<3 && !(used>>(j+1)&1) && !maps[i][j+1])
						inc(res,crt[used|1<<(j+1)]);
					if(i+1<n && !maps[i+1][j])
						inc(res,crt[used|1<<j]);
					next[used]=res;
				}
			}
			swap(crt,next);
		}
	}
	return crt[0];
}

int d[4][2]={{0,-1},{0,1},{-1,0},{1,0}};

void opt(int i,int k)
{
	maps[pi+d[i][0]][pj+d[i][1]]=k;
	maps[pi+2*d[i][0]][pj+2*d[i][1]]=k;
}

int main()
{_
	//freopen("in.txt","r",stdin);
	while(cin>>n)
	{
		REP(i,3)
			REP(j,n)
			{
				char c;
				cin>>c;
				if(c=='X')
					maps[j][i]=1;
				else if(c=='O')
				{
					pi=j,pj=i;
					maps[j][i]=1;
				}
				else
					maps[j][i]=0;
			}
		act.clear();
		REP(i,4)
			if(judge(pi+d[i][0],pj+d[i][1])&&judge(pi+2*d[i][0],pj+2*d[i][1]))
				act.PB(i);
		int len=act.size();
		ll ans=0LL;
		for(int i=1;i<(1<<len);i++)
		{
			int cnt=0;
			ll temp=0LL;
			for(int j=0;j<len;j++)
			{
				if(i>>j&1)
				{
					opt(act[j],1);
					cnt++;
				}
			}
			inc(temp,solve());
			for(int j=0;j<len;j++)
				if(i>>j&1)
					opt(act[j],0);
			if(cnt&1)
				inc(ans,temp);
			else
				sub(ans,temp);
		}
		cout<<ans<<endl;
	}
	return 0;
}


//Template

// By Anudeep :)
//Includes
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <utility> //Pair
#include <algorithm>
#include <sstream> // istringstream>> ostring stream<<
#include <iostream>
#include <iomanip>
//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (4) << f << endl; Prints x.xxxx
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <limits>
using namespace std;

//M lazy ;)
typedef long long ll;
typedef vector <int> vi;
typedef pair< int ,int > pii;
typedef istringstream iss;
typedef ostringstream oss;
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sz size()
#define ln length()
#define rep(i,n) for(int i=0;i<n;i++)
#define fu(i,a,n) for(int i=a;i<=n;i++)
#define fd(i,n,a) for(int i=n;i>=a;i--)
#define all(a)  a.begin(),a.end()
#define ESP (1e-9)

#define gi(n) scanf("%d",&n)
#define gl(n) cin >> n
#define pi(n) printf("%d",n)
#define pl(n) cout << n
#define ps printf(" ")
#define pn printf("\n")
#define dg(n,s); printf("%s %d",s,n)
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()

#define N 11000
char b[3][N], bb[3][N];
int n;
int dp[N][1<<3];
#define M 1000000007

bool okH(int j, int i) {
    return b[i][j] != 'X' && b[i][j+1] != 'X';
}
bool okV(int j, int i) {
    return b[i][j] != 'X' && b[i+1][j] != 'X';
}
int solve(int i, int mask) {
    if(i==n) return mask==0;
    int &ret = dp[i][mask];
    if(ret != -1) return ret;
    int nmask = mask;
    if(b[0][i]=='X') nmask |= 1;
    if(b[1][i]=='X') nmask |= 2;
    if(b[2][i]=='X') nmask |= 4;
    if(nmask != mask) return ret = solve(i, nmask);
    ll retu = 0;
    //all horiz
    if(mask==7) return ret = solve(i+1, 0);
    if(mask==0) {
        if(okH(i,0) && okH(i,1) && okH(i,2)) retu += solve(i+1, 7);
        if(okH(i,0) && okV(i,1)) retu += solve(i+1, 1);
        if(okH(i,2) && okV(i,0)) retu += solve(i+1, 4);
    } else {
        if(__builtin_popcount(mask)==2) {
            int k = mask ^ 7;
            if(k==1) k =0;
            else if (k==2) k = 1;
            else k = 2;
            if(okH(i,k)) retu += solve(i+1, mask ^ 7);
        } else {
            if(mask != 2 && okV(i, 0 + (mask!=4) ) )retu += solve(i+1, 0);
            int k1,k2;
            k1 = 0; k2 = 1;
            if(mask==1) k1 = 2;
            else if(mask==2) k2 = 2;
            if(okH(i,k1) && okH(i,k2)) retu += solve(i+1, mask ^ 7);
        }
    }
    return ret = (retu%M);
}

int main() {
    gi(n);
    rep(i,3) scanf("%s",b[i]);
    int x,y;
    rep(i,3) rep(j,n) if(b[i][j]=='O') x = i, y = j;
    memcpy(bb, b, sizeof b);
    int ans = 0;
    fu(i,1,(1<<4)-1) {
        memcpy(b, bb, sizeof bb);
        if(i&1) {
            //up
            if(x!=2) continue;
            if(b[0][y] == 'B' || b[1][y] == 'B') continue;
            b[0][y] = b[1][y] = b[2][y] = 'X';
        }
        if(i&2) {
            //down
            if(x!=0) continue;
            if(b[1][y] == 'B' || b[2][y] == 'B') continue;
            b[0][y] = b[1][y] = b[2][y] = 'X';
        }
        if(i&4) {
            //left
            if(y<2) continue;
            if(b[x][y-1]=='B' || b[x][y-2]=='B') continue;
            b[x][y] = b[x][y-1] = b[x][y-2] = 'X';
        }
        if(i&8) {
            //right
            if(y+2 >= n) continue;
            if(b[x][y+1]=='B' || b[x][y+2]=='B') continue;
            b[x][y] = b[x][y+1] = b[x][y+2] = 'X';
        }

        memset(dp, -1, sizeof dp);
        if( __builtin_popcount(i) % 2 ) ans += solve(0,0);
        else ans -= solve(0,0);
        ans = ((ans%M)+M)%M;
    }
    pi(ans); pn;
}


//Template

// By Anudeep :)
//Includes
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <utility> //Pair
#include <algorithm>
#include <sstream> // istringstream>> ostring stream<<
#include <iostream>
#include <iomanip>
//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (4) << f << endl; Prints x.xxxx
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <limits>
using namespace std;

//M lazy ;)
typedef long long ll;
typedef vector <int> vi;
typedef pair< int ,int > pii;
typedef istringstream iss;
typedef ostringstream oss;
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sz size()
#define ln length()
#define rep(i,n) for(int i=0;i<n;i++)
#define fu(i,a,n) for(int i=a;i<=n;i++)
#define fd(i,n,a) for(int i=n;i>=a;i--)
#define all(a)  a.begin(),a.end()
#define ESP (1e-9)

#define gi(n) scanf("%d",&n)
#define gl(n) cin >> n
#define pi(n) printf("%d",n)
#define pl(n) cout << n
#define ps printf(" ")
#define pn printf("\n")
#define dg(n,s); printf("%s %d",s,n)
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()

#define N 11000
char b[3][N], bb[3][N];
int n;
int dp[N][1<<3];
#define M 1000000007

bool okH(int j, int i) {
    return b[i][j] != 'X' && b[i][j+1] != 'X';
}
bool okV(int j, int i) {
    return b[i][j] != 'X' && b[i+1][j] != 'X';
}
int solve(int i, int mask) {
    if(i==n) return mask==0;
    int &ret = dp[i][mask];
    if(ret != -1) return ret;
    int nmask = mask;
    if(b[0][i]=='X') nmask |= 1;
    if(b[1][i]=='X') nmask |= 2;
    if(b[2][i]=='X') nmask |= 4;
    if(nmask != mask) return ret = solve(i, nmask);
    ll retu = 0;
    //all horiz
    if(mask==7) return ret = solve(i+1, 0);
    if(mask==0) {
        if(okH(i,0) && okH(i,1) && okH(i,2)) retu += solve(i+1, 7);
        if(okH(i,0) && okV(i,1)) retu += solve(i+1, 1);
        if(okH(i,2) && okV(i,0)) retu += solve(i+1, 4);
    } else {
        if(__builtin_popcount(mask)==2) {
            int k = mask ^ 7;
            if(k==1) k =0;
            else if (k==2) k = 1;
            else k = 2;
            if(okH(i,k)) retu += solve(i+1, mask ^ 7);
        } else {
            if(mask != 2 && okV(i, 0 + (mask!=4) ) )retu += solve(i+1, 0);
            int k1,k2;
            k1 = 0; k2 = 1;
            if(mask==1) k1 = 2;
            else if(mask==2) k2 = 2;
            if(okH(i,k1) && okH(i,k2)) retu += solve(i+1, mask ^ 7);
        }
    }
    return ret = (retu%M);
}

int main() {
    gi(n);
    rep(i,3) scanf("%s",b[i]);
    int x,y;
    rep(i,3) rep(j,n) if(b[i][j]=='O') x = i, y = j;
    memcpy(bb, b, sizeof b);
    int ans = 0;
    fu(i,1,(1<<4)-1) {
        memcpy(b, bb, sizeof bb);
        if(i&1) {
            //up
            if(x!=2) continue;
            if(b[0][y] == 'X' || b[1][y] == 'X') continue;
            b[0][y] = b[1][y] = b[2][y] = 'X';
        }
        if(i&2) {
            //down
            if(x!=0) continue;
            if(b[1][y] == 'X' || b[2][y] == 'X') continue;
            b[0][y] = b[1][y] = b[2][y] = 'X';
        }
        if(i&4) {
            //left
            if(y<2) continue;
            if(b[x][y-1]=='X' || b[x][y-2]=='X') continue;
            b[x][y] = b[x][y-1] = b[x][y-2] = 'X';
        }
        if(i&8) {
            //right
            if(y+2 >= n) continue;
            if(b[x][y+1]=='X' || b[x][y+2]=='X') continue;
            b[x][y] = b[x][y+1] = b[x][y+2] = 'X';
        }

        memset(dp, -1, sizeof dp);
        if( __builtin_popcount(i) % 2 ) ans += solve(0,0);
        else ans -= solve(0,0);
        ans = ((ans%M)+M)%M;
    }
    pi(ans); pn;
}


#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)) == 0){
            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;
                a[i][j] = 'X';
            }
        }
    }
    //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;
}