#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

//// < "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\a.txt" > "d:\d_download\visual studio 2015\projects\programing_contest_c++\debug\b.txt"


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;
		}
	}
	bool findSet(const int x, const int y) {
		return root(x) == root(y);
	}

	//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;
	}
};

struct aa {
	int r;
	int c;
	int a;
};

int main() {
	//{

	//string st; cin >> st;
	//vector<int>nums(st.size());
	//for (int i = 0; i < st.size(); ++i) {
	//	nums[i] = st[i] - 'a';
	//}
	//int N; cin >> N;
	//int rest(N);
	//for (int i = 0; i < st.size(); ++i) {
	//	int num;
	//	if (rest >= 26 - nums[i]) {
	//		num = 26 - nums[i];
	//	}
	//	else {
	//		num = 0;
	//	}
	//	rest -= num;
	//	nums[i] += num;
	//	nums[i] %= 26;
	//}
	//nums[st.size()-1] += rest;
	//nums[st.size() - 1] %= 26;
	//for (int i = 0; i < st.size(); ++i) {
	//	char c('a' + nums[i]);
	//	cout << c;
	//}
	//cout << endl;

	//}
	{

		int R, C; cin >> R >> C;
		int N; cin >> N;
		
		vector<vector<pair<int,int>>>rs(R),cs(C);
		vector<aa>aas;
		for (int i = 0; i < N; ++i) {
			int r, c, a; cin >> r >> c >> a;
			r--; c--;
			aas.push_back(aa{ r,c,a });
			rs[r].emplace_back(c, a);
			cs[c].emplace_back(r, a);
		}
		bool ok = true;
		aUnionFind uf(C);
		//aUnionFind buf(R);
		{
			for (auto ar : rs) {
				if (ar.size() >= 2) {
					for (int i = 0; i < ar.size() - 1; ++i) {
						auto l(uf.root(ar[i].first));
						auto r(uf.root(ar[i + 1].first));
						if (l.first == r.first) {

							if (l.second - ar[i].second != r.second - ar[i + 1].second)ok = false;
						}
						else {

							uf.unionSet(ar[i].first, ar[i + 1].first, ar[i + 1].second - ar[i].second);
						}
					}
				}
			}
		}
		{
			/*for (auto ac : cs) {
				if (ac.size() >= 2) {
					for (int i = 0; i < ac.size() - 1; ++i) {
						auto l(uf.root(ac[i].first));
						auto r(uf.root(ar[i + 1].first));
						if (l.first == r.first) {

							if (l.second - ar[i].second != r.second - ar[i + 1].second)ok = false;
						}
						else {

							uf.unionSet(ar[i].first, ar[i + 1].first, ar[i + 1].second - ar[i].second);
						}
					}
				}
			}*/
		}
		
		if (ok) {
			
			map<int, vector<int>>rootmp;
			for (int i = 0; i < N; ++i) {
				auto arootp(uf.root(aas[i].c));
				rootmp[arootp.first].push_back(i);
			}
			for (auto rm : rootmp) {
				int amin = 2e9 + 1;
				for (auto r : rm.second) {
					auto p(uf.root(aas[r].c));
					amin = min(amin, int(p.second));
				}
				for (auto r : rm.second) {
					auto p(uf.root(aas[r].c));
					int num = aas[r].a - p.second + amin;
					if (num < 0) {
						ok = false;
					}
				}
			}
		}

		if (ok)cout << "Yes" << endl;
		else cout << "No" << endl;
	}

	return 0;
}

Measured memory_bytes: 24884