#include <bits/stdc++.h>
using namespace std;
inline int read() {
  char c = getchar();
  int x = 0, f = 1;
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  return x * f;
}
const int MAXN = 3e2 + 5;
const int MAXQ = 2e6 + 5;
struct Query {
  int x, y, nc, oc;
} q[MAXQ];
int fa[MAXQ << 1], ans[MAXQ], a[MAXN][MAXN], id[MAXN][MAXN];
int N, M, Q, Num, cnt;
inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
inline int mrg(int x, int y) {
  if (find(x) != find(y)) {
    fa[fa[x]] = fa[y];
    Num--;
  }
}
inline void check(int x, int y) {
  if (a[x][y] == a[x - 1][y]) mrg(id[x][y], id[x - 1][y]);
  if (a[x][y] == a[x + 1][y]) mrg(id[x][y], id[x + 1][y]);
  if (a[x][y] == a[x][y - 1]) mrg(id[x][y], id[x][y - 1]);
  if (a[x][y] == a[x][y + 1]) mrg(id[x][y], id[x][y + 1]);
}
inline void solveTo() {
  for (int i = 1; i <= Q; i++) {
    if (q[i].oc == q[i].nc) continue;
    int x = q[i].x, y = q[i].y;
    Num = 1;
    a[x][y] = q[i].nc;
    id[x][y] = ++cnt;
    fa[cnt] = cnt;
    check(x, y);
    ans[i] += Num;
  }
}
inline void solveBack() {
  for (int i = Q; i; i--) {
    if (q[i].oc == q[i].nc) continue;
    int x = q[i].x, y = q[i].y;
    Num = 1;
    a[x][y] = q[i].oc;
    id[x][y] = ++cnt;
    fa[cnt] = cnt;
    check(x, y);
    ans[i] -= Num;
  }
}
int main() {
  N = read();
  M = read();
  Q = read();
  for (int i = 1; i <= Q; i++) {
    int x = read(), y = read(), z = read();
    q[i] = {x, y, z, a[x][y]};
    a[x][y] = z;
  }
  ans[0] = 1;
  cnt = 0;
  memset(a, -1, sizeof(a));
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++) a[i][j] = 0;
  solveTo();
  memset(fa, cnt = 0, sizeof(fa));
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++) {
      id[i][j] = ++cnt;
      fa[cnt] = cnt;
    }
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++) check(i, j);
  solveBack();
  for (int i = 1; i <= Q; i++) {
    ans[i] += ans[i - 1];
    printf("%d\n", ans[i]);
  }
  return 0;
}
