Language: C++

int bottom;
int outside_color;

// Library.
#include<cassert>
#include<map>
#include<vector>
#include<cmath>
#include<queue>
#include<algorithm>
// Type.
typedef int Label;
typedef int Weight;
// Class.
template<typename Vertex, typename Edge>
class PlaneGraph {
public:
  void insert(const Vertex& v);
  void insert(Edge e);
  const PlaneGraph<Vertex, Edge> dualgraph() const;
  const std::map<Label, Weight> Dijkstra(const Label& start) const;
private:
  void dualgraph_color(std::map<Label, std::map<Label, int>>& color, int c, const Edge& e, const std::map<Label, std::vector<Edge>>& edge) const;
  std::map<Label, Vertex> V;
  std::map<Label, std::vector<Edge>> E;
};
// Implement.
template<typename Vertex, typename Edge>
void PlaneGraph<Vertex, Edge>::insert(const Vertex& v) {
  V[v.label] = v;
}
template<typename Vertex, typename Edge>
void PlaneGraph<Vertex, Edge>::insert(Edge e) {
  assert(V.find(e.from) != std::end(V));
  assert(V.find(e.to) != std::end(V));
  E[e.from].push_back(e);
  std::swap(e.from, e.to);
  E[e.from].push_back(e);
}
template<typename Vertex, typename Edge>
const PlaneGraph<Vertex, Edge> PlaneGraph<Vertex, Edge>::dualgraph() const {
  // Sort edges counterclockwise.
  auto edge = E;
  for(auto& list: edge) if(!list.second.empty()) {
    std::sort(std::begin(list.second), std::end(list.second), [&](const Edge& lhs, const Edge& rhs) {
      double l = std::atan2(V.at(lhs.to).y - V.at(lhs.from).y, V.at(lhs.to).x - V.at(lhs.from).x);
      double r = std::atan2(V.at(rhs.to).y - V.at(rhs.from).y, V.at(rhs.to).x - V.at(rhs.from).x);
      return l < r;
    });
    list.second.push_back(list.second.front());
  }
  // Color edges.
  std::map<Label, std::map<Label, int>> color;
  int c = 1;
  for(const auto& list: edge) {
    for(const auto& e: list.second) if(!color[e.from].count(e.to)) dualgraph_color(color, c++, e, edge);
    if(list.first == bottom) outside_color = color[list.second.front().from][list.second.front().to];
  }
  // Construct the dualgraph.
  PlaneGraph<Vertex, Edge> result;
  std::vector<std::vector<bool>> used(c, std::vector<bool>(c, false));
  for(int i = 1; i < c; ++i) result.insert(Vertex({i}));
  for(const auto& list: E) for(const auto& e: list.second) if(!used[color[e.from][e.to]][color[e.to][e.from]]) {
    used[color[e.from][e.to]][color[e.to][e.from]] = true;
    used[color[e.to][e.from]][color[e.from][e.to]] = true;
    result.insert(Edge({color[e.from][e.to], color[e.to][e.from], 1}));
  }
  return result;
}
template<typename Vertex, typename Edge>
void PlaneGraph<Vertex, Edge>::dualgraph_color(std::map<Label, std::map<Label, int>>& color, int c, const Edge& e, const std::map<Label, std::vector<Edge>>& edge) const {
  color[e.from][e.to] = c;
  for(auto it = edge.at(e.to).rbegin(); it != edge.at(e.to).rend(); ++it) if(it->to == e.from) {
    ++it;
    if(!color[it->from].count(it->to)) dualgraph_color(color, c, *it, edge);
    break;
  }
}
template<typename Vertex, typename Edge>
const std::map<Label, Weight> PlaneGraph<Vertex, Edge>::Dijkstra(const Label& start) const {
  std::map<Label, Weight> result;
  std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
    return lhs.weight > rhs.weight;
  });
  q.push(Edge({start, start, 0}));
  while(!q.empty()) {
    auto cur = q.top();
    q.pop();
    if(result.count(cur.to)) continue;
    result[cur.to] = cur.weight;
    for(const auto& nex: E.at(cur.to)) if(!result.count(nex.to)) q.push(Edge({nex.from, nex.to, cur.weight + nex.weight}));
  }
  return result;
}
////////////////////////////////////////
// Configuration.
struct Vertex {Label label; double x, y;};
struct Edge {Label from, to; Weight weight;};
////////////////////////////////////////
#include<bits/stdc++.h>
using namespace std;
int main() {
  int C, W;
  while(cin >> C >> W, C | W) {
    vector<Vertex> pillar;
    int bottom_x = 1001, bottom_y = 1001;
    for(int i = 0; i < C; ++i) {
      double x, y;
      cin >> x >> y;
      pillar.push_back({i, x, y});
      if(bottom_x < x) continue;
      if(bottom_x == x && bottom_y < y) continue;
      bottom_x = x;
      bottom_y = y;
      bottom = i;
    }
    PlaneGraph<Vertex, Edge> G;
    for(const auto& p: pillar) G.insert(p);
    for(int i = 0; i < W; ++i) {
      int s, t;
      cin >> s >> t;
      --s; --t;
      G.insert(Edge({s, t, 1}));
    }
    auto D = G.dualgraph();
    auto distance = D.Dijkstra(outside_color);
    double answer = 0;
    for(const auto& d: distance) answer = max(answer, d.second);
    cout << answer << endl;
  }
}

Compiler output:
a.cc: In member function 'const std::map<int, int> PlaneGraph<Vertex, Edge>::Dijkstra(const Label&) const':
a.cc:82:53: error: 'function' is not a member of 'std'
   82 |   std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
      |                                                     ^~~~~~~~
a.cc:11:1: note: 'std::function' is defined in header '<functional>'; this is probably fixable by adding '#include <functional>'
   10 | #include<algorithm>
  +++ |+#include <functional>
   11 | // Type.
a.cc:82:78: error: template argument 3 is invalid
   82 |   std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
      |                                                                              ^~
a.cc:85:5: error: request for member 'push' in 'q', which is of non-class type 'int'
   85 |   q.push(Edge({start, start, 0}));
      |     ^~~~
a.cc:86:12: error: request for member 'empty' in 'q', which is of non-class type 'int'
   86 |   while(!q.empty()) {
      |            ^~~~~
a.cc:87:18: error: request for member 'top' in 'q', which is of non-class type 'int'
   87 |     auto cur = q.top();
      |                  ^~~
a.cc:88:7: error: request for member 'pop' in 'q', which is of non-class type 'int'
   88 |     q.pop();
      |       ^~~
a.cc:91:68: error: request for member 'push' in 'q', which is of non-class type 'int'
   91 |     for(const auto& nex: E.at(cur.to)) if(!result.count(nex.to)) q.push(Edge({nex.from, nex.to, cur.weight + nex.weight}));
      |                                                                    ^~~~
a.cc: In function 'int main()':
a.cc:128:46: error: no matching function for call to 'max(double&, const int&)'
  128 |     for(const auto& d: distance) answer = max(answer, d.second);
      |                                           ~~~^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/14/bits/stl_tree.h:63,
                 from /usr/include/c++/14/map:62,
                 from a.cc:6:
/usr/include/c++/14/bits/stl_algobase.h:257:5: note: candidate: 'template<class _Tp> constexpr const _Tp& std::max(const _Tp&, const _Tp&)'
  257 |     max(const _Tp& __a, const _Tp& __b)
      |     ^~~
/usr/include/c++/14/bits/stl_algobase.h:257:5: note:   template argument deduction/substitution failed:
a.cc:128:46: note:   deduced conflicting types for parameter 'const _Tp' ('double' and 'int')
  128 |     for(const auto& d: distance) answer = max(answer, d.second);
      |                                           ~~~^~~~~~~~~~~~~~~~~~
/usr/include/c++/14/bits/stl_algobase.h:303:5: note: candidate: 'template<class _Tp, class _Compare> constexpr const _Tp& std::max(const _Tp&, const _Tp&, _Compare)'
  303 |     max(const _Tp& __a, const _Tp& __b, _Compare __comp)
      |     ^~~
/usr/include/c++/14/bits/stl_algobase.h:303:5: note:   candidate expects 3 arguments, 2 provided
In file included from /usr/include/c++/14/algorithm:61,
                 from a.cc:10:
/usr/include/c++/14/bits/stl_algo.h:5706:5: note: candidate: 'template<class _Tp> constexpr _Tp std::max(initializer_list<_Tp>)'
 5706 |     max(initializer_list<_Tp> __l)
      |     ^~~
/usr/include/c++/14/bits/stl_algo.h:5706:5: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/14/bits/stl_algo.h:5716:5: note: candidate: 'template<class _Tp, class _Compare> constexpr _Tp std::max(initializer_list<_Tp>, _Compare)'
 5716 |     max(initializer_list<_Tp> __l, _Compare __comp)
      |     ^~~
/usr/include/c++/14/bits/stl_algo.h:5716:5: note:   template argument deduction/substitution failed:
a.cc:128:46: note:   mismatched types 'std::initializer_list<_Tp>' and 'double'
  128 |     for(const auto& d: distance) answer = max(answer, d.second);
      |                                           ~~~^~~~~~~~~~~~~~~~~~
a.cc: In instantiation of 'const std::map<int, int> PlaneGraph<Vertex, Edge>::Dijkstra(const Label&) const [with Vertex = Vertex; Edge = Edge; Label = int]':
a.cc:126:31:   required from here
  126 |     auto distance = D.Dijkstra(outside_color);
      |                     ~~~~~~~~~~^~~~~~~~~~~~~~~
a.cc:82:83: error: invalid user-defined conversion from 'PlaneGraph<Vertex, Edge>::Dijkstra(const Label&) const::<lambda(Edge, Edge)>' to 'int' [-fpermissive]
   82 |   std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
      |                                                                                   ^~~~~~~~~~~~~~~~~~~~~~~~
   83 |     return lhs.weight > rhs.weight;
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                
   84 |   });
      |   ~                                                                                
a.cc:82:83: note: candidate is: 'constexpr PlaneGraph<Vertex, Edge>::Dijkstra(const Label&) const::<lambda(Edge, Edge)>::operator bool (*)(Edge, Edge)() const' (near match)
   82 |   std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
      |                                                                                   ^
a.cc:82:83: note:   no known conversion from 'bool (*)(Edge, Edge)' to 'int'