Language: C++

#include <bits/stdc++.h>

#define M_PI (3.141592653589793)

using namespace std;

const double EPS = 1e-10;

class Point{
public:
    double x, y;
    int id;
    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(x * a, y * a);}
    Point operator / (double a){return Point(x / a, y / a);}
    Point operator * (const Point &a){
        return Point(x * a.x - y * a.y, x * a.y + y * a.x);
    }
    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;
typedef vector<Point> Polygon;

double dot(Vector a, Vector b){return (a.x * b.x + a.y * b.y);}
double abs(Vector a){return (sqrt(dot(a, a)));}
double cross(Vector a, Vector b){return (a.x * b.y - a.y * b.x);}

int ccw(Point p0, Point p1, Point p2)
{
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if (cross(a, b) > EPS) return (+1); //p0, p1, p2 が反時計周り
    if (cross(a, b) < -EPS) return (-1);//p0, p1, p2 が時計回り
    if (dot(a, b) < -EPS) return (+2); //p2--p0--p1 の順で一直線上
    if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
    
    return (0); //p0--p2--p1 の順で一直線上
}

Polygon conhel(Polygon& ps)
{
    sort(ps.begin(), ps.end());
    int k = 0, n = (int)ps.size();
    Polygon qs(n * 2);
    
    for (int i = 0; i < n; i++){
        while (k > 1 && cross(qs[k - 1] - qs[k - 2], ps[i] - qs[k - 1]) < -EPS) k--;
        qs[k++] = ps[i];
    }
    
    for (int i = n - 2, t = k; i >= 0; i--){
        while (k > t && cross(qs[k - 1] - qs[k - 2], ps[i] - qs[k - 1]) < -EPS) k--;
        qs[k++] = ps[i];
    }
    
    qs.resize(k - 1);
    return (qs);
}

double getCos(Vector a, Vector b)
{
    return (dot(a, b) / (abs(a) * abs(b)));
}

double getArg(Vector v)
{
    return (atan2(v.y, v.x));
}
 
Point rotate(Point t, Point p, double r)
{
    double ta = cos(r) * (t.x - p.x) - sin(r) * (t.y - p.y) + p.x;
    double tb = sin(r) * (t.x - p.x) + cos(r) * (t.y - p.y) + p.y;
    return (Point(ta, tb));
}
 
int main()
{
    int N, M;
    
    while (scanf("%d %d", &N, &M) && N){
        vector<Point> P(N);
        vector<int> to[128];
        bool exist[128][128] = {0};
        
        for (int i = 0; i < N; i++){
            scanf("%lf %lf", &P[i].x, &P[i].y);
            P[i].id = i;
        }
        
        for (int i = 0; i < M; i++){
            int x, y;
            scanf("%d %d", &x, &y);
            to[--x].push_back(--y);
            to[y].push_back(x);
            exist[x][y] = exist[y][x] = 1;
        }
        
        Polygon Q = P;
        Q = conhel(Q);
        
        vector<int> belong[128][128];
        for (int i = 0; i < Q.size(); i++){
            int u = Q[i].id, v = Q[(i + 1) % Q.size()].id;
            belong[u][v].push_back(0);
            belong[v][u].push_back(0);
        }
        int k = 1;
        set<vector<int> > s;
        
        for (int i = 0; i < N; i++){
            for (int j = 0; j < N; j++){
                if (P[j] < P[i] && exist[i][j] && belong[i][j].size() < 2){
                    vector<int> v;
                    v.push_back(i);
                    v.push_back(j);
                    
                    while (1){
                        int nextP = -1;
                        int vv = v[v.size() - 1], uu = v[v.size() - 2];
                        for (int l = 0; l < to[vv].size(); l++){
                            if (to[vv][l] == vv || to[vv][l] == uu) continue;
                            double thetaT, thetaC;
                            thetaT = acos(getCos(P[uu] - P[vv], P[to[vv][l]] - P[vv]));
                            if (ccw(P[uu], P[vv], P[to[vv][l]]) > 0) thetaT = 2 * M_PI - thetaT;
                            if (nextP != -1){
                                thetaC = acos(getCos(P[uu] - P[vv], P[nextP] - P[vv]));
                                if (ccw(P[uu], P[vv], P[nextP]) > 0) thetaC = 2 * M_PI - thetaC;
                            }
                            if (nextP == -1 || thetaT < thetaC) nextP = to[vv][l];
                            
                        }
                        if (nextP == i) break;
                        v.push_back(nextP);
                    }
                    vector<int> ss = v;
                    sort(ss.begin(), ss.end());
                    ss.erase(unique(ss.begin(), ss.end()), ss.end());
                    if (s.find(ss) != s.end()) continue;
                    else s.insert(ss);
                    for (int it = 0; it < v.size(); it++){
                        int uu = v[it], vv = v[(it + 1) % v.size()];
                        belong[uu][vv].push_back(k);
                        belong[vv][uu].push_back(k);
                    }
                    k++;
                }
            }
        }
        
        vector<int> G[1024];
        
        for (int i = 0; i < N; i++){
            for (int j = i + 1; j < N; j++){
                if (belong[i][j].size()){
                    assert(belong[i][j].size() == 2);
                    int u = belong[i][j][0], v = belong[i][j][1];
                    G[u].push_back(v);
                    G[v].push_back(u);
                }
            }
        }
        
        int ans = 0;
        int done[1024];
        fill(done, done + 1024, -1);
        queue<pair<int, int> > q;
        
        for(q.push(make_pair(0, 0)); q.size(); q.pop()){
            pair<int, int> x = q.front();
            if (~done[x.first]) continue;
            done[x.first] = x.second;
            ans = max(ans, x.second);
            
            for (int i = 0; i < G[x.first].size(); i++){
                q.push(make_pair(G[x.first][i], x.second + 1));
            }
        }
        
        printf("%d\n", ans);
    }
    
    return (0);
}

Compiler output:
a.cc:3:9: warning: "M_PI" redefined
    3 | #define M_PI (3.141592653589793)
      |         ^~~~
In file included from /usr/include/c++/14/cmath:47,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:114,
                 from a.cc:1:
/usr/include/math.h:1121:10: note: this is the location of the previous definition
 1121 | # define M_PI           3.14159265358979323846  /* pi */
      |          ^~~~
a.cc: In function 'int ccw(Point, Point, Point)':
a.cc:43:13: error: no matching function for call to 'norm(Vector&)'
   43 |     if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
      |         ~~~~^~~
In file included from /usr/include/c++/14/ccomplex:39,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:127:
/usr/include/c++/14/complex:959:5: note: candidate: 'template<class _Tp> _Tp std::norm(const complex<_Tp>&)'
  959 |     norm(const complex<_Tp>& __z)
      |     ^~~~
/usr/include/c++/14/complex:959:5: note:   template argument deduction/substitution failed:
a.cc:43:13: note:   'Vector' {aka 'Point'} is not derived from 'const std::complex<_Tp>'
   43 |     if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
      |         ~~~~^~~
/usr/include/c++/14/complex:2453:5: note: candidate: 'template<class _Tp> typename __gnu_cxx::__promote<_Tp, std::__is_integer<_Tp>::__value>::__type std::norm(_Tp)'
 2453 |     norm(_Tp __x)
      |     ^~~~
/usr/include/c++/14/complex:2453:5: note:   template argument deduction/substitution failed:
/usr/include/c++/14/complex: In substitution of 'template<class _Tp> typename __gnu_cxx::__promote<_Tp, std::__is_integer<_Tp>::__value>::__type std::norm(_Tp) [with _Tp = Point]':
a.cc:43:13:   required from here
   43 |     if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
      |         ~~~~^~~
/usr/include/c++/14/complex:2453:5: error: no type named '__type' in 'struct __gnu_cxx::__promote<Point, false>'
 2453 |     norm(_Tp __x)
      |     ^~~~
a.cc:43:23: error: no matching function for call to 'norm(Vector&)'
   43 |     if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
      |                   ~~~~^~~
/usr/include/c++/14/complex:959:5: note: candidate: 'template<class _Tp> _Tp std::norm(const complex<_Tp>&)'
  959 |     norm(const complex<_Tp>& __z)
      |     ^~~~
/usr/include/c++/14/complex:959:5: note:   template argument deduction/substitution failed:
a.cc:43:23: note:   'Vector' {aka 'Point'} is not derived from 'const std::complex<_Tp>'
   43 |     if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
      |                   ~~~~^~~
/usr/include/c++/14/complex:2453:5: note: candidate: 'template<class _Tp> typename __gnu_cxx::__promote<_Tp, std::__is_integer<_Tp>::__value>::__type std::norm(_Tp)'
 2453 |     norm(_Tp __x)
      |     ^~~~
/usr/include/c++/14/complex:2453:5: note:   template argument deduction/substitution failed:
/usr/include/c++/14/complex: In substitution of 'template<class _Tp> typename __gnu_cxx::__promote<_Tp, std::__is_integer<_Tp>::__value>::__type std::norm(_Tp) [with _Tp = Point]':
a.cc:43:23:   required from here
   43 |     if (norm(a) < norm(b)) return (-2); //p0--p1--p2 の順で一直線上
      |                   ~~~~^~~
/usr/include/c++/14/complex:2453:5: error: no type named '__type' in 'struct __gnu_cxx::__promote<Point, false>'
 2453 |     norm(_Tp __x)
      |     ^~~~