Problem: Taro got a driver’s license with a great effort in his campus days, but unfortunately there had been no opportunities for him to drive. He ended up obtaining a gold license.

One day, he and his friends made a plan to go on a trip to Kyoto with you. At the end of their meeting, they agreed to go around by car, but there was a big problem; none of his friends was able to drive a car. Thus he had no choice but to become the driver.

The day of our departure has come. He is going to drive but would never turn to the right for fear of crossing an opposite lane (note that cars keep left in Japan). Furthermore, he cannot U-turn for the lack of his technique. The car is equipped with a car navigation system, but the system cannot search for a route without right turns. So he asked to you: “I hate right turns, so, could you write a program to find the shortest left-turn-only route to the destination, using the road map taken from this navigation system?”



Input

The input consists of multiple data sets. The first line of the input contains the number of data sets. Each data set is described in the format below:


m n
name1 x1 y1
...
namem xm ym
p1 q1
...
pn qn
src dst


m is the number of intersections. n is the number of roads. namei is the name of the i-th intersection. (xi, yi) are the integer coordinates of the i-th intersection, where the positive x goes to the east, and the positive y goes to the north. pj and qj are the intersection names that represent the endpoints of the j-th road. All roads are bidirectional and either vertical or horizontal. src and dst are the names of the source and destination intersections, respectively.

You may assume all of the followings:

* 2 ≤ m ≤ 1000, 0 ≤ xi ≤ 10000, and 0 ≤ yi ≤ 10000;
* each intersection name is a sequence of one or more alphabetical characters at most 25 character long;
* no intersections share the same coordinates;
* no pair of roads have common points other than their endpoints;
* no road has intersections in the middle;
* no pair of intersections has more than one road;
* Taro can start the car in any direction; and
* the source and destination intersections are different.



Note that there may be a case that an intersection is connected to less than three roads in the input data; the rode map may not include smaller roads which are not appropriate for the non-local people. In such a case, you still have to consider them as intersections when you go them through.

Output

For each data set, print how many times at least Taro needs to pass intersections when he drive the route of the shortest distance without right turns. The source and destination intersections must be considered as “passed” (thus should be counted) when Taro starts from the source or arrives at the destination. Also note that there may be more than one shortest route possible.

Print “impossible” if there is no route to the destination without right turns.

Example

Input

2 1
KarasumaKitaoji 0 6150
KarasumaNanajo 0 0
KarasumaNanajo KarasumaKitaoji
KarasumaKitaoji KarasumaNanajo
3 2
KujoOmiya 0 0
KujoAburanokoji 400 0
OmiyaNanajo 0 1150
KujoOmiya KujoAburanokoji
KujoOmiya OmiyaNanajo
KujoAburanokoji OmiyaNanajo
10 12
KarasumaGojo 745 0
HorikawaShijo 0 870
ShijoKarasuma 745 870
ShijoKawaramachi 1645 870
HorikawaOike 0 1700
KarasumaOike 745 1700
KawaramachiOike 1645 1700
KawabataOike 1945 1700
KarasumaMarutamachi 745 2445
KawaramachiMarutamachi 1645 2445
KarasumaGojo ShijoKarasuma
HorikawaShijo ShijoKarasuma
ShijoKarasuma ShijoKawaramachi
HorikawaShijo HorikawaOike
ShijoKarasuma KarasumaOike
ShijoKawaramachi KawaramachiOike
HorikawaOike KarasumaOike
KarasumaOike KawaramachiOike
KawaramachiOike KawabataOike
KarasumaOike KarasumaMarutamachi
KawaramachiOike KawaramachiMarutamachi
KarasumaMarutamachi KawaramachiMarutamachi
KarasumaGojo KawabataOike
8 9
NishikojiNanajo 0 0
NishiojiNanajo 750 0
NishikojiGojo 0 800
NishiojiGojo 750 800
HorikawaGojo 2550 800
NishiojiShijo 750 1700
Enmachi 750 3250
HorikawaMarutamachi 2550 3250
NishikojiNanajo NishiojiNanajo
NishikojiNanajo NishikojiGojo
NishiojiNanajo NishiojiGojo
NishikojiGojo NishiojiGojo
NishiojiGojo HorikawaGojo
NishiojiGojo NishiojiShijo
HorikawaGojo HorikawaMarutamachi
NishiojiShijo Enmachi
Enmachi HorikawaMarutamachi
HorikawaGojo NishiojiShijo
0 0


Output

2
impossible
13
4

Solution (in CPP):

Solution:
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum DIR{
	North,
	East,
	South,
	West,
};

struct Info{
	char name[26];
	int x,y;
};

struct Data{
	Data(int arg_to,DIR arg_dir){
		to = arg_to;
		dir = arg_dir;
	}
	int to;
	DIR dir;
};

struct State{
	State(){
		node_id = sum_dist = num_cross_point = 0;
		dir = North;
	}
	State(int arg_node_id,int arg_sum_dist,int arg_num_cross_point,DIR arg_dir){
		node_id = arg_node_id;
		sum_dist = arg_sum_dist;
		num_cross_point = arg_num_cross_point;
		dir = arg_dir;
	}
	bool operator<(const struct State &arg)const{
		return sum_dist > arg.sum_dist;
	}
	int node_id,sum_dist,num_cross_point;
	DIR dir;
};

int M,N;
int min_dist[1000][4],min_cross[1000][4];
Info info[1000];
char buf1[26],buf2[26];
vector<Data> G[1000];


int calc(int node_left,int node_right){
	return abs(info[node_left].x-info[node_right].x)+abs(info[node_left].y-info[node_right].y);
}

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}


void func(){

	for(int i = 0; i < M; i++){
		G[i].clear();
	}

	for(int i = 0; i < M; i++){
		scanf("%s %d %d",info[i].name,&info[i].x,&info[i].y);
	}

	int left_index,right_index;
	for(int loop = 0; loop < N; loop++){
		scanf("%s %s",buf1,buf2);

		for(int i = 0; i < M; i++){
			if(strCmp(info[i].name,buf1)){
				left_index = i;
				break;
			}
		}

		for(int i = 0; i < M; i++){
			if(strCmp(info[i].name,buf2)){
				right_index = i;
				break;
			}
		}

		if(info[left_index].x == info[right_index].x){
			if(info[left_index].y > info[right_index].y){
				G[left_index].push_back(Data(right_index,South));
				G[right_index].push_back(Data(left_index,North));
			}else{
				G[left_index].push_back(Data(right_index,North));
				G[right_index].push_back(Data(left_index,South));
			}
		}else{
			if(info[left_index].x > info[right_index].x){
				G[left_index].push_back(Data(right_index,West));
				G[right_index].push_back(Data(left_index,East));
			}else{
				G[left_index].push_back(Data(right_index,East));
				G[right_index].push_back(Data(left_index,West));
			}
		}
	}

	int start,goal;
	scanf("%s %s",buf1,buf2);
	for(int i = 0; i < M; i++){
		if(strCmp(info[i].name,buf1)){
			start = i;
			break;
		}
	}

	for(int i = 0; i < M; i++){
		if(strCmp(info[i].name,buf2)){
			goal = i;
			break;
		}
	}

	for(int i = 0; i < M; i++){
		for(int k = 0; k < 4; k++){
			min_dist[i][k] = BIG_NUM;
			min_cross[i][k] = BIG_NUM;
		}
	}

	for(int i = 0; i < 4; i++){
		min_dist[start][i] = 0;
		min_cross[start][i] = 1;
	}

	priority_queue<State> Q;
	for(int i = 0; i < G[start].size(); i++){
		min_dist[G[start][i].to][G[start][i].dir] = calc(start,G[start][i].to);
		min_cross[G[start][i].to][G[start][i].dir] = 2;
		Q.push(State(G[start][i].to,min_dist[G[start][i].to][G[start][i].dir],2,G[start][i].dir));
	}

	int next_node,next_dist;
	DIR next_dir;

	while(!Q.empty()){

		if(Q.top().node_id == goal){
			Q.pop();
		}else if((Q.top().sum_dist > min_dist[Q.top().node_id][Q.top().dir]) ||
				(Q.top().sum_dist == min_dist[Q.top().node_id][Q.top().dir] && Q.top().num_cross_point > min_cross[Q.top().node_id][Q.top().dir])){
			Q.pop();
		}else{

			for(int i = 0; i < G[Q.top().node_id].size(); i++){

				if(Q.top().dir == North){
					if(G[Q.top().node_id][i].dir != North && G[Q.top().node_id][i].dir != West)continue;
				}else if(Q.top().dir == West){
					if(G[Q.top().node_id][i].dir != West && G[Q.top().node_id][i].dir != South)continue;
				}else if(Q.top().dir == South){
					if(G[Q.top().node_id][i].dir != South && G[Q.top().node_id][i].dir != East)continue;
				}else{ //Q.top().dir == East
					if(G[Q.top().node_id][i].dir != East && G[Q.top().node_id][i].dir != North)continue;
				}
				next_node= G[Q.top().node_id][i].to;
				next_dist = Q.top().sum_dist+calc(Q.top().node_id,next_node);
				next_dir = G[Q.top().node_id][i].dir;

				if(min_dist[next_node][next_dir] > next_dist){
					min_dist[next_node][next_dir] = next_dist;
					min_cross[next_node][next_dir] = Q.top().num_cross_point+1;
					Q.push(State(next_node,next_dist,Q.top().num_cross_point+1,next_dir));
				}else if(min_dist[next_node][next_dir] == next_dist && min_cross[next_node][next_dir] > Q.top().num_cross_point+1){
					min_cross[next_node][next_dir] = Q.top().num_cross_point+1;
					Q.push(State(next_node,next_dist,Q.top().num_cross_point+1,next_dir));
				}
			}
			Q.pop();
		}
	}

	int final_dist = BIG_NUM,final_cross = BIG_NUM;

	for(int i = 0; i < 4; i++){
		if(min_dist[goal][i] != BIG_NUM){
			if(final_dist > min_dist[goal][i]){
				final_dist = min_dist[goal][i];
				final_cross = min_cross[goal][i];
			}else if(final_dist == min_dist[goal][i]){
				final_cross = min(final_cross,min_cross[goal][i]);
			}
		}
	}

	if(final_dist != BIG_NUM){
		printf("%d\n",final_cross);
	}else{
		printf("impossible\n");
	}

}

int main(){

	while(true){
		scanf("%d %d",&M,&N);
		if(M == 0 && N == 0)break;

		func();
	}

	return 0;
}