// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
/// [Amberjack] CUT BEGIN

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <cctype>

#include <cstring>

#include <cassert>



#include <iostream>

#include <vector>

#include <set>

#include <map>

#include <unordered_set>

#include <unordered_map>

#include <queue>

#include <stack>

#include <bitset>

#include <string>

#include <complex>



#include <algorithm>

#include <utility>

#include <numeric>

#include <functional>



using namespace std;



typedef long long ll;

typedef pair<int,int> pii;

typedef pair<ll,ll> pll;

typedef vector<int> vi;

typedef vector<ll> vl;



typedef int _loop_int;

#define __GET_REP_MACRO(_1,_2,_3,NAME,...) NAME

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

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

#define __REPR0(i,n) for(_loop_int i=(n)-1;i>=0;--i)

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

#define REP(...) __GET_REP_MACRO(__VA_ARGS__,__REP1,__REP0)(__VA_ARGS__)

#define REPR(...) __GET_REP_MACRO(__VA_ARGS__,__REPR1,__REPR0)(__VA_ARGS__)



#ifdef BURI

#define __DEBUG0() "Hello"

#define __DEBUG1(x) #x"("<<(x)<<")"

#define __DEBUG2(x,...) #x"("<<(x)<<"), " __DEBUG1(__VA_ARGS__)

#define __DEBUG3(x,...) #x"("<<(x)<<"), " __DEBUG2(__VA_ARGS__)

#define __DEBUG4(x,...) #x"("<<(x)<<"), " __DEBUG3(__VA_ARGS__)

#define __DEBUG5(x,...) #x"("<<(x)<<"), " __DEBUG4(__VA_ARGS__)

#define __GET_DEBUG_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME

#define __DEBUG(...) __GET_DEBUG_MACRO(__VA_ARGS__,__DEBUG5,__DEBUG4,__DEBUG3,__DEBUG2,__DEBUG1,__DEBUG0)(__VA_ARGS__)

#define DEBUG(...) cerr<<__DEBUG(__VA_ARGS__)<<endl

#else

#define DEBUG(...)

#endif



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

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

#define CHMAX(a,b) a=max((a),(b))



#define gc getchar_unlocked

inline void getll(ll &x){

  int sgn=1;x=0;

  char c=gc();

  while(c!='-'&&(c<'0'||c>'9'))c=gc();

  if(c=='-') sgn=-1; else x=c-'0';

  c=gc();

  while('0'<=c&&c<='9'){

    x*=10;

    x+=c-'0';

    c=gc();

  }

  x*=sgn;

}

inline void read(ll &x){getll(x);}

inline void read(int &x){ll y;getll(y);x=y;}

inline void read(float &x){scanf("%f",&x);}

inline void read(double &x){scanf("%lf",&x);}

inline void read(long double &x){scanf("%Lf",&x);}

inline void read(char *s){scanf("%s",s);}

inline void read(string &s){int len=s.size();char *buf=(char*)malloc(len*sizeof(char));scanf("%s",buf);s=string(buf);free(buf);}

inline void read(char &c){char *buf=(char*)malloc(5*sizeof(char));scanf("%s",buf);c=buf[0];free(buf);}

inline void read(){}

template<typename S,typename ...T>

inline void read(S& first, T&... rest){

  read(first);

  read(rest...);

}

/// [/Amberjack] CUT END



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];

 

inline 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;

}

 

inline 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(){

  read(r,c,n);

  REP(i,n){

    read(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;

}


// Fastest known solution for this problem: