codeparrot/codecomplex huggingface dataset:
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.util.Arrays;
import java.util.Scanner;

public class thing {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		
		int n = in.nextInt();
		int m = in.nextInt();
		
		String s = in.next();
		
		int[][] count = new int[m][m];
		int[] dp = new int[1 << m];
		
		Arrays.fill(dp, Integer.MAX_VALUE);
		dp[0] = 0;
		
		for(int i = 1; i < n; i++) {
			int a = s.charAt(i)-'a';
			int b = s.charAt(i-1)-'a';
			count[a][b]++;
			count[b][a]++;
		}
		
		for(int i = 1; i < (1 << m); i++) {
			
			int pos = set_bits(i);
			
			for(int j = 0; (i >> j) != 0; j++) {
				
				if(((i >> j) & 1) == 0) continue;
				
				int sum = 0;
				
				for(int mask = i, y = 0; y < m; mask >>= 1, y++) {
					if(y == j) continue;
					if((mask & 1) == 1) sum += count[j][y];
					else sum -= count[j][y];
				}
				
				int calc = dp[i-(1<<j)] + pos*sum;
				
				dp[i] = Math.min(dp[i], calc);
			}
			
		}
		
		System.out.println(dp[(1 << m)-1]);
		
	}
	
	public static int set_bits(int n) { 
		int count = 0; 
		while (n > 0) {
			count += n & 1;
			n >>= 1; 
		}
		return count;
	}

}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.io.*;
import java.util.*;

public class cfe {
	static DataReader input;
	static int LARGE_INT = 1000000007;
	//static int MAXN = 300000;
	//static int[] len = new int[300000];
	//static int[] price = new int[300000];
	static final int[] BM =  {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 
	                          1<<17, 1<<18, 1<<19, 1<<20};
	
	public static void main(String[] args) throws IOException {
	    input = new DataReader();
		PrintWriter out = new PrintWriter(System.out);
		int N = nextInt(), M = nextInt(), P = 1<<M;
		String x = nextStr();
		int c1 = x.charAt(0) - 'a';
		int[][] pair_count = new int[M][M];
		for (int i=1; i<N; i++) {
			int c2 = x.charAt(i) - 'a';
			if (c1 < c2) 
				pair_count[c1][c2]++;
			else if (c1 > c2)
				pair_count[c2][c1]++;
			c1 = c2;
		}
		int[] group_count = new int[P];
		for (int mask = 1; mask <P; mask++) {
			int j;
			for (j=0; j<M; j++) {
				if ((mask & BM[j]) > 0)  break;
			}
			int nmask = mask ^ BM[j];
			int val = group_count[nmask];
			for (int i=0; i<j; i++) {
				if ((mask & BM[i]) > 0)  val -= pair_count[i][j];
				else                   val += pair_count[i][j];
			}
			for (int i=j+1; i<M; i++) {
				if ((mask & BM[i]) > 0)  val -= pair_count[j][i];
				else                   val += pair_count[j][i];
			}
			group_count[mask] = val;
		}
		// dp[k][mask] = Accumulated cost of first K positions filled, mask position 1 letters are used
		// dp[0][0] = 0;
		int[][] dp = new int[M+1][P];	   // 
		for (int mask=1; mask<P; mask++) {  // each bit mask
			dp[0][mask] = 0;
			int k = Integer.bitCount(mask);  // computing first k position filled.
			int val = LARGE_INT;
			for (int j=0; j<M; j++) {
				if ((mask & BM[j]) > 0) {
					int nmask = mask ^ BM[j];
					val = Math.min(val, dp[k-1][nmask] + group_count[nmask]);
				}				
			}
			dp[k][mask] = val;
		}
		//out.println(Arrays.deepToString(dp));
		out.println(dp[M][P-1]);
		out.flush();
		out.close();
	}
	static int nextInt() throws IOException {
        return Integer.parseInt(input.next()); 
    } 
	static String nextStr() throws IOException {
        return input.next(); 
    } 
    static class DataReader { 
        BufferedReader br; 
        StringTokenizer st;
        public DataReader() throws IOException {	// reading from standard in
			br = new BufferedReader(new InputStreamReader(System.in));
        } 
		boolean hasNext() throws IOException { 
            while (st == null || !st.hasMoreElements()) {
				String line = br.readLine();
				if (line == null) { // end of file
					return false;
				}
                st = new StringTokenizer(line); 
            }
			return true;
		}
        String next() throws IOException { 
			if (hasNext())
				return st.nextToken(); 
			else
				return null;
        } 
    } 
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.util.*;
import java.io.*;

public class E {
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out, false);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        char[] str = scanner.next().toCharArray();
        int maxMask = 1 << m;
        long[] dp = new long[maxMask];
        int[][] dists = new int[m][m];
        for(int i = 1; i < n; i++) {
            int c1 = str[i] - 'a';
            int c2 = str[i-1] - 'a';
            dists[c1][c2]++;
            dists[c2][c1]++;
        }
        int[] pre = new int[maxMask];
        for(int mask = 0; mask < maxMask; mask++) {
            for(int i = 0; i < m; i++) {
                if (((1 << i) & mask) == 0) continue;
                for(int j = 0; j < m; j++) {
                    if (((1 << j) & mask) > 0) continue;
                    pre[mask] += dists[i][j];
                }
            }
        }
        Arrays.fill(dp, Long.MAX_VALUE/4);
        dp[0] = 0;
        for(int mask = 0; mask < maxMask; mask++) {
            if (dp[mask] == Long.MAX_VALUE/4) continue;
            for(int i = 0; i < m; i++) {
                if (((1 << i) & mask) > 0) continue;
                int nmask = mask | (1 << i);
                dp[nmask] = Math.min(dp[nmask], dp[mask] + pre[nmask]);
            }
        }
        out.println(dp[maxMask - 1]);
        out.flush();
    }
    
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;
        
        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }
        
        public FastScanner() {
            this(new InputStreamReader(System.in));
        }
        
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        
        int nextInt() {
            return Integer.parseInt(next());
        }
        
        long nextLong() {
            return Long.parseLong(next());
        }
        
        double nextDouble() {
            return Double.parseDouble(next());
        }
        
        String readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.util.*;
import java.io.*;

public class E
{
	public static void main(String[] args) throws IOException
	{new E();}
	
	FastScanner in = new FastScanner(System.in);
	PrintWriter out = new PrintWriter(System.out);
	
	int n, m, oo = 1 << 28;
	int[] dp, cost;
	int[][] to;
	char[] w;
	
	E() throws IOException
	{
		n = in.nextInt();
		m = in.nextInt();
		w = in.next().toCharArray();
		to = new int[m+1][m+1];
		for (int i = 0; i < n-1; i++)
			if (w[i] != w[i+1])
			{
				to[w[i]-'a'][w[i+1]-'a']++;
				to[w[i+1]-'a'][w[i]-'a']++;
			}

		cost = new int[1 << m];	
		for (int i = 0; i < (1 << m); i++)
			for (int j = 0; j < m; j++)
			{
				if (((1 << j) & i) > 0)
					continue;
				for (int k = 0; k < m; k++)
				{
					if (((1 << k) & i) == 0)
						continue;
					cost[i] += to[j][k];
				}
			}
		
		dp = new int[1 << m];
		Arrays.fill(dp, oo);
		dp[0] = 0;
		for (int i = 1; i < (1 << m); i++)
		{
			for (int j = 0; j < m; j++)
				if (((i >> j) & 1) > 0)
					dp[i] = Math.min(dp[i], dp[i ^ (1 << j)]);
			dp[i] += cost[i];
		}
		out.println(dp[(1 << m)-1]);
		out.close();	
	}
	
	void sort(int[] x)
	{
		int sz = x.length;
		Random r = new Random();
		for (int i = 0; i < sz; i++)
		{
			int j = r.nextInt(sz);
			x[i] = x[j]-(x[i]-(x[j] = x[i]));
		}
		Arrays.sort(x);
	}
	
	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream i) {
		    br = new BufferedReader(new InputStreamReader(i));
		    st = new StringTokenizer("");
		}		
		public String next() throws IOException {
		    if(st.hasMoreTokens())
		        return st.nextToken();
		    else
		        st = new StringTokenizer(br.readLine());
		    return next();
		}
		public int nextInt() throws IOException {
		    return Integer.parseInt(next());
		}
		public int[] intarr(int n) throws IOException {
			int[] res = new int[n];
			for (int i = 0; i < n; i++)
				res[i] = nextInt();
			return res;
		}
	    public long nextLong() throws IOException {
		    return Long.parseLong(next());
		}
		public double nextDouble() throws IOException {
		    return Double.parseDouble(next());
		}
    }
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
// practice with rainboy
import java.io.*;
import java.util.*;

public class CF1238E extends PrintWriter {
	CF1238E() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF1238E o = new CF1238E(); o.main(); o.flush();
	}

	static final int INF = 0x3f3f3f3f;
	void main() {
		int n = sc.nextInt();
		int m = sc.nextInt();
		byte[] cc = sc.next().getBytes();
		int[] kk = new int[1 << m];
		for (int i = 1; i < n; i++) {
			int a = cc[i - 1] - 'a';
			int b = cc[i] - 'a';
			kk[1 << a | 1 << b]++;
		}
		for (int h = 0; h < m; h++)
			for (int b = 0; b < 1 << m; b++)
				if ((b & 1 << h) == 0)
					kk[b | 1 << h] += kk[b];
		int[] dp = new int[1 << m];
		int m_ = (1 << m) - 1;
		for (int b = 1; b < 1 << m; b++) {
			int k = n - 1 - kk[b] - kk[m_ ^ b];
			int x = INF;
			for (int h = 0; h < m; h++)
				if ((b & 1 << h) != 0) {
					int b_ = b ^ 1 << h;
					x = Math.min(x, dp[b_]);
				}
			dp[b] = x == INF ? INF : x + k;
		}
		println(dp[m_]);
	}
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.util.*;
import java.io.*;

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

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		out.println(work());
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return b==0?a:gcd(b,a%b);
	}
	long work() {
		int n=in.nextInt();
		int m=in.nextInt();
		String str=in.next();
		long[] dp=new long[1<<m];
		long[][] cnt=new long[m][m];
		for(int i=1;i<n;i++) {
			int n1=str.charAt(i-1)-'a';
			int n2=str.charAt(i)-'a';
			cnt[n1][n2]++;
			cnt[n2][n1]++;
		}
		for(int i=1;i<1<<m;i++) {
			dp[i]=9999999999L;
			long v=0;
			for(int j=0;j<m;j++) {
				if((i&(1<<j))>0) {//第j个字母
					for(int k=0;k<m;k++) {
						if((i&(1<<k))==0) {
							v+=cnt[j][k];
						}
					}
				}
			}
			for(int j=0;j<m;j++) {
				if((i&(1<<j))>0) {
					dp[i]=Math.min(dp[i], dp[i-(1<<j)]+v);
				}
			}
		}
		
		return dp[(1<<m)-1];
	}
}



class FastReader
{
	BufferedReader br;
	StringTokenizer st;

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

	public String next() 
	{
		if(st==null || !st.hasMoreElements())
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

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

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np


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

public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt(),m=sc.nextInt();int g[]=new int[1<<m];
		StringBuffer s=new StringBuffer(sc.next());
		s=s.insert(0, 'A');
		int D=(1<<m)-1;
		for(int i=1;i<n;i++)
		{
			int x=s.charAt(i)-'a',y=s.charAt(i+1)-'a';
			if(x!=y)
				g[1<<x|1<<y]++;
		}
		for(int j=0;j<m;j++)
			for(int i=0;i<=D;i++)
				if((i>>j&1)!=0)
					g[i]+=g[i^1<<j];
		int f[]=new int[1<<m];
		Arrays.fill(f, Integer.MAX_VALUE/2);
		f[0]=0;
		for(int i=0;i<=D;i++)
			for(int j=0;j<m;j++)
				if((i>>j&1)==0)
					f[i|1<<j]=Math.min(f[i|1<<j], f[i]+g[D]-g[i]-g[D^i]);
		System.out.println(f[D]);
	}

}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.util.*;
import java.io.*;

public class E74 {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        int n = sc.nextInt(); int m = sc.nextInt();
        String s = sc.next();
        long time = System.currentTimeMillis();
        int [][] a = new int[m][m];
        int [][] pre = new int[m][(1 << m)];
        for (int i = 0; i < n - 1; i++) {
            if (s.charAt(i) == s.charAt(i + 1)) continue;
            a[s.charAt(i) - 'a'][s.charAt(i + 1) - 'a']++;
            a[s.charAt(i + 1) - 'a'][s.charAt(i) - 'a']++;
        }
        //System.out.println("Process Input: " + (System.currentTimeMillis() - time));
        for (int i = 0; i < m; i++) {
            int b = 0; int stor = 2;
            for (int j = 1; j < (1 << m); j++) {
                if (j == stor) {
                    b++;
                    stor = (1 << (b + 1));
                }
                pre[i][j] = pre[i][j ^ (1 << b)] + a[i][b];
            }
        }
        //System.out.println("Precomp: " + (System.currentTimeMillis() - time));
        long [] dp = new long[1 << m];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for (int mask = 1; mask < (1 << m); mask++) {
            // loop on the last added character in the mask
            for (int i = 0; i < m; i++) {
                if (((mask >> i) & 1) == 0) continue;
                long prev = dp[mask ^ (1 << i)];
                long contribution = (pre[i][mask] - pre[i][((1 << m) - 1) ^ mask]) * Integer.bitCount(mask);
                dp[mask] = Math.min(dp[mask], prev + contribution);
            }
        }
        //System.out.println("Done: " + (System.currentTimeMillis() - time));
        out.println(dp[(1 << m) - 1]);
        out.close();
    }


    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

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

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

        long nextLong() {
            return Long.parseLong(next());
        }

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

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }


    }

}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.util.*;
import java.lang.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.math.*;
public class Main {
    public void dfs(ArrayList<Integer>[] graph,int[] visited,int source) {
        
    }
    public static void main(String[] args) throws Exception{
        Reader.init(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Main mm =new Main();
        int n=Reader.nextInt();
        int m=Reader.nextInt();
        String s=Reader.next();
        int[][] count=new int[m][m];
        for(int i=1;i<n;i++) {
            count[s.charAt(i)-'a'][s.charAt(i-1)-'a']++;
            count[s.charAt(i-1)-'a'][s.charAt(i)-'a']++;
        }
        int[] dp=new int[1<<m];
        Arrays.fill(dp, Integer.MAX_VALUE/10);
        for(int i=0;i<m;i++) {
            dp[1<<i]=0;
        }
        for(int i=0;i<(1<<m);i++) {
            int extra=0;
            for(int j=0;j<m;j++) {
                if((i&(1<<j))>0) {
                for(int k=0;k<m;k++) {
                    if(j!=k &&  (i&(1<<k))==0) {
                        extra+=count[j][k];
                    }
                }
               }
            }
            for(int j=0;j<m;j++) {
                if((i&(1<<j))==0) {
                    dp[i|(1<<j)]=Math.min(dp[i|(1<<j)], dp[i]+extra);
                }
            }
        }
        out.println(dp[(1<<m)-1]);
        out.close();
}
}
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;
    /** call this method to initialize reader for InputStream */
    static void init() throws IOException {
         reader = new BufferedReader(
                 new FileReader("input.txt"));
    tokenizer = new StringTokenizer("");
    }
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }
    /** get next word */
    static String nextLine() throws IOException{
        return reader.readLine();
    }
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        }
        return tokenizer.nextToken();
    }
    static int nextInt() throws IOException {
        return Integer.parseInt( next() );
    }
    static long nextLong() throws IOException {
        return Long.parseLong( next() );
    }
    static double nextDouble() throws IOException {
        return Double.parseDouble( next() );
    }
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.io.*;
import java.util.*;

import static java.lang.Math.*;

public class E {
    static int g[][];
    static int n, m;
    static char[] s;
    static int dp[], inf = (int) 2e9;

    public static void main(String[] args) throws Exception {
        Scanner in = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        n = in.nextInt();
        m = in.nextInt();
        s = in.next().toCharArray();
        g = new int[m][m];
        for (int i = 1; i < n; i++) {
            int x = s[i - 1] - 'a', y = s[i] - 'a';
            if (x != y) {
                g[x][y]++;
                g[y][x]++;
            }
        }
        dp = new int[1 << m];
        Arrays.fill(dp, -1);
        pw.println(solve(0, 0));

        pw.close();
    }

    static int solve(int pos, int mask) {
        if (pos >= m) return 0;
        if (dp[mask] != -1) return dp[mask];
        int min = inf;
        for (int i = 0; i < m; i++) {
            if (!check(mask, i)) {
                int res = 0;
                for (int j = 0; j < m; j++) {
                    if (check(mask, j)) res += g[i][j] * pos;
                    else res -= g[i][j] * pos;
                }
                res += solve(pos + 1, set(mask, i));
                min = min(min, res);
            }
        }
        return dp[mask] = min;
    }

    static boolean check(int N, int pos) {
        return (N & (1 << pos)) != 0;
    }

    static int set(int N, int pos) {
        return N = N | (1 << pos);
    }

    static int reset(int N, int pos) {
        return N = N & ~(1 << pos);
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }
}
// Problem: 1238_E. Keyboard Purchase
// Time complexity: np
import java.io.*;
import java.util.*;
import static java.lang.Math.*;

public class E_fast {
    static int g[][];
    static int n, m;
    static char[] s;
    static int dp[], inf = (int) 2e9;
    static int cost[][];

    public static void main(String[] args) throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        n = in.nextInt();
        m = in.nextInt();
        s = in.next().toCharArray();
        g = new int[m][m];
        for (int i = 1; i < n; i++) {
            int x = s[i - 1] - 'a', y = s[i] - 'a';
            if (x != y) {
                g[x][y]++;
                g[y][x]++;
            }
        }
        cost = new int[m][1 << m];
        for (int i = 0; i < m; i++) {
            int w = 0;
            for (int j = 0; j < m; j++) w += g[i][j];
            pre(i, 0, 0, -w);
        }
        dp = new int[1 << m];
        Arrays.fill(dp, -1);
        pw.println(solve(0, 0));

        pw.close();
    }

    static void pre(int x, int pos, int mask, int w) {
        if (pos >= m) {
            cost[x][mask] = w;
            return;
        }
        pre(x, pos + 1, mask, w);
        pre(x, pos + 1, set(mask, pos), w + 2 * g[x][pos]);
    }

    static int solve(int pos, int mask) {
        if (pos >= m) return 0;
        if (dp[mask] != -1) return dp[mask];
        int min = inf;
        for (int i = 0; i < m; i++) {
            if (!check(mask, i)) {
                int res = cost[i][mask] * pos + solve(pos + 1, set(mask, i));
                min = min(min, res);
            }
        }
        return dp[mask] = min;
    }

    static boolean check(int N, int pos) {
        return (N & (1 << pos)) != 0;
    }

    static int set(int N, int pos) {
        return N = N | (1 << pos);
    }

    static int reset(int N, int pos) {
        return N = N & ~(1 << pos);
    }

    static void debug(Object... obj) {
        System.err.println(Arrays.deepToString(obj));
    }
    
    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
    
        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = null;
        }
    
        public String next() throws Exception {
            while (tokenizer == null || !tokenizer.hasMoreTokens())
                tokenizer = new StringTokenizer(reader.readLine());
            return tokenizer.nextToken();
        }
    
        public String nextLine() throws Exception {
            String line = null;
            tokenizer = null;
            line = reader.readLine();
            return line;
        }
    
        public int nextInt() throws Exception {
            return Integer.parseInt(next());
        }
    
        public double nextDouble() throws Exception {
            return Double.parseDouble(next());
        }
    
        public long nextLong() throws Exception {
            return Long.parseLong(next());
        }
    
    }
}