175_F. Gnomes of Might and Magic_32205
Vasya plays a popular game the Gnomes of Might and Magic.

In this game Vasya manages the kingdom of gnomes, consisting of several castles, connected by bidirectional roads. The kingdom road network has a special form. The kingdom has m main castles a1, a2, ..., am, which form the Good Path. This path consists of roads between the castles ai, ai + 1 (1 ≤ i < m) as well as the road between am and a1. There are no other roads between the castles of the Good Path.

In addition, for each pair of neighboring Good Path castles u and v there is exactly one Evil Shortcut — a path that goes along the roads leading from the first castle (u) to the second one (v) and not having any common vertexes with the Good Path except for the vertexes u and v. It is known that there are no other roads and castles in the kingdom there, that is, every road and every castle lies either on the Good Path or the Evil Shortcut (castles can lie in both of them). In addition, no two Evil Shortcuts have any common castles, different than the castles of the Good Path.

At the beginning of each week in the kingdom appears one very bad gnome who stands on one of the roads of the kingdom, and begins to rob the corovans going through this road. One road may accumulate multiple very bad gnomes. Vasya cares about his corovans, so sometimes he sends the Mission of Death from one castle to another.

Let's suggest that the Mission of Death should get from castle s to castle t. Then it will move from castle s to castle t, destroying all very bad gnomes, which are on the roads of the Mission's path. Vasya is so tough that his Mission of Death can destroy any number of gnomes on its way. However, Vasya is very kind, so he always chooses such path between castles s and t, following which he will destroy the smallest number of gnomes. If there are multiple such paths, then Vasya chooses the path that contains the smallest number of roads among them. If there are multiple such paths still, Vasya chooses the lexicographically minimal one among them.

Help Vasya to simulate the life of the kingdom in the Gnomes of Might and Magic game.

A path is a sequence of castles, such that each pair of the neighboring castles on the path is connected by a road. Also, path x1, x2, ... , xp is lexicographically less than path y1, y2, ... , yq, if either p < q and x1 = y1, x2 = y2, ... , xp = yp, or exists such number r (r < p, r < q), that x1 = y1, x2 = y2, ... , xr = yr and xr + 1 < yr + 1.

Input

The first line contains two integers n and m (3 ≤ m ≤ n ≤ 100000) — the number of castles in the kingdom, and the number of castles on the Good Path, respectively.

The second line contains m integers, which are numbers of Good Path castles (the castles are numbered from 1 to n) in the order of occurrence on the Path, starting with some castle. All Good Path castles are different.

Each of the following m lines describes an Evil Shortcut. First a line contains an integer ki (3 ≤ ki ≤ 100000) — the number of castles on the corresponding Evil Shortcut (with the two castles which are on the Good Path), followed by a ki integers — number of castles in the order of occurrence in the given Shortcut. All castles in one Evil Shortcut are different. It is guaranteed that the first and the last castles from the Shortcut are on the Good Path and the first castles in the Evil Shortcuts form the Good Path and are presented in the same order in which the Path was represented on the second line.

The next line contains an integer q (1 ≤ q ≤ 100000) — the number of events in the life of the kingdom. Each of the following q lines describes a single event. An event is described by the symbol cj and two numbers or castles sj and tj (the character and numbers of castles are separated by a single space). If the character of cj is equal to "+" (a plus), it means that a very bad gnome (probably not the first one) has appeared on the road between castles sj and tj. If cj equals "?" (a question), then Vasya sent a Mission of Death from castle sj to castle tj. It is guaranteed that for each request "+", the road between castles sj and tj exists. The events are given in chronological order, starting with the earliest one. Initially there are no very bad gnomes on the roads.

All numbers in all lines are separated by single spaces. It is guaranteed that all the given Evil Shortcuts and Good Path fit in the limitations given in the problem statement.

Output

For each query "?" print a single number on a single line — the number of very bad gnomes destroyed by the corresponding Mission of Death. Print the answers to queries in the chronological order.

Examples

Input

6 3
1 2 3
3 1 4 2
3 2 5 3
3 3 6 1
10
+ 1 2
+ 4 2
+ 1 3
+ 2 3
? 1 2
+ 2 5
? 1 2
? 1 2
+ 1 2
? 1 2


Output

0
1
0
1

Note

In the example after the first four requests there is only one path from castle 1 to castle 2, which does not contain roads with very bad gnomes: 1 <image> 6 <image> 3 <image> 5 <image> 2.

After a gnome stood on the road (2, 5), the next Mission of Death moves along path 1 <image> 2, and destroys the gnome, who was on the road (1, 2). The next Mission of Death follows the same path which is already free of gnomes.

After yet another gnome stood on the road (1, 2), the next Mission of Death goes on the path 1 <image> 2, and kills the gnome.
#include <bits/stdc++.h>
using namespace std;
struct w {
  int sum, x, y, len;
  inline bool operator<(const w &A) const {
    if (sum < A.sum) return 1;
    if (sum > A.sum) return 0;
    if (len < A.len) return 1;
    if (len > A.len) return 0;
    return x < A.x || x == A.x && y < A.y;
  }
  inline bool operator==(const w &A) const {
    return sum == A.sum && x == A.x && y == A.y && len == A.len;
  }
};
struct ww {
  int l, r, c;
  w a[2];
} tr[200010 * 4], kong;
int i, j, k, n, m, t, q, ro, an1, an2, an3;
int se[200010], id[200010], root[200010], ge[200010], len[200010];
vector<int> a[200010];
inline void Gao(int x, int y) {
  ww O = {}, A = tr[root[y]];
  O.a[0] = (w){ge[y], a[0][y - 1], a[0][y], 1};
  O.a[1] = (w){ge[y], a[0][y], a[0][y - 1], 1};
  if (A.a[0] < O.a[0]) swap(A, O);
  tr[x].a[0] = O.a[0], tr[x].a[1] = O.a[1];
}
inline w merge(w a, w b) {
  int d[10] = {}, t = 0;
  if (a.x && a.x != d[t]) d[++t] = a.x;
  if (a.y && a.y != d[t]) d[++t] = a.y;
  if (b.x && b.x != d[t]) d[++t] = b.x;
  if (b.y && b.y != d[t]) d[++t] = b.y;
  return (w){a.sum + b.sum, d[1], d[2], a.len + b.len};
}
inline void update(ww &a, ww b, ww c) {
  a.a[0] = merge(b.a[0], c.a[0]);
  a.a[1] = merge(c.a[1], b.a[1]);
}
inline ww Merge(ww a, ww b) {
  ww O = a;
  update(a, O, b);
  return a;
}
inline void Cl(int x) {
  tr[x].c = 1;
  tr[x].a[0].sum = tr[x].a[1].sum = 0;
}
inline void renew(int x) {
  if (tr[x].c) Cl(tr[x].l), Cl(tr[x].r);
  tr[x].c = 0;
}
void Build(int _, int &q, int x, int y) {
  if (!q) q = ++t;
  if (x == y) {
    tr[q].a[0] = (w){0, a[_][x - 1], a[_][x], 1};
    tr[q].a[1] = (w){0, a[_][x], a[_][x - 1], 1};
    return;
  }
  int mid = (x + y) / 2;
  Build(_, tr[q].l, x, mid);
  Build(_, tr[q].r, mid + 1, y);
  update(tr[q], tr[tr[q].l], tr[tr[q].r]);
}
void build(int &q, int x, int y) {
  if (!q) q = ++t;
  if (x == y) {
    Build(x, root[x], 1, len[x]);
    Gao(q, x);
    return;
  }
  int mid = (x + y) / 2;
  build(tr[q].l, x, mid);
  build(tr[q].r, mid + 1, y);
  update(tr[q], tr[tr[q].l], tr[tr[q].r]);
}
inline void Cl(int q, int x, int y, int l, int r) {
  if (l > r) return;
  if (l <= x && y <= r) {
    Cl(q);
    return;
  }
  renew(q);
  int mid = (x + y) / 2;
  if (l <= mid) Cl(tr[q].l, x, mid, l, r);
  if (mid < r) Cl(tr[q].r, mid + 1, y, l, r);
  update(tr[q], tr[tr[q].l], tr[tr[q].r]);
}
inline void Renew(int x, int y) {
  if (!tr[x].c) return;
  tr[x].c = 0;
  ww O = {};
  O.a[0] = (w){ge[y], a[0][y + 1], 1};
  O.a[1] = (w){ge[y], a[0][y], 1};
  if (O.a[0] < tr[root[y]].a[0])
    ge[y] = 0;
  else
    Cl(root[y], 1, len[y], 1, len[y]);
}
void Inc(int q, int x, int y, int k) {
  if (x == y) {
    tr[q].a[0].sum++;
    tr[q].a[1].sum++;
    return;
  }
  renew(q);
  int mid = (x + y) / 2;
  if (k <= mid)
    Inc(tr[q].l, x, mid, k);
  else
    Inc(tr[q].r, mid + 1, y, k);
  update(tr[q], tr[tr[q].l], tr[tr[q].r]);
}
void inc(int q, int x, int y, int k) {
  if (x == y) {
    Renew(q, x);
    ge[x]++;
    Gao(q, x);
    return;
  }
  renew(q);
  int mid = (x + y) / 2;
  if (k <= mid)
    inc(tr[q].l, x, mid, k);
  else
    inc(tr[q].r, mid + 1, y, k);
  update(tr[q], tr[tr[q].l], tr[tr[q].r]);
}
ww Cal(int q, int x, int y, int l, int r) {
  if (l > r) return kong;
  if (l <= x && y <= r) return tr[q];
  renew(q);
  int mid = (x + y) / 2, F = 0;
  ww A;
  if (l <= mid) A = Cal(tr[q].l, x, mid, l, r), F = 1;
  if (mid < r) {
    ww B = Cal(tr[q].r, mid + 1, y, l, r);
    if (!F)
      A = B;
    else
      A = Merge(A, B);
  }
  return A;
}
void gen(int q, int x, int y, int k) {
  if (x == y) {
    Renew(q, x);
    Gao(q, x);
    return;
  }
  renew(q);
  int mid = (x + y) / 2;
  if (k <= mid)
    gen(tr[q].l, x, mid, k);
  else
    gen(tr[q].r, mid + 1, y, k);
  update(tr[q], tr[tr[q].l], tr[tr[q].r]);
}
inline void jia(int x, int y) {
  int A = id[x], B = id[y];
  if (A == B && se[x] > se[y] || !(A == m && B == 1) && A > B ||
      A == 1 && B == m)
    swap(A, B), swap(x, y);
  if (A != B && x == a[0][A - 1] && y == a[0][A])
    inc(1, 1, m, A);
  else
    gen(1, 1, m, A), Inc(root[A], 1, len[A], se[x]), gen(1, 1, m, A);
}
inline ww merge(int x1, int y1, int x2, int y2) {
  ww A = Cal(1, 1, m, x1, y1), B = Cal(1, 1, m, x2, y2);
  return Merge(A, B);
}
inline void wen(int x, int y) {
  int A = id[x], B = id[y], an1, an2, an3;
  ww tmp, tt, ttt, tttt, sb;
  an1 = an2 = an3 = 0;
  tmp.a[0].sum = 200010;
  gen(1, 1, m, A), gen(1, 1, m, B);
  if (A == B) {
    int _ = 0, l = se[x], r = se[y];
    if (l > r) swap(l, r), _ = 1;
    ww O = Cal(root[A], 1, len[A], l, r - 1);
    tmp.a[0] = O.a[_];
    an1 = -1;
    an2 = l, an3 = r;
  }
  int i, j, k, X, Y;
  for (i = 0; i <= 1; i++) {
    ww a1 = Cal(root[A], 1, len[A], 1, se[x] - 1);
    if (i)
      a1 = Cal(root[A], 1, len[A], se[x], len[A]), X = A + 1;
    else
      swap(a1.a[0], a1.a[1]), X = A;
    for (j = 0; j <= 1; j++) {
      ww a2 = Cal(root[B], 1, len[B], 1, se[y] - 1);
      if (j) {
        a2 = Cal(root[B], 1, len[B], se[y], len[B]), Y = B + 1;
        swap(a2.a[0], a2.a[1]);
      } else
        Y = B;
      for (k = 0; k <= 1; k++) {
        ww a3;
        if (!k) {
          if (X <= Y)
            a3 = Cal(1, 1, m, X, Y - 1);
          else
            a3 = merge(X, m, 1, Y - 1);
        } else {
          if (X >= Y)
            a3 = Cal(1, 1, m, Y, X - 1);
          else
            a3 = merge(Y, m, 1, X - 1);
          swap(a3.a[0], a3.a[1]);
        }
        ww ss = Merge(a3, a2), s = Merge(a1, ss);
        if (s.a[0] < tmp.a[0])
          tmp = s, sb = a1, tt = a3, ttt = a2, tttt = ss, an1 = i, an2 = j,
          an3 = k;
        else if (s.a[0] == tmp.a[0] && a1.a[0].len == sb.a[0].len) {
          if (ss.a[0] < tttt.a[0])
            tmp = s, sb = a1, tt = a3, ttt = a2, tttt = ss, an1 = i, an2 = j,
            an3 = k;
          else if (ss.a[0] == tttt.a[0]) {
            if (a3.a[0].len > tt.a[0].len && a3.a[1].x < ttt.a[0].y ||
                a3.a[0].len < tt.a[0].len && a2.a[0].y < tt.a[1].x)
              tmp = s, sb = a1, tt = a3, ttt = a2, tttt = ss, an1 = i, an2 = j,
              an3 = k;
          }
        }
      }
    }
  }
  printf("%d\n", tmp.a[0].sum);
  if (an1 < 0)
    Cl(root[A], 1, len[A], an2, an3 - 1);
  else
    for (i = an1; i <= an1; i++) {
      if (i)
        Cl(root[A], 1, len[A], se[x], len[A]), X = A + 1;
      else
        Cl(root[A], 1, len[A], 1, se[x] - 1), X = A;
      for (j = an2; j <= an2; j++) {
        if (j)
          Cl(root[B], 1, len[B], se[y], len[B]), Y = B + 1;
        else
          Cl(root[B], 1, len[B], 1, se[y] - 1), Y = B;
        for (k = an3; k <= an3; k++) {
          if (!k) {
            if (X <= Y)
              Cl(1, 1, m, X, Y - 1);
            else {
              Cl(1, 1, m, X, m);
              Cl(1, 1, m, 1, Y - 1);
            }
          } else {
            if (X >= Y)
              Cl(1, 1, m, Y, X - 1);
            else {
              Cl(1, 1, m, Y, m);
              Cl(1, 1, m, 1, X - 1);
            }
          }
        }
      }
    }
  gen(1, 1, m, A), gen(1, 1, m, B);
}
int main() {
  scanf("%d%d", &n, &m);
  for (i = 1; i <= m; i++) {
    scanf("%d", &k);
    a[0].push_back(k);
  }
  a[0].push_back(a[0][0]);
  for (i = 1; i <= m; i++) {
    int x;
    scanf("%d", &x);
    for (j = 1; j <= x; j++) {
      scanf("%d", &k);
      a[i].push_back(k);
      if (j < x) se[k] = j, id[k] = i;
    }
    len[i] = x - 1;
  }
  build(ro, 1, m);
  scanf("%d", &q);
  for (i = 1; i <= q; i++) {
    char p[10];
    int x, y;
    scanf("%s%d%d", p, &x, &y);
    if (p[0] == '+')
      jia(x, y);
    else
      wen(x, y);
  }
  return 0;
}
