#include <iostream>
#include <string>
#include <sstream>
#include <limits>
#include <vector>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>

using namespace std;

// 隣接リストを用いたグラフ構造
// （Weight は、可換群（アーベル群）... operator+, operator- が実装されていること）
// （ABEL_UNITY は、可換群（アーベル群）Weight の単位元）
template <typename Weight = int, Weight ABEL_UNITY = 0>
struct PotentialUnionFind
{
	// 第i頂点が属するグループの親
	vector<int> parent;
	// 第i頂点のランク（ぶらさがる木の最大深さ）
	vector<int> rank;
	// 第i頂点の親との重みの差
	vector<Weight> diffWeight;

	// n個の頂点を事前に生成する
	void resize (size_t n)
	{
		parent.reserve(n);
		for (int i=parent.size(); i<n; ++i)
		{
			parent.push_back(i);
		}

		rank.resize(n, 0);
		diffWeight.resize(n, ABEL_UNITY);
	}

	// 頂点n個分のメモリ領域を事前に確保する
	void reserve (size_t n)
	{
		parent.reserve(n);
		rank.reserve(n);
		diffWeight.reserve(n);
	}

	// 頂点を1つ追加する（返り値は頂点番号）
	int addVertex ()
	{
		int index = parent.size();
		parent.push_back(index);
		rank.push_back(0);
		diffWeight.push_back(ABEL_UNITY);
		return index;
	}

	// グループの親
	int root (int vertex)
	{
		if (vertex == parent[vertex])
		{
			return vertex;
		}
		else
		{
			int r = root(parent[vertex]);
			diffWeight[vertex] += diffWeight[parent[vertex]]; // 重みの累積和をとる

			// 経路圧縮
			return parent[vertex] = r;
		}
	}

	// 同じグループに属しているか
	bool isSame (int vertex1, int vertex2)
	{
		return root(vertex1) == root(vertex2);
	}

	// vertex1 から vertex2 への重みの変分が weight となる
	// ように、グループを結合
	bool merge (int vertex1, int vertex2, Weight weight)
	{
		// 親の重みの差を計算
		weight += this->weight(vertex1);
		weight -= this->weight(vertex2);

		// グループの親の取得
		vertex1 = root(vertex1);
		vertex2 = root(vertex2);

		// 親が既に同じときはマージ済み
		if (vertex1 == vertex2) return false;

		// 深さの大きいほうを vertex1 にして
		if (rank[vertex1] < rank[vertex2])
		{
			swap(vertex1, vertex2);
			weight = -weight;
		}
		// 深さが同じなら vertex1 を持ち上げて
		else if (rank[vertex1] == rank[vertex2]) ++rank[vertex1];

		// vertex2 を vertex1 にぶら下げる
		parent[vertex2] = vertex1;
		diffWeight[vertex2] = weight;

		return true;
	}

	// 頂点の重み
	Weight weight (int vertex)
	{
		// 経路圧縮と重み累積和の計算
		root(vertex);
		return diffWeight[vertex];	
	}

	// vertex1 から vertex2 への重みの変分
	Weight diff (int vertex1, int vertex2)
	{
		return weight(vertex2) - weight(vertex1);
	}
};

// 使用例（AOJ 2207 無矛盾な単位系）

int main ()
{
	int n;
	while (true)
	{
		cin >> n;
		if (0 == n) break;

		PotentialUnionFind<int> unionfind;
		unionfind.reserve(200);

		unordered_map<string, int> unit;

		string _, unit1, value, unit2;
		bool ok = true;
		for (int i=0; i<n; ++i)
		{
			cin >> _ >> unit1 >> _ >> value >> unit2;

			if (!ok) continue;

			// 単位の登録
			if (unit.end() == unit.find(unit1))
			{
				unit[unit1] = unionfind.addVertex();
			}
			if (unit.end() == unit.find(unit2))
			{
				unit[unit2] = unionfind.addVertex();
			}

			// 指数のみ取得
			int diff;
			stringstream(value.substr(3)) >> diff;

			int id1 = unit[unit1];
			int id2 = unit[unit2];

			// 単位に関係があるなら
			if (unionfind.isSame(id1, id2))
			{
				int current_diff = unionfind.diff(id1, id2);
				if (diff != current_diff) ok = false;
			}
			else
			{
				unionfind.merge(id1, id2, diff);
			}
		}

		cout << (ok ? "Yes" : "No") << endl;
	}
	return 0;
}



Measured memory_bytes: 3088