#include<bits/stdc++.h>

struct em {
    using type = std::pair<unsigned long, unsigned long>;
    static type id(){ return {}; }
    static type op(const type& a, const type& b){return {a.first + b.first, a.second + b.second};}
};

// from https://kazuma8128.hatenablog.com/entry/2018/11/29/093827

template <typename M> // Mは 型type, 単位元id(), 演算op() を持つモノイド
class dynamic_segment_tree {
    using T = typename M::type;
    struct node {
        int pos;
        T val, all;
        node *l, *r;
        node(int p, T v)
                : pos(p), val(v), all(v), l(nullptr), r(nullptr) {}
    };
private:
    const int n;
    node *root;
public:
    dynamic_segment_tree(int n_) :
            n(1 << (int)ceil(log2(n_))), root(nullptr) {}
    void update(int p, T val) {
        root = change(root, p, val, 0, n);
    }
    T find(int l, int r) {
        return get(l, r, root, 0, n);
    }
private:
    T value(node *t) {
        return t ? t->all : M::id();
    }
    T get(int l, int r, node* t, int lb, int ub) {
        if (!t || ub <= l || r <= lb) return M::id();
        if (l <= lb && ub <= r) return t->all;
        int c = (lb + ub) / 2;
        T res = get(l, r, t->l, lb, c);
        if (l <= t->pos && t->pos < r) res = M::op(res, t->val);
        return M::op(res, get(l, r, t->r, c, ub));
    }
    node *change(node* t, int p, T val, int lb, int ub) {
        if (!t) return new node(p, val);
        if (t->pos == p) {
            t->val = val;
            t->all = M::op(value(t->l), M::op(t->val, value(t->r)));
            return t;
        }
        int c = (lb + ub) / 2;
        if (p < c) {
            if (p > t->pos) std::swap(p, t->pos), std::swap(val, t->val);
            t->l = change(t->l, p, val, lb, c);
        }
        else {
            if (p < t->pos) std::swap(p, t->pos), std::swap(val, t->val);
            t->r = change(t->r, p, val, c, ub);
        }
        t->all = M::op(value(t->l), M::op(t->val, value(t->r)));
        return t;
    }
};

int main(){
    using namespace std;
    unsigned long N, M, Q;
    cin >> N >> M >> Q;
    vector<unsigned long> A(N), B(M);
    dynamic_segment_tree<em> a(200000000), b(200000000);
    a.update(0, {0, N});
    b.update(0, {0, M});
    const auto dec{[](const auto a, unsigned long x) -> pair<unsigned long, unsigned long> {
        return {a.first - x, a.second - 1};
    }};
    const auto enc{[](const auto a, unsigned long x) -> pair<unsigned long, unsigned long> {
        return {a.first + x, a.second + 1};
    }};
    const auto diff{[](auto& sgt, unsigned long X){
        const auto [sum, cnt]{sgt.find(0, X)};
        return cnt * X - sum;
    }};
    unsigned long ans{0};
    for(unsigned long i{0}, t, x, y; i < Q; ++i){
        cin >> t >> x >> y;
        auto& v{t == 1 ? A[x - 1] : B[x - 1]};
        auto& now{t == 1 ? a : b}, oppo{t == 1 ? b : a};
        ans -= diff(oppo, v);
        now.update(v, dec(now.find(v, v + 1), v));
        swap(v, y);
        now.update(v, enc(now.find(v, v + 1), v));
        ans += diff(oppo, v);
        cout << ans << endl;
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define mod 1000000007
#define mod2 998244353
#define pi 3.1415926535897932384626
#define endl '\n'
#define all(x) x.begin(), x.end()
#define deb(x) cout << #x << " : " << x << endl;
#define deb2(x, y) cout << #x << " : " << x << ", " << #y << " : " << y << endl;
#define lmax LLONG_MAX
#define lmin LLONG_MIN

/**************  segment tree code starts  ***************/

const int N = 2e5 + 100;
int tree[4 * N];

void build(int i, int s, int e, vector<int>& a) {
    if(s == e) {
        tree[i] = a[s];
        return;
    }

    int mid = (s + e) / 2;
    build(2 * i, s, mid, a);
    build(2 * i + 1, mid + 1, e, a);

    tree[i] = tree[2 * i] + tree[2 * i + 1];
}

void update(int i, int s, int e, int ind, int val, vector<int>& a) {
    if(s == e) {
        a[ind] = val;
        tree[i] = val;
        return;
    }

    int mid = (s + e) / 2;
    if(ind <= mid) 
        update(2 * i, s, mid, ind, val, a);
    else 
        update(2 * i + 1, mid + 1, e, ind, val, a);

    tree[i] = tree[2 * i] + tree[2 * i + 1];
}

int query(int i, int s, int e, int l, int r) {
    if(s > r or e < l) return 0;
    if(s >= l and e <= r) return tree[i];

    int mid = (s + e) / 2;
    int left = query(2 * i, s, mid, l, r);
    int right = query(2 * i + 1, mid + 1, e, l, r);

    return left + right;
}

/**************  segment tree code ends  ***************/

void testcase() {
    int r, c, x;
    cin >> r >> c >> x;
    if(x == 0) {
        cout << r * c << endl;
        return;
    }
    vector<int> a(r, c), b(c, r);
    vector<vector<int>> p(x, vector<int>(2));

    for(int i = 0; i < x; i++) {
        int d, e;
        cin >> d >> e;
        d--, e--;
        a[d] = min(a[d], e);
        b[e] = min(b[e], d);
        p[i][0] = e, p[i][1] = d;
    }
    sort(p.begin(), p.end());
    vector<int> g(r + 2);
    build(1, 0, r - 1, g);
    set<int> s;
    int ans = 0, row = 0;
    
    for(int i = 0; i < r; i++) {
        if(a[i] == 0) break;
        ans += a[i];
        row = i;
    }
    
    row++;
    int j = 0;
    for(int i = 0; i < c; i++) {
        if(b[i] == 0) break;
        while(j < x and p[j][0] == i) {
            if(s.count(p[j][1]) == 0 and p[j][1] < row) {
                update(1, 0, r - 1, p[j][1], 1, g);
                s.insert(p[j][1]);
            }
            j++;
        }
        int val = query(1, 0, r - 1, 0, b[i] - 1);    
        ans += b[i];    
        ans -= (min(row, b[i]) - val);        
    }    
    
    cout << ans;
}

signed main() {
#ifdef SP
    freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false), cin.tie(NULL);
    srand(chrono::high_resolution_clock::now().time_since_epoch().count());
    int t = 1;
    // cin >> t;
    for(int i = 1; i <= t; i++) {
        // cout << "Case #" << i << ": ";
        testcase();
        cout << endl;
    }
}