Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem H:
DisconnectedGame

Taro と Hanako がゲームをしている.

最初に, 非連結な無向グラフ(二重辺や self loop を含まない) が与えられる. Taro と Hanako は交互に操作を行う. 操作では, 辺で直接つながれていない異なる2 頂点を選び, その間に辺を加える. グラフを連結にしたほうが負けである.

グラフには $V$ 個の頂点がある. $V \times V$ の行列が与えられる. 行列の $(i, j)$-成分が'Y' であるとき $i$ と $j$ の間には辺があり, 'N' であるときは辺が無い.

両者が最善に操作をしたとき, どちらが勝つかを出力せよ.

Constraints

$V$ will be between 2 and 1,000, inclusive.

$a_{i,i}$ will be 'N'.

$a_{i,j}$ will be 'Y' or 'N'.

$a_{i,j}$ will be equal to $a_{j,i}$.

The graph will not be connected.

Input

入力は以下の形式で与えられる:

$V$

$a_{1,1}$ ... $a_{1,V}$

...

$a_{V,1}$ ... $a_{V,V}$

Output

Taro が勝つ場合には "Taro" (quotes for clarity), Hanako が勝つ場合には "Hanako" (quotes for clarity) と 1 行に出力せよ.

Sample Input 1

3
NNN
NNN
NNN

Sample Output 1

Taro

Sample Input 2

5
NNYNN
NNNNN
YNNNN
NNNNY
NNNYN

Sample Output 2

Hanako

Sample Input 3

8
NYNNNNNN
YNNYNNYN
NNNNNNNY
NYNNNNYN
NNNNNNNN
NNNNNNNN
NYNYNNNN
NNYNNNNN

Sample Output 3

Taro

Solution in C++ (judge verdict: Wrong Answer)

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const int INF = 1<<28;
const double EPS = 1e-8;
const int MOD = 1000000007;


int n;

vector<vi> g;
int visited[1001], par[2];

int dfs(int v){
	if(visited[v]) return 0;
	visited[v] = 1;
	int res = 1;
	FOR(u, g[v]) res += dfs(*u);
	return res;
}

int toOdd(int even, int odd);
int toEven(int even, int odd){
	if(even+odd == 2) return !!even;
	return !toOdd(even+1, odd-2);
}
int toOdd(int even, int odd){
	if(even+odd == 2) return !even;
	return !toEven(even-1, odd);
}

main(){
	ios::sync_with_stdio(false);
	cin >> n;
	g.resize(n);
	int e = 0;
	REP(i, n)REP(j, n){
		char c;
		cin >> c;
		if(i < j && c == 'Y'){
			g[i].push_back(j);
			g[j].push_back(i);
			e ++;
		}
	}
	REP(i, n) if(visited[i] == 0) par[dfs(i)&1] ++;
	int ans = ((n*(n-1)/2-e)&1) ? toEven(par[0], par[1]) : toOdd(par[0], par[1]);
	cout << (ans ? "Taro" : "Hanako") << endl;
	return 0;
}