#include <bits/stdc++.h>   using namespace std;   const int MAXN = 2.1e5;   const int MAXQ = 2.1e5;   int N, Q;   int P[MAXN];   char C[MAXN];   vector<int> ch[MAXN];   int depth[MAXN];   int compChild[MAXN];   int compPar[MAXN];   int cnts[MAXN][26];   int subVal[MAXN][26];   int tot[MAXN];   int main() {     ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);     cin >> N >> Q;     P[1] = 0;     C[1] =  ? ;     for (int i = 2; i <= N; i++) {       cin >> P[i] >> C[i];     }     for (int i = 2; i <= N; i++) {       ch[P[i]].push_back(i);     }     depth[1] = 0;     for (int i = 2; i <= N; i++) {       depth[i] = depth[P[i]] + 1;     }     set<int> leafDepths;     for (int i = 1; i <= N; i++) {       if (ch[i].empty()) {         leafDepths.insert(depth[i]);       }     }     assert(!leafDepths.empty());     if (leafDepths.size() > 1) {       for (int q = 0; q < Q; q++) {         cout <<  Fou  <<   n ;       }       exit(0);     }     assert(leafDepths.size() == 1);     const int leafDepth = *leafDepths.begin();     for (int i = N; i >= 2; i--) {       compPar[i] = P[i];       compChild[i] = i;       if (ch[i].size() == 1) {         compChild[i] = compChild[ch[i][0]];         compPar[compChild[i]] = P[i];       }       if (C[i] !=  ? ) {         cnts[compChild[i]][C[i] -  a ]++;       }     }     compPar[1] = 0;     compChild[1] = 1;     for (int i = 1; i <= N; i++) {       for (auto& c : ch[i]) {         c = compChild[c];       }     }     int numBad = 0;     for (int i = N; i >= 1; i--) {       if (compChild[i] != i) continue;       for (int v = 0; v < 26; v++) {         subVal[i][v] = 0;       }       for (int j : ch[i]) {         for (int v = 0; v < 26; v++) {           subVal[i][v] = max(subVal[i][v], cnts[j][v] + subVal[j][v]);         }       }       tot[i] = 0;       for (int v = 0; v < 26; v++) {         tot[i] += subVal[i][v];       }       if (tot[i] + depth[i] > leafDepth) {         numBad++;       }     }     for (int i = 1; i <= N; i++) {     }     for (int q = 0; q < Q; q++) {       int ind;       char c;       cin >> ind >> c;       if (C[ind] !=  ? ) {         int v = C[ind] -  a ;         cnts[compChild[ind]][v]--;         for (int i = compPar[compChild[ind]]; i != 0; i = compPar[i]) {           assert(compChild[i] == i);           if (tot[i] + depth[i] > leafDepth) {             numBad--;           }           tot[i] -= subVal[i][v];           subVal[i][v] = 0;           for (int j : ch[i]) {             subVal[i][v] = max(subVal[i][v], cnts[j][v] + subVal[j][v]);           }           tot[i] += subVal[i][v];           if (tot[i] + depth[i] > leafDepth) {             numBad++;           }         }       }       C[ind] = c;       if (C[ind] !=  ? ) {         int v = C[ind] -  a ;         cnts[compChild[ind]][v]++;         for (int i = compPar[compChild[ind]]; i != 0; i = compPar[i]) {           assert(compChild[i] == i);           if (tot[i] + depth[i] > leafDepth) {             numBad--;           }           tot[i] -= subVal[i][v];           subVal[i][v] = 0;           for (int j : ch[i]) {             subVal[i][v] = max(subVal[i][v], cnts[j][v] + subVal[j][v]);           }           tot[i] += subVal[i][v];           if (tot[i] + depth[i] > leafDepth) {             numBad++;           }         }       }       if (numBad) {         cout <<  Fou  <<   n ;       } else {         long long res = 0;         for (int v = 0; v < 26; v++) {           res += 1ll * ((leafDepth - tot[1]) + subVal[1][v]) * (v + 1);         }         cout <<  Shi  <<     << res <<   n ;       }     }     return 0;   }