#include<bits/stdc++.h>
using namespace std;
#define INF (1<<20)
typedef pair<double,int> P;
 
/* 平面幾何の基本要素 */
#define EPS (1e-10)
#define equals(a,b) (fabs((a) - (b)) < EPS )
  
class Point { // 点を表すクラス
  public:
  double x,y;
    
  Point(double x=0,double 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 * (double a) { return Point(a * x, a * y); }
  Point operator / (double a) { return Point(x / a, y / a); }
  
  double abs() { return sqrt(norm()); }
  double norm() { return x * x + y * y; }
    
  bool operator < (const Point &p) const {
    return x != p.x ? x < p.x : y < p.y;
  }
  
  bool operator == (const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
};
  
typedef Point Vector; // ベクトルを表す構造体
  
struct Segment { // 線分を表す構造体
  Point p1,p2;
};
  
typedef Segment Line; // 直線を表す構造体
  
class Circle { // 円を表すクラス
public:
  Point c;
  double r;
  Circle(Point c = Point(), double r = 0.0): c(c),r(r) {}
};
typedef vector < Point > Polygon; // 多角形
 
Point post[111];
vector<P> wall[111];
int wall_id[333][111];
int C,W;
int s[333],c[333];
bool used[333][111];
int out_i,out_v;
int out;
vector<int> area[333];
vector<int> edge[333];
int dis[1000];
 
void make_node(int i,int v,int node_num){
  vector<int> ret;
  int sp = i;
  used[sp][v] = true;
  ret.push_back(sp);
  if(i==out_i&&v==out_v) out=node_num;
  while(1){
    i = wall[v][(wall_id[i][v]+1)%wall[v].size()].second;
    if(s[i]==v) v = c[i];
    else v = s[i];
    if(i==sp) break;
    used[i][v] = true;
    ret.push_back(i);
    if(i==out_i&&v==out_v) out=node_num;
  }
  for(int i=0;i<ret.size();i++) area[ret[i]].push_back(node_num);
}
 
void bfs(int n,int s){
  for(int i=0;i<n;i++){
    dis[i] = -1;
  }
  dis[s] = 0;
  queue<int> que;
  que.push(s);
  while(!que.empty()){
    int v = que.front();
    que.pop();
    for(int i=0;i<edge[v].size();i++){
      if(dis[edge[v][i]] == -1){
    que.push(edge[v][i]);
    dis[edge[v][i]] = dis[v]+1;
      }
    }
  }
}
 
int main(){
  while(cin >> C >> W , C){
    for(int i=0;i<111;i++) wall[i].clear();
    for(int i=0;i<333;i++){
      area[i].clear();
      edge[i].clear();
    }
    memset(wall_id,-1,sizeof(wall_id));
    int lp = 0;
    for(int i=0;i<C;i++){
      cin >> post[i].x >> post[i].y;
      if(post[i].x<post[lp].x) lp = i;
    }
    for(int i=0;i<W;i++){
      cin >> s[i] >> c[i];
      s[i]--; c[i]--;
      double dx = post[c[i]].x-post[s[i]].x;
      double dy = post[c[i]].y-post[s[i]].y;
      wall[s[i]].push_back(P(atan2(dy,dx),i));
      wall[c[i]].push_back(P(atan2(-dy,-dx),i));
    }
    for(int i=0;i<C;i++) sort(wall[i].begin(),wall[i].end());
    int bt=0;
    for(int i=0;i<C;i++){
      for(int j=0;j<wall[i].size();j++){
    wall_id[wall[i][j].second][i]=j;
    if(i==lp){
      int u,v;
      if(s[wall[i][j].second]==lp) u = c[wall[i][j].second];
      else u = s[wall[i][j].second];
      if(s[wall[i][bt].second]==lp) v = c[wall[i][bt].second];
      else v = s[wall[i][j].second];
      double tmp1 = atan2(post[u].y-post[i].y,post[u].x-post[i].x);
      double tmp2 = atan2(post[v].y-post[i].y,post[v].x-post[i].x);
      if(tmp1>tmp2) bt = j;
    }
      }
    }
    out_i = wall[lp][bt].second;
    out_v = lp;
    for(int i=0;i<W;i++){
      for(int j=0;j<C;j++){
    used[i][j] = false;
      }
    }
    int node_cnt=0;
    for(int i=0;i<W;i++){
      if(used[i][s[i]]==false){
    make_node(i,s[i],node_cnt);
    node_cnt++;
      }
      if(used[i][c[i]]==false){
    make_node(i,c[i],node_cnt);
    node_cnt++;
      }
    }
    for(int i=0;i<W;i++){
      edge[area[i][0]].push_back(area[i][1]);
      edge[area[i][1]].push_back(area[i][0]);
    }
    bfs(node_cnt,out);
    int ans = 0;
    for(int i=0;i<node_cnt;i++) ans=max(ans,dis[i]);
    cout << ans << endl;
  }
}

Measured memory_bytes: 3584