Problem:
こぶたぬきつねこ

A子さんの家に親戚のB男君がやってきました。彼は3歳で歌が大好きです。彼は幼稚園でならった「こぶたぬきつねこ」(山本直純作詞・作曲)という歌を一生懸命に歌っています。この歌では、4つのことば「こぶた」 「たぬき」 「きつね」「ねこ」が順にしりとりになっていて、さらに最後の音と最初の音が同じになっています。B男君は、A子さんに、同じようなしりとりが、B男君が言った単語から作れるか教えて欲しいと言われました。

そこで、A子さんを助けるために、与えられた単語から、その単語をすべて使って、順にしりとりをつくり、その上で、 第1 の単語の最初の文字と最終の単語の最後の文字が同じであるようにできるか否かを判定するプログラムを作成しましょう。

n 個の単語を入力とし、それらの単語の組からしりとりを作成できるか否かを判定し、可能な場合はOK と、不可能な場合は NG と出力するプログラムを作成してください。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。
各データセットは以下の形式で与えられます。

n
word1
word2
:
wordn

1 行目に単語の個数 n (2 ≤ n ≤ 10000) が与えられます。続く n 行に n 個の単語 wordi (32 文字以下の半角英小文字だけからなる文字列) が与えられます。

データセットの数は 50 を超えません。

Output

入力データセットごとに、判定結果を１行に出力します。

Sample Input

5
apple
yellow
georgia
king
email
7
apple
yellow
georgia
king
email
wink
lucky
0

Output for the Sample Input

NG
OK

Solution in Rust (judge verdict: Accepted)

use std::collections::HashSet;

fn main(){
  loop {
    let n: usize = read();

    if n == 0 { break; }

    let mut adj: Vec<Vec<usize>> = vec![vec![0;26];26];
    let mut set: HashSet<usize> = HashSet::new();
    let mut uf: UnionFind = UnionFind::new(26);
    
    for _ in 0 .. n {
      let s:String = read();
      let h = s.chars().next().unwrap() as usize - 97;
      let t = s.chars().last().unwrap() as usize - 97;
      adj[h][t] += 1;
      set.insert(h);
      set.insert(t);
      uf.unite(h, t);
    }

    let mut link = true;
    let sl = set.len();
    
    for i in set.iter() {
      if sl != uf.size(*i) {
        link = false;
        break;
      }
    }

    let mut eg = true;

    for i in 0 .. 26 {
      let mut sr = 0;
      for j in 0 .. 26 {
        sr += adj[i][j];
      }
      let mut sc = 0;
      for j in 0 .. 26 {
        sc += adj[j][i];
      }
      if sr != sc {
        eg = false;
        break;
      }
    }
    
    println!("{}", if link && eg { "OK" } else { "NG" });

  }
}

fn read<T>() -> T
  where T: std::str::FromStr,
        T::Err: std::fmt::Debug
{
  let mut buf = String::new();
  std::io::stdin().read_line(&mut buf).expect("failed to read");
  buf.trim().parse().unwrap()
}

#[derive(Debug)]
struct UnionFind {
  p: Vec<isize>
}

#[allow(dead_code)]
impl UnionFind {
  fn new(n: usize) -> UnionFind {
    UnionFind {
      p: vec![-1;n]
    }
  }

  fn root(&mut self, a: usize) -> usize {
    let u = self.p[a];
    if u < 0 { a }
    else {
      let rt = self.root( u as usize);
      self.p[a] = rt as isize;
      rt
    }
  }

  fn unite(&mut self, a: usize, b: usize){
    let ra = self.root(a);
    let rb = self.root(b);

    if ra != rb {
      if self.p[ra] < self.p[rb] {
        self.p[ra] = self.p[ra] + self.p[rb];
        self.p[rb] = ra as isize;
      } else {
        self.p[rb] = self.p[ra] + self.p[rb];
        self.p[ra] = rb as isize;
      }
    }
  }

  fn same(&mut self, a: usize, b:usize) -> bool {
    self.root(a) == self.root(b)
  }

  fn size(&mut self, a: usize) -> usize {
    let ra = self.root(a);
    (-1 * self.p[ra]) as usize
  }
}