#include <bits/stdc++.h>
using namespace std;
const int maxn = 2000 + 5, maxq = 100000 + 5;
int n, m, q, tot, line[maxn], ans[maxq];
int e, last[maxq], Next[maxq], to[maxq];
bool book[maxn][maxn];
struct query {
  int id, p, x, y;
} ask[maxq];
inline void _read(int& x) {
  char ch = getchar();
  bool mark = false;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') mark = true;
  for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  if (mark) x = -x;
}
void Addedge(int x, int y) {
  to[++e] = y;
  Next[e] = last[x];
  last[x] = e;
}
void DFS(int x) {
  int i;
  bool flag = false;
  query& q = ask[x];
  if (q.p == 1 && !book[q.x][q.y]) {
    tot++;
    flag = true;
    book[q.x][q.y] = true;
    line[q.x]++;
  } else if (q.p == 2 && book[q.x][q.y]) {
    tot--;
    flag = true;
    book[q.x][q.y] = false;
    line[q.x]--;
  } else if (q.p == 3) {
    flag = true;
    tot += m - 2 * line[q.x];
    line[q.x] = m - line[q.x];
    for (i = 1; i <= m; i++) book[q.x][i] = !book[q.x][i];
  }
  ans[q.id] = tot;
  for (i = last[x]; i != -1; i = Next[i]) DFS(to[i]);
  if (!flag) return;
  if (q.p == 1) {
    tot--;
    book[q.x][q.y] = false;
    line[q.x]--;
  } else if (q.p == 2) {
    tot++;
    book[q.x][q.y] = true;
    line[q.x]++;
  } else if (q.p == 3) {
    tot += m - 2 * line[q.x];
    line[q.x] = m - line[q.x];
    for (i = 1; i <= m; i++) book[q.x][i] = !book[q.x][i];
  }
}
int main() {
  int i, j, x, y, z;
  _read(n);
  _read(m);
  _read(q);
  memset(last, -1, sizeof(last));
  for (i = 1; i <= q; i++) {
    ask[i].id = i;
    _read(ask[i].p);
    if (ask[i].p != 4) {
      Addedge(i - 1, i);
      _read(ask[i].x);
      if (ask[i].p != 3) _read(ask[i].y);
    } else {
      _read(x);
      Addedge(x, i);
    }
  }
  DFS(0);
  for (i = 1; i <= q; i++) printf("%d\n", ans[i]);
  return 0;
}
