Language: C++

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<complex>
#include<deque>
#include<vector>
using namespace std;
double eps=1e-6;
double x[110];
double y[110];
double px[700];
double py[700];
int ijk[700];
int v[700];
const double EPS = 1e-8;
const double INF = 1e12;
double PI=3.14159265358;
struct P{
	double x;double y;
	P(){}
	P(double X,double Y){
		x=X;y=Y;
	}
	P operator+ (const P &a)const{
		return P(x+a.x,y+a.y);
	}
	P operator- (const P &a)const{
		return P(x-a.x,y-a.y);
	}
	P operator* (const double &a)const{
		return P(x*a,y*a);
	}
	/*operator+ (P a){
		return P(x+a.x,y+a.y);
	}
	operator+ (P a){
		return P(x+a.x,y+a.y);
	}*/
	
};
inline bool operator < (const P& a, const P& b) {
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
inline double cross(const P& a, const P& b) {
	return a.x*b.y-a.y*b.x;
}
inline double dot(const P& a, const P& b) {
	return a.x*b.x+a.y*b.y;
}

inline int ccw(const P &a, const P &b, const P &c) {
	b=b-a;c=c-a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  if (dot(b, c) < 0)     return +2;       // c--a--b on line
  if (b.x*b.x+b.y*b.y<c.x*c.x+c.y*c.y) return -2;       // a--b--c on line
  return 0;
}
#define se second
#define fi first

bool intersectSS(const pair<P,P> &s, const pair<P,P> &t) {
  return ccw(s.fi,s.se,t.fi)*ccw(s.fi,s.se,t.se) <= 0 &&
         ccw(t.fi,t.se,s.fi)*ccw(t.fi,t.se,s.se) <= 0;
}

P pt[700];
P ps[300];
int s[400];
int t[400];
double left[400];
double right[400];
vector<pair<int,int> >g[700];
int UF[700];
int FIND(int a){
	if(UF[a]<0)return a;
	return UF[a]=FIND(UF[a]);
}
void UNION(int a,int b){
	a=FIND(a);b=FIND(b);if(a==b)return;UF[a]+=UF[b];UF[b]=a;
}
int main(){
	int a,b;
	while(scanf("%d%d",&a,&b),a){
		for(int i=0;i<700;i++)UF[i]=-1;
		for(int i=0;i<700;i++)g[i].clear();
		for(int i=0;i<a;i++)scanf("%lf%lf",x+i,y+i);
		for(int i=0;i<a;i++){
			double X=cos(1)*x[i]-sin(1)*y[i];
			double Y=sin(1)*x[i]+cos(1)*y[i];
			x[i]=X;
			y[i]=Y;
			ps[i]=P(x[i],y[i]);
		}
		for(int i=0;i<b;i++){
			int p,q;scanf("%d%d",&p,&q);
			p--;q--;
			s[i]=p;t[i]=q;
			px[i*2]=(x[p]+x[q])/2+eps;
			py[i*2]=(y[p]+y[q])/2;
			px[i*2+1]=(x[p]+x[q])/2-eps;
			py[i*2+1]=(y[p]+y[q])/2;
			pt[i*2]=P(px[i*2],py[i*2]);
			pt[i*2+1]=P(px[i*2+1],py[i*2+1]);
		}
		deque<pair<int,int> >Q;
		for(int i=0;i<a;i++){
			vector<pair<double,pair<int,int> > >vec;
			for(int j=0;j<b;j++){
				if(s[j]==i){
					vec.push_back(make_pair(atan2(y[t[j]]-y[i],x[t[j]]-x[i]),make_pair(j,t[j])));
				}
				if(t[j]==i){
					vec.push_back(make_pair(atan2(y[s[j]]-y[i],x[s[j]]-x[i]),make_pair(j,s[j])));
				}
			}
			std::sort(vec.begin(),vec.end());
			int sz=vec.size();
			for(int j=0;j<vec.size();j++){
				double th=vec[j].first;
				double th2=vec[(j+1)%sz].first;
				if(th>th2)th2+=2*PI;
				if(th2-th<=PI+EPS)continue;
				for(int k=0;k<2;k++)for(int l=0;l<2;l++){
					if(intersectSS(make_pair(pt[vec[j].second.first*2+k],pt[vec[(j+1)%sz].second.first*2+l]),
					make_pair(ps[i],ps[vec[j].second.second]))&&intersectSS(make_pair(pt[vec[j].second.first*2+k],pt[vec[(j+1)%sz].second.first*2+l]),
					make_pair(ps[i],ps[vec[(j+1)%sz].second.second]))){
						g[vec[j].second.first*2+k].push_back(make_pair(vec[(j+1)%sz].second.first*2+l,0));
						g[vec[(j+1)%sz].second.first*2+l].push_back(make_pair(vec[j].second.first*2+k,0));
						UNION(vec[j].second.first*2+k,vec[(j+1)%sz].second.first*2+l);
					}
				}
			}
		}
		for(int i=0;i<b*2;i++){
			ijk[i]=999999999;
			v[i]=0;
			bool OK=true;
			int tt=s[i/2];
			for(int j=0;j<b;j++){
				if(tt==s[j]||tt==t[j])continue;
				if(intersectSS(make_pair(ps[tt],ps[tt]+(pt[i]-ps[tt])*10000.0),make_pair(ps[s[j]],ps[t[j]]))){
					OK=false;break;
				}
			}
			tt=t[i/2];
			for(int j=0;j<b;j++){
				if(tt==s[j]||tt==t[j])continue;
				if(intersectSS(make_pair(ps[tt],ps[tt]+(pt[i]-ps[tt])*10000.0),make_pair(ps[s[j]],ps[t[j]]))){
					OK=false;break;
				}
			}
			
			if(OK){
				ijk[i]=0;
				Q.push_back(make_pair(0,i));
			}
			for(int j=i+1;j<b*2;j++){
				int cnt=0;
				if(FIND(i)==FIND(j))continue;
				for(int k=0;k<b;k++){
					if(intersectSS(make_pair(ps[s[k]],ps[t[k]]),make_pair(pt[i],pt[j]))){
						cnt++;
						if(cnt>1)break;
					}
				}
				if(cnt<2){
					if(cnt==0){
						UNION(i,j);
					}
					g[i].push_back(make_pair(j,cnt));
					g[j].push_back(make_pair(i,cnt));
				}
			}
		}
		while(Q.size()){
			int cost=-Q.front().first;
			int at=Q.front().second;Q.pop_front();
			if(v[at])continue;
			v[at]=1;
			for(int i=0;i<g[at].size();i++){
				if(!v[g[at][i].first]&&ijk[g[at][i].first]>cost+g[at][i].second){
					ijk[g[at][i].first]=cost+g[at][i].second;
					if(g[at][i].second==1)Q.push_back(make_pair(-ijk[g[at][i].first],g[at][i].first));
					else Q.push_front(make_pair(-ijk[g[at][i].first],g[at][i].first));
				}
			}
		}
		int ret=0;
		for(int i=0;i<b*2;i++)ret=max(ret,ijk[i]);
		printf("%d\n",ret);
	}
}

Compiler output:
a.cc: In function 'int ccw(const P&, const P&, const P&)':
a.cc:53:13: error: passing 'const P' as 'this' argument discards qualifiers [-fpermissive]
   53 |         b=b-a;c=c-a;
      |             ^
a.cc:19:8: note:   in call to 'constexpr P& P::operator=(P&&)'
   19 | struct P{
      |        ^
a.cc:53:19: error: passing 'const P' as 'this' argument discards qualifiers [-fpermissive]
   53 |         b=b-a;c=c-a;
      |                   ^
a.cc:19:8: note:   in call to 'constexpr P& P::operator=(P&&)'
   19 | struct P{
      |        ^