#include <bits/stdc++.h>
const int MAXN = 1250;
const int MAXQ = 120000;
int a[MAXN][MAXN], lazy[MAXN];
int tag[MAXN];
int sum[MAXN];
int n, m, q, tot;
int pointer[MAXQ];
struct node {
  int ans, ty, x, y;
} ask[MAXQ];
struct Edge {
  int to, next;
  Edge() {}
  Edge(int b, int nxt) {
    to = b;
    next = nxt;
  }
} edge[MAXQ];
inline void addedge(int a, int b) {
  edge[tot] = Edge(b, pointer[a]);
  pointer[a] = tot++;
}
int ans;
void init() {
  tot = 0;
  ans = 0;
  memset(pointer, -1, sizeof(pointer));
}
void dfs(int u) {
  bool flag = false;
  int x, y;
  if (ask[u].ty == 1) {
    x = ask[u].x;
    y = ask[u].y;
    if (a[x][y] == tag[x]) {
      a[x][y] = 1 ^ tag[x];
      sum[x]++;
      flag = true;
      ans++;
    }
  }
  if (ask[u].ty == 2) {
    x = ask[u].x;
    y = ask[u].y;
    if (a[x][y] == (tag[x] ^ 1)) {
      a[x][y] = tag[x];
      sum[x]--;
      flag = true;
      ans--;
    }
  }
  if (ask[u].ty == 3) {
    x = ask[u].x;
    tag[x] ^= 1;
    ans -= sum[x];
    sum[x] = m - sum[x];
    ans += sum[x];
  }
  ask[u].ans = ans;
  for (int j = pointer[u]; j != -1; j = edge[j].next) {
    dfs(edge[j].to);
  }
  if (ask[u].ty == 1 && flag) {
    a[x][y] = tag[x];
    sum[x]--;
    ans--;
  }
  if (ask[u].ty == 2 && flag) {
    a[x][y] = 1 - tag[x];
    sum[x]++;
    ans++;
  }
  if (ask[u].ty == 3) {
    tag[x] ^= 1;
    ans -= sum[x];
    sum[x] = m - sum[x];
    ans += sum[x];
  }
}
int main() {
  int a, b, type;
  init();
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= q; ++i) {
    scanf("%d", &type);
    ask[i].ty = type;
    if (type < 3) {
      scanf("%d%d", &a, &b);
      ask[i].x = a;
      ask[i].y = b;
      addedge(i - 1, i);
    } else {
      scanf("%d", &a);
      ask[i].x = a;
      int u = (type == 4) ? a : i - 1;
      addedge(u, i);
    }
  }
  dfs(0);
  for (int i = 1; i <= q; ++i) printf("%d\n", ask[i].ans);
  return 0;
}
