#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 25;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 29;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	vis[po] = 1;
//	printf("%d\n",po);
//	if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i]; if(vis[tt]) continue;
	    assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(vis,0,sizeof(vis));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 25;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[100005][100005];
int flag[100005];
int sum[100005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
//	printf("%d\n",po);
//	if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	   // assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(q == 70888 && cc > 25) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 26;
void dfs(int po,int fa) {
	int fl = 0;
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) {
	//	printf("%dhhaa: %d fa:%d\n",cc,po,fa);
		if(cc == 26) fl = 1;
	}
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	//	if(fl) { printf("hhhh:%d %d\n",po,tt); continue; }
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

		if(fl) printf("hhh %d: %d %d %d\n",po,t1,t2,t3);

		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(fl) { printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4); continue; }

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(q == 70888 && cc > 10) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 24;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= 30) printf("hhaa: %d fa:%d\n",po,fa);
    if(q == 70888 && cc > 30) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {

//	printf("%d\n",po);
	if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < mp[po].size(); ++i) {
		int tt = mp[po][i];
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(q == 70888 && cc > 50) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= 100) printf("hhaa: %d fa:%d\n",po,fa);
    if(q == 70888 && cc > 100) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {

//	printf("%d\n",po);
//	if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	    assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 27;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
//	printf("%d\n",po);
//	if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 26;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 26;
void dfs(int po,int fa) {
//	int fl = 0;
//	if(cc <INF) cc ++;
//	if(q == 70888 && cc <= Ed) {
	//	printf("%dhhaa: %d fa:%d\n",cc,po,fa);
//		if(cc == 26) fl = 1;
//	}
//    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	//	if(fl) { printf("hhhh:%d %d\n",po,tt); continue; }
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

	//	if(fl) { printf("hhh %d: %d %d %d\n",po,t1,t2,t3); continue; }

		if(t1 == 4) t2 = 0;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

	//	if(fl) { printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4); continue; }

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(q == 70888 && cc > 30) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 26;
void dfs(int po,int fa) {
	int fl = 0;
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) {
	//	printf("%dhhaa: %d fa:%d\n",cc,po,fa);
		if(cc == 26) fl = 1;
	}
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	//	if(fl) { printf("hhhh:%d %d\n",po,tt); continue; }
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

		if(fl) { printf("hhh %d: %d %d %d\n",po,t1,t2,t3); continue; }

		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(fl) { printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4); continue; }

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("hhaa: %d\n",po);
    if(q == 70888 && cc > 24) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 25;
void dfs(int po,int fa) {
	int fl = 0;
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) { printf("%dhhaa: %d fa:%d\n",cc,po,fa); if(po > 100) fl = 1; }
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(fl) printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4);

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(q == 70888 && cc > 20) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];
struct ASK{
	int ty; int x,y,z;
	ASK(int a=0,int b=0,int c=0,int d=0):ty(a), x(b), y(c), z(d){}
};

void dfs(int po) {
//	printf("%d\n",po);
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < mp[po].size(); ++i) {
		int tt = mp[po][i];
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 25;
void dfs(int po,int fa) {
	int fl = 0;
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) { printf("%dhhaa: %d fa:%d\n",cc,po,fa); fl = 1; }
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(fl) printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4);

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 26;
void dfs(int po,int fa) {
	int fl = 0;
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) {
	//	printf("%dhhaa: %d fa:%d\n",cc,po,fa);
		if(cc == 26) fl = 1;
	}
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
		if(fl) { printf("hhhh: %d\n",tt); continue; }
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(fl) { printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4); continue; }

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {

//	printf("%d\n",po);
//	if(cc > 500) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	    assert(tt > 0 && tt <= n);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
const int Ed = 26;
void dfs(int po,int fa) {
	int fl = 0;
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= Ed) {
	//	printf("%dhhaa: %d fa:%d\n",cc,po,fa);
		if(cc == 26) fl = 1;
	}
    if(q == 70888 && cc > Ed) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;

		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(fl) { printf("%d:%d %d %d %d %d %d %d\n",po,tt,x1,x2,y1,y2,y3,y4); continue; }

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po,int fa) {
	if(q == 70888) printf("hhaa: %d fa:%d\n",po,fa);
    if(q == 70888 && cc > 24) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po,int fa) {
	if(cc <INF) cc ++;
	if(q == 70888 && cc <= 23) printf("%dhhaa: %d fa:%d\n",cc,po,fa);
    if(q == 70888 && cc > 23) return;

	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt,po);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0,-1);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
int vis[MAXN];
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {
	if(q == 70888) printf("%d\n",po);
    if(q == 70888 && cc > 23) return;
    cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < (int)mp[po].size(); ++i) {
		int tt = mp[po][i];
	  //  assert(tt > 0 && tt <= q);
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;
		cc = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;

int sh[1005][1005];
int flag[1005];
int sum[1005];
int all;
vector<int> mp[MAXN];
int n,m,q;

struct Node{
	int ty; int x,y; int ans;
}as[MAXN];

int cc = 0;
void dfs(int po) {

//	printf("%d\n",po);
	if(cc > 10000) return; cc ++;
	int x1,x2; int y1,y2,y3,y4; // sh[x1][x2], all, sum[x1], flag[x1]
	for(int i = 0; i < mp[po].size(); ++i) {
		int tt = mp[po][i];
		int t1 = as[tt].ty; int t2 = as[tt].x; int t3 = as[tt].y;
		x1 = t2; x2 = t3; y1 = sh[x1][x2]; y2 = all; y3 = sum[x1]; y4 = flag[x1];

		if(t1 == 1) {
			if( (flag[t2] ^ sh[t2][t3]) == 0) {
				all ++; sh[t2][t3] ^= 1; sum[t2] ++;
			}
		}else if(t1 == 2) {
			if( (flag[t2] ^ sh[t2][t3]) == 1){
				all--; sh[t2][t3] ^= 1; sum[t2] --;
			}
		}else if(t1 == 3) {
			flag[t2] ^= 1;
			all += m-sum[t2]*2;
		   	sum[t2] = m-sum[t2];
		}

		as[tt].ans = all;
		dfs(tt);

		sh[x1][x2] = y1; all = y2; sum[x1] = y3; flag[x1] = y4;
	}
}
int main(){
	while(~scanf("%d %d %d",&n,&m,&q)){
		memset(flag,0,sizeof(flag));
		memset(sh,0,sizeof(sh));
		memset(sum,0,sizeof(sum));
		all = 0;

		for(int i = 0; i <= q; ++i) mp[i].clear();

		for(int i = 1; i <= q; ++i) {
			as[i].y = 0;
			scanf("%d",&as[i].ty);
			if(as[i].ty < 3) scanf("%d %d",&as[i].x,&as[i].y);
			else scanf("%d",&as[i].x);

			if(as[i].ty == 4) mp[as[i].x].push_back(i);
			else mp[i-1].push_back(i);
		}

		dfs(0);
		for(int i = 1; i <= q; ++i) printf("%d\n",as[i].ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,7500);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,11250);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<iterator>
#include<iostream>
#include<list>
#include<map>
#include<memory>
#include<queue>
#include<set>
#include<stack>
#include<string>
#include<vector>
#include<utility>
#include<bitset>
#define ll long long
const int inf=0x3f3f3f3f;
const int N=100005;
using namespace std;

int n,m,T;
vector<int> g[N];

struct state{
       bitset<1000> b[1000],v;
       int sum;
       state(){v.reset();
               for(int i=0;i<n;i++) {b[i].reset();sum=0;}
       }
};

queue<state> que;
int q2[N];
int q[N][3],fa[N],ans[N];

state cur,tmp;
void bfs(){//cout<<x<<','<<endl;
     int i,j,r,c,sz;
     int h=0,t=1;
     que.push(cur);
     q2[h]=0;
     while(h<t)
     {  cur=que.front();sz=g[q2[h]].size();h++;que.pop();
        tmp=cur;
        for(i=0;i<sz;i++){
        j=g[q2[h-1]][i]+1;ans[j-1]=tmp.sum;//cout<<j<<endl;
        cur=tmp;
        while(q[j][0]<4 && j<=T)
        {  if(q[j][0]==1)
           {  r=q[j][1];c=q[j][2];
              if(!(cur.b[r][c]^cur.v[r])){cur.sum++;cur.b[r][c]=cur.v[r]^1;}
           }
           else if(q[j][0]==2)
           {  r=q[j][1];c=q[j][2];
              if(cur.b[r][c]^cur.v[r]) {cur.sum--;cur.b[r][c]=cur.v[r];}
           }
           else
           {  r=q[j][1];
              if(!cur.v[r]) cur.sum+=m-cur.b[r].count()*2;
              else cur.sum+=cur.b[r].count()*2-m;
              cur.v[r]=cur.v[r]^1;
           }
           ans[j]=cur.sum;
           if(g[j].size()>0) {q2[t++]=j;que.push(cur);}
           j++;
        }
        }
     }
}
int main(){
    scanf("%d%d%d",&n,&m,&T);
    fa[0]=0;
    int i,j;g[0].push_back(0);
    for(i=1;i<=T;i++)
    {  scanf("%d%d",&q[i][0],&q[i][1]);
       if(q[i][0]<3) scanf("%d",&q[i][2]);
       q[i][1]--;q[i][2]--;
       if(q[i][0]==4)
       {  q[i][1]++;
          fa[i]=fa[q[i][1]];
          g[fa[i]].push_back(i);
       }
       else fa[i]=i;
    }
    bfs();
    for(i=1;i<=T;i++) printf("%d\n",ans[i]);
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,10937);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				*st[i]=*st[b];
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[100050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,9960);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,30000);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,9765);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				*st[i]=*st[b];
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,10156);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row *row;
		int tot;
		State()
		{
			row=new Row[n];
		}
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[100050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row *row;
		int tot;
		State()
		{
			row=new Row[n+1];
		}
		State(const State& r)
		{
			row=new Row[n+1];
			for(int i=0;i<=n;i++)
				row[i]=r.row[i];
		}
		~State()
		{
			delete[] row;
		}
		State& operator=(const State& r)
		{
			for(int i=0;i<=n;i++)
				row[i]=r.row[i];
			return *this;
		}
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[100050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[100050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,15000);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		q=min(q,9375);
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				if(b < i)
				{
					delete st[i];
					st[i]=st[b];
				}
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

namespace PROG
{
	int n,m,q;
	struct Node
	{
		Node *ls,*rs,*p;
		int num;
		void Init(int l,int r)
		{
			//cout<<l<<' '<<r<<endl;
			num=0;
			if(l == r) return;
			ls=new Node;ls->p=this;ls->Init(l,(l+r)>>1);
			rs=new Node;rs->p=this;rs->Init(((l+r)>>1)+1,r);
		}
		bool Get(int pos,int l,int r) const
		{
			if(l == r) return num;
			int mid	= (l+r)>>1;
			if(pos <= mid) return ls->Get(pos,l,mid);
			else return rs->Get(pos,mid+1,r);
		}
		void Add(int pos,int l,int r,Node *&to) const
		{
			to = new Node(*this);
			to->num++;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
		void Dec(int pos,int l,int r,Node *&to)
		{
			to = new Node(*this);
			to->num--;
			if(l == r) return;
			int mid = (l+r)>>1;
			if(pos <= mid) return to->ls->Add(pos,l,mid,to->ls);
			else return to->rs->Add(pos,mid+1,r,to->rs);
		}
	};
	struct Row
	{
		Node *root;
		bool inv;
		void Init()
		{
			inv=false;
			root = new Node;
			root->Init(1,m);
		}
		bool Get(int pos)
		{
			return root->Get(pos,1,m) != inv;
		}
		void Add(int pos)
		{
			if(!inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		void Dec(int pos)
		{
			if(inv) root->Add(pos,1,m,root);
			else root->Dec(pos,1,m,root);
		}
		int Calc()
		{
			//cout<<root->num<<' '<<inv<<endl;
			if(!inv) return root->num;
			else return m-root->num;
		}
		void Inverse()
		{
			inv=inv^true;
		}
	};
	struct State
	{
		Row row[1001];
		int tot;
		bool Get(int r,int pos)
		{
			return row[r].Get(pos);
		}
		void Init()
		{
			tot=0;
			for(int i=1;i<=1000;i++)
				row[i].Init();
		}
		void Inverse(int r)
		{
			//cout<<tot<<' '<<row[r].Calc()<<endl;
			tot=tot-row[r].Calc();
			row[r].Inverse();
			tot=tot+row[r].Calc();
			//cout<<tot<<' '<<row[r]
		}
	} *st[10050];

	int main(void)
	{
		cin>>n>>m>>q;
		st[0]=new State;
		st[0]->Init();
		int a,b,c;
		for(int i=1;i<=q;i++)
		{
			st[i]=new State(*st[i-1]);
			scanf("%d",&a);
			if(a == 1)
			{
				scanf("%d%d",&b,&c);
				if(!st[i]->Get(b,c))
					st[i]->row[b].Add(c),st[i]->tot++;
			}
			if(a == 2)
			{
				scanf("%d%d",&b,&c);
				if(st[i]->Get(b,c))
					st[i]->row[b].Dec(c),st[i]->tot--;
			}
			if(a == 3)
			{
				scanf("%d",&b);
				st[i]->Inverse(b);
			}
			if(a == 4)
			{
				scanf("%d",&b);
				delete st[i];
				st[i]=st[b];
			}
			cout<<st[i]->tot<<endl;
		}
	}
}

int main(void)
{
	PROG::main();
	return 0;
}