Problem:
Problem D: 無矛盾な単位系

京、垓、{禾予}、穣、溝、澗、正、載、極、恒河沙、阿僧祇、那由他、不可思議、無量大数
分、厘、毛、糸、忽、微、繊、沙、塵、埃、渺、漠、模糊、逡巡、須臾、瞬息、弾指、刹那、六徳、虚空、清浄、阿頼耶、阿摩羅、涅槃寂静

これらが何か分かるだろうか。これらは全て10の累乗につけられた数詞である。

京 = 1016, 垓 = 1020, {禾予} = 1024, 穣 = 1028, 溝 = 1032, ...
分 = 10-1、厘 = 10-2、毛 = 10-3、糸 = 10-4、忽 = 10-5, ...

ではこれらが実用的に使われているのを見たことはあるだろうか？無いのではなかろうか？ 過去の先人達が熟考の末にこれらの命名を行ったにもかかわらず、これらの数詞が日の目を見られないとはなんと勿体無いことだろう。

この問題は、コンテスト参加者の皆様にこれらの数詞を知ってもらうために作られたものである。以下に問題の概要を示す。

1 km = 103 m

上記のような単位間の関係が入力として与えられる。この問題では、左辺における単位が右辺における単位の10の累乗倍となっているような単位間の関係だけが与えられる。
単位間の関係が矛盾しているとは、与えられた関係から以下の関係が同時に成り立つことをいう。

1 A = 10x B
1 A = 10y B

ただし、 x≠yであり、 AとBは任意の単位。

入力として与えられた単位間の関係が矛盾しているかどうか判定せよ。 なお、入力は簡易のため指数表記で与えられる。

Input

入力の一行目に、単位間の関係の個数を示す整数 N (1≤ N ≤ 100) が与えられる。

続くN行に、単位間の関係が含まれる。
単位間の関係は以下のフォーマットで与えられる。

"1 A = 10^x B"

A, B は単位を示す。AとBは相異なっており、それぞれ空白を含まないアルファベット小文字1〜16文字からなる。x は -100から100までの整数である。
"1 A = 10^x B" が定義されたとき、 "1 B = 10^-x A" も暗黙のうちに定義されているものとする。

任意の単位系のペアが2回以上定義されることはない。
すなわち、"1 kilobyte = 10^3 byte", "1 kilobyte = 10^1 byte" のような関係が、同時に入力に含まれることはない。
同様に、"1 kilobyte = 10^3 byte", "1 byte = 10^-3 kilobyte" のような関係が、同時に入力に含まれることはない。

Output

与えられた単位系が矛盾していなければ Yes を、 矛盾していれば No を出力せよ。

Notes on Test Cases

上記入力形式で複数のデータセットが与えられます。各データセットに対して上記出力形式で出力を行うプログラムを作成して下さい。

N が 0 のとき入力の終わりを示します。

Sample Input

3
1 km = 10^3 m
1 m = 10^2 cm
1 km = 10^5 cm
7
1 kilometre = 10^3 metre
1 megametre = 10^3 kilometre
1 metre = 10^-6 megametre
1 terametre = 10^3 gigametre
1 petametre = 10^3 terametre
1 gigametre = 10^-6 petametre
1 metre = 10^-15 petametre
4
1 a = 10^2 b
1 a = 10^3 c
1 b = 10^2 c
1 c = 10^1 d
4
1 acm = 10^2 icpc
1 icpc = 10^3 utpc
1 utpc = 10^4 topcoder
1 topcoder = 10^-1 acm
0

Output for Sample Input

Yes
Yes
No
No

Solution in JAVA (judge verdict: Accepted)

import java.awt.geom.Point2D;
import java.util.*;

import static java.lang.Math.*;
public class Main {
	final Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		new Main().init();
	}
	void init(){
		new AOJ2207();
	}
	class AOJ2207{
		int N;
		final int INF=1<<29;
		AOJ2207(){
			while(sc.hasNext()){
				N=sc.nextInt();
				if(N==0)	break;
				solve();
			}
		}
		void solve(){
			ArrayList<Edge> es=new ArrayList<Edge>();
			HashMap<String,Integer> map=new HashMap<String,Integer>();
			int kind=0;
			for(int i=0; i<N; ++i){
				sc.nextInt();
				String as=sc.next();
				int a=-1;
				if(map.containsKey(as))	a=map.get(as);
				else{
					a=kind;
					map.put(as, kind);
					++kind;
				}
				sc.next();
				int c=Integer.parseInt(sc.next().substring(3));
				String bs=sc.next();
				int b=-1;
				if(map.containsKey(bs))	b=map.get(bs);
				else{
					b=kind;
					map.put(bs, kind);
					++kind;
				}
				es.add(new Edge(a,b,c));
				es.add(new Edge(b,a,-c));
			}
//			System.out.println(es);

			bellmanFord bf=new bellmanFord(map.size(), es);
			for(int i=0; i<map.size(); ++i)if(bf.shortestPath(i)==null){
				System.out.println("No");
				return;
			}
			System.out.println("Yes");
		}
		class bellmanFord{
			final int INF=1<<29;
			int V,E;
			ArrayList<Edge> es;
			int[] d;
			bellmanFord(int V,ArrayList<Edge> es){
				this.V=V; this.es=es; this.E=es.size();
			}
			// startから到達可能な負の閉路があればnull．それ以外はstartからの最短経路．
			int[] shortestPath(int start){
				d=new int[V];
				for(int i=0; i<V; ++i)	d[i]=INF;
				d[start]=0;
				for(int i=1; i<=V; ++i){
					boolean update=false;
					for(Edge e:es){
						if(d[e.from]<INF && d[e.to]>d[e.from]+e.cost){
							d[e.to]=d[e.from]+e.cost;
							update=true;
							if(i==V)	return null;
						}
					}
					if(!update)	break;
				}
				return d;
			}
		}
		class Edge implements Comparable<Edge>{
			int from,to,cost;
			Edge(int from,int to,int cost){
				this.from=from;	this.to=to;	this.cost=cost;
			}
			@Override public int compareTo(Edge e){
				return this.cost-e.cost;
			}
			@Override public String toString(){
				return from+"->"+to+":"+cost;
			}
		}
	}
}