// Slower C++ solution:
#include <bits/stdc++.h>

 

using namespace std;

 

typedef long long ll;

typedef vector<int> vi;

typedef vector<ll> vl;

typedef pair<int,int> pii;

typedef pair<ll,ll> pll;

 

typedef int _loop_int;

#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)

#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)

#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)



#define DEBUG(x) cout<<#x<<": "<<x<<endl

#define DEBUG_VEC(v) cout<<#v<<":";REP(ix,v.size())cout<<" "<<v[ix];cout<<endl

#define ALL(a) (a).begin(),(a).end()



#define CHMIN(a,b) a=min((a),(b))



const int INF = 2125252830;



int r,c,n;

int xy[252521];

int val[125252];



int xmin[125252];

vector<pii> ys[125252];

vector<pii> g[125252];

ll dist[125252];

bool used[125252];



bool po[125252];

int a;

int node[125252];

int vere[125252];



bool check(){

  REP(i,a)vere[node[i]] = i;

  REP(i,a)dist[i] = 0;

  REP(i,a)used[i] = false;

  dist[0] = 0;

  used[0] = true;

  queue<int> Q;

  Q.push(0);

  while(!Q.empty()){

    int p = Q.front(); Q.pop();

    int id = node[p];

    ll d = dist[p];

    REP(i,g[id].size()){

      int to = vere[g[id][i].first];

      ll cost = (ll)g[id][i].second;

      ll nd = d+cost;

      if(used[to]){

        if(dist[to]!=nd)return false;

      }else{

        dist[to] = nd;

        used[to] = true;

        Q.push(to);

      }

    }

  }

  // negative check

  ll sm = *min_element(dist,dist+a);

  REP(i,a){

    if(sm + (ll)xmin[node[i]] < 0){

      return false;

    }

    if(i==a-1)break;

    sm -= dist[i+1]-dist[i];

  }

  return true;

}

 

bool valid(int n){

  REP(i,125252)po[i]=false;

  REP(i,n){

    if(po[i])continue;

    a = 0;

    po[i] = true;

    node[a++] = i;

    queue<int> Q;

    Q.push(i);

    while(!Q.empty()){

      int p = Q.front(); Q.pop();

      REP(j,g[p].size()){

        int to = g[p][j].first;

        if(po[to])continue;

        po[to] = true;

        node[a++] = to;

        Q.push(to);

      }

    }

    sort(node,node+a);

    if(!check())return false;

  }

  return true;

}



int Sx[125252],Sy[125252];

int Mx[125252],My[125252];

 

int main(){

  scanf("%d%d%d",&r,&c,&n);

  REP(i,n){

    scanf("%d%d%d",xy+2*i,xy+2*i+1,val+i);

    Sx[i] = xy[2*i];

    Sy[i] = xy[2*i+1];

  }

  sort(Sx,Sx+n);

  sort(Sy,Sy+n);

  r = unique(Sx,Sx+n)-Sx;

  c = unique(Sy,Sy+n)-Sy;

  REP(i,r)Mx[Sx[i]]=i;

  REP(i,c)My[Sy[i]]=i;



  REP(i,125252)xmin[i] = INF;

  REP(i,n){

    int x,y;

    x=Mx[xy[2*i]];

    y=My[xy[2*i+1]];

    CHMIN(xmin[y],val[i]);

    ys[x].emplace_back(y,val[i]);

  }

  // graph

  REP(i,r){

    sort(ALL(ys[i]));

    vector<pii> &vec = ys[i];

    REP(j,vec.size()-1){

      int s,t;

      s = vec[j].first;

      t = vec[j+1].first;

      int sa = vec[j+1].second - vec[j].second;

      g[s].emplace_back(t,sa);

      g[t].emplace_back(s,-sa);

    }

  }

  if(!valid(r)){

    puts("No");

    return 0;

  }

  // ok

  puts("Yes");

  return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.3485888833297703x):
#include <bits/stdc++.h>

 

using namespace std;

 

typedef long long ll;

typedef vector<int> vi;

typedef vector<ll> vl;

typedef pair<int,int> pii;

typedef pair<ll,ll> pll;

 

typedef int _loop_int;

#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)

#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)

#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)



#define DEBUG(x) cout<<#x<<": "<<x<<endl

#define DEBUG_VEC(v) cout<<#v<<":";REP(ix,v.size())cout<<" "<<v[ix];cout<<endl

#define ALL(a) (a).begin(),(a).end()



#define CHMIN(a,b) a=min((a),(b))



const int INF = 2125252830;

const int MAX = 100000;



int r,c,n;

int xy[2*MAX];

int val[MAX];



int xmin[MAX];

vector<pii> ys[MAX];

vector<pii> g[MAX];

ll dist[MAX];

bool used[MAX];



bool po[MAX];

int a;

int node[MAX];

int vere[MAX];



bool check(){

  REP(i,a)vere[node[i]] = i;

  REP(i,a)dist[i] = 0;

  REP(i,a)used[i] = false;

  dist[0] = 0;

  used[0] = true;

  queue<int> Q;

  Q.push(0);

  while(!Q.empty()){

    int p = Q.front(); Q.pop();

    int id = node[p];

    ll d = dist[p];

    REP(i,g[id].size()){

      int to = vere[g[id][i].first];

      ll cost = (ll)g[id][i].second;

      ll nd = d+cost;

      if(used[to]){

        if(dist[to]!=nd)return false;

      }else{

        dist[to] = nd;

        used[to] = true;

        Q.push(to);

      }

    }

  }

  // negative check

  ll sm = *min_element(dist,dist+a);

  REP(i,a){

    if(sm + (ll)xmin[node[i]] < 0){

      return false;

    }

    if(i==a-1)break;

    sm -= dist[i+1]-dist[i];

  }

  return true;

}

 

bool valid(int n){

  REP(i,n)po[i]=false;

  REP(i,n){

    if(po[i])continue;

    a = 0;

    po[i] = true;

    node[a++] = i;

    queue<int> Q;

    Q.push(i);

    while(!Q.empty()){

      int p = Q.front(); Q.pop();

      REP(j,g[p].size()){

        int to = g[p][j].first;

        if(po[to])continue;

        po[to] = true;

        node[a++] = to;

        Q.push(to);

      }

    }

    sort(node,node+a);

    if(!check())return false;

  }

  return true;

}



int Sx[MAX],Sy[MAX];

int Mx[MAX],My[MAX];

 

int main(){

  scanf("%d%d%d",&r,&c,&n);

  REP(i,n){

    scanf("%d%d%d",xy+2*i,xy+2*i+1,val+i);

    Sx[i] = xy[2*i];

    Sy[i] = xy[2*i+1];

  }

  sort(Sx,Sx+n);

  sort(Sy,Sy+n);

  r = unique(Sx,Sx+n)-Sx;

  c = unique(Sy,Sy+n)-Sy;

  REP(i,r)Mx[Sx[i]]=i;

  REP(i,c)My[Sy[i]]=i;



  REP(i,c)xmin[i] = INF;

  REP(i,n){

    int x,y;

    x=Mx[xy[2*i]];

    y=My[xy[2*i+1]];

    CHMIN(xmin[y],val[i]);

    ys[x].emplace_back(y,val[i]);

  }

  // graph

  REP(i,r){

    sort(ALL(ys[i]));

    vector<pii> &vec = ys[i];

    REP(j,vec.size()-1){

      int s,t;

      s = vec[j].first;

      t = vec[j+1].first;

      int sa = vec[j+1].second - vec[j].second;

      g[s].emplace_back(t,sa);

      g[t].emplace_back(s,-sa);

    }

  }

  if(!valid(r)){

    puts("No");

    return 0;

  }

  // ok

  puts("Yes");

  return 0;

}