//  [go]
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

// An Item is something we manage in a priority queue.
type Item struct {
	//value    string // The value of the item; arbitrary.
	word     string
	weight   [2]int64
	priority int // The priority of the item in the queue.
	// The index is needed by update and is maintained by the heap.Interface methods.
	//index int // The index of the item in the heap.
}

// A PriorityQueue implements heap.Interface and holds Items.
type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	// We want Pop to give us the highest, not lowest, priority so we use greater than here.
	return pq[i].priority < pq[j].priority
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	//pq[i].index = i
	//pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
	//n := len(*pq)
	item := x.(*Item)
	//item.index = n
	*pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	//item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

func nextInt() int64 {
	var i int64
	var e error
	for {
		sc.Scan()
		k := sc.Text()
		//re, _ := regexp.Compile(`\d{1,100}`)
		//t := re.FindAllStringSubmatch(k, -1)
		//k = t[0][0]
		//k = strings.TrimSpace(k)
		i, e = strconv.ParseInt(k, 10, 64)
		if e == nil {
			break
		}
	}
	return i
}
func bool2int(b bool) int {
	if b {
		return 1
	}
	return 0
}

func abs(a int64, b int64) int64 {
	if a < b {
		return b - a
	} else {
		return a - b
	}
}

func main() {
	sc.Split(bufio.ScanWords)
	r := nextInt()
	c := nextInt()
	n := nextInt()
	//dary2 := make([]bool, h)
	//fmt.Println(dary2[0])
	dary := make([][]bool, 3)
	for i := range dary {
		dary[i] = make([]bool, 3)
	}
	m := map[[2]int64]int64{}
	kk := map[[2]int64]int{}
	ans := true

	for i := int64(0); i < n; i++ {
		x := nextInt() - 1
		y := nextInt() - 1
		a := nextInt()
		//dary[a-1][b-1] = 1
		//m[b-1] = append(m[b-1], a-1)
		m[[2]int64{x, y}] = a
		for j := x - 1; j <= x; j++ {
			for k := y - 1; k <= y; k++ {
				if !(j < 0 || j > r-2 || k < 0 || k > c-2) {
					kk[[2]int64{j, k}] += 1
				}
			}
		}
	}
	pqs := len(kk)
	pq := make(PriorityQueue, pqs)
	pqi := 0
	for k, v := range kk {
		//priority := strings.Index(s, colors[i])
		pq[pqi] = &Item{
			weight:   k,
			priority: v,
		}
		pqi++
	}

	heap.Init(&pq)
	q := make([]int64, 4)
	ok := make([]bool, 4)
	pairtate := map[int64][2]int64{}
	pairyoko := map[int64][2]int64{}
	for {
		if pq.Len() == 0 {
			break
		}
		item := heap.Pop(&pq).(*Item)
		k := item.weight
		q[0], ok[0] = m[k]
		q[1], ok[1] = m[[2]int64{k[0], k[1] + 1}]
		q[2], ok[2] = m[[2]int64{k[0] + 1, k[1]}]
		q[3], ok[3] = m[[2]int64{k[0] + 1, k[1] + 1}]
		boolsum := 0
		intsum := int64(0)
		for i := 0; i < 4; i++ {
			boolsum += bool2int(ok[i])
			intsum += q[i]
		}
		if boolsum == 4 {
			if q[0]+q[3] != q[1]+q[2] {
				ans = false
			}
		} else if boolsum == 3 {
			x := k[0]
			y := k[1]
			ans2 := (q[0] + q[3]) - (q[1] + q[2])
			if !ok[2] || !ok[1] {
				ans2 = -ans2 // (q[0] + q[3]) - (q[1] + q[2])
			}
			if !ok[1] || !ok[3] {
				y += 1
			}
			if !ok[2] || !ok[3] {
				x += 1
			}
			if ans2 > 0 {
				ans = false
			}
			m[[2]int64{x, y}] = -ans2 //((q[0] + q[3]), (q[1] + q[2]))
			for j := x - 1; j <= x; j++ {
				for k := y - 1; k <= y; k++ {
					if !(j < 0 || j > r-2 || k < 0 || k > c-2) {
						if kk[[2]int64{j, k}] == 0 {
							item := Item{
								weight:   [2]int64{j, k},
								priority: kk[[2]int64{j, k}] + 1,
							}
							pt := &item
							heap.Push(&pq, pt)
						}
						//kk[[2]int64{j, k}] += 1
					}
				}
			}
		} else if boolsum == 2 {
			x := k[0]
			y := k[1]
			if !ok[0] && !ok[1] {
				p, ok := pairyoko[x]
				if ok {
					if p[0]+q[3] != p[1]+q[2] {
						ans = false
					}
				} else {
					pairyoko[x] = [2]int64{q[2], q[3]}
				}

				m[[2]int64{x, y}] = q[2]     //((q[0] + q[3]), (q[1] + q[2]))
				m[[2]int64{x, y + 1}] = q[3] //((q[0] + q[3]), (q[1] + q[2]))
			} else if !ok[0] && !ok[2] {
				p, ok := pairtate[x]
				if ok {
					if p[0]+q[3] != q[1]+p[1] {
						ans = false
					}
				} else {
					pairtate[y] = [2]int64{q[1], q[3]}
				}
				m[[2]int64{x, y}] = q[1]     //((q[0] + q[3]), (q[1] + q[2]))
				m[[2]int64{x + 1, y}] = q[3] //((q[0] + q[3]), (q[1] + q[2]))
			} else if !ok[2] && !ok[3] {
				p, ok := pairyoko[x]
				if ok {
					if p[1]+q[0] != q[1]+p[0] {
						ans = false
					}
				} else {
					pairyoko[x] = [2]int64{q[0], q[1]}
				}
				m[[2]int64{x + 1, y}] = q[0]     //((q[0] + q[3]), (q[1] + q[2]))
				m[[2]int64{x + 1, y + 1}] = q[1] //((q[0] + q[3]), (q[1] + q[2]))
			} else if !ok[1] && !ok[3] {
				p, ok := pairtate[x]
				if ok {
					if p[1]+q[0] != q[2]+p[0] {
						ans = false
					}
				} else {

					pairtate[y] = [2]int64{q[0], q[2]}
				}
				m[[2]int64{x, y + 1}] = q[0]     //((q[0] + q[3]), (q[1] + q[2]))
				m[[2]int64{x + 1, y + 1}] = q[2] //((q[0] + q[3]), (q[1] + q[2]))
			}
			/*
				if !(j < 0 || j > r-2 || k < 0 || k > c-2) {
					if kk[[2]int64{j, k}] == 0 {
						item := Item{
							weight:   [2]int64{j, k},
							priority: kk[[2]int64{j, k}] + 1,
						}
						pt := &item
						heap.Push(&pq, pt)
					}
				}
				if !(l < 0 || l > r-2 || v < 0 || v > c-2) {
					if kk[[2]int64{l, v}] == 0 {
						item := Item{
							weight:   [2]int64{l, v},
							priority: kk[[2]int64{l, v}] + 1,
						}
						pt := &item
						heap.Push(&pq, pt)
					}
				}*/
		}
		//fmt.Println(q, boolsum, m)
	}
	if ans {
		fmt.Println("Yes")
	} else {
		fmt.Println("No")
	}

}