Problem:
Problem D:
無矛盾な単位系
京、垓、{禾予}、穣、溝、澗、正、載、極、恒河沙、阿僧祇、那由他、不可思議、無量大数
分、厘、毛、糸、忽、微、繊、沙、塵、埃、渺、漠、模糊、逡巡、須臾、瞬息、弾指、刹那、六徳、虚空、清浄、阿頼耶、阿摩羅、涅槃寂静
これらが何か分かるだろうか。これらは全て10の累乗につけられた数詞である。
京 = 10
16
, 垓 = 10
20
, {禾予} = 10
24
, 穣 = 10
28
, 溝 = 10
32
, ...
分 = 10
-1
、厘 = 10
-2
、毛 = 10
-3
、糸 = 10
-4
、忽 = 10
-5
, ...
ではこれらが実用的に使われているのを見たことはあるだろうか？無いのではなかろうか？ 過去の先人達が熟考の末にこれらの命名を行ったにもかかわらず、これらの数詞が日の目を見られないとはなんと勿体無いことだろう。
この問題は、コンテスト参加者の皆様にこれらの数詞を知ってもらうために作られたものである。以下に問題の概要を示す。
1 km = 10
3
m
上記のような単位間の関係が入力として与えられる。この問題では、左辺における単位が右辺における単位の10の累乗倍となっているような単位間の関係だけが与えられる。
単位間の関係が矛盾しているとは、与えられた関係から以下の関係が同時に成り立つことをいう。
1 A = 10
x
B
1 A = 10
y
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

Submitted solutions:

code_snippet: // #define _GLIBCXX_DEBUG 1
#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
#define ll long long
#define ull unsigned long long

#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = 0; i < n; i++)
#define rep_1(i, s, n) for (int i = s; i < n + s; i++)
#define rep_2(i, s, t, n) for (int i = s; i <= n; i += t)
#define rep_overload(e1, e2, e3, e4, f, ...) f
#define rep(...) rep_overload(__VA_ARGS__, rep_2, rep_1, rep_0)(__VA_ARGS__)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define repr1(i, n) for (int i = n; i > 0; i--)

auto chmax = [](auto& a, auto b) {bool ret=a<b; if(ret)a=b; return ret; };
auto chmin = [](auto& a, auto b) {bool ret=a>b; if(ret)a=b; return ret; };
template <typename T>
using pq_inv = priority_queue<T, vector<T>, greater<T>>;
vector<int> dd4 = {1, 0, -1, 0, 1};                // rep(i,4) nh=h+dd4[i]; nw=w+dd4[i+1];
vector<int> dd8 = {1, 0, -1, 0, 1, 1, -1, -1, 1};  // rep(i,8) nh=h+dd8[i]; nw=w+dd8[i+1];
// using mint = atcoder::modint1000000007;
// using mint = atcoder::modint998244353;

template <typename T>
struct WeightedUnionFind {
    vector<int> par, rank;
    vector<T> diff_weight;
    WeightedUnionFind(int n) {
        init(n);
    }
    void init(int n) {
        par.assign(n, -1);
        rank.assign(n, 0);
        diff_weight.assign(n, 0);
    }
    int root(int x) {
        if (par[x] == -1) return x;
        int r = root(par[x]);
        diff_weight[x] += diff_weight[par[x]];
        return par[x] = r;
    }
    T weight(int x) {
        root(x);
        return diff_weight[x];
    }

    bool is_same(int x, int y) {
        return root(x) == root(y);
    }
    bool merge(int x, int y, T w) {
        w += weight(x) - weight(y);
        x = root(x);
        y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) rank[x]++;
        par[y] = x;
        diff_weight[y] = w;
        return true;
    }

    T diff(int x, int y) {
        return weight(y) - weight(x);
    }
};

void solve(int N) {
    map<string, int> mp;
    WeightedUnionFind<int> wuf(300);
    bool ok = true;
    rep(i, N) {
        string s;
        while (true) {
            getline(cin, s);
            if (s != "") break;
        };
        // parse number from string input wigh regex
        // 1 kilometer = 10^3 m
        regex re(R"(\d+ (.*?) = 10\^(-?\d+) (.*))");
        smatch m;
        regex_search(s, m, re);
        if (mp.count(m[1]) == 0) mp[m[1]] = mp.size();
        if (mp.count(m[3]) == 0) mp[m[3]] = mp.size();
        if (wuf.is_same(mp[m[1]], mp[m[3]])) {
            if (wuf.diff(mp[m[1]], mp[m[3]]) != stoi(m[2])) ok = false;
        } else {
            wuf.merge(mp[m[1]], mp[m[3]], stoi(m[2]));
        }
    }
    cout << (ok ? "Yes" : "No") << endl;
}

int main() {
    std::cin.tie(nullptr);
    // int T;
    // // cin >> T;
    // T = 1;
    // for (int i = 0; i < T; i++) {
    //     // solve(i);
    //     solve();
    // }

    while (true) {
        int N;
        cin >> N;
        if (N == 0) break;
        solve(N);
    }
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3452
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include<iomanip>
#include<functional>
#include<algorithm>
#include<deque>
#include<math.h>
#include<set>
#include<cstdio>
#include<string>
#include<queue>
#include<complex>
#include<numeric>
#include<stack>
#include<unordered_map>
#include<map>
#include <cassert>
using namespace std;
#define rep(i,n) for(int i = 0;i<n;i++)
#define req(i,n) for(ll i = 1;i<=n;i++)
#define rrep(i,n) for(int i = n-1;i>=0;i--)
#define ALL(a) a.begin(),a.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
typedef long long ll;
typedef long double ld;
template<class Abel> struct UnionFind {
    vector<int> par, rank;
    vector<Abel> diff_weight;
    UnionFind(int n = 1, Abel SUM_UNITY = 0) {
        init(n, SUM_UNITY);
    }
    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
    }
    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            diff_weight[x] += diff_weight[par[x]];
            return par[x] = r;
        }
    }
    Abel weight(int x) {
        root(x);
        return diff_weight[x];
    }
    bool same(int x, int y) {
        return root(x) == root(y);
    }
    bool merge(int x, int y, Abel w) {
        w += weight(x); w -= weight(y);
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        diff_weight[y] = w;
        return true;
    }
    Abel diff(int x, int y) {
        return weight(y) - weight(x);
    }
};
int main() {
    int n, m;
    while (cin >> n,n) {
        bool f = 1; int id = 0,a,b; map<string, int> mp;
        UnionFind<int> uf(200);
        rep(i, n) {
            char c; string s, t, u, v;
            cin >> c >> s >> t >> u >> v;
            if (!mp.count(s)) mp[s] = id++;
            a = mp[s];
            if (!mp.count(v)) mp[v] = id++;
            b = mp[v]; int dif;
            stringstream si(u.substr(3));
            si >> dif;
            if (uf.same(a, b)) {
                int cur = uf.diff(a, b);
                if (dif != cur)f = 0;
            }
            else uf.merge(a, b, dif);
        }if (f) puts("Yes");
        else puts("No");
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3120
final_rank: 6

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 6 "/home/yuruhiya/programming/library/template/constants.cpp"
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1e9;
constexpr long long inf_ll = 1e18, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = next_char(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 4 "/home/yuruhiya/programming/library/DataStructure/WeightedUnionFind.cpp"
using namespace std;

template <class T> class WeightedUnionFind {
	vector<int> par_m, rank_m;
	vector<T> weight_m;

public:
	WeightedUnionFind(int n) : par_m(n), rank_m(n, 0), weight_m(n, 0) {
		for (int i = 0; i < n; ++i) par_m[i] = i;
	}
	int root(int x) {
		if (par_m[x] == x) {
			return x;
		} else {
			int r = root(par_m[x]);
			weight_m[x] += weight_m[par_m[x]];
			return par_m[x] = r;
		}
	}
	T weight(int x) {
		root(x);
		return weight_m[x];
	}
	bool same(int x, int y) {
		return root(x) == root(y);
	}
	bool merge(int x, int y, T w) {
		w += weight(x);
		w -= weight(y);
		x = root(x);
		y = root(y);
		if (x == y) return false;
		if (rank_m[x] < rank_m[y]) {
			swap(x, y);
			w = -w;
		}
		if (rank_m[x] == rank_m[y]) rank_m[x]++;
		par_m[y] = x;
		weight_m[y] = w;
		return true;
	}
	T diff(int x, int y) {
		return weight(y) - weight(x);
	}
};
#line 3 "a.cpp"

bool solve(int n) {
	VS str = step(n) | Map([&](int i) { return in.read_line(); });
	dump(str);

	int k = 0;
	map<string, int> index;
	WeightedUnionFind<int> uf(200);

	for (const string& s : str) {
		smatch result;
		regex_search(s, result, regex("1 (\\w+) = 10\\^([\\-\\d]+) (\\w+)"));
		string s1 = result[1].str(), s2 = result[3].str();
		int i1 = index.count(s1) ? index[s1] : index[s1] = k++;
		int i2 = index.count(s2) ? index[s2] : index[s2] = k++;
		dump(result[2].str());
		int val = stoi(result[2].str());
		if (uf.same(i1, i2)) {
			if (uf.diff(i1, i2) != val) {
				return false;
			}
		} else {
			uf.merge(i1, i2, val);
		}
	}
	return true;
}

int main() {
	for (int n = in; n; n = in) {
		out(solve(n));
	}
}
accuracy: 1
time_ms: 200
memory_kb: 3480
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
using ll = long long;
using P = pair<ll, ll>;
ll GCD(ll a, ll b) { return b?GCD(b, a%b):a; }
ll LCM(ll a, ll b) { return a/GCD(a, b)*b; }

template<class Abel> struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<Abel> diff_weight;

    UnionFind(int n = 1, Abel SUM_UNITY = 0) {
        init(n, SUM_UNITY);
    }

    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for(int i = 0; i < n; ++i) {
            par[i] = i; rank[i] = 0; diff_weight[i] = SUM_UNITY;
        }
    }

    int find(int x) {
        if(par[x] == x) return x;
        else {
            int r = find(par[x]);
            diff_weight[x] += diff_weight[par[x]];  // 累積和を取る
            return par[x] = r;
        }
    }

    Abel weight(int x) {
        find(x);
        return diff_weight[x];
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    bool unite(int x, int y, Abel w) {
        w += weight(x); w -= weight(y); // xとyそれぞれについて、rootとの重み差分を補正
        x = find(x); y = find(y);
        if(x == y) return false;
        if(rank[x] < rank[y]) swap(x, y), w = -w;   // rank[x] >= rank[y]になるようにswap
        if(rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        diff_weight[y] = w; // xがyの親になるので、xとyの差分をdiff_weight[y]に記録
        return true;
    }

    // 重みを取得する
    Abel diff(int x, int y) {
        return weight(y) - weight(x);
    }
};

int n;

int xcalc(string z) {
    int zlen = z.length();
    int zfin = zlen - 3;
    string subz = z.substr(3, zfin);
    int ret = 0;
    if(subz.at(0) == '-') {
        subz.at(0) = '0';
        ret = stoi(subz);
        ret = -ret;
    }else {
        ret = stoi(subz);
    }
    return ret;
}

int main() {
    while(1) {
        cin >> n;
        if(n == 0) break;
        UnionFind<ll> uf(200);
        bool flg = true;
        map<string, int> mdata;
        int cnt = 0;
        for(int i = 0; i < n; ++i) {
            int one;
            string A, eq, x, B;
            cin >> one >> A >> eq >> x >> B;
            if(mdata[A] == 0) {
                mdata[A] = cnt+1; cnt++;
            }
            if(mdata[B] == 0) {
                mdata[B] = cnt+1; cnt++;
            }

            int ch = xcalc(x);
            if(uf.same(mdata[A]-1, mdata[B]-1)) {
                // もし繋がっていたら
                if(uf.diff(mdata[A]-1, mdata[B]-1) != ch) flg = false;
            }else {
                // 繋がっていなかったら
                uf.unite(mdata[A]-1, mdata[B]-1, ch);
            }
        }

        if(flg) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3116
final_rank: 5

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <map>
using namespace std;

template<class Abel> struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<Abel> diff_weight;

    UnionFind(int n = 1, Abel SUM_UNITY = 0) {
        init(n, SUM_UNITY);
    }

    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            diff_weight[x] += diff_weight[par[x]];
            return par[x] = r;
        }
    }

    Abel weight(int x) {
        root(x);
        return diff_weight[x];
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y, Abel w) {
        w += weight(x); w -= weight(y);
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        diff_weight[y] = w;
        return true;
    }

    Abel diff(int x, int y) {
        return weight(y) - weight(x);
    }
};

vector<string> split_native(const string &s, char delim) {
    vector<string> elems;
    string item;
    for (char ch: s) {
        if (ch == delim) {
            if (!item.empty())
                elems.push_back(item);
            item.clear();
        }
        else {
            item += ch;
        }
    }
    if (!item.empty())
        elems.push_back(item);
    return elems;
}

int main(){
    int N;

    while(cin >> N){
        if(N ==0) break;

        UnionFind<int> UF(200);
        map<string, int> m;
        int idx = 0;
        bool flag = true;

        for(int i=0; i<N; ++i){
            string one, unit1, equal, val, unit2;
            cin >> one >> unit1 >> equal >> val >> unit2;
            if(m.count(unit1) == 0){
                m[unit1] = idx;
                ++idx;
            }
            int id1 = m[unit1];

            if(m.count(unit2) == 0){
                m[unit2] = idx;
                ++idx;
            }
            int id2 = m[unit2]; 

            int w;
            vector<string> vec;
            vec = split_native(val, '^');
            w = stoi(vec[1]);

            if(UF.issame(id1, id2)){
                int diff = UF.diff(id1, id2);
                if(diff != w) flag = false;
            }else{
                UF.merge(id1, id2, w);
            }                 
        }
        if(flag){
            puts("Yes");
        }else{
            puts("No");
        }
    }    
}
accuracy: 1
time_ms: 10
memory_kb: 3192
final_rank: 13

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <map>
using namespace std;

template<class Abel> struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<Abel> diff_weight;

    UnionFind(int n = 1, Abel SUM_UNITY = 0) {
        init(n, SUM_UNITY);
    }

    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            diff_weight[x] += diff_weight[par[x]];
            return par[x] = r;
        }
    }

    Abel weight(int x) {
        root(x);
        return diff_weight[x];
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y, Abel w) {
        w += weight(x); w -= weight(y);
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        diff_weight[y] = w;
        return true;
    }

    Abel diff(int x, int y) {
        return weight(y) - weight(x);
    }
};

// vector<string> split_native(const string &s, char delim) {
//     vector<string> elems;
//     string item;
//     for (char ch: s) {
//         if (ch == delim) {
//             if (!item.empty())
//                 elems.push_back(item);
//             item.clear();
//         }
//         else {
//             item += ch;
//         }
//     }
//     if (!item.empty())
//         elems.push_back(item);
//     return elems;
// }

int main(){
    int N;

    while(cin >> N){
        if(N ==0) break;

        UnionFind<int> UF(200);
        map<string, int> m;
        int idx = 0;
        bool flag = true;

        for(int i=0; i<N; ++i){
            string one, unit1, equal, val, unit2;
            cin >> one >> unit1 >> equal >> val >> unit2;
            if(m.count(unit1) == 0){
                m[unit1] = idx;
                ++idx;
            }
            int id1 = m[unit1];

            if(m.count(unit2) == 0){
                m[unit2] = idx;
                ++idx;
            }
            int id2 = m[unit2]; 

            // int w;
            // vector<string> vec;
            // vec = split_native(val, '^');
            // w = stoi(vec[1]);

            // 単位換算の倍率の取得
            stringstream si(val.substr(3));
            int w;
            si >> w; // "1 kilometre = 10^3 metre" の 3 の部分を取得


            if(UF.issame(id1, id2)){
                int diff = UF.diff(id1, id2);
                if(diff != w) flag = false;
            }else{
                UF.merge(id1, id2, w);
            }                 
        }
        if(flag){
            puts("Yes");
        }else{
            puts("No");
        }
    }    
}
accuracy: 1
time_ms: 10
memory_kb: 3132
final_rank: 8

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <map>
using namespace std;

template<class Abel> struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<Abel> diff_weight;

    UnionFind(int n = 1, Abel SUM_UNITY = 0) {
        init(n, SUM_UNITY);
    }

    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            diff_weight[x] += diff_weight[par[x]];
            return par[x] = r;
        }
    }

    Abel weight(int x) {
        root(x);
        return diff_weight[x];
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y, Abel w) {
        w += weight(x); w -= weight(y);
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        diff_weight[y] = w;
        return true;
    }

    Abel diff(int x, int y) {
        return weight(y) - weight(x);
    }
};

// vector<string> split_native(const string &s, char delim) {
//     vector<string> elems;
//     string item;
//     for (char ch: s) {
//         if (ch == delim) {
//             if (!item.empty())
//                 elems.push_back(item);
//             item.clear();
//         }
//         else {
//             item += ch;
//         }
//     }
//     if (!item.empty())
//         elems.push_back(item);
//     return elems;
// }

int main(){
    int N;

    while(cin >> N){
        if(N ==0) break;

        UnionFind<int> UF(200);
        map<string, int> m;
        int idx = 0;
        bool flag = true;

        for(int i=0; i<N; ++i){
            string one, unit1, equal, val, unit2;
            cin >> one >> unit1 >> equal >> val >> unit2;
            if(m.count(unit1) == 0){
                m[unit1] = idx;
                ++idx;
            }
            int id1 = m[unit1];

            if(m.count(unit2) == 0){
                m[unit2] = idx;
                ++idx;
            }
            int id2 = m[unit2]; 

            // int w;
            // vector<string> vec;
            // vec = split_native(val, '^');
            // w = stoi(vec[1]);

            // 単位換算の倍率の取得
            stringstream si(val.substr(3));
            int w;
            si >> w; // "1 kilometre = 10^3 metre" の 3 の部分を取得


            if(UF.issame(id1, id2)){
                int diff = UF.diff(id1, id2);
                if(diff != w) flag = false;
            }else{
                UF.merge(id1, id2, w);
            }                 
        }

        if (flag) puts("Yes");
        else puts("No");
    }    
}
accuracy: 1
time_ms: 10
memory_kb: 3092
final_rank: 4

code_snippet: #include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
using namespace std;

template<class Abel> struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<Abel> diff_weight;

    UnionFind(int n = 1, Abel SUM_UNITY = 0) {
        init(n, SUM_UNITY);
    }

    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            diff_weight[x] += diff_weight[par[x]];
            return par[x] = r;
        }
    }

    Abel weight(int x) {
        root(x);
        return diff_weight[x];
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y, Abel w) {
        w += weight(x); w -= weight(y);
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        diff_weight[y] = w;
        return true;
    }

    Abel diff(int x, int y) {
        return weight(y) - weight(x);
    }
};

int main() {
    int N;
    while (cin >> N) {
        if (N == 0) break;
        bool ok = true;
        UnionFind<int> uf(200); // 単位個数は最悪で 200 個
        map<string,int> str2id; // 単位 -> id の対応
        int final_id = 0;
        for (int i = 0; i < N; ++i) {
            string ichi, unit1, equal, val, unit2;
            cin >> ichi >> unit1 >> equal >> val >> unit2;

            // 1個目の単位の番号
            if (!str2id.count(unit1)) {
                str2id[unit1] = final_id++;
            }
            int id1 = str2id[unit1];

            // 2個目の単位の番号
            if (!str2id.count(unit2)) {
                str2id[unit2] = final_id++;
            }
            int id2 = str2id[unit2];

            // 単位換算の倍率の取得
            stringstream si(val.substr(3));
            int diff;
            si >> diff; // "1 kilometre = 10^3 metre" の 3 の部分を取得

            // 重み付き Union-Find 木の処理
            if (uf.issame(id1, id2)) {
                int curdiff = uf.diff(id1, id2);
                if (diff != curdiff) ok = false;
            }
            else {
                uf.merge(id1, id2, diff);
            }
        }

        if (ok) puts("Yes");
        else puts("No");
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3188
final_rank: 12

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <sstream>
#include <map>
using namespace std;

template<typename T>
struct WeightedUnionFind {
    vector<int> data;
    vector<T> ws;
    WeightedUnionFind(int sz) : data(sz, -1), ws(sz) { }
    bool merge(int x, int y, T w) {             // ws(y) = ws(x) + w
        w += weight(x); w -= weight(y);
        if ((x = root(x)) == (y = root(y))) return false;
        if (data[x] > data[y]) swap(x, y), w = -w;
        data[x] += data[y]; data[y] = x; ws[y] = w;
        return true;
    }
    bool find(int x, int y) { return root(x) == root(y); }
    T diff(int x, int y) { return weight(y) - weight(x); }
    T weight(int t) { root(t); return ws[t]; }
    int root(int k) {
        if (data[k] < 0) return k;
        int par = root(data[k]);
        ws[k] += ws[data[k]];
        return data[k] = par;
    }
};

template<typename F, typename T>
void convert(const F &f, T &t) { stringstream ss; ss << f; ss >> t; }

int main() {
    int N;
    while (cin >> N, N) {
        bool ok = true;
        WeightedUnionFind<int> wuf(200);
        map<string, int> str2id;
        int cnt = 0;
        for (int i = 0; i < N; ++i) {
            string one, unit1, equal, val, unit2;
            cin >> one >> unit1 >> equal >> val >> unit2;
            if (!str2id.count(unit1)) str2id[unit1] = cnt++;
            int id1 = str2id[unit1];
            if (!str2id.count(unit2)) str2id[unit2] = cnt++;
            int id2 = str2id[unit2];
            int diff;
            convert(val.substr(3), diff);
            if (wuf.find(id1, id2)) {
                int curdiff = wuf.diff(id1, id2);
                if (diff != curdiff) ok = false;
            } else {
                wuf.merge(id1, id2, diff);
            }
        }
        puts(ok ? "Yes" : "No");
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3124
final_rank: 7

code_snippet: #include <algorithm>
#include <cstdio>
#include <vector>
#include <string>
#include <map>
using namespace std;

template <typename T>
struct Edge { int src, dst; T cost;
    Edge(int dst, T cost) : src(-1), dst(dst), cost(cost) { }
    Edge(int src, int dst, T cost) : src(src), dst(dst), cost(cost) { }
};
template <typename T> using Edges = vector<Edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
template <typename T> using Matrix = vector<vector<T>>;

template <typename T>
void warshall_floyd(Matrix<T> &g) {
    const T INF = numeric_limits<T>::max();
    for (int k = 0; k < g.size(); k++) {
        for (int i = 0; i < g.size(); i++) if (g[i][k] != INF) {
            for (int j = 0; j < g.size(); j++) if (g[k][j] != INF) {
                g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
            }
        }
    }
}

int main() {
    const auto INF = numeric_limits<int>::max();
    int N;
    while (scanf("%d%*c", &N), N) {
        map<string, int> unit2id;
        Matrix<int> mat(200, vector<int>(200, INF));
        for (int i = 0; i < 200; i++) mat[i][i] = 0;
        int n = 0;
        while (N--) {
            char s[32], t[32]; int val;
            scanf("1 %s = 10^%d %s", s, &val, t); getchar();
            string s1 = s, s2 = t;
            if (!unit2id.count(s1)) unit2id[s1] = n++;
            if (!unit2id.count(s2)) unit2id[s2] = n++;
            int id1 = unit2id[s1], id2 = unit2id[s2];
            mat[id1][id2] =  val;
            mat[id2][id1] = -val;
        }
        warshall_floyd(mat);
        bool ok = true;
        for (int i = 0; i < n; i++) ok &= mat[i][i] == 0;
        puts(ok ? "Yes" : "No");
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 2892
final_rank: 2

code_snippet: #include<iostream>
#include<vector>
#include<map>
#include<queue>
using namespace std;

const int INF = 1<<29;
int main(){
    int n;
    while(cin >> n, n){
        map<string, int> enc;
        vector<vector<int>> path(200, vector<int>(200, INF));
        int cnt = 0;
        string x, a, b, c;
        for(int i = 0; i < n; i++){
            cin >> x >> a >> x >> c >> b;
            int val = stoi(c.substr(3));
            if(enc.count(a) == 0)   enc[a] = cnt++;
            if(enc.count(b) == 0)   enc[b] = cnt++;
            path[enc[a]][enc[b]] = val;
            path[enc[b]][enc[a]] = -val;
        }
        // run dijkstra from all vertexes
        bool valid = true;
        for(int i = 0; i < cnt && valid; i++){
            vector<int> dp(cnt, INF);
            dp[i] = 0;
            queue<int> q;
            q.push(i);
            while(valid && !q.empty()){
                int pos = q.front(); q.pop();
                for(int j = 0; j < cnt; j++){
                    if(path[pos][j] == INF)   continue;
                    if(dp[j] == INF){
                        dp[j] = dp[pos]+path[pos][j];
                        q.push(j);
                    }else if(dp[pos]+path[pos][j] != dp[j]){
                        valid = false;
                        break;
                    }
                }
            }
        }
        cout << (valid ? "Yes" : "No") << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3336
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

template <typename T>
struct UF {
  int n;
  T d;
  vector<int> r, p;
  vector<T> ws;
  UF() {}
  UF(int sz, T d_) :
    n(sz), d(d_), r(n, 1), p(n), ws(n, d) { iota(p.begin(), p.end(), 0); }
  int find(int x) {
    if ( x == p[x] ) {
      return x;
    } else {
      int t = find(p[x]);
      ws[x] += ws[p[x]];
      return p[x] = t;
    }
  }

  T weight(int x) {
    find(x);
    return ws[x];
  }

  bool same(int x, int y) {
    return find(x) == find(y);
  }

  void unite(int x, int y, T w) {
    w += weight(x);
    w -= weight(y);
    x = find(x); y = find(y);
    if ( x == y ) return;
    if ( r[x] < r[y] ) swap(x, y), w = -w;
    r[x] += r[y];
    p[y] = x;
    ws[y] = w;
  }

  T diff(int x, int y) {
    return weight(y) - weight(x);    
  }
};

signed main(){
	int n;
	while(cin>>n,n){
		UF<int> U(2*n,0);
		map<string,int>M;
		int cnt=0,F=0;
		for(int i=0;i<n;i++){
			int a,D;
			string b,c,e,d;
			cin>>a>>b>>c>>d>>e;
			d=d.substr(3);
			stringstream SS(d);
			SS>>D;
			//cout<<D<<endl;
			if(!M.count(b)) M[b]=cnt++;
			if(!M.count(e)) M[e]=cnt++;
			if(U.same(M[b],M[e])&&U.diff(M[b],M[e])!=D)F=1;
			U.unite(M[b],M[e],D);
			//cout<<F<<endl;
		}
		if(F)goto L;
		cout<<"Yes"<<endl;
		if(0){
			L:;
			cout<<"No"<<endl;
		}
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3184
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long

template <typename T>
struct UF {
  int n;
  T d;
  vector<int> r, p;
  vector<T> ws;
  UF() {}
  UF(int sz, T d_) :
    n(sz), d(d_), r(n, 1), p(n), ws(n, d) { iota(p.begin(), p.end(), 0); }
  int find(int x) {
    if ( x == p[x] ) {
      return x;
    } else {
      int t = find(p[x]);
      ws[x] += ws[p[x]];
      return p[x] = t;
    }
  }

  T weight(int x) {
    find(x);
    return ws[x];
  }

  bool same(int x, int y) {
    return find(x) == find(y);
  }

  void unite(int x, int y, T w) {
    w += weight(x);
    w -= weight(y);
    x = find(x); y = find(y);
    if ( x == y ) return;
    if ( r[x] < r[y] ) swap(x, y), w = -w;
    r[x] += r[y];
    p[y] = x;
    ws[y] = w;
  }

  T diff(int x, int y) {
    return weight(y) - weight(x);    
  }
};

signed main() {
  int n;
  while ( cin >> n, n ) {
    bool flag = true;    
    UF<int> uf(2*n+1, 0);
    map<string, int> stoi;
    int cnt = 0;
    for ( int i = 0; i < n; i++ ) {
      int a;
      string b, c, d, e;
      cin >> a >> b >> c >> d >> e;      
      if ( !flag ) continue;
      if ( !stoi.count(b) ) stoi[b] = cnt++;
      if ( !stoi.count(e) ) stoi[e] = cnt++;

      int numd = 0;
      for ( int i = 0; i < (int)d.size(); i++ ) {
	if ( d[i] == '^' ) {
	  i++;	  
	  int mi = 1;	  
	  if ( d[i] == '-' ) mi = -1, i++;
	  for ( ; i < (int)d.size(); i++ ) {
	    numd *= 10;
	    numd += d[i]-'0';	    
	  }
	  numd *= mi;       
	}
      }
      // cout << stoi[b] << " " <<  stoi[e] << endl;
      if ( uf.same(stoi[b], stoi[e]) && uf.diff(stoi[b], stoi[e]) != numd ) {	
	flag = false;
	continue;	
      }
      uf.unite(stoi[b], stoi[e], numd);
      // cout << uf.diff(stoi[e], stoi[b]) << endl;
    }

    if ( flag ) cout << "Yes" << endl;
    else cout << "No" << endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3180
final_rank: 10

code_snippet: #include <algorithm>
#include <cstdio>
#include <vector>
#include <string>
#include <map>
using namespace std;
const int INF = (int)1e9 + 7;

int main() {
    int N;
    while (scanf("%d%*c", &N), N) {
        map<string, int> unit2id;
        vector<vector<int>> dp(200, vector<int>(200, INF));
        int n = 0;
        while (N--) {
            char s[32], t[32]; int val;
            scanf("1 %s = 10^%d %s", s, &val, t); getchar();
            string s1 = s, s2 = t;
            if (unit2id.find(s1) == unit2id.end()) unit2id[s1] = n++;
            if (unit2id.find(s2) == unit2id.end()) unit2id[s2] = n++;
            int id1 = unit2id[s1], id2 = unit2id[s2];
            dp[id1][id2] =  val;
            dp[id2][id1] = -val;
        }
        // WarshallFloyd
        for (int k = 0; k < n; k++) {
            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
                if (dp[i][k] != INF && dp[k][j] != INF) {
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
                }
            }
        }
        bool ok = true;
        for (int i = 0; i < n; i++) if (dp[i][i] != 0) ok = false;
        puts(ok ? "Yes" : "No");
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 2888
final_rank: 1

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <sstream>
#include <map>
using namespace std;

template<class Abel> struct UnionFind {
    vector<int> par;
    vector<int> rank;
    vector<Abel> diff_weight;
    UnionFind(int n = 1, Abel SUM_UNITY = 0) { init(n, SUM_UNITY); }
    void init(int n = 1, Abel SUM_UNITY = 0) {
        par.resize(n); rank.resize(n); diff_weight.resize(n);
        for (int i = 0; i < n; ++i) {
            par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
        }
    }
    int root(int x) {
        if (par[x] == x) {
            return x;
        } else {
            int r = root(par[x]);
            diff_weight[x] += diff_weight[par[x]];
            return par[x] = r;
        }
    }
    Abel weight(int x) { root(x); return diff_weight[x]; }
    bool issame(int x, int y) { return root(x) == root(y); }
    // weight(y) - weight(x) = w となるように merge
    bool merge(int x, int y, Abel w) {
        w += weight(x); w -= weight(y);
        if ((x = root(x)) == (y = root(y))) return false;
        if (rank[x] < rank[y]) swap(x, y), w = -w;
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x; diff_weight[y] = w;
        return true;
    }
    Abel diff(int x, int y) { return weight(y) - weight(x); }
};

int main() {
    int N;
    while (cin >> N, N) {
        bool ok = true;
        UnionFind<int> uf(200);
        map<string, int> str2id;
        int cnt = 0;
        for (int i = 0; i < N; ++i) {
            string one, unit1, equal, val, unit2;
            cin >> one >> unit1 >> equal >> val >> unit2;
            if (!str2id.count(unit1)) str2id[unit1] = cnt++;
            int id1 = str2id[unit1];
            if (!str2id.count(unit2)) str2id[unit2] = cnt++;
            int id2 = str2id[unit2];
            stringstream ss(val.substr(3));
            int diff;
            ss >> diff;
            if (uf.issame(id1, id2)) {
                int curdiff = uf.diff(id1, id2);
                if (diff != curdiff) ok = false;
            } else {
                uf.merge(id1, id2, diff);
            }
        }
        puts(ok ? "Yes" : "No");
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3196
final_rank: 14

code_snippet: #include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
using namespace std;

template<class Abel> struct UnionFind {
	vector<int> par;
	vector<int> rank;
	vector<Abel> diff_weight;

	UnionFind(int n = 1, Abel SUM_UNITY = 0) {
		init(n, SUM_UNITY);
	}

	void init(int n = 1, Abel SUM_UNITY = 0) {
		par.resize(n); rank.resize(n); diff_weight.resize(n);
		for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
	}

	int root(int x) {
		if (par[x] == x) {
			return x;
		}
		else {
			int r = root(par[x]);
			diff_weight[x] += diff_weight[par[x]];
			return par[x] = r;
		}
	}

	Abel weight(int x) {
		root(x);
		return diff_weight[x];
	}

	bool issame(int x, int y) {
		return root(x) == root(y);
	}

	bool merge(int x, int y, Abel w) {
		w += weight(x); w -= weight(y);
		x = root(x); y = root(y);
		if (x == y) return false;
		if (rank[x] < rank[y]) swap(x, y), w = -w;
		if (rank[x] == rank[y]) ++rank[x];
		par[y] = x;
		diff_weight[y] = w;
		return true;
	}

	Abel diff(int x, int y) {
		return weight(y) - weight(x);
	}
};

int main() {
    int N;
    while (cin >> N) {
        if (N == 0) break;
        bool ok = true;
        UnionFind<int> uf(200); // 単位個数は最悪で 200 個
        map<string,int> str2id; // 単位 -> id の対応
        int final_id = 0;
        for (int i = 0; i < N; ++i) {
            string ichi, unit1, equal, val, unit2;
            cin >> ichi >> unit1 >> equal >> val >> unit2;
        
            // 1個目の単位の番号
            if (!str2id.count(unit1)) {
                str2id[unit1] = final_id++;
            }
            int id1 = str2id[unit1];
        
            // 2個目の単位の番号
            if (!str2id.count(unit2)) {
                str2id[unit2] = final_id++;
            }
            int id2 = str2id[unit2];
        
            // 単位換算
            stringstream si(val.substr(3));
            int diff;
            si >> diff; // "1 kilometre = 10^3 metre" の 3 の部分を取得
        
            // 重み付き Union-Find 木の処理
            if (uf.issame(id1, id2)) {
                int curdiff = uf.diff(id1, id2);
                if (diff != curdiff) ok = false;
            }
            else {
                uf.merge(id1, id2, diff);
            }
        }
        
        if (ok) puts("Yes");
        else puts("No");
	}
}
accuracy: 1
time_ms: 10
memory_kb: 3032
final_rank: 3

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;


struct aUnionFind {
	vector<pair<int, long long int>> data;
	aUnionFind(int size) : data(size, make_pair(-1, 0)) { }

	//y is w bigger than x
	bool unionSet(const int x, const int y, const long long int w) {
		const int rx(root(x).first), ry(root(y).first);
		if (rx != ry) {
			data[rx].first += data[ry].first; data[ry].first = rx;
			data[ry].second = w + data[x].second - data[y].second;
			return true;
		}
		else {
			return root(x).second + w == root(y).second;
		}
	}

	//x is belong to first
	//x is second bigger than first
	pair<int, long long int> root(const int x) {
		if (data[x].first < 0) {
			return make_pair(x, 0);
		}
		else {
			pair<int, long long int>ndata;
			ndata.first = root(data[x].first).first;
			ndata.second = data[x].second + root(data[x].first).second;
			return data[x] = ndata;
		}
	}
	int size(const int x) {
		return -data[root(x).first].first;
	}
};



int main() {
	
	while (true) {
		int T;cin>>T;
		if(!T)break;
		map<string,int>mp;
		int id=0;
		aUnionFind uf(1000);
		bool ok=true;
		while (T--) {
			string one,name1,eq,num,name2;
			cin>>one>>name1>>eq>>num>>name2;

			if (mp.find(name1) == mp.end()) {
				mp[name1]=id++;
			}
			if (mp.find(name2) == mp.end()) {
				mp[name2]=id++;
			}

			string n_st(num);
			int anum=stoi(n_st.substr(3));

			if (uf.root(mp[name1]).first != uf.root(mp[name2]).first) {
				uf.unionSet(mp[name1],mp[name2],anum);
			}
			else {
				if (uf.root(mp[name1]).second + anum == uf.root(mp[name2]).second) {

				}
				else {
					ok=false;
				}
			}
		}
		if(ok)cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3196
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	int loc;
};

int N;
char name_table[200][17];
char left_table[100][17],relative[100][17],right_table[100][17];

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

Info info[200];

int get_relative(char buf[17]){

	int ret = 0;

	if(buf[3] == '-'){
		for(int i = 4; buf[i] != '\0'; i++){
			ret = 10*ret+buf[i]-'0';
		}
		ret*= -1;
	}else{
		for(int i = 3; buf[i] != '\0'; i++){
			ret = 10*ret+buf[i]-'0';
		}
	}
	return ret;
}

void func(){

	for(int i = 0; i < 100; i++){
		info[i].loc = -1;
	}

	int tmp;
	char buf[2];

	for(int i = 0; i < N; i++){
		scanf("%d %s %s %s %s",&tmp,left_table[i],buf,relative[i],right_table[i]);
	}

	strcpy(name_table[0],left_table[0]);
	strcpy(name_table[1],right_table[0]);

	int index = 2;
	tmp = get_relative(relative[0]);
	info[0].loc = 10000;
	info[1].loc = 10000-tmp;

	int used_num = 1;
	int left_index,right_index;
	int eq_num;

	bool FLG;

	vector<int> V;
	for(int i = 1; i < N; i++)V.push_back(i);
	int V_loc;

	while(used_num < N){

		FLG = false;

		for(int i = 0; i < V.size(); i++){

			left_index = -1;
			for(int k = 0; k < index; k++){
				if(strCmp(name_table[k],left_table[V[i]])){
					left_index = k;
					break;
				}
			}

			right_index = -1;
			for(int k = 0; k < index; k++){
				if(strCmp(name_table[k],right_table[V[i]])){
					right_index = k;
					break;
				}
			}

			if(left_index != -1 || right_index != -1){
				FLG = true;
				eq_num = V[i];
				V_loc = i;
				break;
			}
		}

		if(!FLG){
			for(int i = 0; i < V.size(); i++){

				eq_num = V[i];
				V_loc = i;
				break;
			}

			V.erase(V.begin()+V_loc);
			used_num++;

			strcpy(name_table[index],left_table[eq_num]);
			strcpy(name_table[index+1],right_table[eq_num]);
			tmp = get_relative(relative[eq_num]);
			info[index].loc = 10000;
			info[index+1].loc = info[index].loc-tmp;
			index += 2;
			continue;
		}

		V.erase(V.begin()+V_loc);
		used_num++;

		if(left_index == -1){
			strcpy(name_table[index],left_table[eq_num]);
			tmp = get_relative(relative[eq_num]);
			info[index].loc = info[right_index].loc+tmp;
			index++;
		}else if(right_index == -1){
			strcpy(name_table[index],right_table[eq_num]);
			tmp = get_relative(relative[eq_num]);
			info[index].loc = info[left_index].loc-tmp;
			index++;
		}else{
			tmp = get_relative(relative[eq_num]);

			if(info[left_index].loc-info[right_index].loc != tmp){
				printf("No\n");
				return;
			}
		}
	}

	printf("Yes\n");
}

int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3128
final_rank: 16

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	int loc;
};

int N;
char name_table[200][17];
char left_table[100][17],relative[100][17],right_table[100][17];

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

Info info[200];
bool used[100];

int get_relative(char buf[17]){

	int ret = 0;

	if(buf[3] == '-'){
		for(int i = 4; buf[i] != '\0'; i++){
			ret = 10*ret+buf[i]-'0';
		}
		ret*= -1;
	}else{
		for(int i = 3; buf[i] != '\0'; i++){
			ret = 10*ret+buf[i]-'0';
		}
	}
	return ret;
}

void func(){

	for(int i = 0; i < 100; i++){
		info[i].loc = -1;
		used[i] = false;
	}

	int tmp;
	char buf[2];

	for(int i = 0; i < N; i++){
		scanf("%d %s %s %s %s",&tmp,left_table[i],buf,relative[i],right_table[i]);
	}

	strcpy(name_table[0],left_table[0]);
	strcpy(name_table[1],right_table[0]);

	int index = 2;
	tmp = get_relative(relative[0]);
	info[0].loc = 10000;
	info[1].loc = 10000-tmp;
	used[0] = true;

	int used_num = 1;
	int left_index,right_index;
	int eq_num;

	bool FLG;

	while(used_num < N){

		FLG = false;

		for(int i = 1; i < N; i++){
			if(used[i])continue;

			left_index = -1;
			for(int k = 0; k < index; k++){
				if(strCmp(name_table[k],left_table[i])){
					left_index = k;
					break;
				}
			}

			right_index = -1;
			for(int k = 0; k < index; k++){
				if(strCmp(name_table[k],right_table[i])){
					right_index = k;
					break;
				}
			}

			if(left_index != -1 || right_index != -1){
				FLG = true;
				eq_num = i;
				break;
			}
		}

		if(!FLG){
			for(int i = 1; i < N; i++){
				if(used[i])continue;

				eq_num = i;
				break;
			}

			used[eq_num] = true;
			used_num++;

			strcpy(name_table[index],left_table[eq_num]);
			strcpy(name_table[index+1],right_table[eq_num]);
			tmp = get_relative(relative[eq_num]);
			info[index].loc = 10000;
			info[index+1].loc = info[index].loc-tmp;
			index += 2;
			continue;
		}

		used[eq_num] = true;
		used_num++;

		if(left_index == -1){
			strcpy(name_table[index],left_table[eq_num]);
			tmp = get_relative(relative[eq_num]);
			info[index].loc = info[right_index].loc+tmp;
			index++;
		}else if(right_index == -1){
			strcpy(name_table[index],right_table[eq_num]);
			tmp = get_relative(relative[eq_num]);
			info[index].loc = info[left_index].loc-tmp;
			index++;
		}else{
			tmp = get_relative(relative[eq_num]);

			if(info[left_index].loc-info[right_index].loc != tmp){
				printf("No\n");
				return;
			}
		}
	}

	printf("Yes\n");
}

int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3068
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;

int G[200][200];
int tmp[200][200];

map<string,int> mp;

int func(string s){
  if(mp.count(s)==0){
    int res=mp.size();
    mp[s]=res;
    return res;
  }else{
    return mp[s];
  }
}

int getNum(string s){
  for(int i=0;i<(int)s.size();i++)
    if(s[i]=='^')s[i]=' ';
  stringstream ss(s);
  int res;
  ss>>res;
  ss>>res;
  return res;
}

void init(){
  fill(G[0],G[200], 1e9);
  mp.clear();
  for(int i=0;i<200;i++)
    G[i][i]=0;
}

int main(){
  int n;
  while(1){
    cin>>n;
    if(n==0)break;
    init();
    bool ans=true;
    for(int i=0;i<n;i++){
      string A,B,C,D,E;
      cin>>A>>B>>C>>D>>E;
      int a=func(B);
      int b=func(E);
      int c=getNum(D);
      if(G[b][a]!=1e9&&G[b][a]!=c)ans=false;
      G[b][a]=c;
      G[a][b]=-c;
    }
    int size=mp.size();
    for(int i=0;i<size;i++){
      for(int j=0;j<size;j++){
        tmp[i][j]=G[i][j];
      }
    }
    
    for(int k=0;k<size;k++)
      for(int i=0;i<size;i++)
        for(int j=0;j<size;j++)
          G[i][j]=min(G[i][j],G[i][k]+G[k][j]);

    for(int i=0;i<size;i++)
      for(int j=0;j<size;j++)
        if(tmp[i][j]!=1e9 && G[i][j]!=tmp[i][j])ans=false;

    cout<< (ans?"Yes":"No") <<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3464
final_rank: 18