#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#define range(i,a,b) for(int i = (a); i < (b); i++)
#define rep(i,b) for(int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cout << #x << " = " << (x) << endl;
using namespace std;
typedef long long ll;
const int N=2e5+11;
const ll INF=1e18+11;
struct Edge{int nxt,to;ll w;}edge[N<<2];
int r,c,n,num_edge,head[N];
ll val[N],mn1,mn2;
bool vis[N];
ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
void add_edge(int from,int to,ll w){
	edge[++num_edge].nxt=head[from];
	edge[num_edge].to=to;
	edge[num_edge].w=w;
	head[from]=num_edge;
}
void back(){
	puts("No");
	exit(0);
}
void dfs(int u,ll sh){
	if(vis[u]){
		if(sh!=val[u]) back();
		return;
	}
	val[u]=sh;vis[u]=1;
	if(u>=r) mn2=min(mn2,val[u]);else mn1=min(mn1,val[u]);
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		dfs(v,edge[i].w-val[u]);
	}
}
int main(){
//	freopen("ex.in","r",stdin);
	r=(int)read();c=(int)read();n=(int)read();
	rep(i,n){
		int x=(int)read(),y=(int)read();ll z=read();x--;y--;
		add_edge(x,r+y,z);add_edge(r+y,x,z);
	}
	rep(i,r+c) if(!vis[i]){
		mn1=mn2=INF;
		dfs(i,0);
		if(mn1+mn2<0) back();
	}
	puts("Yes");
	return 0;
}