#include <bits/stdc++.h>
using namespace std;
struct CharFreq {
  array<int, 27> f;
  CharFreq() {
    for (int i = 0; i < 27; ++i) {
      f[i] = 0;
    }
  }
  CharFreq(char c) {
    for (int i = 0; i < 27; ++i) {
      f[i] = 0;
    }
    f[c == '?' ? 26 : c - 'a'] = 1;
  }
  int& operator[](char c) { return f[c == '?' ? 26 : c - 'a']; }
  const int& operator[](char c) const { return f[c == '?' ? 26 : c - 'a']; }
  CharFreq operator+(const CharFreq& rhs) const {
    CharFreq result;
    for (int i = 0; i < 27; ++i) {
      result.f[i] = f[i] + rhs.f[i];
    }
    return result;
  }
  CharFreq operator*(const CharFreq& rhs) const {
    CharFreq res;
    for (int i = 0; i < 27; ++i) {
      res.f[i] = max(f[i], rhs.f[i]);
    }
    return res;
  }
  void update(char c, int amt = 1) { (*this)[c] += amt; }
  void update(char from, char to) {
    (*this)[from]--;
    (*this)[to]++;
  }
  int sum() const {
    int s = 0;
    for (int i = 0; i < 26; ++i) {
      s += f[i];
    }
    return s;
  }
};
char s[10];
int main() {
  int N, Q;
  scanf("%d %d", &N, &Q);
  vector<int> p(N);
  vector<char> c(N);
  vector<vector<int>> graph(N);
  vector<int> height(N);
  for (int i = 1; i < N; ++i) {
    scanf("%d %s", &p[i], s);
    p[i]--;
    c[i] = s[0];
    graph[p[i]].push_back(i);
    height[i] = height[p[i]] + 1;
  };
  int max_height = height.back();
  ;
  for (int i = 0; i < N; ++i) {
    if (graph[i].size() == 0 && height[i] != max_height) {
      for (int j = 0; j < Q; ++j) {
        printf("Fou\n");
      }
      return 0;
    }
  }
  for (int i = 0; i < N; ++i) {
    height[i] = max_height - height[i];
  }
  vector<int> cpar(N, 0);
  vector<int> merge(N, 0);
  for (int i = 1; i < N; ++i) {
    merge[i] = i;
    cpar[i] = merge[p[i]];
    if (graph[p[i]].size() == 1 && p[i] != 0) {
      merge[i] = merge[p[i]];
    }
  };
  vector<vector<int>> cgraph = graph;
  vector<CharFreq> cc(N);
  for (int i = 1; i < N; ++i) {
    cc[i] = CharFreq();
    if (merge[i] != i) {
      ;
      cgraph[merge[i]].insert(cgraph[merge[i]].end(), graph[i].begin(),
                              graph[i].end());
      cc[merge[i]].update(c[i]);
      cgraph[i].clear();
      height[merge[i]] = min(height[merge[i]], height[i]);
    } else {
      ;
      cc[i].update(c[i]);
    }
  };
  for (int i = 0; i < N; ++i) {
    cgraph[i].erase(
        remove_if(cgraph[i].begin(), cgraph[i].end(),
                  [&merge](int i) -> bool { return merge[i] != i; }),
        cgraph[i].end());
  };
  vector<CharFreq> mem(N);
  vector<int> fails(N);
  auto update = [&](int i) {
    fails[i] = 0;
    if (cgraph[i].size() == 1) {
      int child = cgraph[i][0];
      mem[i] = mem[child] + cc[child];
      fails[i] += fails[child];
    } else if (cgraph[i].size() == 2) {
      int lchild = cgraph[i][0];
      int rchild = cgraph[i][1];
      mem[i] = (mem[lchild] + cc[lchild]) * (mem[rchild] + cc[rchild]);
      fails[i] += fails[lchild];
      fails[i] += fails[rchild];
    } else if (cgraph[i].size() == 0) {
      mem[i] = CharFreq();
    } else {
      assert(false);
    }
    int tot = mem[i].sum();
    if (tot > height[i]) {
      fails[i]++;
    }
  };
  for (int i = N - 1; i >= 0; --i) {
    if (merge[i] == i) {
      update(i);
    }
  };
  auto debug_graph = [&]() -> void {
    printf("the graph:\n");
    for (int i = 0; i < N; ++i) {
      if (merge[i] == i) {
        printf("node %d:\n", i);
        printf("\tmerge = %d\n", merge[i]);
        printf("\tcpar = %d\n", cpar[i]);
        printf("\tcc = ");
        for (int j = 0; j < 27; ++j) {
          printf("%d ", cc[i].f[j]);
        }
        printf("\n");
        printf("\tcgraph = ");
        for (int j : cgraph[i]) {
          printf("%d ", j);
        }
        printf("\n");
        printf("\theight = %d\n", height[i]);
        printf("\tfails = %d\n", fails[i]);
        printf("\tmem = ");
        for (int j = 0; j < 27; ++j) {
          printf("%d ", mem[i].f[j]);
        }
        printf("\n");
      }
    }
  };
  ;
  for (int i = 0; i < Q; ++i) {
    int v;
    scanf("%d %s", &v, s);
    v--;
    int cv = merge[v];
    cc[cv].update(c[v], -1);
    cc[cv].update(s[0]);
    c[v] = s[0];
    while (cv != 0) {
      update(cpar[cv]);
      cv = cpar[cv];
    };
    ;
    if (fails[0]) {
      printf("Fou\n");
    } else {
      int tot = mem[0].sum();
      int leftover = height[0] - tot;
      int answer = 0;
      for (char l = 'a'; l <= 'z'; ++l) {
        int anagramnity = leftover + mem[0][l];
        answer += (l - 'a' + 1) * anagramnity;
      }
      printf("Shi %d\n", answer);
    }
  }
  return 0;
}
