#include<cstdio> usingnamespace std; template <classType> voidread(Type &x) { char c; while ((c = getchar()) < '0' || c > '9'); x = c - '0'; while ((c = getchar()) >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0'; } template <classType, class ...rest> voidread(Type &x, rest &...y){ read(x), read(y...); } template <classType> voidwrite(Type x) { if (x < 0) putchar('-'), x = ~x + 1; if (x > 9) write(x / 10); putchar(x % 10 + '0'); } typedeflonglong LL; constint N = 1e5 + 10, mod = 1e9; intbinpow(int b, int k) { int res = 1; for (; k; b = (LL)b * b % mod, k >>= 1) if (k & 1) res = (LL)res * b % mod; return res; } bool d[N << 1]; int n, m, q, p[N << 1]; intfa(int x) { if (p[x] == x) return x; int t = p[x]; p[x] = fa(p[x]); d[x] ^= d[t]; return p[x]; } structOP {int x, y; bool v; } o[N]; intcalc(bool v) { for (int i = 1; i < n + m; ++i) p[i] = i, d[i] = 0; for (int i = 1; i <= q; ++i) { int a = o[i].x, b = o[i].y == 1 ? 1 : o[i].y + n - 1; if (a == 1 && b == 1) continue; int x = fa(a), y = fa(b); if (x == y) { if (d[a] ^ d[b] ^ v ^ o[i].v) return0; } else p[x] = y, d[x] ^= o[i].v ^ v ^ d[a] ^ d[b]; } int res = 0; for (int i = 1; i < n + m; ++i) res += fa(i) == i; returnbinpow(2, res - 1); } intmain() { read(n, m, q); int flag = -1; for (int i = 1; i <= q; ++i) { read(o[i].x, o[i].y, o[i].v); o[i].v ^= (o[i].x | o[i].y) & 1; if (o[i].x == 1 && o[i].y == 1) flag = o[i].v; } write(~flag ? calc(flag) : (calc(0) + calc(1)) % mod); return0; }