#include<bits/stdc++.h>
using namespace std;
int n,m,k,x[114514],y[114514],c[114514],f[2],fa[200001],val[200001];
//f:是否进行 fa:带权并查集父亲 val:带权并查集权值
const int mod=1e9;//模数
int find(int x)
{
if(x==fa[x])return x;
val[x]^=val[fa[x]];
return fa[x]=find(fa[x]);
}
int rma()
{
for(int i=1;i<=n+m;i++)fa[i]=i;
fa[n+1]=1;//差点被坑……n+1和1是一个点!!!!!!
for(int i=1;i<=k;i++)
{
int fax=find(x[i]),fay=find(y[i]+n);//找出x和y的祖先
if(fax!=fay)//合并
{
fa[fax]=fay;
val[fax]=val[x[i]]^val[y[i]+n]^c[i];//这个脑瘫没有异或上c[i]调了半个小时
}
else if(val[x[i]]^val[y[i]+n]^c[i])return 0;//不要忘记矛盾情况虽然我没有忘记
}
int res=-114514;//统计答案
for(int i=1;i<=n+m;i++)
{
if(fa[i]==i)
{
if(res==-114514)res=1;//记得减去(1,1)对应的连通块
else
{
res*=2;
res%=mod;
}
}
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int ans=0;
cin>>n>>m>>k;
f[0]=f[1]=1;
for(int i=1;i<=k;i++)
{
cin>>x[i]>>y[i]>>c[i];
if(x[i]==1&&y[i]==1)f[c[i]^1]=0;//标记是否进行
if(x[i]%2==0&&y[i]%2==0)c[i]^=1;//为了以后方便处理
}
if(f[0])ans+=rma();
if(f[1])
{
for(int i=1;i<=k;i++)
if(x[i]!=1&&y[i]!=1)c[i]^=1;//异或1正好取反
ans+=rma();
}
cout<<ans%mod;
return 0;
}