import java.io.*;
import java.util.*;

class Main{

    void solve(){
        int xmax = ni();
        int xmin = 0;
        int ymax = ni();
        int ymin = 0;
        int n = ni();
        for(int i = 0; i < n; i++){
            int x = ni();
            int y = ni();
            int a = ni();
            switch(a){
                case 1:
                    xmin = max(x, xmin);
                    break;
                case 2:
                    xmax = min(x, xmax);
                    break;
                case 3:
                    ymin = max(y, ymin);
                    break;
                case 4:
                    ymax = min(y, ymax);
                    break;
            }
        }

        int width = 0;
        if(xmax > xmin){
            width = xmax - xmin;
        }
        int height = 0;
        if(ymax > ymin){
            height = ymax - ymin;
        }
        System.out.println(height * width);

    }

    public static void main(String[] args){
        new Main().solve();
    }

    private FastScanner scan = new FastScanner();
    private final int MOD = 1_000_000_007;
    private final int INF = 2147483647;
    private final long LINF = 9223372036854775807L;
    private long[] fac;
    private long[] finv;
    private long[] inv;

    // Scanner
    int ni(){ return scan.nextInt();}
    int[] ni(int n){int[] a = new int[n]; for(int i = 0; i < n; i++){a[i] = ni();} return a;}
    int[][] ni(int y, int x){int[][] a = new int[y][x];
        for(int i = 0; i < y; i++){for(int j = 0; j < x; j++){a[i][j] = ni();}} return a;}
    long nl(){return scan.nextLong();}
    long[] nl(int n){long[] a = new long[n]; for(int i = 0; i < n; i++){a[i] = nl();} return a;}
    long[][] nl(int y, int x){long[][] a = new long[y][x];
        for(int i = 0; i < y; i++){for(int j = 0; j < x; j++){a[i][j] = nl();}} return a;}
    String ns(){return scan.next();}
    String[] ns(int n){String[] a = new String[n]; for(int i = 0; i < n; i++){a[i] = ns();} return a;}
    String[][] ns(int y, int x){String[][] a = new String[y][x];
        for(int i = 0; i < y; i++){for(int j = 0; j < x; j++){a[i][j] = ns();}} return a;}

    // Mathematics
    int max(int a, int b){return Math.max(a, b);}
    long max(long a, long b){return Math.max(a, b);}
    double max(double a, double b){return Math.max(a, b);}
    int max(int[] a){int max = a[0]; for(int value:a){max = max(max,value);} return max;}
    long max(long[] a){long max = a[0]; for(long value:a){max = max(max,value);} return max;}
    double max(double[] a){double max = a[0]; for(double value:a){max = max(max,value);} return max;}
    int min(int a, int b){return Math.min(a, b);}
    long min(long a, long b){return Math.min(a, b);}
    double min(double a, double b){return Math.min(a, b);}
    int min(int[] a){int min = a[0]; for(int value:a){min = min(min,value);} return min;}
    long min(long[] a){long min = a[0]; for(long value:a){min = min(min,value);} return min;}
    double min(double[] a){double min = a[0]; for(double value:a){min = min(min,value);} return min;}
    long sum(int[] a){long sum = 0; for(int value:a){sum += value;} return sum;}
    long sum(long[] a){long sum = 0; for(long value:a){sum += value;} return sum;}
    double sum(double[] a){double sum = 0; for(double value:a){sum += value;} return sum;}
    int gcd(int a, int b){return b == 0 ? a : gcd(b, a % b);}
    long gcd(long a, long b){return b == 0 ? a : gcd(b, a % b);}
    int lcm(int a, int b){return a / gcd(a, b) * b;}
    long lcm(long a, long b){return a / gcd(a, b) * b;}
    long fact(int n){ if(n == 0){ return 1; } long a = n; for(long i = n - 1; i >= 2; i--){ a = a % MOD * i; } return a; }
    long fact(long n){ if(n == 0){ return 1; } long a = n; for(long i = n - 1; i >= 2; i--){ a = a % MOD * i; } return a; }
    // nPr(int)
    long npr(int n, int r){
        long a = 1;
        for(int i = n; i > n - r; i--){
            a *= i;
        }
        return a;
    }
    // nPr(long)
    long npr(long n, long r){
        long a = 1;
        for(long i = n; i > n - r; i--){
            a *= i;
        }
        return a;
    }
    // 素数判定(int)
    boolean checkPrime(int n){
        for(int i = 2; i * i <= n; i++){
            if(n % i == 0){
                return false;
            }
        }
        return true;
    }
    // 素数判定(long)
    boolean checkPrime(long n){
        for(long i = 2; i * i <= n; i++){
            if(n % i == 0){
                return false;
            }
        }
        return true;
    }
    // エラトステネスの篩
    List<Integer> erathos(int n){
        boolean[] flag = new boolean[n + 1];
        List<Integer> nums = new ArrayList<>();
        for(int i = 2; i <= n; i++){
            if(flag[i]) continue;
            nums.add(i);
            for(int j = i * 2; j <= n; j += i){
                flag[j] = true;
            }
        }

        return nums;
    }

    // mod pにおける累乗 a^n
    long modpow(long a, long n, long p){
        long res = 1;
        while(n > 0){
            if((n & 1) == 1){
                res = res * a % p;
            }
            a = a * a % p;
            n = n >> 1;
        }
        return res;
    }
    // mod pにおけるaの逆元a^-1
    long modinv(long a, long p){
        return modpow(a, p - 2, p);
    }
    // fac,finv,invの初期化
    void comInit(int max){
        fac = new long[max];
        finv = new long[max];
        inv = new long[max];
        fac[0] = fac[1] = 1;
        finv[0] = finv[1] = 1;
        inv[1] = 1;
        for(int i = 2; i < max; i++){
            fac[i] = fac[i - 1] * i % MOD;
            inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
            finv[i] = finv[i - 1] * inv[i] % MOD;
        }
    }
    // 二項係数nCr
    long com(int n, int r){
        if(n < r || (n < 0 || r < 0)){
            return 0;
        }
        return fac[n] * (finv[r] * finv[n - r] % MOD) % MOD;
    }
    // 二項係数nCr（nが10^9など巨大なとき用）
    long ncr(long n, long k){
        long a = 1;
        long b = 1;
        for(int i = 1; i <= k; i++){
            a = a * (n + 1 - i) % MOD;
            b = b * i % MOD;
        }

        return modinv(b, MOD) * a % MOD;
    }
    // 二次元上の二点間の距離
    double distance(double x1, double y1, double x2, double y2){
        double dist = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        return dist;
    }
    // 三次元上の二点間の距離
    double distance(double x1, double y1, double z1, double x2, double y2, double z2){
        double dist = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
        return dist;
    }

    // Array
    void sort(int[] a){ Arrays.sort(a);}
    void sort(long[] a){ Arrays.sort(a);}
    void sort(double[] a){ Arrays.sort(a);}
    void sort(String[] a){ Arrays.sort(a);}
    int[] reverse(int[] a){
        int[] reversed = new int[a.length];
        for(int i = 0; i < a.length; i++){
            reversed[a.length - i - 1] = a[i];
        }
        return reversed;
    }
    long[] reverse(long[] a){
        long[] reversed = new long[a.length];
        for(int i = 0; i < a.length; i++){
            reversed[a.length - i - 1] = a[i];
        }
        return reversed;
    }
    double[] reverse(double[] a){
        double[] reversed = new double[a.length];
        for(int i = 0; i < a.length; i++){
            reversed[a.length - i - 1] = a[i];
        }
        return reversed;
    }
    char[] reverse(char[] a){
        char[] reversed = new char[a.length];
        for(int i = 0; i < a.length; i++){
            reversed[a.length - i - 1] = a[i];
        }
        return reversed;
    }
    String[] reverse(String[] a){
        String[] reversed = new String[a.length];
        for(int i = 0; i < a.length; i++){
            reversed[a.length - i - 1] = a[i];
        }
        return reversed;
    }
    boolean[] reverse(boolean[] a){
        boolean[] reversed = new boolean[a.length];
        for(int i = 0; i < a.length; i++){
            reversed[a.length - i - 1] = a[i];
        }
        return reversed;
    }
    void fill(int[] array, int x) { Arrays.fill(array, x); }
    void fill(long[] array, long x) { Arrays.fill(array, x); }
    void fill(double[] array, double x) { Arrays.fill(array, x); }
    void fill(boolean[] array, boolean x) { Arrays.fill(array, x); }
    void fill(int[][] array, int x) { for(int a[] : array) { fill(a, x); } }
    void fill(long[][] array, long x) { for(long a[] : array) { fill(a, x); } }
    void fill(double[][] array, double x) { for(double a[] : array) { fill(a, x); } }
    void fill(boolean[][] array, boolean x) { for(boolean a[] : array) { fill(a, x); } }
    void fill(int[][][] array, int x) { for(int[][] ary : array) { for(int[] a : ary){ fill(a, x); } } }
    void fill(long[][][] array, long x) { for(long[][] ary : array) { for(long[] a : ary){ fill(a, x); } } }

    // Algorithm
    // 深さ優先探索
    void dfs(Node[] nodes, int v, boolean[] seen){
        seen[v] = true;

        for(Edge edge : nodes[v].edges){
            if(seen[edge.to]) continue;
            dfs(nodes, edge.to, seen);
        }

    }
    // 幅優先探索
    long[] bfs(Node[] nodes, int start){
        Queue<Integer> queue = new ArrayDeque<>();
        queue.add(start);
        long[] dist = new long[nodes.length];
        fill(dist, -1);
        dist[start] = 0;

        while(!queue.isEmpty()){
            int now = queue.poll();
            for(Edge edge : nodes[now].edges){
                if(dist[edge.to] != -1) continue;
                dist[edge.to] = dist[now] + 1;
                queue.add(edge.to);
            }
        }

        return dist;
    }

    // ダイクストラ法
    long[] dijkstra(Node[] nodes, int start){
        Queue<Edge> queue = new PriorityQueue<>();
        long[] dist = new long[nodes.length];
        fill(dist, LINF / 2);
        dist[start] = 0;
        queue.add(new Edge(start, start, dist[start]));

        while(!queue.isEmpty()){
            Edge now = queue.poll();
            if(dist[now.to] < now.cost) continue;
            for(Edge edge : nodes[now.to].edges){
                if(dist[edge.to] > dist[edge.from] + edge.cost){
                    dist[edge.to] = dist[edge.from] + edge.cost;
                    queue.add(new Edge(edge.from, edge.to, dist[edge.to]));
                    nodes[edge.to].past = edge.from;
                }
            }
        }

        return dist;
    }

    // ソート済みint型配列でkey以上の値の最小indexを返す
    int lowerBound(int[] a, int key){
        int ng = -1;
        int ok = a.length;
        while(Math.abs(ok - ng) > 1){
            int mid = (ok + ng) / 2;
            if(a[mid] >= key){
                ok = mid;
            } else {
                ng = mid;
            }
        }
        return ok;
    }
    // ソート済みlong型配列でkey以上の値の最小indexを返す
    int lowerBound(long[] a, long key){
        int ng = -1;
        int ok = a.length;
        while(Math.abs(ok - ng) > 1){
            int mid = (ok + ng) / 2;
            if(a[mid] >= key){
                ok = mid;
            } else {
                ng = mid;
            }
        }
        return ok;
    }
    // 文字列sとtの最長共通部分列の長さを返す
    int lcs(String s , String t){
        int[][] dp = new int[s.length() + 1][t.length() + 1];

        for(int i = 0; i < s.length(); i++){
            for(int j = 0; j < t.length(); j++){
                if(s.charAt(i) == t.charAt(j)){
                    dp[i + 1][j + 1] = max(dp[i][j] + 1, dp[i + 1][j + 1]);
                }
                dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i + 1][j]);
                dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j + 1]);
            }
        }

        return dp[s.length()][t.length()];
    }

}

// ノード
class Node{
    int id;             // ノード番号
    int past;           // 直前の頂点
    List<Edge> edges;   // 辺のリスト

    Node(int id, int past){
        this.id = id;
        this.past = past;
        this.edges = new ArrayList<>();
    }
    void addEdge(Edge edge){
        edges.add(edge);
    }

    public boolean equals(Object obj){
        if(obj instanceof Node){
            Node node = (Node)obj;
            return this.id == node.id;
        }
        return false;
    }
    public int hashCode(){
        return id;
    }
    public String toString(){
        return "[id:" + id + " past: " + past + "]";
    }
}

// 辺の情報を持つクラス
class Edge implements Comparable<Edge>{
    int from;       // どの頂点から
    int to;          //  どの頂点へ
    long cost;       // 辺の重み

    Edge(int from, int to, long cost){
        this.from = from;
        this.to = to;
        this.cost = cost;
    }
    public int compareTo(Edge edge){
        return Long.compare(this.cost, edge.cost);
    }

    public String toString(){
        return "[" + from + " to " + to + " cost:" + cost + "]";
    }
}
// 辺の重み比較のComparator
class EdgeComparator implements Comparator<Edge>{
    @Override
    public int compare(Edge e1, Edge e2){
        long cost1 = e1.cost;
        long cost2 = e2.cost;
        if(cost1 < cost2){
            return -1;
        } else if(cost1 > cost2){
            return 1;
        } else {
            return 0;
        }
    }
}
// Union-Find
class UnionFind{
    int[] par;
    int[] size;
    UnionFind(int N){
        par = new int[N];
        size = new int[N];
        for(int i = 0; i < N; i++){
            par[i] = i;
            size[i] = 1;
        }
    }

    void init(int N){
        for(int i = 0; i < N; i++){
            par[i] = i;
            size[i] = 1;
        }
    }

    int root(int x){
        if(par[x] == x){
            return x;
        } else {
            return par[x] = root(par[x]);
        }
    }

    boolean same(int x, int y){
        return root(x) == root(y);
    }

    void unite(int x, int y){
        x = root(x);
        y = root(y);
        if(x == y) return;
        if(size[x] < size[y]){
            int tmp = x;
            x = y;
            y = tmp;
        }
        size[x] += size[y];
        par[y] = x;
    }

    int size(int x){
        return size[root(x)];
    }

}

// 順列を管理する
class Permutation {
    private int number;
    private int listSize;
    private int searched;
    private int nextIndex;
    private int[][] permList;

    Permutation(int num) {
        this.number = num;
        this.listSize  = this.fact(this.number);
        this.searched   = 0;
        this.nextIndex = 0;
        this.permList  = new int[this.listSize][this.number];

        this.create(0, new int[this.number], new boolean[this.number]);
    }

    int[] nextPerm() {
        return permList[this.nextIndex++];
    }

    boolean isNext() {
        if(this.nextIndex < this.listSize) {
            return true;
        } else {
            this.nextIndex = 0;
            return false;
        }
    }

    int fact(int n){
        return n == 0 ? 1 : n * fact(n-1);
    }

    void create(int num, int[] list, boolean[] flag) {
        if(num == this.number) {
            copyArray(list, permList[this.searched]);
            this.searched++;
        }
        for(int i = 0; i < this.number; i++){
            if(flag[i]) continue;
            list[num] = i;
            flag[i] = true;
            this.create(num+1, list, flag);
            flag[i] = false;

        }
    }

    void copyArray(int[] from, int[] to) {
        for(int i=0; i<from.length; i++) to[i] = from[i];
    }

    void printNum(int[] nums) {
        for(int n : nums) System.out.print(n);
        System.out.println();
    }
}

// 一点更新区間取得Segment Tree
class SegTree{
    int[] dat;
    int size;

    SegTree(int N){
        this.dat = new int[N * 4];
        this.size = N;
    }

    // [a, b]の最小値を返す
    // l,rにはノードkに対応する区間を与える
    int query(int a, int b, int k, int l, int r){
        if(r < a || b < l) return Integer.MAX_VALUE;
        if(a <= l && r <= b) return dat[k];
        int vl = query(a, b, k << 1, l, (l + r) / 2);
        int vr = query(a, b, (k << 1) + 1, (l + r) / 2 + 1, r);
        return Math.min(vl, vr);
    }

    // インデックスiの値をxに更新
    void update(int i, int x){
        i += this.size - 1;
        dat[i] = x;
        while(i > 0){
            i = i >> 1;     // 1ビットぶん右シフト
            dat[i] = Math.min(dat[i << 1], dat[(i << 1) + 1]);
        }
    }

    public String toString(){
        StringBuilder sb = new StringBuilder("[");
        for(int i = size; i < 2 * size; i++){
            sb.append(dat[i]).append(",");
        }
        sb.delete(sb.length() - 1, sb.length());
        String output = sb.append("]").toString();
        return output;
    }
}

// Range Sum Queryを実現するBinary Indexed Tree
class BIT{
    int[] tree;

    BIT(int N){
        this.tree = new int[N + 1];
    }

    int sum(int i){
        int sum = 0;
        while(i > 0){
            sum += this.tree[i];
            i -= i & -i;
        }
        return sum;
    }

    void add(int i, int x){
        while(i <= tree.length){
            this.tree[i] += x;
            i += i & -i;
        }
    }

    public String toString(){
        StringBuilder sb = new StringBuilder("[");
        for(int i = 0; i < tree.length; i++){
            sb.append(tree[i] + ",");
        }
        sb.append("]");
        String output = sb.toString();
        return output;
    }

}

// 標準のScannerより高速に標準入力する
class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() { return Double.parseDouble(next());}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;

public class Main {

	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		int W = sc.nextInt();
		int H = sc.nextInt();
		int N = sc.nextInt();
		int[] x = new int[N];
		int[] y = new int[N];
		int[] a = new int[N];
		for (int i = 0; i < N; i++) {
			x[i] = sc.nextInt();
			y[i] = sc.nextInt();
			a[i] = sc.nextInt();
		}

		int x1 = 0;
		int x2 = W;
		int y3 = 0;
		int y4 = H;

		for (int i = 0; i < N; i++) {
			if (a[i] == 1)
				x1 = Math.max(x1, x[i]);
			else if (a[i] == 2)
				x2 = Math.min(x2, x[i]);
			else if (a[i] == 3)
				y3 = Math.max(y3, y[i]);
			else if (a[i] == 4)
				y4 = Math.min(y4, y[i]);
		}
		if (x1 < x2 && y3 < y4)
			System.out.println((x2 - x1) * (y4 - y3));
		else
			System.out.println(0);

	}

	//以下、自作ライブラリ

	/*
		int N = sc.nextInt();

		int[] a = new int[N];
		for (int i = 0; i < N; i++)
			a[i] = sc.nextInt();

		String s = sc.next();

		String[] a = new String[N];
		for (int i = 0; i < N; i++)
			a[i] = sc.next();
	 */

	//階乗
	public static int fact(int n) {
		if (n == 1 || n == 0)
			return 1;
		else
			return n * fact(n - 1);
	}

	//指定した値以上の要素が最初に現れる位置
	//要素の数は+1（配列のズレ)
	public static long lowerBound(int n, long[] x, long y) {
		int left = 0;
		int right = n;
		while (left < right) {
			int mid = (left + right) / 2;
			if (x[mid] < y) {
				left = mid + 1;
			} else {
				right = mid;
			}
		}
		return left;
	}

	//指定した値より大きい要素が最初に現れる位置
	//要素の数は+1（配列のズレ)
	public static long upperBound(int n, long[] x, long y) {
		int left = 0;
		int right = n;
		while (left < right) {
			int mid = (left + right) / 2;
			if (x[mid] <= y) {
				left = mid + 1;
			} else {
				right = mid;
			}
		}
		return left;
	}

	//最大公約数
	public static long gcd(long a, long b) {
		if (a < b)
			return gcd(b, a);
		long c = 0;
		c = a % b;
		if (c == 0)
			return b;
		return gcd(b, c);
	}

	//最小公倍数
	public static long lcm(long m, long n) {
		return m * n / gcd(m, n);
	}

	//素数判定
	public static boolean isPrime(int n) {
		if (n < 2)
			return false;
		if (n == 2)
			return true;
		if (n % 2 == 0)
			return false;

		for (int i = 3; i * i <= n; i += 2) {
			if (n % i == 0)
				return false;
		}
		return true;
	}
}

//以下、高速スキャナークラス
class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;

	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		} else {
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) {
				return false;
			}
		}
		return true;
	}

	private int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	private static boolean isPrintableChar(int c) {
		return 33 <= c && c <= 126;
	}

	public boolean hasNext() {
		while (hasNextByte() && !isPrintableChar(buffer[ptr]))
			ptr++;
		return hasNextByte();
	}

	public String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (isPrintableChar(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) {
			throw new NumberFormatException();
		}
		while (true) {
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			} else if (b == -1 || !isPrintableChar(b)) {
				return minus ? -n : n;
			} else {
				throw new NumberFormatException();
			}
			b = readByte();
		}
	}

	public int nextInt() {
		long nl = nextLong();
		if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
			throw new NumberFormatException();
		return (int) nl;
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;
import static java.lang.Math.max;
import static java.lang.Math.min;

public class Main {
    public static void main(String[] args) {
        FastScanner fsc = new FastScanner();
        int w=fsc.nextInt();
        int h=fsc.nextInt();
        int n=fsc.nextInt();
        int l=0, r=w, b=0, t=h;
        for(int i=0;i<n;i++){
            int x=fsc.nextInt();
            int y=fsc.nextInt();
            int a=fsc.nextInt();
            if(a==1){
                l=max(l, x);
            } else if(a==2){
                r=min(r, x);
            } else if(a==3){
                b=max(b, y);
            } else{
                t=min(t, y);
            }
        }
        System.out.println(l<=r && b<=t?(r-l)*(t-b):0);
    }
}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() { return Double.parseDouble(next());}
}


import java.util.*;
 class ck {

 public static void main(String[] args) {
   Scanner no=new Scanner(System.in);
   int n=no.nextInt();
   int u=n;
   int m=no.nextInt();
   int minx=0;
   int maxx=n;
   int miny=0;
   int maxy=m;
   int v=m;
   int t=no.nextInt();
   for(int i=0;i<t;i++){
     int a=no.nextInt();
     int b=no.nextInt();
     int y=no.nextInt();
    /* 5 4 2
     2 1 1
     3 3 4*/
     if(y==1){
       if(a>minx){
         minx=a;
       }
       //u=a;
     }
     else if(y==2){
      if(maxx>a){
        maxx=a;
      }
      // a=a-n;
     }
     else if(y==3){
      if(b>miny){
        miny=b;
      }
       //v=b;
     }
     else{
      if(maxy>b){
        maxy=b;
      }
      // v=b-m;
     }
   }
   if(minx>=maxx||miny>=maxy){
     System.out.println("0");
   }
   else System.out.println((maxx-minx)*(maxy-miny));
 }

}


import java.util.*;
public class Main {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		// 整数の入力
        int w = sc.nextInt();
     	int h = sc.nextInt();
        int n = sc.nextInt();
        int x[] = new int[n];
        int y[] = new int[n];
        int a[] = new int[n];
        int ans;
        int yoko0 = 0,yoko = w,tate0 = 0,tate = h;
        for(int i = 0;i < n; i++){
          x[i] = sc.nextInt();
          y[i] = sc.nextInt();
          a[i] = sc.nextInt();
        }

        for(int i = 0;i < n;i++){
        	if(a[i] == 1 && yoko0 < x[i]){
              yoko0 = x[i];
            }else if(a[i] == 2 && yoko > x[i]){
              yoko = x[i];
            }else if(a[i] == 3 && tate0 < y[i]){
              tate0 = y[i];
            }else if(a[i] == 4 && tate > y[i]){
              tate = y[i];
            }
        }
        ans = (yoko - yoko0) * (tate - tate0);
        if(ans < 0){ans = 0;}
        System.out.println(ans);
    }
}


import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        Main m = new Main(sc);
        m.show(m.solve());
        sc.close();
    }

	//フィールド
    Scanner sc;
    int W;
    int H;
    int N;
    int[] x;
    int[] y;
    int[] a;

    //入力
    Main(Scanner sc) {
        this.sc = sc;
        this.W = sc.nextInt();
        this.H = sc.nextInt();
        this.N = sc.nextInt();
        x = new int[N];
        y = new int[N];
        a = new int[N];
        for (int i=0; i<N; i++) {
        	x[i] = sc.nextInt();
        	y[i] = sc.nextInt();
        	a[i] = sc.nextInt();
        }
    }

    //解答処理
    private int solve() {
        int answer = 0;

        int lx = 0; //長方形左下のx座標
        int ly = 0; //長方形左下のy座標
        int rx = W; //長方形右上のx座標
        int ry = H; //長方形右上のy座標
        //右下と左上は(W,0)、(0,H)

        for(int i=0; i<N; i++){
          if(a[i] == 1){ //x[i]>xの領域を塗りつぶす
            lx = Math.max(lx, x[i]);
          }else if(a[i] == 2){ //x[i]<xの領域を塗りつぶす
            rx = Math.min(rx, x[i]);
          }else if(a[i] == 3){ //y[i]>yの領域を塗りつぶす
            ly = Math.max(ly, y[i]);
          }else if(a[i] == 4){ //y[i]<yの領域を塗りつぶす
            ry = Math.min(ry, y[i]);
          }
        }

        answer = (rx-lx) * (ry-ly);
        if (answer < 0) {
        	answer = 0;
        }
        return answer;
    }

    //出力
    public void show(int answer) {
        System.out.println(answer);
    }

}


///////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <queue>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <typeinfo>
#include <numeric>
#include <cassert>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

using namespace std;

///////////////////////////////////////////////////////////////////////////////

#define DEBUG 0

#define pb push_back
#define V vector
#define M unordered_map

#define rep(i,n) for(ll i=0LL;i<n;++i)
#define srep(i,s,n) for(ll i=s;i<n;++i)
#define rrep(i,n) for(ll i=n-1LL;i>=0LL;--i)
#define ALL(a) (a).begin(),(a).end()
#define CIN(x) do { \
    assert(!cin.eof()); \
    cin >> x; \
    assert(!cin.fail()); \
} while(0);
#if DEBUG
#define debug_print(...) _debug_print(__VA_ARGS__)
#define debug_printf(...) printf(__VA_ARGS__)
#else // DEBUG
#define debug_print(...)
#define debug_printf(...)
#endif // DEBUG

typedef long long ll;
typedef unsigned long long ull;
typedef tuple<ll, ll> t2;
typedef tuple<ll, ll, ll> t3;
typedef tuple<ll, ll, ll, ll> t4;
typedef tuple<ll, ll, ll, ll, ll> t5;
template <typename T>
using priority_queue_incr = priority_queue<T, V<T>, greater<T>>;

struct UnionFind
{
    ull *parent, *count, *rank;

    UnionFind(ull n) {
        parent = new ull[n+1];
        count = new ull[n+1];
        rank = new ull[n+1];
        for (ull i = 0ULL; i < n+1; ++i) {
            parent[i] = i;
            count[i] = 1;
            rank[i] = 0;
        }
    }

    ull root(ull i) {
        if (parent[i] == i) return i;
        parent[i] = root(parent[i]);
        return parent[i];
    }

    void unite(ull i, ull j) {
        ull rooti = root(i);
        ull rootj = root(j);

        if (rooti == rootj) return;

        if (rank[rootj] < rank[rooti]) {
            parent[i] = parent[j] = parent[rootj] = rooti;
            count[rooti] += count[rootj];
        }
        else {
            parent[i] = parent[j] = parent[rooti] = rootj;
            count[rootj] += count[rooti];
            if (rank[rootj] == rank[rooti]) rank[rootj]++;
        }
    }

    bool same(ull i, ull j) {
        return root(i) == root(j);
    }
};

struct BIT
{
    ll *tree;
    ll size;

    BIT(ll n, ll init) {
        tree = new ll[n+1];
        size = n;
        memset(tree, 0, sizeof(ll) * (n+1));
        this->init(init);
    }

    void init(ll init) {
        rep (i0, size) {
            ll idx = i0 + 1LL;
            while (idx <= size) {
                tree[idx] += init;
                idx += (idx & (-idx));
            }
        }
    }

    // idx is 1 origin
    void add(ll idx, ll x) {
        assert(idx > 0LL);
        while (idx <= size) {
            tree[idx] += x;
            idx += (idx & (-idx));
        }
    }

    // idx is 1 origin
    ll sum(ll idx) {
        assert(idx > 0LL);
        ll ret = 0LL;
        while (idx > 0LL) {
            ret += tree[idx];
            idx -= (idx & (-idx));
        }
        return ret;
    }
};

struct MaxFlow {
    V<ll> links[1005];
    ll capacities[1005][1005];
    ll nodes;

    MaxFlow(ll nodes) {
        // i == 0       --> S
        // i == nodes+1 --> T
        rep (i, nodes+2LL) links[i].clear();
        memset(capacities, 0, sizeof(capacities));
        this->nodes = nodes;
    }

    void add_path(ll a, ll b, ll capacity) {
        links[a].pb(b);
        links[b].pb(a);
        capacities[a][b] = capacity;
        capacities[b][a] = 0LL;
    }

    ll solve(void) {
        deque<V<ll>> q;
        ll ret = 0LL;

        for ( ; ; q.clear()) {

            V<ll> start;
            start.pb(0);
            q.push_front(start);

            bool checked[nodes+2];
            memset(checked, 0, sizeof(checked));

            V<ll> found;

            for ( ; !(q.empty()); ) {
                V<ll> path = q.front(); q.pop_front();
                ll last = path[path.size()-1];

                if (checked[last]) continue;
                if (last == nodes+1) {
                    found = path;
                    break;
                }

                checked[last] = true;
                for (auto next : (links[last])) {
                    if (capacities[last][next] == 0) continue;
                    V<ll> newpath(path);
                    newpath.pb(next);
                    q.push_front(newpath);
                }
            }

            if (found.size() == 0) {
                break;
            }
            else {
                ll flowcount = capacities[found[0]][found[1]];
                rep (i, found.size()-1) {
                    ll src = found[i];
                    ll dst = found[i+1];
                    flowcount = min(flowcount, capacities[src][dst]);
                }
                rep (i, found.size()-1) {
                    ll src = found[i];
                    ll dst = found[i+1];
                    capacities[src][dst] -= flowcount;
                    capacities[dst][src] += flowcount;
                }
                ret += flowcount;
            }
        }

        return ret;
    }
};

template <typename T>
struct SegmentTree {
    T *nodes;
    t2 *ranges;  // [start, end)
    ll nodecount;
    ll itemcount;
    T unit;
    T (*op)(T, T);

    SegmentTree(ll itemcount, T unit, T op(T, T)) {
        ll orig_itemcount = itemcount;
        this->itemcount = 1LL;
        while (this->itemcount < orig_itemcount) this->itemcount *= 2LL;
        nodecount = this->itemcount * 2 - 1;
        nodes = new T[nodecount];
        ranges = new t2[nodecount];
        this->unit = unit;
        this->op = op;

        ll start = 0LL;
        ll end = this->itemcount;
        ll len = this->itemcount;

        rep (i, nodecount) {
            nodes[i] = unit;
            ranges[i] = t2(start, end);
            if (end >= this->itemcount) {
                len /= 2LL;
                start = 0LL;
                end = len;
            }
            else {
                start = end;
                end = start + len;
            }
        }
    }

    void update(ll k, T v) {
        ll idx = k + itemcount - 1LL;
        nodes[idx] = v;
        idx = (idx - 1LL) / 2LL;

        for ( ; idx >= 0; idx = (idx - 1LL) / 2LL) {
            nodes[idx] = op(nodes[idx * 2LL + 1LL],
                            nodes[idx * 2LL + 2LL]);
            if (!idx) break;
        }
    }

    T query(ll start, ll end) const {
        return _query(start, end, 0LL);
    }

    T _query(ll start, ll end, ll idx) const {
        ll rstart = get<0>(ranges[idx]);
        ll rend = get<1>(ranges[idx]);

        if (start <= rstart && rend <= end) {
            return nodes[idx];
        }
        if (rend <= start || end <= rstart) {
            return unit;
        }
        T left = _query(start, end, idx * 2LL + 1LL);
        T right = _query(start, end, idx * 2LL + 2LL);
        return op(left, right);
    }

};

void llin(ll &a)
{
    CIN(a);
}

void llinl1(auto &v, ll count)
{
    for (ll i = 0LL; i < count ; ++i) {
        ll a;
        CIN(a);
        v.push_back(a);
    }
}

void llinl2(auto &v, ll count)
{
    for (ll i = 0LL; i < count ; ++i) {
        ll a, b;
        CIN(a >> b);
        v.push_back(t2(a, b));
    }
}

void llinl3(auto &v, ll count)
{
    for (ll i = 0LL; i < count ; ++i) {
        ll a, b, c;
        CIN(a >> b >> c);
        v.push_back(t3(a, b, c));
    }
}

void llinl4(auto &v, ll count)
{
    for (ll i = 0LL; i < count ; ++i) {
        ll a, b, c, d;
        CIN(a >> b >> c >> d);
        v.push_back(t4(a, b, c, d));
    }
}

void llina(auto &v, ll count)
{
    llinl1(v, count);
}

template <typename T>
T min(const V<T> v)
{
    T ret = v[0];
    for (auto i : v) ret = min(ret, i);
    return ret;
}

template <typename T>
T max(const V<T> v)
{
    T ret = v[0];
    for (auto i : v) ret = max(ret, i);
    return ret;
}

ll absll(ll x)
{
    if (x < 0) return -x;
    return x;
}

ll mod_mlt(ll x, ll y, ll mod)
{
    ll ret = 0LL;
    x %= mod;

    while (y) {
        if (y & 1LL) {
            ret += x;
            ret %= mod;
        }
        y >>= 1;
        x <<= 1;
        x %= mod;
    }

    return ret;
}

// O(log(exp))
ll mod_pow(ll base, ll exp, ll mod)
{
    ll ret = 1LL;

    for ( ; exp; ) {
        if (exp & 1LL) {
            ret *= base;
            ret %= mod;
        }
        base = (base * base) % mod;
        exp >>= 1;
    }

    return ret;
}

// O(log(mod))
ll mod_inv(ll x, ll mod)
{
    // available only when mod is prime
    return mod_pow(x, mod - 2LL, mod);
}

ll gcm(ll x, ll y)
{
    while (y != 0) {
        ll z = x % y;
        x = y;
        y = z;
    }
    return x;
}

template <typename T>
void sort(V<T> &v)
{
    sort(v.begin(), v.end());
}

template <typename T>
void sort_reverse(V<T> &v)
{
    sort(v.begin(), v.end(), greater<T>());
}

void get_divisors(V<ll> &retlist, ll x)
{
    for (ll i = 1LL; i < sqrt(x) + 3LL; ++i) {
        if (x % i == 0LL) {
            retlist.push_back(i);
            retlist.push_back(x / i);
        }
    }
}

void get_factors(V<ll> &retlist, ll x)
{
    for (ll i = 2LL; i < (ll)(sqrt(x)) + 3LL; ++i) {
        while (x % i == 0LL) {
            retlist.pb(i);
            x /= i;
        }
    }
    retlist.pb(x);
}

bool is_prime(ll x)
{
    V<ll> factors, factors2;

    get_factors(factors, x);

    for (auto factor : factors) {
        if (factor > 1) factors2.pb(factor);
    }

    return factors2.size() == 1 && x == factors2[0];
}

template <typename T>
void intersection(const set<T> &a, const set<T> &b,
                  set<T> &result)
{
    set_intersection(ALL(a), ALL(b), inserter(result, result.end()));
}

ull combination(ll x, ll y)
{
    if (y > x / 2LL) y = x - y;

    ull ret = 1LL;
    for (ll i = 0LL; i < y; ++i) {
        ret *= x--;
        ret /= (i + 1LL);
    }

    return ret;
}

ull mod_combination(ll x, ll y, ll mod)
{
    if (y > x / 2LL) y = x - y;

    ll ret = 1;

    for (ll i = 0LL; i < y; ++i) {
        ret = (ret * x--) % mod;
        ret = (ret * mod_inv(i + 1LL, mod)) % mod;
    }

    return ret;
}

void make_linklist(const V<t2> &srclist, V<ll> dstlist[])
{
    for (auto src : srclist) {
        ll a = get<0>(src);
        ll b = get<1>(src);
        dstlist[a].pb(b);
        dstlist[b].pb(a);
    }
}

void make_parent(const V<ll> linklist[], ll root, ll n,
                 ll parent[], ll level[])
{
    queue<ll> q;
    bool checked[n+1];

    memset(checked, 0, sizeof(checked));

    q.push(root);
    checked[root] = true;
    parent[root] = root;
    level[root] = 0LL;

    for ( ; !(q.empty()); ) {
        ll now = q.front(); q.pop();
        for (auto next : linklist[now]) {
            if (checked[next]) continue;
            q.push(next);
            checked[next] = true;
            parent[next] = now;
            level[next] = level[now] + 1LL;
        }
    }
}

#define POW_ANCESTOR_MAXSIZE   20

// preprocess for get_common_ancestor()
void make_pow_ancestor(const ll parent[], ll n,
                       ll (*pow_ancestor)[POW_ANCESTOR_MAXSIZE])
{
    rep (i, n) pow_ancestor[i+1][0] = parent[i+1];

    for (int pow2 = 1; pow(2, pow2) <= n; ++pow2) {
        rep (i0, n) {
            int i = i0+1;
            ll prev = pow_ancestor[i][pow2-1];
            pow_ancestor[i][pow2] = pow_ancestor[prev][pow2-1];
        }
    }
}

ll get_common_ancestor(ll n, ll x, ll y,
                       const ll (*pow_ancestor)[POW_ANCESTOR_MAXSIZE],
                       const ll level[])
{
    if (level[x] < level[y]) {
        ll diff = level[y] - level[x];
        for ( ; diff; ) {
            ll bit = diff & -diff;
            y = pow_ancestor[y][(int)log2(bit)];
            diff -= bit;
        }
    }
    else {
        ll diff = level[x] - level[y];
        for ( ; diff; ) {
            ll bit = diff & -diff;
            x = pow_ancestor[x][(int)log2(bit)];
            diff -= bit;
        }
    }

    if (x == y) return x;

    rrep (i, (int)log2(n)+1) {
        if (pow_ancestor[x][i] != pow_ancestor[y][i]) {
            x = pow_ancestor[x][i];
            y = pow_ancestor[y][i];
        }
    }

    return pow_ancestor[x][0];
}

void kmp_init(const string &pattern, ll kmp_next[])
{
    kmp_next[0] = -1LL;

    ll plen = pattern.size();
    ll prefix_end = -1;

    rep (suffix_end, pattern.size()) {
        while (prefix_end >= 0 && pattern[suffix_end] != pattern[prefix_end]) {
            prefix_end = kmp_next[prefix_end];
        }
        kmp_next[suffix_end+1] = ++prefix_end;
    }

    kmp_next[0] = 0LL;
}

// founds ... list of text's idx of match position. start position idx.
void kmp_search(const string &text, const string &pattern, const ll kmp_next[],
                V<ll> &founds)
{
    ll text_size = text.size();
    ll pattern_size = pattern.size();
    ll text_start = 0LL;
    ll pattern_idx = 0LL;

    assert(pattern_size <= text_size);

    for ( ; ; ) {
        if (text_start + pattern_idx >= text_size) break;
        if (pattern_idx >= pattern_size) break;

        if (text[text_start+pattern_idx] == pattern[pattern_idx]) {
            pattern_idx++;
            if (pattern_idx == pattern_size) {
                founds.pb(text_start);
                pattern_idx = kmp_next[pattern_idx];
                text_start += (pattern_size - pattern_idx);
            }
        }

        else {
            text_start += (pattern_idx - kmp_next[pattern_idx]);
            pattern_idx = kmp_next[pattern_idx];
            if (pattern_idx == 0LL && text[text_start] != pattern[0]) {
                text_start++;
            }
        }
    }
}

void _debug_print(auto x)
{
    cout << x << endl;
}

void _debug_print(const t2 &x)
{
    ll x1 = get<0>(x);
    ll x2 = get<1>(x);
    cout << "-- " << x1 << " -- " << x2 << endl;
}

void _debug_print(const t3 &x)
{
    ll x1 = get<0>(x);
    ll x2 = get<1>(x);
    ll x3 = get<2>(x);
    cout << "-- " << x1 << " -- " << x2 << " -- " << x3 << endl;
}

void _debug_print(const t4 &x)
{
    ll x1 = get<0>(x);
    ll x2 = get<1>(x);
    ll x3 = get<2>(x);
    ll x4 = get<3>(x);
    cout << "-- " << x1 << " -- " << x2
        << " -- " << x3 << " -- " << x4 << endl;
}

template <typename T>
void _debug_print(T xarray[], ll n)
{
    rep (i, n) _debug_print(xarray[i]);
}

template <typename T>
void _debug_print(const V<T> &xlist)
{
    for (auto x : xlist) {
        cout << "-- ";
        _debug_print(x);
    }
}

template <typename T>
void _debug_print(const set<T> &xset)
{
    for (auto x : xset) {
        cout << "-- ";
        _debug_print(x);
    }
}

template <typename S, typename T>
void _debug_print(const M<S, T> &xlist)
{
    for (auto x : xlist) {
        S k = x.first;
        T v = x.second;
        cout << "====" << endl;
        cout << "K=";
        _debug_print(k);
        cout << "V=";
        _debug_print(v);
    }
}

int _main();
int main()
{
    cout << setprecision(12);
    return _main();
}

///////////////////////////////////////////////////////////////////////////////

int _main()
{
    ll w; llin(w);
    ll h; llin(h);
    ll n; llin(n);
    V<t3> xyalist; llinl3(xyalist, n);

    ll x1 = 0LL;
    ll y1 = 0LL;
    ll x2 = w;
    ll y2 = h;

    for (auto xya : xyalist) {
        ll x = get<0>(xya);
        ll y = get<1>(xya);
        ll a = get<2>(xya);

        if (a == 1) x1 = max(x1, x);
        if (a == 2) x2 = min(x2, x);
        if (a == 3) y1 = max(y1, y);
        if (a == 4) y2 = min(y2, y);
    }

    ll xlen = max(0LL, x2 - x1);
    ll ylen = max(0LL, y2 - y1);
    cout << xlen * ylen;

    return 0;
}

///////////////////////////////////////////////////////////////////////////////


#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using vec=vector<ll>;
using mat=vector<vec>;
#define For(i,a,b) for(i=a;i<b;i++)
#define rep(i,N) For(i,0,N)
#define rep1(i,N) For(i,1,N)
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define vsort(v) sort(all(v))
#define vrsort(v) sort(allr(v))
#define mod 1000000007
using datas=pair<ll,ll>;

long mmid(long a,long b,long c){return a<b?(b<c?b:max(a,c)):(b>c?b:min(a,c));}

ll modinv(ll a) {
  ll b=mod,u=1,v=0,t;
  while(b){
    t=a/b;
    a-=t*b; swap(a,b);
    u-=t*v; swap(u,v);
  }
  return (u+mod)%mod;
}

ll moddevide(ll a,ll b){return (a*modinv(b))%mod;}

ll modncr(ll n,ll r){
  ll i,plus=1;
  rep(i,r){
    plus=(plus*(n-i))%mod;
    plus=moddevide(plus,i+1);
  }
  return plus;
}

ll euclidean_gcd(ll a, ll b) {
  if(a<b) return euclidean_gcd(b, a);
  ll r;
  while ((r=a%b)){a=b;b=r;}
  return b;
}

ll countdigits(ll n){
  ll ans=0;
  while(n){n/=10;ans++;}
  return ans;
}

ll sumdigits(ll n){
  ll ans=0;
  while(n){ans+=n%10;n/=10;}
  return ans;
}

void printmap(vector<ll>& a,ll H,ll W){
  ll i,j;
  For(i,0,H+2){
    For(j,0,W+2){cout<<a[i*(W+2)+j];}
    cout<<endl;
  }
}
void inputmap(vector<ll>& a,ll H,ll W){
  ll i,j;
  string ss;
  For(i,1,H+1){
    cin>>ss;
    For(j,1,W+1){
      if(ss[j-1]=='#'){
        a[i*(W+2)+j]=1;
      }else{
        a[i*(W+2)+j]=0;
      }
    }
  }
}

int main(){
  ll i,a,b,c,N,H,W,x=0,y=0;
  cin>>W>>H>>N;
  rep(i,N){
    cin>>a>>b>>c;
    switch(c){
      case 1:
        x=max(a,x);
      break;
      case 2:
        W=min(a,W);
      break;
      case 3:
        y=max(b,y);
      break;
      case 4:
        H=min(b,H);
      break;
    }
  }
  if(x>=W||y>=H){
    cout<<0<<endl;
  }else{
    cout<<(W-x)*(H-y)<<endl;
  }
  return 0;
}


#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/numeric/interval.hpp>
#include <boost/numeric/interval/io.hpp>
using namespace::std;
namespace mp = boost::multiprecision;
typedef mp::number<mp::cpp_dec_float<32,int64_t>> cfloat;
typedef mp::cpp_int cint;
typedef long long lint;
typedef long long ll;
typedef long double ldouble;
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<double> dvec;
typedef vector<vector<double>> dmat;
typedef vector<vector<vector<double>>> dmat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
typedef vector<vector<vector<string>>> smat3;
typedef vector<pair<lint,lint>> pvec;
typedef vector<vector<pair<lint,lint>>> pmat;
typedef vector<vector<vector<pair<lint,lint>>>> pmat3;
#define rep(i, n) for(lint i = 0; i < (lint)(n); i++)
#define irep(i) for(lint i = 0;; i++)
#define irep1(i) for(lint i = 1;; i++)
#define irep2(i) for(lint i = 2;; i++)
#define rrep(i, n) for(lint i = (lint)(n-1); i >-1; i--)
#define rrepi(i,a,b) for(lint i = (lint)(b-1); i >a-1; i--)
#define repi(i,a,b) for(lint i=lint(a);i<lint(b);i++)
#define rep2(i,a,b,c) for(lint i=lint(a);i>lint(b);i+=c)
#define all(x) (x).begin(),(x).end()
#define PI 3.141592653589793
#define cout (cout<<fixed<<setprecision(15))
#define dist(x1,y1,x2,y2) (pow(pow(x2-x1,2)+pow(y2-y1,2),0.5))
#define output(v) do{bool f=0;for(auto i:v){cout<<(f?" ":"")<<i;f=1;}cout<<"\n";}while(0)
#define output2(v) for(auto i:v)output(i);
#define input(a,n) lint n;cin>>n;vector<lint>a(n);rep(i,n)cin>>a[i];
#define sum(v) accumulate(all(v),0LL)
#define INF (1LL<<60)
#define IINF (1<<30)
#define LINF 9223372036854775807
#define MOD 1000000007
vector<lint> dx={-1,1,0,0,1,1,-1,-1};
vector<lint> dy={0,0,-1,1,1,-1,1,-1};
inline lint gcd(lint a,lint b){return b?gcd(b,a%b):a;}
inline lint lcm(lint a,lint b){return a*b/gcd(a,b);}
class Comb{
    public:
    vector<lint> fac,ifac;
    lint M=1000000;
    Comb(){
        fac.resize(M+1);
        ifac.resize(M+1);
        fac[0] = 1;
        ifac[0] = 1;
        rep(i,M){
            fac[i+1] = fac[i]*(i+1) % MOD;
            ifac[i+1] = ifac[i]*mpow(i+1, MOD-2) % MOD;
        }
    }
    lint mpow(lint x, lint n){
        lint ans = 1;
        while(n != 0){
            if(n&1) ans = ans*x % MOD;
            x = x*x % MOD;
            n = n >> 1;
        }
        return ans;
    }
    lint comb(lint a, lint b){
        if(a == 0 && b == 0)return 1;
        if(a < b || a < 0)return 0;
        lint tmp = ifac[a-b]* ifac[b] % MOD;
        return tmp * fac[a] % MOD;
    }
};
int main(){
    lint w,h,n;
    cin>>w>>h>>n;
    vec x(n),y(n),a(n);
    rep(i,n)cin>>x[i]>>y[i]>>a[i];
    lint s=0,t=0,u=w,r=h;
    rep(i,n){
        if(a[i]==1)s=max(s,x[i]);
        if(a[i]==2)u=min(u,x[i]);
        if(a[i]==3)t=max(t,y[i]);
        if(a[i]==4)r=min(r,y[i]);
    }
    cout<<max(0LL,u-s)*max(0LL,r-t);
}


#include <bits/stdc++.h>
using namespace std;
#define PI 3.141592653589793
#define MOD 1000000007
#define rep(i, n) for (ll i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
typedef long long ll;
typedef long double ld;

int main(){
    ll H, W, N;
    cin >> H >> W >> N;
    ll x0 = 0, x1 = W, y0 = 0, y1 = H;
    rep(i, N){
        ll x, y, a;
        cin >> x >> y >> a;
        if(a==1)
            x0 = max(x, x0);
        if(a==2)
            x1 = min(x, x1);
        if(a==3)
            y0 = max(y, y0);
        if(a==4)
            y1 = min(y, y1);
    }

    cout << max(x1 - x0, 0LL) * max(y1 - y0, 0LL) << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define PI 3.141592653589793
#define MOD 1000000007
#define rep(i, n) for (ll i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
typedef long long ll;
typedef long double ld;

int main(){
    ll Square[100][100] = {0};
    ll H, W, N;
    cin >> H >> W >> N;

    rep(j,H){
        rep(i,W){
            Square[j][i] = 1;
        }
    }

    rep(i, N){
        ll x, y, a;
        cin >> x >> y >> a;
        x--;
        y--;
        if(a == 1){
            rep(j,H){
                rep(i,W){
                    if(i < x){
                        Square[j][i] = 0;
                    }

                }
            }
        }
        if(a == 2){
            rep(j,H){
                rep(i,W){
                    if(i > x){
                        Square[j][i] = 0;
                    }

                }
            }
        }

        if(a == 3){
            rep(j,H){
                rep(i,W){
                    if(j < y){
                        Square[j][i] = 0;
                    }

                }
            }
        }
        if(a == 4){
            rep(j,H){
                rep(i,W){
                    if(j > y){
                        Square[j][i] = 0;
                    }

                }
            }
        }
    }
    ll ans = 0;
    rep(j,H){
        rep(i,W){
            ans += Square[j][i];
        }
    }

    cout << ans << endl;
}


//  すぬけ君の塗り絵 2 イージー  WA
#include <bits/stdc++.h>
using namespace std;

int main(){
    int W, H, N;
    cin >> W >> H >> N;
    int x[N], y[N], a[N];
    for(int i=0; i<N; i++){
        cin >> x[i] >> y[i] >> a[i];
    }
    int xl=0, yd=0;
    int xr=W, yu=H;
    for(int i=0; i<N; i++){
        if(a[i]==1){
            xl=max(xl, x[i]);
        }
        if(a[i]==2){
            xr=min(xr, x[i]);
        }
        if(a[i]==3){
            yd=max(yd, y[i]);
        }
        if(a[i]==4){
            yu=min(yu, y[i]);
        }
    }

    int s=(xr-xl)*(yu-yd);
    if(s>=0){
        cout << s << endl;
    }
    else{
        cout << 0 << endl;
    }
    return 0;
}


#include<stdio.h>
int main()
{
	int w,h,n,x,y,a,x0=0,y0=0;

	scanf("%d%d%d",&w,&h,&n);
	while(n--){
		scanf("%d%d%d",&x,&y,&a);
		if(a==1&&x0<x)
			x0=x;
		else if(a==2&&w>x)
			w=x;
		else if(a==3&&y0<y)
			y0=y;
		else if(a==4&&h>y)
			h=y;
		if(w<x0||h<y0){
			puts("0");
			return 0;
		}
	}
	printf("%d",(w-x0)*(h-y0));
	return 0;
}


#include <stdio.h>

#define N_MAX 100
#define W_MAX 100
#define H_MAX 100

int main()
{
    int w, h, n;
    int points[N_MAX][2];
    int commands[N_MAX];

    scanf("%d %d %d", &w, &h, &n);
    for (int i = 0; i < n; i++)
    {
	scanf("%d", &points[i][0]);
	scanf("%d", &points[i][1]);
	scanf("%d", &commands[i]);
    }

    int area[W_MAX][H_MAX] = {};
    for (int i = 0; i < n; i++)
    {
	switch (commands[i])
	{
	    case 1:
		for (int x = 0; x < points[i][0]; x++)
		{
		    for (int y = 0; y < h; y++)
		    {
			area[x][y] = 1;
		    }
		}
		break;
	    case 2:
		for (int x = points[i][0]; x < w; x++)

		{
		    for (int y = 0; y < h; y++)
		    {
			area[x][y] = 1;
		    }
		}
		break;
	    case 3:
		for (int x = 0; x < w; x++)
		{
		    for (int y = 0; y < points[i][1]; y++)
		    {
			area[x][y] = 1;
		    }
		}
		break;
	    case 4:
		for (int x = 0; x < w; x++)
		{
		    for (int y = points[i][1]; y < h; y++)
		    {
			area[x][y] = 1;
		    }
		}
		break;
	}
    }

    int count = 0;
    for (int x = 0; x < w; x++)
    {
	for (int y = 0; y < h; y++)
	{
	    if (area[x][y] == 0)
	    {
		count++;
	    }
	}
    }
    printf("%d\n", count);

    return 0;
}


# include"stdio.h"

int main(){
    int w,h,n;
    scanf("%d %d %d",&w,&h,&n);
    int x[n],y[n],a[n],f[w][h];
    for(int i=0;i<n;i++)
        scanf("%d %d %d",&x[i],&y[i],&a[i]);
    for(int i=0;i<w;i++)
        for(int j=0;j<h;j++)
            f[i][j]=1;
    for(int i=0;i<n;i++){
        if(a[i]==1)
            for(int j=x[i]-1;j>=0;j--)
                for(int k=0;k<h;k++)
                    f[j][k]=0;
        if(a[i]==2)
            for(int j=x[i];j<w;j++)
                for(int k=0;k<h;k++)
                    f[j][k]=0;
        if(a[i]==3)
            for(int j=y[i]-1;j>=0;j--)
                for(int k=0;k<w;k++)
                    f[k][j]=0;
        if(a[i]==4)
            for(int j=y[i];j<h;j++)
                for(int k=0;k<w;k++)
                    f[k][j]=0;
    }
    int ans=0;
    for(int i=0;i<w;i++)
        for(int j=0;j<h;j++)
            if(f[i][j]) ans++;
    printf("%d\n",ans);

}


#include<stdio.h>

int main(){
    int w,h,n;
    scanf("%d%d%d",&w,&h,&n);
    int right=w;
    int left=0;
    int up=h;
    int down=0;
    int x[n],y[n],a[n];
    for(int i=0;i<n;i++){
        scanf("%d%d%d",&x[i],&y[i],&a[i]);
        if(a[i]==1){
            left=x[i];
        }else if(a[i]==2){
            right=x[i];
        }else if(a[i]==3){
            down=y[i];
        }else if(a[i]==4){
            up=y[i];
        }
    }
    if(left>=right||down>=up){
        printf("0\n");
    }else{
        printf("%d\n",(right-left)*(up-down));
    }
    return 0;
}


#include<stdio.h>

int main(){
    int w,h,n;
    scanf("%d%d%d",&w,&h,&n);
    int right=w;
    int left=0;
    int up=h;
    int down=0;
    int x[n],y[n],a[n];
    for(int i=0;i<n;i++){
        scanf("%d%d%d",&x[i],&y[i],&a[i]);
        if(a[i]==1){
            left=x[i];
        }else if(a[i]==2){
            right=x[i];
        }else if(a[i]==3){
            down=y[i];
        }else if(a[i]==4){
            up=y[i];
        }
    }
    if(left>right||down>up){
        printf("0\n");
    }else{
        printf("%d\n",(right-left)*(up-down));
    }
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
typedef long long ll;

int main() {
	ll w, h, n, x, y, a;
	scanf("%lld%lld%lld", &w, &h, &n);
	ll w1 = 0, w2 = w, h1 = 0, h2 = h;
	for (int i = 0; i < n; i++) {
		scanf("%lld%lld%lld", &x, &y, &a);
		switch (a) {
		case 1:
			if (x > w1) w1 = x;
			break;
		case 2:
			if (x < w2) w2 = x;
			break;
		case 3:
			if (y > h1) h1 = y;
			break;
		case 4:
			if (y < h2) h2 = y;
			break;
		}
	}
	printf("%lld", (w2 - w1) * (h2 - h1));

	return 0;
}


"use strict"
function Main(input) {
  input = input.trim().split('\n');
  let WHN = input[0].split(' ').map(Number);
  let minX = 0;
  let minY = 0;
  let maxX = WHN[0];
  let maxY = WHN[1];
  const N = WHN[2];

  for(let i=1; i<=N; i++){
    let tmp = input[i].trim().split(' ').map(Number)
    let A = tmp[2];
    if(A === 1){
      if(tmp[0] > minX){
        minX = tmp[0];
      }
    } else if (A === 2) {
      if(tmp[0] < maxX){
        maxX = tmp[0];
      }
    } else if (A === 3) {
      if(tmp[1] > minY) {
        minY = tmp[1];
      }
    } else if (A === 4) {
      if(tmp[1] < maxY) {
        maxY = tmp[1];
      }
    }
  }

  const X = maxX - minX;
  const Y = maxY - minY;
  if(X <= 0 || Y <= 0){
    console.log(0);
  } else {
    console.log(X*Y);
  }
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


"use strict";

var input = require("fs").readFileSync("/dev/stdin", "utf8");
var cin = input.split(/ |\n/),
    cid = 0;

function next() {
    return +cin[cid++];
} // number一個取得
function nextstr() {
    return cin[cid++];
} // 文字列一個取得
function nextbig() {
    return BigInt(cin[cid++]);
} // BigInteger一個取得
// 長さnの配列として取得。aは文字列フラグ
function nexts(n, a) {
    return a ? cin.slice(cid, cid += n) : cin.slice(cid, cid += n).map(a => +a);
}
// 長さnのBigInt配列として取得。
function nextsbig(n) {
    return cin.slice(cid, cid += n).map(a => BigInt(a));
}
// w個ずつを組にして長さhの配列。aは文字列フラグ。
function nextm(h, w, a) {
    var r = [],
        i = 0;
    if (a)
        for (; i < h; i++) r.push(cin.slice(cid, cid += w));
    else
        for (; i < h; i++) r.push(cin.slice(cid, cid += w).map(a => +a));
    return r;
}
// 多次元配列。v,a1,a2,a3 なら、3次元。[[値vで長さa3の配列]をa2個並べた配列]をa1個並べた配列。
function xArray(v) {
    var a = arguments,
        l = a.length,
        r = "Array(a[" + --l + "]).fill().map(x=>{return " + v + ";})";
    while (--l) r = "Array(a[" + l + "]).fill().map(x=>" + r + ")";
    return eval(r);
}

console.log(main().toString());

function main() {
    let w = next();
    let h = next();
    let n = next();
    let xya = nextm(n, 3)
    let t1 = [];
    let t2 = [];
    let t3 = [];
    let t4 = [];
    // xyaをaでソート
    // console.log({xya})
    xya.forEach(v => {
        if (v[2] == 1) t1.push(v)
        if (v[2] == 2) t2.push(v)
        if (v[2] == 3) t3.push(v)
        if (v[2] == 4) t4.push(v)
    });
    //console.log(t1,t2,t3,t4)
    t1 = t1.length > 0 ? t1.sort((a, b) => b[0] - a[0])[0][0] : 0
    t2 = t2.length > 0 ? t2.sort((a, b) => a[0] - b[0])[0][0] : w
    t3 = t3.length > 0 ? t3.sort((a, b) => b[1] - a[1])[0][1] : 0
    t4 = t4.length > 0 ? t4.sort((a, b) => a[1] - b[1])[0][1] : h

    //console.log(t1,t2,t3,t4)
    return Math.max(t2 - t1, 0) * Math.max(t4 - t3, 0)
}


'use strict'

let rect = [];

function Main(input) {
    const d = input.split('\n').map(v => v.split(' '));
    let s = d.shift();
    const W = Number(s[0]);
    const H = Number(s[1]);
    const N = Number(s[2]);

    rect = [];
    for (let i = 0; i < H; i++) {
        for (let j = 0; j < W; j++) {
            rect[i] = Array(W).fill(0);
        }
    }
    for (let i = 0; i < N; i++) {
        switch (Number(d[i][2])) {
            case 1:
                draw(0, d[i][0], 0, H);
                break;
            case 2:
                draw(d[i][0], W, 0, H);
                break;
            case 3:
                draw(0, W, 0, d[i][1]);
                break;
            case 4:
                draw(0, W, d[i][1], H);
                break;
            default:
                break;
        }
    }
    console.log(rect)

    let result = 0;
    for (const arr of rect) {
        for (const v of arr) {
            if (v === 0) {
                result++
            }
        }
    }

    console.log(result);
}

function draw(xStart, xEnd, yStart, yEnd) {
    for (let y = yStart; y < yEnd; y++) {
        for (let x = xStart; x < xEnd; x++) {
            rect[y][x] += 1;
        }
    }
}

Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


"use strict"
function Main(input) {
  input = input.trim().split('\n');
  let WHN = input[0].split(' ').map(Number);
  let minX = 0;
  let minY = 0;
  let maxX = WHN[0];
  let maxY = WHN[1];
  const N = WHN[2];

  for(let i=1; i<=N; i++){
    let tmp = input[i].trim().split(' ').map(Number)
    let A = tmp[2];
    if(A === 1){
      if(tmp[0] < maxX){
        minX = tmp[0];
      } else {
        minX = maxX;
      }
    } else if (A === 2) {
      if(tmp[0] > minX){
        maxX = tmp[0];
      } else {
        maxX = minX;
      }
    } else if (A === 3) {
      if(tmp[1] > minY) {
        minY = tmp[1];
      }
    } else if (A === 4) {
      if(tmp[1] > minY) {
        maxY = tmp[1];
      } else {
        maxY = minY;
      }
    }
  }

  let ret = (maxX - minX) * (maxY - minY);
  console.log(ret);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


"use strict"
function Main(input) {
  input = input.trim().split('\n');
  let WHN = input[0].split(' ').map(Number);
  let minX = 0;
  let minY = 0;
  let maxX = WHN[0];
  let maxY = WHN[1];
  const N = WHN[2];

  for(let i=1; i<=N; i++){
    let tmp = input[i].trim().split(' ').map(Number)
    let A = tmp[2];
    if(A === 1){
      if(tmp[0] < maxX){
        minX = tmp[0];
      } else {
        minX = maxX;
      }
    } else if (A === 2) {
      if(tmp[0] > minX){
        maxX = tmp[0];
      } else {
        maxX = minX;
      }
    } else if (A === 3) {
      if(tmp[1] < maxY) {
        minY = tmp[1];
      } else {
        minY = maxY;
      }
    } else if (A === 4) {
      if(tmp[1] > minY) {
        maxY = tmp[1];
      } else {
        maxY = minY;
      }
    }
  }

  let ret = (maxX - minX) * (maxY - minY);
  console.log(ret);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

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

const (
	initialBufSize = 10000
	maxBufSize     = 1000000
	mod            = 1e9 + 7
)

var (
	sc *bufio.Scanner = func() *bufio.Scanner {
		sc := bufio.NewScanner(os.Stdin)
		buf := make([]byte, initialBufSize)
		sc.Buffer(buf, maxBufSize)
		sc.Split(bufio.ScanWords)
		return sc
	}()
)

func main() {
	W := getInt()
	H := getInt()
	N := getInt()
	x := make([]int, N)
	y := make([]int, N)
	a := make([]int, N)
	for i := 0; i < N; i++ {
		x[i] = getInt()
		y[i] = getInt()
		a[i] = getInt()
	}

	l := 0
	r := W
	t := H
	b := 0

	for i := 0; i < N; i++ {
		switch a[i] {
		case 1:
			l = max(l, x[i])
		case 2:
			r = min(r, x[i])
		case 3:
			b = max(b, y[i])
		case 4:
			t = min(t, y[i])
		}
	}

	w := max(r - l, 0)
	h := max(t - b, 0)

	fmt.Println(w * h)
}

type Graph struct {
	n     int
	edges [][]int
}

func NewGraph(n int) *Graph {
	g := &Graph{
		n:     n,
		edges: make([][]int, n),
	}
	return g
}

func (g *Graph) AddEdge(u, v int) {
	g.edges[v] = append(g.edges[v], u)
	g.edges[u] = append(g.edges[u], v)
}

func dfs(c int, edges [][]int, visited map[int]struct{}) {
	visited[c] = struct{}{}

	for _, v := range edges[c] {
		_, flag := visited[v]
		if flag {
			continue
		}
		dfs(v, edges, visited)
	}
}

func bfs(c int, graph *Graph) {
	next := make([]int, 0)
	next = append(next, c)
	visited := make(map[int]struct{})

	for ; len(next) != 0; {
		u := next[0]
		next = next[1:]
		visited[u] = struct{}{}

		for _, v := range graph.edges[u] {
			_, flag := visited[v]
			if flag {
				continue
			}

			// なにか処理

			next = append(next, v)
		}
	}
}

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getIntArray(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = getInt()
	}
	return array
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

func getStringArray(n int) []string {
	array := make([]string, n)
	for i := 0; i < n; i++ {
		array[i] = getString()
	}
	return array
}

func abs(a int) int {
	return int(math.Abs(float64(a)))
}

func pow(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}

func powMod(n, p int) int {
	if p == 0 {
		return 1
	} else if p%2 == 0 {
		t := powMod(n, p/2)
		return calcMod(t * t)
	} else {
		return calcMod(n * powMod(n, p-1))
	}
}

func min(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton min() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Min(float64(res), float64(nums[i])))
	}
	return res
}

func max(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton max() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Max(float64(res), float64(nums[i])))
	}
	return res
}

func strSearch(a []string, b string) bool {
	for i := 0; i < len(a); i++ {
		if a[i] == b {
			return true
		}
	}
	return false
}

func printIntArray(array []int) {
	strArray := fmt.Sprint(array)
	fmt.Println(strArray[1 : len(strArray)-1])
}

func calcMod(x int) int {
	return x % mod
}

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func isPrime(n int) bool {
	if n < 2 {
		return false
	} else if n == 2 {
		return true
	} else if n % 2 == 0 {
		return false
	}

	sqrtN := int(math.Sqrt(float64(n)))
	for i := 3; i <= sqrtN; i += 2 {
		if n % i == 0 {
			return false
		}
	}

	return true
}

func contains(s []int, e int) bool {
	for _, v := range s {
		if e == v {
			return true
		}
	}
	return false
}

func makeRange(min, max int) []int {
	a := make([]int, max-min+1)
	for i := range a {
		a[i] = min + i
	}
	return a
}

func powerset2(nums []int) [][]int {
	length := int(math.Pow(2, float64(len(nums))))
	result := make([][]int, length)

	index := 0
	result[index] = []int{}
	index++

	for _, n := range nums {
		max := index
		for i := 0; i < max; i++ {
			result[index] = copyAndAppend(result[i], n)
			index++
		}
	}

	return result
}

func copyAndAppend(nums []int, n int) []int {
	dst := make([]int, len(nums)+1)
	copy(dst, nums)
	dst[len(nums)] = n
	return dst
}

func calcGcd(x, y int) int {
	if y == 0 {
		return x
	} else if x >= y {
		return calcGcd(y, x % y)
	} else {
		return calcGcd(x, y % x)
	}
}

func getDivisor(n int) []int {
	var divisor []int
	divisor = append(divisor, 1)
	if n != 1 {
		divisor = append(divisor, n)
	}

	sqrt := int(math.Sqrt(float64(n)))
	for i := 2; i <= sqrt; i++ {
		if n % i == 0 {
			divisor = append(divisor, i)
			divisor = append(divisor, n/i)
		}
	}
	return divisor
}

type intHeap []int

func (h intHeap) Len() int {
	return len(h)
}

func (h intHeap) Less(i, j int) bool {
	return h[i] > h[j]
}

func (h intHeap) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

func (h *intHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *intHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func initHeap() *intHeap {
	ih := &intHeap{}
	heap.Init(ih)
	return ih
}

func (h *intHeap) pushHeap(n int) {
	heap.Push(h, n)
}

func (h *intHeap) popHeap() int {
	return heap.Pop(h).(int)
}

func factMod(n int) int {
	value := 1
	for ; n > 1; n-- {
		value = calcMod(value * n)
	}
	return value
}

func combinationMod(n, k int) int {
	factN := factMod(n)
	factK := factMod(k)
	factNK := factMod(n - k)
	factKR := powMod(factK, mod - 2)
	factNKR := powMod(factNK, mod - 2)
	return calcMod(factN * calcMod(factKR * factNKR))
}

func primeFactors(n int) [] int {
	factors := make([]int, 0)
	i := 2
	for i * i <= n {
		r := n % i
		if r != 0 {
			i += 1
		} else if r == 0 {
			n /= i
			factors = append(factors, i)
		}
	}
	if n > 1 {
		factors = append(factors, n)
	}
	return factors
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
	di8     = []int64{-1, -1, 0, 1, 1, 1, 0, -1}
	dj8     = []int64{0, -1, -1, -1, 0, 1, 1, 1}
)

type point struct {
	x, y int64
}

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	W, H, N := readInt(), readInt(), readInt()
	l, r := point{0, 0}, point{W, H}

	for i := int64(0); i < N; i++ {
		x, y, a := readInt(), readInt(), readInt()
		switch a {
		case 1:
			l.x = max(l.x, x)
			r.x = max(r.x, x)
		case 2:
			l.x = min(l.x, x)
			r.x = min(r.x, x)
		case 3:
			l.y = max(l.y, y)
			r.y = max(r.y, y)
		case 4:
			l.y = min(l.y, y)
			r.y = min(r.y, y)
		}
	}
	fmt.Println((abs(r.x-l.x) * abs(r.y-l.y)))
}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func max(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans < v {
			ans = v
		}
	}
	return ans
}
func min(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans > v {
			ans = v
		}
	}
	return ans
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func scanInt() int {
	sc.Scan()
	iv, _ := strconv.Atoi(sc.Text())
	return iv
}

func init() {
	sc.Split(bufio.ScanWords)
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func main() {
	w, h, n := scanInt(), scanInt(), scanInt()

	xl, xr := 0, w
	yl, yr := 0, h
	for i := 0; i < n; i++ {
		x, y, a := scanInt(), scanInt(), scanInt()
		switch a {
		case 1:
			xl = max(xl, x)
		case 2:
			xr = min(xr, x)
		case 3:
			yl = max(yl, y)
		case 4:
			yr = min(yr, y)
		}
	}
	if xr > xl && yr > yl {
		fmt.Println((xr - xl) * (yr - yl))
	} else {
		fmt.Println(0)
	}
}


package main

import "fmt"

func main() {
	// Code for B - Snuke's Coloring 2 (ABC Edit)
	var W, H, N int
	fmt.Scanf("%d %d %d", &W, &H, &N)

	x := make([]int, N)
	y := make([]int, N)
	a := make([]int, N)

	for i := 0; i < N; i++ {
		fmt.Scanf("%d %d %d", &x[i], &y[i], &a[i])
	}

	var X1, Y1, X2, Y2 int
	X1 = 0
	Y1 = 0
	X2 = W
	Y2 = H
	for i := 0; i < N; i++ {
		if a[i] == 1 {
			if X1 <= x[i] {
				X1 = x[i]
			}
		} else if a[i] == 2 {
			if X2 >= x[i] {
				X2 = x[i]
			}
		} else if a[i] == 3 {
			if Y1 <= y[i] {
				Y1 = y[i]
			}
		} else {
			if Y2 >= y[i] {
				Y2 = y[i]
			}
		}
	}

	S := (X2 - X1) * (Y2 - Y1)
	if S < 0 {
		fmt.Println("0")
	} else {
		fmt.Println(S)
	}
}


package main

import "fmt"

func main() {
	// Code for B - Snuke's Coloring 2 (ABC Edit)
	var W, H, N int
	fmt.Scanf("%d %d %d", &W, &H, &N)

	x := make([]int, N)
	y := make([]int, N)
	a := make([]int, N)

	for i := 0; i < N; i++ {
		fmt.Scanf("%d %d %d", &x[i], &y[i], &a[i])
	}

	var X1, Y1, X2, Y2 int
	X1 = 0
	Y1 = 0
	X2 = W
	Y2 = H
	for i := 0; i < N; i++ {
		if a[i] == 1 {
			if X1 <= x[i] {
				X1 = x[i]
			}
		} else if a[i] == 2 {
			if X2 >= x[i] {
				X2 = x[i]
			}
		} else if a[i] == 3 {
			if Y1 <= y[i] {
				Y1 = y[i]
			}
		} else if a[i] == 4 {
			if Y2 >= y[i] {
				Y2 = y[i]
			}
		}
	}

	S := (X2 - X1) * (Y2 - Y1)
	if S < 0 {
		fmt.Println("0")
	} else {
		fmt.Println(S)
	}
}


package main

import "fmt"

func main() {
	// Code for B - Snuke's Coloring 2 (ABC Edit)
	var W, H, N int
	fmt.Scanf("%d %d %d", &W, &H, &N)

	x := make([]int, N)
	y := make([]int, N)
	a := make([]int, N)

	for i := 0; i < N; i++ {
		fmt.Scanf("%d %d %d", &x[i], &y[i], &a[i])
	}

	var X1, Y1, X2, Y2 int
	X1 = 0
	Y1 = 0
	X2 = W
	Y2 = H
	for i := 0; i < N; i++ {
		if a[i] == 1 {
			if X1 < x[i] {
				X1 = x[i]
			}
		} else if a[i] == 2 {
			if X2 > x[i] {
				X2 = x[i]
			}
		} else if a[i] == 3 {
			if Y1 < y[i] {
				Y1 = y[i]
			}
		} else if a[i] == 4 {
			if Y2 > y[i] {
				Y2 = y[i]
			}
		}
	}
	S := (X2 - X1) * (Y2 - Y1)
	if S < 0 {
		fmt.Println("0")
	} else {
		fmt.Println(S)
	}
}


W,H,N = gets.split.map(&:to_i)
x_left = 0
x_right = W
y_bottom = 0
y_top = H
N.times do |i|
    x,y,a = gets.split.map(&:to_i)
    case a
    when 1
        x_left = x if x_left < x
    when 2
        x_right = x if x < x_right
    when 3
        y_bottom = y if y_bottom < y
    when 4
        y_top = y if y < y_top
    end
end
x = x_right - x_left
y = y_top - y_bottom
x = 0 if x < 0
y = 0 if y < 0
puts x*y


w,h,n = gets.split.map(&:to_i)
xl = 0
xr = w
yl = 0
yh = h
n.times do
  x,y,a = gets.split.map(&:to_i)
  if a == 1
    xl = x if x >= xl
  elsif a == 2
    xr = x if x <= xr
  elsif a == 3
    yl = y if y > yl
  else
    yh = y if y < yh
  end
end

ans = (yh-yl) * (xr - xl)
if yh -yl > 0 && xr - xl > 0
  puts ans
else
  puts 0
end


w, h, n = gets.split.map(&:to_i)
a = Array.new(n){gets.split.map(&:to_i)}
x0, y0, x1, y1 = 0, 0, w, h
n.times do |i|
  if a[i][2] == 1
    x0 = a[i][0] if x0 < a[i][0]
  elsif a[i][2] == 2
    x1 = a[i][0] if x1 > a[i][0]
  elsif a[i][2] == 3
    y0 = a[i][1] if y0 < a[i][1]
  elsif a[i][2] == 4
    y1 = a[i][1] if y1 > a[i][1]
  end
end
puts (x1 > x0 && y1 > y0 ? (x1 - x0) * (y1 - y0) : 0)


w, h, n = gets.split.map(&:to_i)
arr = [nil, 0, w, 0, h]

n.times do
  x, y, a = gets.split.map(&:to_i)

  arr[a] = a <= 2 ? x : y
end

puts (arr[1]...arr[2]).to_a.length * (arr[3]...arr[4]).to_a.length


W,H,N = gets.chomp.split(" ").map(&:to_i)
x,y,a = N.times.map{gets.split.map(&:to_i)}.transpose
x0 = 0
y0 = 0
x1 = W
y1 = H
N.times do |i|
  if a[i] == 1
    x0 = x[i] if x0 < x[i]
  elsif a[i] == 2
    x1 = x[i] if x1 > x[i]
  elsif a[i] == 3
    y0 = y[i] if y0 < y[i]
  else
    y1 = y[i] if y1 > y[i]
  end
end
puts [(x1-x0)*(y1-y0),0].max


w,h,n = gets.chomp.split(' ').map(&:to_i)
i = 0
hash = {1=>0, 2=>w, 3=>0, 4=>h}
# p hash
while i < n
  x,y,a = gets.chomp.split(' ').map(&:to_i)
  case a
  when 1
    if hash[a] < x # 存在し、xが大きい場合
      hash[a] = x
    end
  when 2
    if hash[a] > x # 存在し、xが大きい場合
      hash[a] = x
    end
  when 3
    if hash[a] < y # 存在し、yが大きい場合
      hash[a] = y
    end
  when 4
    if hash[a] > y # 存在し、yが大きい場合
      hash[a] = y
    end
  end
  i += 1
end

# p hash
# 縦 * 横
s = ((h-hash[3]) - (h-hash[4])) * ((h-hash[1]) - (h-hash[2])) >= 0 ?
((h-hash[3]) - (h-hash[4])) * ((h-hash[1]) - (h-hash[2])) : 0
p s


use std::io::{Read, stdin};
use std::str::FromStr;
use std::cmp;

fn main() {
    let w: i64 = read();
    let h: i64 = read();
    let n = read();
    let mut x_min: i64 = 0;
    let mut x_max: i64 = w;
    let mut y_min: i64 = 0;
    let mut y_max: i64 = h;

    for _i in 0..n {
        let x: i64 = read();
        let y: i64 = read();
        let a = read();
        match a {
            1 => x_min = cmp::max(x_min, x),
            2 => x_max = cmp::min(x_max, x),
            3 => y_min = cmp::max(y_min, y),
            4 => y_max = cmp::min(y_max, y),
            _ => (),
        }
    }
    let mut ans = 0;
    if y_max > y_min && x_max > x_min {
        ans = (y_max - y_min) * (x_max - x_min);
    }
    println!("{}", ans);
}

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}


macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { let mut $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { let $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }

use std::cmp::max;
fn main() {
    input! {
        w: i64,
        h: i64,
        n: i64,
        xya: [(i64, i64, i8); n],
    }
    let mut p = (0,0,w,h);
    for (x,y,a) in xya {
        match a {
            1 => if p.0 < x { p.0 = x },
            2 => if p.2 > x { p.2 = x },
            3 => if p.1 < y { p.1 = y },
            4 => if p.3 > y { p.3 = y },
            _ => panic!()
        };
    }
    println!("{}", max(p.2-p.0,0) * max(p.3-p.1, 0));
}


use std::cmp::max;
use std::cmp::min;
use std::io::stdin;

fn main() {
    let mut s = String::new();
    stdin().read_line(&mut s).ok();
    let mut itr = s.split_whitespace().map(|e| e.parse::<usize>().unwrap());
    let w = itr.next().unwrap();
    let h = itr.next().unwrap();
    let n = itr.next().unwrap();
    let mut xl = 0;
    let mut xh = w;
    let mut yl = 0;
    let mut yh = h;

    for _ in 0..n {
        let mut s = String::new();
        stdin().read_line(&mut s).ok();
        let mut itr = s.split_whitespace().map(|e| e.parse::<usize>().unwrap());
        let x = itr.next().unwrap();
        let y = itr.next().unwrap();
        let a = itr.next().unwrap();
        match a {
            1 => xl = max(xl, x),
            2 => xh = min(xh, x),
            3 => yl = max(yl, y),
            4 => yh = min(yh, y),
            _ => (),
        }
    }

    println!(
        "{}",
        if xl < xh && yl < yh {
            (xh - xl) * (yh - yl)
        } else {
            0
        }
    );
}


use proconio::{input, fastout};
use proconio::marker::{Chars};
use proconio::marker::Usize1;
use std::cmp::*;

macro_rules! debug {
      ($($a:expr),*) => {
          eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

#[fastout]
fn main() {
    input!{
        w: usize,
        h: usize,
        n: usize,
    }

    let mut x: Vec<usize> = Vec::new();
    let mut y: Vec<usize> = Vec::new();
    let mut a: Vec<usize> = Vec::new();
    for i in 0..n {
        input!{
            x_tmp: usize,
            y_tmp: usize,
            a_tmp: usize,
        }
        x.push(x_tmp);
        y.push(y_tmp);
        a.push(a_tmp);
    }

    let mut sx = 0;
    let mut sy = 0;
    let mut dx = w;
    let mut dy = h;
    for i in 0..n {
        if a[i]==1 {
            sx = x[i];
        } else if a[i]==2 {
            dx = x[i];
        } else if a[i]==3 {
            sy = y[i];
        } else {
            dy = y[i];
        }
    }

    if sx<dx && sy<dy {
        println!("{}", (dx-sx)*(dy-sy));
    } else {
        println!("0");
    }

}


#![allow(unused_imports)]

use std::{i32, i64, u32, u64, usize, f64};
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::io::{stdout, Write, BufWriter};
use std::mem::{swap};
use maplit::*;
use proconio::marker::{Isize1, Usize1, Bytes, Chars};

#[proconio::fastout]
fn main() {
    proconio::input!(
        w: i32,
        h: i32,
        n: usize,
        xya: [(i32, i32, i32); n],
    );
    let (mut xl, mut xr, mut yb, mut ya) = (0, w, 0, h);
    for (x, y, a) in xya {
        match a {
            1 => { xl = max(xl, x); },
            2 => { xr = min(xr, x); },
            3 => { yb = max(yb, y); },
            _ => { ya = min(ya, y); },
        };
    };
    println!("{}", max(0, (xr - xl) * (ya - yb)));
}


#![allow(unused, non_snake_case, dead_code, non_upper_case_globals)]
use std::cmp::*;
use std::collections::*;
use std::mem::*;

fn main() {
    let (r, w, e) = (std::io::stdin(), std::io::stdout(), std::io::stderr());
    let mut io = IO::new(r.lock(), w.lock(), e.lock());

    let (w, h, n) = (io.read::<i64>(), io.read::<i64>(), io.read::<i64>());

    let mut mn2 = w;
    let mut mx1 = 0i64;
    let mut mx3 = 0i64;
    let mut mn4 = h;
    for _ in 0..n {
        let (x, y, a) = (io.read::<i64>(), io.read::<i64>(), io.read::<i64>());
        match a {
            1 => mx1 = max(mx1, x),
            2 => mn2 = min(mn2, x),
            3 => mx3 = max(mx3, y),
            _ => mn4 = min(mn4, y),
        }
    }
    if mx1 > mn2 && mx3 > mn4 {
        io.writeln((mx1 - mn2) * (mx3 - mn4));
    } else {
        io.writeln(0);
    }
}

static MOD: i64 = 1000000007;
static INF: i64 = std::i64::MAX >> 1;
// IO
use std::io::*;
struct IO<R: Read, W: Write, E: Write> {
    Read: R,
    Write: BufWriter<W>,
    Error: BufWriter<E>,
}
impl<R: Read, W: Write, E: Write> IO<R, W, E> {
    fn new(r: R, w: W, e: E) -> IO<R, W, E> {
        IO {
            Read: r,
            Write: BufWriter::new(w),
            Error: BufWriter::new(e),
        }
    }
    fn read<T>(&mut self) -> T
    where
        T: std::str::FromStr,
    {
        let next: String = self
            .Read
            .by_ref()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect();
        next.parse().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
    fn chari(&mut self) -> Vec<i64> {
        self.chars()
            .iter()
            .map(|&c| (c as u8 - b'0') as i64)
            .collect::<Vec<i64>>()
    }
    fn readn<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read::<T>()).collect::<Vec<_>>()
    }
    fn readmat<T: std::str::FromStr>(&mut self, n: usize, m: usize) -> Vec<Vec<T>> {
        (0..n).map(|_| self.readn(m)).collect()
    }
    fn write<S: ToString>(&mut self, val: S) {
        self.Write.write(val.to_string().as_bytes());
    }
    fn writeln<S: ToString>(&mut self, val: S) {
        self.Write.write(val.to_string().as_bytes());
        self.Write.write(b"\n");
    }
    fn debug<S: std::fmt::Debug>(&mut self, val: S) {
        writeln!(self.Error, "(debug) {:?}", &val);
    }
    fn debug2<S: std::fmt::Debug, T: std::fmt::Debug>(&mut self, val1: S, val2: T) {
        writeln!(self.Error, "(debug2) {:?} -> {:?}", val1, val2);
    }
    fn debug3<S: std::fmt::Debug, T: std::fmt::Debug, U: std::fmt::Debug>(
        &mut self,
        val1: S,
        val2: T,
        val3: U,
    ) {
        writeln!(
            self.Error,
            "(debug3) {:?} -> {:?} -> {:?}",
            val1, val2, val3
        );
    }
}


let input = readLine()!.characters.split(" ").map{Int(String($0))!}
let (W, H, N) = (input[0], input[1], input[2])
var (minX, minY, maxX, maxY) = (0, 0, W, H)
for _ in 0..<N {
    let input = readLine()!.characters.split(" ").map{Int(String($0))!}
    let (x, y, a) = (input[0], input[1], input[2])
  	switch a {
    case 1:
        minX = max(minX, x)
    case 2:
        maxX = min(maxX, x)
    case 3:
        minY = max(minY, y)
    case 4:
        maxY = min(maxY, y)
    default:
      	break
    }
}
print(max(0,maxX-minX) * max(0,maxY-minY))


let input = readLine()!.characters.split(" ").map{Int(String($0))!}
let (W, H, N) = (input[0], input[1], input[2])
var (minX, minY, maxX, maxY) = (0, 0, W, H)
for _ in 0..<N {
    let input = readLine()!.characters.split(" ").map{Int(String($0))!}
    let (x, y, a) = (input[0], input[1], input[2])
  	switch a {
    case 1:
        minX = max(minX, x)
    case 2:
        maxX = min(maxX, x)
    case 3:
        minY = max(minY, y)
    case 4:
        maxY = min(maxY, y)
    default:
      	break
    }
}
print((maxX-minX) * (maxY-minY))


let input = readLine()!.characters.split(" ").map{Int(String($0))!}
let (W, H, N) = (input[0], input[1], input[2])
var (minX, minY, maxX, maxY) = (0, 0, W, H)
for _ in 0..<N {
    let input = readLine()!.characters.split(" ").map{Int(String($0))!}
    let (x, y, a) = (input[0], input[1], input[2])
  	switch a {
    case 1:
        minX = max(minX, x)
    case 2:
        maxX = min(maxX, x)
    case 3:
        minY = max(minY, y)
    case 4:
        maxY = min(maxY, y)
    }
}
print(max(0, maxX-minX) * max(0,maxY-minY))


"use strict";

const Main = args => {
  const input = args.trim().split("\n").map(e => e.split(' ').map(e => e - 0));
  const paints = input.slice(1);

  let xMin = 0;
  let xMax = input[0][0];
  let yMin = 0;
  let yMax = input[0][1];

  paints.forEach(e => {
    let xi = e[0];
    let yi = e[1];
    let ai = e[2];

    if (ai === 1) {
      if (xMin < xi) xMin = xi;
    } else if (ai === 2) {
      if (xMax > xi) xMax = xi;
    } else if (ai === 3) {
      if (yMin < yi) yMin = yi;
    } else if (ai === 4) {
      if (yMax > yi) yMax = yi;
    }
  });

  let x = xMax - xMin;
  let y = yMax - yMin;
  console.log((x > 0 && y > 0) ? x * y : 0);
}

Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


const main = (txt: any): void => {
  const input = txt.split('\n')
  let [W, H, N] = input[0].split(' ').map((i: string) => { return Number(i) })
  let Ma1 = 0
  let Ma2 = W
  let Ma3 = 0
  let Ma4 = H
  for (let i = 1; i <= N; i++) {
    let x: number
    let y: number
    let a: number
    [x, y, a] = input[i].split(' ').map((i: string) => { return Number(i) })
    if (a === 1 && x > Ma1) {
      Ma1 = x
    }
    if (a === 2 && x < Ma2) {
      Ma2 = x
    }
    if (a === 3 && y > Ma3) {
      Ma3 = y
    }
    if (a === 4 && y < Ma4) {
      Ma4 = y
    }
  }
  const Wn = Ma2 - Ma1
  const Hn = Ma4 - Ma3
  const sum = (Ma2 - Ma1) * (Ma4 - Ma3)
  if (sum >= 0 && Wn > 0 && Hn > 0) {
    console.log(sum)
  }
  else {
    console.log('0')
  }
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));


const main = (txt: any): void => {
  const input = txt.split('\n')
  let [W, H, N] = input[0].split(' ').map((i: string) => { return Number(i) })
  let Ma1 = 0
  let Ma2 = W
  let Ma3 = 0
  let Ma4 = H
  for (let i = 1; i <= N; i++) {
    const [x, y, a] = input[i].split(' ').map((i: string) => { return Number(i) })
    if (a === 1 && x > Ma1) {
      Ma1 = x
    }
    if (a === 2 && x < Ma2) {
      Ma2 = x
    }
    if (a === 3 && y > Ma3) {
      Ma3 = y
    }
    if (a === 4 && y < Ma4) {
      Ma4 = y
    }
  }
  const Wn = Ma2 - Ma1
  const Hn = Ma4 - Ma3
  const sum = (Ma2 - Ma1) * (Ma4 - Ma3)
  if (sum >= 0 && Wn > 0 && Hn > 0) {
    console.log(sum)
  }
  else {
    console.log('0')
  }
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));


import { readFileSync } from "fs";

const read = () =>
  readFileSync(0, "utf8")
    .split("\n")
    .map((line) => line.split(" "));

const main = (input: string[][]) => {
  const [W, H, N] = input[0].map(Number);

  let top = H;
  let bottom = 0;
  let left = 0;
  let right = W;

  for (let i = 1; i <= N; i++) {
    const [x, y, a] = input[i].map(Number);

    switch (a) {
      case 1: {
        left = x;
        break;
      }
      case 2: {
        right = x;
        break;
      }
      case 3: {
        bottom = y;
        break;
      }
      case 4: {
        top = y;
        break;
      }
    }
  }

  const height = Math.max(0, top - bottom);
  const width = Math.max(0, right - left);

  return height * width;
};

console.log(main(read()));


import { readFileSync } from "fs";

const read = () =>
  readFileSync(0, "utf8")
    .split("\n")
    .map((line) => line.split(" "));

const main = (input: string[][]) => {
  const [W, H, N] = input[0].map(Number);

  let top = H;
  let bottom = 0;
  let left = 0;
  let right = W;

  for (let i = 1; i <= N; i++) {
    const [x, y, a] = input[i].map(Number);

    switch (a) {
      case 1: {
        left = x;
        break;
      }
      case 2: {
        right = x;
        break;
      }
      case 3: {
        bottom = y;
        break;
      }
      case 4: {
        top = y;
        break;
      }
    }
  }

  return Math.max(0, (top - bottom) * (right - left));
};

console.log(main(read()));


"use strict";

const Main = args => {
  const input = args.trim().split("\n").map(e => e.split(' ').map(e => e - 0));
  const paints = input.slice(1);

  let xMin = 0;
  let xMax = input[0][0];
  let yMin = 0;
  let yMax = input[0][1];

  paints.forEach(e => {
    let xi = e[0];
    let yi = e[1];
    let ai = e[2];

    if (ai === 1) {
      if (xMin < xi) xMin = xi;
    } else if (ai === 2) {
      if (xMax > xi) xMax = xi;
    } else if (ai === 3) {
      if (yMin < yi) yMin = yi;
    } else if (ai === 4) {
      if (yMax > yi) yMax = yi;
    }
  });

  let area = (xMax - xMin) * (yMax - yMin);
  console.log(area > 0 ? area : 0);
}

Main(require('fs').readFileSync('/dev/stdin', 'utf8'));


s = input()
l = sorted(s)
if l[0] == l[1] and l[1] != l[2] and l[2] == l[3]:
    print('Yes')
else:
    print('No')


s_ll = sorted(list(input()))
if s_ll[0] == s_ll[1] and s_ll[2] == s_ll[3] and s_ll[1] != s_ll[2]:
    print('Yes')
else:
    print('No')


S = input()
D = {chr(i):0 for i in range(65, 65+26)}

f=0
for i in range(4):
  D[S[i]] += 1
  if D[S[i]] == 2:
    f +=1

if f ==2:
  print ("Yes")
else:
  print ("No")


s=input()
ans="No"
for i in range(4):
    if s.count(s[i])==2:
        ans="Yes"
print(ans)


s=input()
if s[0]==s[1]==s[2]==s[3]:
  print("No")
elif s[0]!=s[1]!=s[2]!=s[3]:
  print("NO")
elif s[0]==s[1]==s[2]:
  print("No")
elif s[1]==s[2]==s[3]:
  print("No")
elif s[0]==s[2]==s[3]:
  print("No")
elif s[0]==s[1]==s[3]:
  print("No")
else:
  print("Yes")


s=input()

if s[0]==s[1]==s[2]==s[3]:
  print("No")
elif s[0]!=s[1]!=s[2]!=s[3]:
  print("NO")
elif s[0]==s[1]==s[2]:
  print("No")
elif s[1]==s[2]==s[3]:
  print("No")
elif s[0]==s[2]==s[3]:
  print("No")
elif s[0]==s[1]==s[3]:
  print("No")
else:
  print("Yes")


import java.util.*;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.awt.Point;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        char[] c = new char[4];

        int count = 1;
        boolean flag = true;
        for (int i = 0; i < s.length(); i++) {
            count = 1;
            for (int j = 0; j < s.length(); j++) {
                if (i == j) continue;
                if (s.charAt(i) == s.charAt(j)) {
                    count++;
                }
            }
            if (count != 2) {
                flag = false;
                break;
            }
        }

        System.out.println(flag?"Yes":"No");
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

class Main {
	public static void main(String args[]) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		Solver solver = new Solver();
		solver.init();
		solver.readHead(in.readLine());
		// for (; solver.hasNext();) {
		// solver.readBody(in.readLine());
		// }
		// solver.solve();
	}
}

class Solver {
	int N;
	int cnt;

	public void init() {
		N = 0;
		cnt = 0;
	}

	public void readHead(String str) {
		// String[] strArr = str.split("\\s+");
		// N = Integer.parseInt(strArr[0]);
		// System.out.println(N);
		HashMap<Character, Integer> hist = new HashMap<Character, Integer>();
		for (char c : str.toCharArray()) {
			if (hist.containsKey(c)) {
				hist.put(c, hist.get(c) + 1);
			} else {
				hist.put(c, 1);
			}
		}
		if (hist.size() == 2 && hist.get(str.charAt(0)) == 2)
			System.out.println("Yes");
		else
			System.out.println("No");
	}

	public boolean hasNext() {
		return cnt < N;
	}

	public void readBody(String str) {
		// System.out.println(str);
		cnt++;
	}

	public void solve() {

	}
}