import java.io.*;
import java.util.*;

public class Main {
    private static InputStream is;
    private static PrintWriter out;
    private static String INPUT = "";

    void solve() {
        int n = ni(), m = ni(), z = 1 << m;
        int bit[] = new int[n];
        int dp[][] = new int[n + 1][z];
        for (int i = 0; i < m; ++i) {
            int k = ni();
            for (int j = 0; j < k; ++j) {
                int b = ni() - 1;
                bit[b] |= 1 << i;
            }
        }
        int s = 0;
        for (int i = 0; i < m; ++i) {
            int p = ni();
            if (p == 0) s |= 1 << i;
        }
        dp[0][s] = 1;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < z; ++j) {
                dp[i + 1][j ^ bit[i]] += dp[i][j];
            }
            for (int j = 0; j < z; ++j) {
                dp[i + 1][j] += dp[i][j];
            }
        }
        out.println(dp[n][z - 1]);
    }

    public static void main(String[] args) throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);
        new Main().solve();
        out.flush();
    }

    private static boolean eof() {
        if (lenbuf == -1) return true;
        int lptr = ptrbuf;
        while (lptr < lenbuf)
            if (!isSpaceChar(inbuf[lptr++])) return false;

        try {
            is.mark(1000);
            while (true) {
                int b = is.read();
                if (b == -1) {
                    is.reset();
                    return true;
                } else if (!isSpaceChar(b)) {
                    is.reset();
                    return false;
                }
            }
        } catch (IOException e) {
            return true;
        }
    }

    private static byte[] inbuf = new byte[1024];
    static int lenbuf = 0, ptrbuf = 0;

    private static int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private static boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private static int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b))
            ;
        return b;
    }

    private static double nd() {
        return Double.parseDouble(ns());
    }

    private static char nc() {
        return (char) skip();
    }

    private static String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private static char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private static char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++)
            map[i] = ns(m);
        return map;
    }

    private static int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = ni();
        return a;
    }

    private static long[] nal(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nl();
        return a;
    }

    private static int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
            ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private static long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
            ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private class XorShift {
        int x = 123456789;
        int y = 362436069;
        int z = 521288629;
        int w = 88675123;

        int nextInt(int n) {
            final int t = x ^ (x << 11);
            x = y;
            y = z;
            z = w;
            w = (w ^ (w >>> 19)) ^ (t ^ (t >>> 8));
            final int r = w % n;
            return r < 0 ? r + n : r;
        }
    }

    private static void tr(Object... o) {
        System.err.println(Arrays.deepToString(o));
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.NoSuchElementException;

public class Main {

	private static void solve() {
		int n = nei();
		int m = nei();
		int[] bs = new int[m];
		for (int i = 0; i < m; i++) {
			int k = nei();
			for (int j = 0; j < k; j++) {
				bs[i] |= 1 << (nei() - 1);
			}
		}
		int[] ps = nis(m);
		int max = 1 << n;
		int res = 0;
		L: for (int i = 0; i < max; i++) {
			for (int j = 0; j < m; j++) {
				if ((Integer.bitCount(bs[j] & i) & 1) != ps[j]) {
					continue L;
				}
			}
			res++;
		}
		out(res);
	}

	// returns (x, y, d) s.t. ax + by = d
	static long[] exgcd(long a, long b) {
		int sa = a < 0 ? -1 : 1;
		int sb = b < 0 ? -1 : 1;
		a *= sa;
		b *= sb;
		long x = 1;
		long y = 0;
		long z = 0;
		long w = 1;
		while (b > 0) {
			long q = a / b;
			long t = z;
			z = x - q * z;
			x = t;
			t = w;
			w = y - q * w;
			y = t;
			t = b;
			b = a - q * b;
			a = t;
		}
		return new long[] { x * sa, y * sb, a };
	}

	static int[] lis(int[] s) {
		int n = s.length;
		int[] dp = new int[n];
		int[] ids = new int[n];
		int[] pids = new int[n];
		dp[0] = s[0];
		int len = 1;
		int lidx = 0;
		for (int i = 1; i < n; i++) {
			int idx = bs(s[i], dp, 0, len);
			dp[idx] = s[i];
			ids[idx] = i;
			if (idx == len) {
				lidx = i;
				len++;
			}
			if (idx > 0)
				pids[i] = ids[idx - 1];
		}
		int[] lis = new int[len];
		lis[len - 1] = s[lidx];
		for (int i = len - 1; i >= 0; i--) {
			lis[i] = s[lidx];
			lidx = pids[lidx];
		}
		return lis;
	}

	static int bs(int a, int[] as, int from, int num) {
		int min = from;
		int max = from + num - 1;
		while (min < max) {
			int mid = min + max >> 1;
			if (as[mid] < a)
				min = mid + 1;
			else if (as[mid] > a)
				max = mid;
			else
				return mid;
		}
		return as[min] < a ? min + 1 : min;
	}

	static int gcd(int x, int y) {
		x = (x ^ x >> 31) - (x >> 31);
		y = (y ^ y >> 31) - (y >> 31);
		if (x < y) {
			x ^= y;
			y ^= x;
			x ^= y;
		}
		int z = x % y;
		if (z == 0)
			return y;
		return gcd(y, z);
	}

	static long gcd(long x, long y) {
		x = (x ^ x >> 63) - (x >> 63);
		y = (y ^ y >> 63) - (y >> 63);
		if (x < y) {
			x ^= y;
			y ^= x;
			x ^= y;
		}
		long z = x % y;
		if (z == 0)
			return y;
		return gcd(y, z);
	}

	static long modinv(long a, long mod) {
		return modpow(a, mod - 2, mod);
	}

	static long modpow(long a, long b, long mod) {
		if (b == 0)
			return 1;
		if ((b & 1) == 0) {
			long sqrt = modpow(a, b >> 1, mod);
			return sqrt * sqrt % mod;
		}
		return a * modpow(a, b - 1, mod) % mod;
	}

	static long fact(long n) {
		if (n <= 1)
			return 1;
		long res = 2;
		for (long i = 3; i <= n; i++) {
			res *= i;
		}
		return res;
	}

	static long modfact(long n, long mod) {
		if (n <= 1)
			return 1 % mod;
		long res = 2;
		for (long i = 3; i <= n; i++) {
			res *= i;
			res %= mod;
		}
		return res % mod;
	}

	// returns facts([0]) and invfacts([1])
	static long[][] enumfacts(int n, long mod) {
		int num = n + 10;
		long[][] res = new long[2][num];
		long[] facts = res[0];
		long[] invfacts = res[1];
		for (int i = 0; i < num; i++) {
			if (i <= 1) {
				facts[i] = 1;
				invfacts[i] = 1;
			} else {
				facts[i] = facts[i - 1] * i % mod;
				invfacts[i] = modinv(facts[i], mod);
			}
		}
		return res;
	}

	static long modcomb(long n, long m, long mod) {
		if (m > n)
			return 0;
		if (m > n - m) {
			m = n - m;
		}
		long numer = 1;
		for (int i = 0; i < m; i++) {
			numer = numer * (n - i) % mod;
		}
		long denom = modfact(m, mod);
		return numer * modinv(denom, mod) % mod;
	}

	static long modcomb(int n, int m, long[] facts, long[] invfacts, long mod) {
		if (m > n)
			return 0;
		long numer = facts[n];
		long denom = invfacts[m] * invfacts[n - m] % mod;
		return numer * denom % mod;
	}

	// res[i][0]: prime factor, res[i][1]: exponent
	static int[][] factorize(int n) {
		int[][] pfs = new int[32][2];
		int num = 0;
		for (int i = 2; i * i <= n; i++) {
			int count = 0;
			while (n % i == 0) {
				n /= i;
				count++;
			}
			if (count > 0) {
				pfs[num][0] = i;
				pfs[num][1] = count;
				num++;
			}
		}
		if (n > 1) {
			pfs[num][0] = n;
			pfs[num][1] = 1;
			num++;
		}
		int[][] res = new int[num][2];
		for (int i = 0; i < num; i++) {
			res[i][0] = pfs[i][0];
			res[i][1] = pfs[i][1];
		}
		return res;
	}

	static long lcm(long x, long y) {
		x = (x ^ x >> 63) - (x >> 63);
		y = (y ^ y >> 63) - (y >> 63);
		return x / gcd(x, y) * y;
	}

	static int abs(int x) {
		return x < 0 ? -x : x;
	}

	static long abs(long x) {
		return x < 0 ? -x : x;
	}

	static int min(int a, int b) {
		return a < b ? a : b;
	}

	static long min(long a, long b) {
		return a < b ? a : b;
	}

	static int max(int a, int b) {
		return a > b ? a : b;
	}

	static long max(long a, long b) {
		return a > b ? a : b;
	}

	static int clamp(int a, int min, int max) {
		return a < min ? min : a > max ? max : a;
	}

	static long clamp(long a, long min, long max) {
		return a < min ? min : a > max ? max : a;
	}

	static double clamp(double a, double min, double max) {
		return a < min ? min : a > max ? max : a;
	}

	static void out(String val) {
		IO.out(val);
	}

	static void out(Object val) {
		IO.out(String.valueOf(val));
	}

	static void out(int val) {
		IO.out(String.valueOf(val));
	}

	static void out(long val) {
		IO.out(String.valueOf(val));
	}

	static void out(char val) {
		IO.out(String.valueOf(val));
	}

	static void out(double val) {
		IO.out(Double.isFinite(val) ? BigDecimal.valueOf(val).toPlainString() : String.valueOf(val));
	}

	static void out(boolean val) {
		IO.out(val ? "true" : "false");
	}

	static void kil(String val) {
		IO.out(val);
		IO.flush();
		System.exit(0);
	}

	static void kil(Object val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(int val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(long val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(char val) {
		IO.out(String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(double val) {
		IO.out(Double.isFinite(val) ? BigDecimal.valueOf(val).toPlainString() : String.valueOf(val));
		IO.flush();
		System.exit(0);
	}

	static void kil(boolean val) {
		IO.out(val ? "true" : "false");
		IO.flush();
		System.exit(0);
	}

	static String nes() {
		return IO.next();
	}

	static int nei() {
		return IO.nextInt();
	}

	static long nel() {
		return IO.nextLong();
	}

	static double ned() {
		return IO.nextDouble();
	}

	static char nec() {
		return IO.nextChar();
	}

	static String[] nss(int n) {
		String[] as = new String[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.next();
		}
		return as;
	}

	static int[] nis(int n) {
		int[] as = new int[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextInt();
		}
		return as;
	}

	static long[] nls(int n) {
		long[] as = new long[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextLong();
		}
		return as;
	}

	static double[] nds(int n) {
		double[] as = new double[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextDouble();
		}
		return as;
	}

	static char[] ncs(int n) {
		char[] as = new char[n];
		for (int i = 0; i < n; i++) {
			as[i] = IO.nextChar();
		}
		return as;
	}

	static String[][] nss2(int n, int m) {
		String[][] as = new String[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.next();
			}
		}
		return as;
	}

	static int[][] nis2(int n, int m) {
		int[][] as = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextInt();
			}
		}
		return as;
	}

	static long[][] nls2(int n, int m) {
		long[][] as = new long[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextLong();
			}
		}
		return as;
	}

	static double[][] nds2(int n, int m) {
		double[][] as = new double[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextDouble();
			}
		}
		return as;
	}

	static char[][] ncs2(int n, int m) {
		char[][] as = new char[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				as[i][j] = IO.nextChar();
			}
		}
		return as;
	}

	static int parseInt(String val) {
		return Integer.parseInt(val);
	}

	static int parseInt(char val) {
		return Integer.parseInt(String.valueOf(val));
	}

	static long parseLong(String val) {
		return Long.parseLong(val);
	}

	public static void main(String[] args) {
		try {
			solve();
			IO.flush();
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
	}
}

final class IO {
	private static final InputStream in = System.in;
	private static final PrintWriter out = new PrintWriter(System.out, false);
	private static final byte[] buffer = new byte[1024];
	private static int ptr = 0;
	private static int len = 0;

	private static boolean hasNextByte() {
		if (ptr < len)
			return true;
		ptr = 0;
		try {
			len = in.read(buffer);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return len > 0;
	}

	private static int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	static boolean hasNext() {
		byte c;
		while (hasNextByte() && ((c = buffer[ptr]) < '!' || c > '~'))
			ptr++;
		return hasNextByte();
	}

	static String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (b >= '!' && b <= '~') {
			sb.append((char) b);
			b = readByte();
		}
		return sb.toString();
	}

	static char nextChar() {
		if (!hasNext())
			throw new NoSuchElementException();
		return (char) readByte();
	}

	static long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		int sign = 1;
		int b = readByte();
		if (b == '-') {
			sign = -1;
			b = readByte();
		}
		if (b < '0' || '9' < b)
			throw new NumberFormatException();
		while (true) {
			if ('0' <= b && b <= '9')
				n = n * 10 + b - '0';
			else if (b == -1 || b < '!' || b > '~')
				return n * sign;
			else
				throw new NumberFormatException();
			b = readByte();
		}
	}

	static int nextInt() {
		if (!hasNext())
			throw new NoSuchElementException();
		int n = 0;
		int sign = 1;
		int b = readByte();
		if (b == '-') {
			sign = -1;
			b = readByte();
		}
		if (b < '0' || '9' < b)
			throw new NumberFormatException();
		while (true) {
			if ('0' <= b && b <= '9')
				n = n * 10 + b - '0';
			else if (b == -1 || b < '!' || b > '~')
				return n * sign;
			else
				throw new NumberFormatException();
			b = readByte();
		}
	}

	static double nextDouble() {
		return Double.parseDouble(next());
	}

	static void out(String val) {
		out.println(val);
	}

	static void flush() {
		out.flush();
	}
}


import java.util.Arrays;
import java.util.Scanner;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {

	public static void main(String[] args) {
		try (Scanner scanner = new Scanner(System.in)) {
			int n = scanner.nextInt(), m = scanner.nextInt();
			@SuppressWarnings("unchecked")
			Set<Integer>[] sets = new Set[m];
			IntStream.range(0, m).forEach(i -> {
				int k = scanner.nextInt();
				sets[i] = IntStream.range(0, k).map(j -> scanner.nextInt()).boxed().collect(Collectors.toSet());
			});
			int[] p = IntStream.range(0, m).map(i -> scanner.nextInt()).toArray();
			int[] counts = new int[m];
			System.out.println(IntStream.range(1, 1 << n).filter(i -> {
				Arrays.fill(counts, 0);
				IntStream.range(0, n).filter(j -> (i & (1 << j)) > 0).forEach(j -> {
					IntStream.range(0, m).forEach(k -> counts[k] += sets[k].contains(j + 1) ? 1 : 0);
				});
				return m == IntStream.range(0, m).filter(j -> p[j] == (1 & counts[j])).count();
			}).count());
		}
	}
}


import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {

		//    	File file = new File("src/in.txt");
		//    	Scanner sc = new Scanner(file);

		Scanner sc = new Scanner(System.in);

		int N = sc.nextInt();
		int M = sc.nextInt();

		int[][] s = new int[M][N];

		for (int i = 0; i < M; i++) {
			int k = sc.nextInt();
			for (int j = 0; j < k; j++) {
				int num = sc.nextInt()-1;
				s[i][num] = 1;
			}
		}

		int[] p = new int[M];
		for (int i = 0; i < M; i++) {
			p[i] = sc.nextInt();
		}

		int ans = 0;
		for (int i = 0; i < 1 << N; i++) {
			boolean flg = true;
			// bit全探索の全通りのloop
			int[] A = new int[N];
			for (int j = 0; j < N; j++) {
				if ((1 & i >> j) == 1) {
					A[j] = 1;
				}
			}

			for (int k = 0; k < M; k++) {
				int sum = 0;
				for (int l = 0; l < N; l++) {
					sum = sum + s[k][l] * A[l];
				}
				if (sum%2 == p[k]) {
					flg = false;
				}
			}
			if (flg == true) {
				ans++;
			}
		}
		System.out.println(ans);

	}
}


import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int switchCount = sc.nextInt();
		int lampCount = sc.nextInt();
		List<int[]> switchInfo = new ArrayList<int[]>();
		for(int i =0;i < lampCount;i++) {
			int connectSwitch = sc.nextInt();
			int[] connectSwitchInfo = new int[connectSwitch];
			for(int j =0; j < connectSwitch; j++) {
				connectSwitchInfo[j] = sc.nextInt();
			}
			switchInfo.add(connectSwitchInfo);
		}
		int[] onOffInfo = new int[lampCount];
		for(int i =0;i < lampCount; i++) {
			onOffInfo[i] = sc.nextInt();
		}
		int answer = 0;
		for(int i =0;i < 1 <<switchCount;i++) {
			for(int j =0; j < lampCount;j++) {
				int switchOnCount = 0;
				for(int k =0; k < switchInfo.get(j).length;k++) {
					if((1 & (i >> k)) == 1 ) {
						switchOnCount++;
					}
				}
				if(switchOnCount % 2 != onOffInfo[j]) {
					break;
				}
				if(j ==lampCount-1) {
					answer++;
				}
			}
		}
		System.out.println(answer);
	}
}


#include <bits/stdc++.h>
#define rep(i,n)for(int i=0;i<(n);i++)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define EPS (1e-10)
using namespace std;
typedef long long ll;
typedef pair<int,int>P;

vector<int>v[20];
int p[20];

int main(){
	int n,m;cin>>n>>m;
	rep(i,m){
		int a;scanf("%d",&a);
		rep(j,a){
			int b;scanf("%d",&b);b--;
			v[i].push_back(b);
		}
	}
	rep(i,m){
		scanf("%d",&p[i]);
	}
	int ans=0;
	rep(i,1<<n){
		bool ok=true;
		rep(j,m){
			int cnt=0;
			for(int k:v[j]){
				if(i>>k&1)cnt^=1;
			}
			if(cnt!=p[j])ok=false;
		}
		ans+=ok;
	}
	cout<<ans<<endl;
}


#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repp(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perr(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)

typedef long long LL;
typedef long double LD;

int main(){
  int n,m;
  cin >> n >> m;
  vector<vector<int>> w(m,vector<int>(n,0));
  vector<int> p(m);
  rep(i,m){
    int k;
    cin >> k;
    int s;
    rep(j,k){
      cin >> s;
      w[i][s-1]=1;
    }
  }
  rep(i,m) cin >> p[i];
  int ans=0;
  rep(i,(1<<n)){
    int tmp=0;
    rep(j,m){
      int x=0;
      rep(k,n){
        if((i&(1<<k))&&w[j][k]) x++;
      }
      if(x%2==p[j]) tmp++;
    }
    if(tmp==m) ans++;
  }
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
using pii=pair<int,int>;
using vi = vector<int>;
using vvi = vector<vi>;
#define all(c) begin(c),end(c)
#define rall(c) rbegin(c),rend(c)
#define fore(x,c) for(auto &&x:c)
#define rep(i,a,n) for(int i=a,i##len=(int)(n);i<i##len;++i)
#define rrep(i, a, n) for(int i=(int)(n-1);i>=a;--i)
#define sz(c) ((int)c.size())
#define contains(c,x) (c.find(x)!=end(c))
#define inseg(l,x,r) ((l)<=(x)&&(x)<(r))
#define dump(...)
#define pb push_back
#define _ 0
const signed INF_=1001001001; const long long INF=1001001001001001001LL;
const int DX[9]={0,1,0,-1,1,1,-1,-1,0},DY[9]={-1,0,1,0,-1,1,1,-1,0};
template<class T> ostream& operator<<(ostream &os,const vector<T> &v) {
    for (auto i = begin(v); i != end(v); i++) os<<*i<<(i==end(v)-1?"":" ");return os;}
template<class T> istream& operator>>(istream &is,vector<T> &v) {
    for (auto i = begin(v); i != end(v); i++) is>>*i;return is;}
template<class T,class U> istream& operator>>(istream &is, pair<T,U> &p) {
    is>>p.first>>p.second;return is;}
template<class T, class U> bool chmax(T &a,const U &b){return a<b?a=b,1:0;}
template<class T, class U> bool chmin(T &a,const U &b){return a>b?a=b,1:0;}
template <class T> void psum(T& c) {partial_sum(begin(c), end(c), begin(c));}
template<class T> using heap=priority_queue<T,vector<T>,greater<T>>;
struct before_main_function {
    before_main_function() {
        cin.tie(nullptr); ios::sync_with_stdio(0);
        cout << setprecision(15) << fixed;
        // #define endl "\n"
    }
} before_main_function;
//------------------8<------------------------------------8<--------------------

signed main() {
    int N, M;
    cin >> N >> M;
    vector<vector<int>> s(M);
    rep(i, 0, M) {
        int k;
        cin >> k;
        s[i].resize(k);
        cin >> s[i];
        for (int &x : s[i]) x--;
    }
    vector<int> p(M);
    cin >> p;
    int ans = 0;
    rep(i, 0, 1 << N) {
        bool ok = true;
        rep(j, 0, M) {
            int cnt = 0;
            for (int k : s[j]) {
                if (i >> k & 1) {
                    cnt++;
                }
            }
            if (cnt % 2 != p[j]) {
                ok = false;
            }
        }
        if (ok) ans++;
    }
    cout << ans << endl;
    return (0^_^0);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
#define rep(i,n) for (int i = 0; i < (n); i++)

int main() {
    int N, M; cin >> N >> M;
    vector<vector<int> > s(M);
    for (int i = 0; i < M; ++i) {
        int k; cin >> k;
        for (int j = 0; j < k; ++j) {
            int a; cin >> a; --a;
            s[i].push_back(a);
        }
    }
    vector<int> p(M);
    for (int i = 0; i < M; ++i) cin >> p[i];

    long long res = 0;
    for (int bit = 0; bit < (1<<N); ++bit) {
      cout << bit << endl;
        bool ok = true;
        for (int i = 0; i < M; ++i) {
            int con = 0;
            for (auto v : s[i]) {
                // onになっているスイッチの数を数える
                if (bit & (1<<v)) ++con;
            }
            // スイッチの数を2で割った個数が不一致の場合
            if (con % 2 != p[i]) ok = false;
        }
        // 不一致が一つもなかった場合にのみ　カウントする
        if (ok) ++res;
    }
    cout << res << endl;
}


#include <iostream>
#include <vector>
using namespace std;

int main() {
    int N, M; cin >> N >> M;
    vector<int> s[M];
    for (int i = 0; i < M; i++) {
        int k; cin >> k;
        s[i].resize(k);
        for (int j = 0; j < k; j++) cin >> s[i][j];
    }
    vector<int> p(M);
    for (int i = 0; i < M; i++) cin >> p[i];

    int ans = 0;
    for (int bit = 0; bit < (1<<N); bit++) {
        int sum = 0;
        for (int i = 0; i < M; i++) {
            int cnt = 0;
            for (int j = 0; j < s[i].size(); j++) {
                if ((bit >> s[i][j]) & 1) cnt++;
            }
            if (cnt % 2 == p[i]) sum++;
        }
        if (sum == M) ans++;
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int,int>;
#define chmax(x,y) x = max(x,y);
#define chmin(x,y) x = min(x,y);
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, -1, 0, 1};
const int INF = 1001001001;

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> s(m);
    rep(i,m) {
        int k;
        cin >> k;
        rep(j,k) {
            int a;
            cin >> a;
            s[i].push_back(a);
        }
    }
    vector<int> p(m);
    rep(i,m) cin >> p[i];
    int ans = 0;
    rep(is,1<<n) {
        bool ok = true;
        rep(i,m) {
            int cnt = 0;
            for (int x : s[i]) {
                if (is>>x&1) cnt++;
            }
            cnt %= 2;
            if (cnt != p[i]) ok = false;
        }
        if (ok) ans++;
    }
    cout << ans << endl;
    return 0;
}


#include <stdio.h>
int main(void){
    int n,m,i,j,k,s,ans=0;
    scanf("%d%d",&n,&m);
    int a[10]={0},p=0;
    for(i=0;i<m;i++){
        scanf("%d",&k);
        for(j=0;j<k;j++){
            scanf("%d",&s);
            s--;
            a[s] |= 1<<i;
        }
    }
    for(i=0;i<m;i++){
        scanf("%d",&s);
        p |= s<<i;
    }
    for(i=0;i<(1<<n);i++){
        int t=0;
        for(j=0;j<n;j++){
            if(i>>j&1) t^=a[j];
        }
        if(t==p) ans++;
    }
    printf("%d",ans);
}


#include <stdio.h>

int main()
{
	int i, j, N, M, k[11], s[11][11], p[11];
	scanf("%d %d", &N, &M);
	for (i = 1; i <= M; i++) {
		scanf("%d", &(k[i]));
		for (j = 1; j <= k[i]; j++) scanf("%d", &(s[i][j]));
	}
	for (i = 1; i <= M; i++) scanf("%d", &(p[i]));

	int count = 0, flag[11] = {}, tmp;
	while (1) {
		for (i = 1; i <= M; i++) {
			tmp = 0;
			for (j = 1; j <= k[i]; j++) {
              if (flag[s[i][j]] == 1) tmp ^= 1;
            }
			if (tmp != p[i]) break;
		}

		if (i > M) count++;
		for (i = 1; i <= N; i++) if (flag[i] == 0) break;
		if (i > N) break;
		flag[i] = 1;
		for (i--; i >= 1; i--) flag[i] = 0;
	}

	printf("%d\n", count);
	fflush(stdout);
	return 0;
}


#include<stdio.h>

#define N 10
#define M 10

int n, m, k[M], s[M][N], p[M];

int search(int a, int *cnt, int *isSwitch){
  if(a==n){
    int isAllLight=1;
    for(int i=0; i<m; i++){
      int sumSwitchOn=0;
      for(int j=0; j<k[i]; j++){
        if(isSwitch[s[i][j]-1]==1){
          sumSwitchOn++;
        }
      }
      if((sumSwitchOn&1)!=p[i]){
        isAllLight=0;
        break;
      }
    }
    if(isAllLight==1){
      *cnt=*cnt+1;
    }
  }
  else{
    for(int b=0; b<=1; b++){
      isSwitch[a] = b;
      search(a+1, cnt, isSwitch);
    }
  }
  return 0;
}

int main(){
  int isSwitch[N], cnt=0;
  scanf("%d %d", &n, &m);
  for(int i=0; i<m; i++){
    scanf("%d", &k[i]);
    for(int j=0; j<k[i]; j++){
      scanf("%d", &s[i][j]);
    }
  }
  for(int i=0; i<m; i++){
    scanf("%d", &p[i]);
  }

  search(0, &cnt, isSwitch);
  printf("%d",cnt);

  return 0;
}


#include <stdio.h>
#include <stdlib.h>

int N, M;   //N個のスイッチとM個の電球
int k[11];  //k個のスイッチにつながってる
int s[11][11];  //k個のスイッチ=s1~sk
int p[11];  //s個のスイッチのうち、オンになっている数を2で割った余りがpの時、点灯

/* ビットの立っているフラグをついてる電球する。s個ずらす方法で比べて、つながってる電球のうちついているものがいくつかを調べる。その調べた個数を2で割ってpと比べる */
int judge(int bit)
{
    int cnt;
    for(int i=1; i<=N; i++) {
        cnt=0;
        for(int j=1; j<=k[i]; j++) {
            if(bit & (1<<(s[i][j]-1))) cnt++;
            // printf("%dの%d回目:%d\n", i, j, cnt);
        }
        if((cnt%2) != p[i]) return 0;
    }
    return 1;
}

int main()
{
    int total=0;
    scanf("%d %d", &N, &M);
    for(int i=1; i<=M; i++) {
        scanf("%d", &k[i]);
        for(int j=1; j<=k[i]; j++) {
            scanf("%d", &s[i][j]);
        }
    }
    for(int i=1; i<=M; i++) scanf("%d", &p[i]);

    for(int bit=0; bit<(1<<N); bit++) {
        if(judge(bit)) total++;
    }

    printf("%d", total);
}


#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
const int INF = 1e9;

int main() {
  int n, m; cin >> n >> m;
  vector<int> k(m);
  vector<vector<int>> s(m);
  vector<int> p(m);

  for (int i = 0; i < m; ++i) {
    cin >> k[i];
    s[i].resize(k[i]);
    for (int j = 0; j < k[i]; ++j) {
      cin >> s[i][j];
      --s[i][j];
    }
  }
  for (int k = 0; k < m; ++k) {
    cin >> p[k];
  }

  int ans = 0;
  for (int bits = 0; bits < (1 << n); ++bits) {
    bool all_ok = true;
    for (int i = 0; i < m; ++i) {
      int cnt = 0;
      for (int j = 0; j < k[i]; ++j) {
        if ( (bits >> j) & 1 ) cnt++;
      }
      if (p[i] != (cnt % 2)) all_ok = false;
    }
    if (all_ok) ++ans;
  }
  cout << ans << endl;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef long long ll;
#define rep(i,l,r) for(int i=l; i<(int)(r); i++)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
int upcmpll(const void *a, const void *b){
    return (*(ll*)a == *(ll*)b ? 0 : (*(ll*)a > *(ll*)b ? 1 : -1));
}
void sort_u(ll *a, int n){ qsort(a, n, sizeof(ll), upcmpll); }

int k[12], s[12][12], p[12];

int main(){
    int n,m; scanf("%d%d", &n, &m);
    rep(i,0,m){
        scanf("%d", k+i);
        rep(j,0,k[i]){
            scanf("%d", &s[i][j]);
        }
    }
    rep(i,0,m) scanf("%d", p+i);

    int ans = 0;
    //ビット全探索　初期値は0 (ans=0あり)
    rep(bit, 0, (1 << n)) {
        int t_lmp = 0;
        rep(i, 0, m) {
            int tmp_sum = 0;
            rep(j, 0, k[i]){
                if(bit&(1<<s[i][j])) tmp_sum++;
            }
            if(tmp_sum%2 == p[i]) t_lmp++;
            else break;
        }
        if(t_lmp == m) ans++;
    }

    printf("%d\n", ans);
    return 0;
}


'use strict';
console.log(function(args){
  const tmp = args.trim().split('\n').map(a=>a.split(' ').map(v=>v|0));
  const N = tmp[0][0], M = tmp[0][1];
  const p = tmp[M+1];
  const k = Array(M),s = Array(M);
  let count = 0;
  for ( let i = 1; i <= M; i++ ) {
    k[i-1] = tmp[i][0];
    s[i-1] = tmp[i].slice(1).map(v=>v-1);
  }
  TEST: for ( let state = 0; state < 1<<N; state++ ) {
    for ( let i = 0; i < M; i++ ) {
      let bulb = !p[i];
      for ( let j = 0; j < k[i]; j++ ) {
        if ( state & (1 << s[i][j] ) ) {
          bulb^=1;
        }
      }
      if ( !bulb ) continue TEST;
    }
    count++;
  }
  return count.toString();
}(require('fs').readFileSync('/dev/stdin', 'utf8')));


'use strict'

const INF = 900719925474099;

function numofbits5(bits)
{
    bits = bits & 0xffffffff
    bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
    bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
    bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
    bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
    bits = (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);

    //console.log('bits:',bits);
    return bits;
}

function Main(input){
    let temp = input.trim().split('\n');
    let temp2 = temp[0].split(' ').map((v)=>parseInt(v));
    let n = temp2.shift();
    let m = temp2.shift();

    let k;
    let sum;
    let ksw = [];
    for(let i=1;i<=m;i++){
        temp2 = temp[i].split(' ').map((v)=>parseInt(v));
        k = temp2[0];
        sum = 0;
        for(let j=1;j<=k;j++){
            sum += 1 << (temp2[j]-1);
        }
        ksw.push(sum);
    }
    let p = temp[m+1].split(' ').map((v)=>parseInt(v));

    //console.log('-------------------------');
    //console.log(ksw,p);
    let ans = 0;
    let f;
    let maxi = Math.pow(2,n)
    for(let i=0;i<maxi;i++){
        f = true;
        for(let j=0;j<m;j++){
            //console.log('ksw:',ksw[j],'i:',i,'ksw&i:',ksw[j]&i,'bits:',numofbits5(ksw[j]&i),'p:',p[j],'if:',numofbits5(ksw[j]&i)%2 != p[j]);
            if(numofbits5(ksw[j]&i)%2 != p[j]){
                f = false;
                //console.log('break;');
                break;
            }
        }
        if(f == true) ans++;
        //console.log('cnt:',ans);
    }
    console.log(ans);
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


'use strict';(function(input){
  function count(pi,A,B){
    var C=A&B;
    var counter=pi;
    while(C>0){
      counter+=(C%2);
      C=(C>>1);
    }
    return ((counter%2)===0);
  }

  input=input.trim().split(/\n+/);
  input=input.map(str=>str.split(/\s+/).map(x=>x-0));
  const N=input[0][0];
  const M=input[0][1];
  const p=input.pop();
  for(let i=1;i<=M;i++)
    input[i].shift();
  const arr=new Array(1<<N).fill('filler').map((x,i)=>i);
  const mask=[];
  for(let i=1;i<=M;i++)
    mask.push(input[i].reduce((acc,cur)=>acc+(1<<(cur-1)),0));
  mask.forEach(function(A,i){
    let j=0;
    while(j<arr.length){
      if(!count(p[i],A,arr[j])){
        arr.splice(j,1);
      }else{
        j++;
      }
    }
  });
  console.log(arr.length);
})(require('fs').readFileSync('/dev/stdin','utf8'));


function Main(input) {
    input = input.trim().split("\n").map(function(x) { return x.split(" ")});
    var NM = [ ];
    var vec_p = [ ];
    var vec_s = [ ];
    var ary_ks = [];
    var ans = 0;
    var tmpAry, j, tmpNum, tmpSum;
    NM = input[0].map(e => parseInt(e, 10));
    vec_p = input[NM[1]+1].map(e => parseInt(e, 10));
    for (var ki = 1; ki <= NM[1]; ki++){
    	ary_ks.push(input[ki].map(e => parseInt(e, 10)));
    }
  var x=0;
    for (var i = Math.pow(2, NM[0]); i <  Math.pow(2, NM[0]) * 2; i++){
      x++;
    	tmpAry = i.toString(2).substr(1);
    	tmpSum = 0;
    	tmpAry_loop:
    	for (var ki = 1; ki <= NM[1]; ki++){
			for (var sij = 1; sij <=  ary_ks[ki-1][0]; sij++){
				tmpNum = parseInt(tmpAry[ary_ks[ki-1][sij]-1], 10);
 				tmpSum +=  tmpNum;
			}
			if (ki == NM[1])  {
              //console.log("tmpNum %d", tmpNum);
            }

			if (tmpSum % 2 != vec_p [ki-1]) break tmpAry_loop;
			if (ki == NM[1]) {
                           //console.log(tmpAry);
              	//			console.log(tmpSum);
				//console.log(tmpSum % 2);

              ans ++;
            }
		}
    }
    console.log(ans);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
    input = input.trim().split("\n").map(function(x) { return x.split(" ")});
    var NM = [ ];
    var vec_p = [ ];
    var vec_s = [ ];
    var ary_ks = [];
    var ans = 0;
    var tmpAry, j, tmpNum, tmpSum;
    NM = input[0].map(e => parseInt(e, 10));
    vec_p = input[NM[1]+1].map(e => parseInt(e, 10));
    for (var ki = 1; ki <= NM[1]; ki++){
    	ary_ks.push(input[ki].map(e => parseInt(e, 10)));
    }
    for (var i = Math.pow(2, NM[0]); i <  Math.pow(2, NM[0]) * 2; i++){
    	tmpAry = i.toString(2).substr(1);
    	tmpSum = 0;
    	tmpAry_loop:
    	for (var ki = 1; ki <= NM[1]; ki++){
			for (var sij = 1; sij <=  ary_ks[ki-1][0]; sij++){
				tmpNum = parseInt(tmpAry[ary_ks[ki-1][sij]-1], 10);
				tmpSum +=  tmpNum;
			}
			if (tmpSum % 2 != vec_p [ki-1]) break tmpAry_loop;
			if (ki == NM[1]) ans ++;
		}
    }
    console.log(ans);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function main(input) {
  const inputs = input.split('\n');
  var n = inputs[0].split(' ')[0] - 0;
  var m = inputs[0].split(' ')[1] - 0;

  var ds = [];
  for (var i = 0; i < n; i++) {
    ds.push(inputs[i + 1].split(' ').filter((n, i) => i > 0).map((n) => n - 1));
  }
  var p = inputs[1 + m].split(' ').map((n) => parseInt(n, 10));

  var counter = 0;
  // bit all search
  for (var bit = 0; bit < (1 << n); bit++) {
    var allOn = true;
    // all search for switches
    for (var swi = 0; swi < n; swi++) {
      var sum = 0;
      // a bit pattern
      for (var biti = 0; biti < n; biti++) {
        if ((bit & (1 << biti)) != 0) continue;
        if (ds[swi].find((v) => v == biti) >= 0) sum++;
      }
      allOn = allOn && (sum % 2 == p[swi]);
    }
    if (allOn) counter += 1;
  }
  console.log(counter);
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
)

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	N, M := readInt(), readInt()
	a := make([]int64, N)
	p := int64(0)
	ans := 0
	for i := int64(0); i < M; i++ {
		k := readInt()
		for j := int64(0); j < k; j++ {
			s := readInt() - 1
			a[s] |= 1 << uint32(i)
		}
	}
	for i := int64(0); i < M; i++ {
		x := readInt()
		p |= x << uint32(i)
	}
	for s := 0; s < (1 << uint32(N)); s++ {
		t := int64(0)
		for i := int64(0); i < N; i++ {
			if s>>uint32(i)&1 == 1 {
				t ^= a[i]
			}
		}
		if t == p {
			ans++
		}
	}
	fmt.Println(ans)

}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)
var ans int = 0

func scanInt() int {
	num, _ := strconv.Atoi(scanString())
	return num
}

func scanString() string {
	sc.Scan()
	return sc.Text()
}

func scanInts(n int) []int {
	sl := make([]int, n)
	for i := range sl {
		sl[i] = scanInt()
	}
	return sl
}

func scanStrings(n int) []string {
	sl := make([]string, n)
	for i := range sl {
		sl[i] = scanString()
	}
	return sl
}

func init() {
	sc.Split(bufio.ScanWords)
}

func check(now []bool, next_idx int, N int, data map[int][]int, correct []bool) {
	// if index N is on
	now_on := make([]bool, len(now))
	now_off := make([]bool, len(now))
	copy(now_on, now)
	copy(now_off, now)

	if _, ok := data[next_idx]; ok {
		for _, i := range data[next_idx] {
			now_on[i-1] = !now_on[i-1]
		}
	}
	ok := true
	for i := range now_on {
		if correct[i] != now_on[i] {
			ok = false
			break
		}
	}
	if ok == true {
		ans++
	}

	if next_idx == 1 {
		ok := true
		for i := range now_off {
			if correct[i] != now_off[i] {
				ok = false
				break
			}
		}
		if ok == true {
			ans++
		}
	}

	//fmt.Printf("%v => %v %v\n", now, now_on, now_off)
	if next_idx != N {
		// if index N is off
		check(now_off, next_idx+1, N, data, correct)
		check(now_on, next_idx+1, N, data, correct)
	}
}

func main() {
	N, M := scanInt(), scanInt()
	data := map[int][]int{}
	for i := 0; i < M; i++ {
		k := scanInt()
		for j := 0; j < k; j++ {
			s := scanInt()
			if _, ok := data[s]; ok {
				data[s] = append(data[s], i+1)
			} else {
				data[s] = []int{i + 1}
			}
		}
	}
	//fmt.Printf("%v\n", data)
	correct := make([]bool, M)
	for i := 0; i < M; i++ {
		if scanInt() == 0 {
			correct[i] = false
		} else {
			correct[i] = true
		}
	}
	state := make([]bool, M)
	//fmt.Printf("init: %v\n", state)
	check(state, 1, N, data, correct)
	fmt.Println(ans)
}


package main

import (
	"fmt"
)

func main() {
	var n, m int
	fmt.Scan(&n, &m)
	k := make([]int, m)
	s := make([][]int, m)
	for i := range k {
		fmt.Scan(&k[i])
		s[i] = make([]int, k[i])
		for j := range s[i] {
			fmt.Scan(&s[i][j])
		}
	}
	p := make([]int, m)
	for i := range p {
		fmt.Scan(&p[i])
	}

	ans := 0
	for i := 0; i < (1 << uint(n)); i++ {
		ok := true
		for j := 0; j < m; j++ {
			sum := 0
			for _, v := range s[j] {
				sum += i >> uint(v-1) & 1
			}
			if sum%2 != p[j] {
				ok = false
				break
			}
		}
		if ok {
			ans++
		}
	}
	fmt.Println(ans)
}


package main

import (
        "fmt"
)

func solution(n, m int, k, p []int, s [][]int) int {

        out := 0

        for a := 0; a < 1<<uint(n); a++ {
                var ok bool = true
                for i := 0; i < m; i++ {
                        c := 0
                        for j := range s[i] {
                                if (a>>uint(j))&1 == 1 {
                                        c++
                                }
                        }
                        c %= 2
                        if c != p[i] {
                                ok = false
                        }
                }
                if ok {
                        out++
                }
        }
        return out
}

func main() {
        var n, m int
        fmt.Scan(&n, &m)
        k := make([]int, m)
        s := make([][]int, m)
        for i := range k {
                fmt.Scan(&k[i])
                s[i] = make([]int, k[i])
                for j := range s[i] {
                        fmt.Scan(&s[i][j])
                }
        }
        p := make([]int, m)
        for i := range p {
                fmt.Scan(&p[i])
        }
        fmt.Println(solution(n, m, k, p, s))
}


package main

import (
        "fmt"
)

func solution(n, m int, k, p []int, s [][]int) int {

        out := 0

        for a := 0; a < 1<<uint(n); a++ {
                var ok bool = true
                for i := 0; i < m; i++ {
                        c := 0
                        for j := range s[i] {
                                if a>>uint(j)&1 == 1 {
                                        c++
                                }
                        }
                        c %= 2
                        if c != p[i] {
                                ok = false
                        }
                }
                if ok {
                        out++
                }
        }
        return out
}

func main() {
        var n, m int
        fmt.Scan(&n, &m)
        k := make([]int, m)
        s := make([][]int, m)
        for i := range k {
                fmt.Scan(&k[i])
                s[i] = make([]int, k[i])
                for j := range s[i] {
                        fmt.Scan(&s[i][j])
                }
        }
        p := make([]int, m)
        for i := range p {
                fmt.Scan(&p[i])
        }
        fmt.Println(solution(n, m, k, p, s))
}


package main

import (
        "fmt"
)

func solution(n, m int, k, p []int, s [][]int) int {

        out := 0

        for a := 0; a < 1<<uint(n); a++ {
                var ok bool = true
                for i := 0; i < m; i++ {
                        c := 0
                        for j := range s[i] {
                                if a>>uint(j)&1 == 0 {
                                        c++
                                }
                        }
                        c %= 2
                        if c != p[i] {
                                ok = false
                        }
                }
                if ok {
                        out++
                }
        }
        return out
}

func main() {
        var n, m int
        fmt.Scan(&n, &m)
        k := make([]int, m)
        s := make([][]int, m)
        for i := range k {
                fmt.Scan(&k[i])
                s[i] = make([]int, k[i])
                for j := range s[i] {
                        fmt.Scan(&s[i][j])
                }
        }
        p := make([]int, m)
        for i := range p {
                fmt.Scan(&p[i])
        }
        fmt.Println(solution(n, m, k, p, s))
}


=begin
－－－－－－－－－－－－－－
n = スイッチの数
m = 電球の数
k = 電球[i]に繋がっているスイッチ
a = スイッチを表す配列 (N個分)
pi = スイッチの最終状態
t = スイッチの押しパターンごとの電球の状態を記録
ans = 答えの数
－－－－－－－－－－－－－－
1: 各スイッチにどの電球が繋がっているのかを記録する
  1.1: i 番目の電球に繋がっている スイッチ k を受け取り、k をループする
    1.1.1: k 番目のスイッチ(a[k]) が繋がっている 電球[i]を 2進数で記録する (スイッチ k[j] には複数の 電球m[i] が繋がっている可能性のあるため ビットOR で受け取る)
2: スイッチの最終状態 pi を 2 進数で 受け取る
3: スイッチの押しパターンを全て試す
  3.1: パターンごとに 電球の状態 t を記録し、スイッチの最終状態 pi と一致すれば ans += 1
4: ans を出力
=end

n, m = gets.split.map(&:to_i)
a = Array.new(n,0)
pi = 0
ans = 0

for i in 0..(m-1) do
  k = gets.split.map{|v| v.to_i - 1}
  k.shift()
  k.each do |j|
    a[j] |=  1<<i
  end
end

a_pi = gets.split.map(&:to_i)
a_pi.each_with_index do |x, i|
  pi |= x << i
end

s = 0;
while(s < (1<<n)) do
  t = 0;
  for i in 0..(n-1) do
    if s[i] != 0
      t ^= a[i];
    end
  end
  ans += 1 if t == pi
  s += 1
end

puts ans


N,M = gets.split.map &:to_i
switches = Array.new(N,0)
M.times{ |j|
  k,*s = gets.split.map &:to_i
  s.each{ |i| switches[i-1] += (1 << j) }
}
P = gets.split.reverse.join.to_i(2)
p (0...(1<<N)).count{ |s|
  t = 0
  (0...N).each{ |i|
    t ^= switches[i] if (s & (1 << i)) > 0
  }
  t == P
}


N, M = gets.split.map(&:to_i)
sw = [0] * -~N
M.times do |i|
	gets.split.map(&:to_i)[1..-1].each do |s|
		sw[s-1] |= 1 << i
	end
end
#p sw
#p b

pp =  gets.tr(" ",?_).reverse.to_i(2)
res = -(pp-1 >> 20)
1.upto(N) do |n|
	N.times.to_a.combination(n) do |x|
#		p [x, sw.values_at(*x),sw.values_at(*x).inject(:^)]
		res += 1 if sw.values_at(*x).inject(:^) == pp
	end
end
p res


n,m=gets.split.map(&:to_i)
k=[]
m.times do
  k<<gets.split.map(&:to_i)
end
p=gets.split.map(&:to_i)
switch=0
ans=0
can=0
s=[0,1].repeated_permutation(n).to_a
s.each do |s|
  can=0
  m.times do |i|
    1.upto(k[i][0]) do |j|
      switch+=s[k[i][j]-1]
    end
    if switch%2==p[i]
      can+=1
    end
  end
  if can==m
    ans+=1
  end
end
puts ans


n,m=gets.split.map(&:to_i)
k=[]
m.times do
  k<<gets.split.map(&:to_i)
end
p=gets.split.map(&:to_i)
switch=0
ans=0
can=0
s=[0,1].repeated_permutation(n).to_a
s.each do |s|
  can=0
  m.times do |i|
    1.upto(k[i][0]) do |j|
      switch+=s[k[i][j]-1]
    end
    if switch%2==p[i]
      can+=1
    else
      break
    end
  end
  if can==m
    ans+=1
  end
end
puts ans


n,m=gets.split.map(&:to_i)
k=[]
m.times do
  k<<gets.split.map(&:to_i)
end
switch=0
ans=0
can=false
p=gets.split.map(&:to_i)
s=[0,1].repeated_permutation(n).to_a
s.each do |s|
  m.times do |i|
    can=false
    1.upto(k[i][0]) do |j|
      switch+=s[k[i][j]-1]
    end
    if switch%2==p[i]
      can=true
    else
      break
    end
  end
  if can
    ans+=1
  end
end
puts ans


use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("filed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: usize = read();
    let m: usize = read();
    let mut s = vec![vec![]; m];
    for i in 0..m {
        let k: usize = read();
        for _ in 0..k {
            // sにはk個の各スイッチの1～Nの番号
            let a = read::<usize>() - 1;
            s[i].push(a);
        }
    }
    let p: Vec<usize> = (0..m).map(|_| read()).collect();

    let mut res = 0;
    for bit in 0..1 << n {
        let mut ok = true;
        for (i, switch) in s.iter().enumerate() {
            let mut con = 0;
            for &j in switch.iter() {
                if bit & 1 << j == 1 << j {
                    con += 1;
                }
            }
            if con % 2 != p[i] {
                ok = false;
                break;
            }
        }
        if ok {
            res += 1;
        }
    }
    println!("{}", res);
}


use std::io::*;
use std::str::FromStr;

//https://qiita.com/tubo28/items/e6076e9040da57368845
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn rec(
    n: usize,
    m: usize,
    status: &mut Vec<usize>,
    mut ans: u32,
    switch: &Vec<Vec<usize>>,
    p: &Vec<u32>,
) -> u32 {
    //最深まで探索し、状態を判定する
    if status.len() == n {
        let mut light = vec![false; m];
        for i in 0..m {
            let mut on = 0;
            for j in switch[i].iter() {
                if (status[*j - 1]) == 1 {
                    on += 1;
                }
            }
            //点灯の確認
            //println!("on{}",on);
            if on % 2 == p[i]{
                light[i] = true;
            }
        }
        //全点灯の確認
        if light.iter().all(|c| *c == true) {
            ans += 1;
        }
        //println!("ans{} status{:?}",ans,status);
    } else {
        //再帰全探索
        for c in 0..2 {
            status.push(c);
            ans = rec(n, m, status, ans, switch, p);
            status.pop();
        }
    }

    return ans;
}
fn main() {
    let n: usize = read();
    let m: usize = read();
    let mut switch: Vec<Vec<usize>> = vec![vec![0; 0]; m]; //m個の空のvecを用意

    for i in 0..m {
        let k: usize = read();
        for _ in 0..k {
            let s: usize = read();
            switch[i].push(s);
        }
    }
    let p: Vec<u32> = (0..m).map(|_| read()).collect();

    let mut status = Vec::new();
    let ans = rec(n, m, &mut status, 0, &switch, &p);
    print!("{}", ans);
}


use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("filed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let n: usize = read();
    let m: usize = read();
    let mut s = vec![vec![]; m];
    for i in 0..m {
        let k: usize = read();
        for _ in 0..k {
            // sにはk個の各スイッチの1～Nの番号
            let a = read::<usize>() - 1;
            s[i].push(a);
        }
    }
    let p: Vec<usize> = (0..m).map(|_| read()).collect();

    let mut res = 0;
    for bit in 0..1 << n {
        let mut ok = true;
        for (i, switch) in s.iter().enumerate() {
            let mut con = 0;
            for &i in switch.iter() {
                if bit & 1 << i == 1 << i {
                    con += 1;
                }
            }
            if con % 2 != p[i] {
                ok = false;
                break;
            }
        }
        if ok {
            res += 1;
        }
    }
    println!("{}", res);
}


// -*- coding:utf-8-unix -*-

use proconio::input;
use std::collections::HashSet;

fn main() {
    input! {
        n: usize,
        m: usize,
    }
    let mut k = vec![];
    let mut s = vec![];
    for _ in 0..m {
        input! {
            a: usize,
            b: [u16; a],
        }
        k.push(a);
        s.push(b);
    }
    input! {
        p: [u16; m],
    }
    // println!("k: {:?}", k);
    // println!("s: {:?}", s);
    // println!("p: {:?}", p);

    let mut ans = 0;
    for bit_row in 0..2u32.pow(n as u32) {
        // println!("{:b}", bit_row);
        let mut selected = HashSet::new();
        for i in 0..n {
            if (bit_row & (1 << i)) > 0 {
                selected.insert(i as u16);
            }
        }
        // println!("on: {:?}", selected);

        if selected.len() == 0 {
            if p.iter().all(|&a| a == 0) {
                ans += 1;
            }
        }

        for i in 0..m {
            let mut swsum = 0;
            for j in 0..k[i] {
                // println!("sij: {}", s[i][j]);
                if selected.contains(&(s[i][j] - 1)) {
                    swsum += 1;
                }
            }
            // println!("{}: {}", i, swsum);
            if swsum % 2 != p[i] {
                break;
            }

            if i == m - 1 {
                ans += 1;
            }
        }
    }
    println!("{}", ans);
}


fn solve(ksss: Vec<Vec<u64>>, ps: Vec<u64>, n: usize) -> usize {
    let mut result = 0;
    let sss: Vec<Vec<u64>> = ksss.iter()
        .map(|kss| kss.iter().skip(1).map(|s| s - 1).collect::<Vec<_>>())
        .collect();

    for bins in binary_combinations(n) {
        if (0..ps.len()).all(|i| sss[i].iter().zip(&bins).filter(|(_, &bin)| bin).count() % 2 == ps[i] as usize) {
            result += 1
        }
    }

    result
}

fn binary_combinations(n: usize) -> Vec<Vec<bool>> {
    fn rec(n: usize, mut acc: Vec<Vec<bool>>) -> Vec<Vec<bool>> {
        if n == 0 {
            acc
        } else {
            let mut tmp = acc.clone();
            acc.iter_mut().for_each(|v| v.push(false));
            tmp.iter_mut().for_each(|v| v.push(true));
            acc.extend(tmp);

            rec(n - 1, acc)
        }
    }

    rec(n, vec![vec![]])
}

fn main() {
    let (n, m) = read_tup2();
    let ksss = read_vec_n(m);
    let ps = read_vec();

    println!("{}", solve(ksss, ps, n));
}

fn read_tup2<T: std::str::FromStr + Copy>() -> (T, T) {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    let v = s.trim().split_whitespace()
        .map(|c| c.parse().ok().unwrap())
        .collect::<Vec<T>>();
    (v[0], v[1])
}

fn read_vec_n<T: std::str::FromStr>(n: usize) -> Vec<Vec<T>> {
    let mut ss = String::new();
    for _ in 0..n {
        std::io::stdin().read_line(&mut ss).ok();
    }
    let mut v = ss.split("\n").collect::<Vec<&str>>();
    v.pop();
    v.iter()
        .map(
            |s| {
                s.trim().split_whitespace()
                    .map(|c| c.parse().ok().unwrap())
                    .collect()
            }
        )
        .collect()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().split_whitespace()
        .map(|c| c.parse().ok().unwrap())
        .collect()
}


use proconio::input;
use proconio::marker::Usize1;
use std::collections::HashMap;

fn main() {
  input! {
    n: usize,
    m: usize,
  }

  let mut map: HashMap<usize, Vec<usize>> = HashMap::new();
  for i in 0..m {
    input! {
      nn: usize,
      switches: [Usize1;nn]
    }
    map.insert(i, switches.into_iter().collect::<Vec<usize>>());
  }

  input! {
    needs: [usize;m]
  }

  let mut total = 0;
  for mut i in 0..2usize.pow(n as u32) {
    let mut ons: Vec<usize> = vec![0;n];
    let mut index = 0;
    while 0 <  i {
      if i & 1 == 1 {
        ons[index] = 1;
      }
      index += 1;
      i >>= 1;
    }

    let mut flag = true;
    for (index, key) in map.keys().enumerate() {
      let mut sum = 0;
      for ii in map.get(key).unwrap() {
        if ons[*ii] == 1 {
          sum += 1;
        }
      }
      if sum % 2 != needs[index] {
        flag = false;
      }
    }

    if flag {
      total += 1;
    }
  }
  println!("{}", total);
}


func readInts() -> [Int]{
    return readLine()!.split(separator: " ").map{Int($0)!};
}
let a = readInts();
let N = a[0], M = a[1];
var A: Array<Array<Int>> = Array();
for i in 0 ..< M {
    let b = readInts();
    A.append([Int]());
    for j in 0 ..< N {
        A[i].append(0);
    }
    for j in 1 ... b[0] {
        A[i][b[j]-1] = 1;
    }
}
var answer = 0;
let p = readInts();
for bit in 0 ..< (1<<N) {
    var rock = 0;
    var check: Array<Int> = Array(repeating: 0, count: 12);
    for i in 0 ..< N {
        if bit & 1<<i > 0 {
            check[i] = 1;
        }
    }
    for i in 0 ..< M {
        var count = 0;
        for j in 0 ..< N {
            if check[j] == 1 && A[i][j] == 1 {
                count += 1;
            }
        }
        if count % 2 == p[i] {
            rock += 1;
        }
    }
    if rock == M {
        answer += 1;
    }
}
print(answer);


func readInts() -> [Int]{
    return readLine()!.split(separator: " ").map{Int($0)!};
}
let a = readInts();
let N = a[0], M = a[1];
var A: Array<Array<Int>> = Array();
for i in 0 ..< a[1] {
    let b = readInts();
    let k = b[0];
    A.append([Int]());
    for j in 0 ..< N {
        A[i].append(0);
    }
    for j in 1 ... k {
        A[i][b[j]-1] = 1;
    }
}
var answer = 0;
let p = readInts();
for bit in 0 ..< (1<<N) {
    var rock = 0;
    var check: Array<Int> = Array(repeating: 0, count: 12);
    for i in 0 ..< N {
        if bit & 1<<i > 0 {
            check[i] = 1;
        }
    }
    for i in 0 ..< M {
        var count = 0;
        for j in 0 ..< N {
            if check[j] == 1 && A[i][j] == 1 {
                count += 1;
            }
        }
        if count % 2 == p[i] {
            rock += 1;
        }
    }
    if rock == M {
        answer += 1;
    }
}
print(answer);


// 🐋💭
import Foundation

func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}

func readInt() -> Int {
    return Int(readLine()!)!
}

func readDoubles () -> [Double] {
    return readLine()!.split(separator: " ").map { Double($0)! }
}

func readDouble() -> Double{
    return Double(readLine()!)!
}

func readLines() -> [String] {
    return readLine()!.map { String($0) }
}
///最大公約数を返す
func gcd(_ m:Int, _ n:Int) -> Int {
    if n == 0 {return m}
    return gcd(n, m % n)
}

///最大公約数を返す
func gcd(_ array: [Int]) -> Int {
    var value = array[0]
    if array.count > 1 {
        for i in 1..<array.count {
            value = gcd(value, array[i])
        }
    }
    return value
}

///最小公倍数を返す
func lcm(_ m:Int, _ n:Int) -> Int {
    let g = gcd(m, n)
    return m / g * n
}

///素数判定(試し割り)
func isPrime(_ x:Int) -> Bool {
    if x <= 1 || x % 2 == 0 { return false }
    if x == 2 { return true }
    for i in stride(from: 3, to: Int(ceil(sqrt(Double(x)))), by: 2){
        if x % i == 0 {
            return false
        }
    }
    return true
}

//https://program-life.com/669
///実行速度の計測
func exectionTime(action: () -> Void) {
    let startDate = Date()
    action()
    let endDate = Date()
    print(endDate.timeIntervalSince(startDate))
}

//https://riptutorial.com/ja/swift/example/14738/インデックスを知らずに配列から要素を削除する
extension Array where Element: Equatable {

    mutating func remove(_ element: Element) {
        _ = firstIndex(of: element).flatMap {
            self.remove(at: $0)
        }
    }
}

func binarySearch(rifgt:Int, key:Int, ary:[String]) -> Int{
    var left = 0
    var right = rifgt

    while abs(right - left) > 1 {
        let mid = left + (right - left) / 2

        if Int(ary[mid])! < key {
            left = mid

        } else {
            right = mid
        }
    }
    return left
}

func arrangement (prev:String, ary:[String], returnVal:[String]) -> [String] {
    var returnVal = returnVal
    if ary.count == 0 {
        returnVal.append(prev)
        return returnVal
    }

    for s in ary {
        let wprev = prev + s
        var wary = ary
        wary.remove(s)
        returnVal = arrangement(prev: wprev, ary: wary, returnVal: returnVal)
    }
    return returnVal
}
// https://algo-logic.info/divisor/
/// 約数の配列を返す
func divisor(_ n:Int) -> [Int] {
    var ret = [Int]()
    var i = 1
    while i * i <= n {
        if n % i == 0 {
            ret.append(i)
            if i * i != n {
                ret.append(n / i)
            }
        }
        i += 1
    }
    return ret.sorted()
}

/// 1〜nまでの数字からなる辞書順列のm番目の順列を返す
func permutation(_ n: Int, _ m: Int) -> [Int] {
    var m = m

    var temp = [Int](repeating: 0, count: n)
    var surplus = [Int](repeating: 0, count: n)

    for i in 1...n {
        temp[i - 1] = i

        surplus[n - i] = m % i
        m = m / i
    }

    var order = [Int](repeating: 0, count: n)

    for i in 0..<n {
        order[i] = temp[surplus[i]]
        var j = surplus[i]
        while j + 1 < n {
            temp[j] = temp[j + 1]
            j += 1
        }
    }
    return order
}
func mod() -> Int {
    return Int(pow(10.0, 9.0)) + 7
}

func nPk(_ n: Int, _ k: Int) -> Int {
    var (n, k) = (n, k)
    var res = 1
    while k > 0 {
        res *= n
        res %= mod()
        n -= 1
        k -= 1
    }
    return res
}

func main() {
    let input = readInts()
    let (N, M) = (input[0], input[1])
    /// 1であればその添字のスイッチに接続されている
    var pair = [[Int]](repeating: [Int](repeating: 0, count: N), count: M)
    for i in 0..<M {
        let input = readInts()
        // input[0]はk
        for j in 1...input[0] {
            pair[i][input[j] - 1] = 1
        }
    }
    let p = readInts()
    //＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿ここまで入力
    var ans = 0
    for i in 0..<1<<N {
        /// 0…OFF、1…ON
        var stateSwitches = [Int](repeating: 0, count: N)
        for j in 0..<N {
            if (i>>j) & 1 == 1 {
                stateSwitches[j] = 1
            }
        }

        var flag = true
        var cnt = 0
        while cnt < M && flag {
            var switchCount = 0
            for j in 0..<N {
                if pair[cnt][j] == 1 && stateSwitches[j] == 1 {
                    switchCount += 1
                }
            }
            if switchCount % 2 != p[cnt] {
                flag = false
            }
            cnt += 1
        }
        if flag {
            ans += 1
        }
    }
    print(ans)
}
main()


import Foundation

// 標準入力からnとmを受け取る
let nm = readLine()!.split(separator:" ").map{Int($0)!}
let n = nm[0]
let m = nm[1]

// 標準入力からkとsを受け取る
// 要素がすべて0で初期化されたn*mの2次元配列Sを用意
var S = [[Int]](repeating:[Int](repeating:0, count:m), count:n)
// Sに入力値を入れていく
for i in 0..<m{
    let s = readLine()!.split(separator:" ").map{Int($0)!}
    // s[0]==k
    for j in 0...s[0]{
        // kは除く
        if j == 0 {
            continue
        }
        S[s[j]-1][i] = 1
    }
}

// 標準入力からpを受け取る (答えの配列)
let p = readLine()!.split(separator:" ").map{Int($0)!}

// 答えを入れる変数を用意
var ans = 0

// 要素数nの集合についてbit全探索を行う
// 0~n^2のループ
for bit in 0..<(1<<n){

    // 電球の状態を持つ配列 (点灯しているなら1,消えているなら0)
    var check = [Int](repeating:0, count:m)

    // 順に左にシフトさせ最下位bitのチェックを行う
    for i in 0..<n{

        // フラグが立っているかどうかの判定
        if 1<<i > 0 {

            // フラグが立っていた時の処理 (フラグが立つ = スイッチを入れる)
            // 各電球に対して全探索
            for j in 0..<m{

                // S[i][j] == 1ならばスイッチと電球はつながっている
                // スイッチを入れると点灯と消灯が反転する
                if S[i][j] == 1 && check[j] == 1{
                    check[j] = 0
                }
                else if S[i][j] == 1 && check[j] == 0{
                    check[j] = 1
                }
            }
        }
    }

    // 一致しているならすべて点灯している
    if p == check{
        ans += 1
    }
}

// 答えの出力
print(ans)


import Foundation

// 標準入力からnとmを受け取る
let nm = readLine()!.split(separator:" ").map{Int($0)!}
let n = nm[0]
let m = nm[1]

// 標準入力からkとsを受け取る
// 要素がすべて0で初期化されたn*mの2次元配列Sを用意
var S = [[Int]](repeating:[Int](repeating:0, count:m), count:n)
// Sに入力値を入れていく
for i in 0..<m{
    let s = readLine()!.split(separator:" ").map{Int($0)!}
    // s[0]==k
    for j in 0...s[0]{
        // kは除く
        if j == 0 {
            continue
        }
        S[j-1][i] = 1
    }
}

// 標準入力からpを受け取る (答えの配列)
let p = readLine()!.split(separator:" ").map{Int($0)!}

// 答えを入れる変数を用意
var ans = 0

// 要素数nの集合についてbit全探索を行う
// 0~n^2のループ
for bit in 0..<(1<<n){

    // 電球の状態を持つ配列 (点灯しているなら1,消えているなら0)
    var check = [Int](repeating:0, count:m)

    // 順に左にシフトさせ最下位bitのチェックを行う
    for i in 0..<n{

        // フラグが立っているかどうかの判定
        if bit & 1<<i > 0 {

            // フラグが立っていた時の処理 (フラグが立つ = スイッチを入れる)
            // 各電球に対して全探索
            for j in 0..<m{

                // S[i][j] == 1ならばスイッチと電球はつながっている
                // スイッチを入れると点灯と消灯が反転する
                if S[i][j] == 1 && check[j] == 1{
                    check[j] = 0
                }
                else if S[i][j] == 1 && check[j] == 0{
                    check[j] = 1
                }
            }
        }
    }

    // 一致しているならすべて点灯している
    if p == check{
        ans += 1
    }
}

// 答えの出力
print(ans)


import Foundation

// 標準入力からnとmを受け取る
let nm = readLine()!.split(separator:" ").map{Int($0)!}
let n = nm[0]
let m = nm[1]

// 標準入力からkとsを受け取る
// 要素がすべて0で初期化されたn*mの2次元配列Sを用意
var S = [[Int]](repeating:[Int](repeating:0, count:m), count:n)
// Sに入力値を入れていく
for i in 0..<m{
    let s = readLine()!.split(separator:" ").map{Int($0)!}
    // s[0]==k
    for j in 0...s[0]{
        // kは除く
        if j == 0 {
            continue
        }
        S[j-1][i] = 1
    }
}

// 標準入力からpを受け取る (答えの配列)
let p = readLine()!.split(separator:" ").map{Int($0)!}

// 答えを入れる変数を用意
var ans = 0

// 要素数nの集合についてbit全探索を行う
// 0~n^2のループ
for bit in 0..<(1<<n){

　　// 電球の状態を持つ配列(点灯しているなら1,消えているなら0)
    var check = [Int](repeating:0, count:m)

    // 順に左にシフトさせ最下位bitのチェックを行う
    for i in 0..<n{

        // フラグが立っているかどうかの判定
        if bit & 1<<i > 0 {

            // フラグが立っていた時の処理 (フラグが立つ = スイッチを入れる)
            // 各電球に対して全探索
            for j in 0..<m{

                // S[i][j] == 1ならばスイッチと電球はつながっている
                // スイッチを入れると点灯と消灯が反転する
                if S[i][j] == 1 && check[j] == 1{
                    check[j] = 0
                }
                else if S[i][j] == 1 && check[j] == 0{
                    check[j] = 1
                }
            }
        }
    }

    // 一致しているならすべて点灯している
    if p == check{
        ans += 1
    }
}

// 答えの出力
print(ans)


export class Main {
  static main(input): string {
    const tmp: string[] = input.split("\n");
    const [n, m]: number[] = tmp[0].split(" ").map(Number);
    const p: number[] = tmp[m + 1].split(" ").slice(0, m).map(Number);
    const list: ((onList: number[]) => boolean)[] = [];
    for (let i = 1; i <= m; ++i) {
      const [k, ...sList]: number[] = tmp[i].split(" ").map(Number);
      const tmpS: number[] = sList.slice(0, k).map(s => s - 1);
      const tmpP: number = p[i - 1];
      list.push(onList => {
        let t: number = 0;
        for (let j = 0, len = tmpS.length; j < len; ++j) {
          t += onList[tmpS[j]];
        }
        return t % 2 == tmpP;
      });
    }
    let result: number = 0;
    for (let i = 0, len = Math.pow(2, n); i < len; ++i) {
      const indexList: number[] = [];
      for (let j = 1; j < len; j *= 2) {
        indexList.push((i & j) == j ? 1 : 0);
      }
      if (list.every(f => f(indexList))) {
        ++result;
      }
    }
    return `${result}`;
  }

}
console.log(Main.main(require("fs").readFileSync("/dev/stdin", "utf8")));


const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};
const main=()=>{
  let [n,m]=tnn(2),st=[]
  for(let i=0;i<m;i++){
    let h=tn()
    st.push(tnn(h))
  }
  let p=tnn(m),c=0
  for(let i=0;i<(1<<n);i++){
    let bit=i.toString(2),f=true
    for(let j=0;j<st.length;j++){
      let on=0
      for(let k=0;k<st[j].length;k++){
        if(i & 1<<st[j][k]-1)on++
      }
      if(on%2!=p[j])f=false
    }
    if(f)c++
  }
  to(c)
}
main()


const log = console.log;

const createScanFunctions = (input: string) => {
  const str = input.trim();
  const len = str.length;
  let index = 0;

  const scan = () => {
    const startIndex = index;

    while (index < len) {
      const char = str[index];

      if (char === " " || char === "\n")
        return str.substring(startIndex, index++);

      index++;
    }

    return str.substr(startIndex);
  };

  const scanInt = () => parseInt(scan());

  return { scan, scanInt };
};

const scanArray = <T>(scanFunction: () => T, length: number) => {
  const array = new Array<T>(length);
  for (let i = 0; i < length; i++) array[i] = scanFunction();

  return array;
};

// ----

const countSetBits = (bits: number, length = 32): number => {
  let count = 0;

  for (let i = 0; i < length; i += 1) {
    if ((bits & 1) === 1) count += 1;
    bits >>>= 1;
  }

  return count;
};

// ----

function Main(input: string): void {
  const { scanInt } = createScanFunctions(input);

  const n = scanInt();
  const m = scanInt();

  /**
   * Bits to be checked for each light.
   */
  const kBits = new Array<number>(m);

  /**
   * Should be referred by a switch index.
   */
  const kBitArray = [
    0b0000000001,
    0b0000000010,
    0b0000000100,
    0b0000001000,
    0b0000010000,
    0b0000100000,
    0b0001000000,
    0b0010000000,
    0b0100000000,
    0b1000000000
  ];

  for (let lightIndex = 0; lightIndex < m; lightIndex++) {
    kBits[lightIndex] = 0;
    const k = scanInt();

    for (let i = 0; i < k; i++) {
      const s = scanInt(); // switch number
      kBits[lightIndex] += kBitArray[s - 1];
    }
  }

  const p = scanArray(scanInt, m);

  const allLightsOn = (switchBits: number) => {
    for (let lightIndex = 0; lightIndex < m; lightIndex++) {
      const onSwitchCount = countSetBits(switchBits & kBits[lightIndex]);
      if (onSwitchCount % 2 === p[lightIndex]) continue;

      return false;
    }

    return true;
  };

  // validate each switch pattern
  let validPatternCount = 0;
  const len = Math.pow(2, n);

  for (let switchBits = 0; switchBits < len; switchBits++) {
    if (allLightsOn(switchBits)) validPatternCount++;
  }

  log(validPatternCount);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
  const data = input.split("\n");
  const [n, m] = data[0].split(" ").map(n => Number(n));
  const ps = data[m+1].split(" ").map(n => Number(n));
  let result = 0;
    for (let i = 0; i < 2 ** n; i++) {
        let str = i.toString(2);
        for (let tmp = 0; tmp < m - str.length; tmp++) {
            str = "0" + str;
        }
    const switches = str.split("").map(s => Number(s));
    let isOk = true;
    for (let j = 1; j <= m; j++) {
    	const sList = data[j].split(" ");
      	let onNum = 0;
      	for (let k = 1; k <= sList[0]; k++) {
          if (switches[sList[k] - 1] === 1) onNum++;
        }
      	if (onNum%2 !== ps[j-1]) {
          isOk = false;
          break;
        }
      }
    if (isOk) result++;
  }
  console.log(result);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


a, b = map(str, input().split())
if a < b:
    print('<')
elif a > b:
    print('>')
else:
    print('=')


A,B = input().split()
if A>B:
  print(">")
elif A==B:
  print("=")
else:
  print("<")


#!/usr/bin/env python
x, y = input().split()

if x<y:
    print('<')
elif x>y:
    print('>')
else:
    print('=')


A=1
B=2
C=3
D=4
E=5
F=6
X,Y=input().split()
if X<Y:
  pritn("<")
elif X>Y:
  print(">")
elif X==Y:
  print("=")


x,y = map(ord,input().split())
print("<" if x < y else ">")


a, b = input().split()
if a < b:
    print('<')
elsif a > b:
 	print('>')
else:
  	print('=')


import java.io.*;
import java.util.*;
class Main{
	static final long MOD = 1_000_000_007; // 10^9+7
    static final int MAX = 2_147_483_646; // intMax
    static final int INF = 1_000_000_000; // 10^9
    public static void main(String[] args) throws Exception {
		hayami saori = new hayami();
		String s = saori.nextHayami();
		char x = s.charAt(0);
		s = saori.nextHayami();
		char y = s.charAt(0);
		if(x > y)System.out.println(">");
		else if(x < y) System.out.println("<");
		else System.out.println("=");
		saori.close();
    }
}

class hayami implements Closeable {
	private final InputStream in = System.in;
	private final byte[] hayami = new byte[1024];
	private int Hayami = 0;
	private int saori = 0;
	private boolean HayamiSaori() {
		if (Hayami < saori) {
			return true;
		}else{
			Hayami = 0;
			try {
				saori = in.read(hayami);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (saori <= 0) {
				return false;
			}
		}
		return true;
	}
	private int SaoriHayami() {
		if (HayamiSaori()) {
            return hayami[Hayami++];
         }else{
             return -1;
         }
	}
	private static boolean hayami_saori(int hayami) {
		return 33 <= hayami && hayami <= 126;
	}
	public boolean hayamisaori() {
		while(HayamiSaori() && !hayami_saori(hayami[Hayami])) Hayami++; return HayamiSaori();
	}
	public String nextHayami() {
		if (!hayamisaori()) throw new NoSuchElementException();
		StringBuilder hayamin = new StringBuilder();
		int saori = SaoriHayami();
		while(hayami_saori(saori)) {
			hayamin.appendCodePoint(saori);
			saori = SaoriHayami();
		}
		return hayamin.toString();
	}
	public long saorihayami() {//nextLong
		if (!hayamisaori()) throw new NoSuchElementException();
		long hayami = 0;
		boolean misao = false;
		int saori = SaoriHayami();
		if (saori == '-') {
			misao = true;
			saori = SaoriHayami();
		}
		if (saori < '0' || '9' < saori) {
			throw new NumberFormatException();
		}
		while(true){
			if ('0' <= saori && saori <= '9') {
				hayami *= 10;
				hayami += saori - '0';
			}else if(saori == -1 || !hayami_saori(saori)){
				return misao ? -hayami : hayami;
			}else{
				throw new NumberFormatException();
			}
			saori = SaoriHayami();
		}
	}
	public int saori_hayami() {//nextInt
		long hayami = saorihayami();
		if (hayami < Integer.MIN_VALUE || hayami > Integer.MAX_VALUE) throw new NumberFormatException();
		return (int) hayami;
	}
	public double Hayamin() { //nextDouble
		return Double.parseDouble(nextHayami());
	}
	public void close() {
		try {
			in.close();
		} catch (IOException e) {
		}
    }

}


import java.util.*;
import java.io.*;

class Main{
    public static void main(String[] args){
        FastScanner fsc=new FastScanner();
        char x=fsc.next().charAt(0);
        char y=fsc.next().charAt(0);
        fsc.close();
        if(x<y) System.out.println('<');
        else if(x>y) System.out.println('>');
        else System.out.println('=');
    }
    static class FastScanner {
        private final InputStream in = System.in;
        private final byte[] buffer = new byte[1024];
        private int ptr = 0;
        private int buflen = 0;
        private boolean hasNextByte(){
            if(ptr<buflen) return true;
            else{
                ptr = 0;
                try{
                    buflen = in.read(buffer);
                }
                catch(IOException e){
                    e.printStackTrace();
                }
                if(buflen<=0) return false;
            }
        return true;
        }
        private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
        private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
        public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
        public String next() {
            if (!hasNext()) throw new NoSuchElementException();
            StringBuilder sb = new StringBuilder();
            int b = readByte();
            while(isPrintableChar(b)) {
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }
        public long nextLong() {
            if (!hasNext()) throw new NoSuchElementException();
            long n = 0;
            boolean minus = false;
            int b = readByte();
            if (b == '-') {
                minus = true;
                b = readByte();
            }
            if (b < '0' || '9' < b) throw new NumberFormatException();
            while(true){
                if ('0' <= b && b <= '9') {
                    n *= 10;
                    n += b - '0';
                }
                else if(b == -1 || !isPrintableChar(b)) return minus ? -n : n;
                else throw new NumberFormatException();
                b = readByte();
            }
        }
        public int nextInt() {
            long nl = nextLong();
            if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
            return (int) nl;
        }
        public double nextDouble() { return Double.parseDouble(next());}
        public void close(){
            try{in.close();}
            catch(IOException e){e.printStackTrace();}
        }
    }
}


import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;

public class Main {
	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		String x = sc.next();
		String y = sc.next();
		if(x.compareTo(y) == 0) {
			System.out.println("=");
		} else if(x.compareTo(y) > 0) {
			System.out.println(">");
		} else if(x.compareTo(y) < 0) {
			System.out.println("<");
		}
	}
}

class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;

	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		} else {
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) {
				return false;
			}
		}
		return true;
	}

	private int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	private static boolean isPrintableChar(int c) {
		return 33 <= c && c <= 126;
	}

	private void skipUnprintable() {
		while (hasNextByte() && !isPrintableChar(buffer[ptr]))
			ptr++;
	}

	public boolean hasNext() {
		skipUnprintable();
		return hasNextByte();
	}

	public String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (isPrintableChar(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) {
			throw new NumberFormatException();
		}
		while (true) {
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			} else if (b == -1 || !isPrintableChar(b)) {
				return minus ? -n : n;
			} else {
				throw new NumberFormatException();
			}
			b = readByte();
		}
	}

	public int nextInt() {
		long nl = nextLong();
		if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
			throw new NumberFormatException();
		return (int) nl;
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}

}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String X =sc.next();
        String Y =sc.next();
        int numX;
        int numY;

        if(X.equals("A")){
            numX=1;
        }else if(X.equals("B")){
            numX=2;
        }else if(X.equals("C")){
            numX=3;
        }else if(X.equals("D")){
            numX=4;
        }else if(X.equals("E")){
            numX=5;
        }else if(X.equals("F")){
            numX=6;
        }//else{
         //   numX=0;
        //}

        if(Y.equals("A")){
            numY=1;
        }else if(Y.equals("B")){
            numY=2;
        }else if(Y.equals("C")){
            numY=3;
        }else if(Y.equals("D")){
            numY=4;
        }else if(Y.equals("E")){
            numY=5;
        }else if(Y.equals("F")){
            numY=6;
        }//else{
           // numY=0;

        //}

        if(numX<numY){
            System.out.println("<");
        }else if(numX>numY){
            System.out.println(">");
        }else{
            System.out.println("=");
        }

   }
}


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String a = sc.next();
        String b = sc.next();

        if(a.equals(b)){
            System.out.print("=");
        }else if(a.compareTo(b)==-1){
            System.out.print("<");
        }else{
            System.out.print(">");
        }
   }
}


import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(System.in);
    	String s1 = sc.next();
        String s2 = sc.next();
        int n1 = (int)s1.charAt(0);
        int n2 = (int)s2.charAt(0);
        if(n1 > n2){
        	System.out.println(">");
        }else if(n1 < n2){
        	System.out.println("<");
        }else{
        	System.out.println("=");
        }
    }
}


#include<stdio.h>
int main(){
	char x,y;
	scanf("%c %c",&x,&y);
	if(x>y) printf(">\n");
	else if(x<y) printf("<\n");
	else printf("=\n");
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
char s1[1000],s2[1000];
int l1,l2,i;
int main()
{
  scanf("%s%s",s1,s2);
  l1=strlen(s1);l2=strlen(s2);
  if (l1<l2) {printf("<\n");return 0;}
  if (l1>l2) {printf(">\n");return 0;}
  for (i=0;i<l1;i++)
  {
    if (s1[i]>s2[i]) {printf(">\n");return 0;}
    if (s1[i]<s2[i]) {printf("<\n");return 0;}
  }
  printf("=\n");
}


#include <cstdio>
using namespace std;
char str[2][5];
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%s%s",str[0],str[1]);
	if (str[0][0]==str[1][0]) puts("="); else puts(str[0][0]>str[1][0]?">":"<");
	return 0;
}


#include<bits/stdc++.h>

#define Vsort(a) sort(a.begin(), a.end())
#define Vreverse(a) reverse(a.begin(), a.end())
#define Srep(n) for(int i = 0; i < (n); i++)
#define Lrep(i,a,n) for(int i = (a); i < (n); i++)
#define Brep(n) for(int bit = 0; bit < (1<<n); bit++)
#define rep2nd(n,m) Srep(n) Lrep(j,0,m)
#define vi vector<int>
#define vi64 vector<int64_t>
#define vvi vector<vector<int>>
#define vvi64 vector<vector<int64_t>>

using namespace std;

int main(){
  char a,b;
  cin >> a >> b;
  cout << (a > b ? ">" : "<") << endl;
}


#include <bits/stdc++.h>
using namespace std;

int main() {
  char A, B;
  cin >>A >>B;

  if(A<B)
  cout<<"<";

  else
  cout<<">";
}


#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
using namespace std;
int main() {
	char x, y;
	cin >> x >> y;
	if (x > y)
		cout << x << "\n";
	else
		cout << y << "\n";
}


#include <stdio.h>
int main(void)
{
    char x,y;
    scanf("%c %c",&x,&y);
    if(x==y)printf("=");
    else if(x>y)printf(">");
    else if(x<y)printf("<");
}


#include <stdio.h>

int main(int argc,char* argv[]){
    char x,y;
    scanf("%c %c",&x,&y);
    if(x<y)printf("<\n");
    else if (x>y) printf(">\n");
    else printf("=\n");
    return 0;
}


#include <stdio.h>

int main(void)
{
  char A,B;

  scanf("%c %c",&A,&B);

  if(A==B)
    printf("=\n");
  else if(A<B)
    printf("<\n");
  else
    printf(">\n");

  return 0;

}


#include<stdio.h>
int main(){
  char a,b;
  scanf("%d %d",&a,&b);

  if(a>b)
    printf(">");
  else if(a==b)
    printf("=");
  else
    printf("<");
  return 0;
}


#include<stdio.h>
int main()
{
    int hexa_ara[X,Y] = [A,B,C,D,E,F];
    scanf("%d %d", &X, &Y);
    if(X>Y)
    {
        printf("%d = >",X);
    }
    else if(X<Y){
            printf("%d = <",Y);
    }
    return 0;
}


#include<stdio.h>
int main()
{
    char x,y;
    scanf("%c%c",&x,&y);
    if(x<y){
        printf("<\n");
    }
    else if(x==y){
        printf("=\n");
    }
    else{
            printf(">\n");
            }
    return 0;
}


inp = require('fs').readFileSync('/dev/stdin', 'utf8').split('\n')
l = inp.shift().split(' ')
x = l[0]
y = l[1]
console.log(x == y ? '=' : x.charCodeAt() < y.charCodeAt() ? '<' : '>')


var input = require("fs").readFileSync("/dev/stdin", "utf8");

var words = input.split(' ');

var operand;
if (words[0][0] === words[1][0]) {
    operand = '=';
} else if (words[0] < words[1]) {
    operand = '<';
} else {
    operand = '>';
}
console.log(operand);


function Main(input) {
  input = input.trim()
  input = input.split(" ");
var a = parseInt(input[0],16);

var b = parseInt(input[1],16);
if(a<b){
  console.log("<")
}else if(a>b){
  console.log(">")
}else{
  console.log("=")
}

}Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function main(input) {
  input = input.trim();
  const a = input.split(" ").map(Number);
  if(a[0]>a[1]){
  	console.log('>');
  }else if(a[0]<a[1]){
  	console.log('<');
  }else{
  	console.log('=');
  }
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


var input = require("fs").readFileSync("/dev/stdin", "utf8");

var words = input.split(' ');

var operand;
if (words[0] === words[1]) {
    operand = '=';
} else if (words[0] < words[1]) {
    operand = '<';
} else {
    operand = '>';
}
console.log(operand);


package main

import (
	"fmt"
)

func main() {
	var x, y int
	fmt.Scanf("%x %x", &x, &y)
	switch {
	case x > y:
		fmt.Println(">")
	case x < y:
		fmt.Println("<")
	default:
		fmt.Println("=")
	}
}


package main

import (
	"fmt"
)

func main() {
	var X int
	var Y int

	fmt.Scanf("%x", &X)
	fmt.Scanf("%x", &Y)

	if X > Y {
		fmt.Println(">")
	} else if X < Y {
		fmt.Println("<")
	} else if X == Y {
		fmt.Println("=")
	}

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	In := strings.Split(readLine(), " ")
	if In[0] < In[1] {
		fmt.Println("<")
	} else if In[0] == In[1] {
		fmt.Println("=")
	} else {
		fmt.Println(">")
	}
}

/////////////////////////////////////////

//func readLineInt() []int {
//	result := make([]int, 0)
//	for _, v := range strings.Split(readLine(), " ") {
//		i, _ := strconv.Atoi(v)
//		result = append(result, i)
//	}
//	return result
//}

var reader = bufio.NewReaderSize(os.Stdin, 1e6)

func readLine() string {
	result := make([]byte, 0, 1e6)
	for {
		line, remains, e := reader.ReadLine()
		if e != nil {
			panic(e)
		}
		result = append(result, line...)
		if !remains {
			break
		}
	}
	return string(result)
}


package main

import (
	"fmt"
)

func main() {
	var x, y byte
	fmt.Scan(&x, &y)

	if x < y {
		fmt.Println('<')
	} else if x > y {
		fmt.Println('>')
	} else {
		fmt.Println("=")
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strings"
)

func main() {
	In := strings.Split(readLine(), " ")
	Origin := make([]string, 2)
	copy(Origin, In)
	sort.Strings(In)
	if In[0] != Origin[0] {
		fmt.Println(">")
	} else {
		fmt.Println("<")
	}
}

/////////////////////////////////////////

//func readLineInt() []int {
//	result := make([]int, 0)
//	for _, v := range strings.Split(readLine(), " ") {
//		i, _ := strconv.Atoi(v)
//		result = append(result, i)
//	}
//	return result
//}

var reader = bufio.NewReaderSize(os.Stdin, 1e6)

func readLine() string {
	result := make([]byte, 0, 1e6)
	for {
		line, remains, e := reader.ReadLine()
		if e != nil {
			panic(e)
		}
		result = append(result, line...)
		if !remains {
			break
		}
	}
	return string(result)
}


package main

import (
  ."fmt"
)

func main(){
  var x,y rune
  Scanf("%v%V",&x,&y)
  if x-y > 0{
    Println(">")
  }else if x-y == 0{
    Println("=")
  }else{
    Println("<")
  }
}


xy = gets.chomp.split
x = xy[0]
y = xy[1]
if x == y
    puts "="
else
    a = [x, y]
    a.sort!
    case a.first
    when x
        puts "<"
    else
        puts ">"
    end
end


n=gets.chomp.split(' ')

if n[0]>n[1]
    puts '>'
elsif n[0]==n[1]
    puts '='
else
    puts '<'
end


x, y = gets.chomp.split
if x < y
  puts "<"
elsif x > y
  puts ">"
else
  puts "="
end


n = gets.chomp.split(" ")
arr = n.sort
if n.uniq.size == 1
  puts "="
elsif arr.join("") == n.join("")
  puts ">"
else
  puts "<"
end


x, y = gets().chomp.split("\s").map{|x| x.to_i}

list = {'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15}

if x == y
  puts '='
elsif list[x] > list[y]
  puts '>'
else
  puts '<'
end


a, b = readline.split.map(&:chomp)
puts a.to_i(16) > b.to_i(16) ? ">" : "<"


use std::cmp::*;
use std::io::*;
use std::num::*;
use std::str::*;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let s = stdin
        .bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect::<String>();
    s.parse::<T>().ok().unwrap()
}

fn string() -> String {
    read()
}

fn int() -> i64 {
    read()
}

fn char() -> char {
    read::<String>().pop().unwrap()
}

fn vecchar() -> Vec<char> {
    string().chars().collect()
}

fn vecint(n: i64) -> Vec<i64> {
    let mut vec = Vec::new();
    for i in 0..n {
        vec.push(int())
    }
    vec
}

fn main() {
    let (a, b) = (char(), char());
    println!(
        "{}",
        if a == b {
            "="
        } else {
            if a < b {
                "<"
            } else {
                ">"
            }
        }
    )
}


use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let x: Vec<char> = read::<String>().chars().collect();
    let y: Vec<char> = read::<String>().chars().collect();
    let xnum = x[0] as u32;
    let ynum = y[0] as u32;
    if xnum < ynum {
        println!("<")
    } else {
        if xnum == ynum {
            println!("=")
        } else {
            println!(">")
        }
    }
}


fn main() {
	let mut buf = String::new();
	std::io::stdin().read_line(&mut buf).expect("");
	let mut iter = buf.split_whitespace();
	let x = iter.next().unwrap();
	let y = iter.next().unwrap();
	if x<y {
		println!("<");
	}else if x > y {
		println!(">");
	}else{
		println!("=");
	}
}


fn main() {
	let mut buf = String::new();
	std::io::stdin().read_line(&mut buf).expect("");
	let mut iter = buf.split_whitespace();
	let x = iter.next().unwrap();
	let y = iter.next().unwrap();
	if x<y {
		println!("<");
	}else if x > y {
		println!("<");
	}else{
		println!("=");
	}
}


use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let x: char = read();
    let y: char = read();
    let xnum = x as u32;
    let ynum = y as u32;
    if xnum < ynum {
        println!("<")
    } else {
        if xnum == ynum {
            println!("=")
        } else {
            println!(">")
        }
    }
}


use proconio::input;
#[allow(unused_imports)]
use proconio::marker::*;

fn main() {
    input! {
        x: char, y: char,
    }
    if x < y {
        println!("<");
    } else if x == y {
        println!("=");
    } else {
        println!(">");
    }
}


import Glibc
extension String: CollectionType {}

//var abc = readLine()!.split(" ").map { Int($0)! }
var xy = readLine()!.split(" ")
if xy[0] > xy[1] {
  print(">")
} else if xy[0] < xy[1] {
  print("<")
} else {
  print("=")
}


var i=readLine()!.characters.split(" ").map{String($0)},o="=";if i[0]>i[1]{o=">"};if i[0]<i[1]{o="<"};print(o)


#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
typedef long long ll;
#define INF 1e9

int main(){

    string a, b;
    cin >> a >> b;
    if(a < b){
        cout << "<"<< endl;
        return 0;
    }
    if(a > b){
        cout << ">" << endl;
        return 0;
    }
    cout << "="<< endl;

}


var i=readLine()!.characters.split(" "),o="=";if i[0]>i[1]{o=">"};if i[0]<i[1]{o="<"};print(o)


var i=readLine()!.characters.split(“ “).map{String($0)},o="=";if i[0]>i[1]{o=">"};if i[0]<i[1]{o="<"};print(o)


const stdin = require('fs').readFileSync('/dev/stdin', 'utf8')

const [x, y] = stdin.split('\n')[0].split(' ')

const res = _ => {
  return x === y ? '=' : x > y ? '>' : '<'
}

console.log(res())


import * as fs from 'fs';

namespace AtCoder {
    export interface Paramable {
        readonly args: string[][];
    }

    export interface Task {
        main(this: Task): void;
    }
}

namespace AtCoder.abc078 {
    export class TaskA implements AtCoder.Task, AtCoder.Paramable {

        public constructor(public readonly args: string[][]) {

        }

        public main(this: TaskA): void {
            const [x, y]: string[] = this.args[0];

            if (x>y) {
                console.log('>');
            } else if (x<y) {
                console.log('<');
            } else {
                console.log('=');
            }

        }
    }

    const args: string[][] = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n').map(x => x.split(' '));
    const task: AtCoder.Task = new TaskA(args);
    task.main();
}


const input=require('fs').readFileSync('/dev/stdin', 'utf8').split(/[\s]/);const nin=()=>{const r = input[0];input.shift();return Number(r)};const nrin=(n)=>{const a:number[]=[];rep(n,()=>a.push(nin()));return a};const sin=()=>{const r = input[0];input.shift();return String(r)};const out=(...a)=>{console.log(...a)};const floor=(a)=>{return Math.floor(a)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const rep=(n, callback)=>{for(let i = 0;i < n; i++){callback()}};const strrep=(s, i, v)=>{return s.slice(0, i)+v+s.slice(i+1);};const permutation=({result=[],pre=[],post,n=post.length})=>{if(n>0){post.forEach((_,i)=>{const rest=[...post];const elem=rest.splice(i, 1);permutation({result, pre: [...pre,...elem],post:rest,n:n-1})})}else{result.push(pre)}return result};const sw=(s,a:any[],op:'='|'>='|'>'|'<='|'<'='=')=>{for(let i=0;i<a.length;i+=2){if(op==='='){if(s==a[i])return a[i+1]}else if(op==='>='){if(s>=a[i])return a[i+1]}else if(op==='<='){if(s<=a[i])return a[i+1]}else if(op==='>'){if(s>a[i])return a[i+1]}else if(op==='<'){if(s<a[i])return a[i+1]}}return a[a.length-1];};const or=(a,...b)=>{for(let i=0;i<b.length;i++)if(a==b[i])return true;return false};const maxindex=(...a)=>{return a.indexOf(Math.max.apply(null,a))};const asc=(ar:number[])=>{return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{return ar.sort((a,b)=>{return b-a})};const ceil=a=>{return Math.ceil(a)};const srin=s=>{const a:string[]=[];rep(s,()=>a.push(sin()));return a};

const main = ()=>{
  let [a,b]=srin(2)
  out(a==b?'=':eval('0x' + a + '> 0x'+ b)?'>':'<')
}
main()