#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <vector>
#include <valarray>
#include <array>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <complex>
#include <random>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;

typedef double R;
typedef complex<R> P;

const R EPS = 1e-9;
const R PI = acos((R)(-1));

int sgn(R a) {
    if (a < -EPS) return -1;
    if (a > EPS) return 1;
    return 0;
}

R cross(P a, P b) { return a.real()*b.imag() - a.imag()*b.real(); }

typedef vector<P> Pol;

P cu(const Pol &p, int i) {
    int s = p.size();
    return p[(i%s+s)%s];
}

R area_naive(const Pol &p) {
    R u = 0;
    for (int i = 0; i < (int)p.size(); i++) {
        u += cross(cu(p, i), cu(p, i+1));
    }
    return u/2;
}

R area(const Pol &p) {
    return abs(area_naive(p));
}

/*
 -1 -> clock
 0 -> non polygon
 1 -> counter clock
 */
int iscclock(const Pol &p) {
    return sgn(area_naive(p));
}

int dualGraph(P p[], vector<int> g[], int n,
    Pol pol[], vector<int> rg[]) {
    map<pair<int, int>, int> mp;
    for (int i = 0; i < n; i++) {
        sort(g[i].begin(), g[i].end(), [&](int l, int r){
            return arg(p[l]-p[i]) > arg(p[r]-p[i]);
        });
        for (int j = 0; j < (int)g[i].size(); j++) {
            mp[make_pair(i, g[i][j])] = j;
        }
    }

    vector<vector<int>> idx(n), rev(n);
    for (int i = 0; i < n; i++) {
        idx[i] = vector<int>(g[i].size(), -1);
        rev[i].resize(g[i].size());
        for (int j = 0; j < (int)g[i].size(); j++) {
            rev[i][j] = mp[make_pair(g[i][j], i)];
        }
    }

    int idc = 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < (int)g[i].size(); j++) {
            if (idx[i][j] != -1) continue;
            Pol po;
            int ii = i, jj = j;
            while (idx[ii][jj] != -2) {
                po.push_back(p[ii]);
                idx[ii][jj] = -2;
                int ni = g[ii][jj];
                int nj = (rev[ii][jj]+1) % g[ni].size();
                ii = ni; jj = nj;
            }
            int id;
            if (iscclock(po) != 1) {
                id = 0;
            } else {
                id = idc;
                pol[idc] = po;
                idc++;
            }
            while (idx[ii][jj] == -2) {
                idx[ii][jj] = id;
                int ni = g[ii][jj];
                int nj = (rev[ii][jj]+1) % g[ni].size();
                ii = ni; jj = nj;
            }
        }
    }

    for (int i = 0; i < idc; i++) {
        rg[i].clear();
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < (int)g[i].size(); j++) {
            if (idx[i][j] < 0) continue;
            rg[idx[i][j]].push_back(idx[g[i][j]][rev[i][j]]);
        }
    }

    for (int i = 0; i < n; i++) {
        sort(rg[i].begin(), rg[i].end());
        rg[i].erase(unique(rg[i].begin(), rg[i].end()), rg[i].end());
    }

    return idc;
}

const int MN = 110;


P p[MN];
vector<int> g[MN];

Pol pol[2*MN];
vector<int> rg[2*MN];

int dist[2*MN][2*MN];

bool solve() {
    int c, w;
    cin >> c >> w;
    if (!c) return false;

    for (int i = 0; i < c; i++) {
        R x, y;
        cin >> x >> y;
        p[i] = P(x, y);
        g[i].clear();
    }

    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);
    }

    dualGraph(p, g, c, pol, rg);
    int ma = 0;
    bool used[2*MN] = {};
    queue<pair<int, int>> q;
    q.push(make_pair(0, 0));
    while (q.size()) {
        int t, di;
        tie(t, di) = q.front(); q.pop();
        if (used[t]) continue;
        used[t] = true;
        ma = max(ma, di);
        for (int d: rg[t]) {
            if (used[d]) continue;
            q.push(make_pair(d, di+1));
        }
    }
    cout << ma << endl;
    return true;
}


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

Measured memory_bytes: 1384