#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;
}

Measured memory_bytes: 3308