#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cassert>
#include<map>
#include<set>
using namespace std;
#define rep(i, n) for ( int i = 0; i < n; i++ )
#define INF (1<<21)
#define MAX 104

int n, m;
bool V[MAX][MAX];
int T[MAX][MAX];
int F[MAX][MAX];
int face;

vector<int> G[MAX];
pair<int, int> P[MAX];

vector<vector<pair<int, int> > > R; // room;

double angle(int s, int t){
  return atan2(P[t].second - P[s].second, P[t].first - P[s].first);
}

void parse(int s, int t, bool isouter, int f){
  if ( V[s][t] || s == t ) return;
  int cur1 = s, cur2 = t;

  vector<pair<int, int> > room;

  while(1){
    if ( V[cur1][cur2] ) break;
    V[cur1][cur2] = true;
    F[cur1][cur2] = f;
    room.push_back(make_pair(cur1, cur2));
    int nx;
    rep(i, G[cur2].size() ){
      if ( G[cur2][i] == cur1 ){ nx = i; break; } // next node after counter-clock
    }
    nx = (nx+1)%G[cur2].size();
    cur1 = cur2;
    cur2 = G[cur2][nx];
  }
  R.push_back(room);
}

bool isConnected(vector<pair<int, int> > &c1, vector<pair<int, int> > &c2){
  for ( int i = 0; i < c1.size(); i++ ){
    for ( int j = 0; j < c2.size(); j++ ){
      pair<int, int> p1 = c1[i];
      pair<int, int> p2 = c2[j];
      if ( p1 == p2 ) return true;
      swap(p2.first, p2.second);
      if ( p1 == p2 ) return true;
    }
  }
  return false;
}

vector<vector<int> > makeGraph(){
  R.clear();

  // sort by angle
  rep(s, n) {
    for ( int e = G[s].size()-2; e >= 0; e--)
      for ( int j = 0; j <= e; j++ )
	if ( angle(s, G[s][j]) > angle(s, G[s][j+1]) ) swap(G[s][j], G[s][j+1]);
  }

  rep(i, n) rep(j, n) V[i][j] = false;

  int bottom = 0;
  rep(i, n){
    if ( P[i].second == P[bottom].second ){
      if ( P[i].first < P[bottom].first ) bottom = i;
    } else {
      if ( P[i].second < P[bottom].second ) bottom = i;
    }
  }

  face = 0;
  rep(i, n) rep(j, n) F[i][j] = -1;

  parse(bottom, G[bottom][0], true, face); // the outer

  rep(s, n)  rep(j, G[s].size()){
    int t =  G[s][j];
    parse(s, t, false, ++face);
  }

  rep(i, n) rep(j, n) {
    if ( F[i][j] == -1 ){
      assert( F[j][i] == -1);
      continue;
    }
    assert( F[i][j] != F[j][i] );
  }


  vector<vector<int> > g;
  g.resize(R.size());
  for ( int i = 0; i < R.size()-1; i++ ){
    for ( int j = i+1; j < R.size(); j++ ){
      if ( isConnected(R[i], R[j])) {
	g[i].push_back(j);
	g[j].push_back(i);
      }
    }
  }

  assert( n - m + R.size() == 2 );

  return g;
}

int bfs(vector<vector<int> > g){
  vector<int> d;
  d.resize(g.size());
  rep(i, g.size()) d[i] = INF;
  queue<int> Q;
  int u, v;
  for ( d[0] = 0, Q.push(0); !Q.empty(); ){
    u = Q.front(); Q.pop();
    for ( int i = 0; i < g[u].size(); i++ ){
      int v = g[u][i];
      if ( d[v] != INF ) continue;
      d[v] = d[u] + 1;
      Q.push(v);
    }
  }
  int maxv = 0;
  for ( int i = 0; i < d.size(); i++) maxv = max(maxv, d[i]);
  return maxv;
}

main(){
  while(1){
    cin >> n >> m;
    if ( n == 0 ) break;
    assert( 3 <= n && n <= 100 );
    assert( n <= m && m <= 300 );
    set<pair<int, int> > S;
    rep(i, n) {
      cin >> P[i].first >> P[i].second;
      S.insert( P[i]) ;
    }
    assert( S.size() == n );
    rep(i, n) G[i].clear();
    map<pair<int, int>, bool> vis;
    rep(i, m){
      int s, t;
      cin >> s >> t;
      s--; t--;
      G[s].push_back(t);
      G[t].push_back(s);
      T[s][t] = T[t][s] = (i+1); // 0 = outer

      assert( !vis[make_pair(min(s, t), max(s,t))]);
      vis[make_pair(min(s, t), max(s,t))] = true;
    }
    for ( int i = 0; i < n; i++ ){
      assert( G[i].size() >= 2 );
    }
    cout << bfs(makeGraph()) << endl;
  }
}

Measured memory_bytes: 1404