#define _CRT_SECURE_NO_DEPRECATE
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <memory.h>
#include <set>
#include <ctime>
#include <map>
#include <cstring>
#include <iterator>
#include <queue>

using namespace std;

#define ll long long
#define ld long double
#define pb push_back
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pdd pair<double, double>
#define pldld pair<ld, ld>
#define mp make_pair
#define ull unsigned long long
#define pss pair<string, string>
#pragma comment(linker, "/STACK:64000000")
#define null NULL

const int infi = 1e9 + 7;
const ll infl = 1e18;
const long double eps = (ld)1e-8;
const long double eps1 = 1e-10;
const int mod = (1e9 + 7);
const ll mod1 = (1e9 + 7);
const ll mod2 = 1e9 + 9;
const ll mod3 = (ll)(1e9);
const ll p1 = 31;
const ll p2 = 37;
const ll p3 = 29;
const ull maxn = 10000000000000000LL;
const ull maxres = 800000;

int resh[500500];
int s[500500];
int fc[20];
int fact(int a) {
    int sz = 0;
    while (a > 1 && resh[a]) {
        fc[sz] = resh[a];
        while (!(a % fc[sz])) {
            a /= fc[sz];
        }
        ++sz;
    }
    if (a > 1) {
        fc[sz++] = a;
    }
    return sz;
}
int flag;
int getans(int i, int a, int sum) {
    if (i < 0) {
        int ans;
        if (flag == 1) {
            if (sum & 1) {
                ans = -s[a];
            }
            ans = s[a];
            s[a]++;
        }
        else {
            --s[a];
            if (sum & 1) {
                ans = -s[a];
            }
            ans = s[a];
        }
        return ans;
    }
    return getans(i - 1, a, sum) + getans(i - 1, a * fc[i], sum + 1);
}
int ar[200500];
int used[200500];

int main() {
   // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    //freopen(".in", "r", stdin); freopen(".out", "w", stdout);
    for (int i = 2; i * i < 500500; ++i) {
        if (!resh[i]) {
            for (int j = i * i; j < 500500; j += i) {
                resh[j] = i;
            }
        }
    }
    int n, q;
    cin >> n >> q;
    ll ans =0;
    for (int i = 0; i < n; ++i) {
        cin >> ar[i];
    }
    for (;q;--q) {
        int x;
        cin >> x;
        if (used[x -1]) {
            flag = -1;
        }
        else {
            flag = 1;
        }
        used[x - 1] ^= 1;
        ans += (ll)getans(fact(ar[x - 1]) - 1, 1, 0) * (ll)flag;
        cout << ans << endl;
    }
    return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <memory.h>
#include <set>
#include <ctime>
#include <map>
#include <cstring>
#include <iterator>
#include <queue>

using namespace std;

#define ll long long
#define ld long double
#define pb push_back
#define pii pair<int, int>
#define pll pair<long long, long long>
#define pdd pair<double, double>
#define pldld pair<ld, ld>
#define mp make_pair
#define ull unsigned long long
#define pss pair<string, string>
#pragma comment(linker, "/STACK:64000000")
#define null NULL

const int infi = 1e9 + 7;
const ll infl = 1e18;
const long double eps = (ld)1e-8;
const long double eps1 = 1e-10;
const int mod = (1e9 + 7);
const ll mod1 = (1e9 + 7);
const ll mod2 = 1e9 + 9;
const ll mod3 = (ll)(1e9);
const ll p1 = 31;
const ll p2 = 37;
const ll p3 = 29;
const ull maxn = 10000000000000000LL;
const ull maxres = 800000;

int resh[500500];
int s[500500];
int fc[20];
int fact(int a) {
    int sz = 0;
    while (a > 1 && resh[a]) {
        fc[sz] = resh[a];
        while (!(a % fc[sz])) {
            a /= fc[sz];
        }
        ++sz;
    }
    if (a > 1) {
        fc[sz++] = a;
    }
    return sz;
}
int flag;
int getans(int i, int a, int sum) {
    if (i < 0) {
        s[a] += flag;
        if (sum & 1) {
            return -(s[a] - flag);
        }
        return s[a] - flag;
    }
    return getans(i - 1, a, sum) + getans(i - 1, a * fc[i], sum + 1);
}
int ar[200500];
int used[200500];

int main() {
   // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    //freopen(".in", "r", stdin); freopen(".out", "w", stdout);
    for (int i = 2; i * i < 500500; ++i) {
        if (!resh[i]) {
            for (int j = i * i; j < 500500; j += i) {
                resh[j] = i;
            }
        }
    }
    int n, q;
    cin >> n >> q;
    ll ans =0;
    for (int i = 0; i < n; ++i) {
        cin >> ar[i];
    }
    for (;q;--q) {
        int x;
        cin >> x;
        if (used[x -1]) {
            flag = -1;
        }
        else {
            flag = 1;
        }
        used[x - 1] ^= 1;
        ans += (ll)getans(fact(ar[x - 1]) - 1, 1, 0) * (ll)flag;
        if (flag == -1) {
            ans ++;
        }
        cout << ans << endl;
    }
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

int n,q,x,tmp;
int a[200005],v[200005],vis[200005],c[200005],vt[200005];
long long ans;

void prime()
{
     for(int i=2;i<200005;i++)
     if(!vis[i])
     {
			v[i]=-1;
			for(int j=i+i;j<200005;j+=i)
			{
				vis[j]=1;
				if(j/i%i==0)v[j]=0; else v[j]*=-1;
			}
      }
}

int main()
{
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<200005;i++)v[i]=1;

    prime();

    ans=0;
	while(q--)
	{
		int x;
		cin>>x;
		for(int i=1;i*i<=a[x];i++)
		{
			if(a[x]%i==0)
			{
				tmp=i;
				if(vt[x])c[tmp]--;
				if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
				if(!vt[x])c[tmp]++;

				if(a[x]!=i*i)
				{
    				tmp=a[x]/i;
    				if(vt[x])c[tmp]--;
    				if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
    				if(!vt[x])c[tmp]++;
                }
			}
        }
        vt[x]^=1;
        cout<<ans<<endl;
	}
    //system("pause");
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

int n,q,x,tmp;
int a[200005],v[200005],vis[200005],c[200005],vt[200005];
long long ans;

int main()
{
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<200005;i++)v[i]=1;

    for(int i=2;i<200005;i++)
    {
        if(!vis[i])
        {
                v[i]=-1;
                for(int j=i+i;j<200005;j+=i)
                {
                    vis[j]=1;
                    if(j/i%i==0)v[j]=0; else v[j]*=-1;
                }
        }
    }

    ans=0;
    while(q--)
    {
        int x;
        cin>>x;
        for(int i=1;i*i<=a[x];i++)
        {
            if(a[x]%i==0)
            {
                tmp=i;
                if(vt[x])c[tmp]--;
                if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
                if(!vt[x])c[tmp]++;

                if(a[x]!=i*i)
                {
                    tmp=a[x]/i;
                    if(vt[x])c[tmp]--;
                    if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
                    if(!vt[x])c[tmp]++;
                }
            }
        }
        vt[x]^=1;
        cout<<ans<<endl;
    }
    //system("pause");
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

int n,q,x,tmp,ans;
int a[200005],v[200005],vis[200005],c[200005],vt[200005];

void prime()
{
     for(int i=2;i<200005;i++)
     if(!vis[i])
     {
			v[i]=-1;
			for(int j=i+i;j<200005;j+=i)
			{
				vis[j]=1;
				if (j/i%i==0)v[j]=0; else v[j]*=-1;
			}
      }
}

int main()
{
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<200005;i++)v[i]=1;

    prime();

    ans=0;
	while(q--)
	{
		int x;
		cin>>x;
		for(int i=1;i*i<=a[x];i++)
		{
			if(a[x]%i==0)
			{
				tmp=i;
				if(vt[x])c[tmp]--;
				if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
				if(!vt[x])c[tmp]++;

				if(a[x]!=i*i)
				{
    				tmp=a[x]/i;
    				if(vt[x])c[tmp]--;
    				if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
    				if(!vt[x])c[tmp]++;
                }
			}
        }
        vt[x]^=1;
        cout<<ans<<endl;
	}
    //system("pause");
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;

int n,q,x,tmp;
int a[200005],v[200005],vis[200005],c[200005],vt[200005];
long long ans;

int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);;
    for(int i=1;i<200005;i++)v[i]=1;

    for(int i=2;i<200005;i++)
    {
        if(!vis[i])
        {
    			v[i]=-1;
    			for(int j=i+i;j<200005;j+=i)
    			{
    				vis[j]=1;
    				if(j/i%i==0)v[j]=0; else v[j]*=-1;
    			}
        }
    }

    ans=0;
	while(q--)
	{
		int x;
		scanf("%d",&x);
		for(int i=1;i*i<=a[x];i++)
		{
			if(a[x]%i==0)
			{
				tmp=i;
				if(vt[x])c[tmp]--;
				if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
				if(!vt[x])c[tmp]++;

				if(a[x]!=i*i)
				{
    				tmp=a[x]/i;
    				if(vt[x])c[tmp]--;
    				if(vt[x])ans+=-1*c[tmp]*v[tmp]; else ans+=1*c[tmp]*v[tmp];
    				if(!vt[x])c[tmp]++;
                }
			}
        }
        vt[x]^=1;
        printf("%d\n",ans);
	}
    //system("pause");
    return 0;
}


#include <bits/stdc++.h>
#define fr(i,a,b) for (int i = (a); i < (b); ++i)
#define rp(i,b) fr(i,0,b)
#define st first
#define nd second
#define pb push_back
#define db(x) cerr << #x << " == " << x << endl
using namespace std;

typedef pair<int,int> ii;
typedef long long ll;
typedef vector<int> vi;

const double eps = 1e-7;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3fLL;

const int N = 500005;

int bs[N];

inline void sieve() {
  for (int i = 2; i < N; ++i) if (bs[i] == 0) {
    bs[i] = i;
    for (int j = i + i; j < N; j += i) {
      if (bs[j] == 0) bs[j] = i;
    }
  }
}

int inside[N], prime_cnt[N];
vector<int> factors[N], mults[N];

int main() {
  sieve();
  int n, q; scanf("%d %d", &n, &q);
  for (int i = 0; i < n; ++i) {
    int x; scanf("%d", &x);

    while (x != 1) {
      factors[i].push_back(bs[x]);
      x /= bs[x];
    }
    sort(factors[i].begin(), factors[i].end());
    int sz = unique(factors[i].begin(), factors[i].end()) - factors[i].begin();
    factors[i].resize(sz);

    for (int j = 1, e = 1 << factors[i].size(); j < e; ++j) {
      int m = -1;
      for (int k = 0; k < factors[i].size(); ++k) {
        if (j & (1 << k)) m = -m * factors[i][k];
      }
      mults[i].push_back(m);
    }
  }
  ll ans = 0;
  ll many_inside = 0;
  while (q --> 0) {
    int p; scanf("%d", &p); --p;
    if (inside[p]) {
      for (int i = 0; i < mults[p].size(); ++i) {
        --prime_cnt[abs(mults[p][i])];
      }
      --many_inside;
    }
    ll cnt = 0;
    for (int i = 0; i < mults[p].size(); ++i) {
      if (mults[p][i] < 0) {
        cnt -= prime_cnt[abs(mults[p][i])];
      } else {
        cnt += prime_cnt[abs(mults[p][i])];
      }
    }
    if (inside[p]) {
      ans -= many_inside - cnt;
    } else {
      ans += many_inside - cnt;
      ++many_inside;
      for (int i = 0; i < mults[p].size(); ++i) {
        ++prime_cnt[abs(mults[p][i])];
      }
    }
    inside[p] ^= 1;
    cout << ans << "\n";
  }
  return 0;
}


#include<cstdio>
#include<cstring>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cmath>

using namespace std;

typedef long long lld;

const int N = 600000;
int a[N];
int f[N];

const int pn = 600000;
int mark[pn];
int p[pn];
int prime(int n = pn-1){
    int num = 0, i, j;
    memset(mark, 0, sizeof(mark));
    for(i=2; i<=n; i++){
	if(!mark[i]) mark[i] = p[num++] = i;
	for(j=0; j<num && i*p[j]<n; j++){
	    mark[i*p[j]] = p[j];
	    if(i%p[j] == 0) break;
	}
    }
    return num;
}

int cnt[N];

lld dfs(int c, int f, int n, int m){
    //    cout << ":" << c << ' ' << m << ' ' << cnt[c] * f << endl;
    lld ans = 0;
    if (n != 1){
	int fac = mark[n];
	while (n % fac == 0) n /= fac;
	ans += dfs(c, f, n, m);
	ans += dfs(c*fac, f*-1, n, m);
    }else{
	ans = cnt[c] * f;
	cnt[c] += m;
    }
    return ans;
}

int main(){
    prime();
    int n, q;
    cin >> n >> q;
    for (int i=1; i<=n; ++i) cin >> a[i];
    memset(f, 0, sizeof(f));
    memset(cnt, 0, sizeof(cnt));
    lld ans = 0;
    for (int i=0; i<q; ++i){
	int x;
	cin >> x;
	int m = f[x] == 0 ? 1 : -1;
	f[x] ^= 1;
	ans += m * dfs(1, 1, a[x], m);
	if (m == -1 && a[x] == 1) ans ++;
	cout << ans << endl;
    }
    return 0;
}


#include<cstdio>
#include<cstring>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cmath>

using namespace std;

typedef long long lld;

const int N = 300000;
int a[N];
int f[N];

const int pn = 600000;
int mark[pn];
int p[pn];
int prime(int n = pn-1){
    int num = 0, i, j;
    memset(mark, 0, sizeof(mark));
    for(i=2; i<=n; i++){
	if(!mark[i]) mark[i] = p[num++] = i;
	for(j=0; j<num && i*p[j]<n; j++){
	    mark[i*p[j]] = p[j];
	    if(i%p[j] == 0) break;
	}
    }
    return num;
}

int cnt[N];

lld dfs(int c, int f, int n, int m){
    //    cout << ":" << c << ' ' << m << ' ' << cnt[c] * f << endl;
    lld ans = 0;
    if (n != 1){
	int fac = mark[n];
	while (n % fac == 0) n /= fac;
	ans += dfs(c, f, n, m);
	ans += dfs(c*fac, f*-1, n, m);
    }else{
	ans = cnt[c] * f;
	cnt[c] += m;
    }
    return ans;
}

int main(){
    prime();
    int n, q;
    cin >> n >> q;
    for (int i=1; i<=n; ++i) cin >> a[i];
    memset(f, 0, sizeof(f));
    memset(cnt, 0, sizeof(cnt));
    lld ans = 0;
    for (int i=0; i<q; ++i){
	int x;
	cin >> x;
	int m = f[x] == 0 ? 1 : -1;
	f[x] ^= 1;
	ans += m * dfs(1, 1, a[x], m);
	if (m == -1 && a[x] == 1) ans ++;
	cout << ans << endl;
    }
    return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#pragma comment(linker, "/STACK:64000000")

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <utility>
#include <memory.h>
#include <cstring>

#include <set>
#include <map>
#include <vector>
#include <string>
#include <queue>

#include <iostream>
#include <sstream>

using namespace std;

typedef long long int64;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define all(a) a.begin(), a.end()

const int INF = (int)1E9;
const int64 INF64 = (int64)1E18;
const long double EPS = 1E-8;
const long double PI = 3.1415926535897932384626433832795;

const int MAXN = 110;

int n, m, num;
vector<int> g[MAXN], st;
bool used[MAXN], G[MAXN][MAXN];

void DFS(int v) {
    used[v] = true;
    forn(i, g[v].size()) {
        int u = g[v][i];
        if (!used[u]) DFS(u);
    }

    st.pb(v);
    if (g[v].size() != 2) st.clear();
}

bool check() {
    if (st.size() < 3) return false;
    if ((int)st.size() != num) return false;

    forn(v, n)
        forn(i, g[v].size()) {
            int u = g[v][i];
            G[v][u] = G[u][v] = true;
        }

    forn(i, st.size()) {
        int v = st[i], u = st[(i + 1) % st.size()];
        if (!G[v][u]) return false;
    }

    return true;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

    cin >> n >> m;
    num = n;
    forn(i, m) {
        int v, u;
        cin >> v >> u;
        g[v - 1].pb(u - 1);
        g[u - 1].pb(v - 1);
    }

    while (true) {
        bool del = false;
        forn(i, n)
            if (g[i].size() == 1) {
                del = true;
                int v = g[i][0];
                g[i].clear();
                g[v].erase(find(all(g[v]), i));
                used[i] = true;
                num--;
            }

        if (!del) break;
    }

    forn(i, n)
        if (!used[i]) {
            DFS(i);
            break;
        }

    if (!check())
        cout << "NO" << endl;
    else
        cout << "FHTAGN!" << endl;

    return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
int ans=0;
int a = 0;
vector< int > v[101];
int visited[101];
int parent[101];
void dsf(int s)
{
	visited[s] = 1;
	for (int n = 0; n < v[s].size(); n++)
	{
		int d=v[s][n];

		if (visited[d] == 1 && parent[d] != s) ans++;
		else if(visited[d]==0)
		{
			parent[d] = s;

			dsf(d);

		}
	}
}
int main()
{
	int n, e;
	cin >> n >> e;
	int s, d;
	for (int m = 0; m < e; m++)
	{

		cin >> s >> d;
		v[s].push_back(d);
		v[d].push_back(s);
	}
	for (int m = 1; m <= n; m++)
	{
		if (visited[m] == 0)
		{
			parent[m] = m;
			dsf(m);
			a++;
		}

	}

	if (a == 1 && ans == 1)
		cout << "FHTAGN!";
	else
		cout << "NO";

	return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
int ans;
int a = 0;
vector< int > v[101];
int visited[101];
int parent[101];
void dsf(int s)
{
	for (int n = 0; n < v[s].size(); n++)
	{
		int d=v[s][n];

		if (visited[d] == 1 && parent[s] != d) ans++;
		else if (parent[s] == d)continue;
		else
		{
			parent[d] = s;
			visited[d] = 1;
			dsf(d);

		}
	}
}
int main()
{
	int n, e;
	cin >> n >> e;
	int s, d;
	for (int m = 0; m < e; m++)
	{

		cin >> s >> d;
		v[s].push_back(d);
		v[d].push_back(s);
	}
	for (int m = 1; m <= n; m++)
	{
		if (visited[m] == 0)
		{
			dsf(m);
			a++;
		}

	}

	if (a == 1 && ans == 1)
		cout << "FHTAGN!";
	else
		cout << "NO";
//	cin >> a;
	return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
int ans=0;
int a = 0;
vector< int > v[101];
int visited[101];
int parent[101];
void dsf(int s)
{
	visited[s] = 1;
	for (int n = 0; n < v[s].size(); n++)
	{
		int d = v[s][n];
		if (parent[s] != d && visited[d]!=2)
		{
			if (visited[d] == 1)
			{
				ans++;
				//cout << s << " " << d << endl;
			}
			else
			{
				visited[d] = 1;
				parent[d] = s;
				dsf(d);
			}
		}
	}
	visited[s] = 2;
}
int main()
{
	int n, e;
	cin >> n >> e;
	int s, d;
	for (int m = 0; m < e; m++)
	{

		cin >> s >> d;
		v[s].push_back(d);
		v[d].push_back(s);
	}
	for (int m = 1; m <= n; m++)
	{
		if (visited[m] == 0)
		{
			parent[m] = m;
			dsf(m);
			a++;
		}

	}
	//cout << a << " " << ans << endl;
	if (a == 1 && ans == 1)
		cout << "FHTAGN!";
	else
		cout << "NO";
	//cin >> a;
	return 0;
}


#include <iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
int ans;
int a = 0;
vector< int > v[101];
int visited[101];
int parent[101];
void dsf(int s)
{
	for (int n = 0; n < v[s].size(); n++)
	{
		int d=v[s][n];

		if (visited[d] == 1 && parent[s] != d) ans++;
		else if (parent[s] == d)continue;
		else
		{
			parent[d] = s;
			visited[d] = 1;
			dsf(d);

		}
	}
}
int main()
{
	int n, e;
	cin >> n >> e;
	int s, d;
	for (int m = 0; m < e; m++)
	{

		cin >> s >> d;
		v[s].push_back(d);
		v[d].push_back(s);
	}
	for (int m = 1; m <= n; m++)
	{
		if (visited[m] == 0)
		{
			dsf(m);
			a++;
		}

	}
	cout << a << " " << ans << endl;
	if (a == 1 && ans == 1)
		cout << "FHTAGN!";
	else
		cout << "NO";
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

int n, m;
bool check[105][105];//방문한 정점인지 본다.
vector <int> v[105];//어떤 vertex가 연결되었는가?

int main() {

	cin >> n >> m;

	int start, end;
	for (int i = 0; i < m; i++) {
		cin >> start >> end;
		v[start].push_back(end);
		v[end].push_back(start);
	}
	/*
	for (int i = 1; i <= n; i++) {
		cout << i << " : ";
		for (int j = 0; j < v[i].size(); j++) {
			cout << v[i][j] << " ";
		}
		cout << endl;
	}*/

	bool flag = false;
	for (int i = 1; i <= n; i++) {

		//1. 체크 배열 초기화
		for (int j = 1; j <= n; j++) {
			for (int k = 1; k <= n; k++) {
				check[j][k] = false;
			}
		}

		vector<pair<int,int>> s;//스택, 시작점과 이전 인덱스
		check[i][i] = true;
		s.push_back(make_pair(i,0));//i에서 시작해 i로 돌아오는 경로를 찾을거임
		//cout << "=============" << endl;
		int cur, pre, next;
		while (!s.empty()) {
			cur = s.back().first;
			pre = s.back().second;
		//	cout << cur <<" "<<pre<< endl;
			s.pop_back();

			for (int j = 0; j < v[cur].size(); j++) {
				next = v[cur][j];
				if ((next == pre) || check[cur][next]) {
					continue;
				}
				else if (next == i) {
					//cout << "찾았다!" << endl;
					flag = true;
					break;
				}
				check[cur][next] = true;
				s.push_back(make_pair(next,cur));
			}
			if (flag) {
				break;
			}
		}
		if (flag) {
			break;
		}
	}

	if (flag && m==n) {
		cout << "FHTAGN!" << endl;
	}
	else {
		cout << "NO" << endl;
	}

	return 0;

}


#include <iostream>
#include <vector>
#include <tuple>

using namespace std;

int n, m;
bool check[105];//방문한 정점인지 본다.
vector <int> v[105];//어떤 vertex가 연결되었는가?

int main() {

	cin >> n >> m;

	int start, end;
	for (int i = 0; i < m; i++) {
		cin >> start >> end;
		v[start].push_back(end);
		v[end].push_back(start);
	}

	for (int i = 1; i <= n; i++) {

		//1. 체크 배열 초기화
		for (int j = 1; j <= n; j++) {
			check[j] = false;
		}

		vector<int> s;//스택
		check[i] = true;
		s.push_back(i);
		int cur, next;
		while (!s.empty()) {
			cur = s.back();
			s.pop_back();

			for (int j = 0; j < v[cur].size(); j++) {
				next = v[cur][j];
				if (check[next]) {
					continue;
				}
				check[next] = true;
				s.push_back(next);
			}
		}
	}

	bool flag = true;
	for (int i = 1; i <= n; i++) {
		if (!check[i]) {
			flag = false;
			break;
		}
	}

	if (flag && n==m) {
		cout << "FHTAGN!" << endl;
	}
	else {
		cout << "NO" << endl;
	}

	return 0;

}


#include <iostream>
#include <vector>

using namespace std;

int n, m;
bool check[105][105];//방문한 정점인지 본다.
vector <int> v[105];//어떤 vertex가 연결되었는가?

int main() {

	cin >> n >> m;

	int start, end;
	for (int i = 0; i < m; i++) {
		cin >> start >> end;
		v[start].push_back(end);
		v[end].push_back(start);
	}
	/*
	for (int i = 1; i <= n; i++) {
		cout << i << " : ";
		for (int j = 0; j < v[i].size(); j++) {
			cout << v[i][j] << " ";
		}
		cout << endl;
	}*/

	bool flag = false;
	for (int i = 1; i <= n; i++) {

		//1. 체크 배열 초기화
		for (int j = 1; j <= n; j++) {
			for (int k = 1; k <= n; k++) {
				check[j][k] = false;
			}
		}

		vector<pair<int,int>> s;//스택, 시작점과 이전 인덱스
		check[i][i] = true;
		s.push_back(make_pair(i,0));//i에서 시작해 i로 돌아오는 경로를 찾을거임
		//cout << "=============" << endl;
		int cur, pre, next;
		while (!s.empty()) {
			cur = s.back().first;
			pre = s.back().second;
		//	cout << cur <<" "<<pre<< endl;
			s.pop_back();

			for (int j = 0; j < v[cur].size(); j++) {
				next = v[cur][j];
				if ((next == pre) || check[cur][next]) {
					continue;
				}
				else if (next == i) {
					//cout << "찾았다!" << endl;
					flag = true;
					break;
				}
				check[cur][next] = true;
				s.push_back(make_pair(next,cur));
			}
			if (flag) {
				break;
			}
		}
		if (flag) {
			break;
		}
	}

	if (flag) {
		cout << "FHTAGN!" << endl;
	}
	else {
		cout << "NO" << endl;
	}

	return 0;

}


#include <iostream>
#include <vector>
#include <tuple>

using namespace std;

int n, m;
bool check[105];//방문한 정점인지 본다.
vector <int> v[105];//어떤 vertex가 연결되었는가?

int main() {

	cin >> n >> m;

	int start, end;
	for (int i = 0; i < m; i++) {
		cin >> start >> end;
		v[start].push_back(end);
		v[end].push_back(start);
	}

	bool flag = false;
	for (int i = 1; i <= n; i++) {

		//1. 체크 배열 초기화
		for (int j = 1; j <= n; j++) {
			check[j] = false;
		}

		vector<int> s;//스택
		check[i] = true;
		s.push_back(i);
		int cur, next;
		while (!s.empty()) {
			cur = s.back();
			s.pop_back();

			for (int j = 0; j < v[cur].size(); j++) {
				next = v[cur][j];
				if (check[next]) {
					continue;
				}
				check[next] = true;
				s.push_back(next);
			}
		}
	}

	bool flag = true;
	for (int i = 1; i <= n; i++) {
		if (!check[i]) {
			flag = false;
			break;
		}
	}

	if (flag && n==m) {
		cout << "FHTAGN!" << endl;
	}
	else {
		cout << "NO" << endl;
	}

	return 0;

}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<queue>
#include<stack>
#include<iterator>
#include<cmath>
#include<string>
#include<sstream>
#include<cstring>
#include<ctype.h>
#include<iomanip>
#include<bitset>
#include<stdio.h>
#include<fstream>
#include<regex>
#include<stdlib.h>
#include<math.h>

using namespace std;

#define all(v)         v.begin(),v.end()
#define sz(v)        ((int)((v).size()))
#define psh(x)               push_back(x)
#define mk(x,y)           make_pair(x,y)
#define ck(a)               (a<1 || a>9)
#define lop(i,n)     for(ll i=0;i<n;i++)
#define loop(i,f,l)  for(ll i=f;i<l;i++)
#define READ(s)   freopen(s, "r", stdin)
#define WRITE(s) freopen(s, "w", stdout)
#define scl(n)          scanf("%lld",&n)
#define sc(n)             scanf("%d",&n)
#define INF                   1000000000
#define LINF               1000000000000
#define PI             3.141592653589793

typedef long long           ll;
typedef pair <int, int>     ii;
typedef pair<double, double>dd;
typedef pair<string, int>   si;
typedef pair<int, string>   is;
typedef pair<char, int>    chi;
typedef vector<ii>         vii;
typedef vector<int>         vi;
typedef vector<vi>         vvi;
typedef vector<string>      vs;
typedef vector<ll>         vll;
typedef vector<vii>       vvii;
typedef set<int>           sti;

const double EPS = (1e-7);

int dx[] = { 1, -1, 0, 0, 1, 1, -1, -1 };
int dy[] = { 0, 0, -1, 1, 1, -1, 1, -1 };

int gcd(int a, int b) { return (b == 0 ? a : gcd(b, a % b)); }
int lcm(int a, int b) { return ((a*b) / gcd(a, b)); }
ll pw(ll b, ll p){ if (!p) return 1; ll sq = pw(b, p / 2); sq *= sq; if (p % 2) sq *= b; return sq; }
int sd(ll x){ return x<10 ? x : x % 10 + sd(x / 10); }
ll sq(ll x){ lop(i, x)if ((ll)i*i > x) return (i - 1); return ll(1); }
//READ("input.txt");WRITE("output.txt");

int vis[105];
vvi graph(105);

void dfs(int n)
{
	vis[n] = 1;
	lop(i, sz(graph[n]))
		if (!vis[graph[n][i]]) dfs(graph[n][i]);
}

int main()
{
	int n, m;	cin >> n >> m;	if (n != m) { cout << "NO"; return 0; }
	lop(i, m)	{ int x, y; cin >> x >> y; graph[x].push_back(y); graph[y].push_back(x); }
	dfs(1);
	loop(i, 1, n + 1) if (!vis[i]) { cout << "NO"; return 0; }
	cout << "FHTAGN!";
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;
int a[100][100], n, m;
bool boo[100];
int sc = 0;
bool all[100];
void dfs(int v, int pr)
{
	boo[v] = 1;
	for(int i = 0; i < n; i++)
		if(a[v][i]&&pr!=i)
		{
			if(boo[i]&&!all[i]&&!all[v])
			{
				sc++;
				all[i]=1;
				all[v]=1;
				continue;
			}
			if(!boo[i])
				dfs(i, v);
		}
}
int main()
{

	cin >> n >> m;
	memset(boo, 0, 100);
	memset(all, 0, 100);
	for(int i = 0; i <m; i++)
	{
		int t1,t2;
		cin >> t1 >> t2;
		a[t1-1][t2-1]=1;
		a[t2-1][t1-1]=1;
	}
	dfs(0,0);
	for(int i = 0; i < n; i++)
		if(!boo[i])
		{
			cout << "FHTAGN!";
			return 0;
		}
	if(sc==1)
	{
		cout << "FHTAGN!";
		return 0;
	}
	else
	{
		cout << "NO";
		return 0;
	}
}


#include <iostream>
#include <vector>

using namespace std;
int a[100][100], n, m;
int boo[100];
int sc = 0;
bool all[100];
void dfs(int v, int pr)
{
	boo[v] = 1;
	for(int i = 0; i < n; i++)
		if(a[v][i]&&pr!=i)
		{
			if(boo[i]==1)
			{
				sc++;
				continue;
			}
			if(!boo[i])
				dfs(i, v);
		}
	boo[v] = 2;
}
int main()
{

	cin >> n >> m;
	memset(boo, 0, 100);
	memset(all, 0, 100);
	for(int i = 0; i <m; i++)
	{
		int t1,t2;
		cin >> t1 >> t2;
		a[t1-1][t2-1]=1;
		a[t2-1][t1-1]=1;
	}
	dfs(0,0);
	for(int i = 0; i < n; i++)
		if(boo[i]==0)
		{
			cout << "NO";
			return 0;
		}
	if(sc==1)
	{
		cout << "FHTAGN!";
		return 0;
	}
	else
	{
		cout << "NO";
		return 0;
	}
}


#include <iostream>
#include <vector>

using namespace std;

int n, m;
int visit[101];
vector<vector<int>> graph(101);
int cycle;
void dfs(int node, int parent)
{
	visit[node] = 1;

	for (int i = 0; i < graph[node].size(); i++)
	{
		if (graph[node][i] != parent && visit[graph[node][i]] == 1)//�湮�� ��� �� �θ� ��尡 �ƴϸ鼭 �̹� �湮�� ��尡 �ִ�
		{//�� ����Ŭ�� �����Ѵ�.
			cycle++;
		}

		if (visit[graph[node][i]] == 0)
		{
			dfs(graph[node][i], node);
		}
	}
	return;
}

int main()
{
	cin >> n >> m;

	int x, y;
	for (int i = 0; i < m; i++)
	{
		cin >> x >> y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}
	int count = 0;
	for (int i = 1; i < n+1; i++)
	{
		if (visit[i] == 0)
		{
			dfs(i, i);
			count++;
		}

	}

	cycle /= 2;//����Ŭ�� �ϳ� üũ�� ������ 2���� �ö󰡱⋚��.

	if (cycle==1 && count==1)
		cout << "FHTAGN!" << endl;
	else
		cout << "NO" << endl;
	//system("pause");
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

int n, m;
int visit[101];
vector<vector<int>> graph(101);
bool answer = false;
void dfs(int node, int parent)
{
	visit[node] = 1;

	for (int i = 0; i < graph[node].size(); i++)
	{
		if (graph[node][i] != parent && visit[graph[node][i]] == 1)//�湮�� ��� �� �θ� ��尡 �ƴϸ鼭 �̹� �湮�� ��尡 �ִ�
		{//�� ����Ŭ�� �����Ѵ�.
			answer = true;
		}
		else
		{
			if (visit[graph[node][i]] == 0)
				dfs(graph[node][i], node);
		}
	}
	return;
}

int main()
{
	cin >> n >> m;

	int x, y;
	for (int i = 0; i < m; i++)
	{
		cin >> x >> y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}

	dfs(1,1);

	if (answer)
		cout << "FHTAGN!" << endl;
	else
		cout << "NO" << endl;
	//system("pause");
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

int n, m;
int visit[101];
vector<vector<int>> graph(101);
bool answer = false;
void dfs(int node, int parent)
{
	visit[node] = 1;

	for (int i = 0; i < graph[node].size(); i++)
	{
		if (graph[node][i] != parent && visit[graph[node][i]] == 1)//�湮�� ��� �� �θ� ��尡 �ƴϸ鼭 �̹� �湮�� ��尡 �ִ�
		{//�� ����Ŭ�� �����Ѵ�.
			answer = true;
		}
		else
		{
			if (visit[graph[node][i]] == 0)
				dfs(graph[node][i], node);
		}
	}
	return;
}

int main()
{
	cin >> n >> m;

	int x, y;
	for (int i = 0; i < m; i++)
	{
		cin >> x >> y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}
	int count = 0;
	for (int i = 1; i < n+1; i++)
	{
		if (visit[i] == 0)
		{
			dfs(i, i);
			count++;
		}

	}

	if (answer && count==1)
		cout << "FHTAGN!" << endl;
	else
		cout << "NO" << endl;
	//system("pause");
	return 0;
}


#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <cctype>
#include <algorithm>
using namespace std;
vector<vector<int> > gr;
vector<char> cycle,used;

bool dfs(int v,int pr,int start){
    used[v]=1;
    for (int i=0;i<gr[v].size();i++){
        int to=gr[v][i];
        if (to==pr)
            continue;
        if (used[to]==1 && to==start || !used[to] && dfs(to,v,start))
            return true;
    }
    used[v]=0;
    return false;
}

int main(){
    //freopen("input.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    gr.resize(n);
    for (int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        a--;b--;
        gr[a].push_back(b);
        gr[b].push_back(a);
    }
    cycle.resize(n);
    used.resize(n);
    int cnt=0;
    for (int i=0;i<n;i++){
        if (!cycle[i] && dfs(i,-1,i)){
            for (int j=0;j<n;j++)
                if (used[j]==1){
                    used[j]=0;
                    cycle[j]=1;
                }
            cnt++;
            if (cnt>1)break;
        }
    }
    if (cnt==1)
        cout<<"FHTAGN!";
    else
        cout<<"NO";
    return 0;
}


#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <cctype>
#include <algorithm>
using namespace std;
vector<vector<int> > gr;
vector<char> cycle,used;

bool dfs(int v,int pr,int start){
    used[v]=1;
    for (int i=0;i<gr[v].size();i++){
        int to=gr[v][i];
        if (to==pr)
            continue;
        if (used[to]==1 && to==start || !used[to] && dfs(to,v,start))
            return true;
    }
    return false;
}

int main(){
    //freopen("input.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    gr.resize(n);
    for (int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        a--;b--;
        gr[a].push_back(b);
        gr[b].push_back(a);
    }
    cycle.resize(n);
    used.resize(n);
    int cnt=0;
    for (int i=0;i<n;i++){
        used.assign(n,false);
        if (!cycle[i] && dfs(i,-1,i)){
            for (int j=0;j<n;j++)
                if (used[j]==1){
                    used[j]=0;
                    cycle[j]=1;
                }
            cnt++;
            if (cnt>1)break;
        }
    }
    if (cnt==1)
        cout<<"FHTAGN!";
    else
        cout<<"NO";
    return 0;
}


#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <cctype>
#include <algorithm>
using namespace std;
vector<vector<int> > gr;
vector<char> cycle,used;

int dfs(int v,int pr=-1){
    used[v]=1;
    for (int i=0;i<gr[v].size();i++){
        int to=gr[v][i];
        if (to==pr)
            continue;
        if (used[to]){
            cycle[v]=true;
            return to;
        }
        int tmp=dfs(to,v);
        if (tmp<0)
            return tmp;
        if (tmp==v){
            cycle[v]=true;
            return -tmp;
        }
        if (tmp>0){
            cycle[v]=true;
            return tmp;
        }
    }
    used[v]=0;
    return false;
}
bool dfs2(int v,int pr=-1){
    used[v]=1;
    for (int i=0;i<gr[v].size();i++){
        int to=gr[v][i];
        if (cycle[to] || to==pr)
            continue;
        if (used[to])
            return true;
        if (dfs2(to,v))
            return true;
    }
    used[v]=0;
    return false;
}
int main(){
    //freopen("input.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    gr.resize(n+1);
    for (int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        gr[a].push_back(b);
        gr[b].push_back(a);
    }
    cycle.resize(n+1);
    used.resize(n+1);
    if (!dfs(1)){
        cout<<"NO";
        return 0;
    }
    for (int i=1;i<=n;i++){
        if (cycle[i]){
            used.assign(n+1,false);
            if (dfs2(i)){
                cout<<"NO";
                return 0;
            }
        }
    }
    cout<<"FHTAGN!";
    return 0;
}


#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <cctype>
#include <algorithm>
using namespace std;
vector<vector<int> > gr;
vector<char> cycle,used;

bool dfs(int v,int pr,int start){
    used[v]=1;
    for (int i=0;i<gr[v].size();i++){
        int to=gr[v][i];
        if (to==pr)
            continue;
        if (used[to]==1 && to==start || !used[to] && dfs(to,v,start))
            return true;
    }
    return false;
}

int main(){
    //freopen("input.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    gr.resize(n);
    for (int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        a--;b--;
        gr[a].push_back(b);
        gr[b].push_back(a);
    }
    cycle.resize(n);
    used.resize(n);
    int cnt=0;
    for (int i=0;i<n;i++){
        if (!cycle[i] && dfs(i,-1,i)){
            for (int j=0;j<n;j++)
                if (used[j]==1){
                    used[j]=0;
                    cycle[j]=1;
                }
            cnt++;
            if (cnt>1)break;
        }
    }
    if (cnt==1)
        cout<<"FHTAGN!";
    else
        cout<<"NO";
    return 0;
}


#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <deque>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <cctype>
#include <algorithm>
using namespace std;
vector<vector<int> > gr;
vector<char> used;

void dfs(int v){
    used[v]=true;
    for (int i=0;i<gr[v].size();i++)
        if (!used[gr[v][i]])
            dfs(gr[v][i]);
}

int main(){
    //freopen("input.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    gr.resize(n);
    used.resize(n);
    for (int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        a--;b--;
        gr[a].push_back(b);
        gr[b].push_back(a);
    }
    dfs(0);
    for (int i=0;i<n;i++)
        if (!used[i]){
            cout<<"NO";
            return 0;
        }
    if (n==m)
        cout<<"FHTAGN!";
    else
        cout<<"NO";
    return 0;
}


#include <iostream>
#include <vector>
#include <numeric>
vector<int> g[100];
bool u[100];
void dfs(int a){
    if (u[a]) return;
    u[a] = 1;
    for (int i = 0; i <g[a].size(); ++i) dfs(g[a][i]);
}
int main(){
    int n, m;
    cin>>n>>m;
    if (n != m || n < 3) cout << "NO";
    else {
        for (int i = 0; i < m; ++i){
            int a, b;
            cin>>a>>b;--a;--b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        dfs(0);
        cout << accumulate(u, u + n,0) != n ? "NO" : "NTHFANG!";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
vector<int> g[100];
bool u[100];
void dfs(int a){
    if (u[a]) return;
    u[a] = 1;
    for (int i = 0; i <g[a].size(); ++i) dfs(g[a][i]);
}
int main(){
    int n, m;
    cin>>n>>m;
    if (n != m || n < 3) cout << "NO";
    else {
        for (int i = 0; i < m; ++i){
            int a, b;
            cin>>a>>b;--a;--b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        dfs(0);
        cout << accumulate(u, u + n,0) != n ? "NO" : "NTHFANG!";
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
vector<int> g[100];
bool u[100];
void dfs(int a){
    if (u[a]) return;
    u[a] = 1;
    for (int i = 0; i <g[a].size(); ++i) dfs(g[a][i]);
}
int main(){
    int n, m;
    cin>>n>>m;
    if (n != m || n < 3) cout << "NO";
    else {
        for (int i = 0; i < m; ++i){
            int a, b;
            cin>>a>>b;--a;--b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        dfs(0);
        cout << ((accumulate(u, u + n,0) != n) ? "NO" : "FHTAGN!");
    }
    return 0;
}


#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int N=50;
int n,m,a[200][200],col[200],p[200],cycle,cnt=1,x,y;
int gl=1,ok=1;
void dfs (int v, int c) {
	col[v]=c;
	for (int i=1; i<=n; i++)
		if (a[v][i] && i!=p[v]) {
			if (!col[i]) { p[i]=v; dfs(i,c); if (cycle) return;}
			else if (col[i]==c) {
				cycle=1;
				int cur=v;
				while (cur!=i) {
					col[cur]=gl;
					cur=p[cur];
				}
				col[cur]=gl;
				return;
			}
		}
}
int dfs2 (int v ,int p=-1) {
	for (int i=1; i<=n; i++)
		if (i!=p && col[i]!=1 && a[v][i]) {
			if (!col[i]) {
				col[i]=2;
				if (dfs2(i,v)) return 1;
			} else return 1;
		}
	return 0;
}
int main () {
#ifndef ONLINE_JUDGE
    freopen ("input.txt","r",stdin);
    freopen ("output.txt","w",stdout);
#endif
	cin>>n>>m;
	for (int i=1; i<=m; i++) { cin>>x>>y; a[x][y]=a[y][x]=1; }
	for (int i=1; i<=n; i++) {
		if (!col[i]) {
			p[i]=-1;
			dfs(i,++cnt);
			if (cycle) {
				for (int j=1; j<=n; j++)
					if (col[j]!=1) col[j]=0;
				break;
			}
		}
	}
	if (!cycle) ok=0;
	for (int i=1; i<=n; i++)
		if (col[i]==1) {
			if (dfs2(i)) { ok=0; break;}
		}
	for (int i=1; i<=n; i++)
		if (!col[i]) ok=0;
	if (ok) puts("FHTAGN!");
	else puts("NO");
}


#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int N=50;
int n,m,a[200][200],col[200],p[200],cycle,cnt=1,x,y;
int gl=1,ok=1;
void dfs (int v, int c) {
	col[v]=c;
	for (int i=1; i<=n; i++)
		if (a[v][i] && i!=p[v]) {
			if (!col[i]) { p[i]=v; dfs(i,c); }
			else if (col[i]==c) {
				cycle=1;
				int cur=v;
				while (cur!=i) {
					col[cur]=gl;
					cur=p[cur];
				}
				col[cur]=gl;
				return;
			}
		}
}
int dfs2 (int v ,int p=-1) {
	for (int i=1; i<=n; i++)
		if (i!=p && col[i]!=1 && a[v][i]) {
			if (!col[i]) {
				col[i]=2;
				if (dfs2(i,v)) return 1;
			} else return 1;
		}
	return 0;
}
int main () {
#ifndef ONLINE_JUDGE
    freopen ("input.txt","r",stdin);
    freopen ("output.txt","w",stdout);
#endif
	cin>>n>>m;
	for (int i=1; i<=m; i++) { cin>>x>>y; a[x][y]=a[y][x]=1; }
	for (int i=1; i<=n; i++) {
		if (!col[i]) {
			p[i]=-1;
			dfs(i,++cnt);
			if (cycle) {
				for (int j=1; j<=n; j++)
					if (col[j]!=1) col[j]=0;
			}
		}
	}
	if (!cycle) ok=0;
	for (int i=1; i<=n; i++)
		if (col[i]==1) {
			if (dfs2(i)) { ok=0; break;}
		}
	for (int i=1; i<=n; i++)
		if (!col[i]) ok=0;
	if (ok) puts("FHTAGN!");
	else puts("NO");
}


#include <iostream>
#include<algorithm>
#include<string>
#include<map>
#include<iomanip>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include <functional>

#define mod 1000000007
#define pa(a,b) make_pair(a,b)
#define f first
#define s second
#define pb(a)  push_back(a)
#define all(a) a.begin() , a.end()
#define mem(a, b) memset(a, b, sizeof(a))
#define LL  long long int
#define oo 1e9
#define pi 3.14159265359

LL maxx(LL a , LL b){ return a>b ?  a : b ;}
LL minn(LL a , LL b){ return a>b ?  b : a ;}

using namespace std;
LL gcd(LL a, LL b) {
    return b == 0 ? a : gcd(b, a % b);
}
LL lcm(LL a , LL b )
{
    return (a*b)/gcd(a , b);
}
LL poww(LL base, LL exp){
  base %= mod;
  LL result = 1;
  while (exp > 0) {
    if (exp & 1) result = (result * base) % mod;
    base = (base * base) % mod;
    exp >>= 1;
  }
  return result;
}
vector<int>a[200];
bool vis[200]; int num;
void dfs(int root)
{
    vis[root]=1; num++;
    for(int i=0;i<a[root].size();i++)if(!vis[a[root][i]])dfs(a[root][i]);
    return ;
}
int main()
{
    int n,m; cin>>n>>m;
    if(n>m||n<3)return cout<<"NO" , 0 ;
    for(int i=0;i<n;i++)
    {
        int u,v; cin>>u>>v;
        a[u].pb(v); a[v].pb(u);
    }
    dfs(1);
    if(num==n)cout<<"FHTAGN!";
    else cout<<"NO";
}


#include <stdio.h>

void transformation (int **E, int *Number_of_E, int **list, int N, int m, bool **graph)
{
     int t1, t2, t3, t4;
   for (int i=0; i<m; i++)
   {
       t1=E[i][1];
       t2=Number_of_E[t1-1];
       t3=E[i][0];
       t4=Number_of_E[t3-1];
       Number_of_E[t1-1]++;
       Number_of_E[t3-1]++;
      list[t1-1][t2]=t3;
      list[t3-1][t4]=t1;
      graph[t1-1][t3-1]=graph[t3-1][t1-1]=true;
   }

}

void dfs(int v, bool *flag, int N, bool**graph){
int  i;
  flag[v] = true;

  for (i = 1; i<N; i++)
  {

    if ((graph[v][i])&&(!(flag[i])))
      dfs(i, flag, N, graph);
      }
}

int main()
{
      int N, m;
      FILE *inf, *outf;
      bool answ=false;

 //     inf=fopen("input.txt", "rt");
        inf=stdin;
      outf= stdout;
      fscanf(inf, "%d %d", &N, &m);
      bool *flag=new bool [N];
      bool **graph=new bool *[N];
      int **E=new int *[m];
      for (int i=0; i<m; i++)
      {
            E[i]=new int[2];
            flag[i]=false;
      }
      int *Number_of_E =new int[N];
      for(int i=0; i<N; i++)
      {
              Number_of_E[i]=0;
      graph[i]=new bool[N];
      }
      int **list=new int *[N];
      for (int i=0; i<m; i++)
      {
           list[i]=new int [N];
      }
      for (int i=0; i<m; i++)
      {
          fscanf(inf, "%d %d", &E[i][0], &E[i][1]);
      }
      for(int i=0; i<N;i++)
              for (int j=0; j<N;j++)
                  graph[i][j]=false;

      if ((N==m)&&(N>=3))
      {
               transformation(E, Number_of_E, list, N, m, graph);
               dfs(0,flag, N, graph);
               bool fl=false;
               for (int i=0; i<N; i++)
               {
                   if (!(flag[i]))
                   {
                                  fl=true;
                                  break;
                   }
               }
               if (!(fl))
                 answ=true;

      }
      if (answ)
      {
      fprintf(outf,"FHTAGN!" );
      }else{
            fprintf(outf, "NO");
      }
/*   for (int i=0; i<N; i++
   {
      flag[i]=false;
      Number_of_E[i]=0;
   }

*/
fclose(inf);
fclose(outf);

      for (int i=0; i<m; i++)
            delete[]E[i];
      delete[]E;

    delete[] Number_of_E;
          for (int i=0; i<m; i++)
      {
           delete[]list[i];
      }
           for (int i=0; i<N; i++)
      {
           delete[]graph[i];
      }
      delete[] graph;
    delete[]list;
  //getchar();
      return 0;
}


#include <stdio.h>

void transformation (int **E/*, int *Number_of_E, int **list*/, int N, int m, bool **graph)
{
     int t1, t2, t3, t4;
   for (int i=0; i<m; i++)
   {
       t1=E[i][1];
   //    t2=Number_of_E[t1-1];
       t3=E[i][0];
   //    t4=Number_of_E[t3-1];
  //     Number_of_E[t1-1]++;
    //   Number_of_E[t3-1]++;
      //list[t1-1][t2]=t3;
      //list[t3-1][t4]=t1;
      graph[t1-1][t3-1]=graph[t3-1][t1-1]=true;
   }

}

void dfs(int v, bool *flag, int N, bool**graph){
int  i;
  flag[v] = true;

  for (i = 1; i<N; i++)
  {

    if ((graph[v][i])&&(!(flag[i])))
      dfs(i, flag, N, graph);
      }
}

int main()
{
      int N, m;
      FILE *inf, *outf;
      bool answ=false;

 //     inf=fopen("input.txt", "rt");
        inf=stdin;
      outf= stdout;
      fscanf(inf, "%d %d", &N, &m);
      bool *flag=new bool [N];
      bool **graph=new bool *[N];
      int **E=new int *[m];
      for (int i=0; i<m; i++)
      {
            E[i]=new int[2];
            flag[i]=false;
      }
//      int *Number_of_E =new int[N];
      for(int i=0; i<N; i++)
      {
      //        Number_of_E[i]=0;
      graph[i]=new bool[N];
      }
//      int **list=new int *[N];
  //    for (int i=0; i<m; i++)
    //  {
      //     list[i]=new int [N];
      //}
      for (int i=0; i<m; i++)
      {
          fscanf(inf, "%d %d", &E[i][0], &E[i][1]);
      }
      for(int i=0; i<N;i++)
              for (int j=0; j<N;j++)
                  graph[i][j]=false;

      if ((N==m)&&(N>=3))
      {
               transformation(E/*, Number_of_E, list*/, N, m, graph);
               dfs(0,flag, N, graph);
               bool fl=false;
               for (int i=0; i<N; i++)
               {
                   if (!(flag[i]))
                   {
                                  fl=true;
                                  break;
                   }
               }
               if (!(fl))
                 answ=true;

      }
      if (answ)
      {
      fprintf(outf,"FHTAGN!" );
      }else{
            fprintf(outf, "NO");
      }
/*   for (int i=0; i<N; i++
   {
      flag[i]=false;
      Number_of_E[i]=0;
   }

*/
fclose(inf);
fclose(outf);

      for (int i=0; i<m; i++)
            delete[]E[i];
      delete[]E;

  //  delete[] Number_of_E;
    //      for (int i=0; i<m; i++)
    //  {
      //     delete[]list[i];
      //}
           for (int i=0; i<N; i++)
      {
           delete[]graph[i];
      }
      delete[] graph;
  //  delete[]list;
  //getchar();
      return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <memory.h>
#include <assert.h>
#include <complex>
#include <ctime>
#include <cstdlib>
using namespace std;

#pragma comment(linker, "/STACK:100000000")

#define mp make_pair
#define pb push_back
#define sz(x) (int)(x).size()
#define ll long long
#define ull unsigned long long

vector<int> v[100100];

int vis[100100];

bool endd = false;

int stackk[100100];

void go(int cur, int last, int dist) {
	if(endd) return;
	stackk[dist] = cur;
	if(vis[cur] != 0) { // значит я в этой вершине уже был
		int pos = dist;
		int c = stackk[pos];
		int cnt = 0;
		do {
			if(sz(v[c]) > 0) cnt++;
			pos--;
			c = stackk[pos];
		} while(c != cur);
		if(cnt >= 3) {
			endd = true;
			printf("FHTAGN!\n");
			return;
		}
		else {
			endd = true;
			printf("NO\n");
			return;
		}
	}
	vis[cur] = dist;
	for(int i = 0, maxi = sz(v[cur]); i < maxi; i++) {
		if(endd) return;
		if(v[cur][i] != last) go(v[cur][i], cur, dist + 1);
	}
}

int main() {
    //freopen("input.txt", "rt", stdin);
    //freopen("cycle2.out", "wt", stdout);

	int n, m;
	scanf("%d %d", &n, &m);

	if(n != m) {
		printf("NO\n");
		return 0;
	}

	for(int i = 0; i < n; i++) {
		int a, b;
		scanf("%d %d", &a, &b);
		a--;
		b--;
		v[a].pb(b);
		v[b].pb(a);
	}

	for(int i = 0; i < n; i++) {
		if(sz(v[i]) < 1) {
			printf("NO\n");
			return 0;
		}
	}

	for(int i = 0; i < n; i++) {
		if(endd) break;
		for(int j = 0; j < n; j++) vis[j] = 0;
		go(i, -1, 1);
	}
	if(!endd) printf("NO\n");

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <memory.h>
#include <assert.h>
#include <complex>
#include <ctime>
#include <cstdlib>
using namespace std;

#pragma comment(linker, "/STACK:100000000")

#define mp make_pair
#define pb push_back
#define sz(x) (int)(x).size()
#define ll long long
#define ull unsigned long long

vector<int> v[100100];

int vis[100100];

bool endd = false;

int stackk[100100];

bool a[100100];
void dfs(int s) {
    if(a[s]) return;
    a[s] = true;
    for(int i = 0, maxi = sz(v[s]); i < maxi; i++) dfs(v[s][i]);
}

void go(int cur, int last, int dist) {
    if(endd) return;
    stackk[dist] = cur;
    if(vis[cur] != 0) { // значит я в этой вершине уже был
        int pos = dist;
        int c = stackk[pos];
        int cnt = 0;
        do {
            if(sz(v[c]) > 0) cnt++;
            pos--;
            c = stackk[pos];
        } while(c != cur);
        if(cnt >= 3) {
            endd = true;
            printf("FHTAGN!\n");
            return;
        }
        else {
            endd = true;
            printf("NO\n");
            return;
        }
    }
    vis[cur] = dist;
    for(int i = 0, maxi = sz(v[cur]); i < maxi; i++) {
        if(endd) return;
        if(v[cur][i] != last) go(v[cur][i], cur, dist + 1);
    }
}

int main() {
    //freopen("input.txt", "rt", stdin);
    //freopen("cycle2.out", "wt", stdout);

    int n, m;
    scanf("%d %d", &n, &m);

    if(n != m) {
        printf("NO\n");
        return 0;
    }

    for(int i = 0; i < n; i++) {
        int a, b;
        scanf("%d %d", &a, &b);
        a--;
        b--;
        v[a].pb(b);
        v[b].pb(a);
    }

    for(int i = 0; i < n; i++) {
        if(sz(v[i]) < 1) {
            printf("NO\n");
            return 0;
        }
    }
    dfs(0);
    for(int i = 0; i < n; i++) {
        if(!a[i]) {
            printf("NO\n");
            return 0;
        }
    }

    for(int i = 0; i < n; i++) {
        if(endd) break;
        for(int j = 0; j < n; j++) vis[j] = 0;
        go(i, -1, 1);
    }
    if(!endd) printf("NO\n");

    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <memory.h>
#include <iomanip>
#include <string>
#include <map>
#include <utility>

using namespace std;

int n,m;

vector<int> l[111];

bool used[111];

bool DFS(int a, int p) {
        used[a] = true;
        for (int i=0; i<l[a].size(); i++) {
                if (l[a][i] != p) {
                        if (used[l[a][i]])
                                return false;
                        if (DFS(l[a][i], a) == false)
                                return false;
                }
        }

        return true;
}

bool isTree(int a, int b) {
        memset(used, 0, sizeof used);
        return DFS(b,a);
}

vector<int> cyc;

int gggg = 0;
bool DFS2(int v, int p) {
        used[v] = true;

        for (int i=0; i<l[v].size(); i++) {
                if (l[v][i] == p) continue;
                if (used[l[v][i]]) {
						gggg = l[v][i];
                        cyc.push_back(v);
                        return false;
                }
                if (DFS2(l[v][i], v) == false) {
                        cyc.push_back(v);
						if (v != gggg)
							return false;
						else return true;
                }
        }

        return true;
}

vector<int> findCycle() {
        memset(used, 0, sizeof used);
        DFS2(1, -1);

        return cyc;
}

int sum = 0;

void DFS3(int v, int p) {
        ++sum;
        used[v] = true;

        for (int i=0; i<l[v].size(); i++) {
                if (l[v][i] == p) continue;
                if (used[l[v][i]]) continue;

                DFS3(l[v][i], v);
        }
}

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

        cin >> n >> m;

        for (int i=0; i<m; i++) {
                int a,b;
                cin >> a >> b;
                l[a].push_back(b);
                l[b].push_back(a);
        }

        vector<int> cycle = findCycle();

        if (cycle.size() == 0) {
                cout << "NO" << endl;
                return 0;
        }

        memset(used, 0, sizeof used);

        DFS3(1, -1);

        if (sum != n) {
                cout << "NO" << endl;
                return 0;
        }

        bool kt = true;

        for (int i=0; i<cycle.size(); i++) {
                for (int r=0; r<l[cycle[i]].size(); r++) {
                        if ( find(cycle.begin(), cycle.end(), l[cycle[i]][r]) == cycle.end()) {
                                kt &= isTree(cycle[i], l[cycle[i]][r]);
                        }
                }
        }

        if (kt) {
                cout << "FHTAGN!" << endl;
                return 0;
        }

        cout << "NO" << endl;

        return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <memory.h>
#include <iomanip>
#include <string>
#include <map>
#include <utility>

using namespace std;

int n,m;

vector<int> l[111];

bool used[111];

bool DFS(int a, int p) {

        used[a] = true;
        for (int i=0; i<l[a].size(); i++) {
                if (l[a][i] != p) {
                        if (used[l[a][i]])
                                return false;
                        if (DFS(l[a][i], a) == false)
                                return false;
                }
        }

        return true;
}

bool isTree(int a, int b) {
        memset(used, 0, sizeof used);
        return DFS(b,a);
}

vector<int> cyc;

int start = 0;

bool DFS2(int v, int p) {
        used[v] = true;

        for (int i=0; i<l[v].size(); i++) {
                if (l[v][i] == p) continue;
                if (used[l[v][i]]) {
						start = l[v][i];
                        cyc.push_back(v);
                        return false;
                }
                if (DFS2(l[v][i], v) == false) {
                        cyc.push_back(v);
						if (v == start)
							throw 5;
                        return false;
                }
        }

        return true;
}

vector<int> findCycle() {
        memset(used, 0, sizeof used);

		try {
			DFS2(1, -1);
		} catch (...) {}

        return cyc;
}

int sum = 0;

void DFS3(int v, int p) {
        ++sum;
        used[v] = true;

        for (int i=0; i<l[v].size(); i++) {
                if (l[v][i] == p) continue;
                if (used[l[v][i]]) continue;

                DFS3(l[v][i], v);
        }
}

bool c[111][111];
int main() {
       // freopen("input.txt", "r", stdin);
        cin >> n >> m;

        for (int i=0; i<m; i++) {
                int a,b;
                cin >> a >> b;
                c[a][b] = c[b][a] = true;
                l[a].push_back(b);
                l[b].push_back(a);
        }

        vector<int> cycle = findCycle();

        if (cycle.size() == 0) {
                cout << "NO" << endl;
                return 0;
        }

        memset(used, 0, sizeof used);

        DFS3(1, -1);

        if (sum != n) {
                cout << "NO" << endl;
                return 0;
        }

        bool kt = true;

        for (int i=0; i<cycle.size(); i++) {
                for (int r=0; r<l[cycle[i]].size(); r++) {
                        if ( find(cycle.begin(), cycle.end(), l[cycle[i]][r]) == cycle.end()) {
                                kt &= isTree(cycle[i], l[cycle[i]][r]);
                        }
                }
        }

        if (kt) {
                cout << "FHTAGN!" << endl;
                return 0;
        }

        cout << "NO" << endl;

        return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <memory.h>
#include <iomanip>
#include <string>
#include <map>
#include <utility>

using namespace std;

int n,m;

vector<int> l[111];

bool used[111];

bool DFS(int a, int p) {

	used[a] = true;
	for (int i=0; i<l[a].size(); i++) {
		if (l[a][i] != p) {
			if (used[l[a][i]])
				return false;
			if (DFS(l[a][i], a) == false)
				return false;
		}
	}

	return true;
}

bool isTree(int a, int b) {
	memset(used, 0, sizeof used);
	return DFS(b,a);
}

vector<int> cyc;

bool DFS2(int v, int p) {
	used[v] = true;

	for (int i=0; i<l[v].size(); i++) {
		if (l[v][i] == p) continue;
		if (used[l[v][i]]) {
			cyc.push_back(v);
			return false;
		}
		if (DFS2(l[v][i], v) == false) {
			cyc.push_back(v);
			return false;
		}
	}

	return true;
}

vector<int> findCycle() {
	memset(used, 0, sizeof used);

	DFS2(1, -1);

	return cyc;
}

bool c[111][111];
int main() {
	//freopen("input.txt", "r", stdin);

	cin >> n >> m;

	for (int i=0; i<m; i++) {
		int a,b;
		cin >> a >> b;
		c[a][b] = c[b][a] = true;
		l[a].push_back(b);
		l[b].push_back(a);
	}

	vector<int> cycle = findCycle();

	if (cycle.size() == 0) {
		cout << "NO" << endl;
		return 0;
	}

	bool kt = true;

	for (int i=0; i<cycle.size(); i++) {
		if (l[cycle[i]].size() > 3) {
			cout << "NO" << endl;
			return 0;
		}
		if (l[cycle[i]].size() == 3) {
			for (int r=0; r<l[cycle[i]].size(); r++) {
				if ( find(cycle.begin(), cycle.end(), l[cycle[i]][r]) == cycle.end()) {
					kt &= isTree(cycle[i], l[cycle[i]][r]);
				}
			}
		}
	}

	if (kt) {
		cout << "FHTAGN!" << endl;
		return 0;
	}

	cout << "NO" << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <memory.h>
#include <iomanip>
#include <string>
#include <map>
#include <utility>

using namespace std;

int n,m;

vector<int> l[111];

bool used[111];

bool DFS(int a, int p) {

	used[a] = true;
	for (int i=0; i<l[a].size(); i++) {
		if (l[a][i] != p) {
			if (used[l[a][i]])
				return false;
			if (DFS(l[a][i], a) == false)
				return false;
		}
	}

	return true;
}

bool isTree(int a, int b) {
	memset(used, 0, sizeof used);
	return DFS(b,a);
}

vector<int> cyc;

bool DFS2(int v, int p) {
	used[v] = true;

	for (int i=0; i<l[v].size(); i++) {
		if (l[v][i] == p) continue;
		if (used[l[v][i]]) {
			cyc.push_back(v);
			return false;
		}
		if (DFS2(l[v][i], v) == false) {
			cyc.push_back(v);
			return false;
		}
	}

	return true;
}

vector<int> findCycle() {
	memset(used, 0, sizeof used);

	DFS2(1, -1);

	return cyc;
}

int sum = 0;

void DFS3(int v, int p) {
	++sum;
	used[v] = true;

	for (int i=0; i<l[v].size(); i++) {
		if (l[v][i] == p) continue;
		if (used[l[v][i]]) continue;

		DFS3(l[v][i], v);
	}
}

bool c[111][111];
int main() {
	//freopen("input.txt", "r", stdin);

	cin >> n >> m;

	for (int i=0; i<m; i++) {
		int a,b;
		cin >> a >> b;
		c[a][b] = c[b][a] = true;
		l[a].push_back(b);
		l[b].push_back(a);
	}

	vector<int> cycle = findCycle();

	if (cycle.size() == 0) {
		cout << "NO" << endl;
		return 0;
	}

	memset(used, 0, sizeof used);

	DFS3(1, -1);

	if (sum != n) {
		cout << "NO" << endl;
		return 0;
	}

	bool kt = true;

	for (int i=0; i<cycle.size(); i++) {
		if (l[cycle[i]].size() > 3) {
			cout << "NO" << endl;
			return 0;
		}
		if (l[cycle[i]].size() == 3) {
			for (int r=0; r<l[cycle[i]].size(); r++) {
				if ( find(cycle.begin(), cycle.end(), l[cycle[i]][r]) == cycle.end()) {
					kt &= isTree(cycle[i], l[cycle[i]][r]);
				}
			}
		}
	}

	if (kt) {
		cout << "FHTAGN!" << endl;
		return 0;
	}

	cout << "NO" << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <memory.h>
#include <iomanip>
#include <string>
#include <map>
#include <utility>

using namespace std;

int n,m;

vector<int> l[111];

bool used[111];

bool DFS(int a, int p) {

	used[a] = true;
	for (int i=0; i<l[a].size(); i++) {
		if (l[a][i] != p) {
			if (used[l[a][i]])
				return false;
			if (DFS(l[a][i], a) == false)
				return false;
		}
	}

	return true;
}

bool isTree(int a, int b) {
	memset(used, 0, sizeof used);
	return DFS(b,a);
}

vector<int> cyc;

bool DFS2(int v, int p) {
	used[v] = true;

	for (int i=0; i<l[v].size(); i++) {
		if (l[v][i] == p) continue;
		if (used[l[v][i]]) {
			cyc.push_back(v);
			return false;
		}
		if (DFS2(l[v][i], v) == false) {
			cyc.push_back(v);
			return false;
		}
	}

	return true;
}

vector<int> findCycle() {
	memset(used, 0, sizeof used);

	DFS2(1, -1);

	return cyc;
}

int sum = 0;

void DFS3(int v, int p) {
	++sum;
	used[v] = true;

	for (int i=0; i<l[v].size(); i++) {
		if (l[v][i] == p) continue;
		if (used[l[v][i]]) continue;

		DFS3(l[v][i], v);
	}
}

bool c[111][111];
int main() {
	//freopen("input.txt", "r", stdin);

	cin >> n >> m;

	for (int i=0; i<m; i++) {
		int a,b;
		cin >> a >> b;
		c[a][b] = c[b][a] = true;
		l[a].push_back(b);
		l[b].push_back(a);
	}

	vector<int> cycle = findCycle();

	if (cycle.size() == 0) {
		cout << "NO" << endl;
		return 0;
	}

	memset(used, 0, sizeof used);

	DFS3(1, -1);

	if (sum != n) {
		cout << "NO" << endl;
		return 0;
	}

	bool kt = true;

	for (int i=0; i<cycle.size(); i++) {
		for (int r=0; r<l[cycle[i]].size(); r++) {
			if ( find(cycle.begin(), cycle.end(), l[cycle[i]][r]) == cycle.end()) {
				kt &= isTree(cycle[i], l[cycle[i]][r]);
			}
		}
	}

	if (kt) {
		cout << "FHTAGN!" << endl;
		return 0;
	}

	cout << "NO" << endl;

	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <memory.h>
#include <iomanip>
#include <string>
#include <map>
#include <utility>

using namespace std;

int n,m;

vector<int> l[111];

bool used[111];

bool DFS(int a, int p) {

	used[a] = true;
	for (int i=0; i<l[a].size(); i++) {
		if (l[a][i] != p) {
			if (used[l[a][i]])
				return false;
			if (DFS(l[a][i], a) == false)
				return false;
		}
	}

	return true;
}

bool isTree(int a, int b) {
	memset(used, 0, sizeof used);
	return DFS(b,a);
}

bool c[111][111];
int main() {
	//freopen("input.txt", "r", stdin);

	cin >> n >> m;

	for (int i=0; i<m; i++) {
		int a,b;
		cin >> a >> b;
		c[a][b] = c[b][a] = true;
		l[a].push_back(b);
		l[b].push_back(a);
	}

	for (int i=1; i<=n; i++) {
		for (int u=i+1; u<=n; u++) {
			for (int t=u+1; t<=n; t++) {
				if (c[i][u] && c[u][t] && c[t][i]) {
					if (l[i].size() <= 3 && l[u].size() <= 3 && l[t].size() <= 3) {
						bool kt = true;
						if (l[i].size() == 3) {
							for (int r=0; r<3; r++) {
								if (l[i][r] != u && l[i][r] != t)
									kt &= isTree(i, l[i][r]);
							}
						}
						if (l[u].size() == 3) {
							for (int r=0; r<3; r++) {
								if (l[u][r] != i && l[u][r] != t)
									kt &= isTree(u, l[u][r]);
							}
						}
						if (l[t].size() == 3) {
							for (int r=0; r<3; r++) {
								if (l[t][r] != u && l[t][r] != i)
									kt &= isTree(t, l[t][r]);
							}
						}

						if (kt) {
							cout << "FHTAGN!" << endl;
							return 0;
						}
					}
				}
			}
		}
	}

	cout << "NO" << endl;

	return 0;
}


#include<iostream>
#include<vector>
#include<cmath>

using namespace std;
int g[100][100];
bool mark[100];
int c =0;
 int n,m;
void dfs(int u,int p)
{
  //  cout <<u<<' ';
  mark[u]=true;
  for(int v=0 ;v<n;v++)
    {
      if (g[u][v]==1&&!mark[v])
    {
      dfs(v,u);
    }
      else if (g[v][u] == 1 &&mark[v]&&v!=p&&v!=u)
    {
      //      cout << v << ' ' << u << endl;
      c++;

    }

    }
}
int main()
{

  cin>>n>>m;
  for(int i =0; i<m;i++)
    {
      int tmpx,tmpy;
      cin>>tmpx>>tmpy;
      g[tmpx-1][tmpy-1] = 1;
      g[tmpy-1][tmpx-1] = 1;
    }
  dfs(0,0);
  c/=2;
  cout<<c<<" ";
  if (c == 1)
    {
      for(int i = 0 ; i<n;i++)
    {
          if (! mark[i])
        {
          cout<<"NO";
          return 0;
        }
    }
    }
  else
    {
      cout<<"NO";
      return 0;
    }

  cout<<"FHTAGN!";
  return 0;
}


#include<iostream>
#include<vector>
#include<cmath>

using namespace std;
int g[100][100];
bool mark[100];
int c =0;
 int n,m;
void dfs(int u,int p)
{
  //  cout <<u<<' ';
  mark[u]=true;
  for(int v=0 ;v<n;v++)
    {
      if (g[u][v]==1&&!mark[v])
	{
	  dfs(v,u);
	}
      else if (g[v][u] == 1 &&mark[v]&&v!=p&&v!=u)
	{
	  //	  cout << v << ' ' << u << endl;
	  c++;

	}

    }
}
int main()
{

  cin>>n>>m;
  for(int i =0; i<m;i++)
    {
      int tmpx,tmpy;
      cin>>tmpx>>tmpy;
      g[tmpx-1][tmpy-1] = 1;
      g[tmpy-1][tmpx-1] = 1;
    }
  dfs(0,0);
  c/=2;
  //  cout<<c<<" ";
  if (c == 1)
    {
      for(int i = 0 ; i<n;i++)
	{
	      if (! mark[i])
		{
		  cout<<"NO";
		  return 0;
		}
	}
    }
  else
    {
      cout<<"NO";
      return 0;
    }

  cout<<"FHTAGN!";
  return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <ctime>
#include <float.h>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define pb push_back
#define inf 1000000000
#define L(s) (int)(s).size()
#define rp(i,n) for(int (i)=0;(i)<(n);++(i))
#define C(a) memset((a),0,sizeof(a))
#define ll long long
#define all(c) (c).begin(), (c).end()
#define VI vector<int>
#define mp make_pair
#define pii pair<int,int>
#define pdd pair<double,double>
#define x first
#define y second
int a[111][111];
int c[111];
int n,m;
int main()
{
	scanf("%d%d",&n,&m);
	rp(i,m)
	{
		int p,q;
		scanf("%d%d",&p,&q);
		--p;--q;
		a[p][q]=a[q][p]=1;
		c[p]++;c[q]++;
	}
	bool upd=1;
	bool ends=0;
	do
	{
		upd=0;
		rp(i,n)
			if (c[i]==1)
			{
				rp(j,n)
					if (a[i][j]==1)
					{
						a[i][j]=a[j][i]=0;
						c[i]--;c[j]--;upd=1;
						if (c[j]==0)
							ends=1;
						break;

					}
			}
	}while(upd);
	if (ends)
	{
		cout<<"NO\n";
		return 0;
	}
	int st=-1,cnt=0;
	rp(i,n)
		if (c[i]!=2 && c[i]!=0)
		{
			cout<<"NO\n";
			return 0;
		}
		else
			if (c[i]==2)
			{
				if (st==-1)
					st=i;
				cnt++;
			}
	if (cnt<3)
	{
		cout<<"NO\n";
		return 0;
	}
	int cur=st;
	do
	{
		rp(i,n)
			if (a[cur][i])
			{
				a[cur][i]=a[i][cur]=0;
				c[cur]--;c[i]--;cur=i;
				break;
			}
	}while(cur!=st);
	rp(i,n)
		if (c[i]==2)
		{
			cout<<"NO\n";
			return 0;
		}
	cout<<"FHTAGN!\n";

}


#define _CRT_SECURE_NO_DEPRECATE
#include <ctime>
#include <float.h>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define pb push_back
#define inf 1000000000
#define L(s) (int)(s).size()
#define rp(i,n) for(int (i)=0;(i)<(n);++(i))
#define C(a) memset((a),0,sizeof(a))
#define ll long long
#define all(c) (c).begin(), (c).end()
#define VI vector<int>
#define mp make_pair
#define pii pair<int,int>
#define pdd pair<double,double>
#define x first
#define y second
int a[111][111];
int c[111];
int n,m;
int main()
{
	scanf("%d%d",&n,&m);
	rp(i,m)
	{
		int p,q;
		scanf("%d%d",&p,&q);
		--p;--q;
		a[p][q]=a[q][p]=1;
		c[p]++;c[q]++;
	}
	bool upd=1;
	do
	{
		upd=0;
		rp(i,n)
			if (c[i]==1)
			{
				rp(j,n)
					if (a[i][j]==1)
					{
						a[i][j]=a[j][i]=0;
						c[i]--;c[j]--;upd=1;break;
					}
			}
	}while(upd);
	int st=-1,cnt=0;
	rp(i,n)
		if (c[i]!=2 && c[i]!=0)
		{
			cout<<"NO\n";
			return 0;
		}
		else
			if (c[i]==2)
			{
				if (st==-1)
					st=i;
				cnt++;
			}
	if (cnt<3)
	{
		cout<<"NO\n";
		return 0;
	}
	int cur=st;
	do
	{
		rp(i,n)
			if (a[cur][i])
			{
				a[cur][i]=a[i][cur]=0;
				c[cur]--;c[i]--;cur=i;
				break;
			}
	}while(cur!=st);
	rp(i,n)
		if (c[i]==2)
		{
			cout<<"NO\n";
			return 0;
		}
	cout<<"FHTAGN!\n";

}


#define _CRT_SECURE_NO_DEPRECATE
#include <ctime>
#include <float.h>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
#include <set>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define pb push_back
#define inf 1000000000
#define L(s) (int)(s).size()
#define rp(i,n) for(int (i)=0;(i)<(n);++(i))
#define C(a) memset((a),0,sizeof(a))
#define ll long long
#define all(c) (c).begin(), (c).end()
#define VI vector<int>
#define mp make_pair
#define pii pair<int,int>
#define pdd pair<double,double>
#define x first
#define y second
int a[111][111];
int c[111];
int n,m;
int main()
{
	scanf("%d%d",&n,&m);
	rp(i,m)
	{
		int p,q;
		scanf("%d%d",&p,&q);
		--p;--q;
		a[p][q]=a[q][p]=1;
		c[p]++;c[q]++;
	}
	rp(i,n)
		if (c[i]==0)
		{
			cout<<"NO\n";
			return 0;
		}
	bool upd=1;
	bool ends=0;
	do
	{
		upd=0;
		rp(i,n)
			if (c[i]==1)
			{
				rp(j,n)
					if (a[i][j]==1)
					{
						a[i][j]=a[j][i]=0;
						c[i]--;c[j]--;upd=1;
						if (c[j]==0)
							ends=1;
						break;

					}
			}
	}while(upd);
	if (ends)
	{
		cout<<"NO\n";
		return 0;
	}
	int st=-1,cnt=0;
	rp(i,n)
		if (c[i]!=2 && c[i]!=0)
		{
			cout<<"NO\n";
			return 0;
		}
		else
			if (c[i]==2)
			{
				if (st==-1)
					st=i;
				cnt++;
			}
	if (cnt<3)
	{
		cout<<"NO\n";
		return 0;
	}
	int cur=st;
	do
	{
		rp(i,n)
			if (a[cur][i])
			{
				a[cur][i]=a[i][cur]=0;
				c[cur]--;c[i]--;cur=i;
				break;
			}
	}while(cur!=st);
	rp(i,n)
		if (c[i]==2)
		{
			cout<<"NO\n";
			return 0;
		}
	cout<<"FHTAGN!\n";

}


#include<iostream>
#include<vector>
#include<set>
using namespace std;

int mat[100][100];
int vis[100][100];

int n,m;
int cycles=0;

void cycle_det(int cur, int parent);

int main()
{
	cin>>n>>m;

	memset(mat,0,sizeof mat);
	memset(vis,0,sizeof vis);

	for(int i=0; i < m; i++)
	{
		int _1,_2;
		cin>>_1>>_2;

		mat[_1-1][_2-1]=1;
		mat[_2-1][_1-1]=1;
	}

	cycle_det(0,-1);

	if(cycles != 2)
		cout<<"NO\n";
	else
		cout<<"FHTAGN!\n";
}

void cycle_det(int cur, int parent)
{
	//cout<<cur<<endl;

	for(int i=0; i < n; i++)
	{
		int tmp=0;

		if(mat[cur][i]==1 && vis[cur][i]==0)
		{
			vis[cur][i]=1;
			vis[i][cur]=1;

			cycle_det(i, cur);
		}
		else if(mat[cur][i]==1 && i!=parent && vis[cur][i])
		{
			cycles++;

			//cout<< cur << " "<< i <<endl;
		}

		vis[cur][i]=2;
		vis[i][cur]=2;
	}
}


#include<iostream>
#include<vector>
#include<set>
using namespace std;

int mat[105][105];
int vis[105][105];
int nodes[105];

int n,m;
int cycles=0;

void cycle_det(int cur, int parent);

int main()
{
	cin>>n>>m;

	memset(mat,0,sizeof mat);
	memset(vis,0,sizeof vis);
	memset(nodes,0,sizeof nodes);

	for(int i=0; i < m; i++)
	{
		int _1,_2;
		cin>>_1>>_2;

		mat[_1-1][_2-1]=1;
		mat[_2-1][_1-1]=1;
	}

	cycle_det(0,-1);

	int count=0;

	for(int i=0; i < n; i++)
		if(nodes[i]==1)
			count++;

	if(cycles != 2 || count != n)
		cout<<"NO\n";
	else
		cout<<"FHTAGN!\n";
}

void cycle_det(int cur, int parent)
{
	//cout<<cur<<endl;

	nodes[cur]=1;

	for(int i=0; i < n; i++)
	{
		int tmp=0;

		if(mat[cur][i]==1 && vis[cur][i]==0)
		{
			vis[cur][i]=1;
			vis[i][cur]=1;

			cycle_det(i, cur);
		}
		else if(mat[cur][i]==1 && i!=parent && vis[cur][i])
		{
			cycles++;

			//cout<< cur << " "<< i <<endl;
		}

		vis[cur][i]=2;
		vis[i][cur]=2;
	}
}


#include<iostream>
#include<vector>
#include<set>
using namespace std;

int mat[105][105];
int nodes[105];

int n,m;
int cycles=0;

void cycle_det(int cur, int parent);

int main()
{
	cin>>n>>m;

	memset(mat,0,sizeof mat);
	//memset(vis,0,sizeof vis);
	memset(nodes,0,sizeof nodes);

	for(int i=0; i < m; i++)
	{
		int _1,_2;
		cin>>_1>>_2;

		mat[_1-1][_2-1]=1;
		mat[_2-1][_1-1]=1;
	}

	cycle_det(0,-1);

	int count=0;

	for(int i=0; i < n; i++)
		if(nodes[i]==1)
			count++;

	if(cycles != 2 || count != n)
		cout<<"NO\n";
	else
		cout<<"FHTAGN!\n";
}

void cycle_det(int cur, int parent)
{
	//cout<<cur<<endl;

	nodes[cur]=1;

	for(int i=0; i < n; i++)
	{
		int tmp=0;

		if(mat[cur][i]==1 && !nodes[i])
		{
			nodes[i]=1;

			cycle_det(i, cur);
		}
		else if(mat[cur][i]==1 && i!=parent && nodes[i])
		{
			cycles++;

			//cout<< cur << " "<< i <<endl;
		}
	}
}


#include<iostream>
#include<vector>
#include<set>
using namespace std;

int mat[100][100];
int vis[100][100];

int n,m;
int cycles=0;

void cycle_det(int cur);

int main()
{
	cin>>n>>m;

	memset(mat,0,sizeof mat);
	memset(vis,0,sizeof vis);

	for(int i=0; i < m; i++)
	{
		int _1,_2;
		cin>>_1>>_2;

		mat[_1-1][_2-1]=1;
		mat[_2-1][_1-1]=1;
	}

	cycle_det(0);

	if(cycles != 2)
		cout<<"NO\n";
	else
		cout<<"FHTAGN!\n";
}

void cycle_det(int cur)
{
	//cout<<cur<<endl;

	for(int i=0; i < n; i++)
	{
		int tmp=0;

		if(mat[cur][i]==1 && vis[cur][i]==0)
		{
			vis[cur][i]=1;
			vis[i][cur]=1;

			cycle_det(i);
		}
		else if(mat[cur][i]==1 && vis[cur][i]==2)
		{
			cycles++;

			//cout<< cur << " "<< i <<endl;
		}

		vis[cur][i]=2;
		vis[i][cur]=2;
	}
}


#include <vector>
#include <iostream>
using namespace std;
vector <int> G[100000];
bool visited[100000], cat[100000];
int m, ans = 0;
void dfs(int s) {
	visited[s] = true;
	for (int i = 0; i < (int)G[s].size(); i++) {
		if (!visited[G[s][i]]) {
			dfs(G[s][i]);
		}
	}
}
int main()
{
	int n, i, x, y,count=0;
	memset(visited, 0, sizeof(visited));
	cin >> n >> m;
	for (i = 0; i < m; i++)
	{
		cin >> x >> y;
		G[x - 1].push_back(y - 1);
		G[y - 1].push_back(x - 1);
	}
	for (i = 0; i < m;i++)
		if (!visited[i]) {
			dfs(i);
			count++;
		}
	if (count > 1)
		cout << "NO\n";
	else if (m >= n)
		cout << "FHTAGN!\n";
	else
		cout << "NO\n";
	return 0;
}


#include <vector>
#include <iostream>
using namespace std;
vector <int> G[100000];
bool visited[100000], cat[100000];
int m, ans = 0;
void dfs(int s) {
	visited[s] = true;
	for (int i = 0; i < (int)G[s].size(); i++) {
		if (!visited[G[s][i]]) {
			dfs(G[s][i]);
		}
	}
}
int main()
{
	int n, i, x, y,count=0;
	memset(visited, 0, sizeof(visited));
	cin >> n >> m;
	for (i = 0; i < m; i++)
	{
		cin >> x >> y;
		G[x - 1].push_back(y - 1);
		G[y - 1].push_back(x - 1);
	}
	for (i = 0; i < m;i++)
		if (!visited[i]) {
			dfs(i);
			count++;
		}
	if (count > 1)
		cout << "NO\n";
	else if (m == n)
		cout << "FHTAGN!\n";
	else
		cout << "NO\n";
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <cassert>
#include <algorithm>

using namespace std;

typedef long double ldb;
typedef long long int64;

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 2e18;

#define y1 qqqqqqq
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define pii pair < int, int >
#define all(a) (a).begin(), (a).end()
#define mp make_pair
#define fs first
#define sc second
#define sqr(x) ((int64) x) * (x)
#define last(a) (a.size() - 1)

const string name = "b";

const int NMAX = 105;
int n, m, g[NMAX][NMAX], loop[NMAX][NMAX], used[NMAX], st[NMAX];

void dfs(int v)
{
	used[v] = 1;
	forn(i, n)
		if (!used[i] && g[v][i])
			dfs(i);
}

bool good()
{
	seta(used, 0);
	dfs(0);
	forn(i, n)
		if (!used[i]) return 0;
	return 1;
}

int main()
{
	//freopen((name + ".in").data(), "r", stdin);
	//freopen((name + ".out").data(), "w", stdout);

	cin >> n >> m;
	seta(st, 0);
	forn(i, m)
	{
		int x, y;
		cin >> x >> y;
		x--, y--;
		g[x][y] = 1;
		g[y][x] = 1;
	}

	if (!good())
	{
		cout << "NO" << endl;
		return 0;
	}

	int ok = 0;
	seta(loop, 0);
	forn(i, n)
		forn(j, i)
			if (g[i][j])
			{
				g[i][j] = g[j][i] = 0;
				if (good())
				{
					loop[i][j] = loop[j][i] = 1;
					st[i]++, st[j]++;
					ok = 1;
				}
				g[i][j] = g[j][i] = 1;
			}

	if (!ok)
	{
		cout << "NO" << endl;
		return 0;
	}
	forn(i, n)
		if (st[i] != 0 && st[i] != 2)
		{
			cout << "NO" << endl;
			return 0;
		}

	seta(g, 0);
	forn(i, n)
		forn(j, n)
			g[i][j] = loop[i][j];
	int num = 0;
	seta(used, 0);
	forn(i, n)
		if (st[i] == 0) used[i] = 1;
	forn(i, n)
		if (!used[i])
		{
			dfs(i);
			num++;
		}
	if (num != 1)
	{
		cout << "NO" << endl;
		return 0;
	}
	cout << "FHTAGN" << endl;

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <cassert>
#include <algorithm>

using namespace std;

typedef long double ldb;
typedef long long int64;

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 2e18;

#define y1 qqqqqqq
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define pii pair < int, int >
#define all(a) (a).begin(), (a).end()
#define mp make_pair
#define fs first
#define sc second
#define sqr(x) ((int64) x) * (x)
#define last(a) (a.size() - 1)

const string name = "b";

const int NMAX = 105;
int n, m, g[NMAX][NMAX], loop[NMAX][NMAX], used[NMAX], st[NMAX];

void dfs(int v)
{
	used[v] = 1;
	forn(i, n)
		if (!used[i] && g[v][i])
			dfs(i);
}

bool good()
{
	seta(used, 0);
	dfs(0);
	forn(i, n)
		if (!used[i]) return 0;
	return 1;
}

int main()
{
	//freopen((name + ".in").data(), "r", stdin);
	//freopen((name + ".out").data(), "w", stdout);

	cin >> n >> m;
	seta(st, 0);
	forn(i, m)
	{
		int x, y;
		cin >> x >> y;
		x--, y--;
		g[x][y] = 1;
		g[y][x] = 1;
	}

	if (!good())
	{
		cout << "NO" << endl;
		return 0;
	}

	int ok = 0;
	seta(loop, 0);
	forn(i, n)
		forn(j, i)
			if (g[i][j])
			{
				g[i][j] = g[j][i] = 0;
				if (good())
				{
					loop[i][j] = loop[j][i] = 1;
					st[i]++, st[j]++;
					ok = 1;
				}
				g[i][j] = g[j][i] = 1;
			}

	if (!ok)
	{
		cout << "NO" << endl;
		return 0;
	}
	forn(i, n)
		if (st[i] != 0 && st[i] != 2)
		{
			cout << "NO" << endl;
			return 0;
		}

	seta(g, 0);
	forn(i, n)
		forn(j, n)
			g[i][j] = loop[i][j];
	int num = 0;
	seta(used, 0);
	forn(i, n)
		if (st[i] == 0) used[i] = 1;
	forn(i, n)
		if (!used[i])
		{
			dfs(i);
			num++;
		}
	if (num != 1)
	{
		cout << "NO" << endl;
		return 0;
	}
	cout << "FHTAGN!" << endl;

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
typedef long long ll;
#include<iostream>
#include<string>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int n, m;
vector<int> gra[2001];
bool visited[2001];
int cnt = 0;
void dfs(int node)
{
	visited[node] = true;
	cnt++;
	for (int i = 0; i < gra[node].size(); i++)
	{
		int child = gra[node][i];
		if (!visited[child])
			dfs(child);
	}
}
int main()
{
	memset(visited, false, sizeof(visited));
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		int x, y;
		cin >> x >> y;
		gra[x-1].push_back(y-1);
		gra[y-1].push_back(x-1);
	}
	dfs(0);
	cout << ((cnt == n && m>=n) ? "FHTAGN!" : "NO") << endl;
}


#define _CRT_SECURE_NO_WARNINGS
typedef long long ll;
#include<iostream>
#include<string>
#include<vector>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int n, m;
vector<int> gra[2001];
bool visited[2001];
int cnt = 0;
void dfs(int node)
{
	visited[node] = true;
	cnt++;
	for (int i = 0; i < gra[node].size(); i++)
	{
		int child = gra[node][i];
		if (!visited[child])
			dfs(child);
	}
}
int main()
{
	memset(visited, false, sizeof(visited));
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		int x, y;
		cin >> x >> y;
		gra[x-1].push_back(y-1);
		gra[y-1].push_back(x-1);
	}
	dfs(0);
	cout << ((cnt == n && m==n) ? "FHTAGN!" : "NO") << endl;
}


#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <bitset>       //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <iomanip>      //do setprecision
#include <ctime>
#include <complex>
using namespace std;

#define FOR(i,b,e) for(int i=(b);i<(e);++i)
#define FORQ(i,b,e) for(int i=(b);i<=(e);++i)
#define FORD(i,b,e) for(int i=(b)-1;i>=(e);--i)
#define REP(x, n) for(int x = 0; x < (n); ++x)

#define ST first
#define ND second
#define PB push_back
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double

#define MR 110

vector < int > g[MR];

int done[MR];
bool cykl;
vector < int > stos;
bool wCyklu[MR];

void dfs(int nr, int par)
{
    if(cykl)
        return;
    done[nr] = 1;
    stos.PB(nr);
    REP(i,(int)g[nr].size())
    {
        if(!done[g[nr][i]])
            dfs(g[nr][i], nr);
        else if(done[g[nr][i]] == 1 && g[nr][i] != par)
        {
            while(true)
            {
                wCyklu[stos.back()] = 1;
                if(stos.back() == g[nr][i])
                    break;
                stos.pop_back();
            }
            cykl = 1;
            return;
        }
        if(cykl)
            return;
    }
    done[nr] = 2;
    stos.pop_back();
}//dfs

int ilek;   //ile krawedzi odwiedzil
void dfs1(int nr)
{
    done[nr] = 1;
    REP(i,(int)g[nr].size())
        if(!done[g[nr][i]] && !wCyklu[g[nr][i]])
        {
            dfs1(g[nr][i]);
            ilek++;
        }
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    REP(i,m)
    {
        int a, b;
        scanf("%d%d", &a, &b);a--;b--;
        g[a].PB(b);
        g[b].PB(a);
    }
    dfs(0,-1);
    if(!cykl)
    {
        printf("NO\n");
        return 0;
    }
    memset(done, 0, sizeof(done));
    int ilew = 0;   //ilew w cyklu
    REP(i,n)
    {
        if(wCyklu[i])
        {
            ilew++;
            dfs1(i);
        }
    }
    int n1 = 0;
    REP(i,n)
        n1 += done[i];
    if(ilew+ilek == m && ilew > 2 && n1 == n)
        printf("FHTAGN!\n");
    else
        printf("NO\n");
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
using namespace std;

#define pii pair<int, int>

int n, m;
int p[1000];
int r[1000];
int x, y;
set<int> c;
int ca;
map<int, pii> s;
vector<int> ox[10000];
vector<int> oy[10000];
int circle;

int parent(int x)
{
	if(p[x] < 0 || p[x] == x) return x;
	return p[x] = parent(p[x]);
}

bool join(int x, int y)
{
	int px = parent(x);
	int py = parent(y);
	if(px == py) return 0;
	if(r[px] < r[py])
	{
		p[px] = py;
		r[py] += r[px];
	}
	else
	{
		p[py] = px;
		r[px] += r[py];
	}
	return 1;
}

int main()
{
	scanf("%d%d", &n, &m);
	fill_n(p, n + 1, -1);
	fill_n(r, n + 1, 1);
	for(int i = 1; i <= m; ++i)
	{
		scanf("%d%d", &x, &y);
		if(!join(x, y)) circle++;
	}
	if(circle == 1) printf("FHTAGN!");
	else printf("NO");
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
using namespace std;

#define pii pair<int, int>

int n, m;
int p[1000];
int r[1000];
int l[1000];
int x, y;
set<int> c;
int ca;
map<int, pii> s;
vector<int> ox[10000];
vector<int> oy[10000];
int circle;
int ans = 1;

int parent(int x)
{
	if(p[x] < 0 || p[x] == x) return x;
	return p[x] = parent(p[x]);
}

bool join(int x, int y)
{
	int px = parent(x);
	int py = parent(y);
	if(px == py) return 0;
	if(r[px] < r[py])
	{
		p[px] = py;
		r[py] += r[px];
	}
	else
	{
		p[py] = px;
		r[px] += r[py];
	}
	return 1;
}

int main()
{
	scanf("%d%d", &n, &m);
	fill_n(p, n + 1, -1);
	fill_n(r, n + 1, 1);
	fill_n(l, n + 1, 0);
	for(int i = 1; i <= m; ++i)
	{
		scanf("%d%d", &x, &y);
		if(!join(x, y)) circle++;
		l[x] = l[y] = 1;
	}
	for(int i = 1; i <= n; ++i)
		ans = ans & l[i];
	if(circle == 1 && ans) printf("FHTAGN!");
	else printf("NO");
	return 0;
}


 #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#define ll long long
#define ss size()
#define mp make_pair
#define pb push_back
using namespace std;
int n, m;
vector <int> gr[4000], gg[4000];
bool p[4000], b[4000];
int r[4000];
//void f(int v, int o){
//  b[v]=1;
//  r[v]=o;
//  for(int i=0; i<gg[v].ss; i++){
//      if(!b[gg[v][i]]&&!p[gg[v][i]]){
//          f(gg[v][i], o+1);
//      }
//  }
//}
int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++){
        p[i]=0;
    }
    for(int i=1; i<=m; i++){
        int a, p;
        cin>>a>>p;
        gr[a].pb(p);
        gr[p].pb(a);
        gg[a].pb(p);
        gg[p].pb(a);

    }
    bool w=0;
    int k=0;
    while(!w){
        vector <pair<int, int>> fd;
        for(int i=1; i<=n; i++){
            if(gr[i].ss==1){
                fd.pb(mp(i, gr[i][0]));
                gr[i].clear();
            }
        }
        if(fd.empty()){
            w=1;
        }else{
            for(int i=0; i<fd.size(); i++){
                for(int j=0; j<gr[fd[i].second].ss; j++){
                    if(gr[fd[i].second][j]==fd[i].first){
                        gr[fd[i].second].erase(gr[fd[i].second].begin()+j);
                        break;
                    }
                }
            }
        }
        k++;
    }
    int kkk=0;
    for(int i=1; i<=n; i++){
        if(!gr[i].empty()){
            kkk++;
            if(gr[i].ss>2){
                cout<<"NO";
                return 0;
            }
            p[i]=1;
            /*cout<<i<<": ";
            for(int j=0; j<gr[i].ss; j++){
                cout<<gr[i][j]<<" ";
            }
            cout<<endl;*/
        }
    }
    if(kkk<3){
        cout<<"NO";
        return 0;
    }
    //for(int i=1; i<=n; i++){
    //  if(!gr[i].empty()){
    //      f(i, 0);
    //      /*cout<<i<<": ";
    //      for(int j=0; j<gr[i].ss; j++){
    //          cout<<gr[i][j]<<" ";
    //      }
    //      cout<<endl;*/
    //  }
    //}
    cout<<"FHTAGN!";
    //for(int i=1; i<=n; i++){
    //  cout<<r[i]<<" ";
    //}
    return 0;
}


 <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#define ll long long
#define ss size()
#define mp make_pair
#define pb push_back
using namespace std;
int n, m;
vector <int> gr[4000], gg[4000];
bool p[4000], b[4000];
int r[4000];
//void f(int v, int o){
//  b[v]=1;
//  r[v]=o;
//  for(int i=0; i<gg[v].ss; i++){
//      if(!b[gg[v][i]]&&!p[gg[v][i]]){
//          f(gg[v][i], o+1);
//      }
//  }
//}
int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++){
        p[i]=0;
    }
    for(int i=1; i<=m; i++){
        int a, p;
        cin>>a>>p;
        gr[a].pb(p);
        gr[p].pb(a);
        gg[a].pb(p);
        gg[p].pb(a);

    }
    bool w=0;
    int k=0;
    while(!w){
        vector <pair<int, int>> fd;
        for(int i=1; i<=n; i++){
            if(gr[i].ss==1){
                fd.pb(mp(i, gr[i][0]));
                gr[i].clear();
            }
        }
        if(fd.empty()){
            w=1;
        }else{
            for(int i=0; i<fd.size(); i++){
                for(int j=0; j<gr[fd[i].second].ss; j++){
                    if(gr[fd[i].second][j]==fd[i].first){
                        gr[fd[i].second].erase(gr[fd[i].second].begin()+j);
                        break;
                    }
                }
            }
        }
        k++;
    }
    int kkk=0;
    for(int i=1; i<=n; i++){
        if(!gr[i].empty()){
            kkk++;
            if(gr[i].ss>2){
                cout<<"NO";
                return 0;
            }
            p[i]=1;
            /*cout<<i<<": ";
            for(int j=0; j<gr[i].ss; j++){
                cout<<gr[i][j]<<" ";
            }
            cout<<endl;*/
        }
    }
    if(kkk<3){
        cout<<"NO";
        return 0;
    }
    //for(int i=1; i<=n; i++){
    //  if(!gr[i].empty()){
    //      f(i, 0);
    //      /*cout<<i<<": ";
    //      for(int j=0; j<gr[i].ss; j++){
    //          cout<<gr[i][j]<<" ";
    //      }
    //      cout<<endl;*/
    //  }
    //}
    cout<<"FHTAGN!";
    //for(int i=1; i<=n; i++){
    //  cout<<r[i]<<" ";
    //}
    return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#define ll long long
#define ss size()
#define mp make_pair
#define pb push_back
using namespace std;
int n, m;
vector <int> gr[4000], gg[4000];
bool p[4000], b[4000], h[4000];
int r[4000];
int vs=0;
void f(int v){
  h[v]=1;
  vs++;
  for(int i=0; i<gg[v].ss; i++){
      if(!h[gg[v][i]]){
          f(gg[v][i]);
      }
  }
}
int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++){
        p[i]=0;
        h[i]=0;
        b[i]=0;
    }
    for(int i=1; i<=m; i++){
        int a, p;
        cin>>a>>p;
        gr[a].pb(p);
        gr[p].pb(a);
        gg[a].pb(p);
        gg[p].pb(a);

    }
    bool w=0;
    int k=0;
    while(!w){
        vector <pair<int, int>> fd;
        for(int i=1; i<=n; i++){
            if(gr[i].ss==1){
                fd.pb(mp(i, gr[i][0]));
                gr[i].clear();
            }
        }
        if(fd.empty()){
            w=1;
        }else{
            for(int i=0; i<fd.size(); i++){
                for(
                    int j=0; j<gr[fd[i].second].ss; j++){
                    if(gr[fd[i].second][j]==fd[i].first){
                        gr[fd[i].second].erase(gr[fd[i].second].begin()+j);
                        break;
                    }
                }
            }
        }
        k++;
    }
    int kkk=0;
    for(int i=1; i<=n; i++){
        if(!gr[i].empty()){
            if(!h[i]){
                f(i);
                if(vs!=n){
                    cout<<"NO";
                    return 0;
                }
            }
            kkk++;
            if(gr[i].ss>2){
                cout<<"NO";
                return 0;
            }
            p[i]=1;
        }
    }
    if(kkk<3||vs!=n){
        cout<<"NO";
        return 0;
    }
    cout<<"FHTAGN!";
    return 0;
}


#define _USE_MATH_DEFINES

#include <cmath>
#include <cstdio>

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define mp make_pair
#define pb push_back

#define DEBUG(x) cout << #x << ": " << (x) << endl;

set <int> G[110];
bool was[110];

int back[110];
int nR = 0, vF, vP, nV;
int nC = 0;

bool dfs(int from, int pred)
{
    if (was[from])
    {
        nC++;
        int t = pred;
        do
        {
            nR++;
            t = back[t];
        }
        while (t != back[from]);

        vF = from; vP = pred;
        return true;
    }
    was[from] = true;
    back[from] = pred;

    for (set<int>::iterator i= G[from].begin(); i != G[from].end(); i++)
        if (*i != pred)
            if (dfs(*i, from))
                return true;

    return false;
}

int u[110];
int getU(int x)
{
    if (u[x] == x)
        return x;
    return getU(u[x]);
}
void addU(int x, int y)
{
    if (rand()&1)
        u[getU(x)] = getU(y);
    else u[getU(y)] = getU(x);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen( "1.txt", "rt", stdin );
    //freopen("output.txt", "wt", stdout);
#endif

    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        G[a].insert(b);
        G[b].insert(a);
    }

    dfs(1, -1);
    if (nR < 3 || nC != 1)
    {
        cout << "NO";
        return 0;
    }

    vector<int> cycle;
    int _pred = vP;
    int _from = vF;
    do
    {
        cycle.pb(_from);
        G[_pred].erase(_from);
        G[_from].erase(_pred);
        _from = _pred;
        _pred = back[_pred];
    }
    while (_from != vF);

    for (int i = 1; i <= n; i++)
        u[i] = i;

    for (int i = 1; i <= n; i++)
        for (set<int>::iterator j = G[i].begin(); j != G[i].end(); j++)
            addU(i , *j);

    set<int> rootUnions;
    for (int i = 0; i < cycle.size(); i++)
        rootUnions.insert(getU(cycle[i]));

    set<int> res;
    for (int i = 1; i <= n; i++)
        res.insert(getU(u[i]));

    if (res.size() < 3 || !(rootUnions.size() == cycle.size() == res.size()))
        cout << "NO";
    else
        cout << "FHTAGN!";

    return ( 0 );
}


#define _USE_MATH_DEFINES

#include <cmath>
#include <cstdio>

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define mp make_pair
#define pb push_back

#define DEBUG(x) cout << #x << ": " << (x) << endl;

set <int> G[110];
bool was[110];

int back[110];
int nR = 0, vF, vP, nV;
int nC = 0;

bool dfs(int from, int pred)
{
    if (was[from])
    {
        nC++;
        int t = pred;
        do
        {
            nR++;
            t = back[t];
        }
        while (t != back[from]);

        vF = from; vP = pred;
        return true;
    }
    was[from] = true;
    back[from] = pred;

    for (set<int>::iterator i= G[from].begin(); i != G[from].end(); i++)
        if (*i != pred)
            if (dfs(*i, from))
                return true;

    return false;
}

int u[110];
int getU(int x)
{
    if (u[x] == x)
        return x;
    return getU(u[x]);
}
void addU(int x, int y)
{
    if (rand()&1)
        u[getU(x)] = getU(y);
    else u[getU(y)] = getU(x);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen( "1.txt", "rt", stdin );
    //freopen("output.txt", "wt", stdout);
#endif

    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        G[a].insert(b);
        G[b].insert(a);
    }

    dfs(1, -1);
    if (nR < 3 || nC != 1)
    {
        cout << "NO";
        return 0;
    }

    vector<int> cycle;
    int _pred = vP;
    int _from = vF;
    do
    {
        cycle.pb(_from);
        G[_pred].erase(_from);
        G[_from].erase(_pred);
        _from = _pred;
        _pred = back[_pred];
    }
    while (_from != vF);

    for (int i = 1; i <= n; i++)
        u[i] = i;

    for (int i = 1; i <= n; i++)
        for (set<int>::iterator j = G[i].begin(); j != G[i].end(); j++)
            addU(i , *j);

    set<int> rootUnions;
    for (int i = 0; i < cycle.size(); i++)
        rootUnions.insert(getU(cycle[i]));

    set<int> res;
    for (int i = 1; i <= n; i++)
        res.insert(getU(u[i]));

    if (res.size() < 3 || !(rootUnions.size() == cycle.size() && cycle.size()== res.size()))
        cout << "NO";
    else
        cout << "FHTAGN!";

    return ( 0 );
}


#define _USE_MATH_DEFINES

#include <cmath>
#include <cstdio>

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define mp make_pair
#define pb push_back

#define DEBUG(x) cout << #x << ": " << (x) << endl;

set <int> G[110];
bool was[110];

int back[110];
int nR = 0, vF, vP;
int nC = 0;
bool dfs(int from, int pred)
{
    if (was[from])
    {
        nC++;
        int t = pred;
        do
        {
            nR++;
            t = back[t];
        }
        while (t != back[from]);

        vF = from; vP = pred;
        return true;
    }

    was[from] = true;
    back[from] = pred;

    for (set<int>::iterator i= G[from].begin(); i != G[from].end(); i++)
        if (*i != pred)
            if (dfs(*i, from))
                return true;

    return false;
}

int u[110];
int getU(int x)
{
    if (u[x] == x)
        return x;
    return getU(u[x]);
}
void addU(int x, int y)
{
    if (rand()&1)
        u[getU(x)] = getU(y);
    else u[getU(y)] = getU(x);
}

bool was2[110];
void dfs2(int from, int pred)
{
    if (was2[from])
        return;
    if (pred != -1)
        addU(from, pred);

    was2[from] = true;

    for (set<int>::iterator i= G[from].begin(); i != G[from].end(); i++)
        if (!was2[*i])
            dfs2(*i, from);

    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen( "1.txt", "rt", stdin );
    //freopen("output.txt", "wt", stdout);
#endif

    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        G[a].insert(b);
        G[b].insert(a);
    }

    dfs(1, -1);
    if (nR < 3 || nC != 1)
    {
        cout << "NO";
        return 0;
    }

    int _pred = vP;
    int _from = vF;
    do
    {
        G[_pred].erase(_from);
        G[_from].erase(_pred);
        _from = _pred;
        _pred = back[_pred];
    }
    while (_from != vF);

    for (int i = 1; i <= n; i++)
        u[i] = i;

    for (int i = 1; i <= n; i++)
        dfs2(i, -1);

    set<int> res;
    for (int i = 1; i <= n; i++)
        res.insert(getU(u[i]));

    if (res.size() != 3)
        cout << "NO";
    else
        cout << "FHTAGN!";

    return ( 0 );
}


#define _USE_MATH_DEFINES

#include <cmath>
#include <cstdio>

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define mp make_pair
#define pb push_back

#define DEBUG(x) cout << #x << ": " << (x) << endl;

set <int> G[110];
bool was[110];

int back[110];
int nR = 0, vF, vP;
int nC = 0;
bool dfs(int from, int pred)
{
    if (was[from])
    {
        nC++;
        int t = pred;
        do
        {
            nR++;
            t = back[t];
        }
        while (t != back[from]);

        vF = from; vP = pred;
        return true;
    }

    was[from] = true;
    back[from] = pred;

    for (set<int>::iterator i= G[from].begin(); i != G[from].end(); i++)
        if (*i != pred)
            if (dfs(*i, from))
                return true;

    return false;
}

int u[110];
int getU(int x)
{
    if (u[x] == x)
        return x;
    return getU(u[x]);
}
void addU(int x, int y)
{
    if (rand()&1)
        u[getU(x)] = getU(y);
    else u[getU(y)] = getU(x);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen( "1.txt", "rt", stdin );
    //freopen("output.txt", "wt", stdout);
#endif

    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        G[a].insert(b);
        G[b].insert(a);
    }

    dfs(1, -1);
    if (nR < 3 || nC != 1)
    {
        cout << "NO";
        return 0;
    }

    int _pred = vP;
    int _from = vF;
    do
    {
        G[_pred].erase(_from);
        G[_from].erase(_pred);
        _from = _pred;
        _pred = back[_pred];
    }
    while (_from != vF);

    for (int i = 1; i <= n; i++)
        u[i] = i;

    for (int i = 1; i <= n; i++)
        for (set<int>::iterator j = G[i].begin(); j != G[i].end(); j++)
            addU(i , *j);

    set<int> res;
    for (int i = 1; i <= n; i++)
        res.insert(getU(u[i]));

    if (res.size() < 3)
        cout << "NO";
    else
        cout << "FHTAGN!";

    return ( 0 );
}