Twin Trees Bros.

To meet the demand of ICPC (International Cacao Plantation Consortium), you have to check whether two given trees are twins or not.

<image>
Example of two trees in the three-dimensional space.

The term tree in the graph theory means a connected graph where the number of edges is one less than the number of nodes. ICPC, in addition, gives three-dimensional grid points as the locations of the tree nodes. Their definition of two trees being twins is that, there exists a geometric transformation function which gives a one-to-one mapping of all the nodes of one tree to the nodes of the other such that for each edge of one tree, there exists an edge in the other tree connecting the corresponding nodes. The geometric transformation should be a combination of the following transformations:

* translations, in which coordinate values are added with some constants,
* uniform scaling with positive scale factors, in which all three coordinate values are multiplied by the same positive constant, and
* rotations of any amounts around either $x$-, $y$-, and $z$-axes.



Note that two trees can be twins in more than one way, that is, with different correspondences of nodes.

Write a program that decides whether two trees are twins or not and outputs the number of different node correspondences.

Hereinafter, transformations will be described in the right-handed $xyz$-coordinate system.

Trees in the sample inputs 1 through 4 are shown in the following figures. The numbers in the figures are the node numbers defined below.

<image>

For the sample input 1, each node of the red tree is mapped to the corresponding node of the blue tree by the transformation that translates $(-3, 0, 0)$, rotates $-\pi / 2$ around the $z$-axis, rotates $\pi / 4$ around the $x$-axis, and finally scales by $\sqrt{2}$. By this mapping, nodes #1, #2, and #3 of the red tree at $(0, 0, 0)$, $(1, 0, 0)$, and $(3, 0, 0)$ correspond to nodes #6, #5, and #4 of the blue tree at $(0, 3, 3)$, $(0, 2, 2)$, and $(0, 0, 0)$, respectively. This is the only possible correspondence of the twin trees.

For the sample input 2, red nodes #1, #2, #3, and #4 can be mapped to blue nodes #6, #5, #7, and #8. Another node correspondence exists that maps nodes #1, #2, #3, and #4 to #6, #5, #8, and #7.

For the sample input 3, the two trees are not twins. There exist transformations that map nodes of one tree to distinct nodes of the other, but the edge connections do not agree.

For the sample input 4, there is no transformation that maps nodes of one tree to those of the other.



Input

The input consists of a single test case of the following format.


$n$
$x_1$ $y_1$ $z_1$
.
.
.
$x_n$ $y_n$ $z_n$
$u_1$ $v_1$
.
.
.
$u_{n−1}$ $v_{n−1}$
$x_{n+1}$ $y_{n+1}$ $z_{n+1}$
.
.
.
$x_{2n}$ $y_{2n}$ $z_{2n}$
$u_n$ $v_n$
.
.
.
$u_{2n−2}$ $v_{2n−2}$


The input describes two trees. The first line contains an integer $n$ representing the number of nodes of each tree ($3 \leq n \leq 200$). Descriptions of two trees follow.

Description of a tree consists of $n$ lines that give the vertex positions and $n - 1$ lines that show the connection relation of the vertices.

Nodes are numbered $1$ through $n$ for the first tree, and $n + 1$ through $2n$ for the second tree.

The triplet $(x_i, y_i, z_i)$ gives the coordinates of the node numbered $i$. $x_i$, $y_i$, and $z_i$ are integers in the range between $-1000$ and $1000$, inclusive. Nodes of a single tree have distinct coordinates.

The pair of integers $(u_j , v_j )$ means that an edge exists between nodes numbered $u_j$ and $v_j$ ($u_j \ne v_j$). $1 \leq u_j \leq n$ and $1 \leq v_j \leq n$ hold for $1 \leq j \leq n - 1$, and $n + 1 \leq u_j \leq 2n$ and $n + 1 \leq v_j \leq 2n$ hold for $n \leq j \leq 2n - 2$.

Output

Output the number of different node correspondences if two trees are twins. Output a zero, otherwise.

Sample Input 1


3
0 0 0
1 0 0
3 0 0
1 2
2 3
0 0 0
0 2 2
0 3 3
4 5
5 6


Sample Output 1


1


Sample Input 2


4
1 0 0
2 0 0
2 1 0
2 -1 0
1 2
2 3
2 4
0 1 1
0 0 0
0 2 0
0 0 2
5 6
5 7
5 8


Sample Output 2


2


Example

Input

3
0 0 0
1 0 0
3 0 0
1 2
2 3
0 0 0
0 2 2
0 3 3
4 5
5 6


Output

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

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

template<class t>
t sq(t x){
	return x*x;
}


using ld=long double;
const ld eps=1e-10;
int sgn(ld a){return a<-eps?-1:(a>eps?1:0);}

struct pos{
	ld x,y,z;
	ld length(){
		return sqrt(length2());
	}
	ld length2(){
		return sq(x)+sq(y)+sq(z);
	}
	pos operator-(pos r)const{
		return {x-r.x,y-r.y,z-r.z};
	}
	bool operator<(pos r)const{
		return make_tuple(sgn(x-r.x),sgn(y-r.y),sgn(z-r.z))<make_tuple(0,0,0);
	}
	bool operator==(pos r)const{
		return make_tuple(sgn(x-r.x),sgn(y-r.y),sgn(z-r.z))==make_tuple(0,0,0);
	}
	pos operator/(ld r)const{
		return pos{x/r,y/r,z/r};
	}
};

ostream& operator<<(ostream& os,pos p){
	return os<<"{"<<p.x<<","<<p.y<<","<<p.z<<"}";
}

ld dot(pos a,pos b){
	return a.x*b.x+a.y*b.y+a.z*b.z;
}

pos cross(pos a,pos b){
	return {
		a.z*b.y-a.y*b.z,
		a.x*b.z-a.z*b.x,
		a.y*b.x-a.x*b.y,
	};
}

bool collinear(pos a,pos b,pos c){
	return sgn(cross(b-a,c-a).length2())==0;
}

struct ysp{
	vc<pos> ps;
	vc<pi> es;
	bool col;
	int n;
	void init(int nn,int k){
		n=nn;
		rep(i,n){
			ld x,y,z;cin>>x>>y>>z;
			ps.pb(pos{x,y,z});
		}
		rep(_,n-1){
			int a,b;cin>>a>>b;
			a--;b--;
			a-=k*n;
			b-=k*n;
			es.eb(a,b);
			es.eb(b,a);
		}
		col=true;
		rep(i,es.size())rep(j,es.size())if(i!=j){
			if(es[i].a==es[j].a){
				dmp(es[i]);
				dmp(es[j]);
				if(!collinear(ps[es[i].a],ps[es[i].b],ps[es[j].b])){
					col=false;
					break;
				}
			}
		}
	}
	pair<vc<pos>,vc<pi>> waf(int r,int s,int t){
		pos rs=ps[s]-ps[r];
		ld len=rs.length();
		rs=rs/len;
		pos rt=(ps[t]-ps[r])/len;
		pos nr=cross(rs,rt);
		dmp(nr);
		vc<pos> z;
		rep(i,n){
			pos w=(ps[i]-ps[r])/len;
			z.pb(pos{dot(rs,w),dot(rt,w),dot(nr,w)});
		}
		vc<pos> srt=z;
		sort(all(srt));
		vc<pi> tmp;
		for(auto e:es){
			if(e.a<e.b){
				int a=lower_bound(all(srt),z[e.a])-srt.bg;
				int b=lower_bound(all(srt),z[e.b])-srt.bg;
				if(a>b)swap(a,b);
				tmp.eb(a,b);
			}
		}
		sort(all(tmp));
		dmp(r);
		dmp(s);
		dmp(t);
		dmp(srt);
		dmp(tmp);
		return {srt,tmp};
	}
	pair<vc<pos>,vc<pi>> getone(){
		rep(i,es.size())rep(j,es.size())if(i!=j){
			if(es[i].a==es[j].a){
				if(col||!collinear(ps[es[i].a],ps[es[i].b],ps[es[j].b])){
					dmp(es[i].a);
					dmp(es[i].b);
					dmp(es[j].b);
					return waf(es[i].a,es[i].b,es[j].b);
				}
			}
		}
	}
	int enumcheck(pair<vc<pos>,vc<pi>> tar){
		int ans=0;
		rep(i,es.size())rep(j,es.size())if(i!=j){
			if(es[i].a==es[j].a){
				if(col||!collinear(ps[es[i].a],ps[es[i].b],ps[es[j].b])){
					auto cur=waf(es[i].a,es[i].b,es[j].b);
					if(cur==tar)
						ans++;
				}
			}
		}
		return ans;
	}
};

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	
	int n;cin>>n;
	ysp y[2];
	rep(k,2)
		y[k].init(n,k);
	
	int ans=0;
	if(y[0].col!=y[1].col){
	}else{
		auto base=y[0].getone();
		dmp(base);
		ans=y[1].enumcheck(base);
	}
	cout<<ans<<endl;
}

