import java.util.*;
import java.io.*;

/*
If we knew how many people p[i] travelled each road i, then the answer will be (p[i]+1)%2 for each i.
How do we count how many people travelled each road?
Root the tree arbitrarily. Now each path can be described as u->lca(u,v)->v. Where lca(u,v) is the lowest common ancestor of u and v.
Therefore, each path can be decomposed into at two paths.
One that starts at u and goes up to lca(u,v), and one that starts at v and goes up to lca(u,v).
We can solve this for each edge by doing a single DFS.
Keep a value "delta" for each node.
Add 1 to delta[u] and delta[v].
Subtract 2 from delta[lca(u,v)].
In the dfs, keep track of the last used edge e.
When reaching a node n, add the values of its children, and add delta[n] to that value. Call it val.
Finally, p[e] = val.

Read more about lca: https://en.wikipedia.org/wiki/Lowest_common_ancestor
The algorithm: https://cp-algorithms.com/graph/lca_binary_lifting.html
*/
 
public class essential
{
 
	static int[] depth;
	static int[][] lift;
	static int d;
 
	static int[] delta;
 
	static ArrayList<Edge>[] graph;

	public static void main(String[] args) { // Something to set the stack size bigger on my personal computer (not needed to solve this problem)
        new Thread(null, ()->{
            try {
                A(args);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "", 1<<28).start();
    }
 
	public static void A(String[] args) throws Exception
	{
		Scanner scan = new Scanner(new File("essential.in"));
		PrintWriter out = new PrintWriter(new File("essential.out"));
		int tt = scan.nextInt();
		for(int qq = 1; qq <= tt; qq++){
			int n = scan.nextInt();
			int t = scan.nextInt();
			graph = new ArrayList[n];
			int[][] x = new int[2][n-1];
			for(int i = 0; i < n; i++) graph[i] = new ArrayList<Edge>();
			for(int i = 0; i < n-1; i++) {
				int u = scan.nextInt()-1;
				int v = scan.nextInt()-1;
				x[0][i] = u+1;
				x[1][i] = v+1;
				graph[u].add(new Edge(v, i));
				graph[v].add(new Edge(u, i));
			}
			depth = new int[n];
			d = Integer.numberOfTrailingZeros(Integer.highestOneBit(n)) + 2;
			lift = new int[d][n];
			for(int i = 0 ; i < d ; i++) Arrays.fill(lift[i], -1);
			Deque<Integer> q = new ArrayDeque<>();
			q.add(0);
			while(!q.isEmpty()) {
				int u = q.pop();
				for(Edge e : graph[u]) {
					int v = e.to;
					if(lift[0][u] != v) {
						lift[0][v] = u;
						depth[v] = depth[u] + 1;
						q.add(v);
					}
				}
			}
			for(int k = 0 ; k < d - 1 ; k++)
				for(int i = 0 ; i < n ; i++)
					if(lift[k][i] != -1)
						lift[k + 1][i] = lift[k][lift[k][i]];
	
			delta = new int[n];
			fools = new int[n-1];
			int[][] y = new int[2][t];
			for(int i = 0; i < t; i++) {
				int u = scan.nextInt()-1;
				int v = scan.nextInt()-1;
				// out.println(u+" "+v);
				y[0][i] = u+1;
				y[1][i] = v+1;
				int p = lca(u, v);
				delta[p] -= 2;
				delta[u]++;
				delta[v]++;
			}
			solve(0, -1, -1);
			for(int i = 0; i < n-1; i++) {
				out.print((fools[i]+1)%2);
			}
			out.println();
		}
		out.flush();
	}
 
	static int[] fools;
 
	static int solve(int root, int edge, int parent) {
		int cum = delta[root];
		for(int i = 0; i < graph[root].size(); i++) {
			Edge e = graph[root].get(i);
			if(e.to != parent) {
				cum += solve(e.to, e.id, root);
			}
		}
		if(edge != -1) fools[edge] = cum;
		return cum;
	}
 
	static int lca(int u, int v) {
		if(depth[v] > depth[u]) return lca(v, u);
		u = walk(u, depth[u] - depth[v]);
		if(u == v) return u;
		for(int k = d - 1 ; k >= 0 ; k--) {
			if(lift[k][u] != lift[k][v]) {
				u = lift[k][u];
				v = lift[k][v];
			}
		}
		return lift[0][u];
	}
	static int walk(int u, int k) {
		for(int i = 0 ; i < d && u != -1 ; i++) if((k & (1 << i)) > 0) u = lift[i][u];
		return u;
	}
 
	static class Edge{
 
		int to;
		int id;
 
		public Edge(int to, int id) {
			this.to = to;
			this.id = id;
		}
	}
}