#include<iostream>
#include<algorithm>
#include<iomanip>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
enum{ROW=0,COLUMN=1};

int getindex(int a,map<int,int> &M){
  int index=M.size();
  if (M.find(a) == M.end())M[a]=index;
  return M[a];
}

int main(){
  ll r,c,q;
  while(cin>>r>>c>>q){
    if (r == 0 && c == 0 && q == 0)break;
    map<int,int> M[2];
    vector<pii> in[2];
    for(int i=0;i<q;i++){
      int a,b,order;
      cin>>a>>b>>order;
      int index=getindex(b,M[a]);
      if (index == in[a].size()){
	in[a].push_back(make_pair(order,i));
      }else {
	in[a][index]=make_pair(order,i);
      }
    }
    ll ans=0;
    //!Intersection Point
    for(int k=0;k<2;k++){
      for(int i=0;i<in[k].size();i++){
	if (in[k][i].first == 1){
	  ans+=(k==0?c:r)-in[1-k].size();
	}
      }
    }
    vector<int> queryStand,querySit;
    for(int i=0;i<in[1].size();i++){
      if (in[1][i].first == 1){
	queryStand.push_back(in[1][i].second);
      }else {
	querySit.push_back(in[1][i].second);
      }
    }
    sort(queryStand.begin(),queryStand.end());
    sort(querySit.begin(),querySit.end());
    //Intersection Point
    for(int i=0;i<in[0].size();i++){
      if (in[0][i].first == 1){
	ans+=queryStand.size();
	int num=lower_bound(querySit.begin(),querySit.end(),in[0][i].second)-querySit.begin();
	ans+=num;
      }else if(in[0][i].first == 0) {
	int num=lower_bound(queryStand.begin(),queryStand.end(),in[0][i].second)-queryStand.begin();
	ans+=queryStand.size()-num;
      }
    }
    cout << ans << endl;
    //cout << in[0].size() <<" " << in[1].size() << endl;
  }
  return false;
}