#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

struct UF{
  std::vector<int> par, dep, sz;
  UF(int n){
    par.resize(n+1), dep.resize(n+1), sz.resize(n+1);
    init(n);
  }
  void init(int nu) {
    for(int iu=0;iu<=nu;iu++){
      par[iu] = iu;
      dep[iu] = 0;
      sz[iu] = 1;
    }
  }
  int find(int xu){
    if(par[xu] == xu) return xu;
    return par[xu] = find(par[xu]);
  }
  void unite(int xu, int yu){
    xu=find(xu);
    yu=find(yu);
    if(xu == yu) return;
    if(dep[xu] < dep[yu]){
      sz[yu] += sz[xu];
      par[xu] = yu;
    }else{
      par[yu] = xu;
      sz[xu] += sz[yu];
      if(dep[xu] == dep[yu]) dep[xu]++;
    }
  }
  bool same(int xu, int yu){ return find(xu) == find(yu);}
  int get_size(int x){return sz[find(x)];}
};

void err(){
  std::cout << "No" << '\n';
  exit(0);
}

ll INF = 100000000000000;
int main(int argc, char const *argv[]) {
  ll h, w;std::cin >> h >> w;
  ll n;std::cin >> n;
  vvl d = VV(n, 3, 0, ll);
  vll r(h+1, -INF), c(w+1, -INF);
  for(int i=0;i<n;i++) scanf("%lld %lld %lld", &d[i][0], &d[i][1], &d[i][2]);
  //1つ決定するとその連結成分に関しては決められる.
  //連結成分分
  UF uf(n+1);
  vll ruse(h+1, -1), cuse(w+1, -1);

  for(int i=0;i<n;i++){
    ll x = d[i][0], y = d[i][1];
    if(ruse[x]==-1&&cuse[y]==-1){
      ruse[x] = cuse[y] = i;
    }else if(ruse[x]==-1){
      uf.unite(i, cuse[y]);
      ruse[x] = i;
    }else if(cuse[y]==-1){
      uf.unite(i, ruse[x]);
      cuse[y] = i;
    }else{
      uf.unite(ruse[x], cuse[y]);
      uf.unite(ruse[x], i);
    }
  }

  vvl G = VV(n, 0, 0, ll);
  for(int i=0;i<n;i++) G[uf.find(i)].push_back(i);
  vector<set<ll>> gx(h+1);
  vector<set<ll>> gy(w+1);

  ll min_x = 100000000000000;
  ll min_y = 100000000000000;

  for(int k=0;k<n;k++){
    if(G[k].size()==0) continue;
    vvl dat;
    for(auto t:G[k]) dat.push_back(d[t]);
    sort(all(dat), [](vll a, vll b){return a[2] < b[2];});

    ll m = dat.size();
    ll sa = -INF;
    //------------------------
    set<ll> X, Y;
    ll local_min_x = 100000000000000, local_min_y = 100000000000000;
    for(int i=0;i<m;i++){
      ll x = dat[i][0], y = dat[i][1];
      X.insert(x);
      Y.insert(y);
      gx[x].insert(i);
      gy[y].insert(i);
    }
    deque<ll> q;
    vll use(m+1, 0);
    q.push_front(0);
    vll stnum;

    while(!q.empty()){
      ll num = q.front();
      q.pop_front();
      use[num] = 1;
      stnum.push_back(num);
      ll x = dat[num][0], y = dat[num][1], T = dat[num][2];
      if(r[x]==-INF && c[y]==-INF){
        r[x] = T, c[y] = 0;
      }else if(c[y]==-INF){
        c[y] = T - r[x];
      }else if(r[x]==-INF){
        r[x] = T - c[y];
      }else if(r[x] + c[y] != T){
        sa = abs(T - r[x] - c[y]);
        break;
      }
      local_min_x = min(local_min_x, r[x]);
      local_min_y = min(local_min_y, c[y]);

      for(auto to:gx[x]) {
        if(!use[to]) {
          use[to] = 1;
          q.push_front(to);
        }
      }
      for(auto to:gy[y]) {
        if(!use[to]) {
          use[to] = 1;
          q.push_front(to);
        }
      }
    }
    //errorが起きない場合一本道
    if(sa==-INF){
      if(local_min_x+local_min_y<0) err();
      //std::cout << local_min_x << " " << local_min_y << '\n';
    }
    //----------------------------
    if(sa!=-INF){
      for(auto t:X) r[t] = -INF;
      for(auto t:Y) c[t] = -INF;
      c[dat[0][1]] = sa;
      for(auto node:stnum){
        ll x = dat[node][0], y = dat[node][1];
        if(r[x]==-INF&&c[y]==-INF){
          r[x] = dat[node][2];
          c[y] = 0;
        }else if(r[x]==-INF){
          r[x] = dat[node][2] - c[y];
        }else if(c[y]==-INF){
          c[y] = dat[node][2] - r[x];
        }else if(r[x] + c[y] != dat[node][2]){
          err();
        }
        min_x = min(min_x, r[x]);
        min_y = min(min_y, c[y]);
      }
    }
  }

  //std::cout << min_x << " " << min_y << '\n';
  if(min_x+min_y<0) err();
  std::cout << "Yes" << '\n';
  return 0;
}


Measured memory_bytes: 42872