#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <complex>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
#include <assert.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <random>
#include <functional>
#include <numeric>
#include <bitset>
#include <fstream>
#include <memory>

using namespace std;

struct before_main{before_main(){cin.tie(0); ios::sync_with_stdio(false);}} before_main;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
template<class T1, class T2> inline bool minimize(T1 &a, T2 b) { return b < a && (a = b, 1); }
template<class T1, class T2> inline bool maximize(T1 &a, T2 b) { return a < b && (a = b, 1); }
template<class T> ostream& operator << (ostream& ost, vector<T> const& v) { ost << "["; rep(i, v.size()) { if(i) ost << ", "; ost << v[i]; } ost << "]"; return ost; }

namespace parser {
 
typedef string::const_iterator Iter;
Iter __begin, __end;
Iter __it;
 
void remain_dump() {
  cout << "Remain: '" << string(__it, __end) << "'" << endl;
}
 
void init_iterator(Iter begin, Iter end) {
  __begin = begin;
  __end = end;
  __it = begin;
}
 
void consume(char expected) {
  assert(__end != __it);
  if(*__it != expected) {
    remain_dump();
    assert(false);
  }
  __it ++;
}
 
bool consume_if(char expected) {
  if(*__it != expected) return false;
  consume(expected);
  return true;
}
 
void unread() {
  assert(__it != __begin);
  __it --;
}
 
bool eof() {
  return __it == __end;
}
 
void append(int& tar, char add) { tar *= 10; tar += add - '0'; }
void append(string& tar, char add) { tar += add; }
 
enum readable { alphabetical = 1<<0, integer = 1<<1 };
enum class lexstat { no_stat = -1, read_eof, success };
 
lexstat lstat = lexstat::no_stat;
 
template<class return_type>
return_type lex(readable rd, vector<char> const& skipper = {}, vector<char> const& excepts = {}) {
 
  auto can_go = [&](char c) {
    if(find(skipper.begin(), skipper.end(), c) != skipper.end()) return false;
    if(find(excepts.begin(), excepts.end(), c) != excepts.end()) return true;
    if((rd & alphabetical) && isalpha(c)) return true;
    if((rd & integer) && isdigit(c)) return true;
    return false;
  };
 
  if(!can_go(*__it)) {
    lstat = lexstat::read_eof;
    return return_type{};
  }
 
  return_type ret{};
  while(can_go(*__it))
    append(ret, *__it), consume(*__it);
 
  lstat = lexstat::success;
 
  return ret;
}
 
void lex_f(string const& force) {
  for(auto c: force)
    consume(c);
}
 
void lex_f(int force) {
  lex_f(to_string(force));
}
 
template<class return_type>
vector<return_type> lex_stream(readable rd, vector<char> const& skipper, vector<char> const& excepts = {}) {
  vector<return_type> ret;
  while(1) {
    auto r = lex<return_type>(rd, skipper, excepts);
    if(lstat == lexstat::read_eof) break;
    ret.push_back(r);
    if(find(skipper.begin(), skipper.end(), *__it) != skipper.end()) {
      consume(*__it);
    }
  }
  return ret;
}
 
bool look_ahead(string const& expected) {
  int n = expected.size();
  int i = 0;
  while(i < n) {
    if(!consume_if(expected[i])) break;
    i ++;
  }
 
  if(i == n) {
    while(i--) unread();
    return true;
  }
 
  while(i--) unread();
  return false;
}
 
}
using namespace parser;

#define DEF_PARSER(ast, property_definitions, root_settings) \
struct ast {  \
  property_definitions; \
  vector<shared_ptr<ast>> children; \
};  \
shared_ptr<ast> parse_ ## ast(shared_ptr<ast>& p); \
shared_ptr<const ast> parse_ ## ast(Iter begin, Iter end) { \
  init_iterator(begin, end);  \
  auto p = make_shared<xml>();  \
  root_settings; \
  return parse_ ## ast(p);  \
}

#define PARSE(ast, tar) \
  parse_ ## ast(begin(tar), end(tar))

#define PARSER_IMPL(ast, start_cond)  \
shared_ptr<ast> parse_ ## ast(shared_ptr<ast>& p) { \
  while(!eof()) { \
    if (start_cond) {
#define HEAD(str) look_ahead(str)
#define TERMINATE return p;
#define CHANCE(cond)  \
 } else if(cond) {

#define END_PARSER_IMPL \
  }} \
  return p; \
}

#define prop(pr) p->pr
#define cprop(pr) c->pr

#define RECUR(ast, property_settings)  \
auto c = make_shared<ast>(); \
property_settings;  \
p->children.push_back(c); \
parse_ ## ast(c); continue;

#define ast_ref(const_ast) shared_ptr<const const_ast> const& __ast_ref_p
#define enumerate_children(c)  \
  for(auto && c: __ast_ref_p->children)

#define ref_prop(pr) __ast_ref_p->pr

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

DEF_PARSER(xml,
  string tag;
  vector<int> nums;
  ,
  prop(tag) = "OUT OF MAIN PANEL"
)

PARSER_IMPL(xml,
  HEAD("</"))
    lex_f("</" + p->tag + ">"); TERMINATE CHANCE(
  HEAD("<"))
    RECUR(xml,
      cprop(tag)  = lex<string>(alphabetical, {}, {'<','>'});
      cprop(tag)  = c->tag.substr(1, c->tag.size()-2);
      cprop(nums) = lex_stream<int>(integer, {','});
    )
END_PARSER_IMPL


pair<string, int> dfs(ast_ref(xml), int x, int y) {
  enumerate_children(c)
    if(c->nums[0] <= x && c->nums[1] <= y && x <= c->nums[2] && y <= c->nums[3])
      return dfs(c, x, y);

  return {ref_prop(tag), ref_prop(children.size())};
}

int main() {

  for(int T; cin >> T;) {
    string str; cin >> str;
    auto root = PARSE(xml, str);
    while(T--) {
      int x, y; cin >> x >> y;
      auto r = dfs(root, x, y);
      cout << r.first << " " << r.second << endl;
    }
  }
  return 0;
}

Measured memory_bytes: 3192