#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll N=1e5+5;
ll n,m;
// 邻接表存储无向图
vector<vector<ll>>adj(N);
// 存储需要连通的m个目标节点
unordered_set<ll>s;
// BFS队列,用于层序遍历图
queue<ll>q;
// 标记节点是否已访问,避免重复遍历
vector<bool>vis(N,false);
// 存储最终选中的边(生成树的边)
vector<pair<ll,ll>>ans;
void bfs(){
// BFS核心循环:队列非空时持续遍历
while(!q.empty()){
// 取出队首节点作为当前遍历节点
ll t=q.front();
q.pop();
// 遍历当前节点的所有邻接节点
for(auto it:adj[t]){
// 仅处理未访问过的节点(避免环和重复)
if(vis[it]==false){
// 若邻接节点是目标节点(属于s集合)
if(s.find(it)!=s.end()){
// 记录这条边(当前节点 -> 目标节点)
ans.emplace_back(t,it);
// 收集到m-1条边时直接返回(生成树边数=节点数-1)
if(ans.size()==m-1){
return;
}
}
// 将邻接节点入队,继续BFS遍历
q.push(it);
// 标记为已访问,防止重复处理
vis[it]=true;
}
}
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
// 输入节点总数n、需要连通的目标节点数m
cin>>n>>m;
// 读入n-1条边,构建无向图的邻接表
for(ll i=1;i<=n-1;i++){
ll u,v;
cin>>u>>v;
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
// 读入m个目标节点,存入集合s以便快速查询
for(ll i=1;i<=m;i++){
ll t;
cin>>t;
s.insert(t);
}
// BFS初始化:从任意一个目标节点开始(选s的第一个元素)
q.push(*s.begin());
// 标记起始节点为已访问
vis[*s.begin()]=true;
// 执行BFS,收集目标节点间的连通边
bfs();
// 输出选中的边数(理论上是m-1)
cout<<ans.size()<<'\n';
// 输出每条选中的边
for(auto t:ans){
cout<<t.first<<' '<<t.second<<'\n';
}
return 0;
}