#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << (x) << '\n'
#define debugArray(x, n)                                      \
  cerr << __LINE__ << ": " << #x << " = {";                   \
  for (long long hoge = 0; (hoge) < (long long)(n); ++(hoge)) \
    cerr << ((hoge) ? "," : "") << x[hoge];                   \
  cerr << "}" << '\n'
#define debugMatrix(x, h, w)                                         \
  cerr << __LINE__ << ": " << #x << " =\n";                          \
  for (long long hoge = 0; (hoge) < (long long)(h); ++(hoge)) {      \
    cerr << ((hoge ? " {" : "{{"));                                  \
    for (long long fuga = 0; (fuga) < (long long)(w); ++(fuga))      \
      cerr << ((fuga ? ", " : "")) << x[hoge][fuga];                 \
    cerr << "}" << (hoge + 1 == (long long)(h) ? "}" : ",") << '\n'; \
  }
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#define debugMatrix(x, h, w) (void(0))
#endif

template <typename T>
struct BinaryIndexedTree {
  std::vector<T> dat;
  BinaryIndexedTree(int n) : dat(n + 1, T(0)) {}
  BinaryIndexedTree(int n, T a) : BinaryIndexedTree(std::vector<T>(n, a)) {}
  BinaryIndexedTree(std::vector<T> y) : dat(y.size() + 1, 0) {
    for (size_t i = 0; i < y.size(); ++i) dat[i + 1] = y[i];
    for (int i = 1; i < (int)dat.size(); ++i)
      if (i + (i & -i) < (int)dat.size()) dat[i + (i & -i)] += dat[i];
  }
  void add(int i, T a = 1) {
    for (++i; i < (int)dat.size(); i += i & -i) dat[i] += a;
  }
  T sum(int i) {  // sum [0,i)
    T s = 0;
    for (; i > 0; i &= i - 1) s += dat[i];
    return s;
  }
  // sum [l,r)
  T sum(int l, int r) { return sum(r) - sum(l); }
  T operator[](size_t k) { return sum(k + 1) - sum(k); }
  // min { i : sum(i+1) > k } -> kth element(0-indexed)
  int find(T k) const {
    int i = 0;
    for (int p = 1 << (std::__lg(dat.size() - 1) + 1); p > 0; p >>= 1)
      if (i + p < (int)dat.size() && dat[i + p] <= k) k -= dat[i += p];
    return i + 1 == (int)dat.size() ? -1 : i;  // -1 -> no solutions
  }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  int N, M, Q;
  cin >> N >> M >> Q;
  const int MAX_Y = 1e6;
  BinaryIndexedTree<long long> bita1(MAX_Y), bita2(MAX_Y), bitb1(MAX_Y),
      bitb2(MAX_Y);
  for (int i = 0; i < N; i++) bita1.add(0);
  for (int i = 0; i < M; i++) bitb1.add(0);
  long long ans = 0;
  long long a[N] = {}, b[M] = {};
  int T[Q], X[Q], Y[Q];
  for (int i = 0; i < Q; i++) cin >> T[i] >> X[i] >> Y[i];
  vector<int> v(Y, Y + Q);
  v.emplace_back(0);
  sort(begin(v), end(v));
  v.erase(unique(begin(v), end(v)), end(v));
  auto zip = [&](int hoge) {
    return lower_bound(begin(v), end(v), hoge) - begin(v);
  };
  for (int i = 0; i < Q; i++) {
    int t = T[i], x = X[i] - 1;
    if (t == 1) {
      ans -= a[x] * bitb1.sum(zip(a[x]));
      ans -= bitb2.sum(zip(a[x]), MAX_Y);
      ans += Y[i] * bitb1.sum(zip(Y[i]));
      ans += bitb2.sum(zip(Y[i]), MAX_Y);
      bita1.add(zip(a[x]), -1);
      bita2.add(zip(a[x]), -a[x]);
      bita1.add(zip(Y[i]), 1);
      bita2.add(zip(Y[i]), Y[i]);
      a[x] = Y[i];
    } else {
      ans -= b[x] * bita1.sum(zip(b[x]));
      ans -= bita2.sum(zip(b[x]), MAX_Y);
      ans += Y[i] * bita1.sum(zip(Y[i]));
      ans += bita2.sum(zip(Y[i]), MAX_Y);
      bitb1.add(zip(b[x]), -1);
      bitb2.add(zip(b[x]), -b[x]);
      bitb1.add(zip(Y[i]), 1);
      bitb2.add(zip(Y[i]), Y[i]);
      b[x] = Y[i];
    }
    cout << ans << '\n';
  }
  return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int sz = 105, mod = 1e9+7;

struct matrix {
   int n, v[sz][sz];

   matrix(int n) : n(n) {
      memset(v, 0, sizeof(v));
   }

   matrix operator *(const matrix &b) {
      matrix ans = matrix(n);
      for(int k=0; k<n; k++) {
         for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
               int &w = ans.v[i][j];
               w += (ll) v[i][k] * b.v[k][j] % mod;
               w >= mod ? w -= mod : 1;
            }
         }
      }
      return ans;
   }

   matrix operator ^(ll p) {
      matrix ans = matrix(n), b = *this;
      for(int i=0; i<n; i++) ans.v[i][i] = 1;

      while(p) {
         if(p & 1) ans = ans * b;
         p >>= 1;
         b = b * b;
      }
      return ans;
   }
};


ll bigmod(ll b, ll n) {
   if(n == -1) n = mod - 2;
   ll ans = 1;
   while(n) {
      if(n & 1) ans = ans * b % mod;
      n >>= 1;
      b = b * b % mod;
   }
   return ans;
}

ll a[sz];
bool g[sz][sz];

int main() {
   int n, m, k;
   cin >> n >> m >> k;
   for(int i=0; i<n; i++) cin >> a[i];
   matrix mat(n);
   ll two = bigmod(2, -1), minv = bigmod(m, -1);
   for(int i=0; i<m; i++) {
      int u, v;
      scanf("%d %d", &u, &v);
      u--, v--;
      g[u][v] = g[v][u] = 1;
   }
   for(int i=0; i<n; i++) {
      int c = 0;
      for(int j=0; j<n; j++) c += g[i][j];
      mat.v[i][i] = ((m - c) * minv + c * minv % mod * two) % mod;
      for(int j=0; j<n; j++) {
         if(g[i][j]) mat.v[i][j] = minv * two % mod;
      }
   }
   mat = mat ^ k;
   for(int i=0; i<n; i++) {
      ll ans = 0;
      for(int j=0; j<n; j++) ans += mat.v[i][j] * a[j] % mod;
      printf("%lld\n", ans % mod);
   }
}
