//STARTCOPY
#include<bits/stdc++.h>
using namespace std;

using u_counter_type = unsigned int;
using need_int = int;
using counter_type = int;
using MAIN = int;
#define int DontUseIntÉ
using ll = long long;

template<typename T>
using PairOf = pair<T,T>;

using Void = tuple<>;

struct BasicInitialization{
    BasicInitialization(){
        ios_base::sync_with_stdio(false);
    }
};
BasicInitialization __basic_initialization__;
namespace mytl{

template<typename T, typename R>
vector<R> fmap(R(*f)(const T), const vector<T>& t){
    vector<R> res;
    for(auto elem : t) res.push_back(f(elem));
    return res;
}

template<typename T>
vector<T> forrange(T n, T from){
    vector<T> res(n);
    iota(res.begin(), res.end(), from);
    return res;
}

template<typename F>
void repeat(need_int n, const F& callback){
    for(need_int _ : forrange(n,0)) callback();
}

template<typename T>
struct optional{
    private:
        T *val = nullptr;
        void reserve(){
            val = new T;
        }
    public:
        optional<T> operator=(const T& operand){
            reserve();
            *val = operand;
            return *this;
        }
        bool has_value(){
            return val != nullptr;
        }
        T& value(){
            return *val;
        }
        optional(T val_){
            operator=(val_);
        }
        optional(initializer_list<T> l){
            assert(l.size() == 1);
            operator=(*l.begin());
        }
        optional(){}
};

template<typename T>
optional<T> make_optional(T val_){
    return optional<T>(val_);
}

template<typename T, T(*f)(T,T)>
struct Tracker : optional<T>{
    using optional<T>::operator=;

    Tracker() : optional<T>() {};

    void update(T val){
        if(this->has_value()){
            *this = f(this->value(), val);
        }
        else{
            *this = val;
        }
    }
};

template<typename T>
T min(T a, T b){return std::min(a,b);}
template<typename T>
T max(T a, T b){return std::max(a,b);}
template<typename T>
T __gcd(T a, T b){return std::__gcd(a,b);}

template<typename T, template<typename, typename...> typename Container>
vector<PairOf<T&> > adjecent_pairs(Container<T>& c){
    vector<PairOf<T&> > res;
    optional<T*> prev_elem;
    for(auto& elem : c){
        if(prev_elem.has_value()){
            res.push_back({*prev_elem.value(), elem});
        }
        prev_elem = &elem;
    }
    return res;
}

template<typename T>
struct LazyVector : vector<T>{
    typename vector<T>::reference operator[](counter_type i){
        if(i >= this->size()) this->resize(i+1);
        return vector<T>::operator[](i);
    }
};

template<typename K, typename T>
struct AssocVector : LazyVector<T>{
    LazyVector<bool> exists;
    typename vector<T>::reference operator[](counter_type i){
        exists[i] = true;
        return LazyVector<T>::operator[](i);
    }
    typename vector<T>::iterator find(counter_type i){
        if(!exists[i]) return this->end();
        else return this->begin() + i;
    }
};

template<template<typename, typename, typename...> typename Container, typename Key, typename Value>
bool has_key(Container<Key, Value>& container, Key key){
    return container.find(key) != container.end();
}

template<typename T>
struct Lazy : optional<T>{

    function<T()> f;

    Lazy(function<T()> f) : f{f}, optional<T>() {};

    T& value(){
        if(!this->has_value()){
            optional<T>::operator=(f());
        }
        return optional<T>::value();
    }

};

#define LAZY(val, tipe) mytl::Lazy<tipe>([&](){return (val);})
#define WATCH(x) cout << (#x) << " is " << (x) << endl
}

namespace std{

template<typename T>
istream& operator>>(istream& is, mytl::optional<T>& x){
    if(!x.has_value()){
        T x_;
        is>>x_;
        x = x_;
    }
    return is;
}

istream& operator>>(istream& is, Void& x){
    return is;
}

template<typename P, typename Q>
ostream& operator<<(ostream& os, const pair<P,Q>& x){
    os<<"("<<x.first<<", "<<x.second<<")";
    return os;
}

template<typename T, template<typename, typename...> typename Container>
ostream& operator<<(ostream& os, const Container<T>& x){
    os<<"{";
    bool first = true;
    for(const auto& elem : x){
        if(!first) os<<", ";
        os<<elem;
        first = false;
    }
    os<<"}";
    return os;
}

}

namespace mytl{

template<typename T, typename P=T>
T read(istream& is=cin){
    P a;
    is>>a;
    return T(a);
}

template<typename T, typename P, typename Q>
T read(istream& is=cin){
    P a;
    Q b;
    is>>a>>b;
    return T(a,b);
}

template<typename T, typename P, typename Q, typename R>
T read(istream& is=cin){
    P a;
    Q b;
    R c;
    is>>a>>b>>c;
    return T(a,b,c);
}

template<typename T, typename... Q>
vector<T> readValues(ll n, istream& is=cin){
    vector<T> res;
    repeat(n, [&res](){
        res.push_back(read<T,Q...>());
    });
    return res;
}

}

namespace mytl{

template<typename T>
void print(const T& x, ostream& os=cout){
    os<<x;
}

}
namespace mytl{
template<typename T>
T power(T base, ll exponential, T unit=1){
    T res = unit;
    while(exponential > 0){
        if(exponential%2 == 1) res = res * base;
        base = base * base;
        exponential = exponential / 2;
    }
    return res;
}
}
namespace mytl{
    template<ll MOD>
    struct TSModulo{
    private:
        ll val;

    public:
        static TSModulo inverse(TSModulo x){// asserting MOD is prime
            return power(x, MOD-2);
        };
        TSModulo(ll initVal) : val{(MOD + initVal%MOD)%MOD} {};
        TSModulo() : TSModulo(0) {}
        TSModulo& operator=(const TSModulo&) = default;

        ll get() const{ // no type cast operator to prevent accidentally turning into ordinary number
            return val;
        }

        //Unary operators
        TSModulo operator-() const{
            return TSModulo(-val);
        };
        TSModulo operator+() const{
            return TSModulo(+val);
        };

        //Binary operators on ordinary numbers
        TSModulo operator-(const ll& operand) const{
            return TSModulo(val-operand);
        };
        TSModulo operator+(const ll& operand) const{
            return TSModulo(val+operand);
        };
        TSModulo operator*(const ll& operand) const{
            return TSModulo(val*operand);
        };
        TSModulo operator/(const ll& operand) const{ //asserting MOD is prime
            return TSModulo(inverse(operand) * val);
        };

        //Binary operators on Modulo
        TSModulo operator-(const TSModulo& operand) const{
            return TSModulo(val-operand.get());
        };
        TSModulo operator+(const TSModulo& operand) const{
            return TSModulo(val+operand.get());
        };
        TSModulo operator*(const TSModulo& operand) const{
            return TSModulo(val*operand.get());
        };
        TSModulo operator/(const TSModulo& operand) const{ //asserting MOD is prime
            return TSModulo(val * inverse(operand));
        };
    };

    using Mod107 = TSModulo<1000000007LL>;

    template<ll MOD>
    ostream& operator<<(ostream& os, TSModulo<MOD> x){
        return os<<"("<<x.get()<<"%"<<MOD<<")";
    }

}
namespace mytl{
    struct Modulo{
        static ll global_mod;
    private:
        ll val;
    public:
        const ll MOD;
        Modulo(ll initMOD, ll initVal) : MOD{initMOD}, val{initVal} {
            val %= MOD;
            if(val < 0) val += MOD;
        };
        Modulo() : Modulo(global_mod, 0) {};

        static Modulo inverse(Modulo x){// asserting MOD is prime
            return power(x, x.MOD-2, x.unit());
        };
        Modulo unit() const{
            return Modulo(MOD, 1);
        }
        Modulo& operator=(const Modulo& operand){
            val = operand.val;
            return *this;
        };

        ll get() const{ // no type cast operator to prevent accidentally turning into ordinary number
            return val;
        }

        //Unary operators
        Modulo operator-() const{
            return Modulo(MOD, -val);
        };
        Modulo operator+() const{
            return Modulo(MOD, +val);
        };

        //Binary operators on ordinary numbers
        Modulo operator-(const ll& operand) const{
            return Modulo(MOD, val-operand);
        };
        Modulo operator+(const ll& operand) const{
            return Modulo(MOD, val+operand);
        };
        Modulo operator*(const ll& operand) const{
            return Modulo(MOD, val*operand);
        };
        Modulo operator/(const ll& operand) const{ //asserting MOD is prime
            return Modulo(MOD, val * inverse(Modulo(MOD, operand)).get());
        };

        //Binary operators on Modulo
        Modulo operator-(const Modulo& operand) const{
            return Modulo(MOD, val-operand.get());
        };
        Modulo operator+(const Modulo& operand) const{
            return Modulo(MOD, val+operand.get());
        };
        Modulo operator*(const Modulo& operand) const{
            return Modulo(MOD, val*operand.get());
        };
        Modulo operator/(const Modulo& operand) const{ //asserting MOD is prime
            return Modulo(MOD, val * inverse(operand).get());
        };

    };

    ll Modulo::global_mod = 1000000007LL;

    Modulo mod107(ll x){
        return Modulo(1000000007LL, x);
    }
    ostream& operator<<(ostream& os, Modulo x){
        return os<<"("<<x.get()<<"%"<<x.MOD<<")";
    }

}
namespace mytl {

template<class T>
struct Resetter;

template<class T>
Resetter<T>* global_resetter = new Resetter<T>;

template<class T>
struct Resetter {

    using State = pair<counter_type, T>;

    State* state = new State{0, T()};

    Resetter(){}
    Resetter(T value){
        state = new State{0, value};
    }

    void activate(){
        global_resetter<T> = this;
    }

    void reset(T value){
        *state = State{state->first+1, value};
    }

    struct Variable{

        State state;
        State& parent = *global_resetter<T>->state;

        Variable() : state{*global_resetter<T>->state} {}
        Variable(T value) : state{global_resetter<T>->state->first, value} {}
        Variable(State st) : state{st} {}
        Variable(T value, State& parent) : state{parent->first, value} {};

        bool fresh(){
            return state.first >= parent.first;
        }

        void overwrite(){
            state = parent;
        }

        bool refresh(){
            if(!fresh()) overwrite();
        }

        T get(){
            refresh();
            return state.second;
        }

        void survive(){
            state.first = parent.first;
        }

        void operator=(T new_value){
            state.second = new_value;
            survive();
        }

    };

};
}
namespace mytl{

template<typename N, typename E, template<typename, typename, typename...> typename C>
struct Container_Graph : C<N, vector<pair<E, N> > >{
    template<typename A, typename B>
    using Container = C<A,B>;
    using Edge = E;
    using Node = N;
    optional<ll> n;
    Container_Graph(ll n={}) : n{n}, Container<Node, vector<pair<Edge, Node> > >() {}

    void newEdge(Node u, Node v, Edge edge=Void()){
        (*this)[u].push_back(make_pair(edge, v));
    }
    vector<Node> getNodes(){
        vector<Node> res;
        if(n.has_value()){
            for(ll i=1; i<=n.value(); i++) res.push_back(i);
        }
        else{
            for(auto& p : *this){
                res.push_back(p.first);
            }
        }
        return res;

    }
    vector<pair<Edge, Node> >& getEdges(Node node){
        return (*this)[node];
    }
    vector<Node > getNeighbours(Node node){
        vector<Node> res;
        for(auto& par : getEdges(node)){
            res.push_back(par.second);
        }
        return res;
    }

};

using NormalSimpleGraph = Container_Graph<ll, Void, AssocVector>;

template<typename G>
void readNeighbourList(G& g, ll indexing=1){
    for(ll i : forrange(g.n.size(), indexing)){
        for(ll neig : readValues<ll>(read<ll>())){
            g.new_edge(i, neig);
        }
    }
}

template<typename G>
void readEdgeList(G& g, ll m, bool bidirectional=true){
    using Node = typename G::Node;
    using Edge = typename G::Edge;
    for(auto elem : readValues<tuple<Node, Node, Edge>, Node, Node, Edge >(m)){
        Node u, v;
        Edge edge;
        tie(u, v, edge) = elem;
        g.newEdge(u,v,edge);
        if(bidirectional) g.newEdge(v, u, edge);
    }
}

template<
    typename G,
    template<typename> typename A,
    typename F=void(*)(typename A<G>::Option)
>
typename G::template Container<typename G::Node, typename A<G>::Info> queue_graph_algorithm(
    G& g,
    vector<typename A<G>::Option > sources,
    F new_node_callback=[](typename A<G>::Option){})
{
    using Algo = A<G>;
    typename Algo::Queue q;

    for(auto source : sources) q.push(source);
    typename G::template Container<typename G::Node, typename Algo::Info> d;
    while(!q.empty()){
        auto akt = Algo::consume(q);
        typename Algo::Node who = akt.second;
        typename Algo::Info info = akt.first;

        if(has_key(d, who)) continue;

        d[who] = info;

        new_node_callback({info, who});
        for(auto par : g.getEdges(who)) if(!has_key(d, par.second)){
            q.push({Algo::append({info, who}, par.first, par.second), par.second});
        }
    }
    return d;
}

template<template<typename> typename QP, template<typename> typename P>
struct AlgoComposer{
    template<typename G>
    struct A{
        using Path = P<G>;
        using Edge = typename G::Edge;
        using Node = typename G::Node;
        using Info = typename Path::Info;
        using Option = pair<Info, Node>;
        using QueuePolicy = QP<Option>;
        using Queue = typename QueuePolicy::Queue;

        static Option consume(Queue& q){
            return QueuePolicy::consume(q);
        }
        static void push(Queue& q, Option new_option){
            return QueuePolicy::push(q, new_option);
        }
        static Info append(pair<Info, Node> from , Edge e, Node to){
            return Path::append(from, e, to);
        }
    };
};

template<typename T>
struct Priority{
    using Queue = priority_queue<T, vector<T>, greater<T> >;
    static T consume(Queue& q){
        auto res = q.top();
        q.pop();
        return res;
    }
    static void push(Queue& q, T new_option){
        q.push(new_option);
    }
};

template<typename T>
struct FIFO{
    using Queue = queue<T>;
    static T consume(Queue& q){
        auto res = q.front();
        q.pop();
        return res;
    }
    static void push(Queue& q, T new_option){
        q.push(new_option);
    }
};

template<typename T>
struct FILO{
    using Queue = stack<T>;
    static T consume(Queue& q){
        auto res = q.top();
        q.pop();
        return res;
    }
    static void push(Queue& q, T new_option){
        q.pop();
    }
};

template<typename G>
struct JustLength{
    using Info = typename G::Edge;
    static Info append(pair<Info, typename G::Node> from, typename G::Edge e, typename G::Node n){
        return from.first + e;
    }
};

template<typename G>
struct SimpleJustLength{
    using Info = ll;
    static Info append(pair<Info, typename G::Node> from, typename G::Edge e, typename G::Node n){
        return from.first + 1;
    }
};

template<typename G>
struct LengthAndLastNode{
    using Info = pair<ll, typename G::Node>;
    static Info append(pair<Info, typename G::Node> from, typename G::Edge e, typename G::Node n){
        return Info(from.first + e, from.second);
    }
};

template<typename G>
struct SimpleLengthAndLastNode{
    using Info = pair<ll, typename G::Node>;
    static Info append(pair<Info, typename G::Node> from, typename G::Edge e, typename G::Node n){
        return Info(from.first.first + 1, from.second);
    }
};

/*
template<typename G>
struct Custom{
    using Edge = typename G::Edge;
    using Node = typename G::Node;

    using Info = _;
    using Option = pair<Info, Edge>;
    using Queue = _;

    static Option consume(Queue &q){
        _
        return _;
    }

    static void push(Queue &q, Option new_option){
        _
    }

    static Info append(Option from, Edge e, Node to){
        return _
    }

};
*/
}
namespace mytl{

struct Point{
    ll x, y;

    Point(ll x, ll y) : x{x}, y{y} {};
    Point(pair<ll,ll> initPair) : x{initPair.first}, y{initPair.second} {};

    pair<ll,ll> getPair(){//not introducing type cast operator for safety
        return {x,y};
    }

    //Unary operators
    Point operator-() const{
        return {-x, -y};
    }
    Point operator+() const{
        return {x,y};
    }

    static ll sgn(ll x){
        return (x > 0) - (x < 0);
    }

    //Binary operators on ordinary numbers
    Point operator*(const ll& operand) const{
        return {x*operand, y*operand};
    }

    //Binary operators on Point itself
    Point operator+(const Point& operand) const{
        return {x+operand.x, y+operand.y};
    }
    Point operator-(const Point& operand) const{
        return {x-operand.x, y-operand.y};
    }

    ll operator*(const Point& operand){ //vectorial product
        return x*operand.y - y*operand.x;
    }

    ll direction(const Point& a, const Point& b) const{
        return sgn((a - *this) * (b - *this));
    };
};

ll distance_squared(const Point& a, const Point& b){
    return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}

double distance(const Point& a, const Point& b){
    return sqrt(distance_squared(a, b));
}

ll cartesian_distance(const Point& a, const Point& b){
    return abs(a.x - b.x) + abs(a.y - b.y);
}

typedef vector<Point> Poly;

bool inside(const Poly& poly, const Point& point, bool strict){ //assuming Poly is weakly convex
    ll prevdir = -2;
    for(ll i=0; i<poly.size(); i++){
        ll nexdindex = (i+1)%poly.size();
        ll dir = poly[i].direction(poly[nexdindex], point);
        if(dir == 0){
            if(strict) return false;
        }
        else{
            if(dir != prevdir && prevdir != -2) return false;
            prevdir = dir;
        }

    }
    return true;
}

}
namespace mytl{
template<class Op>
struct Node : Op::Range{
    using Range = typename Op::Range;
    using T = typename Op::T;
    using Change = typename Op::Change;
    using Range::singleton;
    using Range::inside;
    using Range::intersect;
    using Range::leftHalf;
    using Range::rightHalf;

    Node *left_child=NULL, *right_child=NULL;

    T partial;
    Change pending = Op::identity();

    Node(Range range) : Range(range), partial{Op::initial(range)} {};

    T query(Range range, Change change){
        return query_(range, change).first;
    }

    void add(Change change){
        pending = Op::push(pending, change);
    }

    void prepare(){
        if(!singleton()){
            if(left_child == NULL) left_child = (new Node(leftHalf()));
            if(right_child == NULL) right_child = (new Node(rightHalf()));
            left_child->add(pending);
            right_child->add(pending);
        }
        partial = Op::apply(*this, partial, pending);
        pending = Op::identity();
    }

    pair<T,T> query_(Range range, Change change){
        //cout<<range<<" "<<*this<<endl;
        prepare();
        if(inside(range)){
            add(change);
            prepare();
            return {partial, Op::zero()};
        }
        if(!intersect(range)){
            //cout<<"n"<<range<<" "<<*this<<endl;
            return {Op::zero(), partial};
        }

        auto from_left = left_child->query_(range, change);
        auto from_right = right_child->query_(range, change);
        //cout<<from_right.first<<endl;
        auto needed = Op::reduce(from_left.first, from_right.first), rest = Op::reduce(from_left.second, from_right.second);
        partial = Op::reduce(needed, rest);
        return {needed, rest};
    }

    T build_from(const function<T(ll)>& getter){
        prepare();
        pending = Op::identity();
        if(singleton()) partial = getter(this->first);
        else partial = Op::reduce(left_child->build_from(getter), right_child->build_from(getter));
        return partial;
    }

};

struct Range1D : PairOf<ll>{
    using PairOf<ll>::pair;

    ll span() const {
        return second-first+1;
    }
    bool singleton() const {
        return span() == 1;
    }
    Range1D leftHalf() const {
        return Range1D(first, (first+second)/2);
    }
    Range1D rightHalf() const {
        return Range1D((first + second)/2 + 1, second);
    }
    bool inside(const Range1D& other) const {
        return other.first <= first && second <= other.second;
    }
    bool intersect(const Range1D& other) const {

        return other.inside(*this)
             ||(other.first <= first && first <= other.second)
             ||(other.first <= second && second <= other.second);
    }
};

}

namespace mytl{
template<typename T_>
struct Add_Sum{
    using Range = Range1D;
    using T = T_;
    using Change = T_;

    static Change identity(){
        return 0;
    }

    static T zero(){
        return 0;
    }

    static T initial(Range r){
        return zero();
    }

    static T reduce(T a, T b){
        return a + b;
    }

    static T apply(Range r, T a, Change c){
        return a + r.span()*c;
    }

    static Change push(Change a, Change b){
        return a + b;
    }
};

template<typename T_>
struct Multiply_Sum{
    using Range = Range1D;
    using T = T_;
    using Change = T_;

    static Change identity(){
        return 1;
    }

    static T zero(){
        return 0;
    }

    static T initial(Range r){
        return r.span()*1;
    }

    static T reduce(T a, T b){
        return a + b;
    }

    static T apply(Range r, T a, Change c){
        return a*c;
    }

    static Change push(Change a, Change b){
        return a*b;
    }
};

}

namespace mytl{
/*
struct Custom_Op{
    using Range = _;
    using T = _;
    using Change = _;

    static Change identity(){
        return _;
    }

    static T zero(){
        return _;
    }

    static T initial(Range r){
        return _;
    }

    static T reduce(T a, T b){
        return _;
    }

    static T apply(Range r, T a, Change c){
        return _;
    }

    static Change push(Change a, Change b){
        return _;
    }

};
*/

}
namespace mytl{

template <template<typename, typename, typename...> typename C, typename Arg, typename R>
function<R (Arg)> memoize(R (*fn)(Arg)) {
    C<Arg, optional<R> > table;
    return [fn, table](Arg arg) mutable -> R {
        optional<R>& res = table[arg];
        if(!res.has_value()){
            res = fn(arg);
        }
        return res.value();
    };
}

}
//ENDCOPY

using G = mytl::Container_Graph<ll, Void, mytl::AssocVector>;

void processs(){
    ll n;
    cin>>n;
    G g(n);
    mytl::readEdgeList(g, n-1);

        //cout<<"hh";
    auto enyem_ = mytl::readValues<ll>(mytl::read<ll>());
    set<ll> enyem(enyem_.begin(), enyem_.end());
    auto ove_ = mytl::readValues<ll>(mytl::read<ll>());
    set<ll> ove(ove_.begin(), ove_.end());

    //cout<<enyem<<" "<<ove<<endl;
    auto ask = [&](ll& ide, char tipus, ll ki) -> bool{
        cout<<tipus<<" "<<ki<<endl;
        ll got;
        cin>>got;
        if(tipus == 'A' && mytl::has_key(ove, got)){
            cout<<"C "<<ki<<endl;
            return true;
        }
        if(tipus == 'B' && mytl::has_key(enyem, got)){
            cout<<"C "<<got<<endl;
            return true;
        }
        ide = got;
        return false;

    };

    ll one_piece;
    if(ask(one_piece, 'B', *ove.begin())) return;
     vector<pair<pair<ll,ll>, ll> > sour{{{0,-1}, *enyem.begin()}};
    // cout<<sour<<endl;
   auto tb = mytl::queue_graph_algorithm<G, mytl::AlgoComposer<mytl::FILO,mytl::SimpleLengthAndLastNode>::A >(g,sour);

    while(!mytl::has_key(enyem, one_piece)){
        one_piece = tb[one_piece].second;
    }

    ll dc;
    if(ask(dc, 'A', one_piece)) return;
    else{
        cout<<"C -1"<<endl;
    }

}

MAIN main(){
    ll T;
    cin>>T;
    mytl::repeat(T, [&](){
        processs();
    }) ;
}


#include <bits/stdc++.h>
using namespace std;

int n;
set<int> me, lichen;
vector<vector<int> > g;

int bfs(int start) {
    queue<int> q;
    q.push(start);
    vector<int> dist(n+1, -1);
    dist[start] = 0;
    while (q.size() > 0) {
        int u = q.front(); q.pop();
        for (int i = 0; i < g[u].size(); ++i) {
            if (dist[g[u][i]] == -1) {
                dist[g[u][i]] = dist[u]+1;
                q.push(g[u][i]);
            }
        }
    }
    int ans = -1;
    for (int i = 1; i <= n; ++i) {
        if (me.find(i) != me.end()) {
            ans = ans == -1 || dist[ans] > dist[i] ? i : ans;
        }
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int T, sz, ans, node;
    for (cin >> T; T-- > 0;) {
        cin >> n;
        g.assign(n+1, vector<int>());
        for (int i = 0, u, v; i < n-1; ++i) {
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        cin >> sz;
        me.clear();
        for (int i = 0, v; i < sz; ++i) {
            cin >> v;
            me.insert(v);
        }
        cin >> sz;
        lichen.clear();
        for (int i = 0, v; i < sz; ++i) {
            cin >> v;
            lichen.insert(v);
        }
        cout << "B " << *lichen.begin() << endl;
        cout.flush();
        cin >> ans;
        node = bfs(ans);
        cout << "A " << node << endl;
        cout.flush();
        cin >> ans;
        cout << "C " << (lichen.find(ans) == lichen.end() ? -1 : node) << endl;
        cout.flush();
    }
}


#include <bits/stdc++.h>
using namespace std;

int n;
set<int> me, lichen;
vector<vector<int> > g;

int bfs(int start) {
    queue<int> q;
    q.push(start);
    vector<int> dist(n+1, -1);
    dist[start] = 0;
    while (q.size() > 0) {
        int u = q.front(); q.pop();
        for (int i = 0; i < g[u].size(); ++i) {
            if (dist[g[u][i]] == -1) {
                dist[g[u][i]] = dist[u]+1;
                q.push(g[u][i]);
            }
        }
    }
    int ans = -1;
    for (int i = 1; i <= n; ++i) {
        if (me.find(i) != me.end()) {
            ans = ans == -1 || dist[ans] > dist[i] ? i : ans;
        }
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int T, sz, ans, node;
    for (cin >> T; T-- > 0;) {
        cin >> n;
        g.assign(n+1, vector<int>());
        for (int i = 0, u, v; i < n-1; ++i) {
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        cin >> sz;
        me.clear();
        for (int i = 0, v; i < sz; ++i) {
            cin >> v;
            me.insert(v);
        }
        cin >> sz;
        lichen.clear();
        for (int i = 0, v; i < sz; ++i) {
            cin >> v;
            lichen.insert(v);
        }
        cout << "B " << *lichen.begin() << endl;
        cin >> ans;
        node = bfs(ans);
        cout << "A " << node << endl;
        cin >> ans;
        cout << "C " << (lichen.find(ans) == lichen.end() ? -1 : node) << "\n";
    }
}


#include<bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define lli long long int
#define ulli unsigned long long int
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pf pop_front()
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define loopl(i,a,b) for(lli i=a;i<b;i++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define inf 1000000000000000
#define lld long double
#define pll pair<long long int,long long int>
#define vll vector<lli>
#define eps 0.000001
//#define endl '\n'

using namespace std ;

#define MAXN 100010
//lli spf[MAXN];
//void sieve();
//set<lli> factors(lli x);
lli power(lli x,lli y,lli p);
//void getZarr(string str, lli Z[]);
//vll prefix_function(vll s);

typedef tree<lli,null_type,less<lli>,rb_tree_tag,
tree_order_statistics_node_update> indexed_set;

vll v[1001];
bool vis[1001]={0};
lli occx[1001]={0},occy[1001]={0};
lli ans=-1;

void dfs(lli q)
{
  vis[q]=1;
  if(occx[q]) {ans = q ;return ;}

  for(auto x:v[q])
  {
    if(!vis[x])
      {
        dfs(x);
        if(ans!=-1) return;
      }

  }
}

int main()
{

///////////////////////////////////////////
    fastio;
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
///////////////////////////////////////////

  lli t;
  cin>>t;
  while(t--)
  {
    loopl(i,0,1001)
    {
      v[i].clear();
      vis[i]=0;
      occx[i]=occy[i]=0;
    }

    ans = -1;

    lli n;
    cin>>n;

    loopl(i,0,n-1)
    {
      lli x,y;
      cin>>x>>y;
      v[x].pb(y);
      v[y].pb(x);
    }

    lli k1,k2;

    cin>>k1;
    lli x[k1];
    loopl(i,0,k1) {cin>>x[i]; occx[x[i]]=1;}

    cin>>k2;
    lli y[k2];
    loopl(i,0,k2) {cin>>y[i]; occy[y[i]]=1;}

    lli p;

    cout<<"B"<<" "<<y[0]<<endl;
    fflush(stdout);
    cin>>p;

    if(p==-1)
      {
        exit(0);
      }

    dfs(p);

    cout<<"A"<<" "<<ans;
    fflush(stdout);
    cin>>p;

    if(p==-1)
      {
        exit(0);
      }

    if(occy[p]) {cout<<"C "<<ans<<endl;fflush(stdout);}
    else {cout<<"C "<<-1<<endl; fflush(stdout);}

  }

}

/*vll prefix_function(vll s)
{
    lli n = (lli)s.size();
    vll pi(n);

    for (lli i = 1; i < n; i++)
    {
        lli j = pi[i-1];

        while (j > 0 && s[i] != s[j])
            j = pi[j-1];

        if (s[i] == s[j])
            j++;

        pi[i] = j;
    }
    return pi;
}
*/
/*void sieve()
{
    spf[1] = 1;
    loopl(i,2,MAXN)
        spf[i] = i;
    for (lli i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (lli i=3; i*i<MAXN; i++) {
        if (spf[i] == i) {
            for (lli j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }

}

multiset<lli> factors(lli x)
{
    multiset<lli> pr;
    while (x != 1)
    {
        pr.insert(spf[x]);
        x = x / spf[x];
    }
    return pr;
}

*/

/*
void dfs(lli q,lli root)
{
    vis[q]=1;

    ans[q]=1;

    for(auto x: v[q])
    {
        if(!vis[x])
        {
            if(a[x]==a[root] && x<root) continue;
            if(a[x]<a[root] || a[x]>a[root]+d) continue;
            dfs(x,root);
            ans[q]=(ans[q]*((ans[x]+1)%mod))%mod ;
        }
    }

}
*/

/*void getZarr(string str, lli Z[])
{
    lli n = str.length();
    lli L, R, k;
    L = R = 0;
    for (lli i = 1; i < n; ++i){
        if (i > R){
            L = R = i;
            while (R<n && str[R-L] == str[R])
                R++;
            Z[i] = R-L;
            R--;
        } else {
            k = i-L;
            if (Z[k] < R-i+1)
                Z[i] = Z[k];
            else {
                L = i;
                while (R<n && str[R-L] == str[R])
                    R++;
                Z[i] = R-L;
                R--;
            }
        }
    }
}

*/

lli power(lli x, lli y, lli p)
{
    lli res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}


#include<bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define lli long long int
#define ulli unsigned long long int
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pf pop_front()
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define loopl(i,a,b) for(lli i=a;i<b;i++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define inf 1000000000000000
#define lld long double
#define pll pair<long long int,long long int>
#define vll vector<lli>
#define eps 0.000001
//#define endl '\n'

using namespace std ;

#define MAXN 100010
//lli spf[MAXN];
//void sieve();
//set<lli> factors(lli x);
lli power(lli x,lli y,lli p);
//void getZarr(string str, lli Z[]);
//vll prefix_function(vll s);

typedef tree<lli,null_type,less<lli>,rb_tree_tag,
tree_order_statistics_node_update> indexed_set;

vll v[1001];
bool vis[1001]={0};
lli occx[1001]={0},occy[1001]={0};
lli ans=-1;

void dfs(lli q)
{
  vis[q]=1;
  if(occx[q]) {ans = q ;return ;}

  for(auto x:v[q])
  {
    if(!vis[x])
      {
        dfs(x);
        if(ans!=-1) return;
      }

  }
}

int main()
{

///////////////////////////////////////////
    fastio;
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
///////////////////////////////////////////

  lli t;
  cin>>t;
  while(t--)
  {
    loopl(i,0,1001)
    {
      v[i].clear();
      vis[i]=0;
      occx[i]=occy[i]=0;
    }

    ans = -1;

    lli n;
    cin>>n;

    loopl(i,0,n-1)
    {
      lli x,y;
      cin>>x>>y;
      v[x].pb(y);
      v[y].pb(x);
    }

    lli k1,k2;

    cin>>k1;
    lli x[k1];
    loopl(i,0,k1) {cin>>x[i]; occx[x[i]]=1;}

    cin>>k2;
    lli y[k2];
    loopl(i,0,k2) {cin>>y[i]; occy[y[i]]=1;}

    lli p;

    cout<<"B"<<" "<<y[0]<<endl;
    cout.flush();
    cin>>p;

    if(p==-1)
      {
        exit(0);
      }

    dfs(p);

    cout<<"A"<<" "<<ans;
    cout.flush();
    cin>>p;

    if(p==-1)
      {
        exit(0);
      }

    if(occy[p]) {cout<<"C "<<ans<<endl;cout.flush();}
    else {cout<<"C "<<-1<<endl; cout.flush();}

  }

}

/*vll prefix_function(vll s)
{
    lli n = (lli)s.size();
    vll pi(n);

    for (lli i = 1; i < n; i++)
    {
        lli j = pi[i-1];

        while (j > 0 && s[i] != s[j])
            j = pi[j-1];

        if (s[i] == s[j])
            j++;

        pi[i] = j;
    }
    return pi;
}
*/
/*void sieve()
{
    spf[1] = 1;
    loopl(i,2,MAXN)
        spf[i] = i;
    for (lli i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (lli i=3; i*i<MAXN; i++) {
        if (spf[i] == i) {
            for (lli j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }

}

multiset<lli> factors(lli x)
{
    multiset<lli> pr;
    while (x != 1)
    {
        pr.insert(spf[x]);
        x = x / spf[x];
    }
    return pr;
}

*/

/*
void dfs(lli q,lli root)
{
    vis[q]=1;

    ans[q]=1;

    for(auto x: v[q])
    {
        if(!vis[x])
        {
            if(a[x]==a[root] && x<root) continue;
            if(a[x]<a[root] || a[x]>a[root]+d) continue;
            dfs(x,root);
            ans[q]=(ans[q]*((ans[x]+1)%mod))%mod ;
        }
    }

}
*/

/*void getZarr(string str, lli Z[])
{
    lli n = str.length();
    lli L, R, k;
    L = R = 0;
    for (lli i = 1; i < n; ++i){
        if (i > R){
            L = R = i;
            while (R<n && str[R-L] == str[R])
                R++;
            Z[i] = R-L;
            R--;
        } else {
            k = i-L;
            if (Z[k] < R-i+1)
                Z[i] = Z[k];
            else {
                L = i;
                while (R<n && str[R-L] == str[R])
                    R++;
                Z[i] = R-L;
                R--;
            }
        }
    }
}

*/

lli power(lli x, lli y, lli p)
{
    lli res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}


#include<bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define lli long long int
#define ulli unsigned long long int
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pf pop_front()
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define loopl(i,a,b) for(lli i=a;i<b;i++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define inf 1000000000000000
#define lld long double
#define pll pair<long long int,long long int>
#define vll vector<lli>
#define eps 0.000001
//#define endl '\n'

using namespace std ;

#define MAXN 100010
//lli spf[MAXN];
//void sieve();
//set<lli> factors(lli x);
lli power(lli x,lli y,lli p);
//void getZarr(string str, lli Z[]);
//vll prefix_function(vll s);

typedef tree<lli,null_type,less<lli>,rb_tree_tag,
tree_order_statistics_node_update> indexed_set;

vll v[1001];
bool vis[1001]={0};
lli occx[1001]={0},occy[1001]={0};
lli ans=-1;

void dfs(lli q)
{
  vis[q]=1;
  if(occx[q]) {ans = q ;return ;}

  for(auto x:v[q])
  {
    if(!vis[x])
      {
        dfs(x);
        if(ans!=-1) return;
      }

  }
}

int main()
{

///////////////////////////////////////////
    fastio;
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
///////////////////////////////////////////

  lli t;
  cin>>t;
  while(t--)
  {
    loopl(i,0,1001)
    {
      v[i].clear();
      vis[i]=0;
      occx[i]=occy[i]=0;
    }

    ans = -1;

    lli n;
    cin>>n;

    loopl(i,0,n-1)
    {
      lli x,y;
      cin>>x>>y;
      v[x].pb(y);
      v[y].pb(x);
    }

    lli k1,k2;

    cin>>k1;
    lli x[k1];
    loopl(i,0,k1) {cin>>x[i]; occx[x[i]]=1;}

    cin>>k2;
    lli y[k2];
    loopl(i,0,k2) {cin>>y[i]; occy[y[i]]=1;}

    lli p;

    cout<<"B"<<" "<<y[0]<<endl;
    fflush(stdout);
    cin>>p;

    if(p==-1)
      {
        exit(0);
      }

    dfs(p);

    cout<<"A"<<" "<<ans<<endl;
    fflush(stdout);
    cin>>p;

    if(p==-1)
      {
        exit(0);
      }

    if(occy[p]) {cout<<"C "<<ans<<endl;fflush(stdout);}
    else {cout<<"C "<<-1<<endl; fflush(stdout);}

  }

}

/*vll prefix_function(vll s)
{
    lli n = (lli)s.size();
    vll pi(n);

    for (lli i = 1; i < n; i++)
    {
        lli j = pi[i-1];

        while (j > 0 && s[i] != s[j])
            j = pi[j-1];

        if (s[i] == s[j])
            j++;

        pi[i] = j;
    }
    return pi;
}
*/
/*void sieve()
{
    spf[1] = 1;
    loopl(i,2,MAXN)
        spf[i] = i;
    for (lli i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (lli i=3; i*i<MAXN; i++) {
        if (spf[i] == i) {
            for (lli j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }

}

multiset<lli> factors(lli x)
{
    multiset<lli> pr;
    while (x != 1)
    {
        pr.insert(spf[x]);
        x = x / spf[x];
    }
    return pr;
}

*/

/*
void dfs(lli q,lli root)
{
    vis[q]=1;

    ans[q]=1;

    for(auto x: v[q])
    {
        if(!vis[x])
        {
            if(a[x]==a[root] && x<root) continue;
            if(a[x]<a[root] || a[x]>a[root]+d) continue;
            dfs(x,root);
            ans[q]=(ans[q]*((ans[x]+1)%mod))%mod ;
        }
    }

}
*/

/*void getZarr(string str, lli Z[])
{
    lli n = str.length();
    lli L, R, k;
    L = R = 0;
    for (lli i = 1; i < n; ++i){
        if (i > R){
            L = R = i;
            while (R<n && str[R-L] == str[R])
                R++;
            Z[i] = R-L;
            R--;
        } else {
            k = i-L;
            if (Z[k] < R-i+1)
                Z[i] = Z[k];
            else {
                L = i;
                while (R<n && str[R-L] == str[R])
                    R++;
                Z[i] = R-L;
                R--;
            }
        }
    }
}

*/

lli power(lli x, lli y, lli p)
{
    lli res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}


#include<bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define lli long long int
#define ulli unsigned long long int
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pf pop_front()
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define loopl(i,a,b) for(lli i=a;i<b;i++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define inf 1000000000000000
#define lld long double
#define pll pair<long long int,long long int>
#define vll vector<lli>
#define eps 0.000001
//#define endl '\n'

using namespace std ;

#define MAXN 100010
//lli spf[MAXN];
//void sieve();
//set<lli> factors(lli x);
lli power(lli x,lli y,lli p);
//void getZarr(string str, lli Z[]);
//vll prefix_function(vll s);

typedef tree<lli,null_type,less<lli>,rb_tree_tag,
tree_order_statistics_node_update> indexed_set;

vll v[1001];
bool vis[1001]={0};
lli occx[1001]={0},occy[1001]={0};
lli ans=-1;

void dfs(lli q)
{
  vis[q]=1;
  if(occx[q]) {ans = q ;return ;}

  for(auto x:v[q])
  {
    if(!vis[x])
      {
        dfs(x);
        if(ans!=-1) return;
      }

  }
}

int main()
{

///////////////////////////////////////////
    fastio;
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
///////////////////////////////////////////

  lli t;
  cin>>t;
  while(t--)
  {
    loopl(i,0,1001)
    {
      v[i].clear();
      vis[i]=0;
    }

    ans = -1;

    lli n;
    cin>>n;

    lli k1,k2;

    cin>>k1;
    lli x[k1];
    loopl(i,0,k1) {cin>>x[i]; occx[x[i]]=1;}

    cin>>k2;
    lli y[k2];
    loopl(i,0,k2) {cin>>y[i]; occy[y[i]]=1;}

    lli p;

    cout<<"B"<<" "<<y[0]<<endl;
    cout.flush();
    cin>>p;

    dfs(p);

    cout<<"A"<<" "<<ans;
    cout.flush();
    cin>>p;

    if(occy[p]) cout<<"C "<<ans<<endl;
    else cout<<"C "<<-1<<endl;
    cout.flush();

  }

}

/*vll prefix_function(vll s)
{
    lli n = (lli)s.size();
    vll pi(n);

    for (lli i = 1; i < n; i++)
    {
        lli j = pi[i-1];

        while (j > 0 && s[i] != s[j])
            j = pi[j-1];

        if (s[i] == s[j])
            j++;

        pi[i] = j;
    }
    return pi;
}
*/
/*void sieve()
{
    spf[1] = 1;
    loopl(i,2,MAXN)
        spf[i] = i;
    for (lli i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (lli i=3; i*i<MAXN; i++) {
        if (spf[i] == i) {
            for (lli j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }

}

multiset<lli> factors(lli x)
{
    multiset<lli> pr;
    while (x != 1)
    {
        pr.insert(spf[x]);
        x = x / spf[x];
    }
    return pr;
}

*/

/*
void dfs(lli q,lli root)
{
    vis[q]=1;

    ans[q]=1;

    for(auto x: v[q])
    {
        if(!vis[x])
        {
            if(a[x]==a[root] && x<root) continue;
            if(a[x]<a[root] || a[x]>a[root]+d) continue;
            dfs(x,root);
            ans[q]=(ans[q]*((ans[x]+1)%mod))%mod ;
        }
    }

}
*/

/*void getZarr(string str, lli Z[])
{
    lli n = str.length();
    lli L, R, k;
    L = R = 0;
    for (lli i = 1; i < n; ++i){
        if (i > R){
            L = R = i;
            while (R<n && str[R-L] == str[R])
                R++;
            Z[i] = R-L;
            R--;
        } else {
            k = i-L;
            if (Z[k] < R-i+1)
                Z[i] = Z[k];
            else {
                L = i;
                while (R<n && str[R-L] == str[R])
                    R++;
                Z[i] = R-L;
                R--;
            }
        }
    }
}

*/

lli power(lli x, lli y, lli p)
{
    lli res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}


#include<bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define lli long long int
#define ulli unsigned long long int
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pf pop_front()
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define loopl(i,a,b) for(lli i=a;i<b;i++)
#define loop(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define inf 1000000000000000
#define lld long double
#define pll pair<long long int,long long int>
#define vll vector<lli>
#define eps 0.000001
//#define endl '\n'

using namespace std ;

#define MAXN 100010
//lli spf[MAXN];
//void sieve();
//set<lli> factors(lli x);
lli power(lli x,lli y,lli p);
//void getZarr(string str, lli Z[]);
//vll prefix_function(vll s);

typedef tree<lli,null_type,less<lli>,rb_tree_tag,
tree_order_statistics_node_update> indexed_set;

vll v[1001];
bool vis[1001]={0};
lli occx[1001]={0},occy[1001]={0};
lli ans=-1;

void dfs(lli q)
{
  vis[q]=1;
  if(occx[q]) {ans = q ;return ;}

  for(auto x:v[q])
  {
    if(!vis[x])
      {
        dfs(x);
        if(ans!=-1) return;
      }

  }
}

int main()
{

///////////////////////////////////////////
    fastio;
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif
///////////////////////////////////////////

  lli t;
  cin>>t;
  while(t--)
  {
    loopl(i,0,1001)
    {
      v[i].clear();
      vis[i]=0;
      occx[i]=occy[i]=0;
    }

    ans = -1;

    lli n;
    cin>>n;

    loopl(i,0,n-1)
    {
      lli x,y;
      cin>>x>>y;
      v[x].pb(y);
      v[y].pb(x);
    }

    lli k1,k2;

    cin>>k1;
    lli x[k1];
    loopl(i,0,k1) {cin>>x[i]; occx[x[i]]=1;}

    cin>>k2;
    lli y[k2];
    loopl(i,0,k2) {cin>>y[i]; occy[y[i]]=1;}

    lli p;

    cout<<"B"<<" "<<y[0]<<endl;
    cout.flush();
    cin>>p;

    dfs(p);

    cout<<"A"<<" "<<ans;
    cout.flush();
    cin>>p;

    if(occy[p]) cout<<"C "<<ans<<endl;
    else cout<<"C "<<-1<<endl;
    cout.flush();

  }

}

/*vll prefix_function(vll s)
{
    lli n = (lli)s.size();
    vll pi(n);

    for (lli i = 1; i < n; i++)
    {
        lli j = pi[i-1];

        while (j > 0 && s[i] != s[j])
            j = pi[j-1];

        if (s[i] == s[j])
            j++;

        pi[i] = j;
    }
    return pi;
}
*/
/*void sieve()
{
    spf[1] = 1;
    loopl(i,2,MAXN)
        spf[i] = i;
    for (lli i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (lli i=3; i*i<MAXN; i++) {
        if (spf[i] == i) {
            for (lli j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }

}

multiset<lli> factors(lli x)
{
    multiset<lli> pr;
    while (x != 1)
    {
        pr.insert(spf[x]);
        x = x / spf[x];
    }
    return pr;
}

*/

/*
void dfs(lli q,lli root)
{
    vis[q]=1;

    ans[q]=1;

    for(auto x: v[q])
    {
        if(!vis[x])
        {
            if(a[x]==a[root] && x<root) continue;
            if(a[x]<a[root] || a[x]>a[root]+d) continue;
            dfs(x,root);
            ans[q]=(ans[q]*((ans[x]+1)%mod))%mod ;
        }
    }

}
*/

/*void getZarr(string str, lli Z[])
{
    lli n = str.length();
    lli L, R, k;
    L = R = 0;
    for (lli i = 1; i < n; ++i){
        if (i > R){
            L = R = i;
            while (R<n && str[R-L] == str[R])
                R++;
            Z[i] = R-L;
            R--;
        } else {
            k = i-L;
            if (Z[k] < R-i+1)
                Z[i] = Z[k];
            else {
                L = i;
                while (R<n && str[R-L] == str[R])
                    R++;
                Z[i] = R-L;
                R--;
            }
        }
    }
}

*/

lli power(lli x, lli y, lli p)
{
    lli res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}


#include<bits/stdc++.h>
#define REP(i,j,k) for(int i=j;i<k;++i)
#define RREP(i,j,k) for(int i=(int)j-1;i>=k;--i)
#define VIS(it,con) for(auto it=con.begin();it!=con.end();++it)
#define int long long
#define pb emplace_back
#define P pair<int,int>
#define F first
#define S second
#define sz(a) (int)(a).size()
#define MX 1005
#define oo 1e18
#define L(i) (i*2+1)
#define R(i) (i*2+2)
#define mid (l+r>>1)
#define MIN(x,y) (x=min(x,(y)))
#define MAX(x,y) (x=max(x,(y)))
#define IOS cin.tie(0) ,cout.tie(0), cout.sync_with_stdio(0)
#define getchar getchar_unlocked
//#pragma GCC optimize("O3")
using namespace std;
int t,n,a,b,c,x,y,vx[MX],vy[MX],used[MX],v;
vector<int> G[MX];
main(){
	//IOS;
	cin>>t;
	while(t--){
		cin>>n;
		REP(i,1,n+1) G[i].clear(),vx[i] = vy[i] = used[i] = 0;
		REP(i,0,n-1){
			cin>>a>>b;
			G[a].pb(b);
			G[b].pb(a);
		}
		cin>>x;
		REP(i,0,x) cin>>a,vx[a] = 1;
		cin>>y;
		REP(i,0,y) cin>>a,vy[a] = 1;
		cout<<"B "<<a<<"\n";
		cin>>c;
		queue<int> q;
		q.push(c); used[c] = 1;
		while(q.size()){
			v = q.front(); q.pop();
			if(vx[v]) break;
			for(auto u:G[v])
				if(!used[u]) q.push(u),used[u] = 1;
		}
		cout<<"A "<<v<<"\n";
		cin>>c;
		if(vy[c]) cout<<"C "<<v<<"\n";
		else cout<<"C -1\n";
	}
}


#include<bits/stdc++.h>
#define REP(i,j,k) for(int i=j;i<k;++i)
#define RREP(i,j,k) for(int i=(int)j-1;i>=k;--i)
#define VIS(it,con) for(auto it=con.begin();it!=con.end();++it)
#define int long long
#define pb emplace_back
#define P pair<int,int>
#define F first
#define S second
#define sz(a) (int)(a).size()
#define MX 1005
#define oo 1e18
#define L(i) (i*2+1)
#define R(i) (i*2+2)
#define mid (l+r>>1)
#define MIN(x,y) (x=min(x,(y)))
#define MAX(x,y) (x=max(x,(y)))
#define IOS cin.tie(0) ,cout.tie(0), cout.sync_with_stdio(0)
#define getchar getchar_unlocked
//#pragma GCC optimize("O3")
using namespace std;
int t,n,a,b,c,x,y,vx[MX],vy[MX],used[MX],v;
vector<int> G[MX];
main(){
	IOS;
	cin>>t;
	while(t--){
		cin>>n;
		REP(i,1,n+1) G[i].clear(),vx[i] = vy[i] = used[i] = 0;
		REP(i,0,n-1){
			cin>>a>>b;
			G[a].pb(b);
			G[b].pb(a);
		}
		cin>>x;
		REP(i,0,x) cin>>a,vx[a] = 1;
		cin>>y;
		REP(i,0,y) cin>>a,vy[a] = 1;
		cout<<"B "<<vy[0]<<"\n";
		cin>>c;
		queue<int> q;
		q.push(c); used[c] = 1;
		while(q.size()){
			v = q.front(); q.pop();
			if(vx[v]) break;
			for(auto u:G[v])
				if(!used[u]) q.push(u),used[u] = 1;
		}
		cout<<"A "<<v<<"\n";
		cin>>c;
		if(vy[c]) cout<<"C "<<v<<"\n";
		else cout<<"C -1\n";
	}
}


#include <bits/stdc++.h>
using namespace std;
const int limN = 1005;

int query(int tp, int pos) {
    printf("%c %d\n", tp + 'A', pos);
    if(tp != 2) {
        int N; scanf("%d", &N);
        if(N == -1) {
            exit(0);
        }
        return N ;
    }
    return 0 ;
}

vector <int> adj[limN];
bool inA[limN], inB[limN];

int closestA(int pos, int pv = -1) {
    if(inA[pos]) return pos;
    int ans ;
    for(const int sig : adj[pos])
        if(sig != pv) {
            ans = closestA(sig);
            if(ans != -1)
                return ans;
        }
    return -1;
}

void testCase() {
    memset(inA, 0, sizeof(inA));
    memset(inB, 0, sizeof(inB));
    int N ;
    int X, Y ;

    scanf("%d", &N);
    for(int i=1, a, b; i<N; i++) {
        scanf("%d%d", &a, &b);
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    scanf("%d", &X);
    for(int i=0, a; i<X; i++) {
        scanf("%d", &a);
        inA[a] = true;
    }
    scanf("%d", &Y);
    for(int i=0, a; i<Y; i++) {
        scanf("%d", &a);
        inB[a] = true;
    }

    int p = -1;
    for(int i=1; i<=N; i++) {
        if(!inB[i]) continue;
        p = closestA(query(1, i));
        break;
    }

    int w = query(0, p);
    query(2, inB[w]? p : -1);

    for(int i=1; i<=N; i++)
        adj[i].clear();
}

int main() {
    int tc;
    scanf("%d", &tc);
    for(int i=0; i<tc; i++)
        testCase();
}


#include <bits/stdc++.h>
using namespace std;
const int limN = 1005;

int query(int tp, int pos) {
    printf("%c %d\n", tp + 'A', pos);
    fflush(stdout);
    if(tp != 2) {
        int N; scanf("%d", &N);
        if(N == -1) {
            exit(0);
        }
        return N ;
    }
    return 0 ;
}

vector <int> adj[limN];
bool inA[limN], inB[limN];

int closestA(int pos, int pv = -1) {
    if(inA[pos]) return pos;
    int ans ;
    for(const int sig : adj[pos])
        if(sig != pv) {
            ans = closestA(sig, pos);
            if(ans != -1)
                return ans;
        }
    return -1;
}

void testCase() {
    memset(inA, 0, sizeof(inA));
    memset(inB, 0, sizeof(inB));
    int N ;
    int X, Y ;

    scanf("%d", &N);
    for(int i=1, a, b; i<N; i++) {
        scanf("%d%d", &a, &b);
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    scanf("%d", &X);
    for(int i=0, a; i<X; i++) {
        scanf("%d", &a);
        inA[a] = true;
    }
    scanf("%d", &Y);
    for(int i=0, a; i<Y; i++) {
        scanf("%d", &a);
        inB[a] = true;
    }

    int p = -1;
    for(int i=1; i<=N; i++) {
        if(!inB[i]) continue;
        p = closestA(query(1, i));
        break;
    }

    int w = query(0, p);
    query(2, inB[w]? p : -1);

    for(int i=1; i<=N; i++)
        adj[i].clear();
}

int main() {
    int tc;
    scanf("%d", &tc);
    for(int i=0; i<tc; i++)
        testCase();
}


#include <bits/stdc++.h>
using namespace std;
const int limN = 1005;

int query(int tp, int pos) {
    printf("%c %d\n", tp + 'A', pos);
    fflush(stdout);
    if(tp != 2) {
        int N; scanf("%d", &N);
        if(N == -1) {
            exit(0);
        }
        return N ;
    }
    return 0 ;
}

vector <int> adj[limN];
bool inA[limN], inB[limN];

int closestA(int pos, int pv = -1) {
    if(inA[pos]) return pos;
    int ans ;
    for(const int sig : adj[pos])
        if(sig != pv) {
            ans = closestA(sig);
            if(ans != -1)
                return ans;
        }
    return -1;
}

void testCase() {
    memset(inA, 0, sizeof(inA));
    memset(inB, 0, sizeof(inB));
    int N ;
    int X, Y ;

    scanf("%d", &N);
    for(int i=1, a, b; i<N; i++) {
        scanf("%d%d", &a, &b);
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    scanf("%d", &X);
    for(int i=0, a; i<X; i++) {
        scanf("%d", &a);
        inA[a] = true;
    }
    scanf("%d", &Y);
    for(int i=0, a; i<Y; i++) {
        scanf("%d", &a);
        inB[a] = true;
    }

    int p = -1;
    for(int i=1; i<=N; i++) {
        if(!inB[i]) continue;
        p = closestA(query(1, i));
        break;
    }

    int w = query(0, p);
    query(2, inB[w]? p : -1);

    for(int i=1; i<=N; i++)
        adj[i].clear();
}

int main() {
    int tc;
    scanf("%d", &tc);
    for(int i=0; i<tc; i++)
        testCase();
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<unordered_set>
#include<map>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<cassert>
#include<sstream>
#include<random>
#include<deque>
#include<set>
#include<unordered_map>
#include<list>

#define int long long int

using namespace std;

const int maxLog = 30;

int n;
vector<vector<int>> g;
vector<int> x, y, tin, tout;
vector<vector<int>> dp;
int timer = 0;

void dfs(int v = 0, int p = -1) {
    tin[v] = timer++;
    for (auto to : g[v]) {
        if (to == p) continue;
        dp[to][0] = v;
        dfs(to, v);
    }
    tout[v] = timer++;
}

void init(int root) {
    timer = 0;
    tin.assign(n, 0);
    tout.assign(n, 0);
    dp.assign(n, vector<int>(maxLog, root));
    dfs(root);
    for (int p = 1; p < maxLog; ++p) {
        for (int v = 0; v < n; ++v) {
            dp[v][p] = dp[dp[v][p - 1]][p - 1];
        }
    }
}

bool isAncestor(int a, int b) {
    return tin[a] <= tin[b] && tout[a] >= tout[b];
}

int LCA(int a, int b) {
    if (isAncestor(a, b)) return a;
    if (isAncestor(b, a)) return b;
    for (int p = maxLog - 1; p >= 0; --p) {
        if (!isAncestor(dp[a][p], b)) {
            a = dp[a][p];
        }
    }
    return dp[a][0];
}

int A(int x) {
    cout << "A " << x << endl;
    int y; cin >> y;
    return y;
}

int B(int y) {
    cout << "B " << y << endl;
    int x; cin >> x;
    return x;
}

void solve() {
    cin >> n;
    g.assign(n, {});
    for (int i = 1; i < n; ++i) {
        int a, b; cin >> a >> b; --a; --b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    int k1; cin >> k1;
    x.assign(k1, 0);
    for (int i = 0; i < k1; ++i) {
        cin >> x[i];
        --x[i];
    }
    int k2; cin >> k2;
    y.assign(k2, 0);
    for (int i = 0; i < k2; ++i) {
        cin >> y[i];
        --y[i];
    }
    int root = B(y[0] + 1) - 1;
    init(root);
    int RA = x[0];
    for (int i = 1; i < k1; ++i) RA = LCA(RA, x[i]);
    int v = A(RA + 1) - 1;
    auto it = find(y.begin(), y.end(), v);
    if (it != y.end()) cout << "C " << RA + 1 << endl;
    else cout << "C " << -1 << endl;
}

signed main() {
    int t; cin >> t;
    while (t--) solve();
    return 0;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<unordered_set>
#include<map>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<cassert>
#include<sstream>
#include<random>
#include<deque>
#include<set>
#include<unordered_map>
#include<list>

#define int long long int

using namespace std;

const int maxLog = 30;

int n;
vector<vector<int>> g;
vector<int> x, y, tin, tout;
vector<vector<int>> dp;
int timer = 0;

void dfs(int v = 0, int p = -1) {
    tin[v] = timer++;
    for (auto to : g[v]) {
        if (to == p) continue;
        dp[to][0] = v;
        dfs(to, v);
    }
    tout[v] = timer++;
}

void init(int root) {
    timer = 0;
    tin.assign(n, 0);
    tout.assign(n, 0);
    dp.assign(n, vector<int>(maxLog, root));
    dfs(root);
    for (int p = 1; p < maxLog; ++p) {
        for (int v = 0; v < n; ++v) {
            dp[v][p] = dp[dp[v][p - 1]][p - 1];
        }
    }
}

bool isAncestor(int a, int b) {
    return tin[a] <= tin[b] && tout[a] >= tout[b];
}

int LCA(int a, int b) {
    if (isAncestor(a, b)) return a;
    if (isAncestor(b, a)) return b;
    for (int p = maxLog - 1; p >= 0; --p) {
        if (!isAncestor(dp[a][p], b)) {
            a = dp[a][p];
        }
    }
    return dp[a][0];
}

int A(int x) {
    cout << "A " << x << endl;
    int y; cin >> y;
    return y;
}

int B(int y) {
    cout << "B " << y << endl;
    int x; cin >> x;
    return x;
}

void solve() {
    cin >> n;
    g.assign(n, {});
    for (int i = 1; i < n; ++i) {
        int a, b; cin >> a >> b; --a; --b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    int k1; cin >> k1;
    x.assign(k1, 0);
    for (int i = 0; i < k1; ++i) {
        cin >> x[i];
        --x[i];
    }
    int k2; cin >> k2;
    y.assign(k2, 0);
    for (int i = 0; i < k2; ++i) {
        cin >> y[i];
        --y[i];
    }
    int root = B(y[0] + 1) - 1;
    init(root);
    int RA = x[0];
    for (int i = 1; i < k1; ++i) RA = LCA(RA, x[i]);
    int v = A(RA + 1) - 1;
    auto it = find(y.begin(), y.end(), v);
    if (it != y.end()) cout << "C " << RA + 1 << endl;
    else cout << -1 << endl;
}

signed main() {
    int t; cin >> t;
    while (t--) solve();
    return 0;
}


#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<unordered_set>
#include<map>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<cassert>
#include<sstream>
#include<random>
#include<deque>
#include<set>
#include<unordered_map>
#include<list>

#define int long long int

using namespace std;

const int maxLog = 30;

int n;
vector<vector<int>> g;
vector<int> x, y, tin, tout;
vector<vector<int>> dp;
int timer = 0;

void dfs(int v = 0, int p = -1) {
    tin[v] = timer++;
    for (auto to : g[v]) {
        if (to == p) continue;
        dp[to][0] = v;
        dfs(to, v);
    }
    tout[v] = timer++;
}

void init(int root) {
    timer = 0;
    tin.assign(n, 0);
    tout.assign(n, 0);
    dp.assign(n, vector<int>(maxLog, root));
    dfs(root);
    for (int p = 1; p < maxLog; ++p) {
        for (int v = 0; v < n; ++v) {
            dp[v][p] = dp[dp[v][p - 1]][p - 1];
        }
    }
}

bool isAncestor(int a, int b) {
    return tin[a] <= tin[b] && tout[a] >= tout[b];
}

int LCA(int a, int b) {
    if (isAncestor(a, b)) return a;
    if (isAncestor(b, a)) return b;
    for (int p = maxLog - 1; p >= 0; --p) {
        if (!isAncestor(dp[a][p], b)) {
            a = dp[a][p];
        }
    }
    return dp[a][0];
}

int A(int x) {
    cout << "A " << x << endl;
    int y; cin >> y;
    return y;
}

int B(int y) {
    cout << "B " << y << endl;
    int x; cin >> x;
    return x;
}

signed main() {
    cin >> n;
    g.resize(n);
    for (int i = 1; i < n; ++i) {
        int a, b; cin >> a >> b; --a; --b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    int k1; cin >> k1;
    x.resize(k1);
    for (int i = 0; i < k1; ++i) {
        cin >> x[i];
        --x[i];
    }
    int k2; cin >> k2;
    y.resize(k2);
    for (int i = 0; i < k2; ++i) {
        cin >> y[i];
        --y[i];
    }
    int root = B(y[0] + 1) - 1;
    init(root);
    int RA = x[0];
    for (int i = 1; i < k1; ++i) RA = LCA(RA, x[i]);
    int v = A(RA + 1) - 1;
    auto it = find(y.begin(), y.end(), v);
    if (it != y.end()) cout << "C " << RA + 1 << endl;
    else cout << -1 << endl;
    return 0;
}


#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <set>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

std::ifstream get_file_input() {
    std::ifstream ifs;
    ifs.open("input.txt");
    //std::ifstream ifs ("input.txt", std::ifstream::in);
    std::ios_base::sync_with_stdio(false);
    ifs.tie(nullptr);
    return ifs;
}

std::istream& get_standard_input() {
    std::istream &input = std::cin;
    std::ios_base::sync_with_stdio(false);
    input.tie(nullptr);
    return input;
}

struct vertice {
    vector<int> childs;
    int parent;
    bool is_in_my;
};

vector<vertice> vertices;
vector<vector<int>> edges;
vector<int> xes;
vector<int> yes;
int n;

void build_tree(int now, int parent) {
    for (auto next : edges[now]) {
        if (next != parent) {
            build_tree(next, now);
            vertices[now].childs.push_back(next);
        }
    }
    vertices[now].parent = parent;
}

int prepare(std::istream& input) {
    input >> n;
    edges = vector<vector<int>>(n);
    vertices = vector<vertice>(n);
    for (int i = 0; i < n; ++i) {
        vertices[i].is_in_my = false;
    }
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        input >> a >> b;
        --a;
        --b;
        edges[a].push_back(b);
        edges[b].push_back(a);
    }

    int k1;
    xes = vector<int>(0);
    input >> k1;
    for (int i = 0; i < k1; ++i) {
        int x;
        input >> x;
        --x;
        vertices[x].is_in_my = true;
        xes.push_back(x);
    }

    int k2;
    yes = vector<int>(0);
    input >> k2;
    for (int i = 0; i < k2; ++i) {
        int y;
        input >> y;
        --y;
        yes.push_back(y);
    }

    int root = xes[0];
    build_tree(root, -1);
    return root;
}

int request_B(std::istream& input, int y) {
    cout << "B " << y + 1 << '\n';
    cout.flush();
    int my_numeration;
    input >> my_numeration;
    --my_numeration;
    return my_numeration;
}

int request_A(std::istream& input, int x) {
    cout << "A " << x + 1 << '\n';
    cout.flush();
    int his_numeration;
    input >> his_numeration;
    --his_numeration;
    return his_numeration;
}

int up_until_good(int num) {
    if (vertices[num].is_in_my) {
        return true;
    }
    return up_until_good(vertices[num].parent);
}

vector<int> rollout_up(int num) {
    if (num == -1) {
        return vector<int>(0);
    }

    auto ans = rollout_up(vertices[num].parent);
    ans.push_back(num);
    return ans;
}

int get_common_parent(int first, int second) {
    auto first_rollout = rollout_up(first);
    auto second_rollout = rollout_up(second);
    int min = std::min(first_rollout.size(), second_rollout.size());
    int ans = first_rollout[0];
    for (int i = 0; i < min; ++i) {
        if (first_rollout[i] == second_rollout[i]) {
            ans = first_rollout[i];
        }
    }
    return ans;
}

int main()
{
    //std::ifstream input = get_file_input();
    std::istream& input = get_standard_input();
    int t;
    input >> t;
    for (int test_num = 0; test_num < t; ++test_num) {
        int root = prepare(input);
        int k1 = xes.size();
        int k2 = yes.size();
        if (k2 == 1) {
            int my_numeration_0 = request_B(input, yes[0]);
            bool good = false;
            for (int i = 0; i < xes.size(); ++i) {
                if (xes[i] == my_numeration_0) {
                    cout << "C " << xes[i] << '\n';
                    cout.flush();
                    good = true;
                    break;
                }
            }
            if (good == false) {
                cout << -1 << '\n';
                cout.flush();
            }
            continue;
        }
        int first = request_B(input, yes[0]);
        int second = request_B(input, yes[1]);
        bool good = false;
        int common_parent = get_common_parent(first, second);
        for (int i = 0; i < xes.size(); ++i) {
            if (xes[i] == common_parent) {
                cout << "C " << xes[i] << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good) {
            continue;
        }

        good = false;
        int first_good = up_until_good(common_parent);
        int his_numeration = request_A(input, first_good);
        for (int i = 0; i < yes.size(); ++i) {
            if (yes[i] == his_numeration) {
                cout << "C " << first_good << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good == false) {
            cout << -1 << '\n';
            cout.flush();
        }
    }
}


#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <set>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

std::ifstream get_file_input() {
    std::ifstream ifs;
    ifs.open("input.txt");
    //std::ifstream ifs ("input.txt", std::ifstream::in);
    std::ios_base::sync_with_stdio(false);
    ifs.tie(nullptr);
    return ifs;
}

std::istream& get_standard_input() {
    std::istream &input = std::cin;
    std::ios_base::sync_with_stdio(false);
    input.tie(nullptr);
    return input;
}

struct vertice {
    vector<int> childs;
    int parent;
    bool is_in_my;
};

vector<vertice> vertices;
vector<vector<int>> edges;
vector<int> xes;
vector<int> yes;
int n;

void build_tree(int now, int parent) {
    for (auto next : edges[now]) {
        if (next != parent) {
            build_tree(next, now);
            vertices[now].childs.push_back(next);
        }
    }
    vertices[now].parent = parent;
}

int prepare(std::istream& input) {
    input >> n;
    edges = vector<vector<int>>(n);
    vertices = vector<vertice>(n);
    for (int i = 0; i < n; ++i) {
        vertices[i].is_in_my = false;
    }
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        input >> a >> b;
        --a;
        --b;
        edges[a].push_back(b);
        edges[b].push_back(a);
    }

    int k1;
    xes = vector<int>(0);
    input >> k1;
    for (int i = 0; i < k1; ++i) {
        int x;
        input >> x;
        --x;
        vertices[x].is_in_my = true;
        xes.push_back(x);
    }

    int k2;
    yes = vector<int>(0);
    input >> k2;
    for (int i = 0; i < k2; ++i) {
        int y;
        input >> y;
        --y;
        yes.push_back(y);
    }

    int root = xes[0];
    build_tree(root, -1);
    return root;
}

int request_B(std::istream& input, int y) {
    cout << "B " << y + 1 << '\n';
    cout.flush();
    int my_numeration;
    input >> my_numeration;
    --my_numeration;
    return my_numeration;
}

int request_A(std::istream& input, int x) {
    cout << "A " << x + 1 << '\n';
    cout.flush();
    int his_numeration;
    input >> his_numeration;
    --his_numeration;
    return his_numeration;
}

int up_until_good(int num) {
    if (vertices[num].is_in_my) {
        return true;
    }
    return up_until_good(vertices[num].parent);
}

vector<int> rollout_up(int num) {
    if (num == -1) {
        return vector<int>(0);
    }

    auto ans = rollout_up(vertices[num].parent);
    ans.push_back(num);
    return ans;
}

int get_common_parent(int first, int second) {
    auto first_rollout = rollout_up(first);
    auto second_rollout = rollout_up(second);
    int min = std::min(first_rollout.size(), second_rollout.size());
    int ans = first_rollout[0];
    for (int i = 0; i < min; ++i) {
        if (first_rollout[i] == second_rollout[i]) {
            ans = first_rollout[i];
        }
    }
    return ans;
}

int main()
{
    //std::ifstream input = get_file_input();
    std::istream& input = get_standard_input();
    int t;
    input >> t;
    for (int test_num = 0; test_num < t; ++test_num) {
        int root = prepare(input);
        int k1 = xes.size();
        int k2 = yes.size();
        if (k2 == 1) {
            int my_numeration_0 = request_B(input, yes[0]);
            bool good = false;
            for (int i = 0; i < xes.size(); ++i) {
                if (xes[i] == my_numeration_0) {
                    cout << "C " << xes[i] + 1 << '\n';
                    cout.flush();
                    good = true;
                    break;
                }
            }
            if (good == false) {
                cout << -1 << '\n';
                cout.flush();
            }
            continue;
        }
        int first = request_B(input, yes[0]);
        int second = request_B(input, yes[1]);
        bool good = false;
        int common_parent = get_common_parent(first, second);
        for (int i = 0; i < xes.size(); ++i) {
            if (xes[i] == common_parent) {
                cout << "C " << xes[i] + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good) {
            continue;
        }

        good = false;
        int first_good = up_until_good(common_parent);
        int his_numeration = request_A(input, first_good);
        for (int i = 0; i < yes.size(); ++i) {
            if (yes[i] == his_numeration) {
                cout << "C " << first_good + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good == false) {
            cout << -1 << '\n';
            cout.flush();
        }
    }
}


#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <set>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

std::ifstream get_file_input() {
    std::ifstream ifs;
    ifs.open("input.txt");
    //std::ifstream ifs ("input.txt", std::ifstream::in);
    std::ios_base::sync_with_stdio(false);
    ifs.tie(nullptr);
    return ifs;
}

std::istream& get_standard_input() {
    std::istream &input = std::cin;
    std::ios_base::sync_with_stdio(false);
    input.tie(nullptr);
    return input;
}

struct vertice {
    vector<int> childs;
    int parent;
    bool is_in_my;
};

vector<vertice> vertices;
vector<vector<int>> edges;
vector<int> xes;
vector<int> yes;
int n;

void build_tree(int now, int parent) {
    for (auto next : edges[now]) {
        if (next != parent) {
            build_tree(next, now);
            vertices[now].childs.push_back(next);
        }
    }
    vertices[now].parent = parent;
}

int prepare(std::istream& input) {
    input >> n;
    edges = vector<vector<int>>(n);
    vertices = vector<vertice>(n);
    for (int i = 0; i < n; ++i) {
        vertices[i].is_in_my = false;
    }
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        input >> a >> b;
        --a;
        --b;
        edges[a].push_back(b);
        edges[b].push_back(a);
    }

    int k1;
    xes = vector<int>(0);
    input >> k1;
    for (int i = 0; i < k1; ++i) {
        int x;
        input >> x;
        --x;
        vertices[x].is_in_my = true;
        xes.push_back(x);
    }

    int k2;
    yes = vector<int>(0);
    input >> k2;
    for (int i = 0; i < k2; ++i) {
        int y;
        input >> y;
        --y;
        yes.push_back(y);
    }

    int root = xes[0];
    build_tree(root, -1);
    return root;
}

int request_B(std::istream& input, int y) {
    cout << "B " << y + 1 << '\n';
    cout.flush();
    int my_numeration;
    input >> my_numeration;
    --my_numeration;
    return my_numeration;
}

int request_A(std::istream& input, int x) {
    cout << "A " << x + 1 << '\n';
    cout.flush();
    int his_numeration;
    input >> his_numeration;
    --his_numeration;
    return his_numeration;
}

int up_until_good(int num) {
    if (vertices[num].is_in_my) {
        return true;
    }
    return up_until_good(vertices[num].parent);
}

vector<int> rollout_up(int num) {
    if (num == -1) {
        return vector<int>(0);
    }

    auto ans = rollout_up(vertices[num].parent);
    ans.push_back(num);
    return ans;
}

int get_common_parent(int first, int second) {
    auto first_rollout = rollout_up(first);
    auto second_rollout = rollout_up(second);
    int min = std::min(first_rollout.size(), second_rollout.size());
    int ans = first_rollout[0];
    for (int i = 0; i < min; ++i) {
        if (first_rollout[i] == second_rollout[i]) {
            ans = first_rollout[i];
        }
    }
    return ans;
}

int main()
{
    //std::ifstream input = get_file_input();
    std::istream& input = get_standard_input();
    int t;
    input >> t;
    cout.flush();
    for (int test_num = 0; test_num < t; ++test_num) {
        int root = prepare(input);
        int k1 = xes.size();
        int k2 = yes.size();
        if (k2 == 1) {
            int my_numeration_0 = request_B(input, yes[0]);
            bool good = false;
            for (int i = 0; i < xes.size(); ++i) {
                if (xes[i] == my_numeration_0) {
                    cout << "C " << xes[i] + 1 << '\n';
                    cout.flush();
                    good = true;
                    break;
                }
            }
            if (good == false) {
                cout << "C " << -1 << '\n';
                cout.flush();
            }
            continue;
        }
        cout << "I am there";
        int first = request_B(input, yes[0]);
        int second = request_B(input, yes[1]);
        bool good = false;
        int common_parent = get_common_parent(first, second);
        for (int i = 0; i < xes.size(); ++i) {
            if (xes[i] == common_parent) {
                cout << "C " << xes[i] + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good) {
            continue;
        }

        good = false;
        int first_good = up_until_good(common_parent);
        int his_numeration = request_A(input, first_good);
        for (int i = 0; i < yes.size(); ++i) {
            if (yes[i] == his_numeration) {
                cout << "C " << first_good + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good == false) {
            cout << "C " << -1 << '\n';
            cout.flush();
        }
    }
}


#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <set>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

std::ifstream get_file_input() {
    std::ifstream ifs;
    ifs.open("input.txt");
    //std::ifstream ifs ("input.txt", std::ifstream::in);
    std::ios_base::sync_with_stdio(false);
    ifs.tie(nullptr);
    return ifs;
}

std::istream& get_standard_input() {
    std::istream &input = std::cin;
    std::ios_base::sync_with_stdio(false);
    input.tie(nullptr);
    return input;
}

struct vertice {
    vector<int> childs;
    int parent;
    bool is_in_my;
};

vector<vertice> vertices;
vector<vector<int>> edges;
vector<int> xes;
vector<int> yes;
int n;

void build_tree(int now, int parent) {
    for (auto next : edges[now]) {
        if (next != parent) {
            build_tree(next, now);
            vertices[now].childs.push_back(next);
        }
    }
    vertices[now].parent = parent;
}

int prepare(std::istream& input) {
    input >> n;
    edges = vector<vector<int>>(n);
    vertices = vector<vertice>(n);
    for (int i = 0; i < n; ++i) {
        vertices[i].is_in_my = false;
    }
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        input >> a >> b;
        --a;
        --b;
        edges[a].push_back(b);
        edges[b].push_back(a);
    }

    int k1;
    xes = vector<int>(0);
    input >> k1;
    for (int i = 0; i < k1; ++i) {
        int x;
        input >> x;
        --x;
        vertices[x].is_in_my = true;
        xes.push_back(x);
    }

    int k2;
    yes = vector<int>(0);
    input >> k2;
    for (int i = 0; i < k2; ++i) {
        int y;
        input >> y;
        --y;
        yes.push_back(y);
    }

    int root = xes[0];
    build_tree(root, -1);
    return root;
}

int request_B(std::istream& input, int y) {
    cout << "B " << y + 1 << '\n';
    cout.flush();
    int my_numeration;
    input >> my_numeration;
    --my_numeration;
    return my_numeration;
}

int request_A(std::istream& input, int x) {
    cout << "A " << x + 1 << '\n';
    cout.flush();
    int his_numeration;
    input >> his_numeration;
    --his_numeration;
    return his_numeration;
}

int up_until_good(int num) {
    if (vertices[num].is_in_my) {
        return true;
    }
    return up_until_good(vertices[num].parent);
}

vector<int> rollout_up(int num) {
    if (num == -1) {
        return vector<int>(0);
    }

    auto ans = rollout_up(vertices[num].parent);
    ans.push_back(num);
    return ans;
}

int get_common_parent(int first, int second) {
    auto first_rollout = rollout_up(first);
    auto second_rollout = rollout_up(second);
    int min = std::min(first_rollout.size(), second_rollout.size());
    int ans = first_rollout[0];
    for (int i = 0; i < min; ++i) {
        if (first_rollout[i] == second_rollout[i]) {
            ans = first_rollout[i];
        }
    }
    return ans;
}

int main()
{
    //std::ifstream input = get_file_input();
    std::istream& input = get_standard_input();
    int t;
    input >> t;
    cout.flush();
    for (int test_num = 0; test_num < t; ++test_num) {
        int root = prepare(input);
        int k1 = xes.size();
        int k2 = yes.size();
        if (k2 == 1) {
            int my_numeration_0 = request_B(input, yes[0]);
            bool good = false;
            for (int i = 0; i < xes.size(); ++i) {
                if (xes[i] == my_numeration_0) {
                    cout << "C " << xes[i] + 1 << '\n';
                    cout.flush();
                    good = true;
                    break;
                }
            }
            if (good == false) {
                cout << "C " << -1 << '\n';
                cout.flush();
            }
            continue;
        }
        int first = request_B(input, yes[0]);
        int second = request_B(input, yes[1]);
        bool good = false;
        int common_parent = get_common_parent(first, second);
        for (int i = 0; i < xes.size(); ++i) {
            if (xes[i] == common_parent) {
                cout << "C " << xes[i] + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good) {
            continue;
        }

        good = false;
        int first_good = up_until_good(common_parent);
        int his_numeration = request_A(input, first_good);
        for (int i = 0; i < yes.size(); ++i) {
            if (yes[i] == his_numeration) {
                cout << "C " << first_good + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good == false) {
            cout << "C " << -1 << '\n';
            cout.flush();
        }
    }
}


#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <set>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

std::ifstream get_file_input() {
    std::ifstream ifs;
    ifs.open("input.txt");
    //std::ifstream ifs ("input.txt", std::ifstream::in);
    std::ios_base::sync_with_stdio(false);
    ifs.tie(nullptr);
    return ifs;
}

std::istream& get_standard_input() {
    std::istream &input = std::cin;
    std::ios_base::sync_with_stdio(false);
    input.tie(nullptr);
    return input;
}

struct vertice {
    vector<int> childs;
    int parent;
    bool is_in_my;
};

vector<vertice> vertices;
vector<vector<int>> edges;
vector<int> xes;
vector<int> yes;
int n;

void build_tree(int now, int parent) {
    for (auto next : edges[now]) {
        if (next != parent) {
            build_tree(next, now);
            vertices[now].childs.push_back(next);
        }
    }
    vertices[now].parent = parent;
}

int prepare(std::istream& input) {
    input >> n;
    edges = vector<vector<int>>(n);
    vertices = vector<vertice>(n);
    for (int i = 0; i < n; ++i) {
        vertices[i].is_in_my = false;
    }
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        input >> a >> b;
        --a;
        --b;
        edges[a].push_back(b);
        edges[b].push_back(a);
    }

    int k1;
    xes = vector<int>(0);
    input >> k1;
    for (int i = 0; i < k1; ++i) {
        int x;
        input >> x;
        --x;
        vertices[x].is_in_my = true;
        xes.push_back(x);
    }

    int k2;
    yes = vector<int>(0);
    input >> k2;
    for (int i = 0; i < k2; ++i) {
        int y;
        input >> y;
        --y;
        yes.push_back(y);
    }

    int root = xes[0];
    build_tree(root, -1);
    return root;
}

int request_B(std::istream& input, int y) {
    cout << "B " << y + 1 << '\n';
    cout.flush();
    int my_numeration;
    input >> my_numeration;
    --my_numeration;
    return my_numeration;
}

int request_A(std::istream& input, int x) {
    cout << "A " << x + 1 << '\n';
    cout.flush();
    int his_numeration;
    input >> his_numeration;
    --his_numeration;
    return his_numeration;
}

int up_until_good(int num) {
    if (vertices[num].is_in_my) {
        return num;
    }
    return up_until_good(vertices[num].parent);
}

vector<int> rollout_up(int num) {
    if (num == -1) {
        return vector<int>(0);
    }

    auto ans = rollout_up(vertices[num].parent);
    ans.push_back(num);
    return ans;
}

int get_common_parent(int first, int second) {
    auto first_rollout = rollout_up(first);
    auto second_rollout = rollout_up(second);
    int min = std::min(first_rollout.size(), second_rollout.size());
    int ans = first_rollout[0];
    for (int i = 0; i < min; ++i) {
        if (first_rollout[i] == second_rollout[i]) {
            ans = first_rollout[i];
        }
    }
    return ans;
}

int main()
{
    //std::ifstream input = get_file_input();
    std::istream& input = get_standard_input();
    int t;
    input >> t;
    cout.flush();
    for (int test_num = 0; test_num < t; ++test_num) {
        int root = prepare(input);
        int k1 = xes.size();
        int k2 = yes.size();
        if (k2 == 1) {
            int my_numeration_0 = request_B(input, yes[0]);
            bool good = false;
            for (int i = 0; i < xes.size(); ++i) {
                if (xes[i] == my_numeration_0) {
                    cout << "C " << xes[i] + 1 << '\n';
                    cout.flush();
                    good = true;
                    break;
                }
            }
            if (good == false) {
                cout << "C " << -1 << '\n';
                cout.flush();
            }
            continue;
        }

        int first = request_B(input, yes[0]);
        int second = request_B(input, yes[1]);
        bool good = false;
        int common_parent = get_common_parent(first, second);
        for (int i = 0; i < xes.size(); ++i) {
            if (xes[i] == common_parent) {
                cout << "C " << xes[i] + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good) {
            continue;
        }

        good = false;
        int first_good = up_until_good(common_parent);
        int his_numeration = request_A(input, first_good);
        for (int i = 0; i < yes.size(); ++i) {
            if (yes[i] == his_numeration) {
                cout << "C " << first_good + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good == false) {
            cout << "C " << -1 << '\n';
            cout.flush();
        }
    }
}


#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <functional>
#include <algorithm>
#include <set>
#include <cstring>
#include <queue>
#include <map>

using namespace std;

std::ifstream get_file_input() {
    std::ifstream ifs;
    ifs.open("input.txt");
    //std::ifstream ifs ("input.txt", std::ifstream::in);
    std::ios_base::sync_with_stdio(false);
    ifs.tie(nullptr);
    return ifs;
}

std::istream& get_standard_input() {
    std::istream &input = std::cin;
    std::ios_base::sync_with_stdio(false);
    input.tie(nullptr);
    return input;
}

struct vertice {
    vector<int> childs;
    int parent;
    bool is_in_my;
};

vector<vertice> vertices;
vector<vector<int>> edges;
vector<int> xes;
vector<int> yes;
int n;

void build_tree(int now, int parent) {
    for (auto next : edges[now]) {
        if (next != parent) {
            build_tree(next, now);
            vertices[now].childs.push_back(next);
        }
    }
    vertices[now].parent = parent;
}

int prepare(std::istream& input) {
    input >> n;
    edges = vector<vector<int>>(n);
    vertices = vector<vertice>(n);
    for (int i = 0; i < n; ++i) {
        vertices[i].is_in_my = false;
    }
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        input >> a >> b;
        --a;
        --b;
        edges[a].push_back(b);
        edges[b].push_back(a);
    }

    int k1;
    xes = vector<int>(0);
    input >> k1;
    for (int i = 0; i < k1; ++i) {
        int x;
        input >> x;
        --x;
        vertices[x].is_in_my = true;
        xes.push_back(x);
    }

    int k2;
    yes = vector<int>(0);
    input >> k2;
    for (int i = 0; i < k2; ++i) {
        int y;
        input >> y;
        --y;
        yes.push_back(y);
    }

    int root = xes[0];
    build_tree(root, -1);
    return root;
}

int request_B(std::istream& input, int y) {
    cout << "B " << y + 1 << '\n';
    cout.flush();
    int my_numeration;
    input >> my_numeration;
    --my_numeration;
    return my_numeration;
}

int request_A(std::istream& input, int x) {
    cout << "A " << x + 1 << '\n';
    cout.flush();
    int his_numeration;
    input >> his_numeration;
    --his_numeration;
    return his_numeration;
}

int up_until_good(int num) {
    if (vertices[num].is_in_my) {
        return true;
    }
    return up_until_good(vertices[num].parent);
}

vector<int> rollout_up(int num) {
    if (num == -1) {
        return vector<int>(0);
    }

    auto ans = rollout_up(vertices[num].parent);
    ans.push_back(num);
    return ans;
}

int get_common_parent(int first, int second) {
    auto first_rollout = rollout_up(first);
    auto second_rollout = rollout_up(second);
    int min = std::min(first_rollout.size(), second_rollout.size());
    int ans = first_rollout[0];
    for (int i = 0; i < min; ++i) {
        if (first_rollout[i] == second_rollout[i]) {
            ans = first_rollout[i];
        }
    }
    return ans;
}

int main()
{
    //std::ifstream input = get_file_input();
    std::istream& input = get_standard_input();
    int t;
    input >> t;
    for (int test_num = 0; test_num < t; ++test_num) {
        int root = prepare(input);
        int k1 = xes.size();
        int k2 = yes.size();
        if (k2 == 1) {
            int my_numeration_0 = request_B(input, yes[0]);
            bool good = false;
            for (int i = 0; i < xes.size(); ++i) {
                if (xes[i] == my_numeration_0) {
                    cout << "C " << xes[i] + 1 << '\n';
                    cout.flush();
                    good = true;
                    break;
                }
            }
            if (good == false) {
                cout << "C " << -1 << '\n';
                cout.flush();
            }
            continue;
        }
        int first = request_B(input, yes[0]);
        int second = request_B(input, yes[1]);
        bool good = false;
        int common_parent = get_common_parent(first, second);
        for (int i = 0; i < xes.size(); ++i) {
            if (xes[i] == common_parent) {
                cout << "C " << xes[i] + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good) {
            continue;
        }

        good = false;
        int first_good = up_until_good(common_parent);
        int his_numeration = request_A(input, first_good);
        for (int i = 0; i < yes.size(); ++i) {
            if (yes[i] == his_numeration) {
                cout << "C " << first_good + 1 << '\n';
                cout.flush();
                good = true;
                break;
            }
        }
        if (good == false) {
            cout << "C " << -1 << '\n';
            cout.flush();
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

const int MAXSIZE = 1000 + 5;
typedef vector<int> vi;
typedef unordered_map<int, vi> mivi;
typedef pair<int, int> ii;
mivi graph;
vi subgA, subgB;
int n;
int inquire(char tree, int index) {
	printf("%c %d\n", tree, index);
	fflush(stdout);
	int res;
	scanf("%d", &res);
	if (res == -1) exit(0);
	return res;
}

vi BFS(int source) {
	queue<ii> q;
	bool explored[MAXSIZE];
	explored[source] = true;
	q.push({ 0, source});
	vi res;
	bool done = false;
	while (!q.empty()) {
		ii item = q.front();q.pop();
		for (auto i : graph[item.second]) {
			if (explored[i]) continue;
			if (subgA[i]) {
				res.push_back(i);
				done = true;
			}
			q.push({ item.first, i});
		}
		if (done) break;
	}
	return res;
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		graph.clear();
		scanf("%d", &n);
		for (int i = 0; i < n - 1; i++ ) {
			int a, b;
			scanf("%d %d", &a, &b);
			graph[a].push_back(b);
			graph[b].push_back(a);
		}
		int k1, k2;
		cin >> k1;
		subgA.assign(n + 1, 0);
		for (int i = 0; i < k1; i++) {
			int temp;
			scanf("%d", &temp);
			subgA[temp]  = 1;
		}
		cin >> k2;
		int startB  = -1;
		subgB.assign(n + 1, 0);
		for (int i = 0; i < k2; i++) {
			int temp;
			scanf("%d", &temp);
			if (startB == -1) startB = temp;
			subgB[temp]  = 1;
		}
		int start = inquire('B', startB);
		if (subgA[start]) {
			printf("C %d\n", start);
			fflush(stdout);
		} else {
			bool can = false;
			vi checkVertices = BFS(start);
			for (auto i : checkVertices) {
				cout << i << endl;
				if (subgB[inquire('A', i)]) {
					printf("C %d\n", i);
					fflush(stdout);
					can = true;
					break;
				}
			}
			if (!can) {
				printf("C -1\n");
				fflush(stdout);
			}
		}

	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXSIZE = 1000 + 5;
typedef vector<int> vi;
typedef unordered_map<int, vi> mivi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
mivi graph;
vi subgA, subgB;
int n;

int inquire(char tree, int index) {
	printf("%c %d\n", tree, index);
	fflush(stdout);
	int res;
	scanf("%d", &res);
	if (res == -1) exit(0);
	return res;
}

vii BFS(int source) {
	queue<ii> q;
	bool explored[MAXSIZE] = { false };
	explored[source] = true;
	q.push({ 0, source});
	vii res;
	bool done = false;
	while (!q.empty()) {
		ii item = q.front();q.pop();
		explored[item.second] = true;
		for (auto i : graph[item.second]) {
			if (explored[i]) continue;
			if (subgA[i]) {
				res.push_back({ item.first + 1, i });
			}
			q.push({ item.first + 1, i});
		}
	}
	return res;
}
int main() {
	int t;
	scanf("%d", &t);
	while(t--) {
		graph.clear();
		scanf("%d", &n);
		for (int i = 0; i < n - 1; i++ ) {
			int a, b;
			scanf("%d %d", &a, &b);
			graph[a].push_back(b);
			graph[b].push_back(a);
		}

		int k1, k2;
		scanf("%d", &k1);
		subgA.assign(n + 1, 0);
		for (int i = 0; i < k1; i++) {
			int temp;
			scanf("%d", &temp);
			subgA[temp]  = 1;
		}
		scanf("%d", &k2);
		int startB  = -1;
		subgB.assign(n + 1, 0);
		for (int i = 0; i < k2; i++) {
			int temp;
			scanf("%d", &temp);
			if (startB == -1) startB = temp;
			subgB[temp]  = 1;
		}

		int start = inquire('B', startB);
		if (subgA[start]) {
			printf("C %d\n", start);
			fflush(stdout);
		} else {
			bool can = false;
			vii checkVertices = BFS(start);
			int MIN = -1;
			for (auto i : checkVertices) {
				int weight = i.first, idx = i.second;
				if (MIN == -1) MIN = weight;
				if (weight > MIN) break;
				int ans = inquire('A', idx);

				if (subgB[ans]) {
					printf("C %d\n", idx);
					fflush(stdout);
					can = true;
					break;
				}
			}
			if (!can) {
				printf("C -1\n");
				fflush(stdout);
			}
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXSIZE = 1000 + 5;
typedef vector<int> vi;
typedef unordered_map<int, vi> mivi;
typedef pair<int, int> ii;
mivi graph;
vi subgA, subgB;
int n;
int inquire(char tree, int index) {
	printf("%c %d\n", tree, index);
	int res;
	scanf("%d", &res);
	if (res == -1) exit(0);
	fflush(stdout);
	return res;
}

vi BFS(int source) {
	queue<ii> q;
	bool explored[MAXSIZE];
	explored[source] = true;
	q.push({ 0, source});
	vi res;
	bool done = false;
	while (!q.empty()) {
		ii item = q.front();q.pop();
		for (auto i : graph[item.second]) {
			if (explored[i]) continue;
			if (subgA[i]) {
				res.push_back(i);
				done = true;
			}
			q.push({ item.first, i});
		}
		if (done) break;
	}
	return res;
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		graph.clear();
		scanf("%d", &n);
		for (int i = 0; i < n - 1; i++ ) {
			int a, b;
			scanf("%d %d", &a, &b);
			graph[a].push_back(b);
			graph[b].push_back(a);
		}
		int k1, k2;
		cin >> k1;
		subgA.assign(n + 1, 0);
		for (int i = 0; i < k1; i++) {
			int temp;
			scanf("%d", &temp);
			subgA[temp]  = 1;
		}
		cin >> k2;
		int startB  = -1;
		subgB.assign(n + 1, 0);
		for (int i = 0; i < k2; i++) {
			int temp;
			scanf("%d", &temp);
			if (startB == -1) startB = temp;
			subgB[temp]  = 1;
		}
		int start = inquire('B', startB);
		if (subgA[start]) {
			printf("C %d\n", start);
		} else {
			vi checkVertices = BFS(start);
			for (auto i : checkVertices) {
				cout << i << endl;
				if (subgB[inquire('A', i)]) {
					printf("C %d\n", i);
					break;
				}
			}
		}

		fflush(stdout);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int MAXSIZE = 1000 + 5;
typedef vector<int> vi;
typedef unordered_map<int, vi> mivi;
typedef pair<int, int> ii;
mivi graph;
vi subgA, subgB;
int n;
int inquire(char tree, int index) {
	printf("%c %d\n", tree, index);
	fflush(stdout);
	int res;
	scanf("%d", &res);
	if (res == -1) exit(0);
	return res;
}

vi BFS(int source) {
	queue<ii> q;
	bool explored[MAXSIZE];
	explored[source] = true;
	q.push({ 0, source});
	vi res;
	bool done = false;
	while (!q.empty()) {
		ii item = q.front();q.pop();
		for (auto i : graph[item.second]) {
			if (explored[i]) continue;
			if (subgA[i]) {
				res.push_back(i);
				done = true;
			}
			q.push({ item.first, i});
		}
		if (done) break;
	}
	return res;
}
int main() {
	int t;
	cin >> t;
	while(t--) {
		graph.clear();
		scanf("%d", &n);
		for (int i = 0; i < n - 1; i++ ) {
			int a, b;
			scanf("%d %d", &a, &b);
			graph[a].push_back(b);
			graph[b].push_back(a);
		}
		int k1, k2;
		cin >> k1;
		subgA.assign(n + 1, 0);
		for (int i = 0; i < k1; i++) {
			int temp;
			scanf("%d", &temp);
			subgA[temp]  = 1;
		}
		cin >> k2;
		int startB  = -1;
		subgB.assign(n + 1, 0);
		for (int i = 0; i < k2; i++) {
			int temp;
			scanf("%d", &temp);
			if (startB == -1) startB = temp;
			subgB[temp]  = 1;
		}
		int start = inquire('B', startB);
		if (subgA[start]) {
			printf("C %d\n", start);
			fflush(stdout);
		} else {
			bool can = false;
			vi checkVertices = BFS(start);
			for (auto i : checkVertices) {
				if (subgB[inquire('A', i)]) {
					printf("C %d\n", i);
					fflush(stdout);
					can = true;
					break;
				}
			}
			if (!can) {
				printf("C -1\n");
				fflush(stdout);
			}
		}

	}
	return 0;
}


#include <bits/stdc++.h>
#define FI(_n) for(int i = 0;i<(_n);i++)
#define FJ(_n) for(int j = 0;j<(_n);j++)
#define pb push_back
#define all(c) c.begin(),c.end()
using namespace std;
typedef long long ll;
const ll INF = 1e18 + 1;
int n;
vector< vector<int> > g;
vector<int> x,y;
vector<int> a;
int k1,k2;
int f;
vector<bool> used;
map<int, int> faf;
int mn, mni;
void dfs(int v, int gl)
{
    bool flag = 0;
    FI(k1) if(v == x[k1]) flag = 1;
    if(flag && mn>gl)
    {
        mn = gl;
        mni = v;
    }
    used[v] = 1;
    FI(g[v].size())
    {
        if(!used[g[v][i]])
            dfs(g[v][i], gl + 1);
    }
}
int main()
{
    ios_base::sync_with_stdio(0);
//    ifstream cin("input.txt");
 //   ofstream cout("output.txt");
    //cin.tie(0);cout.tie(0);

    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        faf.clear();
        a.resize(n);
        FI(n)
        {
            cin>>a[i];
            a[i]--;
            faf[i] = a[i];
        }
        g.resize(n);
        used.resize(n,0);
        FI(n-1)
        {
            int x,y;
            cin>>x>>y;
            --x;--y;
            int x1 = faf[x],y1 = faf[y];
            g[x1].pb(y1);
            g[y1].pb(x1);

        }
        cin>>k1;
        x.resize(k1);
        FI(k1)
        {
            cin>>x[i];
            x[i]--;
        }
        cin>>k2;
        y.resize(k2);
        FI(k2)
        {
            cin>>y[i];
            y[i]--;
        }
        cout<<"B "<<y[0]+1<<"\n";
        cin>>f;
        f--;
        mn = INT_MAX;
        dfs(f, 0);
        cout<<"A "<<mni+1<<"\n";
        int c;
        cin>>c;
        c--;
        bool flag = 0;
        FI(k2) if(y[i] == c)
        {
            cout<<"C "<<mni+1<<"\n";
            break;
        }
        cout<<"C -1"<<"\n";
    }

//    cin.close();
 //  cout.close();
    return 0;
}