#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#define int long long
using namespace std;

const int N = 400 * 1000 + 5;
int n;

int a[N];
int cnt[N];
map <int, int> real;
vector <int> vec;
set <pair <int, int> > s;
vector <pair <int, int> > v;
vector <int> ans[N];

void comp() {
	for (int i = 0; i < n; i++) {
		vec.push_back(a[i]);
	}
	sort(vec.begin(), vec.end());
	vec.resize(unique(vec.begin(), vec.end()) - vec.begin());
	for (int i = 0; i < n; i++) {
		int x = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin();
		real[x] = a[i];
		a[i] = x;
		cnt[x]++;
	}
}

int32_t main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	comp();
	for (int i = 0; i < vec.size(); i++) {
		s.insert({-cnt[i], i});
	}
//	cout << 41 << endl;
	int m = n;
	while (s.size()) {
		pair <int, int> p = *s.begin();
		int c = p.first, x = p.second;
		if (1ll * c * c > (long long) m) {
			m--;
			s.erase(s.begin());
			cnt[x]--;
			s.insert({-cnt[x], x});
		}
		else {
			break;
		}
	}
//	cout << 42 << endl;
	int rad = 1;
	while (1ll * rad * rad <= m) {
		rad++;
	}
	rad--;
//	cout << rad << endl;
	pair <int, int> p = *s.begin();
	int maxc = -p.first;
	int ansfor = maxc;
	for (int j = 1; j <= rad; j++) {
		if (m % j <= m % ansfor) {
			ansfor = j;
		}
	}
	int x = ansfor, y = m / ansfor;
	for (auto p : s) {
		for (int i = 0; i < -p.first; i++) {
			v.push_back(p);
		}
	}
	for (int i = 0; i <= x; i++) {
		for (int j = 0; j <= y; j++) {
			ans[i].push_back(0);
		}
	}
	sort(v.begin(), v.end());
	for (int i = 0; i < x * y; i++) {
		int c = i % x;
		int d = (c + (i / x)) % y;
		ans[c][d] = v[i].second;
	}
	cout << x * y << endl;
	cout << x << " " << y << endl;
	for (int i = 0; i < x; i++) {
		for (int j = 0; j < y; j++) {
			cout << real[ans[i][j]] << " ";
		}
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <string>

#define SIZE 101
typedef long long ll;

using namespace std;
int timee = 0;
int visto[SIZE];
int parents[SIZE];

int edge[SIZE][SIZE];
int cont = 0;
void dfs (int initial) {
  int timee;
  vector<int> stack;
  vector<int> marked;

  stack.push_back(initial);
  int anterior = 0;
  while (stack.size() > 0) {

    int selected = stack.back();
    stack.pop_back();
    if (visto[selected] == -1) {
      anterior = parents[selected];
      edge[anterior][selected] = 2;
      edge[selected][anterior] = 2;
      anterior = selected;
      visto[selected] = 1;
      for (int i = 0; i < SIZE; i++) {
        if (edge[selected][i] != 0) {
          if (visto[i] == -1) {
            parents[i] = selected;

            stack.push_back(i);
          } else {
            if (edge[selected][i] == 1) {
              cont++;
            }
          }
        }
      }
    }
  }
}

int main() {

    int N, M;
    cont = 0;
    cin >> N >> M;

    for (int i = 0; i < SIZE; i++) {
      visto[i] = -1;
      parents[i] = 0;
      for (int j = 0; j < SIZE; j++) {
        edge[i][j] = 0;
      }
    }

    for (int i = 0; i < M; i++) {
        int x, y;
        cin >> x >> y;
        edge[x][y] = 1;
        edge[y][x] = 1;
      }

    dfs(1);
    if (cont==1){
      cout<<"FHTAGN!";
    }
    else{
      cout<<"NO";
    }
    cout<<endl;

}


#include <iostream>
#include <vector>
#include <string>
int N, M;
#define SIZE 101
typedef long long ll;
using namespace std;
int cont = 0;

ll parents[SIZE];
ll find(ll n){
  if(n == parents[n]){
    return n;
  }
  ll aux = find(parents[n]);
  parents[n] = aux;
  return find(parents[n]);
}
ll Union(ll n1, ll n2){
  ll p1 = find(n1);
  ll p2 = find(n2);
  if (p1 != p2)
  {
    parents[p1] = p2;
    return p2;
  }
  cont++;
  return -1;
}

int main() {

    cin >> N >> M;

    for (int i = 0; i < SIZE; i++) {
      parents[i] = i;

    }

    for (int i = 0; i < M; i++) {
        ll x, y;
        cin >> x >> y;
        Union(x, y);
      }
    if (cont==1 && M >= N){
      cout<<"FHTAGN!";
    }
    else{
      cout<<"NO";
    }
    cout<<endl;

}


#include <iostream>
#include <vector>
#include <string>

#define SIZE 101
typedef long long ll;

using namespace std;
int timee = 0;
int visto[SIZE];
int parents[SIZE];

int edge[SIZE][SIZE];
int cont = 0;
void dfs (int initial) {
  int timee;
  vector<int> stack;
  vector<int> marked;

  stack.push_back(initial);
  int anterior = 0;
  while (stack.size() > 0) {

    int selected = stack.back();
    stack.pop_back();
    if (visto[selected] == -1) {
      anterior = parents[selected];
      edge[anterior][selected] = 2;
      edge[selected][anterior] = 2;
      anterior = selected;
      visto[selected] = 1;
      for (int i = 0; i < SIZE; i++) {
        if (edge[selected][i] != 0) {
          if (visto[i] == -1) {
            parents[i] = selected;

            stack.push_back(i);
          } else {
            if (edge[selected][i] == 1) {
              cont++;
            }
          }
        }
      }
    }
  }
}

int main() {

    int N, M;
    cont = 0;
    cin >> N >> M;

    for (int i = 0; i < SIZE; i++) {
      visto[i] = -1;
      parents[i] = 0;
      for (int j = 0; j < SIZE; j++) {
        edge[i][j] = 0;
      }
    }

    for (int i = 0; i < M; i++) {
        int x, y;
        cin >> x >> y;
        edge[x][y] = 1;
        edge[y][x] = 1;
      }
    for (int i = 1; i <= N; i++) {
      dfs(i);
    }

    if (cont==1 && N > 3){
      cout<<"FHTAGN!";
    }
    else{
      cout<<"NO";
    }
    cout<<endl;

}


#include <iostream>
#include <vector>
#include <string>

#define SIZE 101
typedef long long ll;

using namespace std;
int timee = 0;
int visto[SIZE];
int parents[SIZE];

int edge[SIZE][SIZE];
int cont = 0;
void dfs (int initial) {
  int timee;
  vector<int> stack;
  vector<int> marked;

  stack.push_back(initial);
  int anterior = 0;
  while (stack.size() > 0) {

    int selected = stack.back();
    stack.pop_back();
    if (visto[selected] == -1) {
      anterior = parents[selected];
      edge[anterior][selected] = 2;
      edge[selected][anterior] = 2;
      anterior = selected;
      visto[selected] = 1;
      for (int i = 0; i < SIZE; i++) {
        if (edge[selected][i] != 0) {
          if (visto[i] == -1) {
            parents[i] = selected;

            stack.push_back(i);
          } else {
            if (edge[selected][i] == 1) {
              cont++;
            }
          }
        }
      }
    }
  }
}

int main() {

    int N, M;
    cont = 0;
    cin >> N >> M;

    for (int i = 0; i < SIZE; i++) {
      visto[i] = -1;
      parents[i] = 0;
      for (int j = 0; j < SIZE; j++) {
        edge[i][j] = 0;
      }
    }

    for (int i = 0; i < M; i++) {
        int x, y;
        cin >> x >> y;
        edge[x][y] = 1;
        edge[y][x] = 1;
      }
    for (int i = 1; i <= N; i++) {
      dfs(i);
    }

    if (cont==1){
      cout<<"FHTAGN!";
    }
    else{
      cout<<"NO";
    }
    cout<<endl;

}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define inf 1000000000
#define ii pair<int, int>
#define vi vector<int>
#define vii vector< vector<int> >
#define mod 1000000007
#define Left 1
#define Right 2

vii adj;
bool vis[110], fl = 0;
//vi dfsNum, dfsLow;
int dfsCnt = 0;

void dfs(int u, int p)
{
    dfsCnt++;
    vis[u] = 1;
    for(int i=0; i<(int)adj[u].size(); i++){
        int v = adj[u][i];
        if(!vis[v]){
            dfs(v, u);
        }else if(v != p){
            fl = 1;
        }
    }
}

int main()
{
//    freopen("friday.in","r",stdin);
//    freopen("out.txt","w",stdout);
    int n, m;
    scanf("%d%d", &n, &m);
    adj.assign(n+1, vi(0));
//    dfsNum.assign(n+1, 0);
//    dfsLow.assign(n+1, 0);
    int x, y;
    for(int i=0; i<m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    dfs(1, 0);
    if(fl && dfsCnt == n) printf("FHTAGN!");
    else printf("NO");

}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define inf 1000000000
#define ii pair<int, int>
#define vi vector<int>
#define vii vector< vector<int> >
#define mod 1000000007
#define Left 1
#define Right 2

vii adj;
bool vis[110], fl = 0;
//vi dfsNum, dfsLow;
//int dfsCnt = 1;

void dfs(int u, int p)
{
//    dfsNum[u] = dfsLow[u] = dfsCnt++;
    vis[u] = 1;
    for(int i=0; i<(int)adj[u].size(); i++){
        int v = adj[u][i];
        if(!vis[v]){
            dfs(v, u);
        }else if(v != p){
            fl = 1;
            return;
        }
    }
}

int main()
{
//    freopen("friday.in","r",stdin);
//    freopen("out.txt","w",stdout);
    int n, m;
    scanf("%d%d", &n, &m);
    adj.assign(n+1, vi(0));
//    dfsNum.assign(n+1, 0);
//    dfsLow.assign(n+1, 0);
    int x, y;
    for(int i=0; i<m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    dfs(1, 0);
    if(fl) printf("FHTAGN!");
    else printf("NO");

}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define inf 1000000000
#define ii pair<int, int>
#define vi vector<int>
#define vii vector< vector<int> >
#define mod 1000000007
#define Left 1
#define Right 2

vii adj;
bool vis[110];
int fl = 0;
//vi dfsNum, dfsLow;
int dfsCnt = 0;

void dfs(int u, int p)
{
    dfsCnt++;
    vis[u] = 1;
    for(int i=0; i<(int)adj[u].size(); i++){
        int v = adj[u][i];
        if(!vis[v]){
            dfs(v, u);
        }else if(v != p){
            fl++;
        }
    }
}

int main()
{
//    freopen("friday.in","r",stdin);
//    freopen("out.txt","w",stdout);
    int n, m;
    scanf("%d%d", &n, &m);
    adj.assign(n+1, vi(0));
//    dfsNum.assign(n+1, 0);
//    dfsLow.assign(n+1, 0);
    int x, y;
    for(int i=0; i<m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    dfs(1, 0);
    if(fl==1 && dfsCnt == n) printf("FHTAGN!");
    else printf("NO");

}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#define inf 1000000000
#define ii pair<int, int>
#define vi vector<int>
#define vii vector< vector<int> >
#define mod 1000000007
#define Left 1
#define Right 2

vii adj;
bool vis[110];
int fl = 0;
//vi dfsNum, dfsLow;
int dfsCnt = 0;

void dfs(int u, int p)
{
    dfsCnt++;
    vis[u] = 1;
    for(int i=0; i<(int)adj[u].size(); i++){
        int v = adj[u][i];
        if(!vis[v]){
            dfs(v, u);
        }else if(v != p){
            fl++;
        }
    }
}

int main()
{
//    freopen("friday.in","r",stdin);
//    freopen("out.txt","w",stdout);
    int n, m;
    scanf("%d%d", &n, &m);
    adj.assign(n+1, vi(0));
//    dfsNum.assign(n+1, 0);
//    dfsLow.assign(n+1, 0);
    int x, y;
    for(int i=0; i<m; i++){
        scanf("%d%d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    dfs(1, 0);
//    cout<<fl<<endl;
    if(fl==2 && dfsCnt == n) printf("FHTAGN!");
    else printf("NO");

}


#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned int uint;
using namespace std;
const int MAX = 1e6+10;
const int N = 1e5+5;
const int J=550;
#define IO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,m,x,y,cnt;

vector<int> adj[N];
bool vis[N];

void dfs(int src)
{
    cnt++;
    vis[src]=1;
    for(auto x:adj[src])
        if(!vis[x])
            dfs(x);
}
int main ()
{
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    if(m==n)
    {
        dfs(1);
        if(cnt==n) puts("FHTAGN!");
        else puts("NO");
    }
    else puts("NO");
}


#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned int uint;
using namespace std;
const int MAX = 1e6+10;
const int N = 1e5+5;
const int J=550;
#define IO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,m,x,y,cnt;

vector<int> adj[N];
bool vis[N];

void dfs(int src)
{
    cnt++;
    vis[src]=1;
    for(auto x:adj[src])
        if(!vis[x])
            dfs(x);
}
int main ()
{
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    if(m>=n)
    {
        dfs(1);
        if(cnt==n) puts("FHTAGN!");
        else puts("NO");
    }
    else puts("NO");
}


#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned int uint;
using namespace std;
const int MAX = 1e6+10;
const int N = 1e5+5;
const int J=550;
#define IO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,m,x,y,cnt;

vector<int> adj[N];
bool vis[N];

void dfs(int src)
{
    cnt++;
    vis[src]=1;
    for(auto x:adj[src])
        if(!vis[x])
            dfs(x);
}
int main ()
{
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    if(m>=n)
    {
        dfs(1);
        if(cnt==n) puts("FHTAGN!");
    }
    else puts("NO");
}


//  ROAD TO GREEN
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <iomanip>

using namespace std;
typedef long long ll;
const ll MAXN = 1e5;
vector<bool> used(MAXN,false);
int v[102][102];
int n,m;
int nodes = 0;
int cycles = 0;

void dfs(int s, int p){
    used[s] = true;
    nodes++;
    for(int i = 1; i <= n; i++){
        if(!used[i]){
            if(v[s][i] == 1){
                dfs(i,s);
            }
        }
        else{
            if(v[s][i] == 1 && i != p && p != -1){
                v[s][i] = 0;
                v[i][s] = 0;
                cycles++;
            }
        }
    }
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        int a,b;
        cin >> a >> b;
        v[a][b] = v[b][a] = 1;
    }
    dfs(1,-1);
    if(cycles == 1 && nodes == n){
        cout << "FHTAGN!" << endl;
    }
    else{
        cout << "NO" << endl;
    }

    return 0;
}


//  ROAD TO GREEN
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <iomanip>

using namespace std;
typedef long long ll;
const ll MAXN = 1e5;
vector<bool> used(MAXN,false);
int v[102][102];
int n,m;
int cntn = 0;
int cntc = 0;

void dfs(int s, int p){
    used[s] = true;
    cntn++;
    for(int i = 1; i <= n; i++){
        if(!used[i]){
            if(v[s][i] == 1)
            dfs(i,s);
        }
    }
}

int main(){
    cin >> n >> m;
    vector<int> deg(n+1,0);
    int leafs = 0;
    for(int i = 1; i <= m; i++){
        int a,b;
        cin >> a >> b;
        v[a][b] = v[b][a] = 1;
        deg[a]++;
        deg[b]++;
    }
    dfs(1,-1);
    if(cntn != n){
        cout << "NO" << endl;
        return 0;
    }
    while(true){
        int cnt = 0;
        for(int i = 1; i <= n; i++){
            if(deg[i] == 1){
                leafs++;
                deg[i]--;
                for(int j = 1; j <= n; j++){
                    if(v[i][j] == 1){
                        v[i][j] = 0;
                        v[j][i] = 0;
                        deg[j]--;
                    }
                }
            }
            else{
                cnt++;
            }
        }
        if(cnt == n)
        break;
    }
    for(int i = 1; i <= n; i++){
        if(deg[i] == 2)
        leafs++;
    }
    if(leafs == n){
        cout << "FHTAGN!" << endl;
    }
    else{
        cout << "NO" << endl;
    }
    return 0;
}


//  ROAD TO GREEN
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <iomanip>

using namespace std;
typedef long long ll;
const ll MAXN = 1e5;
vector<bool> used(MAXN,false);
int v[102][102];
int n,m;
int cntn = 0;
int cntc = 0;

void dfs(int s, int p){
    used[s] = true;
    cntn++;
    for(int i = 1; i <= n; i++){
        if(!used[i] && v[s][i] == 1){
            dfs(i,s);
        }
        else{
            if(v[s][i] == 1 && i != p && p != -1){
                cntc++;
            }
        }
    }
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        int a,b;
        cin >> a >> b;
        v[a][b] = v[b][a] = 1;
    }
    dfs(1,-1);
    if(cntc == 1 && cntn == n){
        cout << "FHTAGN!" << endl;
    }
    else{
        cout << "NO" << endl;
    }
    return 0;
}


//  ROAD TO GREEN
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cmath>
#include <iomanip>

using namespace std;
typedef long long ll;
const ll MAXN = 1e5;
vector<bool> used(MAXN,false);
int v[102][102];
int n,m;
int cntn = 0;
int cntc = 0;

void dfs(int s, int p){
    used[s] = true;
    cntn++;
    for(int i = 1; i <= n; i++){
        if(!used[i] && v[s][i] == 1){
            dfs(i,s);
        }
        else{
            if(v[s][i] == 1 && i != p && p != -1){
                cntc++;
            }
        }
    }
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        int a,b;
        cin >> a >> b;
        v[a][b] = v[b][a] = 1;
    }
    dfs(1,-1);
    if(cntc > 0 && cntn == n){
        cout << "FHTAGN!" << endl;
    }
    else{
        cout << "NO" << endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
vector<ll>v[105];
ll visited[105],cnt=0;
void dfs(ll x)
{
    visited[x]=1;
    for(ll i=0;i<v[x].size();i++)
    {
        if(visited[v[x][i]]==0)
        {
            cnt++;
            dfs(v[x][i]);
        }
    }

}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
ll i,n,m,x,y;
cin>>n>>m;
for(i=0;i<m;i++)
{
    cin>>x>>y;
    v[x].push_back(y);
    v[y].push_back(x);
}
if(n!=m)
{
    cout<<"NO";
    return 0;
}
dfs(1);
if(cnt==m-1)
    cout<<"FHTAGN!";
return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
vector<ll>v[105];
ll visited[105],cnt=0;
void dfs(ll x)
{
    visited[x]=1;
    for(ll i=0;i<v[x].size();i++)
    {
        if(visited[v[x][i]]==0)
        {
            cnt++;
            dfs(v[x][i]);
        }
    }

}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
ll i,n,m,x,y;
cin>>n>>m;
for(i=0;i<m;i++)
{
    cin>>x>>y;
    v[x].push_back(y);
    v[y].push_back(x);
}
if(n!=m)
{
    cout<<"NO";
    return 0;
}
dfs(1);
if(cnt==m-1)
    cout<<"FHTAGN!";
else
    cout<<"NO";
return 0;
}


#include <iostream>
#include <set>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <numeric>
#include <assert.h>

using namespace std;

#define lop(i,n) for(int i=0 ;i<n ;i++)
#define VI    vector<int>
#define VLL    vector<ll>
#define VPI    vector<pair<int,int>>
#define VII    vector<VI>
#define all(v)    v.begin() , v.end()
#define SORT(v)    sort(all(v))
#define ll    long long
#define ull unsigned long long
#define scni(x)    scanf("%d",&x)
#define scnll(x)    scanf("%lld",&x)
#define scnd(x)    scanf("%lf",&x)
#define prnti(x)    printf("%d\n",x)
#define prntll(x)    printf("%lld",x)
#define prntd(x)    printf("%.9lf",x)
#define sz(x)  x.size()
#define pp push_back
#define P pair<int , int>
#define mp make_pair

const double EPS = 1e-9;
const double PI = 3.14159265359;

//  O( n * log(log(n)) )
vector<ll> primes;
void GeneratingPrimes(int top){
    vector<bool> p (top+1 , 1);
//    vector<ll> primes;
    p[0] = p[1] = 0;

    for(int i = 2; i <= sqrt(top) ; i++){
        if(p[i]){
            for(int j = i*i ; j <= top ; j+=i){
                p[j]=0;
            }
        }
    }
    lop(i , top+1)
        if(p[i])primes.push_back(i);
//    return primes;
}

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);}
void EXTgcd(ll a , ll b , ll & x0 , ll & y0){
    if(b==0){ x0 =1 , y0 = 0; return; }
    EXTgcd( b , a%b , x0 , y0 );
    ll x1 = y0;
    ll y1 = x0 - (a/b) * (y0);

	y1 = y1;
    x0 = x1;
    y0 = y1;
}

long long power(long long n, long long p , ll mod) {
    if (!p)
        return 1;
    long long ans = 1;
    while (p > 1) {
        if (p & 1)
            ans = (ans * n) % mod;
        n = (n * n) % mod;
        p /= 2;
    }
    return (ans * n) % mod;
}

double dist(double a , double b , double x, double y){ return sqrt( pow( a-x ,2) + pow( b-y ,2) ); }
double dist3(double a , double b , double c , double x , double y ,double z ){ return sqrt( pow( a-x ,2) + pow( b-y ,2) + pow( c-z ,2)); }

int xadd[9]= { 1 , -1 , 0 , 1 , -1 , 0 , 1 , -1 , 0 };
int yadd[9]= { 1 , -1 , 0 ,-1 ,  0 , 1 , 0 ,  1, -1 };

int xx[4]={0 , 1 , 0 , -1};
int yy[4]={1 , 0 , -1 , 0};

#define no  { cout<<"NO\n";  }
#define yes { cout<<"YES\n"; }
#define _1  { cout<<"-1\n";  }

ll const N = 1e2 + 10;
ll const INF = 1e18;
ll const mod = 1000000009;

///////////////////////////////////////////////////////////////////

int n,m,vis[N],roots[N],ok,fnd=0;
VI e[N];

bool dfsTree(int idx){
	vis[idx]=1;
	for(int to:e[idx])if(!vis[to] && to){
		if(roots[to])return 0;
		dfsTree(to);
	}
	return 1;
}

bool dfs(int idx, int par=0){
	vis[idx]=1;
	for(int i=0;i<sz(e[idx]);i++){
		int to = e[idx][i];
		if(vis[to]){
			if(to == par)continue;
			roots[to]=1;
			fnd=1;
			e[idx][i]=0;
			for(int j=0;j<sz(e[to]);j++)if(e[to][j]==idx){e[to][j]=0;break;}
			return 1;
		}else{
			bool r = dfs(to , idx);
			if(r){
				roots[to]=1;
				e[idx][i]=0;
				for(int j=0;j<sz(e[to]);j++)if(e[to][j]==idx){e[to][j]=0;break;}
				return !roots[idx];
			}
		}
	}
	return 0;
}

int main(){
	cin >> n >> m;
	while(m--){
		int x,y;
		scni(x),scni(y);
		e[x].pp(y);
		e[y].pp(x);
		vis[x]=vis[y]=1;
	}

	for(int i=1 ;i<=n ;i++){
		memset(vis , 0 , sizeof vis);
		dfs(i);
		if(fnd){ok=1;break;}
	}
	memset(vis , 0 , sizeof vis);

	if(!ok)return cout<<"NO",0;
	for(int i=1 ;i<=n ;i++)if(roots[i]){
		if(!dfsTree(i))return cout<<"NO",0;
	}
	ok=1;
	lop(i,n)if(!vis[i+1])ok=0;
	if(ok)cout << "FHTAGN!";
	else cout << "NO";
return 0;}


#include <iostream>
#include <set>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <numeric>
#include <assert.h>

using namespace std;

#define lop(i,n) for(int i=0 ;i<n ;i++)
#define VI    vector<int>
#define VLL    vector<ll>
#define VPI    vector<pair<int,int>>
#define VII    vector<VI>
#define all(v)    v.begin() , v.end()
#define SORT(v)    sort(all(v))
#define ll    long long
#define ull unsigned long long
#define scni(x)    scanf("%d",&x)
#define scnll(x)    scanf("%lld",&x)
#define scnd(x)    scanf("%lf",&x)
#define prnti(x)    printf("%d\n",x)
#define prntll(x)    printf("%lld",x)
#define prntd(x)    printf("%.9lf",x)
#define sz(x)  x.size()
#define pp push_back
#define P pair<int , int>
#define mp make_pair

const double EPS = 1e-9;
const double PI = 3.14159265359;

//  O( n * log(log(n)) )
vector<ll> primes;
void GeneratingPrimes(int top){
    vector<bool> p (top+1 , 1);
//    vector<ll> primes;
    p[0] = p[1] = 0;

    for(int i = 2; i <= sqrt(top) ; i++){
        if(p[i]){
            for(int j = i*i ; j <= top ; j+=i){
                p[j]=0;
            }
        }
    }
    lop(i , top+1)
        if(p[i])primes.push_back(i);
//    return primes;
}

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);}
void EXTgcd(ll a , ll b , ll & x0 , ll & y0){
    if(b==0){ x0 =1 , y0 = 0; return; }
    EXTgcd( b , a%b , x0 , y0 );
    ll x1 = y0;
    ll y1 = x0 - (a/b) * (y0);

	y1 = y1;
    x0 = x1;
    y0 = y1;
}

long long power(long long n, long long p , ll mod) {
    if (!p)
        return 1;
    long long ans = 1;
    while (p > 1) {
        if (p & 1)
            ans = (ans * n) % mod;
        n = (n * n) % mod;
        p /= 2;
    }
    return (ans * n) % mod;
}

double dist(double a , double b , double x, double y){ return sqrt( pow( a-x ,2) + pow( b-y ,2) ); }
double dist3(double a , double b , double c , double x , double y ,double z ){ return sqrt( pow( a-x ,2) + pow( b-y ,2) + pow( c-z ,2)); }

int xadd[9]= { 1 , -1 , 0 , 1 , -1 , 0 , 1 , -1 , 0 };
int yadd[9]= { 1 , -1 , 0 ,-1 ,  0 , 1 , 0 ,  1, -1 };

int xx[4]={0 , 1 , 0 , -1};
int yy[4]={1 , 0 , -1 , 0};

#define no  { cout<<"NO\n";  }
#define yes { cout<<"YES\n"; }
#define _1  { cout<<"-1\n";  }

ll const N = 1e2 + 10;
ll const INF = 1e18;
ll const mod = 1000000009;

///////////////////////////////////////////////////////////////////

int n,m,vis[N];
VI e[N];

void dfs(int idx){vis[idx]=1; for(int to:e[idx])if(!vis[to]){dfs(to);}}

int main(){
	cin >> n >> m;
	lop(i,m){
		int x,y;
		scni(x),scni(y);
		e[x].pp(y);
		e[y].pp(x);
	}
	if(n==m)dfs(1);
	bool ok=1;
	lop(i,n)if(!vis[i+1])ok=0;
	if(!ok)cout << "NO";
	else cout << "FHTAGN!";

return 0;}


#include <iostream>
#include <set>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <numeric>
#include <assert.h>

using namespace std;

#define lop(i,n) for(int i=0 ;i<n ;i++)
#define VI    vector<int>
#define VLL    vector<ll>
#define VPI    vector<pair<int,int>>
#define VII    vector<VI>
#define all(v)    v.begin() , v.end()
#define SORT(v)    sort(all(v))
#define ll    long long
#define ull unsigned long long
#define scni(x)    scanf("%d",&x)
#define scnll(x)    scanf("%lld",&x)
#define scnd(x)    scanf("%lf",&x)
#define prnti(x)    printf("%d\n",x)
#define prntll(x)    printf("%lld",x)
#define prntd(x)    printf("%.9lf",x)
#define sz(x)  x.size()
#define pp push_back
#define P pair<int , int>
#define mp make_pair

const double EPS = 1e-9;
const double PI = 3.14159265359;

//  O( n * log(log(n)) )
vector<ll> primes;
void GeneratingPrimes(int top){
    vector<bool> p (top+1 , 1);
//    vector<ll> primes;
    p[0] = p[1] = 0;

    for(int i = 2; i <= sqrt(top) ; i++){
        if(p[i]){
            for(int j = i*i ; j <= top ; j+=i){
                p[j]=0;
            }
        }
    }
    lop(i , top+1)
        if(p[i])primes.push_back(i);
//    return primes;
}

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);}
void EXTgcd(ll a , ll b , ll & x0 , ll & y0){
    if(b==0){ x0 =1 , y0 = 0; return; }
    EXTgcd( b , a%b , x0 , y0 );
    ll x1 = y0;
    ll y1 = x0 - (a/b) * (y0);

	y1 = y1;
    x0 = x1;
    y0 = y1;
}

long long power(long long n, long long p , ll mod) {
    if (!p)
        return 1;
    long long ans = 1;
    while (p > 1) {
        if (p & 1)
            ans = (ans * n) % mod;
        n = (n * n) % mod;
        p /= 2;
    }
    return (ans * n) % mod;
}

double dist(double a , double b , double x, double y){ return sqrt( pow( a-x ,2) + pow( b-y ,2) ); }
double dist3(double a , double b , double c , double x , double y ,double z ){ return sqrt( pow( a-x ,2) + pow( b-y ,2) + pow( c-z ,2)); }

int xadd[9]= { 1 , -1 , 0 , 1 , -1 , 0 , 1 , -1 , 0 };
int yadd[9]= { 1 , -1 , 0 ,-1 ,  0 , 1 , 0 ,  1, -1 };

int xx[4]={0 , 1 , 0 , -1};
int yy[4]={1 , 0 , -1 , 0};

#define no  { cout<<"NO\n";  }
#define yes { cout<<"YES\n"; }
#define _1  { cout<<"-1\n";  }

ll const N = 1e2 + 10;
ll const INF = 1e18;
ll const mod = 1000000009;

///////////////////////////////////////////////////////////////////

int n,m,vis[N],roots[N],ok,fnd=0;
VI e[N];

bool dfsTree(int idx){
	vis[idx]=1;
	for(int to:e[idx])if(!vis[to]){
		if(roots[to]){if(!roots[idx])return 0;else continue;}
		dfsTree(to);
	}
	return 1;
}

bool dfs(int idx, int par=0){
	vis[idx]=1;

	for(int to:e[idx]){
		if(vis[to]){
			if(to == par)continue;
			roots[to]=1;
			fnd=1;
			return 1;
		}else{
			bool r = dfs(to , idx);
			if(r){
				roots[to]=1;
				return !roots[idx];
			}
		}
	}
	return 0;
}

int main(){
	cin >> n >> m;
	while(m--){
		int x,y;
		scni(x),scni(y);
		e[x].pp(y);
		e[y].pp(x);
		vis[x]=vis[y]=1;
	}

	for(int i=1 ;i<=n ;i++){
		memset(vis , 0 , sizeof vis);
		dfs(i);
		if(fnd){ok=1;break;}
	}
	memset(vis , 0 , sizeof vis);

	if(!ok)return cout<<"NO",0;
	for(int i=1 ;i<=n ;i++)if(roots[i]){
		if(!dfsTree(i))return cout<<"NO",0;
	}
	ok=1;
	lop(i,n)if(!vis[i+1])ok=0;
	if(ok)cout << "FHTAGN!";
	else cout << "NO";
return 0;}


#include <iostream>
#include <set>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <numeric>
#include <assert.h>

using namespace std;

#define lop(i,n) for(int i=0 ;i<n ;i++)
#define VI    vector<int>
#define VLL    vector<ll>
#define VPI    vector<pair<int,int>>
#define VII    vector<VI>
#define all(v)    v.begin() , v.end()
#define SORT(v)    sort(all(v))
#define ll    long long
#define ull unsigned long long
#define scni(x)    scanf("%d",&x)
#define scnll(x)    scanf("%lld",&x)
#define scnd(x)    scanf("%lf",&x)
#define prnti(x)    printf("%d\n",x)
#define prntll(x)    printf("%lld",x)
#define prntd(x)    printf("%.9lf",x)
#define sz(x)  x.size()
#define pp push_back
#define P pair<int , int>
#define mp make_pair

const double EPS = 1e-9;
const double PI = 3.14159265359;

//  O( n * log(log(n)) )
vector<ll> primes;
void GeneratingPrimes(int top){
    vector<bool> p (top+1 , 1);
//    vector<ll> primes;
    p[0] = p[1] = 0;

    for(int i = 2; i <= sqrt(top) ; i++){
        if(p[i]){
            for(int j = i*i ; j <= top ; j+=i){
                p[j]=0;
            }
        }
    }
    lop(i , top+1)
        if(p[i])primes.push_back(i);
//    return primes;
}

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);}
void EXTgcd(ll a , ll b , ll & x0 , ll & y0){
    if(b==0){ x0 =1 , y0 = 0; return; }
    EXTgcd( b , a%b , x0 , y0 );
    ll x1 = y0;
    ll y1 = x0 - (a/b) * (y0);

	y1 = y1;
    x0 = x1;
    y0 = y1;
}

long long power(long long n, long long p , ll mod) {
    if (!p)
        return 1;
    long long ans = 1;
    while (p > 1) {
        if (p & 1)
            ans = (ans * n) % mod;
        n = (n * n) % mod;
        p /= 2;
    }
    return (ans * n) % mod;
}

double dist(double a , double b , double x, double y){ return sqrt( pow( a-x ,2) + pow( b-y ,2) ); }
double dist3(double a , double b , double c , double x , double y ,double z ){ return sqrt( pow( a-x ,2) + pow( b-y ,2) + pow( c-z ,2)); }

int xadd[9]= { 1 , -1 , 0 , 1 , -1 , 0 , 1 , -1 , 0 };
int yadd[9]= { 1 , -1 , 0 ,-1 ,  0 , 1 , 0 ,  1, -1 };

int xx[4]={0 , 1 , 0 , -1};
int yy[4]={1 , 0 , -1 , 0};

#define no  { cout<<"NO\n";  }
#define yes { cout<<"YES\n"; }
#define _1  { cout<<"-1\n";  }

ll const N = 1e2 + 10;
ll const INF = 1e18;
ll const mod = 1000000009;

///////////////////////////////////////////////////////////////////

int n,m,vis[N];
VI e[N];

void dfs(int idx){vis[idx]=1; for(int to:e[idx])if(!vis[to]){dfs(to);}}

int main(){
	cin >> n >> m;
	lop(i,m){
		int x,y;
		scni(x),scni(y);
		e[x].pp(y);
		e[y].pp(x);
		vis[x]=vis[y]=1;
	}
	dfs(1);
	bool ok=1;
	lop(i,n)if(!vis[i+1])ok=0;
	if(!ok || n!=m)cout << "NO";
	else cout << "FHTAGN!";

return 0;}


#include <iostream>
#include <set>
#include <queue>
#include <vector>
#include <string>
#include <math.h>
#include <cmath>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <sstream>
#include <numeric>
#include <assert.h>

using namespace std;

#define lop(i,n) for(int i=0 ;i<n ;i++)
#define VI    vector<int>
#define VLL    vector<ll>
#define VPI    vector<pair<int,int>>
#define VII    vector<VI>
#define all(v)    v.begin() , v.end()
#define SORT(v)    sort(all(v))
#define ll    long long
#define ull unsigned long long
#define scni(x)    scanf("%d",&x)
#define scnll(x)    scanf("%lld",&x)
#define scnd(x)    scanf("%lf",&x)
#define prnti(x)    printf("%d\n",x)
#define prntll(x)    printf("%lld",x)
#define prntd(x)    printf("%.9lf",x)
#define sz(x)  x.size()
#define pp push_back
#define P pair<int , int>
#define mp make_pair

const double EPS = 1e-9;
const double PI = 3.14159265359;

//  O( n * log(log(n)) )
vector<ll> primes;
void GeneratingPrimes(int top){
    vector<bool> p (top+1 , 1);
//    vector<ll> primes;
    p[0] = p[1] = 0;

    for(int i = 2; i <= sqrt(top) ; i++){
        if(p[i]){
            for(int j = i*i ; j <= top ; j+=i){
                p[j]=0;
            }
        }
    }
    lop(i , top+1)
        if(p[i])primes.push_back(i);
//    return primes;
}

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);}
void EXTgcd(ll a , ll b , ll & x0 , ll & y0){
    if(b==0){ x0 =1 , y0 = 0; return; }
    EXTgcd( b , a%b , x0 , y0 );
    ll x1 = y0;
    ll y1 = x0 - (a/b) * (y0);

	y1 = y1;
    x0 = x1;
    y0 = y1;
}

long long power(long long n, long long p , ll mod) {
    if (!p)
        return 1;
    long long ans = 1;
    while (p > 1) {
        if (p & 1)
            ans = (ans * n) % mod;
        n = (n * n) % mod;
        p /= 2;
    }
    return (ans * n) % mod;
}

double dist(double a , double b , double x, double y){ return sqrt( pow( a-x ,2) + pow( b-y ,2) ); }
double dist3(double a , double b , double c , double x , double y ,double z ){ return sqrt( pow( a-x ,2) + pow( b-y ,2) + pow( c-z ,2)); }

int xadd[9]= { 1 , -1 , 0 , 1 , -1 , 0 , 1 , -1 , 0 };
int yadd[9]= { 1 , -1 , 0 ,-1 ,  0 , 1 , 0 ,  1, -1 };

int xx[4]={0 , 1 , 0 , -1};
int yy[4]={1 , 0 , -1 , 0};

#define no  { cout<<"NO\n";  }
#define yes { cout<<"YES\n"; }
#define _1  { cout<<"-1\n";  }

ll const N = 1e2 + 10;
ll const INF = 1e18;
ll const mod = 1000000009;

///////////////////////////////////////////////////////////////////

int n,m,vis[N],roots[N],ok,fnd=0;
VI e[N];

bool dfsTree(int idx){
	vis[idx]=1;
	for(int to:e[idx])if(!vis[to]){
		if(roots[to]){if(!roots[idx])return 0;else continue;}
		dfsTree(to);
	}
	return 1;
}

bool dfs(int idx, int par=0){
	vis[idx]=1;

	for(int to:e[idx]){
		if(vis[to]){
			if(to == par)continue;
			roots[to]=1;
			fnd=1;
			return 1;
		}else{
			bool r = dfs(to , idx);
			if(r){
				roots[to]=1;
				return !roots[idx];
			}
		}
	}
}

int main(){
	cin >> n >> m;
	while(m--){
		int x,y;
		scni(x),scni(y);
		e[x].pp(y);
		e[y].pp(x);
		vis[x]=vis[y]=1;
	}

	for(int i=1 ;i<=n ;i++){
		memset(vis , 0 , sizeof vis);
		dfs(i);
		if(fnd){ok=1;break;}
	}
	memset(vis , 0 , sizeof vis);

	if(!ok)return cout<<"NO",0;
	for(int i=1 ;i<=n ;i++)if(roots[i]){
		if(!dfsTree(i))return cout<<"NO",0;
	}
	ok=1;
	lop(i,n)if(!vis[i+1])ok=0;
	if(ok)cout << "FHTAGN!";
	else cout << "NO";
return 0;}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

vector<int>adj[110];
vector<int>vis(110);
int n, m;
int ch = 0;
void dfs(int s){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (!vis[child])
			dfs(child);
	}
}
int dfs(int s,int c){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (vis[child])return c;
		else dfs(child, c + 1);
	}
	return c;
}
int main(){

	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++){
		int v, w;
		cin >> v >> w;
		adj[v].push_back(w);
		adj[w].push_back(v);
	}
	int cnt = 0;
	fill(vis.begin(), vis.end(), 0);
	for (int i = 1; i <= n; i++){
		if (!vis[i])
			dfs(i),cnt++;

	}
	if (cnt > 1)return cout << "NO" << endl, 0;
	if (m == n)cout << "FHTAGN!" << endl;
	else cout << "NO" << endl;
	return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

vector<int>adj[110], adj2[110];
vector<int>vis(110);
int n, m;
int ch = 0;
int dfs(int s){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (vis[child])return ch = 1;
		else dfs(child);
	}
	return ch;
}
int dfs2(int s){
	vis[s] = 1;
	for (int i = 0; i < adj2[s].size(); i++){
		int child = adj2[s][i];
		if (vis[child])return ch = 1;
		else dfs2(child);
	}
	return ch;
}
int main(){

	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++){
		int v, w;
		cin >> v >> w;
		adj[v].push_back(w);
		adj2[w].push_back(v);
	}
	int cnt = 0;
	for (int i = 1; i <= n; i++){
		ch = 0;
		fill(vis.begin(), vis.end(), 0);
		cnt += dfs(i);
	}
	for (int i = 1; i <= n; i++){
		ch = 0;
		fill(vis.begin(), vis.end(), 0);
		cnt += dfs2(i);
	}
	if (cnt >= 3)cout << "FHTAGN!" << endl;
	else cout << "NO" << endl;
	return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

vector<int>adj[110];
vector<int>vis(110);
int n, m;
int ch = 0;
void dfs(int s){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (!vis[child])
			dfs(child);
	}
}
int dfs(int s,int c){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (vis[child])return c;
		else dfs(child, c + 1);
	}
	return c;
}
int main(){

	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++){
		int v, w;
		cin >> v >> w;
		adj[v].push_back(w);
		adj[w].push_back(v);
	}

	int cnt = 0;
	fill(vis.begin(), vis.end(), 0);
	for (int i = 1; i <= n; i++){
		if (!vis[i])
			dfs(i),cnt++;

	}
	if (cnt > 1)return cout << "NO" << endl, 0;
	if (m == n)cout << "FHTAGN!" << endl;
	else cout << "NO" << endl;
	return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

vector<int>adj[110];
vector<int>vis(110);
int n, m;
int ch = 0;
void dfs(int s){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (!vis[child])
			dfs(child);
	}
}
int dfs(int s,int c){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (vis[child])return c;
		else dfs(child, c + 1);
	}
	return c;
}
int main(){

	scanf_s("%d%d", &n, &m);
	for (int i = 0; i < m; i++){
		int v, w;
		cin >> v >> w;
		adj[v].push_back(w);
		adj[w].push_back(v);
	}
	int cnt = 0;
	fill(vis.begin(), vis.end(), 0);
	for (int i = 1; i <= n; i++){
		if (!vis[i])
			dfs(i),cnt++;

	}
	if (cnt > 1)return cout << "NO" << endl, 0;
	if (m >= n)cout << "FHTAGN!" << endl;
	else cout << "NO" << endl;
	return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

vector<int>adj[110];
vector<int>vis(110);
int n, m;
int ch = 0;
void dfs(int s){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (!vis[child])
			dfs(child);
	}
}
int dfs(int s,int c){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (vis[child])return c;
		else dfs(child, c + 1);
	}
	return c;
}
int main(){

	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++){
		int v, w;
		cin >> v >> w;
		adj[v].push_back(w);
		adj[w].push_back(v);
	}
	int cnt = 0;
	fill(vis.begin(), vis.end(), 0);
	for (int i = 1; i <= n; i++){
		if (!vis[i])
			dfs(i),cnt++;

	}
	if (cnt > 1)return cout << "NO" << endl, 0;
	if (m >= n)cout << "FHTAGN!" << endl;
	else cout << "NO" << endl;
	return 0;
}


#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

vector<int>adj[110];
vector<int>vis(110);
int n, m;
int ch = 0;
void dfs(int s){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (!vis[child])
			dfs(child);
	}
}
int dfs(int s,int c){
	vis[s] = 1;
	for (int i = 0; i < adj[s].size(); i++){
		int child = adj[s][i];
		if (vis[child])return c;
		else dfs(child, c + 1);
	}
	return c;
}
int main(){

	scanf_s("%d%d", &n, &m);
	for (int i = 0; i < m; i++){
		int v, w;
		cin >> v >> w;
		adj[v].push_back(w);
		adj[w].push_back(v);
	}
	int cnt = 0;
	fill(vis.begin(), vis.end(), 0);
	for (int i = 1; i <= n; i++){
		if (!vis[i])
			dfs(i),cnt++;

	}
	if (cnt > 1)return cout << "NO" << endl, 0;
	if (m == n)cout << "FHTAGN!" << endl;
	else cout << "NO" << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false), cin.tie(NULL)
#define lp(i,n) for(int i = 0 ; i< int(n) ;++i)
#define lp2(i,j,n) for(int i =int(j) ; i< int(n) ;++i)
#define OO 2147483647
#define MOD 1000000007
#define tr(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define all(c) c.begin(), c.end()
#define FindLog(container, element) (container.find(element) != container.end())
#define Find(container, element) (find(all(container),element) != container.end())
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define odd(n)  ((n&1) == 1)
#define even(n) !(odd(n))
#define PI 3.1415926536
#define sp system("pause")
#define mp(x,y) make_pair(x,y)
#define MASK(size) bitset<size>
typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi > vvi;
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)));
}
bool getbit(int num, int idx)//(0-->n-1)
{
return (num >> idx & 1) == 1;
}
int setbit(int num, int idx, bool val)//idx(0-->n-1)
{
if (val == true)
return (num | (1 << idx));
return num & ~(1 << idx);
}
int flipbit(int num, int idx)//idx(0-->n-1)
{
return num ^ (1 << idx);
}
int cntbits(int mask)//O(bits count)
{
int res = 0;
while (mask)
mask &= (mask - 1), res++;
return res;
}
int visited[150], cycle;
vvi adj;
void Dfs(int node,int par)
{
	bool ok = true;
	visited[node] = 1;
	for (int i = 0; i < adj[node].size(); i++)
	{
		int child = adj[node][i];
		if (visited[child] == 0)
		{
			Dfs(child, node);
		}
		else if (visited[child] == 1 && child != par && child != node)
			cycle = 1;
	}
	visited[node] = 121;//useful in directed graph only *_^
}
int main()
{
	int n, m;
	cin >> n >> m;
	adj.resize(n);
	lp(i, m)
	{
		int x, y;
		cin >> x >> y;
		adj[x - 1].push_back(y - 1);
		adj[y - 1].push_back(x - 1);
	}

	int ConnectedComponents = 0;
	lp(i, n)
	{
		if (!visited[i])
		{
			ConnectedComponents++;
			Dfs(i,-1);
		}
	}
	if (m != n || !cycle || ConnectedComponents > 1)
	{
		cout << "NO" << endl;
		return 0;
	}
	cout << "FHTAGN!" << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false), cin.tie(NULL)
#define lp(i,n) for(int i = 0 ; i< int(n) ;++i)
#define lp2(i,j,n) for(int i =int(j) ; i< int(n) ;++i)
#define OO 2147483647
#define MOD 1000000007
#define tr(container, it) for(typeof(container.begin()) it = container.begin(); it != container.end(); it++)
#define all(c) c.begin(), c.end()
#define FindLog(container, element) (container.find(element) != container.end())
#define Find(container, element) (find(all(container),element) != container.end())
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define odd(n)  ((n&1) == 1)
#define even(n) !(odd(n))
#define PI 3.1415926536
#define sp system("pause")
#define mp(x,y) make_pair(x,y)
#define MASK(size) bitset<size>
typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi > vvi;
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)));
}
bool getbit(int num, int idx)//(0-->n-1)
{
return (num >> idx & 1) == 1;
}
int setbit(int num, int idx, bool val)//idx(0-->n-1)
{
if (val == true)
return (num | (1 << idx));
return num & ~(1 << idx);
}
int flipbit(int num, int idx)//idx(0-->n-1)
{
return num ^ (1 << idx);
}
int cntbits(int mask)//O(bits count)
{
int res = 0;
while (mask)
mask &= (mask - 1), res++;
return res;
}
int visited[150], cycle;
vvi adj;
void Dfs(int node,int par)
{
	bool ok = true;
	visited[node] = 1;
	for (int i = 0; i < adj[node].size(); i++)
	{
		int child = adj[node][i];
		if (visited[child] == 0)
		{
			Dfs(child, node);
		}
		else if (visited[child] == 1 && child != par && child != node)
			cycle = 1;
	}
	visited[node] = 121;//useful in directed graph only *_^
}
int main()
{
	int n, m;
	cin >> n >> m;
	adj.resize(n);
	lp(i, m)
	{
		int x, y;
		cin >> x >> y;
		adj[x - 1].push_back(y - 1);
		adj[y - 1].push_back(x - 1);
	}

	int ConnectedComponents = 0;
	lp(i, n)
	{
		if (!visited[i])
		{
			ConnectedComponents++;
			Dfs(i,-1);
		}
	}
	if (m < n || !cycle || ConnectedComponents > 1)
	{
		cout << "NO" << endl;
		return 0;
	}
	cout << "FHTAGN!" << endl;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;

	vector<int >v[109];
	int visit[109]={};

	void dfs(int x)
	{
		visit[x]=1;

		for(std::vector<int>::iterator itr=v[x].begin();itr!=v[x].end();itr++)
		{
			if(visit[*itr]==0)
				dfs(*itr);
		}
	}

main()
{
		ll n,t,a,b,i;
	cin>>n>>t;

	if(t!=n)
	{
	    cout<<"NO";
        return 0;
    }
	for(i=0;i<t;i++)
	{
		cin>>a>>b;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	dfs(1);

	for(i=1;i<=n;i++)
	{
		if(visit[i]==0)
		{
			cout<<"NO";
			return 0;
		}
	}

	cout<<"FHTAGN!";

}


#include<bits/stdc++.h>
#define ll long long
using namespace std;

	vector<int >v[109];
	int visit[109]={};

	void dfs(int x)
	{
		visit[x]=1;

		for(std::vector<int>::iterator itr=v[x].begin();itr!=v[x].end();itr++)
		{
			if(visit[*itr]==0)
				dfs(*itr);
		}
	}

main()
{
		ll n,t,a,b,i;
	cin>>n>>t;

	if(t<=n-1)
	{
	    cout<<"NO";
        return 0;
    }
	for(i=0;i<t;i++)
	{
		cin>>a>>b;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	dfs(1);

	for(i=1;i<=n;i++)
	{
		if(visit[i]==0)
		{
			cout<<"NO";
			return 0;
		}
	}

	cout<<"FHTAGN!";

}


#include<bits/stdc++.h>
#define ll long long
using namespace std;

	vector<int >v[109];
	int visit[109]={};

	void dfs(int x)
	{
		visit[x]=1;

		for(std::vector<int>::iterator itr=v[x].begin();itr!=v[x].end();itr++)
		{
			if(visit[*itr]==0)
				dfs(*itr);
		}
	}

main()
{
		ll n,t,a,b,i;
	cin>>n>>t;

	if(t<=n-1&&t>n)
	{
	    cout<<"NO";
        return 0;
    }
	for(i=0;i<t;i++)
	{
		cin>>a>>b;
		v[a].push_back(b);
		v[b].push_back(a);
	}

	dfs(1);

	for(i=1;i<=n;i++)
	{
		if(visit[i]==0)
		{
			cout<<"NO";
			return 0;
		}
	}

	cout<<"FHTAGN!";

}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <chrono>
#define pb push_back
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define endl '\n'
#define ll long long
#define f first
#define fin cin
#define fout cout
#define int long long
#define s second
#define FAST cin.tie(0), cout.tie(0), ios::sync_with_stdio(0)
#define debug(x) cout << "DEBUG " << x << endl
#define debug2(x, y) cout << "DEBUG " << x << " " << y << endl
#define debug3(x, y, z) cout << "DEBUG " << x << " " << y << " " << z<< endl
#define debug4(x, y, z, o) cout << "DEBUG " << x << " " << y << " " << z<< " " << o << endl
#define all(x) x.begin(), x.end()
#define left vadia
#define lb lower_bound
#define right puta
using namespace std;
using namespace __gnu_pbds;
void setIO(string s) {
  ios_base::sync_with_stdio(0); cin.tie(0);
  freopen((s+".in").c_str(),"r",stdin);
  freopen((s+".out").c_str(),"w",stdout);
}
typedef pair<ll, ll> pii;
typedef vector<vector<char>> mat;
typedef pair<int, string> pis;
const ll mod = 1e9+7;
const int MAXN = 105;
const int MAXV = 1e6+5;
typedef vector<int> vi;
typedef pair<int, pair<int, int>> piii;

pii cycle = {-1, -1};
vector<int> g[MAXN];
int pai[MAXN], h[MAXN];
bool used[MAXN], ok[MAXN];

int cont = 0;

void dfs(int u) {

	h[u] = ++cont;

	for(int &i : g[u]) {
		if(i == pai[u]) continue;
		if(pai[i] != -1)
			cycle = {u, i};
		else {
			pai[i] = u;
			dfs(i);
		}
	}

	return;
}

bool deu = true;
void bang(int u, int p) {
	used[u] = 1;
	for(int &i : g[u]) {
		if(ok[i] or i == p) continue;
		if(used[i]) deu = false;
		else bang(i, u);
	}
}

int32_t main() {

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

	memset(pai, -1, sizeof pai);
	dfs(0);

	for(int i = 1; i < n; i++)
		if(pai[i] == -1) {
			cout << "NO" << endl;
			return 0;
		}

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

	while(cycle.f != cycle.s) {
		if(h[cycle.f] < h[cycle.s]) swap(cycle.f, cycle.s);
		ok[cycle.f] = 1;
		cycle.f = pai[cycle.f];
	}
	ok[cycle.s] = 1;

	for(int i = 0; i < n; i++)
		if(!ok[i] && !used[i]) {
			deu = true;
			bang(i, i);
			if(!deu) {
				cout << "NO" << endl;
				return 0;
			}
		}

	cout << "FHTAGN!" << endl;

}


#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>

#define PB push_back
#define remove erase
#define endl '\n'
#define FOR(IN,N) for(int I = IN;I < N;++I)
#define MAX

using namespace std;

typedef long long i64;
typedef pair<int,int> pii;

int V,E;
int a,b;

vector<int> G[100 + 5];

bool visit[100 + 5];

int parent[100 + 5];

bool belongs[100 + 5];

bool ciclo;

int people;

void traverse(int source,int sink)
{
	int current = source;
	while (current != sink)
	{
		belongs[current] = true;
		people++;
		current = parent[current];
	}
	belongs[current] = true;
	people++;
}

void DFS(int node,int p)
{

	visit[node] = true;

	for(int i = 0 ; i < G[node].size(); i++)
	{
		int ady = G[node][i];

		if(visit[ady] && ady != p){ ciclo = true;
			if(!belongs[node])
				traverse(node,ady);
		}

		if(!visit[ady]){ parent[ady] = node;DFS(ady,node);}
	}

}

int main()
{
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

	cin >> V >> E;
	for(int i  = 0 ; i < E ; i ++)
	{
		cin >> a >> b;
		G[a].PB(b);
		G[b].PB(a);
	}

	int ciclos = 0;
	int comps = 0;

	for(int i = 1 ; i <= V ; i++)
	{
		if(!visit[i])
		{
			comps++;

			ciclo = false;

			DFS(i,0);

			if(ciclo) ++ciclos;
		}
	}

	//cout << ciclos << " " << people << endl;

	if(comps != 1)cout << "NO" << endl;
	else if(ciclos != 1)cout << "NO" << endl;
	else if(people < 3)cout << "NO" << endl;
	else cout << "FHTAGN!" << endl;

	//cout << ciclos << '\n';
}


#include <cstdio>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>

#define PB push_back
#define remove erase
#define endl '\n'
#define FOR(IN,N) for(int I = IN;I < N;++I)
#define MAX

using namespace std;

typedef long long i64;
typedef pair<int,int> pii;

int V,E;
int a,b;

vector<int> G[100 + 5];

bool flags[100 + 5];

void bfs(int node)
{
	queue<int> Q;
	Q.push(node);
	flags[node] = 1;
	while (!Q.empty())
	{
		int cur = Q.front();
		Q.pop();
		for(int i = 0 ; i < G[cur].size(); i++)
		{
			int ady = G[cur][i];
			if(!flags[ady])
			{
				flags[ady] = 1;
				Q.push(ady);
			}
		}
	}
}

int main()
{
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

	cin >> V >> E;
	for(int i  = 0 ; i < E ; i ++)
	{
		cin >> a >> b;
		G[a].PB(b);
		G[b].PB(a);
	}

	int comps = 0;

	for(int i = 1 ; i <= V; i++)
	{
		if(!flags[i])
		{
			comps++;
			bfs(i);
		}
	}

	if(comps != 1)cout << "NO" << endl;
	else if(V != E) cout << "NO" << endl;
	else cout << "FHTAGN!" << endl;

}


//lxrtxdy!
#include <bits/stdc++.h>
typedef long long ll;
typedef unsigned int uint;
using namespace std;
const int MAX = 1e6+10;
const int N = 1e5+5;
const int J=550;
#define IO ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,m,x,y,cnt;

vector<int> adj[N];
bool vis[N];

void dfs(int src)
{
    cnt++;
    vis[src]=1;
    for(auto x:adj[src])
        if(!vis[x])
            dfs(x);
}
int main ()
{
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    if(m==n)
    {
        dfs(1);
        if(cnt==n) puts("FHTAGN!");
        else puts("NO");
    }
    else puts("NO");
}
//orzlxr!


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 100000;
int M, N, T;
struct E {
    int u, v;
    E() {}
    E(int u, int v):u(u),v(v){}
};
vector<E> edge;
vector<int> G[maxn];
void addEdge(int a, int b){
    edge.push_back(E(a, b));
    edge.push_back(E(b, a));
    G[a].push_back(edge.size() - 2);
    G[b].push_back(edge.size() - 1);
}
int cnt = 0; bool vis[maxn];
void dfs(int u, int pu){
    vis[u] = 1;
    for (int i : G[u]){
        E &e = edge[i];
        //printf("(pu,u,v)=(%d,%d,%d)\n",pu,u,e.v);
        if (vis[e.v]) continue;
        vis[e.v] = 1; cnt++;
        dfs(e.v, u);
    }
}
int main(){
    cin >> N >> M;
    if (N < 3) {cout << "NO" << endl; return 0;}
    for (int i = 0; i < M; i++){
        int u, v; scanf("%d%d", &u, &v);
        addEdge(--u, --v);
    }
    dfs(edge[0].u, -1);
    //cout << cnt << endl;
    bool all = 1; for (int i = 0; i < N; i++) all &= vis[i];
    if (cnt == M - 1 && all) cout << "FHTAGN!" << endl;
    else cout << "NO" <<endl;
    return 0;
}

/*
10 10
4 10
8 5
2 8
4 9
9 3
2 7
10 6
10 2
9 8
1 8

*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 100000;
int M, N, T;
struct E {
    int u, v;
    E() {}
    E(int u, int v):u(u),v(v){}
};
vector<E> edge;
vector<int> G[maxn];
void addEdge(int a, int b){
    edge.push_back(E(a, b));
    edge.push_back(E(b, a));
    G[a].push_back(edge.size() - 2);
    G[b].push_back(edge.size() - 1);
}
int cnt = 0; bool vis[maxn];
void dfs(int u, int pu){
    vis[u] = 1;
    for (int i : G[u]){
        E &e = edge[i];
        //printf("(pu,u,v)=(%d,%d,%d)\n",pu,u,e.v);
        if (vis[e.v]) continue;
        vis[e.v] = 1; cnt++;
        dfs(e.v, u);
    }
}
int main(){
    cin >> N >> M;
    if (N < 3) {cout << "No" << endl; return 0;}
    for (int i = 0; i < M; i++){
        int u, v; scanf("%d%d", &u, &v);
        addEdge(--u, --v);
    }
    dfs(edge[0].u, -1);
    //cout << cnt << endl;
    bool all = 1; for (int i = 0; i < N; i++) all &= vis[i];
    if (cnt == M - 1 && all) cout << "FHTAGN!" << endl;
    else cout << "NO" <<endl;
    return 0;
}

/*
10 10
4 10
8 5
2 8
4 9
9 3
2 7
10 6
10 2
9 8
1 8

*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 100000;
int M, N, T;
struct E {
    int u, v;
    E() {}
    E(int u, int v):u(u),v(v){}
};
vector<E> edge;
vector<int> G[maxn];
void addEdge(int a, int b){
    edge.push_back(E(a, b));
    edge.push_back(E(b, a));
    G[a].push_back(edge.size() - 2);
    G[b].push_back(edge.size() - 1);
}
int cnt = 0; bool vis[maxn];
void dfs(int u, int pu){
    vis[u] = 1;
    for (int i : G[u]){
        E &e = edge[i];
        if (vis[e.v]) continue;
        vis[e.v] = 1; cnt++;
        dfs(e.v, u);
    }
}
int main(){
    cin >> N >> M;
    for (int i = 0; i < M; i++){
        int u, v; scanf("%d%d", &u, &v);
        if (i == M - 1){
            dfs(0, -1);
            //cout << cnt << endl;
        }
        addEdge(--u, --v);
    }
    int uu = edge.back().u, vv = edge.back().v;
    if (vis[uu] && vis[vv] && cnt == M - 1) cout << "FHTAGN!" << endl;
    else cout << "No" <<endl;
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 100000;
int M, N, T;
struct E {
    int u, v;
    E() {}
    E(int u, int v):u(u),v(v){}
};
vector<E> edge;
vector<int> G[maxn];
void addEdge(int a, int b){
    edge.push_back(E(a, b));
    edge.push_back(E(b, a));
    G[a].push_back(edge.size() - 2);
    G[b].push_back(edge.size() - 1);
}
int cnt = 0; bool vis[maxn];
void dfs(int u, int pu){
    vis[u] = 1;
    for (int i : G[u]){
        E &e = edge[i];
        //printf("(pu,u,v)=(%d,%d,%d)\n",pu,u,e.v);
        if (vis[e.v]) continue;
        vis[e.v] = 1; cnt++;
        dfs(e.v, u);
    }
}
int main(){
    cin >> N >> M;
    for (int i = 0; i < M; i++){
        int u, v; scanf("%d%d", &u, &v);
        addEdge(--u, --v);
    }
    dfs(edge[0].u, -1);
    //cout << cnt << endl;
    bool all = 1; for (int i = 0; i < N; i++) all &= vis[i];
    if (cnt == M - 1 && all) cout << "FHTAGN!" << endl;
    else cout << "NO" <<endl;
    return 0;
}

/*
10 10
4 10
8 5
2 8
4 9
9 3
2 7
10 6
10 2
9 8
1 8

*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 100000;
int M, N, T;
struct E {
    int u, v;
    E() {}
    E(int u, int v):u(u),v(v){}
};
vector<E> edge;
vector<int> G[maxn];
void addEdge(int a, int b){
    edge.push_back(E(a, b));
    edge.push_back(E(b, a));
    G[a].push_back(edge.size() - 2);
    G[b].push_back(edge.size() - 1);
}
int cnt = 0; bool vis[maxn];
void dfs(int u, int pu){
    vis[u] = 1;
    for (int i : G[u]){
        E &e = edge[i];
        if (vis[e.v]) continue;
        vis[e.v] = 1; cnt++;
        dfs(e.v, u);
    }
}
int main(){
    cin >> N >> M;
    for (int i = 0; i < M; i++){
        int u, v; scanf("%d%d", &u, &v);
        if (i == M - 1){
            dfs(0, -1);
            //cout << cnt << endl;
        }
        addEdge(--u, --v);
    }
    int uu = edge.back().u, vv = edge.back().v;
    if (vis[uu] && vis[vv] && cnt == M - 1) cout << "FHTAGN!" << endl;
    else cout << "NO" <<endl;
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 100000;
int M, N, T;
struct E {
    int u, v;
    E() {}
    E(int u, int v):u(u),v(v){}
};
vector<E> edge;
vector<int> G[maxn];
void addEdge(int a, int b){
    edge.push_back(E(a, b));
    edge.push_back(E(b, a));
    G[a].push_back(edge.size() - 2);
    G[b].push_back(edge.size() - 1);
}
int cnt = 0; bool vis[maxn];
void dfs(int u, int pu){
    vis[u] = 1;
    for (int i : G[u]){
        E &e = edge[i];
        //printf("(pu,u,v)=(%d,%d,%d)\n",pu,u,e.v);
        if (vis[e.v]) continue;
        vis[e.v] = 1; cnt++;
        dfs(e.v, u);
    }
}
int main(){
    cin >> N >> M;
    if (N < 3 || M < N - 1) {cout << "NO" << endl; return 0;}
    for (int i = 0; i < M; i++){
        int u, v; scanf("%d%d", &u, &v);
        addEdge(--u, --v);
    }
    dfs(edge[0].u, -1);
    //cout << cnt << endl;
    bool all = 1; for (int i = 0; i < N; i++) all &= vis[i];
    if (cnt == M - 1 && all) cout << "FHTAGN!" << endl;
    else cout << "NO" <<endl;
    return 0;
}

/*
10 10
4 10
8 5
2 8
4 9
9 3
2 7
10 6
10 2
9 8
1 8

*/


#include <bits/stdc++.h>
using namespace std;
int g[102][102],used[102];
int n,m;
void dfs(int v)
{
    used[v]=1;
    for(int i=1; i<=n; i++)
    if(used[i]==0)
        if (g[v][i]==0)
            dfs(i);
}
int main()
{
    int x,y;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;;
        g[x][y]=1;
        g[y][x]=1;
    }
    dfs(1);
    for(int i=1; i<=n; i++)
    if(used[i]==0)
    {
        cout<<"NO";
        return 0;
    }
    if(m==n)
       cout<<"FHTAGN!";
    else
       cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int g[5800][5800],used[5800];
int n,m,x,y,p=0;
void dfs(int v)
{
    used[v]=1;
    for(int i=1; i<=m; i++)
    if(g[v][i]==1)
    {
        p++;
       if(used[i]==0)
       {
          g[v][i]=0;
          dfs(i);
       }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        cin>>x>>y;
        g[x][y]=1;
    }
    for (int i=1; i<=m; i++)
    {
        for (int k=1; k<=m; k++)
           used[k]=0;
        for (int j=1; j<=n; j++)
          if (g[i][j]==1)
            dfs(i);

    }
    if (p==m)
      cout<<"FHTAGN!";
    else
    cout<<"NO";

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int g[5800][5800],used[5800];
int n,m;
void dfs(int v)
{
    used[v]=1;
    for(int i=1; i<=n; i++)
    if(used[i]==0)
       if(g[v][i]==0)
          dfs(i);
}
int main()
{
    cin>>n>>m;
    int x,y;
    for(int i=1; i<=m; i++)
    {
        cin>>x>>y;
        g[x][y]=1;
        g[y][x]=1;
    }
    dfs(1);
    for(int i=1; i<=n; i++)
    if(0==used[i])
    {
        cout<<"NO";
        return 0;
    }
    if(m==n)
      cout<<"FHTAGN!\n";
    else
     cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int gra[102][102],vis[102];
int n,m;
void dfs(int u)
{
    vis[u]=1;
    for(int i=1;i<=n;i++)
    if(0==vis[i]&&gra[u][i])dfs(i);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;;
        gra[u][v]=gra[v][u]=1;
    }
    dfs(1);
    for(int i=1;i<=n;i++)
    if(0==vis[i])
    {
        cout<<"NO";
        return 0;
    }
    if(m==n)cout<<"FHTAGN!";
    else cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int g[102][102],used[102];
int n,m;
void dfs(int v)
{
    used[v]=1;
    for(int i=1; i<=n; i++)
    if(g[v][i]==1)
        if (used[i]==0)
            dfs(i);
}
int main()
{
    int x,y;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;;
        g[x][y]=1;
        g[y][x]=1;
    }
    dfs(1);
    for(int i=1; i<=n; i++)
    if(used[i]==0)
    {
        cout<<"NO";
        return 0;
    }
    if(m==n)
       cout<<"FHTAGN!";
    else
       cout<<"NO";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int g[5800][5800],used[5800];
int n,m,x,y;
void dfs(int v)
{
    used[v]=1;
    for(int i=1; i<=n; i++)
    if(g[v][i]==0)
       if(used[i]==0)
          dfs(i);
}
int main()
{
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        cin>>x>>y;
        g[x][y]=1;
        g[y][x]=1;
    }
    dfs(1);
    for(int i=1; i<=n; i++)
    if(used[i]==0)
    {
        cout<<"NO";
        return 0;
    }
    if(m==n)
      cout<<"FHTAGN!\n";
    else
     cout<<"NO";
    return 0;
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=400;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=500;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=375;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=105;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c,d;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==0){
		cout<<"NO";
		d=1;
		return ;
	}
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(d){
		return 0;
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=1e2+5;
long long n,m,c,x,y,mark[maxn],a,num1,num2;
vector <int> adj[maxn];
void DFS(int u){
	mark[u]++;
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==0){
			DFS(adj[u][i]);
		}
		else if(mark[adj[u][i]]==1){
			mark[adj[u][i]]++;
			a--;
		}
	}
}
void dfs(int u){
	a++;
	num1++;
	mark[u]++;
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==3){
			break;
		}
		if(mark[adj[u][i]]==2){
			dfs(adj[u][i]);
		}
	}
}
void dfS(int u){
	for(int j=0;j<adj[u].size();j++){
		if(mark[adj[u][j]]==1){
			num2++;
			dfS(adj[u][j]);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[y].push_back(x);
		adj[x].push_back(y);
	}
	if(m<n){
		cout<<"NO";
		return 0;
	}
	DFS(1);
	for(int i=1;i<=n;i++){
		if(mark[i]==2){
			dfs(i);
			break;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i);
		}
	}
	if(a==0&&num1+num2==n){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO ";
		cout<<a;
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=1005;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=105;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c,d;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==v){
			continue;
		}
		else if(mark[adj[u][j]]==1){
			dfS(adj[u][j],u);
		}
		else if(mark[adj[u][j]]==2){
			b=1;
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=250;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=750;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=105;
int n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=500;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=1000;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=397;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=105;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c,d;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int j=0;j<adj[u].size();j++){
		if(mark[adj[u][j]]==1&&adj[u][j]!=v){
			dfS(adj[u][j],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=383;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=391;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=350;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=105;
int   n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c,d;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		if(mark[bu]==2){
			return ;
		}
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=399;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=400;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=1e2+5;
long long n,m,c,x,y,mark[maxn],a,num1,num2;
vector <int> adj[maxn];
void DFS(int u){
	mark[u]++;
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==0){
			DFS(adj[u][i]);
		}
		else if(mark[adj[u][i]]==1){
			mark[adj[u][i]]++;
			a--;
		}
	}
}
void dfs(int u){
	a++;
	num1++;
	mark[u]++;
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==3){
			break;
		}
		if(mark[adj[u][i]]==2){
			dfs(adj[u][i]);
		}
	}
}
void dfS(int u){
	for(int j=0;j<adj[u].size();j++){
		if(mark[adj[u][j]]==1){
			num2++;
			dfS(adj[u][j]);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[y].push_back(x);
		adj[x].push_back(y);
	}
	if(m<n){
		cout<<"NO";
		return 0;
	}
	DFS(1);
	for(int i=1;i<=n;i++){
		if(mark[i]==2){
			dfs(i);
			break;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i);
		}
	}
	if(a==0&&num1+num2==n){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO ";
	}
}


// In the name of god
#include <bits/stdC++.h>
using namespace std;
const int maxn=395;
long long  n,m,mark[maxn],x,y,sum1,sum2,bab[maxn],bab1;
bool b,c;
vector <int> adj[maxn];
vector <int> adj2[maxn];
void dFs(int u,int bu){
	if(bu==bab1){
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		return;
	}
	else{
		adj2[u].push_back(bu);
		adj2[bu].push_back(u);
		mark[u]=2;
		mark[bu]=2;
		dFs(bu,bab[bu]);
	}
}
void dfs(int u,int bu){
	bab[u]=bu;
	mark[u]++;
	for(int j=0;j<adj[u].size();j++){
		if(adj[u][j]==bu){
			continue;
		}
		if(!mark[adj[u][j]]){
			dfs(adj[u][j],u);
		}
		else if(!c){
			bab1=adj[u][j];
			dFs(u,bab[u]);
			adj2[u].push_back(adj[u][j]);
			adj2[adj[u][j]].push_back(u);
			mark[u]=2;
			mark[adj[u][j]]=2;
			c=1;
		}
	}
}
void DFS(int u,int v){
	if(mark[u]!=2){
		b=1;
		return;
	}
	mark[u]++;
	for(int j=0;j<adj2[u].size();j++){
		if(adj2[u][j]==v){
			continue;
		}
		if(mark[adj2[u][j]]==3){
			break;
		}
		else{
			DFS(adj2[u][j],u);
			break;
		}
	}
}
void dfS(int u,int v){
	if(mark[u]==1){
		sum2++;
	}
	for(int i=0;i<adj[u].size();i++){
		if(mark[adj[u][i]]==1&&adj[u][i]!=v){
			dfS(adj[u][i],u);
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(mark[i]>1){
			DFS(i,0);
			break;
		}
		if(mark[i]==0){
			b=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(mark[i]==3){
			dfS(i,0);
			sum1++;
		}
	}
	if(sum1+sum2==n&&!b){
		cout<<"FHTAGN!";
	}
	else{
		cout<<"NO";
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<string>
#include<set>
#include<queue>
#include<functional>
#include<cstring>
#include<bitset>
#include<cmath>
#include<bitset>
#include<sstream>
#include<list>
using namespace std;

static int n, m, a, b;
static int G[110][110];
static int vis[110];
static int flag;
void dfs_cycle(int x, int sums,int f,int& c)
{
	if (flag) return;
	if (x == f&&sums >= 3)
	{
		c = sums;
		flag = 1;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (G[x][i] == 1 && (!vis[i] || i == f))
		{
			vis[i] = 1;
			dfs_cycle(i, sums + 1, f, c);
		}
	}

}

int main()
{
	while (scanf("%d%d", &n, &m) != EOF)
	{
		fill(G[0], G[0] + 110 * 110, 0);
		for (int i = 0; i < m; i++)
		{
			scanf("%d%d", &a, &b);
			G[a][b] = G[b][a] = 1;
		}
		bool ans = false;
		int cycles = 0;
		for (int i = 1; i <= n; i++)
		{
			fill(vis, vis + n + 1, 0);
			flag = false;
			vis[i] = 1;
			cycles = 0;
			dfs_cycle(i, 0, i,cycles);
			if (flag&&cycles >= 3 && m == n)
			{
				ans = true;
				break;
			}
		}
		printf(ans ? "FHTAGN!\n" : "NO\n");
	}
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<string>
#include<set>
#include<queue>
#include<functional>
#include<cstring>
#include<bitset>
#include<cmath>
#include<bitset>
#include<sstream>
#include<list>
using namespace std;

static int n, m, a, b;
static int G[110][110];
static int vis[110];
static int flag;
void dfs_cycle(int x, int sums,int f,int& c)
{
	if (flag) return;
	if (x == f&&sums >= 3)
	{
		c = sums;
		flag = 1;
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (G[x][i] == 1 && (!vis[i] || i == f))
		{
			vis[i] = 1;
			dfs_cycle(i, sums + 1, f, c);
			//vis[i] = 0;
		}
	}

}

static int fa[110];

int find(int x)
{
	return x == fa[x] ? x : find(fa[x]);
}

int main()
{
	while (scanf("%d%d", &n, &m) != EOF)
	{
		fill(G[0], G[0] + 110 * 110, 0);
		for (int i = 1; i <= n; i++) fa[i] = i;
		int sum = 0;
		for (int i = 0; i < m; i++)
		{
			scanf("%d%d", &a, &b);
			int x = find(a);
			int y = find(b);
			if (x != y) ++sum, fa[x] = y;
			G[a][b] = G[b][a] = 1;
		}
		bool ans = false;
		int cycles = 0;
		for (int i = 1; i <= n; i++)
		{
			fill(vis, vis + n + 1, 0);
			flag = false;
			vis[i] = 1;
			cycles = 0;
			dfs_cycle(i, 0, i,cycles);
			if (flag&&cycles >= 3 && m == n)
			{
				ans = true;
				break;
			}
		}
		printf(ans&&sum == n - 1 ? "FHTAGN!\n" : "NO\n");
	}
	return 0;
}


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

int n, cnt, cl[128];
vector <int> g[128];

void dfs(int v, int p) {
  cl[v] = 1;
  for (int u : g[v]) {
    if (u == p) continue;
    if (!cl[u]) dfs(u, v);
    else if (cl[u] == 1) {
      cnt++;
    }
  }
  cl[v] = 2;
}

int main() {
  int m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  int c = 0;
  for (int i = 1; i <= n; i++) {
    if (!cl[i]) {
      dfs(i, 0);
      c++;
    }
  }
  if (cnt == 1 && c == 1) cout << "FHTAGN!";
  else cout << "NO";
}