#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
const int BUF = 200005;
const int INF = 1 << 30;

class SegTree{
public:
  vector<long long> v;
  vector<long long> cnt;

  SegTree(){
    v = vector<long long>(BUF * 4, 0);
    cnt = vector<long long>(BUF * 4, 0);
  }
  
  pair<long long, int> get(int node, int L, int R, int LQ, int RQ){
      if(R<LQ || RQ<L) return make_pair(0, 0);
      if(LQ<=L && R<=RQ) return make_pair(v[node], cnt[node]);
      pair<long long, int> s = get(node*2+1,L,(L+R)/2,LQ,RQ);
      pair<long long, int> t = get(node*2+2,(L+R)/2+1,R,LQ,RQ);
      return make_pair(s.first + t.first, s.second + t.second);
  }
  
  pair<long long, int> update(int node, int L, int R, int Q, int chVal){
      if(R<Q || Q<L) return make_pair(v[node], cnt[node]);
      if(L==R) {
          v[node] += chVal;
          if (chVal > 0) ++cnt[node];
          if (chVal < 0) --cnt[node];
          return make_pair(v[node], cnt[node]);
      }
      pair<long long, int> s = update(node*2+1,L,(L+R)/2,Q,chVal);
      pair<long long, int> t = update(node*2+2,(L+R)/2+1,R,Q,chVal);
      v[node] = s.first + t.first;
      cnt[node] = s.second + t.second;
      return make_pair(v[node], cnt[node]);
  }
};

int row, col, nQuery;
int query[BUF][3];

void read() {
    cin >> row >> col >> nQuery;
    for (int i = 0; i < nQuery; ++i) {
        for (int j = 0; j < 3; ++j) {
            cin >> query[i][j];
        }
        --query[i][1];
    }
}


void work() {
    static int row2val[BUF] = {};
    static int col2val[BUF] = {};

    vector<int> vList;
    vList.push_back(-1);
    vList.push_back(0);
    vList.push_back(INF);
    for (int i = 0; i < nQuery; ++i) {
        vList.push_back(query[i][2]);
    }
    sort(vList.begin(), vList.end());
    vList.erase(unique(vList.begin(), vList.end()), vList.end());
    
    map<int, int> val2idx;
    for (int i = 0; i < vList.size(); ++i) {
        val2idx[vList[i]] = i;
    }
    
    
    SegTree rowStree = SegTree();
    SegTree colStree = SegTree();

    
    long long ans = 0;
    for (int loop = 0; loop < nQuery; ++loop) {
        int type = query[loop][0], idx = query[loop][1], val = query[loop][2];
        
        if (type == 1) {
            // row
            int pre = row2val[idx];

            ans -= 1LL * col * pre;
            ans += colStree.get(0, 0, BUF - 1, val2idx[0], (--val2idx.find(pre))->second).first;
            ans += 1LL * colStree.get(0, 0, BUF - 1, val2idx[pre], val2idx[INF]).second * pre;
            
            ans += 1LL * col * val;
            ans -= colStree.get(0, 0, BUF - 1, val2idx[0], (--val2idx.find(val))->second).first;
            ans -= 1LL * colStree.get(0, 0, BUF - 1, val2idx[val], val2idx[INF]).second * val;
            
            row2val[idx] = val;
            rowStree.update(0, 0, BUF - 1, val2idx[val],  val);
            rowStree.update(0, 0, BUF - 1, val2idx[pre], -pre);
        } else {
            // col
            int pre = col2val[idx];
            
            ans -= 1LL * row * pre;
            ans += rowStree.get(0, 0, BUF - 1, val2idx[0], (--val2idx.find(pre))->second).first;
            ans += 1LL * rowStree.get(0, 0, BUF - 1, val2idx[pre], val2idx[INF]).second * pre;
            
            ans += 1LL * row * val;
            ans -= rowStree.get(0, 0, BUF - 1, val2idx[0], (--val2idx.find(val))->second).first;
            ans -= 1LL * rowStree.get(0, 0, BUF - 1, val2idx[val], val2idx[INF]).second * val;
 
            col2val[idx] = val;
            colStree.update(0, 0, BUF - 1, val2idx[val],  val);
            colStree.update(0, 0, BUF - 1, val2idx[pre], -pre);
        }

        cout << ans << endl;
    }
}


int main() {
    read();
    work();
    return 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const long long N=2e6+6;
ll a[N],b[N];
long long n,m,q,ans;
struct segment {
	long long siz[N<<2],sum[N],ls[N<<2],rs[N<<2],cnt=0,root=0;
	void change(ll l,ll r,ll &p,ll x,ll k) {
		if(!p) p=++cnt;
		if(l==r) {
			sum[p]+=k*x;
			siz[p]+=k;
			return;
		}
		ll mid=(l+r)>>1;
		if(x<=mid) change(l,mid,ls[p],x,k);
		else change(mid+1,r,rs[p],x,k);
		sum[p]=sum[ls[p]]+sum[rs[p]];
		siz[p]=siz[ls[p]]+siz[rs[p]];
	}
	ll query1(ll l,ll r,ll p,ll x) {
		if(!p) return 0;
		if(r<=x) return siz[p];
		ll mid=(l+r)>>1;
		if(x<=mid) return query1(l,mid,ls[p],x);
		else return siz[ls[p]]+query1(mid+1,r,rs[p],x);
	}
	ll query2(ll l,ll r,ll p,ll x) {
		if(!p) return 0;
		if(l>x) return sum[p];
		ll mid=(l+r)>>1;
		if(x<=mid) return sum[rs[p]]+query2(l,mid,ls[p],x);
		else return query2(mid+1,r,rs[p],x);
	}
} A,B;
signed main() {
	scanf("%lld %lld %lld",&n,&m,&q);
	A.change(0,1e8,A.root,0,n),B.change(0,1e8,B.root,0,m);
	for(long long i=1;i<=q;i++) {
		long long opt,t,x,y;
		cin>>opt>>x>>y;
		if(opt==1) {
			ans=ans-B.query1(0,1e8,B.root,a[x])*a[x]-B.query2(0,1e8,B.root,a[x]);
			A.change(0,1e8,A.root,a[x],-1);
			A.change(0,1e8,A.root,y,1);
			a[x]=y;
			ans+=B.query1(0,1e8,B.root,y)*y+B.query2(0,1e8,B.root,y);
		}
		else {
			ans=ans-A.query1(0,1e8,A.root,b[x])*b[x]-A.query2(0,1e8,A.root,b[x]);
			B.change(0,1e8,B.root,b[x],-1);
			B.change(0,1e8,B.root,y,1);
			b[x]=y;
			ans+=A.query1(0,1e8,A.root,y)*y+A.query2(0,1e8,A.root,y);
		}
		cout<<ans<<endl;
	}
	return 0;
}