Problem:
Problem C: Simple GUI Application

Advanced Creative Mobile 社（ACM社）では、新しいポータブルコンピュータに搭載するGUIアプリケーションの開発を行うことになった。

下図に示すように、GUIは１つのメインパネルを持ち、その上にいくつかのパネルが配置され、さらにそれらのパネルの上にもいくつかのパネルが配置されるような入れ子構造になっている。パネルはすべて辺が座標軸に平行・垂直な長方形または正方形である。

アプリケーションはパネルの入れ子構造をタグ構造で保持する仕様となっている。パネルを表すタグ構造は、タグ値とそのパネルの上に配置されているパネルのタグ構造のリストを持つ。タグ値はそのパネルの左上の座標 (x1, y1) と 右下の座標 (x2, y2) を示す。

タグ構造の構文規則を以下に示す。ここで、構文の記述に用いる記号の意味を、以下の表のように定める。"<"、">", "," 及び "/" は、字句要素である。

記号

意味

::=

定義する

{}*

{ と } で囲まれた要素の 0 回以上の繰り返し

タグ構造 ::= 開始タグ タグ値 {タグ構造}* 終了タグ
開始タグ ::= <タグ名>
終了タグ ::= </タグ名>
タグ名 ::= 文字列
タグ値 ::= 整数,整数,整数,整数

タグ名はパネルの名前を示す１文字以上からなる文字列である。

タグ値は、カンマで区切られた４つの整数であり、それぞれパネルの座標を示す x1, y1, x2, y2 である。

例えば、上図に示したGUIは以下のタグ構造で記述される(スペースの関係上２行にまたがっているが、入力は１行で与えられる)：

<main>10,10,190,150<menu>20,20,70,140</menu><primary>80,20,180,140
<text>90,30,170,80</text><button>130,110,170,130</button></primary></main>

このGUIでは、ユーザがある点をタッチすると、その点において最上部にあるパネルが選択される（境界線を含む）。

あなたの仕事は、メインパネルのタグ構造と、タッチされた点のリストを読み込み、以下の情報を出力するプログラムを作成することである。

選択されたパネルの名前

そのパネルの直接上に配置されているパネルの数（以下"子の数"と呼ぶ）

なお、入力されるタグ構造について以下のことを仮定してよい。

タグ構造に文法エラーはない。

パネルがそれを含むパネル（以下"親パネル"と呼ぶ）からはみ出すことはなく、境界にも触れない。

同じ親パネルを持つパネル同士は重ならず、触れない。

同じ名前のパネルはない。

Input

入力は複数のデータセットからなる。各データセットは以下の形式で与えられる：

n
タグ構造
x1 y1
x2 y2
.
.
.
xn yn

n はタッチされた点の数を示す整数である。タグ構造は空白を含まない１行の文字列である。xi, yi は i 番めにタッチされた点の x 座標と y 座標を表す（座標軸は上図に定めたものとする）。

n ≤ 100、タグ構造の文字列の長さ ≤ 1000 と仮定してよい。また、入力で与えられる x 座標 y 座標は 0 以上 10,000 以下と仮定してよい。

n が 0 のとき入力の終わりとする。

Output

各データセットに対して、選択された順番にパネルの名前と子の数を出力せよ。各名前と子の数を１つの空白で区切って１行に出力せよ。何も選択されない場合（タッチされた点にパネルがない場合）は、"OUT OF MAIN PANEL 1"と出力せよ。

Sample Input

5
<main>10,10,190,150<menu>20,20,70,140</menu><primary>80,20,180,140</primary></main>
10 10
15 15
40 60
2 3
130 80
0

Output for the Sample Input

main 2
main 2
menu 0
OUT OF MAIN PANEL 1
primary 0

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Text;

class TEST{
	static void Main(){
		while(true){
			var d=int.Parse(Console.ReadLine());
			if(d==0)break;
			Sol mySol=new Sol(d);
			mySol.WriteAns();
		}
	}
}


class Sol{
	int n;
	PannelTag TOP;
	public void WriteAns(){
		for(int i=0;i<n;i++){
			//var s=Array.ConvertAll(Console.ReadLine().Split(' '),e=>int.Parse(e));
			var ss=Console.ReadLine().Split(' ');
			int[] s=new int[2];
			s[0]=int.Parse(ss[0]);
			s[1]=int.Parse(ss[1]);
			
			SearchAndWrite(TOP,s[0],s[1]);
		}
	}
	
	void SearchAndWrite(PannelTag P,int x,int y){
		bool chk=true;
		for(int i=0;i<P.Children.Count;i++){
			if(x>=P.Children[i].Xmin && x<=P.Children[i].Xmax && y>=P.Children[i].Ymin && y<=P.Children[i].Ymax){
				chk=false;
				SearchAndWrite(P.Children[i],x,y);
				break;
			}
		}
		if(chk){
			Console.Write(P.Body);
			Console.WriteLine(" {0}",P.Children.Count);
		}
	}
	
	public Sol(int n_){
		n=n_;
		String tag_main=Console.ReadLine();
		
		PannelTag Content=new PannelTag(tag_main);
		
		// 外枠を追加する（万一、mainの中に"OUT OF MAIN PANEL"があった時のために、個別に生成）
		TOP=new PannelTag("<OUT OF MAIN PANEL>0,0,10001,10001</OUT OF MAIN PANEL>");
		Content.Parent=TOP;
		TOP.Children.Add(Content);
	}
}


class PannelTag{
	PannelTag parent;
	String body;
	String expr;
	int xmin;
	int xmax;
	int ymax;
	int ymin;
	
	public PannelTag Parent{
		get{return parent;}
		set{this.parent=value;}
	}
	public List<PannelTag> Children;
	public int Xmin{get{return xmin;}}
	public int Xmax{get{return xmax;}}
	public int Ymin{get{return ymin;}}
	public int Ymax{get{return ymax;}}
	public String Body{get{return body;}}


	//constructor
	//exprを与えて再帰的にparseしながらツリーを生成。
	public PannelTag(String expr_){
		expr=expr_;
		
		int cursol=0;
		int cursol_bak=0;
		
		while(expr[cursol]!='>')cursol++;
		body=expr.Substring(1,cursol-1);
		cursol++;
		cursol_bak=cursol;//＠サイズの先頭文字
		while(expr[cursol]!='<')cursol++;
		var Csv=expr.Substring(cursol_bak,cursol-cursol_bak).Split(',');
		xmin=int.Parse(Csv[0]);
		ymin=int.Parse(Csv[1]);
		xmax=int.Parse(Csv[2]);
		ymax=int.Parse(Csv[3]);

		//子ノードを追加する
		//cursol:'<'の上にいる
		Children=new List<PannelTag>();
		while(cursol<expr.IndexOf("</"+body+">",0)){
			cursol_bak=cursol;
			while(expr[cursol]!='>')cursol++;
			String body_child=expr.Substring(cursol_bak+1,cursol-(cursol_bak+1));
			cursol=expr.IndexOf("</"+body_child+">",cursol_bak);
			while(expr[cursol]!='>')cursol++;
			String expr_child=expr.Substring(cursol_bak,cursol-cursol_bak+1);
			Children.Add(new PannelTag(expr_child));
			cursol++;//'<'の上に置く
		}
	}
}