// Arup Guha
// 5/4/2020
// Alternate Solution for 2020 FHSPS Contest Problem: Essential Road Work

import java.util.*;

public class essential_arup {

	public static int n;
	public static ArrayList[] g;
	public static ArrayList[] ancestors;
	public static int[] parEdge;
	public static int[] depth;
	public static int[] score;
	public static int[] nodeScore;
	public static boolean[] res;
	
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		int nC = stdin.nextInt();

		// Process each case.
		for (int loop=0; loop<nC; loop++) {
		
			// Set up graph.
			n = stdin.nextInt();
			int numW = stdin.nextInt();
			g = new ArrayList[n];
			for (int i=0; i<n; i++) g[i] = new ArrayList<edge>();
			ancestors = new ArrayList[n];
			for (int i=0; i<n; i++) ancestors[i] = new ArrayList<Integer>();
			parEdge = new int[n];
			Arrays.fill(parEdge, -1);
			depth = new int[n];

			// Read graph.
			for (int i=0; i<n-1; i++) {
				int u = stdin.nextInt()-1;
				int v = stdin.nextInt()-1;
				g[u].add(new edge(u, v, i));
				g[v].add(new edge(v, u, i));
			}
			
			// DFS to fill in parents, parent edges.
			dfs(0,-1,0);
			
			// Will store the number of paths that start and end at each vertex.
			score = new int[n];
			
			// Go through each worker.
			for (int i=0; i<numW; i++) {
			
				// Here is their path.
				int u = stdin.nextInt()-1;
				int v = stdin.nextInt()-1;
				
				// Get the LCA.
				int mylca = lca(u, v);
				
				// Mark endpoints of path.
				score[u]++;
				score[v]++;
				
				// Neither was the LCA, so we have two paths starting from the LCA.
				if (mylca != u && mylca != v) score[mylca] += 2;
			
			} // end numw
			
			// Do one more DFS to calculate the results.
			res = new boolean[n-1];
			nodeScore = new int[n];
			fillRes(0, -1);
			
			// Output the result.
			char[] str = new char[n-1];
			Arrays.fill(str, '0');
			for (int i=0; i<n-1; i++) 
				if (res[i])
					str[i] = '1';
			System.out.println(new String(str));
		}
	}
	
	// Fills the result for each edge leaving v (except the parent link).
	public static void fillRes(int v, int par) {
	
		// We always do this.
		nodeScore[v] = score[v];
	
		// Leaf Node in tree.
		if (g[v].size() == 1 && par != -1) return;
		
		// Go through each edge from this node.
		for (edge cur: (ArrayList<edge>)g[v]) {
			int x = cur.v;
			
			// Skip the parent of course.
			if (x == par) continue;
			
			// Recurse.
			fillRes(x, v);
			
			// Now we can determine the answer for this edge. It's just the parity of 
			// the road events in this particular subtree.
			res[cur.id] = (nodeScore[x]%2 == 0);
			
			// Also, update this as we go.
			nodeScore[v] += nodeScore[x];
		}
	}
	
	// Returns the LCA of nodes u and v.
	public static int lca(int u, int v) {
	
		// Have whichever is deeper down the tree climb up to an equal level of the other.
		while (depth[v] > depth[u]) v = ((ArrayList<Integer>)ancestors[v]).get(highOneBit(depth[v]-depth[u]));
		while (depth[u] > depth[v]) u = ((ArrayList<Integer>)ancestors[u]).get(highOneBit(depth[u]-depth[v]));
		
		// Stop when equal.
		while (u != v) {
			
			// See how far we can go.
			int jump = 0;
			while (jump < ancestors[u].size() && !ancestors[u].get(jump).equals(ancestors[v].get(jump))) 
				jump++;
			
			// This means the direct parent is the answer.
			if (jump == 0) return ((ArrayList<Integer>)ancestors[u]).get(0);
			
			// Jump up!
			u = ((ArrayList<Integer>)ancestors[u]).get(jump-1);
			v = ((ArrayList<Integer>)ancestors[v]).get(jump-1);
		}

		// Don't think we'll get here, but if we do, this is the answer.
		return u;
	}
	
	// x > 0, returns highest 1 bit, bit location not value.
	public static int highOneBit(int x) {
		int i = 0;
		while ( (1<<i) <= x) i++;
		return i-1;
	}
	
	//par, parEdge, depth
	public static void dfs(int v, int parent, int d) {
	
		// Mark depth.
		depth[v] = d;
		
		// Store ancestral chain.
		if (parent != -1) ancestors[v].add(parent);
		int idx = 0, cur = parent;
		while (true) {
		
			// Time to get out.
			if (cur == -1 || ancestors[cur].size() <= idx) break;
			
			// We want the idx'th ancestor of our current node.
			int prev = ((ArrayList<Integer>)ancestors[cur]).get(idx);
			
			// This is the next power of two for us.
			ancestors[v].add(prev);
			
			// Update our current node.
			idx++;
			cur = prev;
		}
		
		// This is the usual DFS.
		for (edge next: (ArrayList<edge>)g[v]) {
			int x = next.v;
			if (x == parent) {
				parEdge[v] = next.id;
				continue;
			}
			dfs(x, v, d+1);
		}
	}

}

class edge {

	public int u;
	public int v;
	public int id;
	
	public edge(int myu, int myv, int myid) {
		u = myu;
		v = myv;
		id = myid;
	}
}
