codeparrot/codecomplex huggingface dataset:
// 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;
				}
			}
		}
		for (int i = 0; i < n; ++i) {
			long[][] dp = new long[1 << (n - i)][n - i];
			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.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int m = scan.nextInt();

		boolean[][] graph = new boolean[n][n];
		for (int i = 0; i < m; i++) {
			int u = scan.nextInt() - 1;
			int v = scan.nextInt() - 1;
			graph[u][v] = true;
			graph[v][u] = true;
		}

		long[][] dp = new long[1 << n][n];
		long sum = 0;

		for (int i = 0; i < n; i++)
			dp[1 << i][i] = 1;

		for (int mask = 1; mask < (1 << n); mask++) {

			int first = Integer.numberOfTrailingZeros(mask);

			for (int i = 0; i < n; i++) {
				if ((mask & (1 << i)) == 0 || first == i)
					continue;

				for (int j = 0; j < n; j++) {
					if (graph[i][j] && (mask & (1 << j)) != 0)
						dp[mask][i] += dp[mask ^ 1 << i][j];
				}

				if (Integer.bitCount(mask) >= 3 && graph[i][first])
					sum += dp[mask][i];
			}

		}

		System.out.println(sum / 2);
		scan.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.PrintWriter;
import java.util.Arrays;

public class Main {
	public static BufferedReader in;
	public static PrintWriter out;

	public static void main(String[] args) throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		boolean showLineError = true;
		if (showLineError) {
			solve();
			out.close();
		} else {
			try {
				solve();
			} catch (Exception e) {
			} finally {
				out.close();
			}
		}

	}

	static void debug(Object... os) {
		out.println(Arrays.deepToString(os));
	}

	private static void solve() throws IOException {
		String[] line = nss();
		int n = Integer.parseInt(line[0]);
		int m = Integer.parseInt(line[1]);

		boolean[][] matrix = new boolean[n][n];
		for (int i = 0; i < m; i++) {
			line = nss();
			int u = Integer.parseInt(line[0]) - 1;
			int v = Integer.parseInt(line[1]) - 1;
			matrix[u][v] = matrix[v][u] = true;
		}
		long[][] dp = new long[1<<n][n];
		for(int i=0;i<n;i++)
			dp[1<<i][i]=1;
		long ret=0;
		for(int mask =0;mask< 1<<n;mask++){
			for(int last =0;last<n;last++)
				if((mask & (1<<last))!=0){
					int first=-1;
					for(first=0;first<n;first++)
						if((mask & (1<<first))!=0)
							break;
					for(int add =first;add<n;add++)
						if((mask & (1<<add))==0 && matrix[last][add])
							dp[mask+ (1<<add)][add]+=dp[mask][last];
							
					if(Long.bitCount(mask)>2 && matrix[first][last])	
						ret+=dp[mask][last];
				}
		}
		out.println(ret/2L);

	}

	private static String[] nss() throws IOException {
		return in.readLine().split(" ");
	}

	private static int ni() throws NumberFormatException, IOException {
		return Integer.parseInt(in.readLine());
	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.*;
import java.util.*;

public class CF11D {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		boolean[][] ee = new boolean[n][n];
		while (m-- > 0) {
			st = new StringTokenizer(br.readLine());
			int i = Integer.parseInt(st.nextToken()) - 1;
			int j = Integer.parseInt(st.nextToken()) - 1;
			ee[i][j] = ee[j][i] = true;
		}
		long cnt = 0;
		// how many cycles through i with intermediate vertices before i
		for (int i = 2; i < n; i++) {
			long[][] dp = new long[1 << i][i];
			for (int j = 0; j < i; j++)
				dp[0][j] = ee[i][j] ? 1 : 0;
			// dp[b][j]: how many paths from i to j with intermediate vertices in b
			for (int b = 1; b < 1 << i; b++)
				for (int j = 0; j < i; j++) {
					if ((b & 1 << j) > 0)
						continue;
					for (int k = 0; k < i; k++) {
						if ((b & 1 << k) == 0)
							continue;
						if (ee[k][j])
							dp[b][j] += dp[b ^ 1 << k][k];
					}
					if (dp[b][j] > 0 && ee[j][i])
						cnt += dp[b][j];
				}
		}
		System.out.println(cnt / 2);
	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.util.*;
import java.math.*;

public	class task
{
	public static void	main(String args[])
	{
		Scanner a = new Scanner(System.in);
		
		while(a.hasNext())
		{
			int n = a.nextInt();
			int m = a.nextInt();
			if(n == 0 && m == 0) break;
		    
			boolean[][] adj = new boolean[n][n];
			long res = 0;
			
			for (int i = 0; i < m; ++i) {
				int x = a.nextInt();
				int y = a.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;
						
			for (int i = 0; i < n; ++i) 
			{
				long[][] dp = new long[n - i][1 << (n - i)];
				dp[0][0] = 1;
				for (int mask = 0; mask < (1 << (n - i)); ++mask) 
				{
					for (int j = 0; j < n - i; ++j) 
					{
						if (dp[j][mask] != 0) 
						{
							for (int k = 0; k < n - i; ++k) 
							{
								if (((mask >> k) & 1) == 0 && adj[j + i][k + i]) 
									dp[k][mask | (1 << k)] += dp[j][mask];
								
							}
						}
					}
					if (((mask >> 0) & 1) != 0) {
						res += dp[0][mask];
					}
				}
			}
			System.out.println(res/2);
		}
	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.util.Scanner;


public class D {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[][]a = new int[n][n];
        for (int i = 1; i <= m; i++) {
            int v1 = sc.nextInt();
            int v2 = sc.nextInt();
            v1--;
            v2--;
            a[v1][v2] = a[v2][v1] = 1;
        }
        long[][]dp = new long[1 << n][n];
        for (int i = 0; i < n; i++) {
            dp[1 << i][i] = 1;
        }
        for (int mask = 0; mask < (1 << n); mask++) {
            if (Integer.bitCount(mask) > 1) {
                for (int i = 0; i < n; i++) {
                    if (i==Integer.numberOfTrailingZeros(mask))
                        continue;
                    if ((mask & (1 << i)) != 0) {
                        for (int j = 0; j < n; j++) {
                            if ((mask & (1 << j)) != 0 && a[j][i]==1) {
                                dp[mask][i] += dp[(mask ^ (1 << i))][j];
                            }
                        }
                    }
                }
            }
        }
        long ans = 0;
        for (int mask = 0; mask < (1 << n); mask++) {
            if (Integer.bitCount(mask) >= 3) {
                int t = Integer.numberOfTrailingZeros(mask);
                for (int i = 0; i < n; i++) {
                    if (a[t][i]==1)
                        ans += dp[mask][i];
                }
            }
        }
        ans /= 2;
        System.out.println(ans);
    }
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

public class D11 {

	static StreamTokenizer in;
	static PrintWriter out;
	
	static int nextInt() throws IOException {
		in.nextToken();
		return (int)in.nval;
	}
	
	static String nextString() throws IOException {
		in.nextToken();
		return in.sval;
	}

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

		n = nextInt();
		m = nextInt();
		
		g = new boolean[n][n];
		for (int i = 0; i < m; i++) {
			int a = nextInt()-1, b = nextInt()-1;
			g[a][b] = g[b][a] = true;
		}
		
		long ans = 0;
		for (int i = n; i > 0; i--) {
			//long cur = solve(i);
			long cur = calc(g, i-1);
			ans += cur;
		}
		
		out.println(ans/2);
		
		out.flush();
	}

	static int n, m, V;
	static boolean[][] g;
	
	/*static long solve(int V) {
		int v = V-1;
		long[][] memo = new long[V][1 << V];
		
		memo[v][1 << v] = 1;
		for (int mask = 1; mask < (1 << V); mask++)
			for (int i = 0; i < V; i++) if ((mask&(1 << i)) != 0)
				for (int j = 0; j < V; j++) if (g[i][j] && (mask&(1 << j)) == 0)
					memo[j][mask|(1 << j)] += memo[i][mask];
		
		long res = 0;
		for (int mask = 1; mask < (1 << V); mask++)
			for (int i = 0; i < V; i++)
				if (Integer.bitCount(mask) > 2 && g[v][i]) res += memo[i][mask];
		return res/2;
	}*/
	
	static long calc(boolean[][] bs,int n){
        long[][] dp=new long[1<<n][n];
        for(int i=0;i<n;i++){
                if(bs[i][n])
                        dp[1<<i][i] ++;
        }
        for(int i=1;i<1<<n;i++){
                for(int j=0;j<n;j++)if(((i>>j)&1)==1)
                        for(int k=0;k<n;k++)if(((i>>k)&1)==0 && bs[j][k]){//add
                                dp[i|(1<<k)][k] += dp[i][j];
                        }
        }
        long res=0;
        for(int i=0;i<1<<n;i++)for(int j=0;j<n;j++)if(Integer.bitCount(i)>=2&&bs[j][n])res+=dp[i][j];
        return res;
}
}
// 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) {
			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) {
						long am = dp[mask][j];
						for (int k = 0; k < n - i; ++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.*;
import java.util.StringTokenizer;

/**
 * Created by Darren on 14-10-21.
 */
public class D {
    Reader in = new Reader(System.in);
    PrintWriter out = new PrintWriter(System.out);

    public static void main(String[] args) throws IOException {
        new D().run();
    }

    int n, m;
    boolean[][] adjacency;

    void run() throws IOException {
        n = in.nextInt();
        m = in.nextInt();
        adjacency = new boolean[n+1][n];
        for (int i = 0; i < m; i++) {
            int u = in.nextInt(), v = in.nextInt();
            adjacency[u-1][v-1] = adjacency[v-1][u-1] = true;
        }

        final int MAX_MASK = (1 << n) - 1;
        long[][] dp = new long[MAX_MASK+1][n];
        for (int i = 0; i < n; i++)
            dp[1<<i][i] = 1;
        long sum = 0;
        for (int mask = 1; mask <= MAX_MASK; mask++) {
            int lowestBit = first(mask);
            for (int i = 0; i < n; i++) {
                if (bit(i, mask) && i != lowestBit) {
                    for (int j = 0; j < n; j++) {
                        if (adjacency[j][i]) {
                            dp[mask][i] += dp[mask^(1<<i)][j];
                        }
                    }
                    if (count(mask) >= 3 && adjacency[lowestBit][i])
                        sum += dp[mask][i];
                } else {
                    // dp[mask][i] = 0
                }
            }
        }

        out.println(sum / 2);
        out.flush();
    }

    int count(int mask) {
        int count = 0;
        while (mask > 0) {
            if ((mask & 1) == 1)
                count++;
            mask >>= 1;
        }
        return count;
    }

    int first(int mask) {
        int index = 0;
        while (mask > 0) {
            if ((mask & 1) == 1)
                return index;
            mask >>= 1;
            index++;
        }
        return -1;
    }

    boolean bit(int index, int mask) {
        return ((1 << index) & mask) > 0;
    }

    static class Reader {
        BufferedReader reader;
        StringTokenizer tokenizer;

        public Reader(InputStream input) {
            reader = new BufferedReader(new InputStreamReader(input));
            tokenizer = new StringTokenizer("");
        }

        /** get next word */
        String nextToken() throws IOException {
            while ( ! tokenizer.hasMoreTokens() ) {
                //TODO add check for eof if necessary
                tokenizer = new StringTokenizer( reader.readLine() );
            }
            return tokenizer.nextToken();
        }

        String readLine() throws IOException {
            return reader.readLine();
        }

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

        long nextLong() throws IOException {
            return Long.parseLong( nextToken() );
        }

        double nextDouble() throws IOException {
            return Double.parseDouble( nextToken() );
        }
    }
}
// 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 Main {

	/**
	 * @param args
	 */
	static int N, M;
	static long[] C;
	static int[][] g;
	static long[][] DP;
	public static void main(String[] args) {
		InputReader r = new InputReader(System.in);
		
		N = r.nextInt();
		M = r.nextInt();
		
		g = new int[N][N];
		
		C = new long[N + 1];
		
		DP = new long[1 << N][N];
		
		for(int k = 0; k < M; k++){
			int i = r.nextInt() - 1;
			int j = r.nextInt() - 1;
			
			g[i][j] = g[j][i] = 1;
		}
		
		for(long[] i : DP)
			Arrays.fill(i, -1);
		
		long ret = 0;
		for(int s = 0; s < N; s++){
			ret += go(s, 1 << s, s);
		}
		
		System.out.println(ret / 2);
	}
	
	private static long go(int s, int m, int e) {
		if(DP[m][e] != -1)return DP[m][e];
		
		long cnt = 0;
		for(int j = s; j < N; j++)if(g[e][j] == 1){
			if((m & (1 << j)) != 0){
				if(s == j && Integer.bitCount(m) >= 3){
					cnt++;
				}
			}else{
				cnt += go(s, m | 1 << j, j);
			}
		}

		return DP[m][e] = cnt;
	}

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

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

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return 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());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble(){
			return Double.parseDouble(next());
		}
	}
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
	InputStream fin = System.in;
	//fin = new FileInputStream("in.txt");
	Scanner cin = new Scanner(fin);

	int n = cin.nextInt();
	int m = cin.nextInt();
	int bound = 1 << n;
	boolean[][] mp = new boolean[n][n];
	long[][] dp = new long[bound][n];
	int used = 0;
	long ret = 0;
	for (int i = 0; i < n; i++) {
	    Arrays.fill(mp[i], false);
	}

	for (int i = 0; i < m; i++) {
	    int u = cin.nextInt() - 1;
	    int v = cin.nextInt() - 1;
	    mp[u][v] = mp[v][u] = true;
	}

	for (int k = 0; k < n; k++) {
	    for (int i = k; i < bound; i++) {
		Arrays.fill(dp[i], 0);
	    }
	    dp[1 << k][k] = 1;
	    for (int mask = 1 << k; mask < bound; mask++) {
		if ((mask & used) != 0)
		    continue;
		for (int i = k; i < n; i++) {
		    if (dp[mask][i] != 0) {
			if (mp[k][i] && bitcount(mask) > 2)
			    ret += dp[mask][i];
			for (int j = k; j < n; j++) {
			    if ((mask & (1 << j)) == 0 && mp[i][j]) {
				dp[mask ^ (1 << j)][j] += dp[mask][i];
			    }
			}
		    }
		}
	    }
	    used |= 1 << k;
	}

	System.out.println(ret / 2);

	fin.close();
	cin.close();
    }

    private static int bitcount(int mask) {
	// TODO Auto-generated method stub
	int ret = 0;
	while (mask > 0) {
	    ret += mask & 1;
	    mask >>= 1;
	}
	return ret;
    }
}
// Problem: 11_D. A Simple Task
// Time complexity: np
import java.io.*;
import java.util.*;

public class Template implements Runnable {
    private void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        boolean[][] g = new boolean[n][n];
        for (int i = 0; i < m; ++i) {
            int a = nextInt() - 1;
            int b = nextInt() - 1;
            g[a][b] = true;
            g[b][a] = true;
        }
        /*for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                g[i][j] = true;*/
        long[] am = new long[n + 1];
        long[][] ways = new long[1 << n][n];
        for (int start = 0; start < n; ++start) {
            for (int mask = 0; mask < (1 << (n - start)); ++mask)
                for (int last = start; last < n; ++last) {
                    ways[mask][last - start] = 0;
                }
            ways[1][0] = 1;
            for (int mask = 0; mask < (1 << (n - start)); ++mask) {
                int cnt = 0;
                int tmp = mask;
                while (tmp > 0) {
                    ++cnt;
                    tmp = tmp & (tmp - 1);
                }
                for (int last = start; last < n; ++last)
                    if (ways[mask][last - start] > 0) {
                        long amm = ways[mask][last - start]; 
                        for (int i = start; i < n; ++i)
                            if ((mask & (1 << (i - start))) == 0 && g[last][i]) {
                                ways[mask | (1 << (i - start))][i - start] += amm;
                            }
                        if (g[last][start])
                            am[cnt] += ways[mask][last - start];
                    }
            }
        }
        long res = 0;
        for (int cnt = 3; cnt <= n; ++cnt) {
            if (am[cnt] % (2) != 0)
                throw new RuntimeException();
            res += am[cnt] / (2);
        }
        writer.println(res);
    }


    public static void main(String[] args) {
        new Template().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

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

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