Problem:
パトロール

文久２（1862）年、会津の殿様が京都守護職を命ぜられました。京都守護職とは治安の悪化した幕末の京都を守る大切な役目です。幕府や他の藩と分担して市中をパトロールしなければなりません。ところがいざ分担ルートを決める段になって、家臣の中でも有名な頑固者の古老から以下のような注文がつきました。

大変なことになりました。殿様といえどもこの家臣の言い分を無視するわけにはいきません。分担ルートの選択によっては、「武士の面目が立たない」ということになってしまいます。

ということで、スタート地点、ゴール地点、交差点の情報を入力として、上の三つの条件を満たすかどうかを判定するプログラムを作って、殿様に献上してください。

スタート地点を 1、ゴール地点を2、その他の交差点を 3 以上の整数で表します。1つの道路は、その道が結ぶ1組の交差点番号で表します。なお、交差点の数は 100 以下とし、全ての交差点からスタート地点およびゴール地点への経路がそれぞれ一つ以上あるものとします。

入力

複数のデータセットが与えられます。各データセットは以下の形式で与えられます。

a1 b1
a2 b2
：
：
0 0

各行の２つの整数は、交差点 ai と交差点 bi とをつなぐ道路が存在することを示します。
ai と bi がともに 0 のとき交差点情報の入力の終わりを示します。

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

出力

各データセットに対して、武士の面目が立つ場合（三つの条件を満たす場合）OK、それ以外の場合（三つの条件を満たさない場合）NG と１行に出力してください。

Sample Input

1 3
3 4
3 5
3 6
4 6
4 7
4 7
5 6
6 7
5 8
5 8
6 8
6 9
7 9
8 9
9 2
0 0
1 3
3 4
3 4
4 2
0 0

Output for the Sample Input

OK
NG

Solution in JavaScript (judge verdict: Accepted)

const input = require('fs').readFileSync('/dev/stdin', 'utf8');

const inputs = input.trim().split('\n');
const adj = inputs.map((s) => s.split(' ').map(Number));

class Edge {
  constructor(dest, weight = 1) {
    this.dest = dest;
    this.weight = weight;
  }
}

class Node {
  constructor() {
    this.list = [];
  }
  addEdge(edge) {
    this.list.push(edge);
  }
  isOdd() {
    return !!(this.list.length % 2);
  }
}

class Graph {
  constructor() {
    this.init();
  }
  init() {
    this.map = new Map();
  }
  getNode(source, edge) {
    if (!this.map.has(source)) {
      this.map.set(source, new Node());
    }
    return this.map.get(source);
  }
  addEdge(source, edge) {
    const node = this.getNode(source);
    node.addEdge(edge);
  }
  countOdd() {
    return Array.from(this.map.values()).map(node => node.isOdd() ? 1 : 0).reduce((a, b) => a + b);
  }
  canPatrol() {
    if (graph.countOdd() !== 2) {
      return false;
    }
    return graph.getNode(1).isOdd() && graph.getNode(2).isOdd();
  }
}

const graph = new Graph();
adj.forEach(([source, dest]) => {
  if (source === 0 && dest === 0) {
    console.log(graph.canPatrol() ? 'OK' : 'NG');
    graph.init();
    return;
  }
  graph.addEdge(source, new Edge(dest));
  graph.addEdge(dest, new Edge(source));
});