#include <bits/stdc++.h>
using namespace std;
template <typename S, typename T>
ostream& operator<<(ostream& out, pair<S, T> const& p) {
  out << '(' << p.first << ", " << p.second << ')';
  return out;
}
template <typename T>
ostream& operator<<(ostream& out, vector<T> const& v) {
  long long l = v.size();
  for (long long i = 0; i < l - 1; i++) out << v[i] << ' ';
  if (l > 0) out << v[l - 1];
  return out;
}
template <typename T>
void trace(const char* name, T&& arg1) {
  cout << name << " : " << arg1 << "\n";
}
template <typename T, typename... Args>
void trace(const char* names, T&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  cout.write(names, comma - names) << " : " << arg1 << " | ";
  trace(comma + 1, args...);
}
const long long N = 5e5 + 100;
const long long MOD = 1e9 + 7;
long long power(long long x, long long t) {
  long long ans = 1;
  while (t > 0) {
    if (t & 1) ans = 1LL * ans * x % MOD;
    x = 1LL * x * x % MOD;
    t >>= 1;
  }
  return ans;
}
long long n, m, k;
long long arr[N];
vector<vector<long long> > g(N);
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n >> m >> k;
  for (long long i = 1; i <= n; i++) {
    cin >> arr[i];
  }
  map<long long, set<long long> > cnt;
  map<long long, vector<pair<long long, long long> > > edg;
  for (long long i = 1; i <= m; i++) {
    long long v, u;
    cin >> v >> u;
    g[v].push_back(u), g[u].push_back(v);
    long long x = arr[v] ^ arr[u];
    cnt[x].insert(v);
    cnt[x].insert(u);
    edg[x].push_back({v, u});
  }
  long long free = (1LL << k) - (long long)cnt.size();
  long long ans = 0;
  ans = ((free % MOD) * (power(2, n) % MOD)) % MOD;
  for (auto& i : cnt) {
    long long no = i.first;
    long long lol = i.second.size();
    vector<long long> w;
    w.insert(w.begin(), i.second.begin(), i.second.end());
    vector<long long> p, sz;
    for (long long i = 0; i < lol; i++) {
      p.push_back(i);
      sz.push_back(1);
    }
    function<long long(long long)> find;
    find = [&p, &find](long long a) -> long long {
      if (p[a] == a) {
        return a;
      }
      return p[a] = find(p[a]);
    };
    function<void(long long, long long)> union_sets;
    union_sets = [&p, &sz, &union_sets, &find](long long a,
                                               long long b) -> void {
      a = find(a);
      b = find(b);
      if (a != b) {
        if (sz[a] < sz[b]) {
          swap(a, b);
        }
        p[b] = a;
        sz[a] += sz[b];
      }
    };
    long long tot = n;
    for (auto e : edg[no]) {
      long long a = lower_bound(w.begin(), w.end(), e.first) - w.begin();
      long long b = lower_bound(w.begin(), w.end(), e.second) - w.begin();
      a = find(a);
      b = find(b);
      if (a != b) {
        union_sets(a, b);
        tot--;
      }
    }
    ans = (ans + power(2, tot)) % MOD;
  }
  cout << ans << "\n";
}
