//#include "IntMod.h"
//typedef IntMod<1000000007> MInt;

//#include "Union_Find.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <utility>
#include <algorithm>
#include <functional>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <array>
#include <bitset>

using namespace std;
#define REP(i,a,n) for(int i = (a); i < (int)(n); ++i)
#define REPM(i,n,a) for(int i = ((n) - 1); i >= (a); --i)
#define EPS 0.0001
#define INF 0x3FFFFFFF
#define INFLL 0x3FFFFFFF3FFFFFFF
#define INFD 1.0e+308
#define FLOAT setprecision(16)
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<LL, LL> PP;

template <class T, class U>
istream& operator>>(istream& ist, pair<T, U>& right) { return ist >> right.first >> right.second; }
template <class T, class U>
ostream& operator<<(ostream& ost, pair<T, U>& right) { return ost << right.first << ' ' << right.second; }
template <class T, class TCompatible, size_t N>
void Fill(T(&dest)[N], const TCompatible& val) { fill(begin(dest), end(dest), val); }
template <class T, class TCompatible, size_t M, size_t N>
void Fill(T(&dest)[M][N], const TCompatible& val) { for (int i = 0; i < M; ++i) Fill(dest[i], val); }
// all_of

#if 1
#include <unordered_set>
#include <unordered_map>
template<typename T>
using PriorityQ = priority_queue<T, vector<T>, greater<T> >;	// コスト小を優先
#endif

struct Point {
	LL idx, r, c, a;
};

int H, W, N;
LL R[100000], C[100000], A[100000];
vector<Point> V;
vector<LL> G[100000];
bool used[100000];

LL rwall[100000], cwall[100000];


bool wfs(int i) {
	queue<int> Q;
	Q.push(i);

	LL rmin = INFLL, cmin = INFLL;
	while (!Q.empty()) {
		int from = Q.front(); Q.pop();
		if (used[from]) continue;
		used[from] = true;

		int r = V[from].r;
		int c = V[from].c;
		LL a = V[from].a;
		bool rb = rwall[r] != INFLL;
		bool cb = cwall[c] != INFLL;
		if (rb && cb) {
			if (rwall[r] + cwall[c] != a) return false;
		} else if (rb || cb) {
			if (rb) {
				cwall[c] = a - rwall[r];
			} else {
				rwall[r] = a - cwall[c];
			}
		} else {
			rwall[r] = 0;
			cwall[c] = a;
		}

		rmin = min(rmin, rwall[r]);
		cmin = min(cmin, cwall[c]);
		for (int to : G[from]) {
			Q.push(to);
		}
	}
	return rmin + cmin >= 0;
}

int main() {
	cin >> H >> W >> N;
	REP(i, 0, N) {
		cin >> R[i] >> C[i] >> A[i];
		--R[i]; --C[i];
		V.push_back(Point{ i, R[i], C[i], A[i] });
	}
	sort(V.begin(), V.end(), [](Point a, Point b) {return a.r < b.r; });
	REP(i, 0, N - 1) {
		if (V[i].r == V[i + 1].r) {
			G[V[i].idx].push_back(V[i + 1].idx);
			G[V[i + 1].idx].push_back(V[i].idx);
		}
	}
	sort(V.begin(), V.end(), [](Point a, Point b) {return a.c < b.c; });
	REP(i, 0, N - 1) {
		if (V[i].c == V[i + 1].c) {
			G[V[i].idx].push_back(V[i + 1].idx);
			G[V[i + 1].idx].push_back(V[i].idx);
		}
	}
	sort(V.begin(), V.end(), [](Point a, Point b) {return a.idx < b.idx; });
	Fill(rwall, INFLL);
	Fill(cwall, INFLL);
	bool ok = true;
	REP(i, 0, N) {
		if (used[i]) continue;
		ok &= wfs(i);
	}
	cout << (ok ? "Yes" : "No") << endl;
	return 0;
}



Measured memory_bytes: 15468