codeparrot/codecomplex huggingface dataset:
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int V = in.nextInt();
        int E = in.nextInt();
        boolean [][] G = new boolean [V][V];
        for (int i = 0; i < E; i++) {
            int u = in.nextInt()-1;
            int v = in.nextInt()-1;
            G[u][v] = true;
            G[v][u] = true;
        }
        
        int pset = 1 << V;
        
        long [][] dp = new long [pset][V];
        long cycles = 0;
        
        for (int set = 1; set < pset; set++) {
            int bit = Integer.bitCount(set);
            int src = first(set);
            
            if (bit == 1) {
                dp[set][src] = 1;
            }
            else if(bit > 1) {
                for (int i = 0; i < V; i++) {
                    if(i == src) continue;
                    // Check if i is in set
                    if ((set & (1 << i)) != 0) {
                        int S_1 = set ^ (1 << i);
                        for (int v = 0; v < V; v++) {
                            if (G[v][i] == true) {
                                dp[set][i] += dp[S_1][v];
                            }
                        }
                    }
                    //Count Cycles:
                    if (bit >= 3 && G[src][i]) {
                        cycles += dp[set][i];
                    }   
                }
                
            }
                    
                    
        }
        System.out.println(cycles/2);
    }
    
    public static int first(int n) {
        int cnt = 0;
        while ((n & 1) != 1) {
            cnt++;
            n >>= 1;
        }
        return cnt;
    }
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.util.*;
import java.io.*;

public class Main implements Runnable {
	private void solution() throws IOException {
		int n = in.nextInt();
		int m = in.nextInt();
		boolean[][] adj = new boolean[n][n];
		long res = 0;
		for (int i = 0; i < m; ++i) {
			int x = in.nextInt();
			int y = in.nextInt();
			adj[x - 1][y - 1] = true;
			adj[y - 1][x - 1] = true;
		}
		for (int i = 0; i < n; ++i) {
			for (int j = i + 1; j < n; ++j) {
				if (adj[i][j]) {
					--res;
				}
			}
		}
		final long[][] dp = new long[1 << n][n];
		for (int i = 0; i < n; ++i) {
			for (int mask = 0; mask < (1 << (n - i)); ++mask) {
				for (int j = 0; j < n - i; ++j) {
					dp[mask][j] = 0;
				}
			}
			dp[0][0] = 1;
			for (int mask = 0; mask < (1 << (n - i)); ++mask) {
				for (int j = 0; j < n - i; ++j) {
					if (dp[mask][j] != 0) {
						for (int k = 0; k < n - i; ++k) {
							if (((mask >> k) & 1) == 0 && adj[j + i][k + i]) {
								dp[mask | (1 << k)][k] += dp[mask][j];
							}
						}
					}
				}
				if (((mask >> 0) & 1) != 0) {
					res += dp[mask][0];
				}
			}
		}
		out.println(res / 2);
	}

	public void run() {
		try {
			solution();
			in.reader.close();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	private class Scanner {
		BufferedReader reader;
		StringTokenizer tokenizer;

		public Scanner(Reader reader) {
			this.reader = new BufferedReader(reader);
			this.tokenizer = new StringTokenizer("");
		}

		public boolean hasNext() throws IOException {
			while (!tokenizer.hasMoreTokens()) {
				String next = reader.readLine();
				if (next == null) {
					return false;
				}
				tokenizer = new StringTokenizer(next);
			}
			return true;
		}

		public String next() throws IOException {
			hasNext();
			return tokenizer.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public String nextLine() throws IOException {
			tokenizer = new StringTokenizer("");
			return reader.readLine();
		}

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

	public static void main(String[] args) throws IOException {
		new Thread(null, new Main(), "", 1 << 28).start();
	}
	PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	Scanner in = new Scanner(new InputStreamReader(System.in));
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;


public class Ok_Simple {
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	static boolean am[][];
	static long dp[][];
	static int n;
	public static void main(String[] args) throws IOException {
		reader = new BufferedReader(new InputStreamReader(System.in));
		int m;
		n = NextInt();
		m = NextInt();
		am = new boolean[n][n];
		dp = new long[n][1 << n];
		for (int i = 0; i < n; ++i)
			Arrays.fill(dp[i], -1);
		for (int i = 0; i < m; ++i) {
			int a = NextInt() - 1;
			int b = NextInt() - 1;
			am[a][b] = am[b][a] = true;
		};
		long res = 0;
		for (int a = 0; a < n; ++a)
			res += solve(a, (1 << a));
		System.out.println(res / 2);
	}
	private static long solve(int b, int mask) {
		int a = 0;
		for (int i = 0 ;i < n; ++i)
			if (((mask >> i) & 1) != 0)
			{
				a = i;
				break;
			}
		if (dp[b][mask] >= 0)
			return dp[b][mask];
		long res = 0;
		if (am[b][a] && Integer.bitCount(mask) > 2)
			res = 1;
		for (int i = a + 1; i < n; ++i)
			if (((mask >> i) & 1) == 0 && am[b][i])
				res += solve(i, mask ^ (1 << i));
		return dp[b][mask] = res;
	}
	static int NextInt() throws NumberFormatException, IOException {
		return Integer.parseInt(NextToken());
	}
	static double NextDouble() throws NumberFormatException, IOException {
		return Double.parseDouble(NextToken());
	}
	static long NextLong() throws NumberFormatException, IOException {
		return Long.parseLong(NextToken());
	}
	static String NextToken() throws IOException {
		while(tokenizer == null || !tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.*;
import java.util.*;
 

public class Main {
	
	public static void main(String[] args) throws java.lang.Exception {
		BufferedReader kek = new BufferedReader(new InputStreamReader(System.in));
		//Scanner skek = new Scanner(System.in);
		PrintWriter outkek = new PrintWriter(System.out);
		
		String[] input = kek.readLine().split(" ");
		int N = Integer.parseInt(input[0]), M = Integer.parseInt(input[1]);
		boolean[][] connected = new boolean[N + 1][N];
		long[][] walks = new long[1 << N][N];
		long res = 0;
		
		for(int i = 0; i < M; i++){
			input = kek.readLine().split(" ");
			int A = Integer.parseInt(input[0]) - 1, B = Integer.parseInt(input[1]) - 1;
			connected[A][B] = connected[B][A] = true;
		}
		
		for(int i = 0; i < N; i++){
			walks[1 << i][i] = 1;
		}
		
		for(int i = 1; i < 1 << N; i++){
			int temp = (int) (Math.log(i & -(i)) / 0.6931471805599453);
			for(int j = 0; j < N; j++){
				if(((1 << j) & i) > 0 && j != temp){
					for(int k = 0; k < N; k++){
						if(connected[k][j]){
							walks[i][j] += walks[i ^ (1 << j)][k];
						}
					}
					
					int count = 0, track = i;
					while(track > 0){
						if(track % 2 == 1){
							count++;
						}
						track /= 2;
					}
					
					
					if(count >= 3 && connected[temp][j]){
						res += walks[i][j];
					}
				}
			}
		}
		
		outkek.println(res / 2);
		kek.close();
		outkek.close();
	}	
	
}
// Problem: 11_D. A Simple Task
// Time complexity: np


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class ASimpleTask {

	static StreamTokenizer st;

	static int nextInt() {
		try {
			st.nextToken();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return (int) st.nval;
	}

	static int[][] edges;
	static long[][] dp;

	public static void main(String[] args) {
		st = new StreamTokenizer(new BufferedReader(new InputStreamReader(
				System.in)));

		int n = nextInt();
		int m = nextInt();

		edges = new int[n][n];

		for (int i = 0; i < m; i++) {
			int from = nextInt() - 1;
			int to = nextInt() - 1;
			edges[from][to] = edges[to][from] = 1;
		}

		dp = new long[(1 << n) + 1][n + 1];

		for (int mask = 1; mask < (1 << n); mask++) {
			for (int i = 0; i < n; i++) {
				if (Integer.bitCount(mask) == 1 && (mask & (1 << i)) != 0) {
					dp[mask][i] = 1;
					continue;
				}

				if (Integer.bitCount(mask) > 1 && (mask & (1 << i)) != 0
						&& first(mask, n) != i) {
					for (int j = 0; j < n; j++) {
						if (edges[i][j] == 1) {
							dp[mask][i] += dp[mask ^ (1 << i)][j];
						}
					}
				}
			}
		}

		long count = 0;
		for (int mask = 1; mask < (1 << n); mask++) {
			for (int i = 0; i < n; i++) {
				if (Integer.bitCount(mask) >= 3
						&& edges[i][first(mask, n)] != 0)
					count += dp[mask][i];
			}
		}

		System.out.println(count / 2);

	}

	static int first(int mask, int n) {
		for (int i = 0; i < n; i++) {
			if ((mask & (1 << i)) != 0)
				return i;
		}
		return -1;
	}

}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main implements Runnable {

    private int n;
    private int nn;
    private boolean[][] gr;
    private long[][] D;


    // ////////////////////////////////////////////////////////////////////
    // Solution

    private void solve() throws Throwable {
        n = nextInt();
        nn = 1 << n;
        gr = new boolean[n][n];
        int m = nextInt();
        for (int i = 0; i < m; i++) {
            int a = nextInt() - 1, b = nextInt() - 1;
            gr[a][b] = gr[b][a] = true;
        }
        D = new long[n][nn];
        for (int i = 0; i < n; i++) {
            Arrays.fill(D[i], -1);
        }
        long count = 0;
        for (int i = 0; i < n; i++) {
            count += getD(i, i, 1, 1 << i);
        }
        pw.println(count / 2);
    }


    private long getD(int first, int last, int cnt, int mask) {
        if (D[last][mask] != -1) return D[last][mask];
        long ans = 0;
        if (cnt >= 3 && gr[first][last])
            ans++;
        for (int i = first + 1; i < n; i++) {
            if (gr[last][i] && (mask & (1 << i)) == 0) {
                ans += getD(first, i, cnt + 1, mask | (1 << i));
            }
        }
        D[last][mask] = ans;
        return ans;
    }


    // ////////////////////////////////////////////////////////////////////
    // Utility functions

    PrintWriter pw;
    BufferedReader in;
    StringTokenizer st;

    void initStreams() throws FileNotFoundException {
        //System.setIn(new FileInputStream("2"));
        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(System.out);
    }

    String nextString() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws NumberFormatException, IOException {
        return Integer.parseInt(nextString());
    }

    long nextLong() throws NumberFormatException, IOException {
        return Long.parseLong(nextString());
    }

    double nextDouble() throws NumberFormatException, IOException {
        return Double.parseDouble(nextString());
    }

    static Throwable sError;

    public static void main(String[] args) throws Throwable {
        Thread t = new Thread(new Main());
        t.start();
        t.join();
        if (sError != null) {
            throw sError;
        }
    }

    public void run() {
        try {
            initStreams();
            solve();
        } catch (Throwable e) {
            sError = e;
        } finally {
            if (pw != null)
                pw.close();
        }
    }
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.util.*;
import java.io.*;

public class Main implements Runnable {
	private void solution() throws IOException {
		int n = in.nextInt();
		int m = in.nextInt();
		boolean[][] adj = new boolean[n][n];
		long res = 0;
		for (int i = 0; i < m; ++i) {
			int x = in.nextInt();
			int y = in.nextInt();
			adj[x - 1][y - 1] = true;
			adj[y - 1][x - 1] = true;
		}
		final long[][] dp = new long[1 << n][n];
		for (int i = 0; i < n; ++i) {
			int Limit = 1 << (n - i);
			int nn = n - i;
			for (int mask = 0; mask < Limit; ++mask) {
				for (int j = 0; j < nn; ++j) {
					dp[mask][j] = 0;
				}
			}
			dp[0][0] = 1;
			for (int mask = 0; mask < Limit; ++mask) {
				for (int j = 0; j < nn; ++j) {
					if (dp[mask][j] != 0) {
						long am = dp[mask][j];
						for (int k = 0; k < nn; ++k) {
							if (((mask >> k) & 1) == 0 && adj[j + i][k + i]) {
								dp[mask | (1 << k)][k] += am;
							}
						}
					}
				}
				if (((mask >> 0) & 1) != 0) {
					res += dp[mask][0];
				}
			}
		}
		out.println((res - m) / 2);
	}

	public void run() {
		try {
			solution();
			in.reader.close();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	private class Scanner {
		BufferedReader reader;
		StringTokenizer tokenizer;

		public Scanner(Reader reader) {
			this.reader = new BufferedReader(reader);
			this.tokenizer = new StringTokenizer("");
		}

		public boolean hasNext() throws IOException {
			while (!tokenizer.hasMoreTokens()) {
				String next = reader.readLine();
				if (next == null) {
					return false;
				}
				tokenizer = new StringTokenizer(next);
			}
			return true;
		}

		public String next() throws IOException {
			hasNext();
			return tokenizer.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public String nextLine() throws IOException {
			tokenizer = new StringTokenizer("");
			return reader.readLine();
		}

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

	public static void main(String[] args) throws IOException {
		new Thread(null, new Main(), "", 1 << 28).start();
	}
	PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	Scanner in = new Scanner(new InputStreamReader(System.in));
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class SimpleTask {

    public static void main(String[] args) throws Exception {
        InputReader in = new InputReader(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int[] g = new int[n];
        long[][] dp = new long[1 << n][n];
        for (int i = 0; i < m; i++) {
            int a = in.nextInt() - 1, b = in.nextInt() - 1;
            g[a] |= (1 << b);
            g[b] |= (1 << a);
        }
        int all = (1 << n) - 1;
        for (int i = 0; i < n; i++) {
            int l = (1 << i);
            int left = all ^ (l - 1) ^ l;
            for (int j = left; j > 0; j = (j - 1) & left)
                if ((j & (j - 1)) != 0) {
                    dp[j | l][i] = 1;
                }
        }
        for (int i = (1 << n) - 1; i > 0; i--) {
            int last = i & -i;
            for (int j = 0; j < n; j++) {
                if (((1 << j) == last && (i & (i - 1)) != 0)
                        || ((1 << j) & i) == 0)
                    continue;
                for (int k = 0; k < n; k++) {
                    if ((1 << k) >= last && ((1 << k) & g[j]) != 0
                            && ((1 << k) == last || ((1 << k) & i) == 0)) {
                        dp[i][j] += dp[i | (1 << k)][k];
                    }

                }
            }
        }
        long res = 0;
        for (int i = 0; i < n; i++)
            res += dp[(1 << i)][i];
        System.out.println(res / 2);
    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class A{
	static int n,m,start;
	static boolean [][] adj;
	static long [][] mem;
	public static void main(String[] args)throws Throwable {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		adj=new boolean [n][n];
		for(int i=0;i<m;i++){
			int u=sc.nextInt()-1;
			int v=sc.nextInt()-1;
			adj[u][v]=true;
			adj[v][u]=true;
		}
		mem=new long [n+1][(1<<n)];
		for(int i=0;i<=n;i++)
			Arrays.fill(mem[i], -1);
		long ans=0;
		for(int i=0;i<n;i++){
			start=i;
			ans+=dp(i, (1<<i));
		}
		System.out.println(ans/2);
	}
	
	public static long dp(int i,int msk){
		if(mem[i][msk]!=-1)
			return mem[i][msk];
		long ans=0;
		if(adj[i][start] && Integer.bitCount(msk)>2)
			ans++;
		for(int j=start+1;j<n;j++){
			if(adj[i][j] && (msk & (1<<j))==0){
				ans+=dp(j, msk | (1<<j));
			}
		}
		return mem[i][msk]=ans;
	}
	
	static class Scanner {
		StringTokenizer st;
		BufferedReader br;
		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}
		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
			return st.nextToken();}
		public int nextInt() throws IOException {return Integer.parseInt(next());}
		public long nextLong() throws IOException {return Long.parseLong(next());}
		public String nextLine() throws IOException {return br.readLine();}
		public double nextDouble() throws IOException { return Double.parseDouble(next()); }
		public boolean ready() throws IOException {return br.ready();} 
	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.awt.List;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;

public class T {
	static Scanner in = new Scanner();
	static PrintWriter out = new PrintWriter(System.out);
	static boolean adj[][];
	static int n, m, from;
	static long memo[][];
	static long Num_Cycle;

	public static void main(String[] args) throws IOException {

		n = in.nextInt();
		m = in.nextInt();
		adj = new boolean[n][n];
		memo = new long[n][1 << n];
		for (int i = 0; i < m; i++) {
			int u = in.nextInt() - 1;
			int v = in.nextInt() - 1;
			adj[u][v] = adj[v][u] = true;
		}
		for (long arr[] : memo) {
			Arrays.fill(arr, -1);
		}
		Num_Cycle = 0L;
		for (int i = 0; i < n; i++) {
			from = i;
			Num_Cycle += dp(from, (1 << i));
		}
		out.println(Num_Cycle / 2);

		out.flush();
		out.close();
	}

	static long dp(int start, int mask) {
		if (memo[start][mask] != -1) {
			return (memo[start][mask]);
		}
		long ans = 0L;
		if (adj[start][from] && Integer.bitCount(mask) >= 3) {// Cycle has
																// atleast 3
																// node and 3
																// edges
			ans++;
		}
		for (int i = from + 1; i < n; i++) {
			if (adj[start][i] && ((mask & (1 << i)) == 0)) {
				ans += dp(i, mask | (1 << i));
			}
		}
		return memo[start][mask] = ans;
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String file) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(file));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np

import java.util.Arrays;
import java.util.Scanner;

public class C {
    static boolean[][] matrix;
    static long[][] dp;
    static int n;
    static int m;
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        n = s.nextInt();
        m = s.nextInt();
        matrix = new boolean[n][n];
        for (int i=0; i<m; ++i) {
            int v1 = s.nextInt()-1;
            int v2 = s.nextInt()-1;
            matrix[v1][v2] = true;
            matrix[v2][v1] = true;
        }
        dp = new long[n][1<<n+1];
        for (int i=0; i<n; ++i) Arrays.fill(dp[i], -1);
        
        long res = 0;
        for (int i=0; i<n; ++i)
            res += calc(i, i, (1<<i), 1);
        
        System.out.println(res/2);
    }
    
    public static long calc(int h, int c, int m, int len) {
        if (dp[c][m] != -1)
            return dp[c][m];
        
        long ret = 0;
        if (len > 2 && matrix[c][h])
            ret = 1;
        for (int i=h+1; i<n; ++i)
            if ((m & (1<<i)) == 0 && matrix[c][i])
                ret += calc(h, i, m | (1<<i), len + 1);
        return dp[c][m] = ret;
    }
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.IOException;
import java.io.PrintStream;
import java.util.*;

public class Template {

    public static void main(String[] args) throws IOException {
        final Scanner in = new Scanner(System.in);
        final PrintStream out = System.out;
        int n = in.nextInt(), m = in.nextInt();
        boolean[][] g = new boolean[n][n];
        for (int i = 0; i < m; ++i) {
            int a = in.nextInt(), b = in.nextInt();
            --a; --b;
            g[a][b] = g[b][a] = true;
        }
        final int mx = 1<<n;
        long[][] dp = new long[mx][n];
        long res = 0;
        for (int mask = 0; mask < mx; ++mask)
            for (int i = 0; i < n; ++i) {
                if (mask == (1 << i)) {
                    dp[mask][i] = 1;
                } else if (((mask & (1 << i)) != 0) && ((mask & ((1 << i) - 1)) != 0)) {
                    long r = 0;
                    int next = mask ^ (1<<i);
                    for (int j = 0; j < n; ++j) if (g[i][j]) {
                        r += dp[next][j];
                    }
                    dp[mask][i] = r;
                } else {
                    dp[mask][i] = 0;
                }

                if ((mask & (mask-1)) != 0 && g[i][lowestBit(mask)]) {
                    res += dp[mask][i];
                }

            }

        System.out.println((res-m)/2);
    }

    private static int lowestBit(int mask) {
        for (int i = 0;;++i) {
            if ((mask & (1<<i)) > 0) {
                return i;
            }
        }
    }

}