#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;

constexpr bool typetest = 0;
constexpr int N = 2e5 + 5;
constexpr ll mod = 1e9 + 7;
int n, dp[N][65][2];
vector<pair<int, ll>> adj[N];
ll ans(0);

void Read()
{
    cin >> n;
    for (int i = 2; i <= n; ++i)
    {
        int u, v;
        ll w;
        cin >> u >> v >> w;
        adj[u].emplace_back(v, w);
        adj[v].emplace_back(u, w);
    }
}

#define bit(i, x) (((x) >> (i)) & 1)

void dfs(int v, int par)
{
    for (int j = 0; j < 61; ++j)
    {
        ++dp[v][j][0];
        (ans += (1ll << j) % mod * dp[v][j][1] % mod) %= mod;
    }

    for (auto i : adj[v])
        if (i.first != par)
        {
            for (int j = 0; j < 61; ++j)
            {
                dp[i.first][j][1] += dp[v][j][!bit(j, i.second)];
                dp[i.first][j][0] += dp[v][j][bit(j, i.second)];
            }

            dfs(i.first, v);

            for (int j = 0; j < 61; ++j)
            {
                dp[v][j][1] = dp[i.first][j][!bit(j, i.second)];
                dp[v][j][0] = dp[i.first][j][bit(j, i.second)];
            }
        }
}

void Solve()
{
    dfs(1, 1);
    cout << ans;
}

int32_t main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t(1);
    if (typetest)
        cin >> t;
    for (int _ = 1; _ <= t; ++_)
    {
        Read();
        Solve();
    }
}
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;

#define all(a) (a).begin(), (a).end()
#define mp make_pair

template<typename T1, typename T2> 
inline void chkmin(T1& x, const T2& y) {
    if (y < x) x = y;
}

template<typename T1, typename T2>
inline void chkmax(T1& x, const T2& y) {
    if (x < y) x = y;
}

#define int ll

struct Fenwick{
    vector<int> tree;
    int n;
    Fenwick() {}
    Fenwick(int _n) {
        n = _n;
        tree.assign(n, 0);
    }
    void upd(int pos, int val) {
        for (; pos < n; pos |= pos + 1) {
            tree[pos] += val;
        }
    }
    int get(int r) {
        int ans = 0;
        for (; r >= 0; r = (r & (r + 1)) - 1) {
            ans += tree[r];
        }
        return ans;
    }
    int get(int l, int r) {
        if (l > r) return 0;
        return get(r) - get(l - 1);
    }
};

struct Query{
    int t, x, y;
};

int ans = 0;
Fenwick treeA, treeB, cntA, cntB;

signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cout.precision(20), cout.setf(ios::fixed);
    int n, m, q;
    cin >> n >> m >> q;
    vector<Query> queries(q);
    vector<int> coord;
    for (auto &i : queries) {
        cin >> i.t >> i.x >> i.y;
        --i.x;
        coord.push_back(i.y);
    }
    coord.push_back(0);
    sort(all(coord));
    coord.resize(unique(all(coord)) - coord.begin());
    vector<int> a(n + 1, 0);
    vector<int> b(m + 1, 0);
    treeA = Fenwick(coord.size());
    treeB = Fenwick(coord.size());
    cntA = Fenwick(coord.size());
    cntB = Fenwick(coord.size());
    for (int i = 0; i < n; ++i) {
        cntA.upd(0, 1);
    }
    for (int i = 0; i < m; ++i) {
        cntB.upd(0, 1);
    }
    for (auto [t, x, y] : queries) {
        // int posY = lower_bound(all(coord), y) - coord.begin();
        if (t == 1) {
            int posNow = lower_bound(all(coord), a[x]) - coord.begin();
            ans -= cntB.get(posNow) * a[x];
            ans -= treeB.get(posNow + 1, coord.size() - 1);
            treeA.upd(posNow, -a[x]);
            cntA.upd(posNow, -1);
            a[x] = y;
            posNow = lower_bound(all(coord), a[x]) - coord.begin();
            treeA.upd(posNow, a[x]);
            cntA.upd(posNow, 1);
            ans += cntB.get(posNow) * a[x];
            ans += treeB.get(posNow + 1, coord.size() - 1);
        } else {
            int posNow = lower_bound(all(coord), b[x]) - coord.begin();
            ans -= cntA.get(posNow) * b[x];
            ans -= treeA.get(posNow + 1, coord.size() - 1);
            treeB.upd(posNow, -b[x]);
            cntB.upd(posNow, -1);
            b[x] = y;
            posNow = lower_bound(all(coord), b[x]) - coord.begin();
            treeB.upd(posNow, b[x]);
            cntB.upd(posNow, 1);
            ans += cntA.get(posNow) * b[x];
            ans += treeA.get(posNow + 1, coord.size() - 1);
        }
        cout << ans << '\n';
    }
    return 0;
}