#include <iostream>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <cstdlib>
using namespace std;

const double EPS = 1e-10;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : VP{
    L(const P& a, const P& b){ resize(2); at(0)=a; at(1)=b; }
    L(){ resize(2); }
};

namespace std{
    bool operator < (const P &a, const P &b){
        return !EQ(a.X, b.X)? a.X<b.X : a.Y<b.Y;
    }
    bool operator == (const P &a, const P &b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) <-EPS) return -1; //cw
    if(dot(b,c) < EPS) return +2; //c-a-b
    if(norm(b) < norm(c)) return -2; //a-b-c
    return 0; //a-c-b
}

P projection(const L& l, const P& p) {
  double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
  return l[0] + t*(l[0]-l[1]);
}

P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B /A *(m[1]-m[0]);
}

double getangle(const P &p, const P &a, const P &b){ //clockwise
    P proj = projection(L(p,a), b);
    int minus = (dot(a-p, b-p)>=0)? 1 :-1;
    if(ccw(p,a,b)!=1){
        return atan2(abs(b-proj), minus*abs(p-proj));
    }else{
        return 2*M_PI - atan2(abs(b-proj), minus*abs(p-proj));
    }
}
double getarea(const VP &p) {
	double ret = 0;
	for (int i=0; i<(int)p.size(); i++){ 
		ret += cross(p[i], p[(i+1)%p.size()]);
	}
	return ret*0.5;
}

int leftmostpoint(int &pidx, int &cidx, vector<int> &vec, VP &plist){
	P prev = plist[pidx];
	P curr = plist[cidx];
	int nextidx = -1;
	double minangle = INF;
	for(int i=0; i<(int)vec.size(); i++){
		if(vec[i]==pidx) continue;
		double angle = getangle(curr, prev, plist[vec[i]]);
		if(angle < minangle){
			minangle = angle;
			nextidx = i;
		}
	}
	pidx = cidx;
	cidx = vec[nextidx];
	return nextidx;
}

vector<vector<int> > makeDualGraph(vector<vector<int> > &adj, VP &plist, int &out){
    map<pair<int,int>, int> edgelist;
    vector<vector<int> > poly;
    vector<vector<bool> > used(adj.size());
    for(int i=0; i<(int)adj.size(); i++){
        used[i] = vector<bool>(adj[i].size(), false);
    }
    
    int numarea=0;
    for(int i=0; i<(int)adj.size(); i++){
    	for(int j=0; j<(int)adj[i].size(); j++){
    		if(used[i][j]) continue;
    		used[i][j] = true;
    		numarea++;
    		vector<int> border;
    		VP vlist;
    		border.push_back(i);
    		vlist.push_back(plist[i]);
    		int prev = i;
    		int curr = adj[i][j];
    		while(curr!=i){
    			border.push_back(curr);
    			vlist.push_back(plist[curr]);
    			int idx = leftmostpoint(prev, curr, adj[curr], plist);
    			used[prev][idx] = true;
    		}
    		poly.push_back(border);
    		if(getarea(vlist) < 0) out = numarea-1;
    	}
    }
    
    vector<vector<int> > dual(numarea);
    for(int i=0; i<numarea; i++){
    	for(int j=0; j<(int)poly[i].size(); j++){
    		int a = poly[i][j];
    		int b = poly[i][(j+1)%(int)poly[i].size()];
    		pair<int,int> key = make_pair(min(a,b), max(a,b));
    		if(edgelist.count(key) == 0){
    			edgelist[key] = i;
    		}else{
    			dual[i].push_back(edgelist[key]);
    			dual[edgelist[key]].push_back(i);
    		}
    	}
    }
    
    for(int i=0; i<(int)dual.size(); i++){
        sort(dual[i].begin(), dual[i].end());
        dual[i].erase(unique(dual[i].begin(), dual[i].end()), dual[i].end());
    }
    return dual;
}

int main(){
	while(1){
		int c,w;
		cin >> c >> w;
		if(c==0) break;
		
		VP bar(c);
		for(int i=0; i<c; i++){
			int x,y;
			cin >> x >> y;
			bar[i] = P(x,y);
		}
		
		vector<vector<int> > adj(c);
		for(int i=0; i<w; i++){
			int s,t;
			cin >> s >> t;
			s--; t--;
			adj[s].push_back(t);
			adj[t].push_back(s);
		}
		int out;
		vector<vector<int> > dual = makeDualGraph(adj, bar, out);
		
		int numarea = dual.size();
		set<int> reach;
		reach.insert(out);
		int ans = 0;
		while(1){
			if((int)reach.size() == numarea) break;
			set<int> newreach;
			for(set<int>::iterator itr=reach.begin(); itr!=reach.end(); itr++){
				newreach.insert(*itr);
				for(int i=0; i<(int)dual[*itr].size(); i++){
					newreach.insert(dual[*itr][i]);
				}
			}
			reach = newreach;
			ans++;
		}
		cout << ans << endl;
	}
    return 0;
}

Measured memory_bytes: 3352