#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
#define rep(i,n) for(lint (i)=0;(i)<(n);(i)++)
#define repp(i,m,n) for(lint (i)=(m);(i)<(n);(i)++)
#define repm(i,n) for(lint (i)=(n-1);(i)>=0;(i)--)
#define INF (1ll<<60)
#define all(x) (x).begin(),(x).end()
//const lint MOD =1000000007;
const lint MOD=998244353;
const lint MAX = 1000000;
using Graph =vector<vector<lint>>;
typedef pair<lint,lint> P;
typedef map<lint,lint> M;
#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)

 
lint fac[MAX], finv[MAX], inv[MAX];
 
void COMinit() 
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (lint i = 2; i < MAX; i++)
    {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}
 
long long COM(lint n, lint k)
{
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
 
lint primary(lint num)
{
    if (num < 2) return 0;
    else if (num == 2) return 1;
    else if (num % 2 == 0) return 0;
 
    double sqrtNum = sqrt(num);
    for (int i = 3; i <= sqrtNum; i += 2)
    {
        if (num % i == 0)
        {
            return 0;
        }
    }
 
    return 1;
}
   long long modpow(long long a, long long n, long long mod) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
    lint lcm(lint a,lint b){
        return a/__gcd(a,b)*b;
    }
     lint gcd(lint a,lint b){
        return __gcd(a,b);
    } 

    int main(){
        lint a,b,c;
        cin>>a>>b>>c;
        a=a*(a+1)/2;
        a%=MOD;
        b=b*(b+1)/2;
        b%=MOD;
        c=c*(c+1)/2;
        c%=MOD;
        lint ans=a;
        ans*=b;
        ans%=MOD;
        ans*=c;
        ans%=MOD;
        cout<<ans<<endl;
    }
      
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (int)n; i++)
using ll = long long;
const int MAX = 2e5+1;

template <typename T, typename F>
class SegTree{
  int n; T uni; F f;
  vector<T> dat;
public:
  SegTree(int _n, F f, T uni) : f(f), uni(uni) {
    n = 1;
    while(n < _n) n *= 2;
    dat = vector<T>(2*n,uni);
  }
  void set(int k, const T x) {
    dat[k+n] = x;
  }
  void build() {
    for(int i = n-1; i >= 0; i--) {
      dat[i] = f(dat[2*i],dat[2*i+1]);
    }
  }
  void update(int k, T x) {
    k += n;
    dat[k] += x;
    while(k >>= 1){
      dat[k] = f(dat[2*k],dat[2*k+1]);
    }
  }
  T query(int a, int b) {
    T l = uni, r = uni;
    for(a += n, b += n; a < b; a >>= 1, b >>= 1) {
      if(a & 1) l = f(l,dat[a++]);
      if(b & 1) r = f(dat[--b],r);
    }
    return f(l,r);
  }
};

int main(){
  int n, m, q;
  cin >> n >> m >> q;
  vector<ll> a(n), b(m);
  auto f = [](ll a,ll b){return a + b;};
  SegTree<ll,decltype(f)> sa(MAX,f,0), sb(MAX,f,0), na(MAX,f,0), nb(MAX,f,0);
  na.set(0,n); nb.set(0,m);
  na.build(); nb.build();
  ll l[q], r[q], d[q];
  rep(i,q) cin >> l[i] >> r[i] >> d[i];
  vector<ll> v;
  v.push_back(0);
  rep(i,q) v.push_back(d[i]);
  sort(v.begin(),v.end());
  v.erase(unique(v.begin(),v.end()),v.end());
  int vs = v.size();
  map<ll,ll> mp;
  rep(i,vs) mp[v[i]] = i;
  ll sum = 0;
  rep(i,q) {
    ll t, x, y;
    t = l[i], x = r[i], y = d[i];
    x--;
    if(t == 1) {
      sum -= nb.query(0,mp[a[x]]+1)*a[x];
      sum += nb.query(0,mp[y]+1)*y;
      if(a[x] > y) sum += sb.query(mp[y]+1,mp[a[x]]+1);
      else sum -= sb.query(mp[a[x]]+1,mp[y]+1);
      na.update(mp[a[x]],-1);
      na.update(mp[y],1);
      sa.update(mp[a[x]],-a[x]);
      sa.update(mp[y],y);
      a[x] = y;
    } else {
      sum -= na.query(0,mp[b[x]])*b[x];
      sum += na.query(0,mp[y])*y;
      if(b[x] > y) sum += sa.query(mp[y],mp[b[x]]);
      else sum -= sa.query(mp[b[x]],mp[y]);
      nb.update(mp[b[x]],-1);
      nb.update(mp[y],1);
      sb.update(mp[b[x]],-b[x]);
      sb.update(mp[y],y);
      b[x] = y;
    }
    cout << sum << endl;
  }
  return 0;
}
