#include <bits/stdc++.h>   using namespace std;   mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());   template <int modd>   struct modint {     static const int mod = modd;     int v;     explicit operator int() const { return v; }     modint() : v(0) {}     modint(long long x) : v(int(x % mod)) {       if (v < 0) v += mod;     }     friend bool operator==(const modint& a, const modint& b) {       return a.v == b.v;     }     friend bool operator!=(const modint& a, const modint& b) {       return a.v != b.v;     }     friend bool operator<(const modint& a, const modint& b) { return a.v < b.v; }     modint& operator+=(const modint& a) {       if ((v += a.v) >= mod) v -= mod;       return *this;     }     modint& operator-=(const modint& a) {       if ((v -= a.v) < 0) v += mod;       return *this;     }     modint& operator*=(const modint& a) {       v = int((long long)v * a.v % mod);       return *this;     }     modint& operator/=(const modint& a) { return (*this) *= inv(a); }     friend modint pow(modint a, long long p) {       modint ret = 1;       for (; p; p /= 2, a *= a) {         if (p & 1) ret *= a;       }       return ret;     }     friend modint inv(const modint& a) { return pow(a, mod - 2); }     modint operator-() const { return modint(-v); }     modint& operator++() { return *this += 1; }     modint& operator--() { return *this -= 1; }     friend modint operator+(modint a, const modint& b) { return a += b; }     friend modint operator-(modint a, const modint& b) { return a -= b; }     friend modint operator*(modint a, const modint& b) { return a *= b; }     friend modint operator/(modint a, const modint& b) { return a /= b; }     friend ostream& operator<<(ostream& out, modint a) { return out << a.v; }     friend istream& operator>>(istream& in, modint& a) {       long long b;       in >> b;       a.v = b;       return in;     }   };   using mint = modint<1000000007>;   struct change {     int* ptr;     int val, t;     change(int* p, int v, int tin) : ptr(p), val(v), t(tin) {}     void undo() { *ptr = val; }   };   struct dsu {     vector<int> v, len;     stack<change> st;     int ttime, ct;     dsu(int n) : v(n), len(n, 1), ttime(0), ct(n) { iota(v.begin(), v.end(), 0); }     void make_change(int* p, int val) {       change ch(p, *p, ttime);       st.push(ch);       *p = val;     }     void batch_undo() {       assert(!st.empty());       int tt = st.top().t;       while (((int)((st).size())) && st.top().t == tt) {         st.top().undo();         st.pop();       }     }     int root(int a) { return (v[a] == a ? a : root(v[a])); }     bool unite(int a, int b) {       ttime++;       int a1 = root(a), b1 = root(b);       if (a1 == b1) {         make_change(&v[0], v[0]);         return false;       }       make_change(&ct, ct - 1);       if (len[a1] < len[b1]) swap(a1, b1);       make_change(&len[a1], len[a1] + len[b1]);       make_change(&v[b1], a1);       return true;     }   };   const int mx = 5e5 + 5;   int n, m, k;   long long a[mx];   int main() {     ios::sync_with_stdio(0);     cin.tie(0);     cin >> n >> m >> k;     for (int q = 1; q <= n; q++) cin >> a[q];     vector<array<long long, 3>> v(m);     for (int q = 0; q < m; q++) {       cin >> v[q][1] >> v[q][2];       v[q][0] = a[v[q][1]] ^ a[v[q][2]];     }     sort(v.begin(), v.end());     int q = 0, tot = 0;     dsu d(n + 1);     mint ans = 0;     while (q < m) {       tot++;       int w = q;       while (w < m && v[w][0] == v[q][0]) {         d.unite(v[w][1], v[w][2]);         w++;       }       ans += pow(mint(2), d.ct - 1);       w = q;       while (w < m && v[w][0] == v[q][0]) {         d.batch_undo();         w++;       }       q = w;     }     ans += (pow(mint(2), k) - tot) * pow(mint(2), n);     cout << ans <<   n ;     return 0;   }