#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int f = 1, x = 0;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1LL;
  } while (ch < '0' || ch > '9');
  do {
    x = x * 10 + ch - '0';
    ch = getchar();
  } while (ch >= '0' && ch <= '9');
  return f * x;
}
inline long long readll() {
  long long f = 1, x = 0;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1LL;
  } while (ch < '0' || ch > '9');
  do {
    x = x * 10 + ch - '0';
    ch = getchar();
  } while (ch >= '0' && ch <= '9');
  return f * x;
}
template <class T>
inline void chmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void chmin(T &a, T b) {
  if (a > b) a = b;
}
inline void swap(int &a, int &b) {
  int c = a;
  a = b;
  b = c;
}
using namespace std;
const int N = 3e6 + 10;
int n, m, q;
vector<int> vec[N];
vector<pair<int, int>> pos;
int ban[N], banid[N], bancol[N];
int ans[N];
int fa[N], sz[N], a[333][333];
inline int id(int x, int y) { return (x - 1) * m + y; }
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
unordered_map<long long, int> refe;
inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
mt19937 rnd;
uniform_int_distribution<int> dist(0, 1);
inline void merge(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y) return;
  if (sz[x] > sz[y])
    fa[y] = x, sz[x] += sz[y];
  else
    fa[x] = y, sz[y] += sz[x];
}
int fkoff[N];
int main() {
  n = read();
  m = read();
  q = read();
  pos.resize(q + n * m + 1);
  auto cvt = [&](int x, int y) -> long long {
    return 1ll * x + 1ll * n * m * y;
  };
  int colnm = 0, prec = 0;
  int ind = 0;
  for (int i = (1); i <= (n); ++i) {
    for (int j = (1); j <= (m); ++j) {
      ++ind;
      refe[cvt(id(i, j), 0)] = q + ind;
      pos[q + ind] = make_pair(i, j);
    }
  }
  for (int i = (1); i <= (q); ++i) {
    int x = read(), y = read(), c = read();
    if (c != prec) prec = c, ++colnm;
    pos[i] = make_pair(x, y);
    if (!refe[cvt(id(x, y), colnm)])
      refe[cvt(id(x, y), colnm)] = i;
    else
      fkoff[i] = 1;
    vec[colnm].emplace_back(i);
  }
  for (int i = (1); i <= (q + ind); ++i) fa[i] = i, sz[i] = 1;
  for (int i = (1); i <= (ind - 1); ++i) merge(q + i, q + i + 1);
  for (int i = (1); i <= (colnm); ++i) {
    for (auto cur : vec[i]) {
      if (fkoff[cur]) continue;
      int x = pos[cur].first, y = pos[cur].second;
      if (a[x][y] == i) continue;
      banid[cur] = refe[cvt(id(x, y), a[x][y])];
      ban[banid[cur]] = 1;
      bancol[cur] = a[x][y];
      a[x][y] = i;
      vector<int> sur;
      for (int k = (0); k <= (3); ++k) {
        int tx = x + dx[k], ty = y + dy[k];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == i) {
          sur.emplace_back(refe[cvt(id(tx, ty), i)]);
        }
      }
      vector<vector<int>> vis;
      vector<int> kkk;
      vis.assign(sur.size(), vector<int>(sur.size(), 0));
      kkk.assign(sur.size(), 0);
      if (sur.size() > 1) {
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
            if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
          }
        }
        int cnt = 0;
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          if (kkk[i]) continue;
          ++cnt;
          merge(cur, sur[i]);
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
            if (vis[i][j]) kkk[j] = 1;
        }
        ans[cur] -= (cnt - 1);
      } else if (!sur.size()) {
        ++ans[cur];
      } else if (sur.size() == 1) {
        merge(cur, sur[0]);
      }
    }
  }
  for (int i = (1); i <= (q + ind); ++i) fa[i] = i, sz[i] = 1;
  for (int i = (1); i <= (colnm); ++i) {
    for (auto cur : vec[i]) {
      if (fkoff[cur]) continue;
      if (!ban[cur]) {
        int x = pos[cur].first, y = pos[cur].second;
        vector<int> sur;
        for (int k = (0); k <= (3); ++k) {
          int tx = x + dx[k], ty = y + dy[k];
          if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == i) {
            sur.emplace_back(refe[cvt(id(tx, ty), i)]);
          }
        }
        vector<vector<int>> vis;
        vector<int> kkk;
        vis.assign(sur.size(), vector<int>(sur.size(), 0));
        kkk.assign(sur.size(), 0);
        if (sur.size() > 1) {
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
              if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
            }
          }
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            if (kkk[i]) continue;
            merge(cur, sur[i]);
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
              if (vis[i][j]) kkk[j] = 1;
          }
        } else if (!sur.size()) {
        } else if (sur.size() == 1) {
          merge(cur, sur[0]);
        }
      }
    }
  }
  for (int cur = (q + 1); cur <= (q + ind); ++cur) {
    if (!ban[cur]) {
      int x = pos[cur].first, y = pos[cur].second;
      vector<int> sur;
      for (int k = (0); k <= (3); ++k) {
        int tx = x + dx[k], ty = y + dy[k];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == 0) {
          sur.emplace_back(refe[cvt(id(tx, ty), 0)]);
        }
      }
      vector<vector<int>> vis;
      vector<int> kkk;
      vis.assign(sur.size(), vector<int>(sur.size(), 0));
      kkk.assign(sur.size(), 0);
      if (sur.size() > 1) {
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
            if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
          }
        }
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          if (kkk[i]) continue;
          merge(cur, sur[i]);
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
            if (vis[i][j]) kkk[j] = 1;
        }
      } else if (!sur.size()) {
      } else if (sur.size() == 1) {
        merge(cur, sur[0]);
      }
    }
  }
  for (int i = (colnm); i >= (1); --i) {
    if (!vec[i].size()) continue;
    for (int tmp = vec[i].size() - 1; tmp >= 0; --tmp) {
      int now = vec[i][tmp];
      int x = pos[now].first, y = pos[now].second;
      if (banid[now]) {
        int cur = banid[now];
        a[x][y] = bancol[now];
        vector<int> sur;
        for (int k = (0); k <= (3); ++k) {
          int tx = x + dx[k], ty = y + dy[k];
          if (tx >= 1 && tx <= n && ty >= 1 && ty <= m &&
              a[tx][ty] == a[x][y]) {
            sur.emplace_back(refe[cvt(id(tx, ty), a[x][y])]);
          }
        }
        vector<vector<int>> vis;
        vector<int> kkk;
        vis.assign(sur.size(), vector<int>(sur.size(), 0));
        kkk.assign(sur.size(), 0);
        if (sur.size() > 1) {
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
              if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
            }
          }
          int cnt = 0;
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            if (kkk[i]) continue;
            ++cnt;
            merge(cur, sur[i]);
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
              if (vis[i][j]) kkk[j] = 1;
          }
          assert(cnt >= 1);
          ans[now] += (cnt - 1);
        } else if (!sur.size()) {
          --ans[now];
        } else if (sur.size() == 1) {
          merge(cur, sur[0]);
        }
      }
    }
  }
  ans[0] = 1;
  for (int i = (1); i <= (q); ++i) ans[i] += ans[i - 1];
  for (int i = (1); i <= (q); ++i) printf("%d\n", ans[i]);
  return 0;
}

### Prompt

Please create a solution in cpp to the following problem:

You are given a matrix n × m, initially filled with zeroes. We define a_{i, j} as the element in the i-th row and the j-th column of the matrix.

Two cells of the matrix are connected if they share a side, and the elements in these cells are equal. Two cells of the matrix belong to the same connected component if there exists a sequence s_1, s_2, ..., s_k such that s_1 is the first cell, s_k is the second cell, and for every i ∈ [1, k - 1], s_i and s_{i + 1} are connected.

You are given q queries of the form x_i y_i c_i (i ∈ [1, q]). For every such query, you have to do the following:

  1. replace the element a_{x, y} with c; 
  2. count the number of connected components in the matrix. 



There is one additional constraint: for every i ∈ [1, q - 1], c_i ≤ c_{i + 1}.

Input

The first line contains three integers n, m and q (1 ≤ n, m ≤ 300, 1 ≤ q ≤ 2 ⋅ 10^6) — the number of rows, the number of columns and the number of queries, respectively.

Then q lines follow, each representing a query. The i-th line contains three integers x_i, y_i and c_i (1 ≤ x_i ≤ n, 1 ≤ y_i ≤ m, 1 ≤ c_i ≤ max(1000, ⌈ (2 ⋅ 10^6)/(nm) ⌉)). For every i ∈ [1, q - 1], c_i ≤ c_{i + 1}.

Output

Print q integers, the i-th of them should be equal to the number of components in the matrix after the first i queries are performed.

Example

Input


3 2 10
2 1 1
1 2 1
2 2 1
1 1 2
3 1 2
1 2 2
2 2 2
2 1 2
3 2 4
2 1 5


Output


2
4
3
3
4
4
4
2
2
4

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int f = 1, x = 0;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1LL;
  } while (ch < '0' || ch > '9');
  do {
    x = x * 10 + ch - '0';
    ch = getchar();
  } while (ch >= '0' && ch <= '9');
  return f * x;
}
inline long long readll() {
  long long f = 1, x = 0;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1LL;
  } while (ch < '0' || ch > '9');
  do {
    x = x * 10 + ch - '0';
    ch = getchar();
  } while (ch >= '0' && ch <= '9');
  return f * x;
}
template <class T>
inline void chmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void chmin(T &a, T b) {
  if (a > b) a = b;
}
inline void swap(int &a, int &b) {
  int c = a;
  a = b;
  b = c;
}
using namespace std;
const int N = 3e6 + 10;
int n, m, q;
vector<int> vec[N];
vector<pair<int, int>> pos;
int ban[N], banid[N], bancol[N];
int ans[N];
int fa[N], sz[N], a[333][333];
inline int id(int x, int y) { return (x - 1) * m + y; }
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
unordered_map<long long, int> refe;
inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
mt19937 rnd;
uniform_int_distribution<int> dist(0, 1);
inline void merge(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y) return;
  if (sz[x] > sz[y])
    fa[y] = x, sz[x] += sz[y];
  else
    fa[x] = y, sz[y] += sz[x];
}
int fkoff[N];
int main() {
  n = read();
  m = read();
  q = read();
  pos.resize(q + n * m + 1);
  auto cvt = [&](int x, int y) -> long long {
    return 1ll * x + 1ll * n * m * y;
  };
  int colnm = 0, prec = 0;
  int ind = 0;
  for (int i = (1); i <= (n); ++i) {
    for (int j = (1); j <= (m); ++j) {
      ++ind;
      refe[cvt(id(i, j), 0)] = q + ind;
      pos[q + ind] = make_pair(i, j);
    }
  }
  for (int i = (1); i <= (q); ++i) {
    int x = read(), y = read(), c = read();
    if (c != prec) prec = c, ++colnm;
    pos[i] = make_pair(x, y);
    if (!refe[cvt(id(x, y), colnm)])
      refe[cvt(id(x, y), colnm)] = i;
    else
      fkoff[i] = 1;
    vec[colnm].emplace_back(i);
  }
  for (int i = (1); i <= (q + ind); ++i) fa[i] = i, sz[i] = 1;
  for (int i = (1); i <= (ind - 1); ++i) merge(q + i, q + i + 1);
  for (int i = (1); i <= (colnm); ++i) {
    for (auto cur : vec[i]) {
      if (fkoff[cur]) continue;
      int x = pos[cur].first, y = pos[cur].second;
      if (a[x][y] == i) continue;
      banid[cur] = refe[cvt(id(x, y), a[x][y])];
      ban[banid[cur]] = 1;
      bancol[cur] = a[x][y];
      a[x][y] = i;
      vector<int> sur;
      for (int k = (0); k <= (3); ++k) {
        int tx = x + dx[k], ty = y + dy[k];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == i) {
          sur.emplace_back(refe[cvt(id(tx, ty), i)]);
        }
      }
      vector<vector<int>> vis;
      vector<int> kkk;
      vis.assign(sur.size(), vector<int>(sur.size(), 0));
      kkk.assign(sur.size(), 0);
      if (sur.size() > 1) {
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
            if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
          }
        }
        int cnt = 0;
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          if (kkk[i]) continue;
          ++cnt;
          merge(cur, sur[i]);
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
            if (vis[i][j]) kkk[j] = 1;
        }
        ans[cur] -= (cnt - 1);
      } else if (!sur.size()) {
        ++ans[cur];
      } else if (sur.size() == 1) {
        merge(cur, sur[0]);
      }
    }
  }
  for (int i = (1); i <= (q + ind); ++i) fa[i] = i, sz[i] = 1;
  for (int i = (1); i <= (colnm); ++i) {
    for (auto cur : vec[i]) {
      if (fkoff[cur]) continue;
      if (!ban[cur]) {
        int x = pos[cur].first, y = pos[cur].second;
        vector<int> sur;
        for (int k = (0); k <= (3); ++k) {
          int tx = x + dx[k], ty = y + dy[k];
          if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == i) {
            sur.emplace_back(refe[cvt(id(tx, ty), i)]);
          }
        }
        vector<vector<int>> vis;
        vector<int> kkk;
        vis.assign(sur.size(), vector<int>(sur.size(), 0));
        kkk.assign(sur.size(), 0);
        if (sur.size() > 1) {
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
              if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
            }
          }
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            if (kkk[i]) continue;
            merge(cur, sur[i]);
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
              if (vis[i][j]) kkk[j] = 1;
          }
        } else if (!sur.size()) {
        } else if (sur.size() == 1) {
          merge(cur, sur[0]);
        }
      }
    }
  }
  for (int cur = (q + 1); cur <= (q + ind); ++cur) {
    if (!ban[cur]) {
      int x = pos[cur].first, y = pos[cur].second;
      vector<int> sur;
      for (int k = (0); k <= (3); ++k) {
        int tx = x + dx[k], ty = y + dy[k];
        if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] == 0) {
          sur.emplace_back(refe[cvt(id(tx, ty), 0)]);
        }
      }
      vector<vector<int>> vis;
      vector<int> kkk;
      vis.assign(sur.size(), vector<int>(sur.size(), 0));
      kkk.assign(sur.size(), 0);
      if (sur.size() > 1) {
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
            if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
          }
        }
        for (int i = (0); i <= ((sur.size() - 1)); ++i) {
          if (kkk[i]) continue;
          merge(cur, sur[i]);
          for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
            if (vis[i][j]) kkk[j] = 1;
        }
      } else if (!sur.size()) {
      } else if (sur.size() == 1) {
        merge(cur, sur[0]);
      }
    }
  }
  for (int i = (colnm); i >= (1); --i) {
    if (!vec[i].size()) continue;
    for (int tmp = vec[i].size() - 1; tmp >= 0; --tmp) {
      int now = vec[i][tmp];
      int x = pos[now].first, y = pos[now].second;
      if (banid[now]) {
        int cur = banid[now];
        a[x][y] = bancol[now];
        vector<int> sur;
        for (int k = (0); k <= (3); ++k) {
          int tx = x + dx[k], ty = y + dy[k];
          if (tx >= 1 && tx <= n && ty >= 1 && ty <= m &&
              a[tx][ty] == a[x][y]) {
            sur.emplace_back(refe[cvt(id(tx, ty), a[x][y])]);
          }
        }
        vector<vector<int>> vis;
        vector<int> kkk;
        vis.assign(sur.size(), vector<int>(sur.size(), 0));
        kkk.assign(sur.size(), 0);
        if (sur.size() > 1) {
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j) {
              if (find(sur[i]) == find(sur[j])) vis[i][j] = 1;
            }
          }
          int cnt = 0;
          for (int i = (0); i <= ((sur.size() - 1)); ++i) {
            if (kkk[i]) continue;
            ++cnt;
            merge(cur, sur[i]);
            for (int j = (i + 1); j <= ((sur.size() - 1)); ++j)
              if (vis[i][j]) kkk[j] = 1;
          }
          assert(cnt >= 1);
          ans[now] += (cnt - 1);
        } else if (!sur.size()) {
          --ans[now];
        } else if (sur.size() == 1) {
          merge(cur, sur[0]);
        }
      }
    }
  }
  ans[0] = 1;
  for (int i = (1); i <= (q); ++i) ans[i] += ans[i - 1];
  for (int i = (1); i <= (q); ++i) printf("%d\n", ans[i]);
  return 0;
}

```