#include <bits/stdc++.h>
using namespace std;
const int INPUT_MAXCHARS = 1 << 16;
char buffer[INPUT_MAXCHARS];
struct FastReader {
  char *p;
  FastReader() : p(buffer) { fread(buffer, 1, sizeof buffer, stdin); }
  int next_int() { return int(next_ll()); }
  long long next_ll() {
    upd();
    long long sgn = 1;
    while (*p < '0') {
      if (*p++ == '-') {
        sgn = -1;
        break;
      }
    }
    long long val = 0;
    while (*p >= '0') {
      val = val * 10 + (*p - '0');
      ++p;
    }
    return sgn * val;
  }
  char next_char() {
    upd();
    while (*p != '?' && *p != '+') {
      ++p;
    }
    return *p++;
  }

 private:
  void upd() {
    int remchars = INPUT_MAXCHARS - (p - buffer);
    if (remchars < 25) {
      memcpy(buffer, p, remchars);
      size_t cnt = fread(buffer + remchars, 1, sizeof buffer - remchars, stdin);
      if (remchars + cnt < sizeof buffer) {
        buffer[remchars + cnt] = 0;
      }
      p = buffer;
    }
  }
};
const int MAXN = 100000;
int heavyidx[MAXN];
int heavies[MAXN];
long long h_total[MAXN];
long long h_add[MAXN];
int setsz[MAXN];
int sqrtn;
long long A[MAXN];
const int MAXH = 350;
bool h_in[MAXH][MAXN];
int h_intersectsz[MAXN][MAXH];
int main() {
  ios::sync_with_stdio(false);
  FastReader reader;
  int n = reader.next_int();
  sqrtn = int(sqrt(n));
  int m = reader.next_int();
  int Q = reader.next_int();
  for (int i = 0; i < n; ++i) {
    A[i] = reader.next_int();
  }
  memset(heavyidx, 0xff, sizeof heavyidx);
  int nheavy = 0;
  vector<vector<int> > sets(m);
  for (int i = 0; i < m; ++i) {
    setsz[i] = reader.next_int();
    sets[i].reserve(setsz[i]);
    if (setsz[i] > sqrtn) {
      heavies[nheavy] = i;
      heavyidx[i] = nheavy++;
    }
    for (int j = 0; j < setsz[i]; ++j) {
      int x = reader.next_int() - 1;
      sets[i].push_back(x);
    }
    sort(sets[i].begin(), sets[i].end());
  }
  assert(nheavy <= MAXH);
  for (int h = 0; h < nheavy; ++h) {
    int i = heavies[h];
    for (int j = 0; j < (int)sets[i].size(); ++j) {
      int pos = sets[i][j];
      h_in[h][pos] = 1;
      h_total[h] += A[pos];
    }
  }
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < (int)sets[i].size(); ++j) {
      for (int h = 0; h < nheavy; ++h) {
        if (h_in[h][sets[i][j]]) {
          ++h_intersectsz[i][h];
        }
      }
    }
  }
  while (Q--) {
    char op = reader.next_char();
    if (op == '?') {
      int s = reader.next_int() - 1;
      long long sol = 0;
      if (heavyidx[s] == -1) {
        for (int i = 0; i < (int)sets[s].size(); ++i) {
          sol += A[sets[s][i]];
        }
        for (int h = 0; h < nheavy; ++h) {
          sol += h_intersectsz[s][h] * h_add[h];
        }
      } else {
        sol = h_total[heavyidx[s]];
        for (int h = 0; h < nheavy; ++h) {
          sol += h_intersectsz[s][h] * h_add[h];
        }
      }
      printf("%I64d\n", sol);
    } else {
      assert(op == '+');
      int s = reader.next_int() - 1;
      int add = reader.next_int();
      if (heavyidx[s] == -1) {
        for (int i = 0; i < (int)sets[s].size(); ++i) {
          A[sets[s][i]] += add;
        }
        for (int h = 0; h < nheavy; ++h) {
          h_total[h] += h_intersectsz[s][h] * add;
        }
      } else {
        h_add[heavyidx[s]] += add;
      }
    }
  }
  return 0;
}
