#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 7;
const int MX = 1e9 + 7;
int n, m, a, b;
vector <int> G[N];
bool vis[N];
bool reached[N];
int nr[N];
vector <int> reachable;
vector <int> canReach[N];
void dfs(int u){
vis[u] = true;
for(auto v: G[u])
if(!vis[v])
dfs(v);
}
int calc(){
int ret = 0;
int _n = reachable.size();
for(int i = 1; i < (1 << _n); ++i){
auto is = [&](int v) -> bool{
return (i & (1 << v)) > 0;
};
bool ok = true;
for(int j = 1; j <= a; ++j){
bool good = false;
for(auto u: canReach[j])
if(is(nr[u])){
good = true;
break;
}
if(!good){
ok = false;
break;
}
}
ret += ok;
}
return ret;
}
int main(){
scanf("%d %d %d %d", &n, &m, &a, &b);
for(int i = 1; i <= m; ++i){
int u, v;
char s[5];
scanf("%d %s %d", &u, s, &v);
G[u].push_back(v);
if(s[1] == '-')
G[v].push_back(u);
}
for(int i = 1; i <= a; ++i){
for(int j = 1; j <= n; ++j)
vis[j] = false;
dfs(i);
for(int j = a + 1; j <= a + b; ++j)
if(vis[j]){
canReach[i].push_back(j);
reached[j] = true;
}
}
for(int i = a + 1; i <= a + b; ++i)
if(reached[i]){
nr[i] = reachable.size();
reachable.push_back(i);
}
int ans = calc();
for(int i = a + 1; i <= a + b; ++i)
if(!reached[i])
ans = (ans + ans) % MX;
printf("%d\n", ans);
return 0;
}