#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n==0) ? 1 : 10*TEN(n-1); }
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;

template<class T> ostream& operator<<(ostream& os, const V<T> &v) {
    cout << "[";
    for (auto p: v) cout << p << ", ";
    cout << "]";
    return os;
}

template<class T>
struct Pt2 {
    T x, y;
    Pt2() {}
    Pt2(T _x, T _y) : x(_x), y(_y) {}
    Pt2 operator+(const Pt2 &r) const { return Pt2(x+r.x, y+r.y); }
    Pt2 operator-(const Pt2 &r) const { return Pt2(x-r.x, y-r.y); }

    Pt2 operator-() const { return Pt2(-x, -y); }

    T abs() const { return sqrt(x*x + y*y); }
    T rabs() const { return max(x, y); } // robust abs
    T arg() const { return atan2(y, x); }
};
template<class T> ostream& operator<<(ostream& os, const Pt2<T> &p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os;
}

using D = double;
using P = Pt2<D>;

const D PI = acos(D(-1)), EPS = 1e-10;

int sgn(D a) {
    if (abs(a) <= EPS) return 0;
    return (a < 0) ? -1 : 1;
}
//relative sign
int rsgn(D a, D f) {
    if (abs(a) <= f*EPS) return 0;
    return (a < 0) ? -1 : 1;
}
bool near(P a, P b) { return !sgn((a-b).abs()); }

bool lessP(P l, P r) {
    if (sgn(r.x-l.x)) return l.x < r.x;
    if (sgn(r.y-l.y)) return l.y < r.y;
    return false;
}

D cross(P a, P b) { return a.x*b.y - a.y*b.x; }
D dot(P a, P b) { return a.x*b.x + a.y*b.y; }

// -2, -1, 0, 1, 2 : front, clock, on, cclock, back
int ccw(P b, P c) {
    int s = rsgn(cross(b, c), b.rabs());
    if (s) return s;
    if (!sgn(c.rabs()) || !sgn((c-b).rabs())) return 0;
    if (dot(b, c) < 0) return 2;
    if (dot(-b, c-b) < 0) return -2;
    return 0;
}
int ccw(P a, P b, P c) { return ccw(b-a, c-a); }

struct L {
    P s, t;
    L() {}
    L(P s, P t) : s(s), t(t) {}
    P vec() const { return t-s; }
    D abs() const { return vec().abs(); }
    D arg() const { return vec().arg(); }
};
int ccw(L l, P p) { return ccw(l.s, l.t, p); }

using Pol = V<P>;

//cycle at
const P& c_at(const Pol &pol, int i) {
    int n = int(pol.size());
    assert(0 <= i && i < 2*n);
    return pol[(i < n) ? i : i-n];
}

D area2_noabs(const Pol &p) {
    D u = 0;
    for (size_t i = 0; i < p.size(); i++) {
        u += cross(p[i], c_at(p, i+1));
    }
    return u;
}

// -1: cw, 0: line, 1: ccw
int is_ccw(const Pol &p) {
    return sgn(area2_noabs(p));
}

// 0: outside, 1: on line, 2: inside
int contains(const Pol &pol, P p) {
    int in = -1;
    for (int i = 0; i < int(pol.size()); i++) {
        P a = pol[i], b = c_at(pol, i+1);
        if (ccw(a, b, p) == 0) return 1;
        if (a.y > b.y) swap(a, b);
        if (a.y <= p.y && p.y < b.y && cross(a-p, b-p) < 0) in *= -1;
    }
    return in+1;
}


/*
 双対グラフを作成
 pol, rgの要素は2*n-4個確保しておくこと
 gはめちゃくちゃに破壊される
 もし連結でないグラフ、しかも内包があるグラフに行うとrgは0が複数混入する
 0は、その連結成分だけに注目したときの外側の意味。本当に外側か判定したいなら
 contains等を使用すること
 */
struct DualGraph {
    V<Pol> pols;
    VV<int> g;
};
DualGraph dualGraph(V<P> ps, VV<int> g) {
    assert(ps.size() == g.size());
    int n = int(ps.size());
    using Pi = pair<int, int>;
    map<Pi, int> mp;
    for (int i = 0; i < n; i++) {
        sort(g[i].begin(), g[i].end());
        assert(unique(g[i].begin(), g[i].end()) == g[i].end());
        sort(g[i].begin(), g[i].end(), [&](int l, int r){
            return (ps[l]-ps[i]).arg() > (ps[r]-ps[i]).arg();
        });
        for (int j = 0; j < int(g[i].size()); j++) {
            mp[Pi(i, g[i][j])] = j;
        }
    }

    VV<int> vis(n), rev(n);
    for (int i = 0; i < n; i++) {
        vis[i] = V<int>(g[i].size(), -3);
        for (int d: g[i]) {
            rev[i].push_back(mp[Pi(d, i)]);
        }
    }

    V<Pol> pols;
    int idc = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < int(g[i].size()); j++) {
            if (vis[i][j] != -3) continue;
            Pol pol;
            int p = i, idx = j;
            while (vis[p][idx] != -2) {
                pol.push_back(ps[p]);
                vis[p][idx] = -2;
                int np = g[p][idx];
                int nidx = rev[p][idx]+1;
                if (nidx == int(g[np].size())) nidx = 0;

                p = np; idx = nidx;
            }
            int id = -1;
            if (is_ccw(pol) == 1) {
                id = idc;
                pols.push_back(pol);
                idc++;
            }
//            cout << "FIND " << id << " " << is_ccw(pol) << " " << pol << endl;
            while (vis[p][idx] == -2) {
                vis[p][idx] = id;
                int np = g[p][idx];
                int nidx = rev[p][idx]+1;
                if (nidx == int(g[np].size())) nidx = 0;

                p = np; idx = nidx;
            }
        }
    }
    VV<int> g2(idc+1);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < int(g[i].size()); j++) {
            int x = vis[i][j], y = vis[g[i][j]][rev[i][j]];
            if (x == -1) x = idc;
            if (y == -1) y = idc;
            g2[x].push_back(y);
        }
    }
    for (int i = 0; i <= idc; i++) {
        sort(begin(g2[i]), end(g2[i]));
        g2[i].erase(unique(begin(g2[i]), end(g2[i])), end(g2[i]));
    }

    return DualGraph{pols, g2};
}

bool solve() {
    int c, w;
    cin >> c >> w;
    if (!c) return false;
    
    V<P> p(c);
    for (int i = 0; i < c; i++) {
        D x, y;
        cin >> x >> y;
        p[i] = P(x, y);
    }
    
    VV<int> g(c);
    for (int i = 0; i < w; i++) {
        int s, t;
        cin >> s >> t; s--; t--;
        g[s].push_back(t);
        g[t].push_back(s);
    }

    auto dg = dualGraph(p, g);
    int n = int(dg.g.size());

    // cout << "DEBUG: " << endl;
    // cout << n << endl;
    // for (int i = 0; i < n-1; i++) {
    //     for (P p: dg.pols[i]) {
    //         cout << p << ", ";
    //     } cout << endl;
    // }
    V<int> dist(n, TEN(9));

    queue<int> q;
    dist[n-1] = 0;
    q.push(n-1);
    while (q.size()) {
        int p = q.front(); q.pop();
        for (int d: dg.g[p]) {
            if (dist[d] <= dist[p] + 1) continue;
            dist[d] = dist[p] + 1;
            q.push(d);
        }
    }
    int ma = -1;
    for (int i = 0; i < n; i++) ma = max(ma, dist[i]);
    cout << ma << endl;
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << setprecision(20);

    while (solve()) {}
    return 0;
}



Measured memory_bytes: 3584