Language: C++

// Library.
#include<cassert>
#include<map>
#include<vector>
#include<cmath>
#include<queue>
#include<algorithm>
// Type.
typedef int Label;
typedef double 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 PlaneGraph<Vertex, Edge> PlaneGraph<Vertex, Edge>::dualgraph() const':
a.cc:54:22: error: 'bottom' was not declared in this scope
   54 |     if(list.first == bottom) outside_color = color[list.second.front().from][list.second.front().to];
      |                      ^~~~~~
a.cc:54:30: error: 'outside_color' was not declared in this scope
   54 |     if(list.first == bottom) outside_color = color[list.second.front().from][list.second.front().to];
      |                              ^~~~~~~~~~~~~
a.cc: In member function 'const std::map<int, double> PlaneGraph<Vertex, Edge>::Dijkstra(const Label&) const':
a.cc:79:53: error: 'function' is not a member of 'std'
   79 |   std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
      |                                                     ^~~~~~~~
a.cc:8:1: note: 'std::function' is defined in header '<functional>'; this is probably fixable by adding '#include <functional>'
    7 | #include<algorithm>
  +++ |+#include <functional>
    8 | // Type.
a.cc:79:78: error: template argument 3 is invalid
   79 |   std::priority_queue<Edge, std::vector<Edge>, std::function<bool(Edge, Edge)>> q([](Edge lhs, Edge rhs) {
      |                                                                              ^~
a.cc:82:5: error: request for member 'push' in 'q', which is of non-class type 'int'
   82 |   q.push(Edge({start, start, 0}));
      |     ^~~~
a.cc:83:12: error: request for member 'empty' in 'q', which is of non-class type 'int'
   83 |   while(!q.empty()) {
      |            ^~~~~
a.cc:84:18: error: request for member 'top' in 'q', which is of non-class type 'int'
   84 |     auto cur = q.top();
      |                  ^~~
a.cc:85:7: error: request for member 'pop' in 'q', which is of non-class type 'int'
   85 |     q.pop();
      |       ^~~
a.cc:88:68: error: request for member 'push' in 'q', which is of non-class type 'int'
   88 |     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:112:7: error: 'bottom' was not declared in this scope; did you mean 'bottom_y'?
  112 |       bottom = i;
      |       ^~~~~~
      |       bottom_y
a.cc:123:32: error: 'outside_color' was not declared in this scope
  123 |     auto distance = D.Dijkstra(outside_color);
      |                                ^~~~~~~~~~~~~