Problem:
競プロは小惑星探査の役に立つ
JAG (Japan Aerospace-exploration Group) の小惑星探査機群まわりこみやが 2019 年に地球を飛び立ってから 10 年，いよいよ目標の小惑星帯 ICPC-2020 へ接近する日が近づいてきた．この探査プロジェクトにおいては，複数の探査機がそれぞれ異なる小惑星からサンプルを採取することになっている．ところが，この 3 日前になって JAG の宇宙観測部門がある重大な見落としに気がついた．彼らの報告によると，まわりこみやの現在地から ICPC-2020 の間にはいくつもの障害物が存在し，このままの軌道ではまわりこみやは衝突してしまうかもしれないらしい．
すぐさま緊急会議が行われ，エンジン噴射で機体を制御して障害物を回避することになった．必要な制御プログラムの実装は JAG の技術者であり競技プログラマーでもあるあなたが担当することも決まった．あなたがこれから書くプログラムの仕様は競技プログラミング風に言えば次のようになるだろう．
Q
機のまわりこみやの機体とそれぞれが目標とする小惑星の位置が
xy
-平面上の点として与えられる（宇宙工学的要請によりまわりこみやはこの平面上しか動けない．まわりこみやと小惑星は障害物と比べて十分小さく，大きさは無視できる）．また，この平面と交差する障害物の情報も複数の多角形として与えられる．まわりこみやはこの平面上でいくつかの線分からなる折れ線状の経路に沿って移動することができ，これによって障害物にぶつかることなく ICPC-2020 の座標に到達することが目標である（まわりこみやが多角形の辺上に存在することはできる）．
この宙域には弱い重力が作用しており，線分に沿って移動する際に
y
座標が増加しないなら噴射をする必要はないが，
y
座標が増加するときは
y
座標 1 あたり 1 ジュールの割合でエネルギーを使って噴射する必要がある．探査機のエネルギーを使いすぎると帰還が困難になってしまうので，消費エネルギーはできるだけ少なくしたい．
それぞれの機体について，目標の小惑星に到達するのに必要な最小のエネルギーを求めよ．
Input
入力は最大 50 データセットからなり，各データセットは次の形式で表される．
N
Q
v
1
x
1,1
y
1,1
...
x
1,v
1
y
1,v
1
v
2
x
2,1
y
2,1
...
x
2,v
2
y
2,v
2
...
v
N
x
N,1
y
N,1
...
x
N,v
N
y
N,v
N
sx
1
sy
1
gx
1
gy
1
...
sx
Q
sy
Q
gx
Q
gy
Q
最初の行には障害物を表す多角形の個数
N
(
1 ≤ N ≤ 10
) と探査機の個数
Q
(
1 ≤ Q ≤ 1000
) がこの順で与えられている．この次に
N
回にわたって多角形の情報が与えられる．それぞれの多角形は次の形式で表される．
i
個目の多角形の頂点数
v
i
(
3 ≤ v
i
≤ 100
) が 1 行目に与えられる．続く
v
i
行に，1 行に 1 頂点ずつ多角形を構成する頂点の座標が与えられる．これらの行には
x
座標と
y
座標がこの順で与えられている．
i
個目の多角形は，ここに登場する頂点を登場する順に辺で結び，最後の頂点と最初の頂点を辺で結ぶと得られる．この多角形は自己交差を持たない単純な多角形であることが保証されている．
多角形の情報に続いて
Q
行に渡って探査機と小惑星の情報が与えられる．各行には探査機の座標
(sx
i
, sy
i
)
と目標とする小惑星の座標
(gx
i
, gy
i
)
がこの順で与えられる．
各データセットにおいて与えられる座標は全て整数であり，
x
座標と
y
座標の絶対値はともに 1000 を超えない．また，どの 2 つの多角形の面（内部と境界を合わせた点の集合）同士の共通部分も空であること，始点と終点はすべての多角形の外部の共通部分に存在することが保証されている．
入力の末尾は空白で区切られた 2 つの 0 で表される．
Output
各データセットに対し
Q
行を出力せよ．
Q
行のうちの
i
行目には
i
番目の探査機に必要な最小のエネルギーを出力せよ．結果は
10
−6
以上の誤差を含んではいけない．
Sample Input
1 1
4
1 2
3 2
3 -1
1 -1
0 0 5 0
2 1
4
0 -1
-1 -4
0 -2
1 -4
4
0 1
-1 4
0 2
1 4
0 -3 0 3
4 3
6
0 2
3 2
2 0
3 -2
0 -2
1 0
6
3 0
4 -2
5 -2
4 0
5 2
4 2
7
6 2
7 2
9 1
7 0
7 -2
6 -2
5 0
6
9 0
10 -2
11 -2
10 0
11 2
10 2
0 -1 11 1
11 1 0 -1
11 1 11 -1
0 0
Output for the Sample Input
1.000000000000
8.000000000000
3.000000000000
1.000000000000
0

Submitted solutions:

code_snippet: // O(m^2 logm) where m is 2*Q+(#edges of polygons)
// using floating point number

 #include <bits/stdc++.h>

 #define int long long
 #define pa pair<int,int>
 #define PI 3.14159265358979323846
 #define  mp make_pair
 #define  pb push_back
 
using namespace std;

struct P{
	int x,y;
};

int kake(P a,P b){
	return a.x*b.y-a.y*b.x;
}

double sol(int ax,int ay,int bx,int by){
	double a=atan2(ay,ax);
	double b=atan2(by,bx);
	b-=a;
	while(b<0)b+=2*PI;
	while(b>2*PI)b-=2*PI;
	return b;
}

bool ch(int ax,int ay,int bx,int by,int x,int y){
	if(ay==y && ax*x>0)return 0;
	if(by==y && bx*x>0)return 0;
	
	if(abs(sol(ax,ay,x,y)+sol(x,y,bx,by)-sol(ax,ay,bx,by))<0.001)return 1;
	return 0;
}
vector<pa>T[3000];

vector<pa> G[10000];

void solve(){
	for(int i=0;i<3000;i++)T[i].clear();
	for(int i=0;i<10000;i++)G[i].clear();
	
	int n,q;
	if(!(cin>>n>>q))exit(0);
	
	vector<vector<P>> KA;
	vector<vector<int>>ban;
	vector<P> cho;
	int tmp=2*q;
	for(int i=0;i<n;i++){
		vector<P> v;
		vector<int> f;
		int y;
		cin>>y;
		for(int j=0;j<y;j++){
			int df,dff;
			cin>>df>>dff;
			v.pb({df,dff});
			f.pb(tmp);
			tmp++;
		}
		int wa=0;
		for(int j=0;j<y;j++){
			wa+=kake(v[j],v[(j+1)%y]);
		}
		if(wa<0){
		//	cout<<"!"<<endl;
			reverse(v.begin(),v.end());
		}
		ban.pb(f);
		KA.pb(v);
	}
	
	vector<P> ss,gg;
	for(int i=0;i<q;i++){
		int x,y;
		cin>>x>>y;
			ss.pb({x,y});
		cin>>x>>y;
			gg.pb({x,y});
	}
	for(int i=0;i<q;i++){
		cho.pb(ss[i]);
	}
	for(int i=0;i<q;i++){
		cho.pb(gg[i]);
	}
	
	
	vector<pa> eda;
	for(int i=0;i<n;i++){
		int g=KA[i].size();
		for(int j=0;j<KA[i].size();j++){
			cho.pb(KA[i][j]);
			eda.pb(mp(ban[i][j],ban[i][(j+1)%g]));
		}
	}
	
		cho.pb({100000,-1000000});
		cho.pb({100000,1000000});
	eda.pb(mp((int)cho.size()-2,(int)cho.size()-1));
	int cnt=cho.size();
	int m=eda.size();
	
	vector<pa> edge;
	for(int i=0;i<2*q;i++){
		int X=cho[i].x;
		int Y=cho[i].y;
		int edm1=-1,edm2=-1;
		double mx2=1e10,mx1=-(1e10);
		for(int j=0;j<m;j++){
			int sx=cho[eda[j].first].x,sy=cho[eda[j].first].y,gx=cho[eda[j].second].x,gy=cho[eda[j].second].y;
			if(sy>gy){
				swap(sx,gx);
				swap(sy,gy);
			}
			if(!(sy<=Y&&Y<=gy))continue;
			double pos;
			if(gy!=sy)pos=0.0+sx+(Y-sy+0.0)/(gy-sy+0.0)*(gx-sx);
			else pos=gx;
			if(pos>X){
				if(mx2>pos){
					mx2=pos;
					edm2=j;
				}
			}
			else{
				if(mx1<pos){
					mx1=pos;
					edm1=j;
				}	
			}
		}
	
		assert(edm2!=-1);
		T[edm2].pb(mp(Y,cnt));
		edge.pb(mp(i,cnt));
			cho.pb({-1,Y});
		cnt++;
		if(edm1>=0){
			T[edm1].pb(mp(Y,cnt));
			edge.pb(mp(i,cnt));
				cho.pb({-1,Y});
			cnt++;
		}
	}
	
	for(int i=0;i<n;i++){
		int f=KA[i].size();
		for(int j=0;j<f;j++){
			int ax=KA[i][(j+f-1)%f].x;
			int ay=KA[i][(j+f-1)%f].y;
			int bx=KA[i][(j+1)%f].x;
			int by=KA[i][(j+1)%f].y;
			int X=KA[i][j].x;
			int Y=KA[i][j].y;
			bool d2=0;
			if(ch(ax-X,ay-Y,bx-X,by-Y,1,0))d2=1;
			bool d1=0;
			if(ch(ax-X,ay-Y,bx-X,by-Y,-1,0))d1=1;
				int edm1=-1,edm2=-1;
			double mx2=1e10,mx1=-(1e10);
				for(int k=0;k<m;k++){
					if(eda[k].first==ban[i][j])continue;
					if(eda[k].second==ban[i][j])continue;
					
					int sx=cho[eda[k].first].x,sy=cho[eda[k].first].y,gx=cho[eda[k].second].x,gy=cho[eda[k].second].y;
					if(sy>gy){
						swap(sx,gx);
						swap(sy,gy);
					}
					if(!(sy<=Y&&Y<=gy))continue;
					double pos;
					if(gy!=sy)pos=0.0+sx+(Y-sy+0.0)/(gy-sy+0.0)*(gx-sx);
					else pos=gx;
					if(pos>X && d2){
						if(mx2>pos){
							mx2=pos;
							edm2=k;
						}
					}
					else if(pos<X && d1){
						if(mx1<pos){
							mx1=pos;
							edm1=k;
						}	
					}
				}
				if(edm2>=0){
					T[edm2].pb(mp(Y,cnt));
					edge.pb(mp(ban[i][j],cnt));
						cho.pb({-1,Y});
					cnt++;
				}
				if(edm1>=0){
					T[edm1].pb(mp(Y,cnt));
					edge.pb(mp(ban[i][j],cnt));
						cho.pb({-1,Y});
					cnt++;
				}
			
		}
	}
	
	for(int i=0;i<m;i++){
	//	cout<<"d"<<endl;
		T[i].pb(mp(cho[eda[i].first].y,eda[i].first));
		T[i].pb(mp(cho[eda[i].second].y,eda[i].second));
		
		sort(T[i].begin(),T[i].end());
		for(int j=0;j+1<T[i].size();j++){
			edge.pb(mp(T[i][j].second,T[i][j+1].second));
		}
	}
	
	for(auto v:edge){
		int x=v.first,y=v.second;
		G[x].pb(mp(y,max(0ll,cho[y].y-cho[x].y)));
		G[y].pb(mp(x,max(0ll,cho[x].y-cho[y].y)));
	}
	for(int s=0;s<q;s++){
		priority_queue<pa,vector<pa>,greater<pa>> pq;
		pq.push(mp(0,s));
		vector<int> vis(10000,0);
		while(pq.size()){
			pa z=pq.top();
			pq.pop();
			if(vis[z.second])continue;
			vis[z.second]=1;
			if(z.second==s+q){
				cout<<z.first<<endl;
				break;
			}
				for(auto v:G[z.second])pq.push(mp(z.first+v.second,v.first));
			
		}
	}
}




signed main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	int n=100000000;
	for(int i=0;i<n;i++)solve();
	return 0;
 }
accuracy: 1
time_ms: 13060
memory_kb: 5976
final_rank: 3

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
#include <queue>
#include <cstdlib>
using namespace std;

#define ALL(v) begin(v),end(v)
namespace{

using LL = long long;
using pll = pair<LL,LL>;
using segment = pair<pll,pll>;
using vpll = vector<pll>;
using D = long double;
using point = pair<D,LL>;

const LL INF = 1010101010;

D middle(D x, D y){ return (x + y) / 2; }

struct solver{
	vector<vpll> pols;
	vector<segment> segs;
	
	static bool calcx(pll p1, pll p2, LL y, D &res){
		if(p1.second == p2.second){ return false; }
		if(p1.second > p2.second){ swap(p1, p2); }
		if(y < p1.second || y > p2.second){ return false; }
		LL dx = p2.first - p1.first, dy = p2.second - p1.second;
		res = D(y - p1.second) * dx / dy + p1.first;
		return true;
	}
	
	bool inanypol(D x, LL y){
		for(const auto &pol : pols){
			int cnt = 0;
			int m = pol.size() - 1;
			for(int i = 0; i < m; ++i){
				D r;
				pll p1 = pol[i], p2 = pol[i + 1];
				if(p1.second == p2.second && p1.second == y){
					LL x1, x2;
					tie(x1, x2) = minmax(p1.first, p2.first);
					D r1 = x1, r2 = x2;
					if(r1 <= x && x <= r2){
						if(r1 < x && x < r2){ return false; }
						if(right && x == r1){ return false; }
						if(!right && x == r2){ return false; }
					}
				}
				if(max(p1.second, p2.second) <= y){ continue; }
				if(calcx(p1, p2, y, r)){
					if(r < x){ ++cnt; }
				}
			}
			if(cnt & 1){ return true; }
		}
		return false;
	}

	void solve(int npol){
		int q;
		cin >> q;
	
		vector<point> pts;
		map<point,int> pttoidx;
		vector<vector<pll>> G;
		auto regpt = [&](const point &pt){
			int id = pttoidx.emplace(pt, pttoidx.size()).first->second;
			if(id >= (int)pts.size()){
				pts.push_back(pt);
				G.emplace_back();
			}
			return id;
		};

		map<LL,vector<int>> ytoids;
		
		segs.emplace_back(pll(-INF, -INF), pll(-INF, INF));
		segs.emplace_back(pll(INF, -INF), pll(INF, INF));
		for(int i = 0; i < npol; ++i){
			int m;
			cin >> m;
			vector<pll> pl(m + 1);
			for(int j = 0; j < m; ++j){
				cin >> pl[j].first >> pl[j].second;
				ytoids[pl[j].second].push_back(regpt(point(pl[j].first, pl[j].second)));
			}
			pl[m] = pl[0];
			
			for(int j = 0; j < m; ++j){
				pll p1 = pl[j], p2 = pl[j + 1];
				if(p1.second > p2.second){ swap(p1, p2); }
				if(p1.second != p2.second){
					segs.emplace_back(p1, p2);
				}
				else{
					int u1 = regpt(point(p1.first, p1.second));
					int u2 = regpt(point(p2.first, p2.second));
					G[u1].emplace_back(u2, 0);
					G[u2].emplace_back(u1, 0);
				}
			}
			
			pols.emplace_back(move(pl));
		}
		
		vector<int> starts(q), goals(q);
		for(int i = 0; i < q; ++i){
			LL sx, sy, gx, gy;
			cin >> sx >> sy >> gx >> gy;
			starts[i] = regpt(point(sx, sy));
			goals[i] = regpt(point(gx, gy));
			
			ytoids[sy].push_back(starts[i]);
			ytoids[gy].push_back(goals[i]);
		}

		int ns = segs.size();
		vector<vector<int>> idsonsegs(ns);
		for(int i = 0; i < ns; ++i){
			const segment &s = segs[i];
			idsonsegs[i].push_back(regpt(point(s.first.first, s.first.second)));
		}
		for(auto &pr : ytoids){
			LL y = pr.first;
			vector<pair<D,int>> itss;
			
			for(int i = 0; i < ns; ++i){
				D x;
				if(calcx(segs[i].first, segs[i].second, y, x)){
					itss.emplace_back(x, i);
				}
			}
			
			for(int id : pr.second){
				pair<D,int> prv(-INF, 0), nxt(INF, 1);
				for(const auto &p : itss){
					if(p.first < pts[id].first){
						prv = max(prv, p);
					}
					if(pts[id].first < p.first){
						nxt = min(nxt, p);
					}
				}
				
				if(!inanypol(middle(prv.first, pts[id].first), pts[id].second)){
					int k = regpt(point(prv.first, y));
					G[id].emplace_back(k, 0);
					G[k].emplace_back(id, 0);
					idsonsegs[prv.second].push_back(k);
				}
				if(!inanypol(middle(pts[id].first, nxt.first), pts[id].second)){
					int k = regpt(point(nxt.first, y));
					G[id].emplace_back(k, 0);
					G[k].emplace_back(id, 0);
					idsonsegs[nxt.second].push_back(k);
				}
			}
		}
		
		for(int i = 0; i < ns; ++i){
			regpt(point(segs[i].second.first, segs[i].second.second));
			idsonsegs[i].push_back(regpt(point(segs[i].second.first, segs[i].second.second)));
			const auto &v = idsonsegs[i];
			for(size_t j = 0; j + 1 < v.size(); ++j){
				int id1 = v[j];
				int id2 = v[j + 1];
				G[id1].emplace_back(id2, pts[id2].second - pts[id1].second);
				G[id2].emplace_back(id1, 0);
			}
		}

		priority_queue<pll> pq;
		vector<LL> dist;
		for(int i = 0; i < q; ++i){
			pq.emplace(0, starts[i]);
			dist.assign(G.size(), 1LL << 60);
			dist[starts[i]] = 0;
			while(!pq.empty()){
				LL d = -pq.top().first;
				int u = pq.top().second;
				pq.pop();
				if(dist[u] != d){ continue; }
				for(const pll &e : G[u]){
					LL nd = d + e.second;
					if(dist[e.first] > nd){
						dist[e.first] = nd;
						pq.emplace(-nd, e.first);
					}
				}
			}
			cout << dist[goals[i]] << '\n';
		}
	}
};
}

int main() try{
	int n;
	while(cin >> n && n){
		solver().solve(n);
	}
}
catch(const exception &ex){
	cerr << ex.what() << endl;
	abort();
}
accuracy: 1
time_ms: 9790
memory_kb: 5020
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
#include <queue>
#include <cstdlib>
using namespace std;

#define ALL(v) begin(v),end(v)
namespace{

using LL = long long;
using pll = pair<LL,LL>;
using segment = pair<pll,pll>;
using vpll = vector<pll>;
using D = long double;
using point = pair<D,LL>;

const LL INF = 1010101010;

D middle(D x, D y){ return (x + y) / 2; }

struct solver{
	vector<vpll> pols;
	vector<segment> segs;
	
	static bool calcx(pll p1, pll p2, LL y, D &res){
		if(p1.second == p2.second){ return false; }
		if(p1.second > p2.second){ swap(p1, p2); }
		if(y < p1.second || y > p2.second){ return false; }
		LL dx = p2.first - p1.first, dy = p2.second - p1.second;
		res = D(y - p1.second) * dx / dy + p1.first;
		return true;
	}
	
	bool inanypol(D x, LL y){
		for(const auto &pol : pols){
			int cnt = 0;
			int m = pol.size() - 1;
			for(int i = 0; i < m; ++i){
				D r;
				pll p1 = pol[i], p2 = pol[i + 1];
				if(p1.second == p2.second && p1.second == y){
					LL x1, x2;
					tie(x1, x2) = minmax(p1.first, p2.first);
					D r1 = x1, r2 = x2;
					if(r1 <= x && x <= r2){
						if(r1 < x && x < r2){ return false; }
						if(right && x == r1){ return false; }
						if(!right && x == r2){ return false; }
					}
				}
				if(max(p1.second, p2.second) <= y){ continue; }
				if(calcx(p1, p2, y, r)){
					if(r < x){ ++cnt; }
				}
			}
			if(cnt & 1){ return true; }
		}
		return false;
	}

	void solve(int npol){
		int numq;
		cin >> numq;
	
		vector<point> pts;
		map<point,int> pttoidx;
		vector<vector<pll>> G;
		auto regpt = [&](const point &pt){
			int id = pttoidx.emplace(pt, pttoidx.size()).first->second;
			if(id >= (int)pts.size()){
				pts.push_back(pt);
				G.emplace_back();
			}
			return id;
		};

		map<LL,vector<int>> ytoids;
		
		segs.emplace_back(pll(-INF, -INF), pll(-INF, INF));
		segs.emplace_back(pll(INF, -INF), pll(INF, INF));
		for(int i = 0; i < npol; ++i){
			int m;
			cin >> m;
			vector<pll> pl(m + 1);
			for(int j = 0; j < m; ++j){
				cin >> pl[j].first >> pl[j].second;
				ytoids[pl[j].second].push_back(regpt(point(pl[j].first, pl[j].second)));
			}
			pl[m] = pl[0];
			
			for(int j = 0; j < m; ++j){
				pll p1 = pl[j], p2 = pl[j + 1];
				if(p1.second > p2.second){ swap(p1, p2); }
				if(p1.second != p2.second){
					segs.emplace_back(p1, p2);
				}
				else{
					int u1 = regpt(point(p1.first, p1.second));
					int u2 = regpt(point(p2.first, p2.second));
					G[u1].emplace_back(u2, 0);
					G[u2].emplace_back(u1, 0);
				}
			}
			
			pols.emplace_back(move(pl));
		}
		
		vector<int> starts(numq), goals(numq);
		for(int i = 0; i < numq; ++i){
			LL sx, sy, gx, gy;
			cin >> sx >> sy >> gx >> gy;
			starts[i] = regpt(point(sx, sy));
			goals[i] = regpt(point(gx, gy));
			
			ytoids[sy].push_back(starts[i]);
			ytoids[gy].push_back(goals[i]);
		}

		int ns = segs.size();
		vector<vector<int>> idsonsegs(ns);
		for(int i = 0; i < ns; ++i){
			const segment &s = segs[i];
			idsonsegs[i].push_back(regpt(point(s.first.first, s.first.second)));
		}
		for(auto &pr : ytoids){
			LL y = pr.first;
			vector<pair<D,int>> itss;
			
			for(int i = 0; i < ns; ++i){
				D x;
				if(calcx(segs[i].first, segs[i].second, y, x)){
					itss.emplace_back(x, i);
				}
			}
			
			for(int id : pr.second){
				pair<D,int> prv(-INF, 0), nxt(INF, 1);
				for(const auto &p : itss){
					if(p.first < pts[id].first){
						prv = max(prv, p);
					}
					if(pts[id].first < p.first){
						nxt = min(nxt, p);
					}
				}
				
				if(!inanypol(middle(prv.first, pts[id].first), pts[id].second)){
					int k = regpt(point(prv.first, y));
					G[id].emplace_back(k, 0);
					G[k].emplace_back(id, 0);
					idsonsegs[prv.second].push_back(k);
				}
				if(!inanypol(middle(pts[id].first, nxt.first), pts[id].second)){
					int k = regpt(point(nxt.first, y));
					G[id].emplace_back(k, 0);
					G[k].emplace_back(id, 0);
					idsonsegs[nxt.second].push_back(k);
				}
			}
		}
		
		for(int i = 0; i < ns; ++i){
			regpt(point(segs[i].second.first, segs[i].second.second));
			idsonsegs[i].push_back(regpt(point(segs[i].second.first, segs[i].second.second)));
			const auto &v = idsonsegs[i];
			for(size_t j = 0; j + 1 < v.size(); ++j){
				int id1 = v[j];
				int id2 = v[j + 1];
				G[id1].emplace_back(id2, pts[id2].second - pts[id1].second);
				G[id2].emplace_back(id1, 0);
			}
		}

		priority_queue<pll> pq;
		queue<int> q;
		vector<LL> dist;
		for(int i = 0; i < numq; ++i){
			pq.emplace(0, starts[i]);
			dist.assign(G.size(), 1LL << 60);
			dist[starts[i]] = 0;
			while(!pq.empty()){
				LL d = -pq.top().first;
				while(!pq.empty() && -pq.top().first == d){
					int u = pq.top().second;
					pq.pop();
					if(dist[u] != d){ continue; }
					q.push(u);
				}
				while(!q.empty()){
					int u = q.front();
					q.pop();
					for(const pll &e : G[u]){
						LL nd = d + e.second;
						if(dist[e.first] > nd){
							dist[e.first] = nd;
							if(d == nd){
								q.push(e.first);
							}
							else{
								pq.emplace(-nd, e.first);
							}
						}
					}
				}
			}
			cout << dist[goals[i]] << '\n';
		}
	}
};
}

int main() try{
	int n;
	while(cin >> n && n){
		solver().solve(n);
	}
}
catch(const exception &ex){
	cerr << ex.what() << endl;
	abort();
}
accuracy: 1
time_ms: 4550
memory_kb: 4984
final_rank: 1