import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class Village_artur {

  static final int MAXN = 100100;

  static int n, id, k;
  static int[] a = new int[MAXN * 3], b = new int[MAXN], l = new int[MAXN], r = new int[MAXN];
  static Map<Integer, Boolean>[] graph = new HashMap[MAXN];

  static {
    for (int i = 0; i < MAXN; i++)
      graph[i] = new HashMap<Integer, Boolean>();
  }

  public static void main(String[] args) throws Exception {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

    while (true) {
      StringTokenizer str = new StringTokenizer(in.readLine());
      n = Integer.parseInt(str.nextToken());
      int m = Integer.parseInt(str.nextToken());
      int queries = Integer.parseInt(str.nextToken());

      if (n == 0 && m == 0 && queries == 0)
        break;

      for (int i = 0; i < n; i++) {
        a[i] = b[i] = -1;
        graph[i].clear();
      }

      for (int i = 0; i < m; i++) {
        str = new StringTokenizer(in.readLine());
        int p = Integer.parseInt(str.nextToken()) - 1;
        int q = Integer.parseInt(str.nextToken()) - 1;
        if (graph[p].containsKey(q))
          graph[p].put(q, false);
        else
          graph[p].put(q, null);
        if (graph[q].containsKey(p))
          graph[q].put(p, false);
        else
          graph[q].put(p, null);
      }

      k = 0;
      find_bridges(0, -1);

      k = 0;
      id = 0;
      for (int i = 0; i < n; i++) {
        a[i] = r[i] = -1;
        l[i] = n;
      }
      color_components(0, id++);

      Arrays.fill(a, 0);
      for (int query = 0; query < queries; query++) {
        str = new StringTokenizer(in.readLine());
        if ("+".equals(str.nextToken())) {
          id = Integer.parseInt(str.nextToken()) - 1;
          k = Integer.parseInt(str.nextToken());
          increment(0, 0, n - 1, l[b[id]], r[b[id]]);
        } else {
          id = l[b[Integer.parseInt(str.nextToken()) - 1]];
          System.out.println(query(0, 0, n - 1));
        }
      }
    }
  }

  static void color_components(int i, int color) {
    b[i] = color;
    a[i] = k++;
    l[color] = Math.min(l[color], a[i]);
    r[color] = Math.max(r[color], a[i]);
    for (int j : graph[i].keySet())
      if (a[j] == -1)
        if (graph[i].get(j) != Boolean.TRUE)
          color_components(j, color);
        else {
          int newcolor = id++;
          color_components(j, newcolor);
          r[color] = Math.max(r[color], r[newcolor]);
        }
  }

  static void find_bridges(int i, int parent) {
    a[i] = b[i] = ++k;
    for (int j : graph[i].keySet())
      if (j != parent)
        if (a[j] == -1) {
          find_bridges(j, i);
          b[i] = Math.min(b[i], b[j]);
        } else
          b[i] = Math.min(b[i], a[j]);

    if (parent != -1 && a[i] == b[i] && graph[i].get(parent) == null) {
      graph[i].put(parent, true);
      graph[parent].put(i, true);
    }
  }

  static int query(int node, int left, int right) {
    if (left == id && right == id)
      return a[node];

    int mid = (left + right) / 2;
    if (id > mid)
      return query(2 * node + 2, mid + 1, right) + a[node];
    else
      return query(2 * node + 1, left, mid) + a[node];
  }

  static void increment(int node, int left, int right, int begin, int end) {
    if (left > end || begin > right)
      return;

    if (left == begin && end == right)
      a[node] += k;
    else {
      int mid = (left + right) / 2;
      increment(2 * node + 1, left, mid, begin, Math.min(end, mid));
      increment(2 * node + 2, mid + 1, right, Math.max(begin, mid + 1), end);
    }
  }
}
