#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <math.h>
#include <cassert>
#define rep(i,n) for(int i = 0; i < n; ++i )
using namespace std;
using ll = long long;
// auto mod int
const int mod = 1000000007;
struct mint {
  ll x; // typedef long long ll;
  mint(ll x=0):x((x%mod+mod)%mod){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {if ((x += a.x) >= mod) x -= mod; return *this;}
  mint& operator-=(const mint a) {if ((x += mod-a.x) >= mod) x -= mod; return *this;}
  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }
  // for prime mod
  mint inv() const { return pow(mod-2);}
  mint& operator/=(const mint a) { return *this *= a.inv();}
  mint operator/(const mint a) const { return mint(*this) /= a;}
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

struct E{
  vector<mint> v;
  E(int n):v(n){}
};
const mint i2 = mint(1)/2;
int main() {
  int n,m,k;
  cin >> n >> m >> k;
  vector<ll> a(n);
  rep(i,n) cin >> a[i];
  vector<vector<E>> x(1,vector<E>(n,E(n)));
  auto& x0 = x[0];
  rep(i,n) x0[i].v[i] = m;
  rep(i,m){
    int u,v;
    cin >> u >> v;
    --u,--v;
    x0[u].v[u] -= i2;
    x0[u].v[v] += i2;
    x0[v].v[u] += i2;
    x0[v].v[v] -= i2;
  }
  for(int p=1;k>>p;++p){
    x.emplace_back(n,E(n));
    auto &u = x[p-1], &v = x[p];
    rep(k,n){
      auto& e = u[k].v;
      rep(i,n)rep(j,n){
        v[k].v[j] += e[i]*u[i].v[j];
      }
    }
  }
  mint im = mint(1)/m;
  im = im.pow(k);
  rep(u,n){
    vector<mint> s(n);
    s[u] = 1;
    for(int p=0;k>>p;++p)if(k>>p&1){
      auto& xi = x[p];
      vector<mint> t(n);
      rep(i,n)rep(j,n){
        t[j] += s[i]*xi[i].v[j];
      }
      swap(s,t);
    }
    mint ans;
    rep(i,n) ans += s[i]*a[i];
    ans *= im;
    printf("%lld\n",ans.x);
  }
}

// g++ -std=c++11 a.cpp
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<unordered_map>
#include<utility>
#include<cmath>
#include<random>
#include<cstring>
#include<queue>
#include<stack>
#include<bitset>
#include<cstdio>
#include<sstream>
#include<random>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(int i=a;i<b;i++)
#define rep(i,a) loop(i,0,a)
#define FOR(i,a) for(auto i:a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
#define show1d(v) {rep(_,v.size())cout<<" "<<v[_];cout<<endl;}
#define show2d(v) {rep(__,v.size())show1d(v[__]);}
using namespace std;
//kaewasuretyuui
typedef long long ll;
#define int ll
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
#define mt make_tuple
typedef tuple<int,int,int> tp;
typedef vector<tp> vt;
typedef vector<vt>vvt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
const double PI=acos(-1);
const long double EPS=1e-9;
Def inf = sizeof(Def) == sizeof(long long) ? 2e18 : 1e9+10;
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
#define yes cout<<"Yes\n"
#define no cout<<"No\n"

typedef int SegT;
const SegT defvalue=0;
class SegTree{
	private:
		vector<SegT>val;
		int n;
		SegT combine(SegT a,SegT b){return a^b;}
	public:
		SegTree(int size){
			n=1;
			while(n<size)n<<=1;
			val=vector<SegT>(2*n,defvalue);
		}
		SegTree(const vector<SegT> &in){
			n=1;
			while(n<in.size())n<<=1;
			val=vector<SegT>(2*n,defvalue);
			for(int i=n-1+in.size()-1;i>=0;i--){
				if(n-1<=i)val[i]=in[i-(n-1)];
				else val[i]=combine(val[i*2+1],val[i*2+2]);
			}
		}
		void update(int i,SegT a){
			i+=n-1;
			val[i]^=a;
			while(i>0){
				i=(i-1)/2;
				val[i]=combine(val[i*2+1],val[i*2+2]);
			}
		}
		SegT query(int a,int b,int k=0,int l=0,int r=-1){//[a,b)
			if(r==-1)r=n;
			if(r<=a||b<=l)return defvalue;
			if(a<=l&&r<=b)return val[k];
			else return combine(query(a,b,k*2+1,l,(l+r)/2),query(a,b,k*2+2,(l+r)/2,r));
		}
		void tmp(){
			rep(i,val.size())cout<<" "<<val[i];cout<<endl;
		}
};

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n,q;
	cin>>n>>q;
	SegTree st(n);
	rep(i,n){
		int a;cin>>a;
		st.update(i,a);
	}
	while(q--){
		int t,x,y;
		cin>>t>>x>>y;
		if(t==1){
			st.update(x-1,y);
		}else{
			cout<<st.query(x-1,y)<<endl;
		}
	}
}
