#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<queue>
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
using namespace std;
int n,m,q;
int ans[100050];
struct node
{
    int z;
    int i,j;
    int id;
    node(int z,int i,int j,int id):z(z),i(i),j(j),id(id) {}
};
vector<node >v[100050];
int a[1050][1050];
int an;
void dfs(int u)
{
    int siz = v[u].size();
    for(int i=0; i<siz; i++)
    {
        node vv= v[u][i];
        if(vv.z==4)
        {
            ans[vv.id]=an;
            dfs(vv.id);
        }
        else if(vv.z==1)
        {
            if(a[vv.i][vv.j]==0)
            {
                a[vv.i][vv.j]=1;
                an++;
                ans [vv.id ]=an;
                dfs(vv.id);
                an--;
                a[vv.i][vv.j]=0;
            }
            else
            {
                ans [vv.id ]=an;
                dfs(vv.id);
            }
        }
        else if(vv.z==2)
        {
            if(a[vv.i][vv.j]==1)
            {
                a[vv.i][vv.j]=0;
                an--;
                ans [vv.id ]=an;
                dfs(vv.id);
                an++;
                a[vv.i][vv.j]=1;
            }
            else
            {
                ans [vv.id ]=an;
                dfs(vv.id);
            }
        }
        else
        {
            for(int i=1; i<=m; i++)
            {
                if(a[vv.i][i]==1)
                {
                    a[vv.i][i]=0;
                    an--;
                }
                else
                {
                    a[vv.i][i]=1;
                    an++;
                }
            }
            ans[vv.id]=an;
            dfs(vv.id);
            for(int i=1; i<=m; i++)
            {
                if(a[vv.i][i]==1)
                {
                    a[vv.i][i]=0;
                    an--;
                }
                else
                {
                    a[vv.i][i]=1;
                    an++;
                }
            }
        }
    }
}
int main()
{
    cin>>n>>m>>q;
    memset(a,0,sizeof(a));
    for(int i=0; i<=q; i++)
        v[i].clear();
    for(int i=1; i<=q; i++)
    {
        int z,x,c;
        c=1;
        scanf("%d",&z);
        if(z==1||z==2)
            scanf("%d%d",&x,&c);
        else scanf("%d",&x);
        int id = i;
        if(z==4)
        {
            v[x].push_back(node(z,x,c,id));
        }
        else
        {
            v[id-1].push_back(node(z,x,c,id));
        }

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


#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int map[1005][1005] = { 0 };
int dans[100005];
int ans[100005] = { 0 };
int sum;

int main()
{
	int i, j, m, n, q,k,a,b;

	scanf("%d%d%d", &n, &m, &q);
	sum = 0;
	for (i = 1; i <= q; i++)
		dans[i] = -1;
	for (i = 1; i <= q; i++)
	{
		scanf("%d", &k);
		if (k == 1)
		{
			scanf("%d%d", &a, &b);
			if (map[a][b] == 0) sum++;
			map[a][b] = 1;

		}
		else if (k == 2)
		{
			scanf("%d%d", &a, &b);
			if (map[a][b] == 1) sum--;
			map[a][b] = 0;

		}
		else if (k == 3)
		{
			scanf("%d", &a);
			for (j = 1; j <= m; j++)
			{
				map[a][j] = 1 - map[a][j];
				if (map[a][j] == 1) sum++;
				else sum--;
			}

		}
		else if (k == 4)
		{
			scanf("%d", &a);
			dans[i] = a;
		}
		ans[i] = sum;
	}
	for (i = 1; i <= q; i++)
	{
		if (dans[i] == -1)
			printf("%d\n", ans[i]);
		else
			printf("%d\n", ans[dans[i]]);
	}
	return 0;
}


#include<stdio.h>
#include<string.h>
#include<bitset>
#include<algorithm>
#include<iostream>
using namespace std;

bitset<1001> A[1005];
bitset<1001> B;

struct node{
	int to,l,next;
}map[200005];
int head[100005];
int ans[100005];
int qq[100005],a[100005],b[100005];
int k=0;
int m,n,q;

void add(int a,int b,int c)
{
	map[k].to=b;
	map[k].l=c;
	map[k].next=head[a];
	head[a]=k++;
}

int dfs(int nn)
{
	int i,dmark;

	if(nn==0)
	{
		ans[nn]=0;
	}
	else if(qq[nn]==1)
	{
		dmark=0;
		if(A[a[nn]][b[nn]]==0)
		{
			dmark=1;
			ans[nn]++;
		}
		A[a[nn]][b[nn]]=1;
	}
	else if(qq[nn]==2)
	{
		dmark=0;
		if(A[a[nn]][b[nn]]==1)
		{
			dmark=1;
			ans[nn]--;
		}
		A[a[nn]][b[nn]]=0;
	}
	else if(qq[nn]==3)
	{
		ans[nn]=ans[nn]-A[a[nn]].count();
		A[a[nn]]^=B;
		ans[nn]=ans[nn]+A[a[nn]].count();
	}
	for(i=head[nn];i!=-1;i=map[i].next)
	{
		ans[map[i].to]=ans[nn];
		dfs(map[i].to);
	}
	if(qq[nn]==1 && dmark==1) A[a[nn]][b[nn]]=0;
	else if(qq[nn]==2 && dmark==1) A[a[nn]][b[nn]]=1;
	else if(qq[nn]==3) A[a[nn]]^=B;
}

int main()
{
	int i;

	for(i=0;i<=100000;i++)
		head[i]=-1;
	scanf("%d%d%d",&n,&m,&q);
	for(i=1;i<=m;i++)
        B[i]=1;
	for(i=1;i<=q;i++)
	{
		scanf("%d",&qq[i]);
		if(qq[i]==1) scanf("%d%d",&a[i],&b[i]);
		if(qq[i]==2) scanf("%d%d",&a[i],&b[i]);
		if(qq[i]==3) scanf("%d",&a[i]);
		if(qq[i]==4)
		{
			scanf("%d",&a[i]);
			add(a[i],i,1);
		}
		else add(i-1,i,1);
	}
	dfs(0);
	for(i=1;i<=q;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<stdio.h>
#include<string.h>
#include<bitset>
#include<algorithm>
#include<iostream>
using namespace std;

bitset<1001> A[1005];
bitset<1001> B;

struct node{
	int to,l,next;
}map[200005];
int head[100005];
int ans[100005];
int qq[100005],a[100005],b[100005];
int k=0;
int m,n,q;

void add(int a,int b,int c)
{
	map[k].to=b;
	map[k].l=c;
	map[k].next=head[a];
	head[a]=k++;
}

int dfs(int nn)
{
	int i,dmark;

	if(nn==0)
	{
		ans[nn]=0;
	}
	else if(qq[nn]==1)
	{
		dmark=0;
		if(A[a[nn]][b[nn]]==0) dmark=1;
		ans[nn]++;
		A[a[nn]][b[nn]]=1;
	}
	else if(qq[nn]==2)
	{
		dmark=0;
		if(A[a[nn]][b[nn]]==1) dmark=1;
		ans[nn]--;
		A[a[nn]][b[nn]]=0;
	}
	else if(qq[nn]==3)
	{
		ans[nn]=ans[nn]-A[a[nn]].count();
		A[a[nn]]^=B;
		ans[nn]=ans[nn]+A[a[nn]].count();
	}
	for(i=head[nn];i!=-1;i=map[i].next)
	{
		ans[map[i].to]=ans[nn];
		dfs(map[i].to);
	}
	if(qq[nn]==1 && dmark==1) A[a[nn]][b[nn]]=0;
	else if(qq[nn]==2 && dmark==1) A[a[nn]][b[nn]]=1;
	else if(qq[nn]==3) A[a[nn]]^=B;
}

int main()
{
	int i;

	for(i=0;i<=100000;i++)
		head[i]=-1;
	scanf("%d%d%d",&n,&m,&q);
	for(i=1;i<=m;i++)
        B[i]=1;
	for(i=1;i<=q;i++)
	{
		scanf("%d",&qq[i]);
		if(qq[i]==1) scanf("%d%d",&a[i],&b[i]);
		if(qq[i]==2) scanf("%d%d",&a[i],&b[i]);
		if(qq[i]==3) scanf("%d",&a[i]);
		if(qq[i]==4)
		{
			scanf("%d",&a[i]);
			add(a[i],i,1);
		}
		else add(i-1,i,1);
	}
	dfs(0);
	for(i=1;i<=q;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int map[1005][1005] = { 0 };
int dans[100005];
int ans[100005] = { 0 };
int sum;

int main()
{
	int i, j, m, n, q,k,a,b;

	scanf("%d%d%d", &n, &m, &q);
	sum = 0;
	for (i = 1; i <= q; i++)
		dans[i] = -1;
	for (i = 1; i <= q; i++)
	{
		scanf("%d", &k);
		if (k == 1)
		{
			scanf("%d%d", &a, &b);
			if (map[a][b] == 0) sum++;
			map[a][b] = 1;

		}
		else if (k == 2)
		{
			scanf("%d%d", &a, &b);
			if (map[a][b] == 1) sum--;
			map[a][b] = 0;

		}
		else if (k == 3)
		{
			scanf("%d", &a);
			for (j = 1; j <= m; j++)
			{
				map[a][j] = 1 - map[a][j];
				if (map[a][j] == 1) sum++;
				else sum--;
			}

		}
		else if (k == 4)
		{
			scanf("%d", &a);
			dans[i] = a;
		}
		ans[i] = sum;
	}
	for (i = 1; i <= q; i++)
	{
		if (dans[i] == -1)
			printf("%d\n", ans[i]);
		else
			printf("%d\n", ans[dans[i]]);
	}
	system("pause");
	return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
bitset<1001> temp;
int ques[maxn][3],ans[maxn];
vector<int> next[maxn];
int n,m,q;

void oper1(int i,int j){
    bit[i].set(j);
}

void oper2(int i,int j){
    bit[i].reset(j);
}

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

int counting(){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=bit[i].count();
    }
    return sum;
}

void dfs(int x){
    for(int i=0;i<next[x].size();i++){
        int status=0;
        int l=next[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                if(bit[ques[l][1]][ques[l][2]]==0)
                    status=1;
                oper1(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper2(ques[l][1],ques[l][2]);
                break;
            case 2:
                if(bit[ques[l][1]][ques[l][2]]==1)
                    status=1;
                oper2(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper1(ques[l][1],ques[l][2]);
                break;
            case 3:
                temp=bit[ques[l][1]];
                oper3(ques[l][1]);
                ans[l]=counting();
                dfs(l);
                bit[ques[l][1]]=temp;
                break;
            case 4:
                ans[l]=ans[ques[l][1]];
        }
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i-1][0]==4){
            next[ques[i-1][1]].push_back(i);
        }
        else{
            next[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
int ques[100000][4];
struct storage{
    bitset<1001> bit[1001];
};

map<int,storage> s;

storage p;

void oper1(int i,int j){
    p.bit[i].set(j);
}

void oper2(int i,int j){
    p.bit[i].reset(j);
}

void oper3(int i,int m){
    for(int j=1;j<=m;j++)
        p.bit[i].flip(j);
}

int counting(int n){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=p.bit[i].count();
    }
    return sum;
}

int main(){
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);

    for(int i=0;i<q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
            if(ques[i][0]==4){
                if(ques[ques[i][1]][3]==0)
                    ques[ques[i][1]][3]=i;
                else{
                    int m=ques[ques[i][1]][3]+1;
                    while(ques[m][3]!=0)
                        m=ques[m][3]+1;
                    ques[m][3]=i;
                }
            }
        }
    }
    for(int i=0;i<q;i++){
        if(ques[i][3]!=0){
            s[ques[i][3]]=p;
        }
        switch (ques[i][0]){
            case 1:
                oper1(ques[i][1],ques[i][2]);
                break;
            case 2:
                oper2(ques[i][1],ques[i][2]);
                break;
            case 3:
                oper3(ques[i][1],m);
                break;
            case 4:
                p=s[i];
        }
        printf("%d\n",counting(n));
    }

    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
bitset<1001> temp;
int ques[maxn][3],ans[maxn];
vector<int> next[maxn];
int n,m,q;

void oper1(int i,int j){
    bit[i].set(j);
}

void oper2(int i,int j){
    bit[i].reset(j);
}

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

int counting(){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=bit[i].count();
    }
    return sum;
}

void dfs(int x){
    for(int i=0;i<next[x].size();i++){
        int status=0;
        int l=next[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                if(bit[ques[l][1]][ques[l][2]]==0)
                    status=1;
                oper1(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper2(ques[l][1],ques[l][2]);
                break;
            case 2:
                if(bit[ques[l][1]][ques[l][2]]==1)
                    status=1;
                oper2(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper1(ques[l][1],ques[l][2]);
                break;
            case 3:
                temp=bit[ques[l][1]];
                oper3(ques[l][1]);
                ans[l]=counting();
                dfs(l);
                bit[ques[l][1]]=temp;
                break;
            case 4:
                ans[l]=ans[ques[l][1]];
        }
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i-1][0]==4){
            int p=ques[i-1][1];
            while(ques[p][0]==4)
                p=ques[p][1];
            next[p].push_back(i);
        }
        else{
            next[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];

int ques[maxn][3],ans[maxn];
vector<int> next[maxn];
int n,m,q;

void oper1(int i,int j){
    bit[i].set(j);
}

void oper2(int i,int j){
    bit[i].reset(j);
}

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

int counting(){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=bit[i].count();
    }
    return sum;
}

void dfs(int x){
    bitset<1001> temp;
    for(int i=0;i<next[x].size();i++){
        int status=0;
        int l=next[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                if(bit[ques[l][1]][ques[l][2]]==0)
                    status=1;
                oper1(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper2(ques[l][1],ques[l][2]);
                break;
            case 2:
                if(bit[ques[l][1]][ques[l][2]]==1)
                    status=1;
                oper2(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper1(ques[l][1],ques[l][2]);
                break;
            case 3:
                temp=bit[ques[l][1]];
                oper3(ques[l][1]);
                ans[l]=counting();
                dfs(l);
                bit[ques[l][1]]=temp;
                break;
            case 4:
                ans[l]=ans[x];
                dfs(l);
        }
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i][0]==4){
            next[ques[i][1]].push_back(i);
        }
        else{
            next[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];

int ques[maxn][3],ans[maxn];
vector<int> nnext[maxn];
int n,m,q;

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

void dfs(int x){
    bitset<1001> temp;
    for(int i=0;i<nnext[x].size();i++){
        int status=0;
        int l=nnext[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                if(bit[ques[l][1]][ques[l][2]]==0){
                    status=1;
                    bit[ques[l][1]][ques[l][2]]=1;
                }
                ans[l]=ans[x]+status;;
                dfs(l);
                if(status)
                    bit[ques[l][1]][ques[l][2]]=0;
                break;
            case 2:
                if(bit[ques[l][1]][ques[l][2]]){
                    bit[ques[l][1]][ques[l][2]]=0;
                    status=1;
                }
                ans[l]=ans[x]-status;
                dfs(l);
                if(status)
                    bit[ques[l][1]][ques[l][2]]=1;
                break;
            case 3:
                temp=bit[ques[l][1]];
                ans[l]=ans[x]-bit[ques[l][1]].count();
                oper3(ques[l][1]);
                ans[l]=ans[l]+bit[ques[l][1]].count();
                dfs(l);
                bit[ques[l][1]]=temp;
                break;
            case 4:
                ans[l]=ans[x];
                dfs(l);
        }
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i][0]==4){
            nnext[ques[i][1]].push_back(i);
        }
        else{
            nnext[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];

int ques[maxn][3],ans[maxn];
vector<int> nnext[maxn];
int n,m,q;

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

void dfs(int x){
    bitset<1001> temp;
    for(int i=0;i<nnext[x].size();i++){
        int status=0;
        int l=nnext[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                if(bit[ques[l][1]][ques[l][2]]==0){
                    status=1;
                    bit[ques[l][1]][ques[l][2]]=1;
                }
                ans[l]=ans[x]+status;;
                dfs(l);
                if(status)
                    bit[ques[l][1]][ques[l][2]]=0;
                break;
            case 2:
                if(bit[ques[l][1]][ques[l][2]]){
                    bit[ques[l][1]][ques[l][2]]=0;
                    status=1;
                }
                ans[l]=ans[x]-status;
                dfs(l);
                if(status)
                    bit[ques[l][1]][ques[l][2]]=1;
                break;
            case 3:
                temp=bit[ques[l][1]];
                ans[l]=ans[x]-bit[ques[l][1]].count();
                oper3(ques[l][1]);
                ans[l]=ans[l]+bit[ques[l][q]].count();
                dfs(l);
                bit[ques[l][1]]=temp;
                break;
            case 4:
                ans[l]=ans[x];
                dfs(l);
        }
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i][0]==4){
            nnext[ques[i][1]].push_back(i);
        }
        else{
            nnext[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
int ques[maxn][3],ans[maxn];
vector<int> next[maxn];
int n,m,q;

void oper1(int i,int j){
    bit[i].set(j);
}

void oper2(int i,int j){
    bit[i].reset(j);
}

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

int counting(){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=bit[i].count();
    }
    return sum;
}

void dfs(int x){
    for(int i=0;i<next[x].size();i++){
        int l=next[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                oper1(ques[l][1],ques[l][2]);
                ans[l]=counting();
                break;
            case 2:
                oper2(ques[l][1],ques[l][2]);
                ans[l]=counting();
                break;
            case 3:
                oper3(ques[l][1]);
                ans[l]=counting();
                break;
            case 4:
                ans[l]=ans[ques[l][1]];
        }
        dfs(l);
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i-1][0]==4){
            next[ques[i-1][1]].push_back(i);
        }
        else{
            next[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
bitset<1001> temp;
int ques[maxn][3],ans[maxn];
vector<int> next[maxn];
int n,m,q;

void oper1(int i,int j){
    bit[i].set(j);
}

void oper2(int i,int j){
    bit[i].reset(j);
}

void oper3(int i){
    for(int j=1;j<=m;j++)
        bit[i].flip(j);
}

int counting(){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=bit[i].count();
    }
    return sum;
}

void dfs(int x){
    for(int i=0;i<next[x].size();i++){
        int status=0;
        int l=next[x][i];
        int p=ques[l][0];
        switch (p){
            case 1:
                if(bit[ques[l][1]][ques[l][2]]==0)
                    status=1;
                oper1(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper2(ques[l][1],ques[l][2]);
                break;
            case 2:
                if(bit[ques[l][1]][ques[l][2]]==1)
                    status=1;
                oper2(ques[l][1],ques[l][2]);
                ans[l]=counting();
                dfs(l);
                if(status)
                    oper1(ques[l][1],ques[l][2]);
                break;
            case 3:
                temp=bit[ques[l][1]];
                oper3(ques[l][1]);
                ans[l]=counting();
                dfs(l);
                bit[ques[l][1]]=temp;
                break;
            case 4:
                ans[l]=ans[x];
                dfs(l);
        }
    }
}

int main(){

    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
        }
        if(ques[i][0]==4){
            next[ques[i][1]].push_back(i);
        }
        else{
            next[i-1].push_back(i);
        }
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
int ques[100000][4];
struct storage{
    bitset<1001> bit[1001];
};

map<int,storage> s;

storage p;

void oper1(int i,int j){
    p.bit[i].set(j);
}

void oper2(int i,int j){
    p.bit[i].reset(j);
}

void oper3(int i,int m){
    for(int j=1;j<=m;j++)
        p.bit[i].flip(j);
}

int counting(int n){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=p.bit[i].count();
    }
    return sum;
}

int main(){
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);

    for(int i=0;i<q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
            if(ques[i][0]==4)
                ques[ques[i][1]][3]=i;
        }
    }
    for(int i=0;i<q;i++){
        if(ques[i][3]!=0){
            s[ques[i][3]]=p;
        }
        switch (ques[i][0]){
            case 1:
                oper1(ques[i][1],ques[i][2]);
                break;
            case 2:
                oper2(ques[i][1],ques[i][2]);
                break;
            case 3:
                oper3(ques[i][1],m);
                break;
            case 4:
                p=s[i];
        }
        printf("%d\n",counting(n));
    }

    return 0;
}


#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<bitset>
#include<algorithm>
#define LL long long
#define inf 1000000001
#define maxn 100001
using namespace std;

bitset<1001> bit[1001];
int ques[100000][4];
struct storage{
    bitset<1001> bit[1001];
}s[100001];

storage p;

void oper1(int i,int j){
    p.bit[i].set(j);
}

void oper2(int i,int j){
    p.bit[i].reset(j);
}

void oper3(int i,int m){
    for(int j=1;j<=m;j++)
        p.bit[i].flip(j);
}

int counting(int n){
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=p.bit[i].count();
    }
    return sum;
}

int main(){
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);

    for(int i=0;i<q;i++){
        scanf("%d",&ques[i][0]);
        if(ques[i][0]==1||ques[i][0]==2){
            scanf("%d%d",&ques[i][1],&ques[i][2]);
        }
        else{
            scanf("%d",&ques[i][1]);
            if(ques[i][0]==4)
                ques[ques[i][1]][3]=i;
        }
    }
    for(int i=0;i<q;i++){
        if(ques[i][3]!=0){
            s[ques[i][3]]=p;
        }
        switch (ques[i][0]){
            case 1:
                oper1(ques[i][1],ques[i][2]);
                break;
            case 2:
                oper2(ques[i][1],ques[i][2]);
                break;
            case 3:
                oper3(ques[i][1],m);
                break;
            case 4:
                p=s[i];
        }
        printf("%d\n",counting(n));
    }

    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6 + 500;
const int maxm = 1e3 + 50;
int tot = 0;
int a1[maxn], d1[maxn], d2[maxn];
int n, m, p;
int cur[maxm][maxm];
vector <int> edge[maxn];
void dfs(int x, int sum) {
	if (x == 0) {
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
	if (a1[x] == 1) {
		if (cur[d1[x]][d2[x]] == 0) {
			cur[d1[x]][d2[x]] = 1;
			cout <<sum + 1<< endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum + 1);
			}
			cur[d1[x]][d2[x]] = 0;
		}
	}
	if (a1[x] == 2) {
		if (cur[d1[x]][d2[x]] == 1) {
			cur[d1[x]][d2[x]] = 0;
			cout <<sum - 1<< endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum - 1);
			}
			cur[d1[x]][d2[x]] = 1;
		}
	}
	if (a1[x] == 3) {
		int tcur = 0;
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
				tcur++;
			} else {
				cur[d1[x]][i] = 0;
				tcur--;
			}
		}
		cout << sum + tcur<< endl;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum + tcur);
		}
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
			} else {
				cur[d1[x]][i] = 0;
			}
		}
	}
	if (a1[x] == 4) {
		cout << sum;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(tq, sum);
		}
	}
}
int main () {
	ios_base :: sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m >> p;
	for (int i = 1; i <= p; i++) {
		cin >> a1[i];
		if (a1[i] == 1 || a1[i] == 2) {
			cin >> d1[i] >> d2[i];
			edge[i-1].push_back(i);
		} else if (a1[i] == 3) {
			cin >> d1[i];
			edge[i-1].push_back(i);
		} else {
			cin >> d1[i];
			edge[d1[i]].push_back(i);
		}
	}
	//for (int i = 1; i <= p; i++) cout << a1[i] << ' ' << d1[i] << ' ' << d2[i] << endl;
	dfs(0, 0);
	// for (int i = 0; i <= p; i++) {
		// for (int j = 0; j < edge[i].size(); j++) {
			// cout << edge[i][j] << "  ";
		// }
		// cout << endl;
	// }
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6 + 500;
const int maxm = 1e3 + 50;
int tot = 0;
int a1[maxn], d1[maxn], d2[maxn];
int n, m, p;
int cur[maxm][maxm];
vector <int> edge[maxn];
void dfs(int x, int sum) {
	if (x == 0) {
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
	if (a1[x] == 1) {
		if (cur[d1[x]][d2[x]] == 0) {
			cur[d1[x]][d2[x]] = 1;
			cout <<sum + 1<< endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum + 1);
			}
			cur[d1[x]][d2[x]] = 0;
		} else {
			cout << sum << endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum);
			}
		}
	}
	if (a1[x] == 2) {
		if (cur[d1[x]][d2[x]] == 1) {
			cur[d1[x]][d2[x]] = 0;
			cout <<sum - 1<< endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum - 1);
			}
			cur[d1[x]][d2[x]] = 1;
		} else {
			cout << sum << endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum);
			}
		}
	}
	if (a1[x] == 3) {
		int tcur = 0;
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
				tcur++;
			} else {
				cur[d1[x]][i] = 0;
				tcur--;
			}
		}
		cout << sum + tcur<< endl;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum + tcur);
		}
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
			} else {
				cur[d1[x]][i] = 0;
			}
		}
	}
	if (a1[x] == 4) {
		cout << sum << endl;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
}
int main () {
	ios_base :: sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m >> p;
	for (int i = 1; i <= p; i++) {
		cin >> a1[i];
		if (a1[i] == 1 || a1[i] == 2) {
			cin >> d1[i] >> d2[i];
			edge[i-1].push_back(i);
		} else if (a1[i] == 3) {
			cin >> d1[i];
			edge[i-1].push_back(i);
		} else {
			cin >> d1[i];
			edge[d1[i]].push_back(i);
		}
	}
	//for (int i = 1; i <= p; i++) cout << a1[i] << ' ' << d1[i] << ' ' << d2[i] << endl;
	dfs(0, 0);
	// for (int i = 0; i <= p; i++) {
		// for (int j = 0; j < edge[i].size(); j++) {
			// cout << edge[i][j] << "  ";
		// }
		// cout << endl;
	// }
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6 + 500;
const int maxm = 1e3 + 50;
int tot = 0;
int a1[maxn], d1[maxn], d2[maxn];
int n, m, p;
int cur[maxm][maxm];
int ans[maxn];
vector <int> edge[maxn];
void dfs(int x, int sum) {
	if (x == 0) {
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
	if (a1[x] == 1) {
		if (cur[d1[x]][d2[x]] == 0) {
			cur[d1[x]][d2[x]] = 1;
			ans[x] = sum + 1;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum + 1);
			}
			cur[d1[x]][d2[x]] = 0;
		} else {
			ans[x] = sum;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum);
			}
		}
	}
	if (a1[x] == 2) {
		if (cur[d1[x]][d2[x]] == 1) {
			cur[d1[x]][d2[x]] = 0;
			ans[x] = sum - 1;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum - 1);
			}
			cur[d1[x]][d2[x]] = 1;
		} else {
			ans[x] = sum;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum);
			}
		}
	}
	if (a1[x] == 3) {
		int tcur = 0;
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
				tcur++;
			} else {
				cur[d1[x]][i] = 0;
				tcur--;
			}
		}
		ans[x] = sum + tcur ;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum + tcur);
		}
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
			} else {
				cur[d1[x]][i] = 0;
			}
		}
	}
	if (a1[x] == 4) {
		ans[x] = sum ;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
}
int main () {
	ios_base :: sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m >> p;
	for (int i = 1; i <= p; i++) {
		cin >> a1[i];
		if (a1[i] == 1 || a1[i] == 2) {
			cin >> d1[i] >> d2[i];
			edge[i-1].push_back(i);
		} else if (a1[i] == 3) {
			cin >> d1[i];
			edge[i-1].push_back(i);
		} else {
			cin >> d1[i];
			edge[d1[i]].push_back(i);
		}
	}
	//for (int i = 1; i <= p; i++) cout << a1[i] << ' ' << d1[i] << ' ' << d2[i] << endl;
	dfs(0, 0);
	for (int i = 1; i <= p; i++) cout << ans[i] << endl;
	// for (int i = 0; i <= p; i++) {
		// for (int j = 0; j < edge[i].size(); j++) {
			// cout << edge[i][j] << "  ";
		// }
		// cout << endl;
	// }
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6 + 500;
const int maxm = 1e3 + 50;
int tot = 0;
int a1[maxn], d1[maxn], d2[maxn];
int n, m, p;
int cur[maxm][maxm];
vector <int> edge[maxn];
void dfs(int x, int sum) {
	if (x == 0) {
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
	if (a1[x] == 1) {
		if (cur[d1[x]][d2[x]] == 0) {
			cur[d1[x]][d2[x]] = 1;
			cout <<sum + 1<< endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum + 1);
			}
			cur[d1[x]][d2[x]] = 0;
		} else {
			cout << sum << endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum);
			}
		}
	}
	if (a1[x] == 2) {
		if (cur[d1[x]][d2[x]] == 1) {
			cur[d1[x]][d2[x]] = 0;
			cout <<sum - 1<< endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum - 1);
			}
			cur[d1[x]][d2[x]] = 1;
		} else {
			cout << sum << endl;
			for (int tq = 0; tq < edge[x].size(); tq++) {
				dfs(edge[x][tq], sum);
			}
		}
	}
	if (a1[x] == 3) {
		int tcur = 0;
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
				tcur++;
			} else {
				cur[d1[x]][i] = 0;
				tcur--;
			}
		}
		cout << sum + tcur<< endl;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum + tcur);
		}
		for (int i = 1; i <= m; i++) {
			if (cur[d1[x]][i] == 0) {
				cur[d1[x]][i] = 1;
			} else {
				cur[d1[x]][i] = 0;
			}
		}
	}
	if (a1[x] == 4) {
		cout << sum;
		for (int tq = 0; tq < edge[x].size(); tq++) {
			dfs(edge[x][tq], sum);
		}
	}
}
int main () {
	ios_base :: sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m >> p;
	for (int i = 1; i <= p; i++) {
		cin >> a1[i];
		if (a1[i] == 1 || a1[i] == 2) {
			cin >> d1[i] >> d2[i];
			edge[i-1].push_back(i);
		} else if (a1[i] == 3) {
			cin >> d1[i];
			edge[i-1].push_back(i);
		} else {
			cin >> d1[i];
			edge[d1[i]].push_back(i);
		}
	}
	//for (int i = 1; i <= p; i++) cout << a1[i] << ' ' << d1[i] << ' ' << d2[i] << endl;
	dfs(0, 0);
	// for (int i = 0; i <= p; i++) {
		// for (int j = 0; j < edge[i].size(); j++) {
			// cout << edge[i][j] << "  ";
		// }
		// cout << endl;
	// }
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;
bool shelf[MAX_N][MAX_M];

void execute(bool shelf[MAX_N][MAX_M], int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        //shelf[op1[i]].flip();
        //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        //size += set_bits * 2 - m;
        for (int j = 0; j < m; j++) {
          size += (shelf[op1[i]][j]) ? -1 : 1;
          shelf[op1[i]][j] = !shelf[op1[i]][j];
        }
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

struct S {
  bool s[MAX_N][MAX_M];
  bool inverse[MAX_N];
  int set_bits[MAX_N];
};

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;
S shelf;

void execute(S shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    /*for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        cout << shelf.s[i][j] << ' ';
      }
      cout << endl;
    }*/
    if (i) {
      if (op_type[i] == 1) {
        if (!(shelf.s[op1[i]][op2[i]]^(shelf.inverse[op1[i]] && 1))) {
          shelf.s[op1[i]][op2[i]] = 1^(shelf.inverse[op1[i]] && 1);
          shelf.set_bits[op1[i]]++;
          size++;
        }
      } else if (op_type[i] == 2) {
        //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
        if (shelf.s[op1[i]][op2[i]]^(shelf.inverse[op1[i]] && 1)) {
          shelf.s[op1[i]][op2[i]] = 0^(shelf.inverse[op1[i]] && 1);
          shelf.set_bits[op1[i]]--;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        //shelf[op1[i]].flip();
        //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        //size += set_bits * 2 - m;
        shelf.inverse[op1[i]] = !shelf.inverse[op1[i]];
        size -= shelf.set_bits[op1[i]];
        shelf.set_bits[op1[i]] = m - shelf.set_bits[op1[i]];
        size += shelf.set_bits[op1[i]];
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(vector< vector<bool> > shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        shelf[op1[i]].flip();
        int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        size += set_bits * 2 - m;
      } else {
        if (start != i) {
          return;
        }
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      execute(shelf, reset_map[i][j], size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(vector< vector<bool> > shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        shelf[op1[i]].flip();
        int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        size += set_bits * 2 - m;
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1],
    set_bits[MAX_N];
map< int, vector<int> > reset_map;
bool inverse[MAX_N];
bool shelf[MAX_N][MAX_M];

void execute(int i, int size) {
  /*
  cout << "in execute: " << i << ' ' << size << endl;
  for (int k = 0; k < n; k++) {
    for (int j = 0; j < m; j++) {
      cout << shelf[k][j] << ' ';
    }
    cout << endl;
  }*/
  bool changed_bit = false;
  if (op_type[i] == 1) {
    if (!(shelf[op1[i]][op2[i]]^(inverse[op1[i]] && 1))) {
      shelf[op1[i]][op2[i]] = 1^(inverse[op1[i]] && 1);
      set_bits[op1[i]]++;
      size++;
      changed_bit = true;
    }
  } else if (op_type[i] == 2) {
    //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
    if (shelf[op1[i]][op2[i]]^(inverse[op1[i]] && 1)) {
      shelf[op1[i]][op2[i]] = 0^(inverse[op1[i]] && 1);
      set_bits[op1[i]]--;
      size--;
      changed_bit = true;
    }
  } else if (op_type[i] == 3) {
    //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
    //cout << "set_bits2: " << set_bits2 << endl;
    //cout << "size: " << shelf[op1[i]].size() << endl;
    //shelf[op1[i]].flip();
    //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
    //cout << "set_bits: " << set_bits << endl;
    //size += set_bits * 2 - m;
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
  answers[i] = size;
  for (int j = 0; j < reset_map[i].size(); j++) {
    //cout << "in recurse loop: " << j << ' ' << size << endl;
    execute(reset_map[i][j], size);
    //cout << "came back" << endl;
  }
  if (op_type[i] == 1 && changed_bit) {
    shelf[op1[i]][op2[i]] = 0^(inverse[op1[i]] && 1);
    set_bits[op1[i]]--;
    size--;
  } else if (op_type[i] == 2 && changed_bit) {
    shelf[op1[i]][op2[i]] = 1^(inverse[op1[i]] && 1);
    set_bits[op1[i]]++;
    size++;
  } else if (op_type[i] == 3) {
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    } else {
      reset_map[i - 1].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(vector< vector<bool> > shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        shelf[op1[i]].flip();
        int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        size += set_bits * 2 - m;
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      execute(shelf, reset_map[i][j], size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

struct S { bool s[MAX_N][MAX_M]; };

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;
S shelf;

void execute(S shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    /*for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        cout << shelf.s[i][j] << ' ';
      }
      cout << endl;
    }*/
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf.s[op1[i]][op2[i]]) {
          shelf.s[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
        if (shelf.s[op1[i]][op2[i]]) {
          shelf.s[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        //shelf[op1[i]].flip();
        //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        //size += set_bits * 2 - m;
        for (int j = 0; j < m; j++) {
          size += (shelf.s[op1[i]][j]) ? -1 : 1;
          shelf.s[op1[i]][j] = !shelf.s[op1[i]][j];
        }
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

struct S {
  bool s[MAX_N][MAX_M];
  bool inverse[MAX_N];
  int set_bits[MAX_N];
};

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;
S shelf;

void execute(S shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    /*for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        cout << shelf.s[i][j] << ' ';
      }
      cout << endl;
    }*/
    if (i) {
      if (op_type[i] == 1) {
        if (!(shelf.s[op1[i]][op2[i]]^(shelf.inverse[op1[i]] && 1))) {
          shelf.s[op1[i]][op2[i]] = 1^(shelf.inverse[op1[i]] && 1);
          shelf.set_bits[op1[i]]++;
          size++;
        }
      } else if (op_type[i] == 2) {
        //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
        if (shelf.s[op1[i]][op2[i]]^(shelf.inverse[op1[i]] && 1)) {
          shelf.s[op1[i]][op2[i]] = 0^(shelf.inverse[op1[i]] && 1);
          shelf.set_bits[op1[i]]--;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        //shelf[op1[i]].flip();
        //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        //size += set_bits * 2 - m;
        shelf.inverse[op1[i]] = !shelf.inverse[op1[i]];
        size -= shelf.set_bits[op1[i]];
        shelf.set_bits[op1[i]] = m - shelf.set_bits[op1[i]];
        size += shelf.set_bits[op1[i]];
      } else if (start != i) {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      execute(shelf, reset_map[i][j], size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(vector< vector<bool> > shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        shelf[op1[i]].flip();
        int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        size += set_bits * 2 - m;
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (reset_index) {
        reset_index = reset_reference[reset_index];
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  for (int i = 1; i < q + 1; i++) {
    //cout << reset_reference[i] << ' ';
  }
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1],
    set_bits[MAX_N];
map< int, vector<int> > reset_map;
bool inverse[MAX_N];
bool shelf[MAX_N][MAX_M];

void execute(int i, int size) {
  bool changed_bit = false;
  if (op_type[i] == 1) {
    if (!(shelf[op1[i]][op2[i]]^inverse[op1[i]])) {
      shelf[op1[i]][op2[i]] = 1^inverse[op1[i]];
      set_bits[op1[i]]++;
      size++;
      changed_bit = true;
    }
  } else if (op_type[i] == 2) {
    if (shelf[op1[i]][op2[i]]^inverse[op1[i]]) {
      shelf[op1[i]][op2[i]] = 0^inverse[op1[i]];
      set_bits[op1[i]]--;
      size--;
      changed_bit = true;
    }
  } else if (op_type[i] == 3) {
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
  answers[i] = size;
  for (int j = 0; j < reset_map[i].size(); j++) {
    execute(reset_map[i][j], size);
  }
  if (op_type[i] == 1 && changed_bit) {
    shelf[op1[i]][op2[i]] = 0^inverse[op1[i]];
    set_bits[op1[i]]--;
    size--;
  } else if (op_type[i] == 2 && changed_bit) {
    shelf[op1[i]][op2[i]] = 1^inverse[op1[i]];
    set_bits[op1[i]]++;
    size++;
  } else if (op_type[i] == 3) {
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    } else {
      reset_map[i - 1].push_back(i);
    }
  }
  execute(0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1],
    set_bits[MAX_N];
map< int, vector<int> > reset_map;
bool inverse[MAX_N];
bool shelf[MAX_N][MAX_M];

void execute(int i, int size) {
  /*
  cout << "in execute: " << i << ' ' << size << endl;
  for (int k = 0; k < n; k++) {
    for (int j = 0; j < m; j++) {
      cout << shelf[k][j] << ' ';
    }
    cout << endl;
  }*/
  bool changed_bit = false;
  if (op_type[i] == 1) {
    if (!(shelf[op1[i]][op2[i]]^(inverse[op1[i]] && 1))) {
      shelf[op1[i]][op2[i]] = 1^(inverse[op1[i]] && 1);
      set_bits[op1[i]]++;
      size++;
      changed_bit = true;
    }
  } else if (op_type[i] == 2) {
    //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
    if (shelf[op1[i]][op2[i]]^(inverse[op1[i]] && 1)) {
      shelf[op1[i]][op2[i]] = 0^(inverse[op1[i]] && 1);
      set_bits[op1[i]]--;
      size--;
      changed_bit = true;
    }
  } else if (op_type[i] == 3) {
    //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
    //cout << "set_bits2: " << set_bits2 << endl;
    //cout << "size: " << shelf[op1[i]].size() << endl;
    //shelf[op1[i]].flip();
    //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
    //cout << "set_bits: " << set_bits << endl;
    //size += set_bits * 2 - m;
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
  answers[i] = size;
  for (int j = 0; j < reset_map[i].size(); j++) {
    //cout << "in recurse loop: " << j << ' ' << size << endl;
    execute(reset_map[i][j], size);
    //cout << "came back" << endl;
  }
  if (op_type[i] == 1 && changed_bit) {
    shelf[op1[i]][op2[i]] = 0^(inverse[op1[i]] && 1);
    set_bits[op1[i]]--;
    size--;
  } else if (op_type[i] == 2 && changed_bit) {
    shelf[op1[i]][op2[i]] = 1^(inverse[op1[i]] && 1);
    set_bits[op1[i]]++;
    size++;
  } else if (op_type[i] == 3) {
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    } else {
      reset_map[i - 1].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

struct S {
  bool s[MAX_N][MAX_M];
  bool inverse[MAX_N];
  int set_bits[MAX_N];
};

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;
S shelf;

void execute(S shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    /*for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        cout << shelf.s[i][j] << ' ';
      }
      cout << endl;
    }*/
    if (i) {
      if (op_type[i] == 1) {
        if (!(shelf.s[op1[i]][op2[i]]^(shelf.inverse[op1[i]] && 1))) {
          shelf.s[op1[i]][op2[i]] = 1^(shelf.inverse[op1[i]] && 1);
          shelf.set_bits[op1[i]]++;
          size++;
        }
      } else if (op_type[i] == 2) {
        //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
        if (shelf.s[op1[i]][op2[i]]^(shelf.inverse[op1[i]] && 1)) {
          shelf.s[op1[i]][op2[i]] = 0^(shelf.inverse[op1[i]] && 1);
          shelf.set_bits[op1[i]]--;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        //shelf[op1[i]].flip();
        //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        //size += set_bits * 2 - m;
        shelf.inverse[op1[i]] = !shelf.inverse[op1[i]];
        size -= shelf.set_bits[op1[i]];
        shelf.set_bits[op1[i]] = m - shelf.set_bits[op1[i]];
        size += shelf.set_bits[op1[i]];
      } else if (start != i) {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      execute(shelf, reset_map[i][j], size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(bool shelf[MAX_N][MAX_M], int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        //shelf[op1[i]].flip();
        //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        //size += set_bits * 2 - m;
        for (int j = 0; j < m; j++) {
          size += shelf[op1[i]][j] ? -1 : 1;
          shelf[op1[i]][j] = !shelf[op1[i]][j];
        }
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  bool shelf[MAX_N][MAX_M];
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1],
    set_bits[MAX_N];
map< int, vector<int> > reset_map;
bool inverse[MAX_N];
bool shelf[MAX_N][MAX_M];

void execute(int i, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  //cout << "in main execute loop: " << i << ' ' << size << endl;
  /*for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cout << shelf.s[i][j] << ' ';
    }
    cout << endl;
  }*/
  bool changed_bit = false;
  if (op_type[i] == 1) {
    if (!(shelf[op1[i]][op2[i]]^(inverse[op1[i]] && 1))) {
      shelf[op1[i]][op2[i]] = 1^(inverse[op1[i]] && 1);
      set_bits[op1[i]]++;
      size++;
      changed_bit = true;
    }
  } else if (op_type[i] == 2) {
    //cout << "in op_type 2: " << shelf.s[op1[i]][op2[i]] << endl;
    if (shelf[op1[i]][op2[i]]^(inverse[op1[i]] && 1)) {
      shelf[op1[i]][op2[i]] = 0^(inverse[op1[i]] && 1);
      set_bits[op1[i]]--;
      size--;
      changed_bit = true;
    }
  } else if (op_type[i] == 3) {
    //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
    //cout << "set_bits2: " << set_bits2 << endl;
    //cout << "size: " << shelf[op1[i]].size() << endl;
    //shelf[op1[i]].flip();
    //int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
    //cout << "set_bits: " << set_bits << endl;
    //size += set_bits * 2 - m;
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
  answers[i] = size;
  for (int j = 0; j < reset_map[i].size(); j++) {
    //cout << "in recurse loop: " << j << ' ' << size << endl;
    answers[reset_map[i][j] - 1] = size;
    execute(reset_map[i][j], size);
    //cout << "came back" << endl;
  }
  if (op_type[i] == 1 && changed_bit) {
    shelf[op1[i]][op2[i]] = 0^(inverse[op1[i]] && 1);
    set_bits[op1[i]]--;
    size--;
  } else if (op_type[i] == 2 && changed_bit) {
    shelf[op1[i]][op2[i]] = 1^(inverse[op1[i]] && 1);
    set_bits[op1[i]]++;
    size++;
  } else if (op_type[i] == 3) {
    inverse[op1[i]] = !inverse[op1[i]];
    size -= set_bits[op1[i]];
    set_bits[op1[i]] = m - set_bits[op1[i]];
    size += set_bits[op1[i]];
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i + 1);
    } else {
      reset_map[i - 1].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  //vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;
  //for (int i = 0; i < n; i++) {
  //  fill_n(shelf[i], m, false);
  //}
  execute(0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    reset_reference[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(vector< vector<bool> > shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        //int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        shelf[op1[i]].flip();
        int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        size += set_bits * 2 - m;
      } else {
        break;
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      answers[reset_map[i][j]] = size;
      execute(shelf, reset_map[i][j] + 1, size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  fill_n(reset_reference, q + 1, -1);
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_reference[i] = op1[i];
      int reset_index = i;
      while (true) {
        if (reset_reference[reset_index] != -1) {
          reset_index = reset_reference[reset_index];
        } else {
          break;
        }
      }
      reset_map[reset_index].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>

using namespace std;

const int MAX_Q = 100000,
          MAX_M = 1000,
          MAX_N = 1000;

int n, m, q;
int op_type[MAX_Q + 1],
    op1[MAX_Q + 1],
    op2[MAX_Q + 1],
    answers[MAX_Q + 1];
map< int, vector<int> > reset_map;

void execute(vector< vector<bool> > shelf, int start, int size) {
  //cout << "in execute: " << start << ' ' << size << endl;
  for (int i = start; i < q + 1; i++) {
    //cout << "in main execute loop: " << i << ' ' << size << endl;
    if (i) {
      if (op_type[i] == 1) {
        if (!shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 1;
          size++;
        }
      } else if (op_type[i] == 2) {
        if (shelf[op1[i]][op2[i]]) {
          shelf[op1[i]][op2[i]] = 0;
          size--;
        }
      } else if (op_type[i] == 3) {
        int set_bits2 = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits2: " << set_bits2 << endl;
        //cout << "size: " << shelf[op1[i]].size() << endl;
        shelf[op1[i]].flip();
        int set_bits = accumulate(shelf[op1[i]].begin(), shelf[op1[i]].end(), 0);
        //cout << "set_bits: " << set_bits << endl;
        size += set_bits * 2 - m;
      } else {
        if (start != i) {
          return;
        }
      }
      answers[i] = size;
    }
    for (int j = 0; j < reset_map[i].size(); j++) {
      //cout << "in recurse loop: " << j << ' ' << size << endl;
      execute(shelf, reset_map[i][j], size);
      //cout << "came back" << endl;
    }
  }
}

int main() {
  cin >> n >> m >> q;
  for (int i = 1; i < q + 1; i++) {
    scanf("%d", op_type + i);
    scanf("%d", op1 + i);
    op1[i]--;
    if (op_type[i] == 1 || op_type[i] == 2) {
      scanf("%d", op2 + i);
      op2[i]--;
    }
    if (op_type[i] == 4) {
      op1[i]++;
      reset_map[op1[i]].push_back(i);
    }
    //cout << "done with reading " << i << endl;
  }
  vector< vector<bool> > shelf(n, vector<bool>(m, false));
  //cout << "size: " << shelf[2].size() << endl;

  //cout << "reset_reference: ";
  //for (int i = 1; i < q + 1; i++) {
  //  cout << reset_reference[i] << ' ';
  //}
  //cout << endl;

  execute(shelf, 0, 0);
  for (int i = 1; i < q + 1; i++) {
    printf("%d\n", answers[i]);
  }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define inf 10000000000000
# define mx 300010
struct node{
	int  u,a,b,ans;
}qu[mx];
 vector<int>vv[1005];
 vector<int>g[100005];
ll ans[mx];
int n,m,q;
void go(int pos,ll cnt)
{
		int len,i,u,v,ty;
		bool f1,f2,f3;
		f1=f2=f3=0;
	ty = qu[pos].u;
	//cout<<pos<<" "<<ty<<" "<<qu[pos].b<<endl;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(vv[u][v]==0)
	    	{
	    		f1 = 1;
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	//cout<<pos<< " "<<u<<" "<<v<<" "<<vv[u][v]<<" "<<cnt<<endl;
	    	if(vv[u][v]==1)
	    	{
	    	  f2 = 1;
	    		cnt--;
	    		vv[u][v] = 0;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		//cout<<pos<<" "<<u<<endl;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;
			}
			else
			{
				cnt++;
				vv[u][i] = 1;
				//cout<<"ok "<<pos<<" "<<u<<" "<<i<<" "<<vv[u][i]<<endl;
			}
		}
	}
    else
    {

	}
	//cout<<pos<<" "<<cnt<<endl;
	ans[pos] = cnt;
	len = g[pos].size();
	for(i=0;i<len;i++)
	{
		u = g[pos][i];
		go(u,cnt);
	}

	ty = qu[pos].u;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;

	    	if(f1)
	    	{
	    		cnt--;
	    		vv[u][v] = 0;
			}

	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(f2)
	    	{
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;

			}
			else
			{
				cnt++;
				vv[u][i] = 1;
			}
		}
	}
    else
    {

	}
}
int main()
{

    int i,u,a,v,j,b;
    cin>>n>>m>>q;

    for(i=0;i<n+2;i++)
    for(j=0;j<m+2;j++)
    vv[i].push_back(0);

    for(i=1;i<=q;i++)
    {
       scanf("%d",&u);
       if(i==1)
       {
       	   if(u==4 or u==3)
       	   {
       	     scanf("%d",&b);
			qu[i].u = u;
			qu[i].b = b;
			//cout<<"lll "<<u<<" "<<qu[i].b<<endl;
		   }
		   else
		   {
		   	scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   }
		   continue;
	   }

	   if(u==4 or u==3)
	   {
	      scanf("%d",&b);
	      qu[i].u = u;
	      qu[i].b = b;
	      if(u==4){

		  g[b].push_back(i);

		  }
	   	  else
	   	  g[i-1].push_back(i);
	   }
	   else
	   {
	       scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   g[i-1].push_back(i);
	   }
	}
	g[0].push_back(1);
	go(0,0);
    for(i=1;i<=q;i++)
    {
    	cout<<ans[i]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define inf 10000000000000
# define mx 300010
struct node{
	int  u,a,b,ans;
}qu[mx];
 vector<int>vv[305],tmp[305];
 vector<int>g[100005];
ll ans[305];
int n,m,q;
void go(int pos,ll cnt)
{
		int len,i,u,v,ty;
		bool f1,f2,f3;
		f1=f2=f3=0;
	ty = qu[pos].u;
	//cout<<pos<<" "<<ty<<" "<<qu[pos].b<<endl;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(vv[u][v]==0)
	    	{
	    		f1 = 1;
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	//cout<<pos<< " "<<u<<" "<<v<<" "<<vv[u][v]<<" "<<cnt<<endl;
	    	if(vv[u][v]==1)
	    	{
	    	  f2 = 1;
	    		cnt--;
	    		vv[u][v] = 0;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		//cout<<pos<<" "<<u<<endl;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;
			}
			else
			{
				cnt++;
				vv[u][i] = 1;
				//cout<<"ok "<<pos<<" "<<u<<" "<<i<<" "<<vv[u][i]<<endl;
			}
		}
	}
    else
    {

	}
	//cout<<pos<<" "<<cnt<<endl;
	ans[pos] = cnt;
	len = g[pos].size();
	for(i=0;i<len;i++)
	{
		u = g[pos][i];
		go(u,cnt);
	}

	ty = qu[pos].u;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;

	    	if(f1)
	    	{
	    		cnt--;
	    		vv[u][v] = 0;
			}

	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(f2)
	    	{
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==3)
	{
		u =qu[i].b;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;

			}
			else
			{
				cnt++;
				vv[u][i] = 1;
			}
		}
	}
    else
    {

	}
}
int main()
{

    int i,u,a,v,j,b;
    cin>>n>>m>>q;

    for(i=0;i<n+2;i++)
    for(j=0;j<m+2;j++)
    vv[i].push_back(0);

    for(i=1;i<=q;i++)
    {
       scanf("%d",&u);
       if(i==1)
       {
       	   if(u==4 or u==3)
       	   {
       	     scanf("%d",&b);
			qu[i].u = u;
			qu[i].b = b;
			//cout<<"lll "<<u<<" "<<qu[i].b<<endl;
		   }
		   else
		   {
		   	scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   }
		   continue;
	   }

	   if(u==4 or u==3)
	   {
	      scanf("%d",&b);
	      qu[i].u = u;
	      qu[i].b = b;
	      if(u==4)
	      g[b].push_back(i);
	   	  else
	   	  g[i-1].push_back(i);
	   }
	   else
	   {
	       scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   g[i-1].push_back(i);
	   }
	}
	go(1,0);
    for(i=1;i<=q;i++)
    {
    	cout<<ans[i]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define inf 10000000000000
# define mx 300010
struct node{
	int  u,a,b,ans;
}qu[mx];
 vector<int>vv[1005],tmp[1005];
 vector<int>g[100005];
ll ans[305];
int n,m,q;
void go(int pos,ll cnt)
{
		int len,i,u,v,ty;
		bool f1,f2,f3;
		f1=f2=f3=0;
	ty = qu[pos].u;
	//cout<<pos<<" "<<ty<<" "<<qu[pos].b<<endl;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(vv[u][v]==0)
	    	{
	    		f1 = 1;
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	//cout<<pos<< " "<<u<<" "<<v<<" "<<vv[u][v]<<" "<<cnt<<endl;
	    	if(vv[u][v]==1)
	    	{
	    	  f2 = 1;
	    		cnt--;
	    		vv[u][v] = 0;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		//cout<<pos<<" "<<u<<endl;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;
			}
			else
			{
				cnt++;
				vv[u][i] = 1;
				//cout<<"ok "<<pos<<" "<<u<<" "<<i<<" "<<vv[u][i]<<endl;
			}
		}
	}
    else
    {

	}
	//cout<<pos<<" "<<cnt<<endl;
	ans[pos] = cnt;
	len = g[pos].size();
	for(i=0;i<len;i++)
	{
		u = g[pos][i];
		go(u,cnt);
	}

	ty = qu[pos].u;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;

	    	if(f1)
	    	{
	    		cnt--;
	    		vv[u][v] = 0;
			}

	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(f2)
	    	{
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;

			}
			else
			{
				cnt++;
				vv[u][i] = 1;
			}
		}
	}
    else
    {

	}
}
int main()
{

    int i,u,a,v,j,b;
    cin>>n>>m>>q;

    for(i=0;i<n+2;i++)
    for(j=0;j<m+2;j++)
    vv[i].push_back(0);

    for(i=1;i<=q;i++)
    {
       scanf("%d",&u);
       if(i==1)
       {
       	   if(u==4 or u==3)
       	   {
       	     scanf("%d",&b);
			qu[i].u = u;
			qu[i].b = b;
			//cout<<"lll "<<u<<" "<<qu[i].b<<endl;
		   }
		   else
		   {
		   	scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   }
		   continue;
	   }

	   if(u==4 or u==3)
	   {
	      scanf("%d",&b);
	      qu[i].u = u;
	      qu[i].b = b;
	      if(u==4){

		  g[b].push_back(i);

		  }
	   	  else
	   	  g[i-1].push_back(i);
	   }
	   else
	   {
	       scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   g[i-1].push_back(i);
	   }
	}
	g[0].push_back(1);
	go(0,0);
    for(i=1;i<=q;i++)
    {
    	cout<<ans[i]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define inf 10000000000000
# define mx 300010
struct node{
	int  u,a,b,ans;
}qu[mx];
 vector<int>vv[305],tmp[305];
 vector<int>g[100005];
ll ans[305];
int n,m,q;
void go(int pos,ll cnt)
{
		int len,i,u,v,ty;
		bool f1,f2,f3;
		f1=f2=f3=0;
	ty = qu[pos].u;
	//cout<<pos<<" "<<ty<<" "<<qu[pos].b<<endl;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(vv[u][v]==0)
	    	{
	    		f1 = 1;
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	//cout<<pos<< " "<<u<<" "<<v<<" "<<vv[u][v]<<" "<<cnt<<endl;
	    	if(vv[u][v]==1)
	    	{
	    	  f2 = 1;
	    		cnt--;
	    		vv[u][v] = 0;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		//cout<<pos<<" "<<u<<endl;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;
			}
			else
			{
				cnt++;
				vv[u][i] = 1;
				//cout<<"ok "<<pos<<" "<<u<<" "<<i<<" "<<vv[u][i]<<endl;
			}
		}
	}
    else
    {

	}
	//cout<<pos<<" "<<cnt<<endl;
	ans[pos] = cnt;
	len = g[pos].size();
	for(i=0;i<len;i++)
	{
		u = g[pos][i];
		go(u,cnt);
	}

	ty = qu[pos].u;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;

	    	if(f1)
	    	{
	    		cnt--;
	    		vv[u][v] = 0;
			}

	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(f2)
	    	{
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;

			}
			else
			{
				cnt++;
				vv[u][i] = 1;
			}
		}
	}
    else
    {

	}
}
int main()
{

    int i,u,a,v,j,b;
    cin>>n>>m>>q;

    for(i=0;i<n+2;i++)
    for(j=0;j<m+2;j++)
    vv[i].push_back(0);

    for(i=1;i<=q;i++)
    {
       scanf("%d",&u);
       if(i==1)
       {
       	   if(u==4 or u==3)
       	   {
       	     scanf("%d",&b);
			qu[i].u = u;
			qu[i].b = b;
			//cout<<"lll "<<u<<" "<<qu[i].b<<endl;
		   }
		   else
		   {
		   	scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   }
		   continue;
	   }

	   if(u==4 or u==3)
	   {
	      scanf("%d",&b);
	      qu[i].u = u;
	      qu[i].b = b;
	      if(u==4)
	      g[b+1].push_back(i);
	   	  else
	   	  g[i-1].push_back(i);
	   }
	   else
	   {
	       scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   g[i-1].push_back(i);
	   }
	}
	go(1,0);
    for(i=1;i<=q;i++)
    {
    	cout<<ans[i]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define inf 10000000000000
# define mx 300010
struct node{
	int  u,a,b,ans;
}qu[mx];
 vector<int>vv[305],tmp[305];
 vector<int>g[100005];
ll ans[305];
int n,m,q;
void go(int pos,ll cnt)
{
		int len,i,u,v,ty;
		bool f1,f2,f3;
		f1=f2=f3=0;
	ty = qu[pos].u;
	//cout<<pos<<" "<<ty<<" "<<qu[pos].b<<endl;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(vv[u][v]==0)
	    	{
	    		f1 = 1;
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	//cout<<pos<< " "<<u<<" "<<v<<" "<<vv[u][v]<<" "<<cnt<<endl;
	    	if(vv[u][v]==1)
	    	{
	    	  f2 = 1;
	    		cnt--;
	    		vv[u][v] = 0;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		//cout<<pos<<" "<<u<<endl;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;
			}
			else
			{
				cnt++;
				vv[u][i] = 1;
				//cout<<"ok "<<pos<<" "<<u<<" "<<i<<" "<<vv[u][i]<<endl;
			}
		}
	}
    else
    {

	}
	//cout<<pos<<" "<<cnt<<endl;
	ans[pos] = cnt;
	len = g[pos].size();
	for(i=0;i<len;i++)
	{
		u = g[pos][i];
		go(u,cnt);
	}

	ty = qu[pos].u;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;

	    	if(f1)
	    	{
	    		cnt--;
	    		vv[u][v] = 0;
			}

	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(f2)
	    	{
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;

			}
			else
			{
				cnt++;
				vv[u][i] = 1;
			}
		}
	}
    else
    {

	}
}
int main()
{

    int i,u,a,v,j,b;
    cin>>n>>m>>q;

    for(i=0;i<n+2;i++)
    for(j=0;j<m+2;j++)
    vv[i].push_back(0);

    for(i=1;i<=q;i++)
    {
       scanf("%d",&u);
       if(i==1)
       {
       	   if(u==4 or u==3)
       	   {
       	     scanf("%d",&b);
			qu[i].u = u;
			qu[i].b = b;
			//cout<<"lll "<<u<<" "<<qu[i].b<<endl;
		   }
		   else
		   {
		   	scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   }
		   continue;
	   }

	   if(u==4 or u==3)
	   {
	      scanf("%d",&b);
	      qu[i].u = u;
	      qu[i].b = b;
	      if(u==4)
	      g[b].push_back(i);
	   	  else
	   	  g[i-1].push_back(i);
	   }
	   else
	   {
	       scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   g[i-1].push_back(i);
	   }
	}
	go(1,0);
    for(i=1;i<=q;i++)
    {
    	cout<<ans[i]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define inf 10000000000000
# define mx 300010
struct node{
	int  u,a,b,ans;
}qu[mx];
 vector<int>vv[305],tmp[305];
 vector<int>g[100005];
ll ans[305];
int n,m,q;
void go(int pos,ll cnt)
{
		int len,i,u,v,ty;
		bool f1,f2,f3;
		f1=f2=f3=0;
	ty = qu[pos].u;
	//cout<<pos<<" "<<ty<<" "<<qu[pos].b<<endl;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(vv[u][v]==0)
	    	{
	    		f1 = 1;
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	//cout<<pos<< " "<<u<<" "<<v<<" "<<vv[u][v]<<" "<<cnt<<endl;
	    	if(vv[u][v]==1)
	    	{
	    	  f2 = 1;
	    		cnt--;
	    		vv[u][v] = 0;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		//cout<<pos<<" "<<u<<endl;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;
			}
			else
			{
				cnt++;
				vv[u][i] = 1;
				//cout<<"ok "<<pos<<" "<<u<<" "<<i<<" "<<vv[u][i]<<endl;
			}
		}
	}
    else
    {

	}
	//cout<<pos<<" "<<cnt<<endl;
	ans[pos] = cnt;
	len = g[pos].size();
	for(i=0;i<len;i++)
	{
		u = g[pos][i];
		go(u,cnt);
	}

	ty = qu[pos].u;
	if(ty==1)
	{
	    	u = qu[pos].a;
	    	v = qu[pos].b;

	    	if(f1)
	    	{
	    		cnt--;
	    		vv[u][v] = 0;
			}

	}
	else if(ty==2)
	{
		u = qu[pos].a;
	    	v = qu[pos].b;
	    	if(f2)
	    	{
	    		cnt++;
	    		vv[u][v] = 1;
			}
	}
	else if(ty==3)
	{
		u =qu[pos].b;
		for(i=1;i<=m;i++)
		{
			if(vv[u][i]==1)
			{
				cnt--;
				vv[u][i] = 0;

			}
			else
			{
				cnt++;
				vv[u][i] = 1;
			}
		}
	}
    else
    {

	}
}
int main()
{

    int i,u,a,v,j,b;
    cin>>n>>m>>q;

    for(i=0;i<n+2;i++)
    for(j=0;j<m+2;j++)
    vv[i].push_back(0);

    for(i=1;i<=q;i++)
    {
       scanf("%d",&u);
       if(i==1)
       {
       	   if(u==4 or u==3)
       	   {
       	     scanf("%d",&b);
			qu[i].u = u;
			qu[i].b = b;
			//cout<<"lll "<<u<<" "<<qu[i].b<<endl;
		   }
		   else
		   {
		   	scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   }
		   continue;
	   }

	   if(u==4 or u==3)
	   {
	      scanf("%d",&b);
	      qu[i].u = u;
	      qu[i].b = b;
	      if(u==4){

		  g[b].push_back(i);

		  }
	   	  else
	   	  g[i-1].push_back(i);
	   }
	   else
	   {
	       scanf("%d %d",&a,&b);
	       qu[i].u = u;
		   qu[i].a = a;
		   qu[i].b = b;
		   g[i-1].push_back(i);
	   }
	}
	g[0].push_back(1);
	go(0,0);
    for(i=1;i<=q;i++)
    {
    	cout<<ans[i]<<endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int n,m,q;
vector<int> E[maxn];
int op[maxn],a[maxn],b[maxn],c[maxn];
int ans[maxn];
bitset<1001>Bit[1001];
bitset<1001>C;
void dfs(int x)
{
    if(x==0)
    {
        for(int i=0;i<E[x].size();i++)
        {
            ans[E[x][i]]=ans[x];
            dfs(E[x][i]);
        }
    }
    if(op[x]==1)
    {
        int flag = 0;
        if(!Bit[a[x]][b[x]])
        {
            flag = 1;
            ans[x]++;
            Bit[a[x]][b[x]]=1;
        }
        for(int i=0;i<E[x].size();i++)
        {
            ans[E[x][i]]=ans[x];
            dfs(E[x][i]);
        }
        if(flag)
            Bit[a[x]][b[x]]=0;
    }
    if(op[x]==2)
    {
        int flag = 0;
        if(Bit[a[x]][b[x]])
        {
            flag = 1;
            ans[x]--;
            Bit[a[x]][b[x]]=0;
        }
        for(int i=0;i<E[x].size();i++)
        {
            ans[E[x][i]]=ans[x];
            dfs(E[x][i]);
        }
        if(flag)
            Bit[a[x]][b[x]]=1;
    }
    if(op[x]==3)
    {
        ans[x]=ans[x]-Bit[a[x]].count();
        Bit[a[x]]^=C;
        ans[x]=ans[x]+Bit[a[x]].count();
        for(int i=0;i<E[x].size();i++)
        {
            ans[E[x][i]]=ans[x];
            dfs(E[x][i]);
        }
        Bit[a[x]]^=C;
    }
    if(op[x]==4)
    {
        for(int i=0;i<E[x].size();i++)
        {
            ans[E[x][i]]=ans[x];
            dfs(E[x][i]);
        }
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=m;i++)
        C[i]=1;
    for(int i=1;i<=q;i++)
    {
        scanf("%d",&op[i]);
        if(op[i]==1)
            scanf("%d%d",&a[i],&b[i]);
        if(op[i]==2)
            scanf("%d%d",&a[i],&b[i]);
        if(op[i]==3)
            scanf("%d",&a[i]);
        if(op[i]==4)
            scanf("%d",&a[i]),
            E[a[i]].push_back(i);
        else
            E[i-1].push_back(i);
    }
    dfs(0);
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+3;
const int maxn=1e5+3;
int n,m,q;
vector<int> G[N];
bitset<N> bit[N];
bitset<N> opp;
int ope[maxn],a[maxn],b[maxn],ans[maxn];
void dfs(int x)
{
    if(ope[x]==1)
    {
        if(!bit[a[x]][b[x]])
        {
            bit[a[x]][b[x]]=1;
            ans[x]++;
        }
        for(int i=0;i<G[x].size();i++)
        {
            ans[G[x][i]]=ans[x];
            dfs(G[x][i]);
        }
        bit[a[x]][b[x]]=0;

    }
    else if(ope[x]==2)
    {
        if(bit[a[x]][b[x]])
        {
            bit[a[x]][b[x]]=0;
            ans[x]--;
        }
        for(int i=0;i<G[x].size();i++)
        {
            ans[G[x][i]]=ans[x];
            dfs(G[x][i]);
        }
        bit[a[x]][b[x]]=1;
    }
    else if(ope[x]==3)
    {
        ans[x]+=m-2*bit[a[x]].count();
        bit[a[x]]^=opp;
        for(int i=0;i<G[x].size();i++)
        {
            ans[G[x][i]]=ans[x];
            dfs(G[x][i]);
        }
        bit[a[x]]^=opp;
    }
    else
    {
        for(int i=0;i<G[x].size();i++)
        {
            ans[G[x][i]]=ans[x];
            dfs(G[x][i]);
        }
    }
}
int main()
{
    scanf("%d %d %d",&n,&m,&q);
    for(int i=1;i<=m;i++)
        opp[i]=1;
    for(int i=1;i<=q;i++)
    {
        scanf("%d",&ope[i]);
        if(ope[i]==1)
        {
            scanf("%d %d",a+i,b+i);
            G[i-1].push_back(i);
        }
        else if(ope[i]==2)
        {
            scanf("%d %d",a+i,b+i);
            G[i-1].push_back(i);
        }
        else if(ope[i]==3)
        {
            scanf("%d",a+i);
            G[i-1].push_back(i);
        }
        else
        {
            scanf("%d",a+i);
            G[a[i]].push_back(i);
        }
    }
    for(int i=0;i<G[0].size();i++)
    {
        ans[G[0][i]]=0;
        dfs(G[0][i]);
    }
    for(int i=1;i<=q;i++)
        printf("%d\n",ans[i]);
    return 0;
}