#include <bits/stdc++.h>
using namespace std;
const int MAX = 150010;
int n, q;
vector<pair<int, char>> fo[MAX];
struct Edge {
  int to, len;
  array<int, 26> cnt;
  Edge() {
    len = 0;
    fill(cnt.begin(), cnt.end(), 0);
  }
};
map<int, pair<int, int>> edges;
vector<Edge> go[MAX];
int parent[MAX];
int written[MAX];
int leaf_len[MAX];
array<int, 26> path_cnt[MAX];
bool is_failing[MAX];
int tot = 0, root;
int NewNode() { return tot++; }
int Compress(int vr) {
  int me = NewNode();
  for (const auto& to : fo[vr]) {
    Edge e;
    ++e.len;
    ++e.cnt[to.second - 'a'];
    int x = to.first;
    vector<int> on_edge = {x};
    while (((int)(fo[x]).size()) == 1) {
      ++e.len;
      ++e.cnt[fo[x][0].second - 'a'];
      x = fo[x][0].first;
      on_edge.push_back(x);
    }
    e.to = Compress(x);
    go[me].push_back(e);
    for (int& on : on_edge) edges[on] = make_pair(me, e.to);
    parent[e.to] = me;
  }
  return me;
}
array<int, 26> Add(const array<int, 26>& to, const array<int, 26>& what) {
  array<int, 26> res;
  for (int i = 0; i < 26; ++i) res[i] = to[i] + what[i];
  return res;
}
void Combine(const array<int, 26>& a, const array<int, 26>& b,
             array<int, 26>& res) {
  for (int i = 0; i < 26; ++i) res[i] = max(a[i], b[i]);
}
int Delta(int vr) {
  int total = leaf_len[vr];
  for (int e : path_cnt[vr]) total -= e;
  return total;
}
void UpdateNode(int vr) {
  if (go[vr].empty()) return;
  if (((int)(go[vr]).size()) == 1) {
    int a = go[vr][0].to;
    is_failing[vr] = is_failing[a];
    path_cnt[vr] = Add(path_cnt[a], go[vr][0].cnt);
    if (Delta(vr) < 0) is_failing[vr] = true;
    return;
  }
  if (((int)(go[vr]).size()) == 2) {
    int a = go[vr][0].to;
    int b = go[vr][1].to;
    is_failing[vr] = is_failing[a] || is_failing[b];
    Combine(Add(path_cnt[a], go[vr][0].cnt), Add(path_cnt[b], go[vr][1].cnt),
            path_cnt[vr]);
    if (Delta(vr) < 0) is_failing[vr] = true;
  }
}
bool fail = false;
void Init(int vr) {
  leaf_len[vr] = 0;
  fill(path_cnt[vr].begin(), path_cnt[vr].end(), 0);
  for (const auto& e : go[vr]) {
    Init(e.to);
    leaf_len[vr] = leaf_len[e.to] + e.len;
  }
  for (const auto& e : go[vr]) {
    if (leaf_len[vr] != leaf_len[e.to] + e.len) {
      fail = true;
    }
  }
  for (const auto& e : go[vr]) {
    UpdateNode(e.to);
  }
}
int Eval(int root) {
  int total = leaf_len[root];
  for (int e : path_cnt[root]) total -= e;
  int ans = 0;
  for (int i = 0; i < 26; ++i) ans += (i + 1) * (total + path_cnt[root][i]);
  return ans;
}
Edge& GetEdge(int f, int t) {
  for (auto& e : go[f])
    if (e.to == t) return e;
}
void Update(int vr, char to, int root) {
  auto ft = edges[vr];
  Edge& edge = GetEdge(ft.first, ft.second);
  if (written[vr] != '?') --edge.cnt[written[vr] - 'a'];
  written[vr] = to;
  if (written[vr] != '?') ++edge.cnt[written[vr] - 'a'];
  vr = ft.first;
  while (true) {
    UpdateNode(vr);
    if (vr == root) break;
    vr = parent[vr];
  }
}
int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i < n; ++i) {
    int par;
    char buf[3];
    scanf("%d%s", &par, buf);
    --par;
    fo[par].push_back(make_pair(i, buf[0]));
    written[i] = buf[0];
  }
  root = Compress(0);
  Init(root);
  if (fail) {
    for (int i = 0; i < q; ++i) {
      printf("Fou\n");
    }
    exit(0);
  }
  for (int i = 0; i < q; ++i) {
    int vr;
    char buf[3];
    scanf("%d%s", &vr, buf);
    --vr;
    Update(vr, buf[0], root);
    if (is_failing[root]) {
      printf("Fou\n");
    } else {
      printf("Shi ");
      printf("%d\n", Eval(root));
    }
  }
  return 0;
}
