#include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) begin(v), end(v)
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for(int i = (int)(s); i < (int)(n); i++)

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

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

struct Point {
  int x, y;
  Point(int x = 0, int y = 0):x(x), y(y){}
  Point operator + (Point p) { return Point(x+p.x, y+p.y); }
  Point operator - (Point p) { return Point(x-p.x, y-p.y); }
  Point operator * (int k) { return Point(k*x, k*y); }
};

int abs(Point p) {
  return llabs(p.x) + llabs(p.y);
}
int dist(Point a, Point b) {
  return abs(a-b);
}
int cross(Point a, Point b) {
  return a.x*b.y - a.y*b.x;
}
bool izryt(Point a, Point b) {
  return cross(a, b) < 0;
}

struct edge {
  int to, cost;
  edge(){}
  edge(int to, int cost):to(to), cost(cost){}
};

int m, n;
vector<Point> ps;
vector<string> name;
map<string, int> id;
string s, t;
vector< vector<edge> > graph;

void init() {
  ps.clear();
  ps.resize(m);
  name.clear();
  name.resize(m);
  id.clear();
  graph.clear();
  graph.resize(m);
}

struct State {
  int cur, prev, dist, pass;
  State(){}
  State(int cur, int prev, int dist, int pass)
    :cur(cur), prev(prev), dist(dist), pass(pass){}
  bool operator < (const State& s) const {
    if(dist != s.dist) return dist > s.dist;
    if(pass != s.pass) return pass > s.pass;
    return cur > s.cur;
  }
};

int mindist[1001][1001];
int minpass[1001][1001];

int dijkstra() {
  int si = id[s], ti = id[t];
  priority_queue<State> que;
  fill(mindist[0], mindist[1001], inf);
  fill(minpass[0], minpass[1001], inf);
  for(edge e : graph[si]) {
    mindist[e.to][si] = e.cost;
    minpass[e.to][si] = 2;
    que.push(State(e.to, si, e.cost, 2));
  }
  while(!que.empty()) {
    State s = que.top(); que.pop();
    int cur = s.cur, prev = s.prev;
    if(mindist[cur][prev] < s.dist) continue;
    if(minpass[cur][prev] < s.pass) continue;
    if(cur == ti) return minpass[cur][prev];
    for(edge e : graph[cur]) {
      if(e.to == prev) continue;
      Point a = ps[cur] - ps[prev];
      Point b = ps[e.to] - ps[cur];
      if(izryt(a, b)) continue;
      if(mindist[e.to][cur] < mindist[cur][prev]+e.cost) continue;
      if(mindist[e.to][cur] == mindist[cur][prev]+e.cost &&
	 minpass[e.to][cur] <= minpass[cur][prev]+1) continue;
      mindist[e.to][cur] = mindist[cur][prev]+e.cost;
      minpass[e.to][cur] = minpass[cur][prev]+1;
      que.push(State(e.to, cur, mindist[e.to][cur], minpass[e.to][cur]));
    }
  }

  return -1;
}

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while(cin >> m >> n, m || n) {
    init();
    rep(i, m) {
      cin >> name[i] >> ps[i].x >> ps[i].y;
      id[name[i]] = i;
    }
    rep(i, n) {
      string p, q;
      cin >> p >> q;
      int pi = id[p], qi = id[q];
      graph[pi].emplace_back(qi, dist(ps[pi], ps[qi]));
      graph[qi].emplace_back(pi, dist(ps[pi], ps[qi]));
    }
    cin >> s >> t;
    int ans = dijkstra();
    if(ans == -1) cout << "impossible" << endl;
    else cout << ans << endl;
  }

  return 0;
}

Measured memory_bytes: 19192