#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
using namespace std;
#define INF ((1<<30)-1)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()


struct TrieNode{
	int n = 0;
	long long sum = 0;
	TrieNode* l = nullptr, * r = nullptr;
};

class Trie {
public:
	Trie() { root = new TrieNode(); }

	void insert(int x) {
		TrieNode* t = root;
		for (int i = 30; i >= 0; i--) {
			t->n++;
			t->sum += x;
			if (x >> i &1) {
				if (t->r == nullptr) t->r = new TrieNode;
				t = t->r;
			}
			else {
				if (t->l == nullptr) t->l = new TrieNode;
				t = t->l;
			}
		}
		t->n++;
		t->sum += x;
	}

	void erase(int x) {
		TrieNode* t = root;
		for (int i = 30; i >= 0; i--) {
			t->n--;
			t->sum -= x;
			if (x >> i & 1) {
				t = t->r;
			}
			else {
				t = t->l;
			}
		}
		t->n--;
		t->sum -= x;
	}

	pair<int, long long> query(int x) const{
		pair<int, long long > ret(0, 0);
		TrieNode* t = root;
		for (int i = 30; i >= 0; i--) {
			if (t == nullptr)break;
			if (x >> i & 1) {
				if (t->l) {
					ret.first += t->l->n;
					ret.second += t->l->sum;
				}
				t = t->r;
			}
			else {
				t = t->l;
			}
		}
		return ret;
	}
private:
	TrieNode* root;
};



int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int n, m, q;
	cin >> n >> m >> q;

	vector<int> a(n, 0), b(m, 0);

	Trie ta, tb;
	rep(i, n) ta.insert(0);
	rep(i, m)tb.insert(0);

	long long ans = 0;
	rep(_, q) {
		int t, x, y;
		cin >> t >> x >> y;
		x--;

		if (t == 1) {
			auto p = tb.query(a[x]);
			ans -= (long long)p.first * a[x];
			ans += p.second;
		
			p = tb.query(y);
			ans += (long long)p.first * y;
			ans -= p.second;

			ta.erase(a[x]);
			ta.insert(y);
			a[x] = y;
		}
		else {
			auto p = ta.query(b[x]);
			ans -= (long long)p.first * b[x];
			ans += p.second;
			
			p = ta.query(y);
			ans += (long long)p.first * y;
			ans -= p.second;

			tb.erase(b[x]);
			tb.insert(y);
			b[x] = y;
		}
		cout << ans << endl;
	}


	return 0;
}

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
typedef long long ll;
typedef unsigned un;
typedef std::vector<int> P;
typedef std::pair<int,int> pii;
ll read(){ll x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9')x=x*10+(c-'0'),c=getchar();return f*x;}
ll max(ll a,ll b){return a>b?a:b;}
ll min(ll a,ll b){return a<b?a:b;}
template <typename T> bool umax(T& a,T t){if(t>a)return a=t,1;return 0;}
template <typename T> bool umin(T& a,T t){if(t<a)return a=t,1;return 0;}
/**********/
const int MAXN = 200011;
struct one{int t,x,y;}a[MAXN];
int fx[MAXN],diff=0;
int place(int val){return std::lower_bound(fx+1,fx+diff+1,val)-fx;}
struct sgt
{
	struct node
	{
		ll cnt,sum;
	}t[MAXN<<2|1];
#define rt t[num]
	void modify(un pos,ll k,un l=1,un r=diff,un num=1)
	{
		rt.cnt+=k,rt.sum+=k*fx[pos];
		if(l==r)return;
		un mid=(l+r)>>1;
		if(pos<=mid)modify(pos,k,l,mid,num<<1);
		else modify(pos,k,mid+1,r,num<<1|1);
	}
	ll Qcnt(un ql,un qr,un l=1,un r=diff,un num=1)
	{
		if(ql>qr)return 0;
		if(ql<=l&&r<=qr)return rt.cnt;
		un mid=(l+r)>>1;
		ll res=0;
		if(ql<=mid)res+=Qcnt(ql,qr,l,mid,num<<1);
		if(qr>mid)res+=Qcnt(ql,qr,mid+1,r,num<<1|1);
		return res;
	}
	ll Qsum(un ql,un qr,un l=1,un r=diff,un num=1)
	{
		if(ql>qr)return 0;
		if(ql<=l&&r<=qr)return rt.sum;
		un mid=(l+r)>>1;
		ll res=0;
		if(ql<=mid)res+=Qsum(ql,qr,l,mid,num<<1);
		if(qr>mid)res+=Qsum(ql,qr,mid+1,r,num<<1|1);
		return res;
	}
}t[2];
int seq[2][MAXN];
ll f[2][MAXN];
int main()
{
	int n1=read(),n2=read(),m=read();
	fx[++diff]=0;
	for(int i=1;i<=m;++i)a[i].t=read()-1,a[i].x=read(),fx[++diff]=a[i].y=read();
	std::sort(fx+1,fx+diff+1),diff=std::unique(fx+1,fx+diff+1)-fx-1;
	t[0].modify(1,n1),t[1].modify(1,n2);
	for(int i=1;i<=n1;++i)seq[0][i]=1;
	for(int i=1;i<=n2;++i)seq[1][i]=1;
	ll ans=0;
	for(int i=1;i<=m;++i)
	{
		int tp=a[i].t,val=place(a[i].y);
		int& pre=seq[tp][a[i].x];
		///printf("%d to %d(%d)\n",pre,val,a[i].y);
		if(pre<=val)
		{
			//printf("%d\n",a[i].y-fx[pre]);
			ans+=t[!a[i].t].Qcnt(1,pre)*(a[i].y-fx[pre])+ t[!a[i].t].Qcnt(pre+1,val)*a[i].y-t[!a[i].t].Qsum(pre+1,val);
		}
		else
		{
			ans-=t[!a[i].t].Qcnt(1,val)*(fx[pre]-a[i].y)+ t[!a[i].t].Qcnt(val+1,pre)*fx[pre]-t[!a[i].t].Qsum(val+1,pre);
		}
		t[a[i].t].modify(pre,-1);
		t[a[i].t].modify(pre=val,1);
		printf("%lld\n",ans);
	}
	return 0;
}
