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

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

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

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


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/

pair<int, STATE> que[MAXOPT];
int f , l;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}
	*/
	pair<int, STATE> tmp;

	while(f < l){
		tmp = que[f];
		f++;
		pos = tmp.first, iter = tmp.second;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
			que[l].first = *it, que[l].second = iter;
			l++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
				que[l].first = *it, que[l].second = iter;
				l++;
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	f = l = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que[l].first = 0, que[l].second = iter;
		l++;
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

int state[1005][1005];

int n, m, q;

struct operation{
	int op, r, c;
}op[MAXOPT];
int ans[MAXOPT];
vector<int> nt[MAXOPT];

void dfs(int u){
	int sz = nt[u].size();
	for(int i = 0; i < sz; i++){
		int v = nt[u][i];
		if(op[v].op == 1){
			int pre = state[op[v].r][op[v].c];
			if(!pre){
				state[op[v].r][op[v].c] = 1;
				ans[v] = ans[u] + 1;
			}
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 2){
			int pre = state[op[v].r][op[v].c];
			if(pre){
				state[op[v].r][op[v].c] = 0;
				ans[v] = ans[u] - 1;
			}
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 3){
			int c = 0;
			for(int k = 1; k <=m; k++){
				if(state[op[v].r][k]) c++;
				state[op[v].r][k] ^= 1;
			}
			ans[v] = ans[u] - c + m - c;
			dfs(v);

			for(int k = 1; k <=m; k++){
				state[op[v].r][k] ^= 1;
			}

		}
		else{
			ans[v] = ans[u];
		}
	}
}

int main(){

	scanf("%d%d%d", &n, &m, &q);
	memset(ans, 0, sizeof(ans));
	memset(state, 0, sizeof(state));
	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].op);
		if(op[i].op == 1 || op[i].op == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else{
			scanf("%d", &op[i].r);
		}
		if(op[i].op == 4) nt[op[i].r].push_back(i);
		else nt[i - 1].push_back(i)
	}

	dfs(0);

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

	return 0;
}


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

const int MAXOPT = 100505;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/
/*
struct Q{
	int first;
	STATE second;
}que[MAXOPT];
int front, last;

*/
/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

/*
void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}

//	pair<int, STATE> tmp;

	while(front < last){
	//	tmp = que[f];
		pos = que[front].first, iter = que[front].second;
		front++;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
			que[last].first = *it, que[last].second = iter;
		//	que[last] = make_pair(*it, iter);
			last++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
			//	que[last] = make_pair(*it, iter);
				que[last].first = *it, que[last].second = iter;
				last++;
			}
		}
	}

}
*/

struct Q{
	int first;
	STATE second;
}stack[MAXOPT];
int last;

void dfs(int pos, STATE iter, int sh){
	while(last > 0){
		pos = stack[last - 1].first, iter = stack[last - 1].second;
		last --;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			stack[last].first = nt[pos][k], stack[last].second = iter;
			last++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			int sz = nt[pos].size();
			for(int k = 0; k < sz; k++){
				ans[nt[pos][k]] += iter.counts;
				stack[last].first = nt[pos][k], stack[last].second = iter;
				last++;
			}
		}
	}
}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	last = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		stack[last].first = 0, stack[last].second = iter;
		last++;
		dfs(0, iter, i);
	}

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/

pair<int, STATE> que[MAXOPT];
int f , l;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}
	*/
//	pair<int, STATE> tmp;

	while(f < l){
	//	tmp = que[f];
		pos = que[f].first, iter = que[f].second;
		f++;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
			que[l].first = *it, que[l].second = iter;
			l++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
				que[l].first = *it, que[l].second = iter;
				l++;
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	f = l = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que[l].first = 0, que[l].second = iter;
		l++;
		dfs(0, iter, i);
	}

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct STATE{
	bitset<1000> st;
	void init(){
		st.reset();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st[op[pos].c - 1]){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st[op[pos].c - 1]){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}

	/*	if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}*/
	}

}

int main(){

	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	/*
	for(int i = 1; i <= q; i++){
		printf("%d ", nt[i].size());
	}
	puts("");

	*/
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
	/*	int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}
		*/
		dfs(0, iter, i);
	/*	for(int i = 1; i <= q; i++){
			printf("%d  ", ans[i]);
		}

		puts("");
		*/
	}

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

	return 0;
}

/*

7 2 18
2 5 2
1 3 1
2 7 1
3 4
4 0
1 6 1
4 0
4 4
1 6 2
4 7
3 5
2 2 2
2 6 1
4 7
1 7 2
2 4 2
3 4
1 1 1

*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		dfs(0, iter, i);
	}

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

	return 0;
}


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

const int MAXOPT = 100505;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/
/*
struct Q{
	int first;
	STATE second;
}que[MAXOPT];
int front, last;

*/
/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

/*
void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}

//	pair<int, STATE> tmp;

	while(front < last){
	//	tmp = que[f];
		pos = que[front].first, iter = que[front].second;
		front++;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
			que[last].first = *it, que[last].second = iter;
		//	que[last] = make_pair(*it, iter);
			last++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
			//	que[last] = make_pair(*it, iter);
				que[last].first = *it, que[last].second = iter;
				last++;
			}
		}
	}

}
*/

struct Q{
	int first;
	STATE second;
}stack[MAXOPT];
int last;

void dfs(int pos, STATE iter, int sh){
	while(last){
		pos = stack[last - 1].first, iter = stack[last - 1].second;
		last --;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
		//	dfs(nt[pos][k], iter, sh);
			stack[last].first = nt[pos][k], stack[last].second = iter;
			last++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			int sz = nt[pos].size();
			for(int k = 0; k < sz; k++){
				ans[nt[pos][k]] += iter.counts;
				stack[last].first = nt[pos][k], stack[last].second = iter;
				last++;
			}
		}
	}
}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
//	front = last = 0;
	last = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		stack[last].first = 0, stack[last].second = iter;
		last++;
		dfs(0, iter, i);
	}

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/

pair<int, STATE> que[MAXOPT];
int f , l;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}
	*/
//	pair<int, STATE> tmp;

	while(f < l){
	//	tmp = que[f];
		pos = que[f].first, iter = que[f].second;
		f++;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
		//	que[l].first = *it, que[l].second = iter;
			que[l] = make_pair(*it, iter);
			l++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
				que[l] = make_pair(*it, iter);
			//	que[l].first = *it, que[l].second = iter;
				l++;
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	f = l = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que[l].first = 0, que[l].second = iter;
		l++;
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

int state[1005][1005];

int n, m, q;

struct operation{
	int op, r, c;
}op[MAXOPT];
int ans[MAXOPT];
vector<int> nt[MAXOPT];

void dfs(int u){
	int sz = nt[u].size();
	for(int i = 0; i < sz; i++){
		int v = nt[u][i];
		if(op[v].op == 1){
			int pre = state[op[v].r][op[v].c];
			if(!pre){
				state[op[v].r][op[v].c] = 1;
				ans[v] = ans[u] + 1;
			}
			else ans[v] = ans[u];
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 2){
			int pre = state[op[v].r][op[v].c];
			if(pre){
				state[op[v].r][op[v].c] = 0;
				ans[v] = ans[u] - 1;
			}
			else ans[v] = ans[u];
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 3){
			int c = 0;
			for(int k = 1; k <=m; k++){
				if(state[op[v].r][k]) c++;
				state[op[v].r][k] ^= 1;
			}
			ans[v] = ans[u] - c + m - c;
			dfs(v);

			for(int k = 1; k <=m; k++){
				state[op[v].r][k] ^= 1;
			}

		}
		else{
			ans[v] = ans[u];
		}
	}
}

int main(){

	scanf("%d%d%d", &n, &m, &q);
	memset(ans, 0, sizeof(ans));
	memset(state, 0, sizeof(state));
	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].op);
		if(op[i].op == 1 || op[i].op == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else{
			scanf("%d", &op[i].r);
		}
		if(op[i].op == 4) nt[op[i].r].push_back(i);
		else nt[i - 1].push_back(i);
	}

	dfs(0);

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

queue<pair<int, STATE> >que;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}
	*/
	pair<int, STATE> tmp;

	while(!que.empty()){
		tmp = que.front();
		que.pop();
		pos = tmp.first, iter = tmp.second;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			que.push(make_pair(*it, iter));
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
				que.push(make_pair(*it, iter));
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que.push(make_pair(0, iter));
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

int state[1005][1005];

int n, m, q;

struct operation{
	int op, r, c;
}op[MAXOPT];
int ans[MAXOPT];
vector<int> nt[MAXOPT];

void dfs(int u){
	int sz = nt[u].size();
	for(int i = 0; i < sz; i++){
		int v = nt[u][i];
		if(op[v].op == 1){
			int pre = state[op[v].r][op[v].c];
			if(!pre){
				state[op[v].r][op[v].c] = 1;
				ans[v] = ans[u] + 1;
			}
			else ans[v] = ans[u];
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 2){
			int pre = state[op[v].r][op[v].c];
			if(pre){
				state[op[v].r][op[v].c] = 0;
				ans[v] = ans[u] - 1;
			}
			else ans[v] = ans[u];
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 3){
			int c = 0;
			for(int k = 1; k <=m; k++){
				if(state[op[v].r][k]) c++;
				state[op[v].r][k] ^= 1;
			}
			ans[v] = ans[u] - c + m - c;
			dfs(v);

			for(int k = 1; k <=m; k++){
				state[op[v].r][k] ^= 1;
			}

		}
		else{
			ans[v] = ans[u];
		}
	}
}

int main(){

	scanf("%d%d%d", &n, &m, &q);
	memset(ans, 0, sizeof(ans));
	memset(state, 0, sizeof(state));
	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].op);
		if(op[i].op == 1 || op[i].op == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else{
			scanf("%d", &op[i].r);
		}
		if(op[i].op == 4) nt[op[i].r].push_back(i);
		else nt[i - 1].push_back(i)
	}

	dfs(0);

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if((s[p + 1] & (1<<m) )== (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p + 1] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p + 1] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}

	/*	if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}*/
	}

}

int main(){

	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	/*
	for(int i = 1; i <= q; i++){
		printf("%d ", nt[i].size());
	}
	puts("");

	*/
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
	/*	int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}
		*/
		dfs(0, iter, i);
	/*	if(i == 461){
			for(int k = 1; k <= q; k++){
				printf("%d  ", ans[k]);
			}

			puts("");
		}
		*/
	}

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

	return 0;
}

/*

7 2 18
2 5 2
1 3 1
2 7 1
3 4
4 0
1 6 1
4 0
4 4
1 6 2
4 7
3 5
2 2 2
2 6 1
4 7
1 7 2
2 4 2
3 4
1 1 1

1000 1000 36
1 888 252
3 746
2 198 884
3 503
4 1
2 498 718
3 338
3 768
3 312
1 230 712
2 554 102
2 941 545
1 459 921
4 7
4 10
3 964
2 419 626
2 79 137
4 18
1 815 277
2 862 183
1 927 976
4 7
1 4 146
2 461 996
4 19
1 206 920
2 304 909
3 367
1 449 734
1 118 943
1 822 811
1 383 961
2 499 147
1 509 265
1 696 583

*/


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

const int MAXOPT = 100505;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/

struct Q{
	int first;
	STATE second;
}que[MAXOPT];
int front, last;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}
	*/
//	pair<int, STATE> tmp;

	while(front < last){
	//	tmp = que[f];
		pos = que[front].first, iter = que[front].second;
		front++;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
			que[last].first = *it, que[last].second = iter;
		//	que[last] = make_pair(*it, iter);
			last++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
			//	que[last] = make_pair(*it, iter);
				que[last].first = *it, que[last].second = iter;
				last++;
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	front = last = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que[last].first = 0, que[last].second = iter;
		last++;
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		dfs(0, iter, i);
	}

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

queue<pair<int, STATE> >que;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){

	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}

	pair<int, STATE> tmp;

	while(!que.empty()){
		tmp = que.front();
		que.pop();
		pos = tmp.first, iter = tmp.second;
		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
				que.push(make_pair(*it, iter));
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que.push(make_pair(0, iter));
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

int state[1005][1005];

int n, m, q;

struct operation{
	int op, r, c;
}op[MAXOPT];
int ans[MAXOPT];
vector<int> nt[MAXOPT];

void dfs(int u){
	int sz = nt[u].size();
	for(int i = 0; i < sz; i++){
		int v = nt[u][i];
		if(op[v].op == 1){
			int pre = state[op[v].r][op[v].c];
			if(!pre){
				state[op[v].r][op[v].c] = 1;
				ans[v] = ans[u] + 1;
			}
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 2){
			int pre = state[op[v].r][op[v].c];
			if(pre){
				state[op[v].r][op[v].c] = 0;
				ans[v] = ans[u] - 1;
			}
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 3){
			int c = 0;
			for(int k = 1; k <=m; k++){
				if(state[op[v].r][k]) c++;
				state[op[v].r][k] ^= 1;
			}
			ans[v] = ans[u] - c + m - c;
			dfs(v);

			for(int k = 1; k <=m; k++){
				state[op[v].r][k] ^= 1;
			}

		}
		else{
			ans[v] = ans[u];
		}
	}
}

int main(){

	scanf("%d%d%d", &n, &m, &q);
	memset(ans, 0, sizeof(ans));
	memset(state, 0, sizeof(state));
	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].op);
		if(op[i].op == 1 || op[i].op == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else{
			scanf("%d", &op[i].r);
		}
		if(op[i].op == 4) nt[op[i].r].push_back(i);
		else nt[i - 1].push_back(i);
	}

	dfs(0);

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct STATE{
	bitset<1000> st;
	void init(){
		st.reset();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st[op[pos].c -1]){
					iter.counts++;
					iter.st.set(op[pos].c -1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st[op[pos].c -1]){
					iter.counts --;
					iter.st.reset(op[pos].c -1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
	/*	int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}
		*/
		if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}
	}

}

int main(){

	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}

	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
	/*	int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}
		*/
		dfs(0, iter, i);
	}

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

int state[1005][1005];

int n, m, q;

struct operation{
	int op, r, c;
}op[MAXOPT];
int ans[MAXOPT];
vector<int> nt[MAXOPT];

void dfs(int u){
	int sz = nt[u].size();
	for(int i = 0; i < sz; i++){
		int v = nt[u][i];
		if(op[v].op == 1){
			int pre = state[op[v].r][op[v].c];
			if(!pre){
				state[op[v].r][op[v].c] = 1;
				ans[v] = ans[u] + 1;
			}
			else ans[v] = ans[u];
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 2){
			int pre = state[op[v].r][op[v].c];
			if(pre){
				state[op[v].r][op[v].c] = 0;
				ans[v] = ans[u] - 1;
			}
			else ans[v] = ans[u];
			dfs(v);
			state[op[v].r][op[v].c] = pre;
		}
		else if(op[v].op == 3){
			int c = 0;
			for(int k = 1; k <=m; k++){
				if(state[op[v].r][k]) c++;
				state[op[v].r][k] ^= 1;
			}
			ans[v] = ans[u] - c + m - c;
			dfs(v);

			for(int k = 1; k <=m; k++){
				state[op[v].r][k] ^= 1;
			}

		}
		else{
			ans[v] = ans[u];
			dfs(v);
		}
	}
}

int main(){

	scanf("%d%d%d", &n, &m, &q);
	memset(ans, 0, sizeof(ans));
	memset(state, 0, sizeof(state));
	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].op);
		if(op[i].op == 1 || op[i].op == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else{
			scanf("%d", &op[i].r);
		}
		if(op[i].op == 4) nt[op[i].r].push_back(i);
		else nt[i - 1].push_back(i);
	}

	dfs(0);

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

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std;

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if((s[p + 1] & (1<<m) )== (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p + 1] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p + 1] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					if(iter.counts > 0)
						iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}

	/*	if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}*/
	}

}

int main(){
//	initial();
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	/*
	for(int i = 1; i <= q; i++){
		printf("%d ", nt[i].size());
	}
	puts("");

	*/
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
	/*	int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}
		*/
		dfs(0, iter, i);
	/*	if(i == 461){
			for(int k = 1; k <= q; k++){
				printf("%d  ", ans[k]);
			}

			puts("");
		}
		*/
	}

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

	return 0;
}

/*

7 2 18
2 5 2
1 3 1
2 7 1
3 4
4 0
1 6 1
4 0
4 4
1 6 2
4 7
3 5
2 2 2
2 6 1
4 7
1 7 2
2 4 2
3 4
1 1 1

1000 1000 36
1 888 252
3 746
2 198 884
3 503
4 1
2 498 718
3 338
3 768
3 312
1 230 712
2 554 102
2 941 545
1 459 921
4 7
4 10
3 964
2 419 626
2 79 137
4 18
1 815 277
2 862 183
1 927 976
4 7
1 4 146
2 461 996
4 19
1 206 920
2 304 909
3 367
1 449 734
1 118 943
1 822 811
1 383 961
2 499 147
1 509 265
1 696 583

*/


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[m] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[m] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[m] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}

	/*	if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}*/
	}

}

int main(){

	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	/*
	for(int i = 1; i <= q; i++){
		printf("%d ", nt[i].size());
	}
	puts("");

	*/
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
	/*	int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}
		*/
		dfs(0, iter, i);
	/*	for(int i = 1; i <= q; i++){
			printf("%d  ", ans[i]);
		}

		puts("");
		*/
	}

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

	return 0;
}

/*

7 2 18
2 5 2
1 3 1
2 7 1
3 4
4 0
1 6 1
4 0
4 4
1 6 2
4 7
3 5
2 2 2
2 6 1
4 7
1 7 2
2 4 2
3 4
1 1 1

*/


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

const int MAXOPT = 100505;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;
/*
queue<pair<int, STATE> >que;
*/

pair<int, STATE> que[MAXOPT];
int f, l;

/*
void dfs(int pos, STATE iter, int sh){
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		dfs(*it, iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			dfs(*it, iter, sh);
		}
	}

}
*/

void dfs(int pos, STATE iter, int sh){
/*
	vector<int>::iterator it = nt[pos].begin();
	for(; it != nt[pos].end(); it++){
		ans[*it] += iter.counts;
		que.push(make_pair(*it, iter));
	}
	*/
//	pair<int, STATE> tmp;

	while(f < l){
	//	tmp = que[f];
		pos = que[f].first, iter = que[f].second;
		f++;

		vector<int>::iterator it = nt[pos].begin();
		for(; it != nt[pos].end(); it++){
			ans[*it] += iter.counts;
			//que.push(make_pair(*it, iter));
		//	que[l].first = *it, que[l].second = iter;
			que[l] = make_pair(*it, iter);
			l++;
		}

		while(op[pos + 1].opt != 4 && pos < q){
			pos ++;
			if(op[pos].r == sh){
				if(op[pos].opt == 1){
					if(!iter.st.find(op[pos].c - 1)){
						iter.counts++;
						iter.st.set(op[pos].c - 1);
					}
				}
				else if(op[pos].opt == 2){
					if(iter.st.find(op[pos].c - 1)){
						iter.counts --;
						iter.st.reset(op[pos].c - 1);
					}
				}
				else {
					iter.st.flip();
					iter.counts = m - iter.counts;
				}
			}
			ans[pos] += iter.counts;
			vector<int>::iterator it = nt[pos].begin();
			for(; it != nt[pos].end(); it++){
				ans[*it] += iter.counts;
			//	que.push(make_pair(*it, iter));
				que[l] = make_pair(*it, iter);
			//	que[l].first = *it, que[l].second = iter;
				l++;
			}
		}
	}

}

int main(){
	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= q; i++)
		nt[i].clear();

	for(int i = 1; i <= q; i++){
		scanf("%d", &op[i].opt);
		if(op[i].opt == 1 || op[i].opt == 2){
			scanf("%d%d", &op[i].r, &op[i].c);
		}
		else {
			scanf("%d", &op[i].r);
		}
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	f = l = 0;
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		que[l].first = 0, que[l].second = iter;
		l++;
		dfs(0, iter, i);
	}

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct STATE{
	bitset<1000> st;
	void init(){
		st.reset();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
/*	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}
	*/
	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st[op[pos].c]){
					iter.counts++;
					iter.st.set(op[pos].c);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st[op[pos].c]){
					iter.counts --;
					iter.st.reset(op[pos].c);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}

	/*	if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}*/
	}

}

int main(){

	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	/*
	for(int i = 1; i <= q; i++){
		printf("%d ", nt[i].size());
	}
	puts("");

	*/
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
		int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}

		dfs(0, iter, i);
	/*	for(int i = 1; i <= q; i++){
			printf("%d  ", ans[i]);
		}

		puts("");*/
	}

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

	return 0;
}


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

const int MAXOPT = 100005;

struct OPT{
	int opt, r, c;
}op[MAXOPT];

struct bits{
	char s[125];
	void init(){
		for(int i = 0; i < 125; i++) s[i] = 0;
	}
	bool find(int k){
		int p = k / 8;
		int m = k % 8;
		if(s[p + 1] & (1<<m)) return true;
		return false;
	}

	void set(int k){
		int p = k / 8;
		int m = k % 8;
		s[p + 1] |= (1<<m);
	}

	void reset(int k){
		int p = k / 8;
		int m = k % 8;
		s[p + 1] ^= (1<<m);
	}

	void flip(){
		for(int i = 0; i < 125; i++){
			s[i] ^= (-1);
		}
	}
};

struct STATE{
	bits st;
	void init(){
		st.init();
		counts = 0;
	}
	int counts;
};

vector<int>nt[MAXOPT];

int ans[MAXOPT];
int n, m, q;

void dfs(int pos, STATE iter, int sh){
	int sz = nt[pos].size();
	for(int k = 0; k < sz; k++){
		ans[nt[pos][k]] += iter.counts;
		dfs(nt[pos][k], iter, sh);
	}

	while(op[pos + 1].opt != 4 && pos < q){
		pos ++;
		if(op[pos].r == sh){
			if(op[pos].opt == 1){
				if(!iter.st.find(op[pos].c - 1)){
					iter.counts++;
					iter.st.set(op[pos].c - 1);
				}
			}
			else if(op[pos].opt == 2){
				if(iter.st.find(op[pos].c - 1)){
					iter.counts --;
					iter.st.reset(op[pos].c - 1);
				}
			}
			else {
				iter.st.flip();
				iter.counts = m - iter.counts;
			}
		}
		ans[pos] += iter.counts;
		int sz = nt[pos].size();
		for(int k = 0; k < sz; k++){
			ans[nt[pos][k]] += iter.counts;
			dfs(nt[pos][k], iter, sh);
		}

	/*	if(nt[pos].size() > 0){
			dfs(pos, iter, sh);
		}*/
	}

}

int main(){

	int opt, r, c;
	memset(ans, 0, sizeof(ans));
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 1; i <= q; i++){
		nt[i].clear();
		scanf("%d", &opt);
		if(opt == 1 || opt == 2){
			scanf("%d%d", &r, &c);
		}
		else {
			scanf("%d", &r);
		}
		op[i].opt = opt;
		op[i].r = r, op[i].c =c;
		if(op[i].opt == 4){
			nt[op[i].r].push_back(i);
		}
	}
	/*
	for(int i = 1; i <= q; i++){
		printf("%d ", nt[i].size());
	}
	puts("");

	*/
	for(int i = 1; i <= n; i++){
		STATE iter;
		iter.init();
		ans[0] += iter.counts;
	/*	int sz = nt[0].size();
		for(int k = 0; k <sz; k++){
			ans[nt[0][k]]  += iter.counts;
			dfs(nt[0][k], iter, i);
		}
		*/
		dfs(0, iter, i);
	/*	for(int i = 1; i <= q; i++){
			printf("%d  ", ans[i]);
		}

		puts("");
		*/
	}

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

	return 0;
}

/*

7 2 18
2 5 2
1 3 1
2 7 1
3 4
4 0
1 6 1
4 0
4 4
1 6 2
4 7
3 5
2 2 2
2 6 1
4 7
1 7 2
2 4 2
3 4
1 1 1

*/


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];
bool v[100000];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    vector<vector<bool> > s(n,vector<bool> (m));
    vector<vector<vector<bool> > > save;
    int a,b,c;
    vector<int> dbA(q);
    vector<int> dbB(q);
    vector<int> dbC(q);
    int as,bs,cs;
    map<int,int> ver;
    for(int i=0;i<q;i++){
        cin >> a >> b;
        c = 0;
        if(a <= 2)
            cin >> c;
        b--;
        c--;
        if(a == 4 && b != -1)
            v[b] = 1;
        dbA[i] = a;
        dbB[i] = b;
        dbC[i] = c;
    }
    r[0] = 0;
    for(int i=1;i<=q;i++){
        a = dbA[i-1];
        b = dbB[i-1];
        c = dbC[i-1];
        if(a == 1){
            r[i] = r[i-1] + !s[b][c];
            s[b][c] = 1;
        }else if(a == 2){
            r[i] = r[i-1] - s[b][c];
            s[b][c] = 0;
        }else if(a == 3){
            c = 0;
            for(int i=0;i<m;i++){
                s[b][i] = !s[b][i];
                c += 2*s[b][i]-1;
            }
            r[i] = r[i-1]+c;
        }else if(a == 4){
            if(b != -1){
                s = save[ver[b]];
                r[i] = r[b+1];
            }else{
                r[i] = 0;
                for(int i=0;i<n;i++){
                    for(int j=0;j<m;j++){
                        s[i][j] = 0;
                    }
                }
            }
        }
        if(v[i-1]){
            ver[i-1] = save.size();
            save.push_back(s);
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];
bool pol[101001][1000];
int sh[100001];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    int a,b,c;
    int sz = 0;
    for(int i=0;i<n;i++){
        sh[0][i] = sz;
        sz++;
    }
    r[0] = 0;
    int polka;
    for(int i=1;i<=q;i++){
        cin >> a >> b;
        if(a == 1){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 0){
                r[i]++;
                pol.push_back(pol[polka]);
                pol[sz][c] = 1;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 2){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 1){
                r[i]--;
                pol.push_back(pol[polka]);
                pol[sz][c] = 0;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 3){
            b--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            c = 0;
            sh[i] = sh[i-1];
            pol.push_back(pol[0]);
            for(int j=0;j<m;j++){
                pol[sz][j] = !pol[polka][j];
                c += 2*pol[sz][j]-1;
            }
            sh[i][b] = sz;
            r[i] += c;
            sz++;
        }else{
            r[i] = r[b];
            sh[i] = sh[b];
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int sh[100001][1000];
int pol[101000][1000];
int r[100001];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    int a,b,c;
    int sz = 0;
    for(int i=0;i<n;i++){
        sh[0][i] = sz;
        sz++;
    }
    r[0] = 0;
    int polka;
    for(int i=1;i<=q;i++){
        cin >> a >> b;
        if(a == 1){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            for(int j=0;j<n;j++){
                sh[i][j] = sh[i-1][j];
            }
            if(pol[polka][c] == 0){
                r[i]++;
                for(int j=0;j<m;j++){
                    pol[sz][j] = pol[polka][j];
                }
                pol[sz][c] = 1;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 2){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            for(int j=0;j<n;j++){
                sh[i][j] = sh[i-1][j];
            }
            if(pol[polka][c] == 1){
                r[i]--;
                for(int j=0;j<m;j++){
                    pol[sz][j] = pol[polka][j];
                }
                pol[sz][c] = 0;
                for(int j=0;j<n;j++){
                    sh[i][j] = sh[i-1][j];
                }
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 3){
            b--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            c = 0;
            for(int j=0;j<n;j++){
                sh[i][j] = sh[i-1][j];
            }
            for(int j=0;j<m;j++){
                pol[sz][j] = !pol[polka][j];
                c += 2*pol[sz][j]-1;
            }
            sh[i][b] = sz;
            r[i] += c;
            sz++;
        }else{
            r[i] = r[b];
            for(int j=0;j<n;j++){
                sh[i][j] = sh[b][j];
            }
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

bool sw[2000];

int main()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    vector<vector<int> > w(n,vector<int> (m));
    vector<vector<int> > gn(n,vector<int> (m));
    for(int i=0;i<k;i++)
        sw[i] = 1;
    int a,b,c,d;
    for(int i=1;i<=k;i++){
        scanf("%d",&a);
        for(int j=0;j<a;j++){
            scanf("%d%d%d",&b,&c,&d);
            b--;
            c--;
            w[b][c] = d;
            gn[b][c] = i;
        }
    }
    scanf("%d",&a);
    string s;
    int x1,y1,x2,y2;
    long long r;
    while(a--){
        cin >> s;
        if(s == "SWITCH"){
            scanf("%d",&b);
            sw[b-1] = !sw[b-1];
            continue;
        }
        cin >> x1 >> y1 >> x2 >> y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        x1--;
        y1--;
        r = 0;
        for(int i=x1;i<x2;i++){
            for(int j=y1;j<y2;j++){
                if(gn[i][j] && sw[gn[i][j]-1])
                    r += w[i][j];
            }
        }
        cout << r << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    vector<vector<int> > sh(q+1,vector<int> (n));
    vector<vector<bool> > pol(n,vector<bool> (m,0));
    int a,b,c;
    int sz = 0;
    for(int i=0;i<n;i++){
        sh[0][i] = sz;
        sz++;
    }
    r[0] = 0;
    int polka;
    for(int i=1;i<=q;i++){
        cin >> a >> b;
        if(a == 1){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 0){
                r[i]++;
                pol.push_back(pol[polka]);
                pol[sz][c] = 1;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 2){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 1){
                r[i]--;
                pol.push_back(pol[polka]);
                pol[sz][c] = 0;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 3){
            b--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            c = 0;
            sh[i] = sh[i-1];
            pol.push_back(pol[0]);
            for(int j=0;j<m;j++){
                pol[sz][j] = !pol[polka][j];
                c += 2*pol[sz][j]-1;
            }
            sh[i][b] = sz;
            r[i] += c;
            sz++;
        }else{
            r[i] = r[b];
            sh[i] = sh[b];
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    vector<vector<int> > sh(q+1,vector<int> (n));
    vector<vector<int> > pol(n+q+1,vector<int> (m));
    int a,b,c;
    int sz = 0;
    for(int i=0;i<n;i++){
        sh[0][i] = sz;
        sz++;
    }
    r[0] = 0;
    int polka;
    for(int i=1;i<=q;i++){
        cin >> a >> b;
        if(a == 1){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            for(int j=0;j<n;j++){
                sh[i][j] = sh[i-1][j];
            }
            if(pol[polka][c] == 0){
                r[i]++;
                for(int j=0;j<m;j++){
                    pol[sz][j] = pol[polka][j];
                }
                pol[sz][c] = 1;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 2){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            for(int j=0;j<n;j++){
                sh[i][j] = sh[i-1][j];
            }
            if(pol[polka][c] == 1){
                r[i]--;
                for(int j=0;j<m;j++){
                    pol[sz][j] = pol[polka][j];
                }
                pol[sz][c] = 0;
                for(int j=0;j<n;j++){
                    sh[i][j] = sh[i-1][j];
                }
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 3){
            b--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            c = 0;
            for(int j=0;j<n;j++){
                sh[i][j] = sh[i-1][j];
            }
            for(int j=0;j<m;j++){
                pol[sz][j] = !pol[polka][j];
                c += 2*pol[sz][j]-1;
            }
            sh[i][b] = sz;
            r[i] += c;
            sz++;
        }else{
            r[i] = r[b];
            for(int j=0;j<n;j++){
                sh[i][j] = sh[b][j];
            }
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    vector<vector<int> > sh(q+1,vector<int> (n));
    vector<vector<int> > pol(n,vector<int> (m,0));
    int a,b,c;
    int sz = 0;
    for(int i=0;i<n;i++){
        sh[0][i] = sz;
        sz++;
    }
    r[0] = 0;
    int polka;
    for(int i=1;i<=q;i++){
        cin >> a >> b;
        if(a == 1){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 0){
                r[i]++;
                pol.push_back(pol[polka]);
                pol[sz][c] = 1;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 2){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 1){
                r[i]--;
                pol.push_back(pol[polka]);
                pol[sz][c] = 0;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 3){
            b--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            c = 0;
            sh[i] = sh[i-1];
            pol.push_back(pol[0]);
            for(int j=0;j<m;j++){
                pol[sz][j] = !pol[polka][j];
                c += 2*pol[sz][j]-1;
            }
            sh[i][b] = sz;
            r[i] += c;
            sz++;
        }else{
            r[i] = r[b];
            sh[i] = sh[b];
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];
bool v[100000];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    vector<vector<bool> > s(n,vector<bool> (m));
    vector<vector<vector<bool> > > save;
    int a,b,c;
    vector<int> dbA(q);
    vector<int> dbB(q);
    vector<int> dbC(q);
    int as,bs,cs;
    map<int,int> ver;
    for(int i=0;i<q;i++){
        cin >> a >> b;
        c = 0;
        if(a <= 2)
            cin >> c;
        b--;
        c--;
        if(a == 4 && b != -1)
            v[b] = 1;
        dbA[i] = a;
        dbB[i] = b;
        dbC[i] = c;
    }
    r[0] = 0;
    for(int i=1;i<=q;i++){
        a = dbA[i-1];
        b = dbB[i-1];
        c = dbC[i-1];
        if(a == 1){
            r[i] = r[i-1] + !s[b][c];
            s[b][c] = 1;
        }else if(a == 2){
            r[i] = r[i-1] - s[b][c];
            s[b][c] = 0;
        }else if(a == 3){
            c = 0;
            for(int i=0;i<m;i++){
                s[b][i] = !s[b][i];
                c += 2*s[b][i]-1;
            }
            r[i] = r[i-1]+c;
        }else if(a == 4){
            if(b != -1){
                s = save[ver[b]];
                r[i] = r[b];
            }else{
                r[i] = 0;
                for(int i=0;i<n;i++){
                    for(int j=0;j<m;j++){
                        s[i][j] = 0;
                    }
                }
            }
        }
        if(v[i]){
            ver[i] = save.size();
            save.push_back(s);
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

bool sw[2000];

int main()
{
    ios_base::sync_with_stdio(0);
    int n,m,k;
    scanf("%d %d %d",&n,&m,&k);
    vector<vector<int> > w(n,vector<int> (m));
    vector<vector<int> > gn(n,vector<int> (m));
    for(int i=0;i<k;i++)
        sw[i] = 1;
    int a,b,c,d;
    for(int i=1;i<=k;i++){
        cin >> a;
        for(int j=0;j<a;j++){
            scanf("%d %d %d",&b,&c,&d);
            b--;
            c--;
            w[b][c] = d;
            gn[b][c] = i;
        }
    }
    cin >> a;
    string s;
    int x1,y1,x2,y2;
    long long r;
    while(a--){
        cin >> s;
        if(s == "SWITCH"){
            cin >> b;
            sw[b-1] = !sw[b-1];
            continue;
        }
        cin >> x1 >> y1 >> x2 >> y2;
        x1--;
        y1--;
        r = 0;
        for(int i=x1;i<x2;i++){
            for(int j=y1;j<y2;j++){
                if(gn[i][j] && sw[gn[i][j]-1])
                    r += w[i][j];
            }
        }
        cout << r << endl;
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef unsigned short ushort;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;

template <typename T>
void coutVector(vector<T> a){
    for(ull i=0;i<a.size();i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

int r[100001];
bool pol[101001][1000];
int sh[100001][1000];

int main()
{
    int n,m,q;
    cin >> n >> m >> q;
    int a,b,c;
    int sz = 0;
    for(int i=0;i<n;i++){
        sh[0][i] = sz;
        sz++;
    }
    r[0] = 0;
    int polka;
    for(int i=1;i<=q;i++){
        cin >> a >> b;
        if(a == 1){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 0){
                r[i]++;
                pol.push_back(pol[polka]);
                pol[sz][c] = 1;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 2){
            cin >> c;
            b--;
            c--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            sh[i] = sh[i-1];
            if(pol[polka][c] == 1){
                r[i]--;
                pol.push_back(pol[polka]);
                pol[sz][c] = 0;
                sh[i][b] = sz;
                sz++;
            }
        }else if(a == 3){
            b--;
            polka = sh[i-1][b];
            r[i] = r[i-1];
            c = 0;
            sh[i] = sh[i-1];
            pol.push_back(pol[0]);
            for(int j=0;j<m;j++){
                pol[sz][j] = !pol[polka][j];
                c += 2*pol[sz][j]-1;
            }
            sh[i][b] = sz;
            r[i] += c;
            sz++;
        }else{
            r[i] = r[b];
            sh[i] = sh[b];
        }
        cout << r[i] << endl;
    }
    return 0;
}


#include <cstdio>
#include <iostream>
using namespace std;

const int MAXN = 1000;
const int MAXM = 1000;
const int MAXQUERIES = 100000;

int references[MAXQUERIES+1][MAXN];
int delta[MAXQUERIES+1][MAXM];
int delta_sum[MAXQUERIES+1];
int high_bit[MAXQUERIES+1][MAXN];

void copyArray(int* arr1, int* arr2, int N)
{
	for(int i=0;i<N;i++)
		arr1[i] = arr2[i];
}

void copyDeltaArray(int* delta, int* bookshelf, int N, int delta_idx)
{
	for(int i=0;i<N;i++)
		delta[i] = bookshelf[i];
}

void updateDeltaSum(int* delta, int N, int delta_idx)
{
	int sum = 0;
	for(int i=0;i<N;i++)
		sum += delta[i];

	delta_sum[delta_idx] = sum;
}

int main()
{
	int N, M, Q;
	cin>>N>>M>>Q;

	int delta_idx = 1;

	//memset(high_bit[0], 1, sizeof(high_bit[0]));
	for(int i=0;i<MAXN;i++)
		high_bit[0][i] = 1;

	//cout<<high_bit[0][0]<<"asd"<<endl;

	for(int q=1;q<=Q;q++)
	{
		int qn, a;
		cin>>qn;

		copyArray(references[q], references[q-1], N);
		copyArray(high_bit[q], high_bit[q-1], N);

		if(qn == 1)
		{
			int b;
			cin>>a>>b;
			a--;b--;
			if(delta[references[q][a]][b] == !high_bit[q][a])
			{
				copyDeltaArray(delta[delta_idx], delta[references[q][a]], M, delta_idx);
				delta[delta_idx][b] = high_bit[q][a];
				updateDeltaSum(delta[delta_idx], M, delta_idx);
				references[q][a] = delta_idx;
				delta_idx++;
			}
		}
		else if(qn == 2)
		{
			int b;
			cin>>a>>b;
			a--;b--;
			if(delta[references[q][a]][b] == high_bit[q][a])
			{
				copyDeltaArray(delta[delta_idx], delta[references[q][a]], M, delta_idx);
				delta[delta_idx][b] = !high_bit[q][a];
				updateDeltaSum(delta[delta_idx], M, delta_idx);
				references[q][a] = delta_idx;
				delta_idx++;
			}
		}
		else if(qn == 3)
		{
			cin>>a;
			a--;
			high_bit[q][a] = !high_bit[q][a];
		}
		else if(qn == 4)
		{
			cin>>a;
			copyArray(references[q], references[a], N);
			copyArray(high_bit[q], high_bit[a], N);
		}
	}

	/*cout<<"Starts printing the snapshots: "<<endl;
	for(int i=1;i<=Q;i++)
	{
		for(int j=0;j<N;j++)
		{
			for(int k=0;k<M;k++)
				if(high_bit[i][j])
					cout<<delta[references[i][j]][k]<<" ";
				else
					cout<<1-delta[references[i][j]][k]<<" ";
			cout<<"Delta Sum is: "<<delta_sum[references[i][j]]<<endl;
			cout<<endl;
		}
		cout<<endl<<endl;
	}*/

	for(int i=1;i<=Q;i++)
	{
		int sum = 0;
		for(int j=0;j<N;j++)
			if(!high_bit[i][j])
				sum += M-delta_sum[references[i][j]];
			else
				sum += delta_sum[references[i][j]];
		cout<<sum<<endl;
	}
}
/*
Test Case 1:
2 2 2
3 2
2 2 1
Expected Answer:-
2
1

Test Case 2:
4 2 6
3 2
2 2 2
3 3
3 2
2 2 2
3 2
Expected Answer :-
2
1
3
3
2
4

Test Case 3:
2 3 3
1 1 1
3 2
4 0
Expected Answer:-
1
4
0
*/


#include<cstdio>
#include<string>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

int n,reg[26],n_ans;
char ans[255][32];

bool solve(int next){
	if(reg[next-1]>n || next>n_ans) return false; // pruning

	if(reg[next-1]==n){ n_ans=next-1; return true; }

	bool ok=false;
	rep(i,next) rep(j,next) for(int k=1;k<=8;k*=2) {
		reg[next]=reg[i]+k*reg[j];
		if(solve(next+1)){
			sprintf(ans[next-1],"e%cx, [e%cx + %d*e%cx]",next+'a',i+'a',k,j+'a');
			ok=true;
		}
	}

	rep(i,next) for(int k=1;k<=8;k*=2) {
		reg[next]=k*reg[i];
		if(solve(next+1)){
			sprintf(ans[next-1],"e%cx, [%d*e%cx]",next+'a',k,i+'a');
			ok=true;
		}
	}

	return ok;
}

int main(){
	scanf("%d",&n);
	n_ans=6;
	reg[0]=1;

	solve(1);

	printf("%d\n",n_ans);
	rep(i,n_ans) printf("lea %s\n",ans[i]);

	return 0;
}


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

int n;
int ansSize;
char op[30][30];
char ans[30][30];

void calc(int depth, vector<int> &seq);
void NextState(int depth, vector<int> &seq, int left, int right, int k) {
  char next = 'a' + depth + 1;
  char l = 'a' + left - 1;
  char r = 'a' + right - 1;
  if (left == 0) {
    sprintf(op[depth], "lea e%cx, [%d*e%cx]\n", next, k, r);
  } else if (k == 1) {
    sprintf(op[depth], "lea e%cx, [e%cx + e%cx]\n", next, l, r);
  } else {
    sprintf(op[depth], "lea e%cx, [e%cx + %d*e%cx]\n", next, l, k, r);
  }
  seq.push_back(seq[left] + seq[right] * k);
  calc(depth + 1, seq);
  seq.pop_back();
}

void calc(int depth, vector<int> &seq) {
  if (depth >= ansSize) { return; }
  if (seq.back() == n) {
    ansSize = depth;
    memcpy(ans, op, sizeof(ans));
    return;
  }
  if (depth >= ansSize - 1) { return; }
  FOR(i, 1, seq.size()) {
    NextState(depth, seq, 0, i, 2);
    NextState(depth, seq, 0, i, 4);
    NextState(depth, seq, 0, i, 8);
    FOR(j, 1, seq.size()) {
      NextState(depth, seq, j, i, 1);
      NextState(depth, seq, j, i, 2);
      NextState(depth, seq, j, i, 4);
      NextState(depth, seq, j, i, 8);
    }
  }
}

int main() {
  while (cin >> n) {
    if (n == 0) {
      puts("0");
    }
    MEMSET(op, 0);
    ansSize = 5;
    if (n == 254) { ansSize = 6; }
    vector<int> seq(2);
    seq[0] = 0;
    seq[1] = 1;
    calc(0, seq);
    printf("%d\n", ansSize);
    REP(i, ansSize) {
      cout << ans[i];
    }
  }
}


//program 93C

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>

using namespace std;

struct op
{
  int X,Y,Z;
};

const int inf=1000000000;

int Ans;
vector<int> List;
stack<op> Stack,Best;

void Out(int X)
{
  putchar('e');putchar(X+97);putchar('x');
}

void DFS(int Depth,int Max,int N)
{
  if(Depth>Ans)return;
  if(Max==N){Ans=Depth-1;Best=Stack;return;}
  vector<int> TList=List;
  for(int i=0;i<4;i++)
    for(int j=0;j<List.size();j++)
      {
        int T=List[j]<<i;
        if(T>Max&&T<=N)
          {
            List.push_back(T);Stack.push((op){1<<i,j,-1});
            DFS(Depth+1,T,N);
            List=TList;Stack.pop();
          }
      }
  for(int i=0;i<4;i++)
    for(int j=0;j<List.size();j++)
      for(int k=0;k<List.size();k++)
        {
          int T=(List[j]<<i)+List[k];
          if(T>Max&&T<=N)
            {
              List.push_back(T);Stack.push((op){1<<i,j,k});
              DFS(Depth+1,T,N);
              List=TList;Stack.pop();
            }
        }
}

int main()
{
  int N;cin>>N;
  List.push_back(1);
  Ans=6;DFS(1,1,N);
  cout<<Ans<<endl;
  int T=Ans;op A[100];while(T--){A[T]=Best.top();Best.pop();}
  for(int i=0;i<Ans;i++)
    {
      cout<<"lea ";Out(i+1);cout<<", [";
      if(A[i].Z!=-1){Out(A[i].Z);cout<<" + ";}
      cout<<A[i].X<<'*';Out(A[i].Y);cout<<"]"<<endl;
    }
  return 0;
}


#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define For(i,x,y) for (i=x;i<=y;i++)
using namespace std;
const int b[4]={1,2,4,8};
struct ww {
	int a,b,c,d;
} a[100];
int i,j,k,n,m,an;
inline void print() {
	printf("%d\n",an-1);
	int i;
	For(i,2,an) {
		printf("lea e%cx, [",i+'a'-1);
		if (a[i].b) printf("e%cx + ",a[i].b+'a'-1);
		if (a[i].d) printf("%d*",b[a[i].d]);
		printf("e%cx]\n",a[i].c+'a'-1);
	}
	exit(0);
}
void dfs(int x) {
	if (x==an) {
		if (a[x].a==n) print();
		return;
	}
	int i,j,k;
	For(i,0,x)For(j,1,x)For(k,0,3) {
		int A=a[i].a+b[k]*a[j].a;
		if (A<=a[x].a||A>n) continue;
		a[x+1]=(ww){A,i,j,k};
		dfs(x+1);
	}
}
int main() {
	scanf("%d",&n);
	for (an=1;;an++) {
		a[1].a=1;
		dfs(1);
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())

typedef long long ll;

typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef pair<int, int> pii;

int ans, n;
vi cur;
char ops[1024][1024];

bool search(int cop) {
  if (cur[sz(cur) - 1] == n) return true;
  if (cop >= ans) return false;

  for (int a = -1; a < sz(cur); a++) {
    for (int b = 0; b < sz(cur); b++) {
      for (int k = 1; k <= 8; k *= 2) {
        int nv = (a >= 0 ? cur[a] : 0) + cur[b] * k;
        if (nv > n) continue;
        cur.pb(nv);
        if (search(cop + 1)) {
          if (a < 0)
            snprintf(ops[cop], sizeof ops[cop], "lea e%cx, [%d*e%cx]", 'a' + cop + 1, k, 'a' + b);
          else
            snprintf(ops[cop], sizeof ops[cop], "lea e%cx, [e%cx + %d*e%cx]", 'a' + cop + 1, 'a' + a, k, 'a' + b);
          return true;
        }
        cur.resize(sz(cur) - 1);
      }
    }
  }
  return false;
}

int main() {
  #ifdef DEBUG
  freopen("std.in", "r", stdin);
  freopen("std.out", "w", stdout);
  #endif

  while (scanf("%d", &n) >= 1) {
    eprintf("%d\n", n);
    cur = vi(1, 1);
    for (ans = 0;; ans++)
      if (search(0)) {
        printf("%d\n", ans);
        for (int i = 0; i < ans; i++)
          printf("%s\n", ops[i]);
        break;
      }

    #ifndef DEBUG
    break;
    #endif
  }
  return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())

typedef long long ll;

typedef vector<ll> vll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef pair<int, int> pii;

int ans, n;
vi cur;
char ops[1024][1024];

bool search(int cop) {
  if (cur[sz(cur) - 1] == n) return true;
  if (cop >= ans) return false;

  for (int a = -1; a < sz(cur); a++) {
    for (int b = 0; b < sz(cur); b++) {
      for (int k = 1; k <= 8; k *= 2) {
        int nv = (a >= 0 ? cur[a] : 0) + cur[b] * k;
        if (nv > n) continue;
        cur.pb(nv);
        if (search(cop + 1)) {
          if (a < 0)
            snprintf(ops[cop], sizeof ops[cop], "lea e%cx, [%d*e%cx]", 'a' + cop + 1, k, 'a' + b);
          else
            snprintf(ops[cop], sizeof ops[cop], "lea e%cx, [e%cx+%d*e%cx]", 'a' + cop + 1, 'a' + a, k, 'a' + b);
          return true;
        }
        cur.resize(sz(cur) - 1);
      }
    }
  }
  return false;
}

int main() {
  #ifdef DEBUG
  freopen("std.in", "r", stdin);
  freopen("std.out", "w", stdout);
  #endif

  while (scanf("%d", &n) >= 1) {
    eprintf("%d\n", n);
    cur = vi(1, 1);
    for (ans = 0;; ans++)
      if (search(0)) {
        printf("%d\n", ans);
        for (int i = 0; i < ans; i++)
          printf("%s\n", ops[i]);
        break;
      }

    #ifndef DEBUG
    break;
    #endif
  }
  return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <map>

using namespace std;

set<vector<int> > vistos;
set<int> quedan;
queue<vector<int> > q;
map<int,vector<int> > m;

void anyade(vector<int> v,int val)
{
  if (val>255) return;
  if (v.back()>=val) return;
  v.push_back(val);
  if (vistos.find(v)!=vistos.end()) return;
  vistos.insert(v);
  q.push(v);
  if (quedan.find(val)!=quedan.end()) {
    m[val]=v;
    quedan.erase(val);
    //cout<<"visto "<<val<<"   quedan "<<int(quedan.size())<<endl;
  }
}

string reg(int i)
{
  return "e"+string(1,char('a'+i))+"x";
}

void obtener(vector<int> v,int index)
{
  int goal=v[index];
  for (int i=0;i<index;i++) {
    for (int j=i;j<index;j++) {
      int val=v[i];
      if (goal==2*val) {
	cout<<"lea "<<reg(index)<<", [2*"<<reg(i)<<"]"<<endl;
	return;
      }
      if (goal==4*val) {
	cout<<"lea "<<reg(index)<<", [4*"<<reg(i)<<"]"<<endl;
	return;
      }
      if (goal==8*val) {
	cout<<"lea "<<reg(index)<<", [8*"<<reg(i)<<"]"<<endl;
	return;
      }
      for (int j=0;j<index;j++) {
	int aux=v[j];
	if (goal==val+aux) {
	  cout<<"lea "<<reg(index)<<", ["<<reg(i)<<" + "<<reg(j)<<"]"<<endl;
	  return;
	}
	if (goal==val+2*aux) {
	  cout<<"lea "<<reg(index)<<", ["<<reg(i)<<" + 2*"<<reg(j)<<"]"<<endl;
	  return;
	}
	if (goal==val+4*aux) {
	  cout<<"lea "<<reg(index)<<", ["<<reg(i)<<" + 4*"<<reg(j)<<"]"<<endl;
	  return;
	}
	if (goal==val+8*aux) {
	  cout<<"lea "<<reg(index)<<", ["<<reg(i)<<" + 8*"<<reg(j)<<"]"<<endl;
	  return;
	}
      }
    }
  }
}

int main()
{
  for (int i=2;i<=255;i++)
    quedan.insert(i);
  q.push(vector<int> (1,1));
  vistos.insert(vector<int> (1,1));
  m[1]=vector<int> (1,1);
  while ((not q.empty()) and int(quedan.size())>0) {
    vector<int> v=q.front();
    q.pop();
    for (int i=0;i<int(v.size());i++) {
      int val=v[i];
      anyade(v,2*val);
      anyade(v,4*val);
      anyade(v,8*val);
      for (int j=0;j<int(v.size());j++) {
	int aux=v[j];
	anyade(v,val+aux);
	anyade(v,val+2*aux);
	anyade(v,val+4*aux);
	anyade(v,val+8*aux);
      }
    }
  }
  int n;
  while (cin>>n) {
    vector<int> v=m[n];
    cout<<int(v.size())-1<<endl;
    for (int i=1;i<int(v.size());i++) {
      obtener(v,i);
    }
  }
}