#include <bits/stdc++.h>
using namespace std;
int n, m, q, cnt, tot, block, head[100005], id[100005], f[100005][400];
long long a[100005], sum[400], add[400];
bool g[400][100005];
struct edge_type {
  int next, to;
} e[100005];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void add_edge(int x, int y) {
  e[++cnt] = (edge_type){head[x], y};
  head[x] = cnt;
}
int main() {
  n = read();
  m = read();
  q = read();
  block = ceil(sqrt(100000));
  for (int i = 1; i <= n; i++) a[i] = read();
  for (int i = 1; i <= m; i++) {
    int sz = read();
    if (sz >= block) id[i] = ++tot;
    while (sz--) {
      int x = read();
      if (id[i]) g[tot][x] = true;
      add_edge(i, x);
    }
  }
  for (int i = 1; i <= m; i++)
    for (int j = 1; j <= tot; j++)
      for (int k = head[i]; k; k = e[k].next)
        if (g[j][e[k].to]) f[i][j]++;
  for (int i = 1; i <= m; i++)
    if (id[i])
      for (int j = head[i]; j; j = e[j].next) sum[id[i]] += a[e[j].to];
  while (q--) {
    char ch = getchar();
    while (ch != '?' && ch != '+') ch = getchar();
    if (ch == '?') {
      int x = read();
      if (id[x])
        printf("%I64d\n", sum[id[x]]);
      else {
        long long ans = 0;
        for (int i = head[x]; i; i = e[i].next) ans += a[e[i].to];
        for (int i = 1; i <= tot; i++) ans += add[i] * f[x][i];
        printf("%I64d\n", ans);
      }
    } else {
      int x = read(), y = read();
      for (int i = 1; i <= tot; i++) sum[i] += (long long)y * f[x][i];
      if (id[x])
        add[id[x]] += y;
      else
        for (int i = head[x]; i; i = e[i].next) a[e[i].to] += y;
    }
  }
}
