#include <bits/stdc++.h>
using LL = long long;
using ULL = unsigned long long;
using namespace std;
struct Edge {
  int x, y;
  Edge(int x, int y) {
    this->x = x;
    this->y = y;
  }
};
struct ModLL {
  static const LL MOD = 1e9 + 7;

 public:
  ModLL(LL val = 0) { this->val = val % MOD; }
  ModLL& operator+=(const ModLL& x) {
    val = (val + x.getVal()) % MOD;
    return *this;
  }
  ModLL& operator+=(LL x) {
    val = (val + x) % MOD;
    return *this;
  }
  ModLL& operator*=(LL x) {
    val = (val * x) % MOD;
    return *this;
  }
  ModLL& operator*=(const ModLL& x) {
    val = (val * x.getVal()) % MOD;
    return *this;
  }
  LL getVal() const { return val; }

 private:
  LL val;
};
ModLL getPow2(int e) {
  ModLL p = 2;
  ModLL ans = 1;
  while (e > 0) {
    if (e & 1) {
      ans *= p;
    }
    p *= p;
    e >>= 1;
  }
  return ans;
}
struct DSU {
  DSU(int n) : parent(n) {
    setsCount = n;
    std::iota(parent.begin(), parent.end(), 0);
  }
  int getSetsCount() const { return setsCount; }
  void reset() {
    for (const auto i : used) {
      parent[i] = i;
    }
    setsCount = parent.size();
    used.clear();
  }
  void join(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) {
      return;
    }
    used.push_back(x);
    setsCount--;
    parent[x] = y;
  }
  int find(int x) {
    if (x == parent[x]) {
      return x;
    }
    used.push_back(x);
    return parent[x] = find(parent[x]);
  }

 private:
  std::vector<int> parent;
  std::vector<int> used;
  int setsCount;
};
std::unordered_map<ULL, std::vector<Edge>> edges;
int main() {
  std::ios_base::sync_with_stdio(false);
  int n, m, k;
  std::cin >> n >> m >> k;
  std::vector<ULL> v(n);
  for (int i = 0; i < n; ++i) {
    std::cin >> v[i];
  }
  for (int i = 0; i < m; ++i) {
    int x, y;
    std::cin >> x >> y;
    x--;
    y--;
    LL val = v[x] ^ v[y];
    edges[val].emplace_back(x, y);
  }
  ModLL ans = 0;
  DSU dsu(n);
  for (const auto& kv : edges) {
    const std::vector<Edge>& curr = kv.second;
    dsu.reset();
    for (const auto& edge : curr) {
      dsu.join(edge.x, edge.y);
    }
    ans += getPow2(dsu.getSetsCount());
  }
  ModLL rest = (1LL << k) - edges.size();
  rest *= getPow2(n);
  ans += rest;
  std::cout << ans.getVal() << '\n';
  return 0;
}
