#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    vi revs;
    int nz;
    vi difa;
    vi difb;
    int totala;
    int totalb;
    int z, w;
    node_t() {
        vals.resize(26);
        revs.resize(26);
        nz = 0;
        difa.resize(26);
        difb.resize(26);
        totala = totalb = 0;
        z = 0, w = 1;
    }
};

node_t join(node_t a, node_t b) {
    node_t c;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            c.totala += b.vals[i] - a.vals[i];
            c.difa[i] = b.vals[i] - a.vals[i];
        }
        else {
            c.totalb += a.vals[i] - b.vals[i];
            c.difb[i] = a.vals[i] - b.vals[i];
        }
    }
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    //assert(a.z - c.totala == b.z - c.totalb);
    c.z = a.z - c.totala;
    return c;
}

void upd(node_t& c, node_t& a, node_t& b, int i) {
    c.vals[i] = max(a.vals[i], b.vals[i]);
    c.totala -= c.difa[i];
    c.totalb -= c.difb[i];
    if (a.vals[i] < b.vals[i]) {
        c.totala += b.vals[i] - a.vals[i];
        c.difa[i] = b.vals[i] - a.vals[i];
    }
    else {
        c.totalb += a.vals[i] - b.vals[i];
        c.difb[i] = a.vals[i] - b.vals[i];
    }
}
void upd(node_t& c, node_t& a, node_t& b) {
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    //assert(a.z - c.totala == b.z - c.totalb);
    c.z = a.z - c.totala;
}

void add(node_t& a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void rem(node_t& a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void chemthan() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi dj(n);
    FOR(u, 0, n) dj[u] = u;
    function<int(int)> find = [&] (int u) {
        return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
    };
    FOR(u, 1, n) {
        if (sz(adj[u]) == 1) {
            int v = adj[u][0];
            if (sz(adj[v]) == 1) {
                dj[find(v)] = find(u);
            }
        }
    }
    vi lev(n);
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        int flag = 0;
        for (int v : adj[u]) {
            upd_dfs(v);
            if (!flag) {
                flag = 1;
                f[u] = f[v];
            }
            else {
                f[u] = join(f[u], f[v]);
            }
        }
        if (u) {
            add(f[u], c[u]);
        }
    };
    upd_dfs(0);
    vector<vi> adj_t(n);
    vi from(n);
    FOR(u, 0, n) {
        for (int v : adj[u]) {
            int uu = find(u);
            int vv = find(v);
            if (uu ^ vv) {
                adj_t[uu].pb(vv);
                from[vv] = uu;
            }
        }
    }
    FOR(u, 0, n) {
        sort(all(adj_t[u])), uni(adj_t[u]);
    }
    FOR(u, 1, n) {
        int v = find(u);
        if ('a' <= c[u] && c[u] <= 'z') {
            f[v].revs[c[u] - 'a']++;
        }
        else {
            f[v].nz++;
        }
    }
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char y = c[u];
        c[u] = x;
        if (x != y) {
            u = find(u);
            if ('a' <= x && x <= 'z') {
                f[u].revs[x - 'a']++;
            }
            else {
                f[u].nz++;
            }
            if ('a' <= y && y <= 'z') {
                f[u].revs[y - 'a']--;
            }
            else {
                f[u].nz--;
            }
            add(f[u], x);
            rem(f[u], y);
            while (u) {
                int nu = from[u];
                if (sz(adj_t[nu]) == 1) {
                    f[nu].w = f[u].w;
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        f[nu].vals[ix - 'a'] = f[u].vals[ix - 'a'] + f[nu].revs[ix - 'a'];
                    }
                    f[nu].z = f[u].z + f[nu].nz;
                }
                else {
                    int v = adj_t[nu][0];
                    int w = adj_t[nu][1];
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        upd(f[nu], f[v], f[w], ix - 'a');
                    }
                    upd(f[nu], f[v], f[w]);
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        f[nu].vals[ix - 'a'] += f[nu].revs[ix - 'a'];
                    }
                    f[nu].z += f[nu].nz;
                }
                u = nu;
            }
        }
        if (!f[0].w) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    vi revs;
    int nz;
    vi difa;
    vi difb;
    int totala;
    int totalb;
    int z, w;
    node_t() {
        vals.resize(26);
        revs.resize(26);
        nz = 0;
        difa.resize(26);
        difb.resize(26);
        totala = totalb = 0;
        z = 0, w = 1;
    }
};

node_t join(node_t a, node_t b) {
    node_t c;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            c.totala += b.vals[i] - a.vals[i];
            c.difa[i] = b.vals[i] - a.vals[i];
        }
        else {
            c.totalb += a.vals[i] - b.vals[i];
            c.difb[i] = a.vals[i] - b.vals[i];
        }
    }
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    c.z = min(a.z - c.totala, b.z - c.totalb);
    return c;
}

void upd(node_t& c, node_t& a, node_t& b, int i) {
    c.vals[i] = max(a.vals[i], b.vals[i]);
    c.totala -= c.difa[i];
    c.totalb -= c.difb[i];
    if (a.vals[i] < b.vals[i]) {
        c.totala += b.vals[i] - a.vals[i];
        c.difa[i] = b.vals[i] - a.vals[i];
    }
    else {
        c.totalb += a.vals[i] - b.vals[i];
        c.difb[i] = a.vals[i] - b.vals[i];
    }
}
void upd(node_t& c, node_t& a, node_t& b) {
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    c.z = min(a.z - c.totala, b.z - c.totalb);
}

void add(node_t& a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void rem(node_t& a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void chemthan() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi dj(n);
    FOR(u, 0, n) dj[u] = u;
    function<int(int)> find = [&] (int u) {
        return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
    };
    FOR(u, 0, n) {
        if (sz(adj[u]) == 1) {
            int v = adj[u][0];
            if (sz(adj[v]) == 1) {
                dj[find(v)] = find(u);
            }
        }
    }
    vi lev(n);
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        int flag = 0;
        for (int v : adj[u]) {
            upd_dfs(v);
            if (!flag) {
                flag = 1;
                f[u] = f[v];
            }
            else {
                f[u] = join(f[u], f[v]);
            }
        }
        if (u) {
            add(f[u], c[u]);
        }
    };
    upd_dfs(0);
    vector<vi> adj_t(n);
    vi from(n);
    FOR(u, 0, n) {
        for (int v : adj[u]) {
            int uu = find(u);
            int vv = find(v);
            if (uu ^ vv) {
                adj_t[uu].pb(vv);
                from[vv] = uu;
            }
        }
    }
    FOR(u, 0, n) {
        sort(all(adj_t[u])), uni(adj_t[u]);
    }
    FOR(u, 1, n) {
        int v = find(u);
        if ('a' <= c[u] && c[u] <= 'z') {
            f[v].revs[c[u] - 'a']++;
        }
        else {
            f[v].nz++;
        }
    }
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char y = c[u];
        c[u] = x;
        if (x != y) {
            u = find(u);
            if ('a' <= x && x <= 'z') {
                f[u].revs[x - 'a']++;
            }
            else {
                f[u].nz++;
            }
            if ('a' <= y && y <= 'z') {
                f[u].revs[y - 'a']--;
            }
            else {
                f[u].nz--;
            }
            add(f[u], x);
            rem(f[u], y);
            while (u) {
                int nu = from[u];
                if (sz(adj_t[nu]) == 1) {
                    f[nu].w = f[u].w;
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        f[nu].vals[ix - 'a'] = f[u].vals[ix - 'a'] + f[nu].revs[ix - 'a'];
                    }
                    f[nu].z = f[u].z + f[nu].nz;
                }
                else {
                    int v = adj_t[nu][0];
                    int w = adj_t[nu][1];
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        upd(f[nu], f[v], f[w], ix - 'a');
                    }
                    upd(f[nu], f[v], f[w]);
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        f[nu].vals[ix - 'a'] += f[nu].revs[ix - 'a'];
                    }
                    f[nu].z += f[nu].nz;
                }
                u = nu;
            }
        }
        if (!f[0].w) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    vi revs;
    int nz;
    vi difa;
    vi difb;
    int totala;
    int totalb;
    int z, w;
    node_t() {
        vals.resize(26);
        revs.resize(26);
        nz = 0;
        difa.resize(26);
        difb.resize(26);
        totala = totalb = 0;
        z = 0, w = 1;
    }
};

node_t join(node_t a, node_t b) {
    node_t c;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            c.totala += b.vals[i] - a.vals[i];
            c.difa[i] = b.vals[i] - a.vals[i];
        }
        else {
            c.totalb += a.vals[i] - b.vals[i];
            c.difb[i] = a.vals[i] - b.vals[i];
        }
    }
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    assert(a.z - c.totala == b.z - c.totalb);
    c.z = a.z - c.totala;
    return c;
}

void upd(node_t& c, node_t& a, node_t& b, int i) {
    c.vals[i] = max(a.vals[i], b.vals[i]);
    c.totala -= c.difa[i];
    c.totalb -= c.difb[i];
    if (a.vals[i] < b.vals[i]) {
        c.totala += b.vals[i] - a.vals[i];
        c.difa[i] = b.vals[i] - a.vals[i];
    }
    else {
        c.totalb += a.vals[i] - b.vals[i];
        c.difb[i] = a.vals[i] - b.vals[i];
    }
}
void upd(node_t& c, node_t& a, node_t& b) {
    c.w = a.w & b.w;
    if (a.z < c.totala || b.z < c.totalb) {
        c.w = 0;
    }
    assert(a.z - c.totala == b.z - c.totalb);
    c.z = a.z - c.totala;
}

node_t add(node_t a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void chemthan() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi dj(n);
    FOR(u, 0, n) dj[u] = u;
    function<int(int)> find = [&] (int u) {
        return dj[u] == u ? dj[u] : dj[u] = find(dj[u]);
    };
    FOR(u, 1, n) {
        if (sz(adj[u]) == 1) {
            int v = adj[u][0];
            if (sz(adj[v]) == 1) {
                dj[find(v)] = find(u);
            }
        }
    }
    vi lev(n);
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        int flag = 0;
        for (int v : adj[u]) {
            upd_dfs(v);
            if (!flag) {
                flag = 1;
                f[u] = f[v];
            }
            else {
                f[u] = join(f[u], f[v]);
            }
        }
        if (u) {
            f[u] = add(f[u], c[u]);
        }
    };
    upd_dfs(0);
    vector<vi> adj_t(n);
    vi from(n);
    FOR(u, 0, n) {
        for (int v : adj[u]) {
            int uu = find(u);
            int vv = find(v);
            if (uu ^ vv) {
                adj_t[uu].pb(vv);
                from[vv] = uu;
            }
        }
    }
    FOR(u, 0, n) {
        sort(all(adj_t[u])), uni(adj_t[u]);
    }
    FOR(u, 1, n) {
        int v = find(u);
        if ('a' <= c[u] && c[u] <= 'z') {
            f[v].revs[c[u] - 'a']++;
        }
        else {
            f[v].nz++;
        }
    }
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char y = c[u];
        c[u] = x;
        if (x != y) {
            u = find(u);
            if ('a' <= x && x <= 'z') {
                f[u].revs[x - 'a']++;
            }
            else {
                f[u].nz++;
            }
            if ('a' <= y && y <= 'z') {
                f[u].revs[y - 'a']--;
            }
            else {
                f[u].nz--;
            }
            upd_add(f[u], x);
            upd_rem(f[u], y);
            while (u) {
                int nu = from[u];
                if (sz(adj_t[nu]) == 1) {
                    upd_add(f[nu], x);
                    upd_rem(f[nu], y);
                    f[nu].w = f[u].w;
                }
                else {
                    int v = adj_t[nu][0];
                    int w = adj_t[nu][1];
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        upd(f[nu], f[v], f[w], ix - 'a');
                    }
                    upd(f[nu], f[v], f[w]);
                    for (int ix : {x, y}) if ('a' <= ix && ix <= 'z') {
                        f[nu].vals[ix - 'a'] += f[nu].revs[ix - 'a'];
                    }
                    f[nu].z += f[nu].nz;
                }
                u = nu;
            }
        }
        if (!f[0].w) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    chemthan();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z, total;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int total = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            total += b.vals[i] - a.vals[i];
        }
    }
    if (a.z < total) {
        return node_t();
    }
    c.z = a.z - total;
    c.total = total;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (a.z == -1);
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (a.z == -1) return;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    vi id(256);
    FOR(i, 'a', 'z' + 1) id[i] = i - 'a';
    id['?'] = 26;
    vector<vi> d(n, vi(27));
    FOR(u, 0, n) nxt[u] = u;
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
            d[nxt[v]][id[c[v]]]++;
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    FOR(u, 0, n) sort(all(adj[u])), uni(adj[u]);
    auto calc = [&] (int u, char t) {
        int res = d[nxt[par[u]]][id[t]];
        if (c[u] == t) {
            res++;
        }
        return res;
    };
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char px = c[u];
        if (x != px) {
            int nu = nxt[u];
            d[nu][id[px]]--;
            d[nu][id[x]]++;
            vi change(26), vv;
            if (x != '?') {
                vv.pb(id[x]);
            }
            if (px != '?') {
                vv.pb(id[px]);
            }
            if (u ^ nu) {
                f[nu] = rem(f[nu], c[u]);
                c[u] = x;
                f[nu] = add(f[nu], c[u]);
                u = nu;
                if (px != '?') {
                    change[px - 'a'] = -1;
                }
                if (x != '?') {
                    change[x - 'a'] = 1;
                }
            }
            else {
                c[u] = x;
                if (u) {
                    int nu = par[u];
                    f[nu] = node_t();
                    for (int v : adj[nu]) {
                        node_t tmp = f[v];
                        if (c[v] != '?') {
                            tmp.vals[id[c[v]]]++;
                        }
                        else {
                            tmp.z++;
                        }
                        if (f[nu].z == -1) {
                            f[nu] = tmp;
                        }
                        else {
                            f[nu] = join(f[nu], tmp);
                        }
                    }
                    u = nu, nu = nxt[u];
                    node_t tmp = f[nu];
                    f[nu] = f[u];
                    if (f[u].z == -1) {
                        f[nu].z = -1;
                    }
                    else {
                        FOR(i, 0, 26) {
                            f[nu].vals[i] += calc(nu, 'a' + i);
                        }
                        f[nu].z += calc(nu, '?');
                    }
                    for (int w : vv) {
                        change[w] = f[nu].vals[w] - tmp.vals[w];
                    }
                    u = nu;
                }
            }
            while (u) {
                nu = par[u];
                if (sz(adj[nu]) == 1) {
                    if (c[u] != '?') {
                        f[nu].vals[id[c[u]]]++;
                    }
                    else {
                        f[nu].z++;
                    }
                    nu = nxt[nu];
                    FOR(i, 0, 26) {
                        f[nu].vals[i] += calc(u, 'a' + i);
                    }
                    f[nu].z += calc(u, '?');
                }
                else {
                    int v = adj[nu][0] + adj[nu][1] - u;
                    if (f[u].z == -1 || f[v].z == -1) {
                        nu = nxt[nu];
                        f[nu].z = -1;
                    }
                    else {
                        for (int w : vv) {
                            int tmp = f[nu].vals[w];
                            f[u].vals[w] -= change[w];
                            f[u].vals[w] += c[u] == 'a' + w;
                            f[v].vals[w] += c[v] == 'a' + w;
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total -= f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total -= f[v].vals[w] - f[u].vals[w];
                            }
                            f[u].vals[w] += change[w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total += f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total += f[v].vals[w] - f[u].vals[w];
                            }
                            f[nu].vals[w] = max(f[u].vals[w], f[v].vals[w]);
                            f[u].vals[w] -= c[u] == 'a' + w;
                            f[v].vals[w] -= c[v] == 'a' + w;
                            change[w] = f[nu].vals[w] - tmp;
                        }
                        f[u].z += c[u] == '?';
                        f[v].z += c[v] == '?';
                        if (f[u].z + f[v].z < f[nu].total) {
                            nu = nxt[nu];
                            f[nu].z = -1;
                        }
                        else {
                            f[nu].z = (f[u].z + f[v].z - f[nu].total) / 2;
                            nu = nxt[nu];
                            FOR(i, 0, 26) {
                                f[nu].vals[i] += calc(nu, 'a' + i);
                            }
                            f[nu].z += calc(nu, '?');
                        }
                        f[u].z -= c[u] == '?';
                        f[v].z -= c[v] == '?';
                    }
                }
                u = nu;
            }
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z, total;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int total = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            total += b.vals[i] - a.vals[i];
        }
    }
    if (a.z < total) {
        return node_t();
    }
    c.z = a.z - total;
    c.total = total;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (a.z == -1);
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (a.z == -1) return;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    vector<vi> d(n, vi(27));
    FOR(u, 0, n) nxt[u] = u;
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            d[v] = d[u];
            if (c[v] != '?') {
                d[v][c[v] - 'a']++;
            }
            else {
                d[v][26]++;
            }
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    vector<vi> adj_t(n);
    FOR(u, 1, n) {
        if (u == nxt[u]) {
            adj_t[nxt[par[u]]].pb(u);
        }
    }
    adj = adj_t;
    FOR(u, 0, n) sort(all(adj[u])), uni(adj[u]);

    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char px = c[u];
        if (x != px) {
            int nu = nxt[u];
            vi change(26);
            vi vv;
            if (x != '?') {
                vv.pb(x - 'a');
            }
            if (px != '?') {
                vv.pb(px - 'a');
            }
            if (u ^ nu) {
                f[nu] = rem(f[nu], c[u]);
                c[u] = x;
                f[nu] = add(f[nu], c[u]);
                u = nu;
                if (px != '?') {
                    change[px - 'a'] = -1;
                }
                if (x != '?') {
                    change[x - 'a'] = 1;
                }
            }
            else {
                c[u] = x;
                if (u) {
                    int nu = nxt[par[u]];
                    node_t tmp = f[nu];
                    f[nu] = node_t();
                    for (int v : adj[nu]) {
                        if (f[nu].z == -1) {
                            f[nu] = add(f[v], c[v]);
                        }
                        else {
                            f[nu] = join(f[nu], add(f[v], c[v]));
                        }
                    }
                    for (int w : vv) {
                        change[w] = f[nu].vals[w] - tmp.vals[w];
                    }
                    u = nu;
                }
            }
            while (u) {
                nu = nxt[par[u]];
                if (sz(adj[nu]) == 1) {
                    f[nu] = add(f[u], c[u]);
                }
                else {
                    int v = adj[nu][0] + adj[nu][1] - u;
                    if (f[u].z == -1 || f[v].z == -1) {
                        f[nu].z = -1;
                    }
                    else {
                        for (int w : vv) {
                            int tmp = f[nu].vals[w];
                            f[u].vals[w] -= change[w];
                            f[u].vals[w] += d[u][w] - d[nu][w];
                            f[v].vals[w] += d[v][w] - d[nu][w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total -= f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total -= f[v].vals[w] - f[u].vals[w];
                            }
                            f[u].vals[w] += change[w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total += f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total += f[v].vals[w] - f[u].vals[w];
                            }
                            f[nu].vals[w] = max(f[u].vals[w], f[v].vals[w]);
                            f[u].vals[w] -= d[u][w] - d[nu][w];
                            f[v].vals[w] -= d[v][w] - d[nu][w];
                            change[w] = f[nu].vals[w] - tmp;
                        }
                        f[u].z += d[u][26] - d[nu][26];
                        f[v].z += d[v][26] - d[nu][26];
                        if (f[u].z + f[v].z < f[nu].total) {
                            f[nu].z = -1;
                        }
                        else {
                            f[nu].z = (f[u].z + f[v].z - f[nu].total) / 2;
                        }
                        f[u].z -= d[u][26] - d[nu][26];
                        f[v].z -= d[v][26] - d[nu][26];
                    }
                }
                u = nu;
            }
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int totala = 0, totalb = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            totala += b.vals[i] - a.vals[i];
        }
        else {
            totalb += a.vals[i] - b.vals[i];
        }
    }
    if (a.z < totala || b.z < totalb) {
        return node_t();
    }
    assert(a.z - totala == b.z - totalb);
    c.z = a.z - totala;
    return c;
}

node_t add(node_t a, char c) {
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    function<void(int)> dfs = [&] (int u) {
        nxt[u] = u;
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        int nu = nxt[u];
        if (u ^ nu) {
            f[nu] = rem(f[nu], c[u]);
            c[u] = x;
            f[nu] = add(f[nu], c[u]);
            u = nu;
        }
        else {
            c[u] = x;
        }
        while (u) {
            nu = nxt[par[u]];
            f[nu] = node_t();
            for (int v : adj[nu]) {
                if (f[nu].z == -1) {
                    f[nu] = add(f[v], c[v]);
                }
                else {
                    f[nu] = join(f[nu], add(f[v], c[v]));
                }
            }
            u = nu;
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z, total;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int total = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            total += b.vals[i] - a.vals[i];
        }
    }
    if (a.z < total) {
        return node_t();
    }
    c.z = a.z - total;
    c.total = total;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (a.z == -1);
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (a.z == -1) return;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    vi id(256);
    FOR(i, 'a', 'z' + 1) id[i] = i - 'a';
    id['?'] = 26;
    vector<vi> d(n, vi(27));
    FOR(u, 0, n) nxt[u] = u;
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
            d[nxt[v]][id[c[v]]]++;
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    FOR(u, 0, n) sort(all(adj[u])), uni(adj[u]);
    auto calc = [&] (int u, char t) {
        int res = d[nxt[par[u]]][id[t]];
        if (c[u] == t) {
            res++;
        }
        return res;
    };
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char px = c[u];
        if (x != px) {
            int nu = nxt[u];
            d[nu][id[px]]--;
            d[nu][id[x]]++;
            vi change(26), vv;
            if (x != '?') {
                vv.pb(id[x]);
            }
            if (px != '?') {
                vv.pb(id[px]);
            }
            if (u ^ nu) {
                f[nu] = rem(f[nu], c[u]);
                c[u] = x;
                f[nu] = add(f[nu], c[u]);
                u = nu;
                if (px != '?') {
                    change[px - 'a'] = -1;
                }
                if (x != '?') {
                    change[x - 'a'] = 1;
                }
            }
            else {
                c[u] = x;
                if (u) {
                    int nu = par[u];
                    f[nu] = node_t();
                    for (int v : adj[nu]) {
                        node_t tmp = f[v];
                        if (c[v] != '?') {
                            tmp.vals[id[c[v]]]++;
                        }
                        else {
                            tmp.z++;
                        }
                        if (f[nu].z == -1) {
                            f[nu] = tmp;
                        }
                        else {
                            f[nu] = join(f[nu], tmp);
                        }
                    }
                    u = nu, nu = nxt[u];
                    node_t tmp = f[nu];
                    f[nu] = f[u];
                    if (f[u].z == -1) {
                        f[nu].z = -1;
                    }
                    else {
                        FOR(i, 0, 26) {
                            f[nu].vals[i] += calc(nu, 'a' + i);
                        }
                        f[nu].z += calc(nu, '?');
                    }
                    for (int w : vv) {
                        change[w] = f[nu].vals[w] - tmp.vals[w];
                    }
                    u = nu;
                }
            }
            while (u) {
                nu = nxt[par[u]];
                if (sz(adj[nu]) == 1) {
                    FOR(i, 0, 26) {
                        f[nu].vals[i] += calc(u, 'a' + i);
                    }
                    f[nu].z += calc(u, '?');
                }
                else {
                    nu = par[u];
                    int v = adj[nu][0] + adj[nu][1] - u;
                    if (f[u].z == -1 || f[v].z == -1) {
                        nu = nxt[nu];
                        f[nu].z = -1;
                    }
                    else {
                        for (int w : vv) {
                            int tmp = f[nu].vals[w];
                            f[u].vals[w] -= change[w];
                            f[u].vals[w] += c[u] == 'a' + w;
                            f[v].vals[w] += c[u] == 'a' + w;
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total -= f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total -= f[v].vals[w] - f[u].vals[w];
                            }
                            f[u].vals[w] += change[w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total += f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total += f[v].vals[w] - f[u].vals[w];
                            }
                            f[nu].vals[w] = max(f[u].vals[w], f[v].vals[w]);
                            f[u].vals[w] -= c[u] == 'a' + w;
                            f[v].vals[w] -= c[u] == 'a' + w;
                            change[w] = f[nu].vals[w] - tmp;
                        }
                        f[u].z += c[u] == '?';
                        f[v].z += c[v] == '?';
                        if (f[u].z + f[v].z < f[nu].total) {
                            nu = nxt[nu];
                            f[nu].z = -1;
                        }
                        else {
                            f[nu].z = (f[u].z + f[v].z - f[nu].total) / 2;
                            nu = nxt[nu];
                            FOR(i, 0, 26) {
                                f[nu].vals[i] += calc(nu, 'a' + i);
                            }
                            f[nu].z += calc(nu, '?');
                        }
                        f[u].z -= c[u] == '?';
                        f[v].z -= c[v] == '?';
                    }
                }
                u = nu;
            }
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z, total;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int total = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            total += b.vals[i] - a.vals[i];
        }
    }
    if (a.z < total) {
        return node_t();
    }
    c.z = a.z - total;
    c.total = total;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void upd_add(node_t& a, char c) {
    if (a.z == -1);
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
}

void upd_rem(node_t& a, char c) {
    if (a.z == -1) return;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    vi id(256);
    FOR(i, 'a', 'z' + 1) id[i] = i - 'a';
    id['?'] = 26;
    vector<vi> d(n, vi(27));
    FOR(u, 0, n) nxt[u] = u;
    function<void(int)> dfs = [&] (int u) {
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
            d[nxt[v]][id[c[v]]]++;
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    auto calc = [&] (int u, char t) {
        return d[u][id[t]];
    };
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        char px = c[u];
        if (x != px) {
            int nu = nxt[u];
            d[nu][id[px]]--;
            d[nu][id[x]]++;
            vi change(26), vv;
            if (x != '?') {
                vv.pb(id[x]);
            }
            if (px != '?') {
                vv.pb(id[px]);
            }
            if (u ^ nu) {
                f[nu] = rem(f[nu], c[u]);
                c[u] = x;
                f[nu] = add(f[nu], c[u]);
                u = nu;
                if (px != '?') {
                    change[px - 'a'] = -1;
                }
                if (x != '?') {
                    change[x - 'a'] = 1;
                }
            }
            else {
                c[u] = x;
                if (u) {
                    int nu = par[u];
                    f[nu] = node_t();
                    for (int v : adj[nu]) {
                        node_t tmp = f[v];
                        if (c[v] != '?') {
                            tmp.vals[id[c[v]]]++;
                        }
                        else {
                            tmp.z++;
                        }
                        if (f[nu].z == -1) {
                            f[nu] = tmp;
                        }
                        else {
                            f[nu] = join(f[nu], tmp);
                        }
                    }
                    u = nu, nu = nxt[u];
                    node_t tmp = f[nu];
                    f[nu] = f[u];
                    if (f[u].z == -1) {
                        f[nu].z = -1;
                    }
                    else {
                        FOR(i, 0, 26) {
                            f[nu].vals[i] += calc(nu, 'a' + i);
                        }
                        f[nu].z += calc(nu, '?');
                    }
                    for (int w : vv) {
                        change[w] = f[nu].vals[w] - tmp.vals[w];
                    }
                    u = nu;
                }
            }
            while (u) {
                nu = par[u];
                if (sz(adj[nu]) == 1) {
                    if (c[u] != '?') {
                        f[nu].vals[id[c[u]]]++;
                    }
                    else {
                        f[nu].z++;
                    }
                    nu = nxt[nu];
                    FOR(i, 0, 26) {
                        f[nu].vals[i] += calc(nu, 'a' + i);
                    }
                    f[nu].z += calc(nu, '?');
                }
                else {
                    int v = adj[nu][0] + adj[nu][1] - u;
                    if (f[u].z == -1 || f[v].z == -1) {
                        nu = nxt[nu];
                        f[nu].z = -1;
                    }
                    else {
                        for (int w : vv) {
                            int tmp = f[nu].vals[w];
                            f[u].vals[w] -= change[w];
                            f[u].vals[w] += c[u] == 'a' + w;
                            f[v].vals[w] += c[v] == 'a' + w;
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total -= f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total -= f[v].vals[w] - f[u].vals[w];
                            }
                            f[u].vals[w] += change[w];
                            if (f[v].vals[w] < f[u].vals[w]) {
                                f[nu].total += f[u].vals[w] - f[v].vals[w];
                            }
                            else {
                                f[nu].total += f[v].vals[w] - f[u].vals[w];
                            }
                            f[nu].vals[w] = max(f[u].vals[w], f[v].vals[w]);
                            f[u].vals[w] -= c[u] == 'a' + w;
                            f[v].vals[w] -= c[v] == 'a' + w;
                            change[w] = f[nu].vals[w] - tmp;
                        }
                        f[u].z += c[u] == '?';
                        f[v].z += c[v] == '?';
                        if (f[u].z + f[v].z < f[nu].total) {
                            nu = nxt[nu];
                            f[nu].z = -1;
                        }
                        else {
                            f[nu].z = (f[u].z + f[v].z - f[nu].total) / 2;
                            nu = nxt[nu];
                            FOR(i, 0, 26) {
                                f[nu].vals[i] += calc(nu, 'a' + i);
                            }
                            f[nu].z += calc(nu, '?');
                        }
                        f[u].z -= c[u] == '?';
                        f[v].z -= c[v] == '?';
                    }
                }
                u = nu;
            }
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); --i)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define present(t, x) (t.find(x) != t.end())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcountll(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int FFTMOD = 119 << 23 | 1;
const int INF = (int) 1e9 + 23111992;
const ll LINF = (ll) 1e18 + 23111992;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
inline ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
inline ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> inline int chkmin(T& a, const T& val) {return val < a ? a = val, 1 : 0;}
template<class T> inline int chkmax(T& a, const T& val) {return a < val ? a = val, 1 : 0;}
inline ull isqrt(ull k) {ull r = sqrt(k) + 1; while (r * r > k) r--; return r;}
inline ll icbrt(ll k) {ll r = cbrt(k) + 1; while (r * r * r > k) r--; return r;}
inline void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
inline void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
inline int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
inline int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}
inline int sign(ld x) {return x < -EPS ? -1 : x > +EPS;}
inline int sign(ld x, ld y) {return sign(x - y);}
mt19937 mt(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int mrand() {return abs((int) mt());}
#define db(x) cerr << "[" << #x << ": " << (x) << "] ";
#define endln cerr << "\n";

struct node_t {
    vi vals;
    int z;
    node_t() {
        vals.resize(26);
        z = -1;
    }
};

node_t join(node_t a, node_t b) {
    if (a.z == -1 || b.z == -1) return node_t();
    node_t c;
    int totala = 0, totalb = 0;
    FOR(i, 0, 26) {
        c.vals[i] = max(a.vals[i], b.vals[i]);
        if (a.vals[i] < b.vals[i]) {
            totala += b.vals[i] - a.vals[i];
        }
        else {
            totalb += a.vals[i] - b.vals[i];
        }
    }
    if (a.z < totala || b.z < totalb) {
        return node_t();
    }
    assert(a.z - totala == b.z - totalb);
    c.z = a.z - totala;
    return c;
}

node_t add(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z++;
    }
    else {
        a.vals[c - 'a']++;
    }
    return a;
}

node_t rem(node_t a, char c) {
    if (a.z == -1) return a;
    if (c == '?') {
        a.z--;
    }
    else {
        a.vals[c - 'a']--;
    }
    return a;
}

void solve() {
    int n, q; cin >> n >> q;
    vector<vi> adj(n);
    vi par(n);
    vector<char> c(n);
    FOR(i, 1, n) {
        cin >> par[i] >> c[i]; par[i]--;
        adj[par[i]].pb(i);
    }
    vi lev(n);
    vi nxt(n);
    function<void(int)> dfs = [&] (int u) {
        nxt[u] = u;
        for (int v : adj[u]) {
            lev[v] = lev[u] + 1;
            if (sz(adj[u]) == 1) {
                nxt[v] = nxt[u];
            }
            dfs(v);
        }
    };
    dfs(0);
    vi vals;
    FOR(u, 1, n) if (!sz(adj[u])) {
        vals.pb(lev[u]);
    }
    sort(all(vals)), uni(vals);
    if (sz(vals) ^ 1) {
        while (q--) {
            int u; char c; cin >> u >> c; u--;
            cout << "Fou\n";
        }
        return;
    }
    vector<node_t> f(n);
    function<void(int)> upd_dfs = [&] (int u) {
        if (!sz(adj[u])) {
            f[u].z = 0;
        }
        for (int v : adj[u]) {
            upd_dfs(v);
            if (f[u].z == -1) {
                f[u] = add(f[v], c[v]);
            }
            else {
                f[u] = join(f[u], add(f[v], c[v]));
            }
        }
    };
    upd_dfs(0);
    while (q--) {
        int u; char x; cin >> u >> x; u--;
        int nu = nxt[u];
        if (u ^ nu) {
            f[nu] = rem(f[nu], c[u]);
            c[u] = x;
            f[nu] = add(f[nu], c[u]);
            u = nu;
        }
        else {
            c[u] = x;
        }
        while (u) {
            nu = nxt[par[u]];
            f[nu] = node_t();
            for (int v : adj[nu]) {
                if (f[nu].z == -1) {
                    f[nu] = add(f[v], c[v]);
                }
                else {
                    f[nu] = join(f[nu], add(f[v], c[v]));
                }
            }
            u = nu;
        }
        if (f[0].z == -1) {
            cout << "Fou\n";
        }
        else {
            long long res = 0;
            FOR(i, 0, 26) {
                res += (i + 1) * (f[0].vals[i] + f[0].z);
            }
            cout << "Shi " << res << "\n";
        }
    }
}

int main(int argc, char* argv[]) {
    ios_base::sync_with_stdio(0), cin.tie(0);
    if (argc > 1) {
        assert(freopen(argv[1], "r", stdin));
    }
    if (argc > 2) {
        assert(freopen(argv[2], "wb", stdout));
    }
    solve();
    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
#define mp make_pair
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int A = 26;
const int N = 150100;
int n, q;
int deg[N];
char s[N];
int a[N][2][A];
int par[N];
pii realPar[N];
bool imp[N];
vector<int> g[N];
int h[N];
bool ALL_BAD = false;
int cntBad = 0;
int H;
int curV[N];
int sumForV[N];

void dfs(int v, pii rp) {
	realPar[v] = rp;
	if (imp[v]) {
		for (int i = 0; i < (int)g[v].size(); i++)
			dfs(g[v][i], mp(v, i));
	} else {
		for (int u : g[v])
			dfs(u, rp);
	}
}

bool badV(int v) {
	return h[v] + sumForV[v] > H;
}

void setForLet(int v, int c, int p, int val) {
	if (badV(v)) cntBad--;
	sumForV[v] -= max(a[v][0][c], a[v][1][c]);
	a[v][p][c] = val;
	sumForV[v] += max(a[v][0][c], a[v][1][c]);
	if (badV(v)) cntBad++;
}

void updUp(int v, int c, int dx) {
	if (v == 0) return;
	bool st = false;
	while(v != 0) {
		int u = realPar[v].first;
		int p = realPar[v].second;
		int old = max(a[u][0][c], a[u][1][c]);
		setForLet(u, c, p, a[u][p][c] + dx);
		if (old == max(a[u][0][c], a[u][1][c])) break;
		v = u;
	}
}

void printAns() {
	if (cntBad != 0) {
		printf("Fou\n");
		return;
	}
	int res = 0;
	for (int c = 0; c < A; c++) {
		res += (c + 1) * (H - sumForV[0] + max(a[0][0][c], a[0][1][c]));
	}
	printf("Shi %d\n", res);
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d%d", &n, &q);
	h[0] = 0;
	for (int i = 1; i < n; i++) {
		int v;
		char c;
		scanf("%d %c", &v, &c);
		v--;
		s[i] = c;
		par[i] = v;
		g[v].push_back(i);
		deg[v]++;
		h[i] = h[v] + 1;
	}
//	for (int i = 0; i < n; i++)
//		eprintf("%d ", h[i]);
//	eprintf("\n");
	H = -1;
	for (int i = 0; i < n; i++) {
		if (deg[i] != 0) continue;
		if (H == -1)
			H = h[i];
		if (H != h[i])
			ALL_BAD = true;
	}
	if (ALL_BAD) {
		while(q--) printf("Fou\n");
		return 0;
	}
//	eprintf("H = %d\n", H);
	for (int i = 0; i < n; i++)
		if (deg[i] == 2)
			imp[i] = 1;
	imp[0] = 1;
	dfs(0, mp(-1, -1));
	for (int i = 1; i < n; i++) {
		if (s[i] != '?')
			updUp(i, (int)(s[i] - 'a'), 1);
	}
	while(q--) {
		int v;
		char c;
		scanf("%d %c", &v, &c);
		v--;
		if (s[v] != '?')
			updUp(v, (int)(s[v] - 'a'), -1);
		s[v] = c;
		if (s[v] != '?')
			updUp(v, (int)(s[v] - 'a'), 1);
		printAns();
	}

	return 0;
}


#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

typedef long long ll;

const int nax = 3e5 + 5;
int par[nax];
vector<int> children[nax];
char ch[nax];
int in[nax], out[nax];
int depth[nax];
pair<int,int> nxt_par[nax];
int T = 0;
int has[nax][26][2];
int total[nax];

struct Node {
	int big, lazy;
	void add(int x) {
		big += x;
		lazy += x;
	}
};

int B = 1;

struct Tree {
	vector<Node> tree;
	void rec(int id, int low, int high, int q_low, int q_high, int diff) {
		if(high < q_low || q_high < low) {
			return;
		}
		if(q_low <= low && high <= q_high) {
			tree[id].add(diff);
			return;
		}
		for(int b : {2 * id, 2 * id + 1}) {
			tree[b].add(tree[id].lazy);
		}
		tree[id].lazy = 0;
		int last_left = (low + high) / 2;
		rec(2 * id, low, last_left, q_low, q_high, diff);
		rec(2 * id + 1, last_left + 1, high, q_low, q_high, diff);
		tree[id].big = max(tree[2*id].big, tree[2*id+1].big);
	}
} trees[26];

void dfs(int a) {
	in[a] = ++T;
	for(int b : children[a]) {
		depth[b] = depth[a] + 1;
		dfs(b);
	}
	out[a] = T;
}

int main() {
	int n, q;
	scanf("%d%d", &n, &q);
	for(int i = 2; i <= n; ++i) {
		scanf("%d %c", &par[i], &ch[i]);
		children[par[i]].push_back(i);
	}
	for(int i = 2; i <= n; ++i) {
		int p = par[i];
		if((int) children[p].size() >= 2) {
			int which = -1;
			if(children[p][0] == i) {
				which = 0;
			}
			else if(children[p][1] == i) {
				which = 1;
			}
			else {
				assert(false);
			}
			nxt_par[i] = make_pair(p, which);
		}
		else {
			nxt_par[i] = nxt_par[p];
		}
	}
	dfs(1);
	int should = -1;
	for(int i = 2; i <= n; ++i) {
		if(children[i].empty()) {
			if(should == -1) {
				should = depth[i];
				continue;
			}
			if(should != depth[i]) {
				while(q--) {
					puts("Fou");
				}
				return 0;
			}
		}
	}
	assert(should != -1);
	while(B <= n) {
		B *= 2;
	}
	for(int i = 0; i < 26; ++i) {
		trees[i].tree.resize(2 * B, Node{0, 0});
	}
	for(int i = 1; i <= n; ++i) {
		total[i] = should - depth[i];
	}
	int bad = 0;
	for(int i = 2; i <= n; ++i) {
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			trees[A].rec(1, 0, B - 1, in[i], out[i], 1);

			for(pair<int,int> x = nxt_par[i]; x.first; x = nxt_par[x.first]) {
				if(total[x.first] < 0) {
					--bad;
				}
				total[x.first] += max(has[x.first][A][0], has[x.first][A][1]);
				has[x.first][A][x.second]++;
				total[x.first] -= max(has[x.first][A][0], has[x.first][A][1]);
				if(total[x.first] < 0) {
					++bad;
				}
			}
		}
	}
	while(q--) {
		int i;
		char letter;
		scanf("%d %c", &i, &letter);
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			trees[A].rec(1, 0, B - 1, in[i], out[i], -1);

			for(pair<int,int> x = nxt_par[i]; x.first; x = nxt_par[x.first]) {
				if(total[x.first] < 0) {
					--bad;
				}
				total[x.first] += max(has[x.first][A][0], has[x.first][A][1]);
				has[x.first][A][x.second]--;
				total[x.first] -= max(has[x.first][A][0], has[x.first][A][1]);
				if(total[x.first] < 0) {
					++bad;
				}
			}
		}
		ch[i] = letter;
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			trees[A].rec(1, 0, B - 1, in[i], out[i], 1);

			for(pair<int,int> x = nxt_par[i]; x.first; x = nxt_par[x.first]) {
				if(total[x.first] < 0) {
					--bad;
				}
				total[x.first] += max(has[x.first][A][0], has[x.first][A][1]);
				has[x.first][A][x.second]++;
				total[x.first] -= max(has[x.first][A][0], has[x.first][A][1]);
				if(total[x.first] < 0) {
					++bad;
				}
			}
		}
		vector<int> info(26);
		int suma = 0;
		for(int j = 0; j < 26; ++j) {
			info[j] = trees[j].tree[1].big;
			suma += info[j];
		}
		if(suma > should || bad > 0) {
			puts("Fou");
		}
		else {
			long long answer = 0;
			for(int j = 0; j < 26; ++j) {
				answer += (long long) (j + 1) * (info[j] + should - suma);
			}
			printf("Shi %lld\n", answer);
		}
		// debug() << imie(suma);
	}
}


#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

typedef long long ll;

const int nax = 3e5 + 5;
int par[nax];
vector<int> children[nax];
char ch[nax];
int in[nax], out[nax];
int depth[nax];
int T = 0;

struct Node {
	int big, lazy;
	void add(int x) {
		big += x;
		lazy += x;
	}
};

int B = 1;

struct Tree {
	vector<Node> tree;
	void rec(int id, int low, int high, int q_low, int q_high, int diff) {
		if(high < q_low || q_high < low) {
			return;
		}
		if(q_low <= low && high <= q_high) {
			tree[id].add(diff);
			return;
		}
		for(int b : {2 * id, 2 * id + 1}) {
			tree[b].add(tree[id].lazy);
		}
		tree[id].lazy = 0;
		int last_left = (low + high) / 2;
		rec(2 * id, low, last_left, q_low, q_high, diff);
		rec(2 * id + 1, last_left + 1, high, q_low, q_high, diff);
		tree[id].big = max(tree[2*id].big, tree[2*id+1].big);
	}
} trees[26];

void dfs(int a) {
	in[a] = ++T;
	for(int b : children[a]) {
		depth[b] = depth[a] + 1;
		dfs(b);
	}
	out[a] = T;
}

int main() {
	int n, q;
	scanf("%d%d", &n, &q);
	for(int i = 2; i <= n; ++i) {
		scanf("%d %c", &par[i], &ch[i]);
		children[par[i]].push_back(i);
	}
	dfs(1);
	int should = -1;
	for(int i = 2; i <= n; ++i) {
		if(children[i].empty()) {
			if(should == -1) {
				should = depth[i];
				continue;
			}
			if(should != depth[i]) {
				while(q--) {
					puts("Fou");
				}
				return 0;
			}
		}
	}
	assert(should != -1);
	while(B <= n) {
		B *= 2;
	}
	for(int i = 0; i < 26; ++i) {
		trees[i].tree.resize(2 * B, Node{0, 0});
	}
	for(int i = 2; i <= n; ++i) {
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			trees[A].rec(1, 0, B - 1, in[i], out[i], 1);
		}
	}
	while(q--) {
		int i;
		char letter;
		scanf("%d %c", &i, &letter);
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			trees[A].rec(1, 0, B - 1, in[i], out[i], -1);
		}
		ch[i] = letter;
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			trees[A].rec(1, 0, B - 1, in[i], out[i], 1);
		}
		vector<int> info(26);
		int suma = 0;
		for(int i = 0; i < 26; ++i) {
			info[i] = trees[i].tree[1].big;
			suma += info[i];
		}
		if(suma > should) {
			puts("Fou");
		}
		else {
			long long answer = 0;
			for(int i = 0; i < 26; ++i) {
				answer += (long long) (i + 1) * (info[i] + should - suma);
			}
			printf("Shi %lld\n", answer);
		}
		// debug() << imie(suma);
	}
}


#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

typedef long long ll;

#ifdef LOCAL
const int nax = 105;
#else
const int nax = 3e5 + 5;
#endif
int par[nax];
vector<int> children[nax];
char ch[nax];
int in[nax], out[nax];
int depth[nax];
pair<int,int> nxt_par[nax];
int T = 0;
int has[nax][26][2];
int total[nax];

struct Node {
	int big, lazy;
	void add(int x) {
		big += x;
		lazy += x;
	}
};

int B = 1;

struct Tree {
	vector<Node> tree;
	void rec(int id, int low, int high, int q_low, int q_high, int diff) {
		if(high < q_low || q_high < low) {
			return;
		}
		if(q_low <= low && high <= q_high) {
			tree[id].add(diff);
			return;
		}
		for(int b : {2 * id, 2 * id + 1}) {
			tree[b].add(tree[id].lazy);
		}
		tree[id].lazy = 0;
		int last_left = (low + high) / 2;
		rec(2 * id, low, last_left, q_low, q_high, diff);
		rec(2 * id + 1, last_left + 1, high, q_low, q_high, diff);
		tree[id].big = max(tree[2*id].big, tree[2*id+1].big);
	}
} trees[26];

void dfs(int a) {
	in[a] = ++T;
	for(int b : children[a]) {
		depth[b] = depth[a] + 1;
		dfs(b);
	}
	out[a] = T;
}

int bad;
void add(int i, int A, int diff) {
	debug();
	debug() << "add" imie(i) imie(A) imie(diff);
	trees[A].rec(1, 0, B - 1, in[i], out[i], diff);
	for(pair<int,int> x = nxt_par[i]; x.first; x = nxt_par[x.first]) {
		debug() << "> " imie(x);
		if(total[x.first] < 0) {
			--bad;
		}
		int Z = max(has[x.first][A][0], has[x.first][A][1]);
		total[x.first] += Z;
		has[x.first][A][x.second] += diff;
		int Y = max(has[x.first][A][0], has[x.first][A][1]);
		total[x.first] -= Y; //max(has[x.first][A][0], has[x.first][A][1]);
		if(total[x.first] < 0) {
			++bad;
		}
		if(total[x.first] < 0) {
			debug() << ">>> " imie(x) imie(has[x.first][A][0]) imie(has[x.first][A][1]) imie(total[x.first]);
			debug() << ">>>2 " imie(has[x.first][3][0]) imie(has[x.first][3][1]);
		}
		if(Z == Y) {
			break;
		}
	}
}

int main() {
	int n, q;
	scanf("%d%d", &n, &q);
	for(int i = 2; i <= n; ++i) {
		scanf("%d %c", &par[i], &ch[i]);
		children[par[i]].push_back(i);
	}
	for(int i = 2; i <= n; ++i) {
		int p = par[i];
		if((int) children[p].size() >= 2) {
			int which = -1;
			if(children[p][0] == i) {
				which = 0;
			}
			else if(children[p][1] == i) {
				which = 1;
			}
			else {
				assert(false);
			}
			nxt_par[i] = make_pair(p, which);
		}
		else {
			nxt_par[i] = nxt_par[p];
		}
	}
	dfs(1);
	int should = -1;
	for(int i = 2; i <= n; ++i) {
		if(children[i].empty()) {
			if(should == -1) {
				should = depth[i];
				continue;
			}
			if(should != depth[i]) {
				debug() << "spec";
				while(q--) {
					puts("Fou");
				}
				return 0;
			}
		}
	}
	assert(should != -1);
	while(B <= n) {
		B *= 2;
	}
	for(int i = 0; i < 26; ++i) {
		trees[i].tree.resize(2 * B, Node{0, 0});
	}
	for(int i = 1; i <= n; ++i) {
		total[i] = should - depth[i];
	}
	for(int i = 2; i <= n; ++i) {
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			add(i, A, 1);
		}
	}
	debug();
	debug() << imie(bad);
	while(q--) {
		int i;
		char letter;
		scanf("%d %c", &i, &letter);
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			add(i, A, -1);
		}
		ch[i] = letter;
		if(ch[i] != '?') {
			int A = ch[i] - 'a';
			add(i, A, 1);
		}
		vector<int> info(26);
		int suma = 0;
		for(int j = 0; j < 26; ++j) {
			info[j] = trees[j].tree[1].big;
			suma += info[j];
		}
		debug() << imie(suma) imie(should) imie(bad);
		if(suma > should || bad > 0) {
			puts("Fou");
		}
		else {
			long long answer = 0;
			for(int j = 0; j < 26; ++j) {
				answer += (long long) (j + 1) * (info[j] + should - suma);
			}
			// #warning print everything
			// puts("Shi");
			printf("Shi %lld\n", answer);
		}
		// debug() << imie(suma);
	}
}


#include<bits/stdc++.h>
#define ll long long
#define N 300005
#define M 30
using namespace std;
int n,q,c[N],son[N],p[N],num[N][M],sum[N],par[N],cnt[N][M],h[N],belong[N],bad,m,x;
vector<int>G[N];
char ch;
int get(char ch){
	if(ch=='?') return 26;
	return ch-'a';
}
void work(int x,int c){
	while(x!=1){
		int fa=par[x];
		int a,b;
		if(G[fa].size()==2)a=G[fa][0],b=G[fa][1];
		else a=b=G[fa][0];
		if(b==x) swap(a,b);
		int lst=num[fa][c];
		num[fa][c]=max(num[a][c]+cnt[a][c],num[b][c]+cnt[b][c]);
		if(sum[fa]>h[fa]&&sum[fa]+num[fa][c]-lst<=h[fa]) bad--;
		if(sum[fa]<=h[fa]&&sum[fa]+num[fa][c]-lst>h[fa]) bad++;
		sum[fa]+=num[fa][c]-lst;
		x=fa;
	}
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=2;i<=n;i++){
		scanf("%d %c",&p[i],&ch);
		c[i]=get(ch);
		son[p[i]]++;
	}
	for(int i=n;i>1;i--){
		if(h[p[i]]&&h[p[i]]!=h[i]+1){
			cout<<"Fou"<<endl;
			return 0;
		}
		h[p[i]]=h[i]+1;
	}
	belong[1]=1;par[1]=0;
	for(int i=2;i<=n;i++){
		if(p[i]==1||son[p[i]]>1){
			par[i]=belong[p[i]];
			belong[i]=i;
		}else{
			par[i]=belong[p[i]];
			belong[i]=belong[p[i]];
		}
		cnt[belong[i]][c[i]]++;
	}
	for(int i=n;i>=1;i--)
	if(belong[i]==i){
		for(int j=0;j<26;j++)
			sum[i]+=num[i][j];
		if(sum[i]>h[i]) bad++;
		for(int j=0;j<26;j++)
			num[par[i]][j]=max(num[par[i]][j],num[i][j]+cnt[i][j]);
		G[par[i]].push_back(i);
	}
	while(q--){
		scanf("%d %c",&x,&ch);
		int tc=get(ch);
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]--;
			work(belong[x],c[x]);
		}
		c[x]=tc;
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]++;
			work(belong[x],c[x]);
		}
		if(bad){
			puts("Fou");
		}else{
			printf("Shi ");
			ll ans=0;
			for(int i=0;i<26;i++){
				ans+=(i+1)*(h[1]-sum[1]+num[1][i]);
			}
			printf("%lld\n",ans);
		}
	}
}


#include<bits/stdc++.h>
#define ll long long
#define N 300005
#define M 30
using namespace std;
int n,q,c[N],son[N],p[N],num[N][M],sum[N],par[N],cnt[N][M],h[N],belong[N],bad,m,x;
vector<int>G[N];
char ch;
int get(char ch){
	if(ch=='?') return 26;
	return ch-'a';
}
void work(int x,int c){
	while(x!=1){
		int fa=par[x];
		int a=G[fa][0],b=G[fa][1];
		if(b==x) swap(a,b);
		int lst=num[fa][c];
		num[fa][c]=max(num[a][c]+cnt[a][c],num[b][c]+cnt[b][c]);
		if(sum[fa]>h[fa]&&sum[fa]+num[fa][c]-lst<=h[fa]) bad--;
		if(sum[fa]<=h[fa]&&sum[fa]+num[fa][c]-lst>h[fa]) bad++;
		sum[fa]+=num[fa][c]-lst;
		x=fa;
	}
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=2;i<=n;i++){
		scanf("%d %c",&p[i],&ch);
		c[i]=get(ch);
		son[p[i]]++;
	}
	for(int i=n;i>1;i--){
		if(h[p[i]]&&h[p[i]]!=h[i]+1){
			cout<<"Fou"<<endl;
			return 0;
		}
		h[p[i]]=h[i]+1;
	}
	belong[1]=1;par[1]=0;
	for(int i=2;i<=n;i++){
		if(p[i]==1||son[p[i]]>1){
			par[i]=belong[p[i]];
			belong[i]=i;
		}else{
			par[i]=belong[p[i]];
			belong[i]=belong[p[i]];
		}
		cnt[belong[i]][c[i]]++;
	}
	for(int i=n;i>=1;i--)
	if(belong[i]==i){
		for(int j=0;j<26;j++)
			sum[i]+=num[i][j];
		if(sum[i]>h[i]) bad++;
		for(int j=0;j<26;j++)
			num[par[i]][j]=max(num[par[i]][j],num[i][j]+cnt[i][j]);
		G[par[i]].push_back(i);
	}
	while(q--){
		scanf("%d %c",&x,&ch);
		int tc=get(ch);
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]--;
			work(belong[x],c[x]);
		}
		c[x]=tc;
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]++;
			work(belong[x],c[x]);
		}
		if(bad){
			puts("Fou");
		}else{
			printf("Shi ");
			ll ans=0;
			for(int i=0;i<26;i++){
				ans+=(i+1)*(h[1]-sum[1]+num[1][i]);
			}
			printf("%lld\n",ans);
		}
	}
}


#include<bits/stdc++.h>
#define ll long long
#define N 300005
#define M 30
using namespace std;
int n,q,c[N],son[N],p[N],num[N][M],sum[N],par[N],cnt[N][M],h[N],belong[N],bad,m,x;
vector<int>G[N];
char ch;
int get(char ch){
	if(ch=='?') return 26;
	return ch-'a';
}
void work(int x,int c){
	while(x!=1){
		int fa=par[x];
		int a,b;
		if(G[fa].size()==2)a=G[fa][0],b=G[fa][1];
		else a=b=G[fa][0];
		if(b==x) swap(a,b);
		int lst=num[fa][c];
		num[fa][c]=max(num[a][c]+cnt[a][c],num[b][c]+cnt[b][c]);
		if(sum[fa]>h[fa]&&sum[fa]+num[fa][c]-lst<=h[fa]) bad--;
		if(sum[fa]<=h[fa]&&sum[fa]+num[fa][c]-lst>h[fa]) bad++;
		sum[fa]+=num[fa][c]-lst;
		x=fa;
	}
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=2;i<=n;i++){
		scanf("%d %c",&p[i],&ch);
		c[i]=get(ch);
		son[p[i]]++;
	}
	for(int i=n;i>1;i--){
		if(h[p[i]]&&h[p[i]]!=h[i]+1){
			bad=q+1;
		}
		h[p[i]]=h[i]+1;
	}
	belong[1]=1;par[1]=0;
	for(int i=2;i<=n;i++){
		if(p[i]==1||son[p[i]]>1||son[i]>1){
			par[i]=belong[p[i]];
			belong[i]=i;
		}else{
			par[i]=belong[p[i]];
			belong[i]=belong[p[i]];
		}
		cnt[belong[i]][c[i]]++;
	}
	for(int i=n;i>=1;i--)
	if(belong[i]==i){
		for(int j=0;j<26;j++)
			sum[i]+=num[i][j];
		if(sum[i]>h[i]) bad++;
		for(int j=0;j<26;j++)
			num[par[i]][j]=max(num[par[i]][j],num[i][j]+cnt[i][j]);
		G[par[i]].push_back(i);
	}
	while(q--){
		scanf("%d %c",&x,&ch);
		int tc=get(ch);
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]--;
			work(belong[x],c[x]);
		}
		c[x]=tc;
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]++;
			work(belong[x],c[x]);
		}
		if(bad){
			printf("Fou\n");
		}else{
			printf("Shi ");
			ll ans=0;
			for(int i=0;i<26;i++){
				ans+=(i+1)*(h[1]-sum[1]+num[1][i]);
			}
			printf("%lld\n",ans);
		}
	}
}


#include<bits/stdc++.h>
#define ll long long
#define N 300005
#define M 30
using namespace std;
int n,q,c[N],son[N],p[N],num[N][M],sum[N],par[N],cnt[N][M],h[N],belong[N],bad,m,x;
vector<int>G[N];
char ch;
int get(char ch){
	if(ch=='?') return 26;
	return ch-'a';
}
void work(int x,int c){
	while(x!=1){
		int fa=par[x];
		int a,b;
		if(G[fa].size()==2)a=G[fa][0],b=G[fa][1];
		else a=b=G[fa][0];
		if(b==x) swap(a,b);
		int lst=num[fa][c];
		num[fa][c]=max(num[a][c]+cnt[a][c],num[b][c]+cnt[b][c]);
		if(sum[fa]>h[fa]&&sum[fa]+num[fa][c]-lst<=h[fa]) bad--;
		if(sum[fa]<=h[fa]&&sum[fa]+num[fa][c]-lst>h[fa]) bad++;
		sum[fa]+=num[fa][c]-lst;
		x=fa;
	}
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=2;i<=n;i++){
		scanf("%d %c",&p[i],&ch);
		c[i]=get(ch);
		son[p[i]]++;
	}
	for(int i=n;i>1;i--){
		if(h[p[i]]&&h[p[i]]!=h[i]+1){
			cout<<"Fou"<<endl;
			return 0;
		}
		h[p[i]]=h[i]+1;
	}
	belong[1]=1;par[1]=0;
	for(int i=2;i<=n;i++){
		if(p[i]==1||son[p[i]]>1||son[i]>1){
			par[i]=belong[p[i]];
			belong[i]=i;
		}else{
			par[i]=belong[p[i]];
			belong[i]=belong[p[i]];
		}
		cnt[belong[i]][c[i]]++;
	}
	for(int i=n;i>=1;i--)
	if(belong[i]==i){
		for(int j=0;j<26;j++)
			sum[i]+=num[i][j];
		if(sum[i]>h[i]) bad++;
		for(int j=0;j<26;j++)
			num[par[i]][j]=max(num[par[i]][j],num[i][j]+cnt[i][j]);
		G[par[i]].push_back(i);
	}
	while(q--){
		scanf("%d %c",&x,&ch);
		int tc=get(ch);
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]--;
			work(belong[x],c[x]);
		}
		c[x]=tc;
		if(c[x]!=26) {
			cnt[belong[x]][c[x]]++;
			work(belong[x],c[x]);
		}
		if(bad){
			puts("Fou");
		}else{
			printf("Shi ");
			ll ans=0;
			for(int i=0;i<26;i++){
				ans+=(i+1)*(h[1]-sum[1]+num[1][i]);
			}
			printf("%lld\n",ans);
		}
	}
}


#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

#define maxN 223456

vector<int> son[maxN], scomp[maxN];
int dp[maxN][30], cnt[maxN][30];
int id[maxN], idpar[maxN], par[maxN], depc[maxN], sumd[maxN], invalid[maxN];
int n, q, dep, idx, cnts;
char t[maxN], s[30];

void dfs(int u, int d) {
	if (son[u].empty()) {
		if (dep == -1) {
			dep = d;
		}
		if (d != dep) {
			for (int i = 0; i < q; i++)
				printf("Fou\n");
			exit(0);
		}
	}
	depc[id[u]] = max(depc[id[u]], d);
	for (auto v : son[u]) {
		if (u == 1 || (int)son[u].size() >= 2) {
			id[v] = ++idx;
			idpar[idx] = id[u];
			scomp[id[u]].push_back(idx);
		} else {
			id[v] = id[u];
		}
		dfs(v, d + 1);
	}
}

void modify(int u, int c, int delta) {
	if (c < 0) return;
	u = id[u];
	cnt[u][c] += delta;
	while (true) {
		sumd[u] -= dp[u][c];
		cnts -= invalid[u];
		dp[u][c] = 0;
		for (auto v : scomp[u]) {
			dp[u][c] = max(dp[u][c], dp[v][c] + cnt[v][c]);
		}
		sumd[u] += dp[u][c];
		invalid[u] = sumd[u] > dep - depc[u];
		cnts += invalid[u];
		if (u == 0)
			break;
		u = idpar[u];
	}
}

int main() {
	scanf("%d%d", &n, &q);
	for (int i = 2; i <= n; i++) {
		scanf("%d%s", &par[i], s);
		t[i] = s[0];
		son[par[i]].push_back(i);
	}
	dep = -1;
	dfs(1, 0);
	for (int i = 2; i <= n; i++) {
		modify(i, t[i] - 'a', 1);
	}
	for (int i = 0; i < q; i++) {
		int u;
		scanf("%d%s", &u, s);
		modify(u, t[u] - 'a', -1);
		t[u] = s[0];
		modify(u, t[u] - 'a', 1);
		if (cnts) {
			printf("Fou\n");
			continue;
		}
		i64 ans = 0;
		for (int i = 0; i < 26; i++) {
			ans += (i + 1) * (dep - (sumd[0] - dp[0][i]));
		}
		printf("Shi %lld\n", ans);
	}
}