Problem: The country Treeland consists of n cities connected with n - 1 bidirectional roads in such a way that it's possible to reach every city starting from any other city using these roads. There will be a soccer championship next year, and all participants are Santa Clauses. There are exactly 2k teams from 2k different cities.

During the first stage all teams are divided into k pairs. Teams of each pair play two games against each other: one in the hometown of the first team, and the other in the hometown of the other team. Thus, each of the 2k cities holds exactly one soccer game. However, it's not decided yet how to divide teams into pairs.

It's also necessary to choose several cities to settle players in. Organizers tend to use as few cities as possible to settle the teams.

Nobody wants to travel too much during the championship, so if a team plays in cities u and v, it wants to live in one of the cities on the shortest path between u and v (maybe, in u or in v). There is another constraint also: the teams from one pair must live in the same city.

Summarizing, the organizers want to divide 2k teams into pairs and settle them in the minimum possible number of cities m in such a way that teams from each pair live in the same city which lies between their hometowns.

Input

The first line of input contains two integers n and k (2 ≤ n ≤ 2·105, 2 ≤ 2k ≤ n) — the number of cities in Treeland and the number of pairs of teams, respectively.

The following n - 1 lines describe roads in Treeland: each of these lines contains two integers a and b (1 ≤ a, b ≤ n, a ≠ b) which mean that there is a road between cities a and b. It's guaranteed that there is a path between any two cities.

The last line contains 2k distinct integers c1, c2, ..., c2k (1 ≤ ci ≤ n), where ci is the hometown of the i-th team. All these numbers are distinct.

Output

The first line of output must contain the only positive integer m which should be equal to the minimum possible number of cities the teams can be settled in.

The second line should contain m distinct numbers d1, d2, ..., dm (1 ≤ di ≤ n) denoting the indices of the cities where the teams should be settled.

The k lines should follow, the j-th of them should contain 3 integers uj, vj and xj, where uj and vj are the hometowns of the j-th pair's teams, and xj is the city they should live in during the tournament. Each of the numbers c1, c2, ..., c2k should occur in all uj's and vj's exactly once. Each of the numbers xj should belong to {d1, d2, ..., dm}.

If there are several possible answers, print any of them.

Example

Input

6 2
1 2
1 3
2 4
2 5
3 6
2 5 4 6


Output

1
2
5 4 2
6 2 2

Note

In the first test the orginizers can settle all the teams in the city number 2. The way to divide all teams into pairs is not important, since all requirements are satisfied anyway, because the city 2 lies on the shortest path between every two cities from {2, 4, 5, 6}.

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.io.BufferedWriter;
import java.util.AbstractCollection;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jialin Ouyang (Jialin.Ouyang@gmail.com)
 */
public class Main {
  public static void main(String[] args) {
    InputStream inputStream = System.in;
    OutputStream outputStream = System.out;
    QuickScanner in = new QuickScanner(inputStream);
    QuickWriter out = new QuickWriter(outputStream);
    TaskF solver = new TaskF();
    solver.solve(1, in, out);
    out.close();
  }

  static class TaskF {
    int n;
    int m;
    int m2;
    Tree tree;
    boolean[] hasFriend;
    int[] parent;
    int[] size;
    IntArrayList resX;
    IntArrayList resY;
    IntArrayList resD;

    public void solve(int testNumber, QuickScanner in, QuickWriter out) {
      n = in.nextInt();
      m = in.nextInt();
      m2 = m << 1;
      tree = new Tree(n);
      for (int i = 1; i < n; ++i) {
        tree.add(in.nextInt() - 1, in.nextInt() - 1);
      }
      hasFriend = new boolean[n];
      for (int i = 0; i < m2; ++i) {
        hasFriend[in.nextInt() - 1] = true;
      }
      int root = calcRoot();
      out.println(1);
      out.println(root + 1);
      resX = new IntArrayList(m);
      resY = new IntArrayList(m);
      resD = new IntArrayList(m);
      PriorityQueue<IntArrayList> heap = new PriorityQueue<>(n, (l1, l2) -> l2.size - l1.size);
      for (int edgeIdx = tree.lastOut(root); edgeIdx >= 0; edgeIdx = tree.nextOut(edgeIdx)) {
        IntArrayList lst = new IntArrayList();
        dfs(tree.toIdx(edgeIdx), root, lst);
        if (!lst.isEmpty()) heap.add(lst);
      }
      while (heap.size() >= 2) {
        IntArrayList x = heap.poll();
        IntArrayList y = heap.poll();
        addResult(x.pollLast(), y.pollLast(), root);
        if (!x.isEmpty()) heap.add(x);
        if (!y.isEmpty()) heap.add(y);
      }
      if (hasFriend[root]) {
        if (heap.isEmpty()) throw new IllegalArgumentException();
        addResult(root, heap.peek().peekLast(), root);
      } else {
        if (!heap.isEmpty()) throw new IllegalArgumentException();
      }
      for (int i = 0; i < resX.size; ++i) {
        out.println(resX.get(i) + 1, resY.get(i) + 1, resD.get(i) + 1);
      }
    }

    int calcRoot() {
      parent = new int[n];
      size = new int[n];
      dfsRoot(0, -1);
      for (int u = 0; u < n; ++u) {
        int cnt = m2 - size[u];
        if (cnt > m) continue;
        for (int edgeIdx = tree.lastOut(u); edgeIdx >= 0; edgeIdx = tree.nextOut(edgeIdx)) {
          int v = tree.toIdx(edgeIdx);
          if (parent[u] == v) continue;
          cnt = Math.max(cnt, size[v]);
          if (cnt > m) break;
        }
        if (cnt <= m) return u;
      }
      throw new IllegalArgumentException();
    }

    void dfsRoot(int u, int parent) {
      this.parent[u] = parent;
      size[u] = hasFriend[u] ? 1 : 0;
      for (int edgeIdx = tree.lastOut(u); edgeIdx >= 0; edgeIdx = tree.nextOut(edgeIdx)) {
        int v = tree.toIdx(edgeIdx);
        if (v == parent) continue;
        dfsRoot(v, u);
        size[u] += size[v];
      }
    }

    void dfs(int u, int parent, IntArrayList lst) {
      if (hasFriend[u]) {
        lst.add(u);
      }
      for (int edgeIdx = tree.lastOut(u); edgeIdx >= 0; edgeIdx = tree.nextOut(edgeIdx)) {
        int v = tree.toIdx(edgeIdx);
        if (v == parent) continue;
        dfs(v, u, lst);
      }
    }

    void addResult(int x, int y, int d) {
      resX.add(x);
      resY.add(y);
      resD.add(d);
    }

  }

  static interface BidirectionalGraphInterface extends DirectedGraphInterface {
  }

  static class QuickScanner {
    private static final int BUFFER_SIZE = 1024;
    private InputStream stream;
    private byte[] buffer;
    private int currentPosition;
    private int numberOfChars;

    public QuickScanner(InputStream stream) {
      this.stream = stream;
      this.buffer = new byte[BUFFER_SIZE];
      this.currentPosition = 0;
      this.numberOfChars = 0;
    }

    public int nextInt() {
      int c = nextNonSpaceChar();
      boolean positive = true;
      if (c == '-') {
        positive = false;
        c = nextChar();
      }
      int res = 0;
      do {
        if (c < '0' || '9' < c) throw new RuntimeException();
        res = res * 10 + c - '0';
        c = nextChar();
      } while (!isSpaceChar(c));
      return positive ? res : -res;
    }

    public int nextNonSpaceChar() {
      int res = nextChar();
      for (; isSpaceChar(res) || res < 0; res = nextChar()) ;
      return res;
    }

    public int nextChar() {
      if (numberOfChars == -1) {
        throw new RuntimeException();
      }
      if (currentPosition >= numberOfChars) {
        currentPosition = 0;
        try {
          numberOfChars = stream.read(buffer);
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
        if (numberOfChars <= 0) {
          return -1;
        }
      }
      return buffer[currentPosition++];
    }

    public boolean isSpaceChar(int c) {
      return c == ' ' || c == '\t' || isEndOfLineChar(c);
    }

    public boolean isEndOfLineChar(int c) {
      return c == '\n' || c == '\r' || c < 0;
    }

  }

  static interface TreeInterface extends BidirectionalGraphInterface {
  }

  static abstract class AbstractDirectedGraph implements DirectedGraphInterface {
    protected int vertexCnt;
    protected int currentEdgeCnt;
    protected int[] fromIdx;
    protected int[] toIdx;
    protected int[] nextIn;
    protected int[] nextOut;
    protected int[] lastIn;
    protected int[] lastOut;
    protected int[] inDegree;
    protected int[] outDegree;

    public abstract void createSubclass(int vertexCapacity, int edgeCapacity);

    public abstract void initSubclass(int vertexCnt);

    public AbstractDirectedGraph(int vertexCapacity, int edgeCapacity) {
      this(vertexCapacity, edgeCapacity, true);
    }

    public AbstractDirectedGraph(int vertexCapacity, int edgeCapacity, boolean initialize) {
      fromIdx = new int[edgeCapacity];
      toIdx = new int[edgeCapacity];
      lastIn = new int[vertexCapacity];
      lastOut = new int[vertexCapacity];
      nextIn = new int[edgeCapacity];
      nextOut = new int[edgeCapacity];
      inDegree = new int[vertexCapacity];
      outDegree = new int[vertexCapacity];
      createSubclass(vertexCapacity, edgeCapacity);
      if (initialize) init(vertexCapacity);
    }


    public void init(int vertexCnt) {
      this.vertexCnt = vertexCnt;
      currentEdgeCnt = 0;
      Arrays.fill(inDegree, 0, vertexCnt, 0);
      Arrays.fill(outDegree, 0, vertexCnt, 0);
      Arrays.fill(lastIn, 0, vertexCnt, -1);
      Arrays.fill(lastOut, 0, vertexCnt, -1);
      initSubclass(vertexCnt);
    }


    public void add(int fromIdx, int toIdx) {
      this.fromIdx[currentEdgeCnt] = fromIdx;
      this.toIdx[currentEdgeCnt] = toIdx;
      ++outDegree[fromIdx];
      ++inDegree[toIdx];
      nextOut[currentEdgeCnt] = lastOut[fromIdx];
      lastOut[fromIdx] = currentEdgeCnt;
      nextIn[currentEdgeCnt] = lastIn[toIdx];
      lastIn[toIdx] = currentEdgeCnt;
      ++currentEdgeCnt;
    }


    public int toIdx(int edgeIdx) {
      return toIdx[edgeIdx];
    }


    public int lastOut(int nodeIdx) {
      return lastOut[nodeIdx];
    }


    public int nextOut(int edgeIdx) {
      return nextOut[edgeIdx];
    }

  }

  static class Tree extends AbstractTree {
    public Tree(int vertexCapacity) {
      super(vertexCapacity);
    }


    public void createSubclass(int vertexCapacity, int edgeCapacity) {
    }


    public void initSubclass(int vertexCnt) {
    }

  }

  static interface IntCollection {
    int size();

    default boolean isEmpty() {
      return size() == 0;
    }

  }

  static interface DirectedGraphInterface {
  }

  static class IntArrayUtils {
    public static String toString(int[] values, int fromIdx, int toIdx) {
      StringBuilder sb = new StringBuilder("[");
      for (int i = fromIdx; i < toIdx; ++i) {
        if (i != fromIdx) sb.append(", ");
        sb.append(values[i]);
      }
      return sb.append("]").toString();
    }

  }

  static abstract class AbstractTree extends AbstractBidirectionalGraph implements TreeInterface {
    public AbstractTree(int vertexCapacity) {
      super(vertexCapacity, vertexCapacity - 1);
    }

  }

  static class QuickWriter {
    private final PrintWriter writer;

    public QuickWriter(OutputStream outputStream) {
      this.writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public QuickWriter(Writer writer) {
      this.writer = new PrintWriter(writer);
    }

    public void print(Object... objects) {
      for (int i = 0; i < objects.length; ++i) {
        if (i > 0) {
          writer.print(' ');
        }
        writer.print(objects[i]);
      }
    }

    public void println(Object... objects) {
      print(objects);
      writer.print('\n');
    }

    public void close() {
      writer.close();
    }

  }

  static class IntArrayList implements IntCollection {
    private static int[] EMPTY = {};
    public int[] values;
    public int size;

    public IntArrayList() {
      values = EMPTY;
      clear();
    }

    public IntArrayList(int capacity) {
      values = new int[Integer.highestOneBit(capacity) << 1];
      clear();
    }


    public void clear() {
      size = 0;
    }


    public int size() {
      return size;
    }


    public void add(int value) {
      ensureCapacity(size + 1);
      values[size++] = value;
    }

    public int peekLast() {
      return values[size - 1];
    }

    public int pollLast() {
      return values[--size];
    }

    public int get(int idx) {
      if (idx >= size) throw new ArrayIndexOutOfBoundsException();
      return values[idx];
    }


    public String toString() {
      return IntArrayUtils.toString(values, 0, size);
    }

    protected void ensureCapacity(int capacity) {
      if (capacity <= values.length) return;
      int[] newValues = new int[Integer.highestOneBit(capacity) << 1];
      for (int i = 0; i < values.length; ++i) {
        newValues[i] = values[i];
      }
      values = newValues;
    }

  }

  static abstract class AbstractBidirectionalGraph extends AbstractDirectedGraph implements BidirectionalGraphInterface {
    public AbstractBidirectionalGraph(int vertexCapacity, int edgeCapacity) {
      super(vertexCapacity, edgeCapacity << 1);
    }

    public AbstractBidirectionalGraph(int vertexCapacity, int edgeCapacity, boolean initialize) {
      super(vertexCapacity, edgeCapacity << 1, initialize);
    }


    public void add(int u, int v) {
      super.add(u, v);
      super.add(v, u);
    }

  }
}