/*
02:08 - 
 */

#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<unordered_map>
#include<queue>
#include<climits>
#include<cassert>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define MAX 2000
#define pow2(a) ((a)*(a))
#define EPS 1e-7
#define equals(a,b) (fabs((a)-(b)) < EPS)

using namespace std;

struct Point{
  double x,y;
  Point(double x=IINF,double y=IINF):x(x),y(y){}
  Point operator - (const Point& a)const { return {x-a.x,y-a.y}; }
};

struct Edge{
  int from,to;
  double dist;
  Edge(int from=IINF,int to=IINF,double dist=IINF):from(from),to(to),dist(dist){}
};

struct Data{
  int pre,cur,cost;
  double dist;
  Data(int pre=IINF,int cur=IINF,int cost=IINF,double dist=IINF):pre(pre),cur(cur),cost(cost),dist(dist){}
  bool operator < (const Data& a) const {
    if(equals(dist,a.dist))return cost > a.cost;
    return dist > a.dist;
  }
};

inline double getDist(Point a,Point b){ return sqrt(pow2(a.x-b.x)+pow2(a.y-b.y)); }
inline double cross(Point a,Point b){ return a.x*b.y-a.y*b.x; }


vector<Edge> G[MAX];
vector<Point> ps;
double mindist[MAX][MAX];//mindist[pre_node][cur_node] 
int    mincost[MAX][MAX];
int E,V,sp,gp;

bool cmp(const Edge& a,const Edge& b){
  Point A = ps[a.to]-ps[a.from], B = ps[b.to]-ps[b.from];
  return atan2(A.y,A.x) < atan2(B.y,B.x);
}

void compute(){

  rep(i,V)rep(j,V){
    mindist[i][j] = IINF;
    mincost[i][j] = IINF;
  }
  priority_queue<Data> Q;
  rep(i,G[sp].size()){
    mindist[sp][G[sp][i].to] = G[sp][i].dist;
    mincost[sp][G[sp][i].to] = 2;
    Q.push(Data(sp,G[sp][i].to,2,G[sp][i].dist));
  }

  while(!Q.empty()){
    Data data = Q.top(); Q.pop();
    Point cp = ps[data.cur];
    Point pp = ps[data.pre];
    //cout << "cur | (" << data.pre << "," << data.cur << "," << data.cost << "," << data.dist << ")" << endl;
    if(data.cur == gp){
      cout << data.cost << endl;
      return;
    }

    rep(i,G[data.cur].size()){
      //cout << "cand " << G[data.cur][i].to << endl;
      //if(G[data.cur][i].from == data.cur && G[data.cur][i].to == data.pre){
      //int next = (i+(int)G[data.cur].size()-1)%(int)G[data.cur].size();
      int next = i;
	Point np = ps[G[data.cur][next].to];
	//if(equals(pp.x,np.x) || equals(pp.y,np.y))continue;
	//cout << "cand is ok" << endl;
	if(G[data.cur][next].to == data.pre)continue;
	//cout << G[data.cur][next].to << "here" << endl;
	if(cross(cp-pp,np-pp) < -EPS)continue;
	//cout << "ok" << endl;
	double dist = G[data.cur][next].dist;
	if(equals(mindist[data.cur][next],data.dist+dist)){
	  if(mincost[data.cur][G[data.cur][next].to] > data.cost+1){
	    //cout << "go next " << data.cur << " to " << G[data.cur][next].to << endl;
	    mincost[data.cur][G[data.cur][next].to] = data.cost+1;
	    Q.push(Data(data.cur,G[data.cur][next].to,data.cost+1,data.dist+dist));
	  }
	} else if(mindist[data.cur][G[data.cur][next].to] > data.dist+dist){
	  //cout << "go next " << data.cur << " to " << G[data.cur][next].to << endl;
	  mindist[data.cur][G[data.cur][next].to] = data.dist + dist;
	  mincost[data.cur][G[data.cur][next].to] = data.cost + 1;
	  Q.push(Data(data.cur,G[data.cur][next].to,data.cost+1,data.dist+dist));
	}
	//}
    }
  }

  cout << "impossible" << endl;

}

int main(){
  while(cin >> V >> E,V|E){
    unordered_map<string,int> getIndex;
    int x,y;
    string name,p,q;
    ps.clear();
    rep(i,V)G[i].clear();

    rep(i,V){
      cin >> name >> x >> y;
      getIndex[name] = (int)ps.size();
      ps.push_back(Point(x,y));
    }
    assert(getIndex.size() == ps.size());

    rep(i,E){
      cin >> p >> q;
      int node1 = getIndex[p], node2 = getIndex[q];
      G[node1].push_back(Edge(node1,node2,getDist(ps[node1],ps[node2])));
      G[node2].push_back(Edge(node2,node1,getDist(ps[node1],ps[node2])));
    }

    cin >> p >> q;
    sp = getIndex[p], gp = getIndex[q];

    rep(i,V)sort(G[i].begin(),G[i].end(),cmp);


    /*
    cout << "------------" << endl;
    rep(i,V){
      cout << i << " node---" << endl;
      rep(j,G[i].size()){
	cout << "(" << G[i][j].from << "," << G[i][j].to << "," << G[i][j].dist << ") ";
      }
      cout << endl;
    }
    cout << "goto Compute" << endl << endl;
    */
    compute();

  }
  return 0;
}

Measured memory_bytes: 28144