// give up
#include <bitset>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <list>
#include <numeric>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <valarray>

// alias, using declaration
using llint = long long; using ldouble = long double;
template <class T = llint> using vector = std::vector<T>;
template <class T = llint> using deque = std::deque<T>;
template <class T = llint> using list = std::list<T>;
template <class T = llint, class U = llint> using umap = std::unordered_map<T, U>;
template <class T = llint, class U = llint> using ummap = std::unordered_multimap<T, U>;
template <class T = llint> using uset = std::unordered_set<T>;
template <class T = llint> using umset = std::unordered_multiset<T>;
template <class T = llint, class U = T> using pair = std::pair<T, U>;
template <class T = llint> using varray = std::valarray<T>;
template <class T = llint, class U = vector<T>, class V = std::less<class U::value_type>> using pqueue = std::priority_queue<T, U, V>;
using std::array; using std::bitset; using std::string; using std::tuple;

// constant
constexpr llint INF = 0x7FFFFFFFFFFFFFFF;
constexpr llint INVALID = 0x8000000000000000;

namespace io {
  // in
  template <class... T, size_t... S> auto in(std::index_sequence<S...>) {tuple<T...> t; (..., (std::cin >> std::get<S>(t))); return t;}
  template <class... T, size_t... S> auto in(std::index_sequence<S...>, size_t n) {tuple<vector<T>...> t{vector<T>(n)...}; for (size_t i = 0; i < n; i++) (..., (std::cin >> std::get<S>(t)[i])); return t;}
  template <size_t N, class T = llint, class... U> auto in() {static_assert(N >= 1); if constexpr (N > 1) return in<N - 1, T, T, U...>(); else return in<T, U...>(std::index_sequence_for<T, U...>());}
  template <size_t N, class T = llint, class... U> auto in(size_t n) {static_assert(N >= 1); if constexpr (N > 1) return in<N - 1, T, T, U...>(n); else return in<T, U...>(std::index_sequence_for<T, U...>(), n);}
  template <size_t N, class T = llint> auto in(size_t n, size_t m) {static_assert(N == 1); vector<vector<T>> v(n, vector<T>(m)); for (auto&& vi : v) for (auto&& vij : vi) std::cin >> vij; return std::make_tuple(v);}
  // out
  template <class T, class... U> void out(const T& a, const U&... b) {std::cout << a << (sizeof...(b) ? " " : "\n"); if constexpr (sizeof...(b)) out(b...);}
  template <class T, class U = const char*> void out(const vector<T>& a, U d = " ") {for (auto&& b : a) std::cout << b << (&b != &a.back() ? d : "\n");}
}

int main() {
  // input
  auto [N, M, Q] = io::in<3>();
  auto [T, X, Y] = io::in<3>(Q);

  // solve
  vector<> a(N + 1), b(M + 1);
  umap<> Z;
  {
    Z.emplace(0, 0);
    vector<> Y_ = Y;
    std::sort(Y_.begin(), Y_.end());
    for (llint i = 0; i < Q; i++) Z.emplace(Y_.at(i), i + 1);
  }
  constexpr llint ST_SIZE = 1 << 19;
  vector<pair<>> st_a(ST_SIZE), st_b(ST_SIZE);
  auto update = [&Z](vector<pair<>>& st, llint v, llint n) {
    for (llint i = (ST_SIZE >> 1) + Z.at(v); i > 0; i >>= 1) {
      st.at(i).first += n;
      st.at(i).second += v * n;
    }
  };
  auto culc_line = [&Z](const vector<pair<>>& st, llint v) {
    llint r = st.at((ST_SIZE >> 1) + Z.at(v)).second;
    for (llint i = (ST_SIZE >> 1) + Z.at(v); i > 1; i >>= 1) {
      r += i & 1 ? st.at(i ^ 1).first * v : st.at(i ^ 1).second;
    }
    return r;
  };
  update(st_a, 0, N);
  update(st_b, 0, M);
  vector<> result(Q);
  for (llint i = 0; i < Q; i++) {
    auto& t = (T.at(i) == 1 ? a : b).at(X.at(i));
    auto& st_x = T.at(i) == 1 ? st_a : st_b;
    auto& st_y = T.at(i) == 1 ? st_b : st_a;
    update(st_x, t, -1);
    result.at(i) = -culc_line(st_y, t);
    t = Y.at(i);
    update(st_x, t, 1);
    result.at(i) += culc_line(st_y, t);
  }
  for (llint i = 1; i < Q; i++) result.at(i) += result.at(i - 1);

  // output
  io::out(result, "\n");
}
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <utility>
#include <map>
#include <queue>
#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>

#define ll long long
#define ld long double
#define eps 1e-8
#define MOD 1000000007

#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f

// change if necessary
#define MAXN 200010

using namespace std;

struct segtree {
    struct Node {
        Node *l, *r;
        int cnt;
        ll sum;

        Node() {
            l = r = nullptr;
            cnt = sum = 0;
        }

        Node operator+(const Node &b) const {
            Node res;
            res.cnt = this->cnt + b.cnt;
            res.sum = this->sum + b.sum;
            return res;
        }
    };

    deque<Node> dq;
    segtree() {
        dq.push_back(Node());
    }

    Node *new_node() {
        dq.push_back(Node());
        return &dq.back();
    }

    Node get(Node *p) {
        return p ? *p : Node();
    }

    void upd(int x, int y) { upd(&dq[0], 0, 1e8, x, y); }
    void upd(Node *p, int l, int r, int x, int y) {
        if (l == r) {
            p->cnt += y;
            p->sum += x * y;
        } else {
            int m = (l + r) / 2;
            if (x <= m) {
                if (!p->l) p->l = new_node();
                upd(p->l, l, m, x, y);
            } else {
                if (!p->r) p->r = new_node();
                upd(p->r, m + 1, r, x, y);
            }

            Node res = get(p->l) + get(p->r);
            p->cnt = res.cnt;
            p->sum = res.sum;
        }
    }

    Node qry(int x, int y) { return qry(&dq[0], 0, 1e8, x, y); }
    Node qry(Node *p, int l, int r, int x, int y) {
        if (p == nullptr || r < x || l > y) return Node();
        if (x <= l && r <= y) {
            return *p;
        }
        int m = (l + r) / 2;
        return qry(p->l, l, m, x, y) + qry(p->r, m + 1, r, x, y);
    }
};

segtree a, b;
ll cur_a[MAXN];
ll cur_b[MAXN];

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int n, m, q;
    cin >> n >> m >> q;

    a.upd(0, n);
    b.upd(0, m);
    ll ans = 0;

    while (q--) {
        int t, x, y; 
        cin >> t >> x >> y;
        x--;
        if (t == 1) {
            auto res = b.qry(cur_a[x], 1e8);
            ans -= res.sum;
            ans -= (m - res.cnt) * cur_a[x];

            a.upd(cur_a[x], -1);
            cur_a[x] = y;
            a.upd(cur_a[x], 1);

            res = b.qry(cur_a[x], 1e8);
            ans += res.sum;
            ans += (m - res.cnt) * cur_a[x];
        } else {
            auto res = a.qry(cur_b[x], 1e8);
            ans -= res.sum;
            ans -= (n - res.cnt) * cur_b[x];

            b.upd(cur_b[x], -1);
            cur_b[x] = y;
            b.upd(cur_b[x], 1);

            res = a.qry(cur_b[x], 1e8);
            ans += res.sum;
            ans += (n - res.cnt) * cur_b[x];
        }

        cout << ans << '\n';
    }

    return 0;
}
