// Arup Guha
// 7/3/2012
// Solution to 2012 U-Chicago Invitational Problem G: Red/Blue Spanning Tree
// The basic idea here is to run MST two ways - one where blue edges are 1, 
// the other where blue edges are 0. Then, we simply see if the minimum
// number of blue edges required is less than or equal to k, and the maximum
// is greater than or equal to it. As long as this is the case, we can do it.

import java.util.*;

public class g {
	
	public static void main(String[] args) {
		
		Scanner stdin = new Scanner(System.in);
		
		int n = stdin.nextInt();
		int e = stdin.nextInt();
		int k = stdin.nextInt();
		
		// Get data.
		while (n != 0) {
			
			ArrayList<edge> graph1 = new ArrayList<edge>();
			ArrayList<edge> graph2 = new ArrayList<edge>();
			
			// Store our two graphs.
			for (int i=0; i<e; i++) {
				
				String color = stdin.next();
				int v1 = stdin.nextInt() - 1;
				int v2 = stdin.nextInt() - 1;
				
				if (color.equals("B")) {
					graph1.add(new edge(v1, v2, 0));
					graph2.add(new edge(v1, v2, 1));
				}
				else {
					graph1.add(new edge(v1, v2, 1));
					graph2.add(new edge(v1, v2, 0));				
				}
			}
			
			// Calculate both MST's.
			int g1mst = mst(graph1, n);
			int g2mst = mst(graph2, n);
			
			// Check minimum, followed by maximum blue edges.
			if (g2mst <= k && n - 1 - g1mst >= k )
				System.out.println("1");
			else
				System.out.println("0");
			
			n = stdin.nextInt();
			e = stdin.nextInt();
			k = stdin.nextInt();			
		}
	}
	
	// Run Kruskal.
	public static int mst(ArrayList<edge> graph, int n) {
		
		dset list = new dset(n);
		
		Collections.sort(graph);
		
		int index = 0, merges = 0, cost = 0;
		while (true) {
			
			int v1 = graph.get(index).v1;
			int v2 = graph.get(index).v2;
			
			// We can merge these.
			if (list.find(v1) != list.find(v2)) {
				list.union(v1, v2);
				merges++;
				cost += graph.get(index).distance;
			}
			
			// It's one tree now...
			if (merges == n-1)
				break;
			
			index++;
		}
		
		return cost;
	}
}

// Stores each possible edge for the minimum spanning tree.
class edge implements Comparable<edge> {
	
	public int v1;
	public int v2;
	public double distance;
	
	public edge(int start, int end, double d) {
		v1 = start;
		v2 = end;
		distance = d;
	}
	
	// Basic compareTo.
	public int compareTo(edge other) {
		if (this.distance < other.distance)
			return -1;
		else if (this.distance > other.distance)
			return 1;
		return 0;
	}
}

//  Just used for the Disjoint set class.
class pair {
	public int parent;
	public int height;
	
	public pair(int a, int b) {
		parent = a;
		height = b;
	}
}

// Basic Disjoint Set without path compression.
class dset {
	
	private pair[] parents;
	
	public dset(int n) {
		parents = new pair[n];
		for (int i=0; i<n; i++)
			parents[i] = new pair(i,0);
	}
	
	public int find(int child) {
		while (parents[child].parent != child)
			child = parents[child].parent;
		return child;
	}
	
	public boolean union(int c1, int c2) {
		int root1 = find(c1);
		int root2 = find(c2);
		
		// Nothing to union.
		if (root1 == root2)
			return false;
			
		// Root 1 stays parent.
		if (parents[root1].height > parents[root2].height) {
			parents[root2].parent = root1;
		}
		
		// Tie case get assigned to root 1 also.
		else if (parents[root1].height == parents[root2].height) {
			parents[root2].parent = root1;
			parents[root1].height++;
		}
		
		// Must use root 2 here.
		else {
			parents[root1].parent = root2;
		}
		
		return true;
	}
}