#include <bits/stdc++.h>
using namespace std;
map<long long, vector<pair<int, int>>> vec;
const long long NMAX = 500010;
long long p2[NMAX];
namespace UF {
long long tata[NMAX];
long long g[NMAX];
long long nrc;
vector<int> op;
long long find(long long x) {
  if (tata[tata[x]] != tata[x]) tata[x] = find(tata[x]);
  return tata[x];
}
void unite(long long a, long long b) {
  a = find(a);
  b = find(b);
  if (a == b) return;
  if (g[a] < g[b]) swap(a, b);
  tata[b] = a, g[a] += g[b];
  nrc--;
}
}  // namespace UF
long long key[NMAX];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long n, m, a, b, k;
  cin >> n >> m >> k;
  p2[0] = 1;
  for (long long i = 1; i <= n; i++) cin >> key[i];
  for (long long i = 1; i <= max(n, m); i++) p2[i] = 2 * p2[i - 1] % 1000000007;
  for (long long i = 1; i <= m; i++) {
    cin >> a >> b;
    long long x = key[a] ^ key[b];
    vec[x].push_back({a, b});
  }
  long long valok = ((1LL << k) - vec.size()) % 1000000007;
  long long ans = 1LL * valok * p2[n] % 1000000007;
  for (auto& i : vec) {
    auto& adia = i.second;
    for (auto j : adia)
      UF::g[j.first] = UF::g[j.second] = 1, UF::tata[j.first] = j.first,
      UF::tata[j.second] = j.second;
    UF::nrc = n;
    for (auto j : adia) UF::unite(j.first, j.second);
    long long nrm = p2[UF::nrc];
    ans = (ans + nrm) % 1000000007;
  }
  cout << ans << '\n';
  return 0;
}
