/**
 * BaZ :D
 */
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Main
{
    static MyScanner scan;
    static PrintWriter pw;
    static long MOD = 1_000_000_007;
    static long INF = 1_000_000_000_000_000_000L;
    static long inf = 2_000_000_000;
    public static void main(String[] args) {
        new Thread(null, null, "BaZ", 1 << 27) {
            public void run() {
                try {
                    solve();
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }
    static int n,m;
    static int dp[], cnt[][], sum[];
    static void solve() throws IOException
    {
        //initIo(true);
        initIo(false);
        StringBuilder sb = new StringBuilder();
        n = ni();
        m = ni();
        dp = new int[(1<<m)];
        char c[] = ne().toCharArray();
        cnt = new int[m][m];
        for(int i=0;i+1<n;++i) {
            if(c[i]!=c[i+1]) {
                ++cnt[c[i] - 'a'][c[i+1] - 'a'];
                ++cnt[c[i+1] - 'a'][c[i] - 'a'];
            }
        }
        sum = new int[1<<m];
        calc(0, 0, 0);
        Arrays.fill(dp, -1);
        pl(f(0));
        pw.flush();
        pw.close();
    }
    static void calc(int mask, int S, int pos) {
        if(pos==m) {
            sum[mask] = S;
            return;
        }
        calc(mask, S, pos+1);
        int newSum = S;
        for(int i=0;i<pos;++i) {
            if((mask&(1<<i))!=0) {
                newSum-=cnt[i][pos];
            }
            else {
                newSum+=cnt[i][pos];
            }
        }
        for(int i=pos+1;i<m;++i) {
            newSum+=cnt[i][pos];
        }
        calc(mask|(1<<pos), newSum, pos+1);
    }
    static int f(int mask) {
        if(mask==(1<<m) - 1) {
            return 0;
        }
        if(dp[mask]!=-1) {
            return dp[mask];
        }
        int min = Integer.MAX_VALUE;
        for(int i=0;i<m;++i) {
            if((mask&(1<<i))==0) {
                min  =  min(min, sum[mask]+f(mask|(1<<i)));
            }
        }
        return min;
    }
    static void initIo(boolean isFileIO) throws IOException {
        scan = new MyScanner(isFileIO);
        if(isFileIO) {
            pw = new PrintWriter("/Users/amandeep/Desktop/output.txt");
        }
        else {
            pw = new PrintWriter(System.out, true);
        }
    }
    static int ni() throws IOException
    {
        return scan.nextInt();
    }
    static long nl() throws IOException
    {
        return scan.nextLong();
    }
    static double nd() throws IOException
    {
        return scan.nextDouble();
    }
    static String ne() throws IOException
    {
        return scan.next();
    }
    static String nel() throws IOException
    {
        return scan.nextLine();
    }
    static void pl()
    {
        pw.println();
    }
    static void p(Object o)
    {
        pw.print(o+" ");
    }
    static void pl(Object o)
    {
        pw.println(o);
    }
    static void psb(StringBuilder sb)
    {
        pw.print(sb);
    }
    static void pa(String arrayName, Object arr[])
    {
        pl(arrayName+" : ");
        for(Object o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, int arr[])
    {
        pl(arrayName+" : ");
        for(int o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, long arr[])
    {
        pl(arrayName+" : ");
        for(long o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, double arr[])
    {
        pl(arrayName+" : ");
        for(double o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, char arr[])
    {
        pl(arrayName+" : ");
        for(char o : arr)
            p(o);
        pl();
    }
    static void pa(String listName, List list)
    {
        pl(listName+" : ");
        for(Object o : list)
            p(o);
        pl();
    }
    static void pa(String arrayName, Object[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(Object o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, int[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(int o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, long[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(long o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, char[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(char o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, double[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(double o : arr[i])
                p(o);
            pl();
        }
    }
    static class MyScanner
    {
        BufferedReader br;
        StringTokenizer st;
        MyScanner(boolean readingFromFile) throws IOException
        {
            if(readingFromFile) {
                br = new BufferedReader(new FileReader("/Users/amandeep/Desktop/input.txt"));
            }
            else {
                br = new BufferedReader(new InputStreamReader(System.in));
            }
        }
        String nextLine()throws IOException
        {
            return br.readLine();
        }
        String next() throws IOException
        {
            if(st==null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }
        int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
    }
}


/**
 * BaZ :D
 */
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Main
{
    static MyScanner scan;
    static PrintWriter pw;
    static long MOD = 1_000_000_007;
    static long INF = 1_000_000_000_000_000_000L;
    static long inf = 2_000_000_000;
    public static void main(String[] args) {
        new Thread(null, null, "BaZ", 1 << 27) {
            public void run() {
                try {
                    solve();
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }
    static int n,m;
    static int dp[], cnt[][], sum[];
    static void solve() throws IOException
    {
        //initIo(true);
        initIo(false);
        StringBuilder sb = new StringBuilder();
        n = ni();
        m = ni();
        dp = new int[(1<<m)];
        char c[] = ne().toCharArray();
        cnt = new int[m][m];
        for(int i=0;i+1<n;++i) {
            if(c[i]!=c[i+1]) {
                ++cnt[c[i] - 'a'][c[i+1] - 'a'];
                ++cnt[c[i+1] - 'a'][c[i] - 'a'];
            }
        }
        sum = new int[1<<m];
        calc(0, 0, 0);
        Arrays.fill(dp, -1);
        pl(f(0));
        pw.flush();
        pw.close();
    }
    static void calc(int mask, int S, int pos) {
        if(pos==m) {
            sum[mask] = S;
            return;
        }
        calc(mask, S, pos+1);
        int newSum = S;
        for(int i=0;i<pos;++i) {
            if((mask&(1<<i))!=0) {
                newSum-=cnt[i][pos];
            }
            else {
                newSum+=cnt[i][pos];
            }
        }
        for(int i=pos+1;i<m;++i) {
            newSum+=cnt[i][pos];
        }
        calc(mask|(1<<pos), newSum, pos+1);
    }
    static int f(int mask) {
        if(mask==(1<<m) - 1) {
            return 0;
        }
        if(dp[mask]!=-1) {
            return dp[mask];
        }
        int min = Integer.MAX_VALUE;
        for(int i=0;i<m;++i) {
            if((mask&(1<<i))==0) {
                min  =  min(min, sum[mask]+f(mask|(1<<i)));
            }
        }
        return dp[mask] = min;
    }
    static void initIo(boolean isFileIO) throws IOException {
        scan = new MyScanner(isFileIO);
        if(isFileIO) {
            pw = new PrintWriter("/Users/amandeep/Desktop/output.txt");
        }
        else {
            pw = new PrintWriter(System.out, true);
        }
    }
    static int ni() throws IOException
    {
        return scan.nextInt();
    }
    static long nl() throws IOException
    {
        return scan.nextLong();
    }
    static double nd() throws IOException
    {
        return scan.nextDouble();
    }
    static String ne() throws IOException
    {
        return scan.next();
    }
    static String nel() throws IOException
    {
        return scan.nextLine();
    }
    static void pl()
    {
        pw.println();
    }
    static void p(Object o)
    {
        pw.print(o+" ");
    }
    static void pl(Object o)
    {
        pw.println(o);
    }
    static void psb(StringBuilder sb)
    {
        pw.print(sb);
    }
    static void pa(String arrayName, Object arr[])
    {
        pl(arrayName+" : ");
        for(Object o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, int arr[])
    {
        pl(arrayName+" : ");
        for(int o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, long arr[])
    {
        pl(arrayName+" : ");
        for(long o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, double arr[])
    {
        pl(arrayName+" : ");
        for(double o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, char arr[])
    {
        pl(arrayName+" : ");
        for(char o : arr)
            p(o);
        pl();
    }
    static void pa(String listName, List list)
    {
        pl(listName+" : ");
        for(Object o : list)
            p(o);
        pl();
    }
    static void pa(String arrayName, Object[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(Object o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, int[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(int o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, long[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(long o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, char[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(char o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, double[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(double o : arr[i])
                p(o);
            pl();
        }
    }
    static class MyScanner
    {
        BufferedReader br;
        StringTokenizer st;
        MyScanner(boolean readingFromFile) throws IOException
        {
            if(readingFromFile) {
                br = new BufferedReader(new FileReader("/Users/amandeep/Desktop/input.txt"));
            }
            else {
                br = new BufferedReader(new InputStreamReader(System.in));
            }
        }
        String nextLine()throws IOException
        {
            return br.readLine();
        }
        String next() throws IOException
        {
            if(st==null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }
        int nextInt() throws IOException
        {
            return Integer.parseInt(next());
        }
        long nextLong() throws IOException
        {
            return Long.parseLong(next());
        }
        double nextDouble() throws IOException
        {
            return Double.parseDouble(next());
        }
    }
}


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

public class CF1238E {
    public static void main(String[] args) throws Exception {
        boolean local = System.getSecurityManager() == null;
        boolean async = false;

        Charset charset = Charset.forName("ascii");

        FastIO io = local ? new FastIO(new FileInputStream("D:\\DATABASE\\TESTCASE\\Code.in"), System.out, charset) : new FastIO(System.in, System.out, charset);
        Task task = new Task(io, new Debug(local));

        if (async) {
            Thread t = new Thread(null, task, "dalt", 1 << 27);
            t.setPriority(Thread.MAX_PRIORITY);
            t.start();
            t.join();
        } else {
            task.run();
        }

        if (local) {
            io.cache.append("\n\n--memory -- \n" + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20) + "M");
        }

        io.flush();
    }

    public static class Task implements Runnable {
        final FastIO io;
        final Debug debug;
        int inf = (int) 1e8;
        long lInf = (long) 1e18;
        double dInf = 1e50;

        public Task(FastIO io, Debug debug) {
            this.io = io;
            this.debug = debug;
        }

        @Override
        public void run() {
            solve();
        }

        int[][] fee;
        int m;
        long[] dp;
        int mask;
        int[][] maskFee;

        public void solve() {
            int n = io.readInt();
            m = io.readInt();
            char[] s = new char[n];
            io.readString(s, 0);
            for (int i = 0; i < n; i++) {
                s[i] -= 'a';
            }
            fee = new int[m][m];
            for (int i = 1; i < n; i++) {
                fee[s[i]][s[i - 1]]++;
                fee[s[i - 1]][s[i]]++;
            }

            mask = (1 << m) - 1;
            maskFee = new int[m][mask + 1];
            SubsetGenerator sg = new SubsetGenerator();
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < m; j++) {
                    sg.meanings[j] = fee[i][j];
                }
                for (int j = 0; j <= mask; j++) {
                    maskFee[i][j] = sg.next();
                }
            }

            dp = new long[mask + 1];
            Arrays.fill(dp, -1);
            dp[0] = 0;

            io.cache.append(dp(mask));
        }

        BitOperator bo = new BitOperator();

        public long dp(int s) {
            if (dp[s] == -1) {
                long extra = 0;
                int remainSet = mask - s;
                for (int j = 0; j < m; j++) {
                    if (bo.bitAt(s, j) == 0) {
                        continue;
                    }
                    extra += maskFee[j][remainSet];
                }

                dp[s] = lInf;
                for (int j = 0; j < m; j++) {
                    if (bo.bitAt(s, j) == 0) {
                        continue;
                    }
                    int ss = bo.setBit(s, j, false);
                    dp[s] = Math.min(dp[s], extra + dp(ss));
                }
            }

            return dp[s];
        }
    }

    /**
     * Bit operations
     */
    public static class BitOperator {
        public int bitAt(int x, int i) {
            return (x >> i) & 1;
        }

        public int bitAt(long x, int i) {
            return (int) ((x >> i) & 1);
        }

        public int setBit(int x, int i, boolean v) {
            if (v) {
                x |= 1 << i;
            } else {
                x &= ~(1 << i);
            }
            return x;
        }

        public long setBit(long x, int i, boolean v) {
            if (v) {
                x |= 1L << i;
            } else {
                x &= ~(1L << i);
            }
            return x;
        }

        public long swapBit(long x, int i, int j) {
            int bi = bitAt(x, i);
            int bj = bitAt(x, j);
            x = setBit(x, i, bj == 1);
            x = setBit(x, j, bi == 1);
            return x;
        }

        public int swapBit(int x, int i, int j) {
            int bi = bitAt(x, i);
            int bj = bitAt(x, j);
            x = setBit(x, i, bj == 1);
            x = setBit(x, j, bi == 1);
            return x;
        }

        /**
         * Determine whether x is subset of y
         */
        public boolean subset(long x, long y) {
            return intersect(x, y) == x;
        }

        /**
         * Merge two set
         */
        public long merge(long x, long y) {
            return x | y;
        }

        public long intersect(long x, long y) {
            return x & y;
        }

        public long differ(long x, long y) {
            return x - intersect(x, y);
        }
    }

    public static class SubsetGenerator {
        private int[] meanings = new int[33];
        private int[] bits = new int[33];
        private int remain;
        private int next;

        public void setSet(int set) {
            int bitCount = 0;
            while (set != 0) {
                meanings[bitCount] = set & -set;
                bits[bitCount] = 0;
                set -= meanings[bitCount];
                bitCount++;
            }
            remain = 1 << bitCount;
            next = 0;
        }

        public boolean hasNext() {
            return remain > 0;
        }

        private void consume() {
            remain = remain - 1;
            int i;
            for (i = 0; bits[i] == 1; i++) {
                bits[i] = 0;
                next -= meanings[i];
            }
            bits[i] = 1;
            next += meanings[i];
        }

        public int next() {
            int returned = next;
            consume();
            return returned;
        }
    }

    public static class FastIO {
        public final StringBuilder cache = new StringBuilder(1 << 13);
        private final InputStream is;
        private final OutputStream os;
        private final Charset charset;
        private StringBuilder defaultStringBuf = new StringBuilder(1 << 13);
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastIO(InputStream is, OutputStream os, Charset charset) {
            this.is = is;
            this.os = os;
            this.charset = charset;
        }

        public FastIO(InputStream is, OutputStream os) {
            this(is, os, Charset.forName("ascii"));
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public double readDouble() {
            boolean sign = true;
            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+';
                next = read();
            }

            long val = 0;
            while (next >= '0' && next <= '9') {
                val = val * 10 + next - '0';
                next = read();
            }
            if (next != '.') {
                return sign ? val : -val;
            }
            next = read();
            long radix = 1;
            long point = 0;
            while (next >= '0' && next <= '9') {
                point = point * 10 + next - '0';
                radix = radix * 10;
                next = read();
            }
            double result = val + (double) point / radix;
            return sign ? result : -result;
        }

        public String readString(StringBuilder builder) {
            skipBlank();

            while (next > 32) {
                builder.append((char) next);
                next = read();
            }

            return builder.toString();
        }

        public String readString() {
            defaultStringBuf.setLength(0);
            return readString(defaultStringBuf);
        }

        public int readLine(char[] data, int offset) {
            int originalOffset = offset;
            while (next != -1 && next != '\n') {
                data[offset++] = (char) next;
                next = read();
            }
            return offset - originalOffset;
        }

        public int readString(char[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (char) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public int readString(byte[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (byte) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public char readChar() {
            skipBlank();
            char c = (char) next;
            next = read();
            return c;
        }

        public void flush() throws IOException {
            os.write(cache.toString().getBytes(charset));
            os.flush();
            cache.setLength(0);
        }

        public boolean hasMore() {
            skipBlank();
            return next != -1;
        }
    }

    public static class Debug {
        private boolean allowDebug;

        public Debug(boolean allowDebug) {
            this.allowDebug = allowDebug;
        }

        public void assertTrue(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (!flag) {
                fail();
            }
        }

        public void fail() {
            throw new RuntimeException();
        }

        public void assertFalse(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (flag) {
                fail();
            }
        }

        private void outputName(String name) {
            System.out.print(name + " = ");
        }

        public void debug(String name, int x) {
            if (!allowDebug) {
                return;
            }

            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, long x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, double x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, int[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, long[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, double[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, Object x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, Object... x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.deepToString(x));
        }
    }
}


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;
	}

}


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

public class Main {
	static int t,m,mod=998244353,maxn=1000000,q,n,k;
    static int INF=(int)1e8;

    void solve(PrintWriter out, Reader in) throws IOException{
        n = in.nextInt();
        m = in.nextInt();

        String str = in.next();
        int[][] pre = new int[1<<m][m];

        int child=0,head,child2=0;
        for(int i=0;i<n;i++){
            if(i!=0) child = 1<<(str.charAt(i-1)-'a');
            if(i!=n-1) child2 = 1<<(str.charAt(i+1)-'a');
            head = str.charAt(i)-'a';

            if(i!=0) pre[child][head]++;
            if(i!=n-1) pre[child2][head]++;
        }

        //pre[child][head] - number of elemnts that exists in child and are adjacent to head in the string.

        int rmv=0;
        for(int i=0;i<m;i++){
            head = i;
            for(int j=1;j<1<<m;j++){
                if(pre[j][i]!=0) continue;

                rmv = j-(j&-j);
                pre[j][head] = pre[rmv][head]+pre[j^rmv][head];
            }
        }

        int[] dp = new int[1<<m];
        for(int i=1;i<1<<m;i++) dp[i] = INF;

        // dp[mask] - the minimum cost using a permutation of the set bits in the mask.

        int bit=0,full=(1<<m)-1,cnt=0;
        for(int j=1;j<1<<m;j++){
            for(int i=0;i<m;i++){
                if(((1<<i)&j)!=0){
                    bit = 1<<i;
                    cnt = cnt(j);
                    dp[j] = Math.min(dp[j],dp[j^bit]+pre[j^bit][i]*cnt-pre[j^full][i]*cnt);
                }
            }
        }

        out.println(dp[full]);
    }

    static int cnt(int x){
        int res=0;
        while(x>0){
            res+=x&1;
            x>>=1;
        }
        return res;
    }

    static class Reader {

    private InputStream mIs;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public Reader() {
        this(System.in);
    }

    public Reader(InputStream is) {
        mIs = is;
    }

    public int read() {
        if (numChars == -1) {
            throw new InputMismatchException();

    }
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = mIs.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0) {
                return -1;
            }
        }
        return buf[curChar++];
    }

    public String nextLine() {
        int c = read();
        while (isSpaceChar(c)) {
            c = read();
        }
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isEndOfLine(c));
        return res.toString();
    }

    public String next() {
        int c = read();
        while (isSpaceChar(c)) {
            c = read();
        }
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

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

    public long nextLong() {
        int c = read();
        while (isSpaceChar(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9') {
                throw new InputMismatchException();
            }
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public int nextInt() {
        int c = read();
        while (isSpaceChar(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9') {
                throw new InputMismatchException();
            }
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public boolean isEndOfLine(int c) {
        return c == '\n' || c == '\r' || c == -1;
    }

    }
    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
        Reader in = new Reader();
        Main solver = new Main();
        solver.solve(out, in);
        out.flush();
        out.close();

    }
}


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));
    }
}


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());
        }

    }
}


import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

import static java.lang.Math.cos;
import static java.lang.Math.min;

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 {
        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]++;
            }
        }
        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));
    }
}


import java.io.*;
import java.util.*;
public class Sol2{
	final public static int MXN = (1<<21);
	public static void main(String[] args) throws IOException{
		FastIO sc = new FastIO(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int num[][] = new int[m][m];
		String str = sc.next();
		for(int i=0; i<str.length()-1; i++) {
			int a = str.charAt(i)-'a';
			int b = str.charAt(i+1)-'a';
			num[a][b]++;
			num[b][a]++;
		}
		int dp[] = new int[MXN];
		for(int i=0; i<MXN; i++) {
			dp[i] = Integer.MAX_VALUE;
		}
		dp[0] = 0;
		for(int msk = 0; msk<(1<<m); msk++) {
			int bits = Integer.bitCount(msk)+1;
			for(int i=0; i<m; i++) {
				if((msk&(1<<i))!=0) continue;
				int nxt = msk|(1<<i);
				int sub = 0;
				int add = 0;
				for(int j=0; j<m; j++) {
					if((nxt&(1<<j))==0) {
						sub+=num[j][i];
					}else if((msk&(1<<j))!=0) {
						add+=num[j][i];
					}
				}
				dp[nxt] = Math.min(dp[nxt], dp[msk] + bits*(add-sub));
			}
		}
		out.println(dp[(1<<m)-1]);
		out.close();
	}
	static void shuffle(int[] a) {
		Random get = new Random();
		for (int i = 0; i < a.length; i++) {
			int r = get.nextInt(a.length);
			int temp = a[i];
			a[i] = a[r];
			a[r] = temp;
		}
	}
	static class FastIO {

		// Is your Fast I/O being bad?

		InputStream dis;
		byte[] buffer = new byte[1 << 17];
		int pointer = 0;

		public FastIO(String fileName) throws IOException {
			dis = new FileInputStream(fileName);
		}

		public FastIO(InputStream is) throws IOException {
			dis = is;
		}

		int nextInt() throws IOException {
			int ret = 0;

			byte b;
			do {
				b = nextByte();
			} while (b <= ' ');
			boolean negative = false;
			if (b == '-') {
				negative = true;
				b = nextByte();
			}
			while (b >= '0' && b <= '9') {
				ret = 10 * ret + b - '0';
				b = nextByte();
			}

			return (negative) ? -ret : ret;
		}

		long nextLong() throws IOException {
			long ret = 0;

			byte b;
			do {
				b = nextByte();
			} while (b <= ' ');
			boolean negative = false;
			if (b == '-') {
				negative = true;
				b = nextByte();
			}
			while (b >= '0' && b <= '9') {
				ret = 10 * ret + b - '0';
				b = nextByte();
			}

			return (negative) ? -ret : ret;
		}

		byte nextByte() throws IOException {
			if (pointer == buffer.length) {
				dis.read(buffer, 0, buffer.length);
				pointer = 0;
			}
			return buffer[pointer++];
		}

		String next() throws IOException {
			StringBuffer ret = new StringBuffer();

			byte b;
			do {
				b = nextByte();
			} while (b <= ' ');
			while (b > ' ') {
				ret.appendCodePoint(b);
				b = nextByte();
			}

			return ret.toString();
		}

	}
}


import java.io.*;
import java.util.*;
public class Sol2{
	final public static int MXN = (1<<21);
	public static int good[][];
	public static void main(String[] args) throws IOException{
		FastIO sc = new FastIO(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int num[][] = new int[m][m];
		String str = sc.next();
		for(int i=0; i<str.length()-1; i++) {
			int a = str.charAt(i)-'a';
			int b = str.charAt(i+1)-'a';
			num[a][b]++;
			num[b][a]++;
		}
		int lowbit[] = new int[MXN];
		int dp[] = new int[MXN];
		for(int i=0; i<MXN; i++) {
			dp[i] = Integer.MAX_VALUE;
		}
		dp[0] = 0;
		good = new int[MXN][m];
		for(int msk = 0; msk<(1<<m); msk++) {
			for(int i=0; i<m; i++) {
				int low = Integer.numberOfTrailingZeros(Integer.lowestOneBit(msk));
				if(low==32) low = 0;
				good[msk][i] = good[msk^(1<<low)][i] + num[i][low];
			}
		}
		for(int msk = 0; msk<(1<<m); msk++) {
			int bits = Integer.bitCount(msk)+1;
			for(int i=0; i<m; i++) {
				if((msk&(1<<i))!=0) continue;
				int nxt = msk|(1<<i);
				dp[nxt] = Math.min(dp[nxt], dp[msk] + bits*(good[msk][i]-good[((1<<m)-1)^nxt][i]));
			}
		}
		out.println(dp[(1<<m)-1]);
		out.close();
	}
	static void shuffle(int[] a) {
		Random get = new Random();
		for (int i = 0; i < a.length; i++) {
			int r = get.nextInt(a.length);
			int temp = a[i];
			a[i] = a[r];
			a[r] = temp;
		}
	}
	static class FastIO {

		// Is your Fast I/O being bad?

		InputStream dis;
		byte[] buffer = new byte[1 << 17];
		int pointer = 0;

		public FastIO(String fileName) throws IOException {
			dis = new FileInputStream(fileName);
		}

		public FastIO(InputStream is) throws IOException {
			dis = is;
		}

		int nextInt() throws IOException {
			int ret = 0;

			byte b;
			do {
				b = nextByte();
			} while (b <= ' ');
			boolean negative = false;
			if (b == '-') {
				negative = true;
				b = nextByte();
			}
			while (b >= '0' && b <= '9') {
				ret = 10 * ret + b - '0';
				b = nextByte();
			}

			return (negative) ? -ret : ret;
		}

		long nextLong() throws IOException {
			long ret = 0;

			byte b;
			do {
				b = nextByte();
			} while (b <= ' ');
			boolean negative = false;
			if (b == '-') {
				negative = true;
				b = nextByte();
			}
			while (b >= '0' && b <= '9') {
				ret = 10 * ret + b - '0';
				b = nextByte();
			}

			return (negative) ? -ret : ret;
		}

		byte nextByte() throws IOException {
			if (pointer == buffer.length) {
				dis.read(buffer, 0, buffer.length);
				pointer = 0;
			}
			return buffer[pointer++];
		}

		String next() throws IOException {
			StringBuffer ret = new StringBuffer();

			byte b;
			do {
				b = nextByte();
			} while (b <= ' ');
			while (b > ' ') {
				ret.appendCodePoint(b);
				b = nextByte();
			}

			return ret.toString();
		}

	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        EKeyboardPurchase solver = new EKeyboardPurchase();
        solver.solve(1, in, out);
        out.close();
    }

    static class EKeyboardPurchase {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            int m = in.scanInt();
            int step[][] = new int[m][m];
            char arr[] = in.scanString().toCharArray();
            for (int i = 0; i < n - 1; i++) {
                step[arr[i] - 'a'][arr[i + 1] - 'a']++;
                step[arr[i + 1] - 'a'][arr[i] - 'a']++;
            }

            long dp[] = new long[1 << m];
            Arrays.fill(dp, Long.MAX_VALUE / 3);
            for (int i = 0; i < m; i++) dp[1 << i] = 0;
            for (int i = 0; i < (1 << m); i++) {
                long cost = 0;
                for (int j = 0; j < m; j++) {
                    for (int k = 0; k < m; k++) {
                        if (((i & (1 << j)) != 0) && ((i & (1 << k)) == 0)) {
                            cost += step[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] + cost);

            }

            out.println(dp[(1 << m) - 1]);

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        EKeyboardPurchase solver = new EKeyboardPurchase();
        solver.solve(1, in, out);
        out.close();
    }

    static class EKeyboardPurchase {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            int n = in.scanInt();
            int m = in.scanInt();
            int step[][] = new int[m][m];
            char arr[] = in.scanString().toCharArray();
            for (int i = 0; i < n - 1; i++) {
                step[arr[i] - 'a'][arr[i + 1] - 'a']++;
                step[arr[i + 1] - 'a'][arr[i] - 'a']++;
            }

            int dp[] = new int[1 << m];
            Arrays.fill(dp, Integer.MAX_VALUE / 2);
            for (int i = 0; i < m; i++) dp[1 << i] = 0;
            for (int i = 0; i < (1 << m); i++) {
                int cost = 0;
                for (int j = 0; j < m; j++) {
                    if (((i & (1 << j)) != 0)) {
                        for (int k = 0; k < m; k++) {
                            if (((i & (1 << k)) == 0)) {
                                cost += step[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] + cost);

            }

            out.println(dp[(1 << m) - 1]);

        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        public String scanString() {
            int c = scan();
            while (isWhiteSpace(c)) c = scan();
            StringBuilder RESULT = new StringBuilder();
            do {
                RESULT.appendCodePoint(c);
                c = scan();
            } while (!isWhiteSpace(c));
            return RESULT.toString();
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}


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

public class Main {
	static long mod = 1000000007;
	static int INF = 1000000000;
 	public static void main(String[] args){
		FastScanner scanner = new FastScanner();
		int n = scanner.nextInt();
		int m = scanner.nextInt();
		String s = scanner.next();
		int[][] cnt = new int[20][20];
		for(int i = 0; i < n-1; i++){
			cnt[s.charAt(i)-'a'][s.charAt(i+1)-'a']++;
			cnt[s.charAt(i+1)-'a'][s.charAt(i)-'a']++;
		}
		//dp[i]:= 文字列i(この中に同一文字は含まれない)を作った時のコストの最小値
		int[] dp = new int[(1<<m)];
		for(int i = 0; i < (1<<m); i++){
			dp[i] = INF;
		}
		dp[0] = 0;
		for(int i = 0; i < (1<<m); i++){
			int cost = 0;
			for(int j = 0; j < m; j++){
				if((i>>j & 1) == 0){
					for(int k = 0; k < m; k++){
						if((~i>>k & 1) == 0){
							cost += cnt[j][k];
						}
					}
				}
			}
			for(int j = 0; j < m; j++){
				dp[i|1<<j] = Math.min(dp[i|1<<j],dp[i]+cost);
			}
		}
		System.out.println(dp[(1<<m)-1]);
	}
	static class BIT{
		int n;
		int[] bit;
		public BIT(int n){
			this.n = n;
			bit = new int[n+1];
		}
		void add(int idx, int val){
			for(int i = idx+1; i <= n; i += i&(-i)) bit[i-1] += val;
		}
		int sum(int idx){
			int res = 0;
			for(int i = idx+1; i > 0; i -= i&(-i)) res += bit[i-1];
			return res;
		}
		int sum(int begin, int end){
			if(begin == 0) return sum(end);
			return sum(end)-sum(begin-1);
		}
	}
	static class Pair implements Comparable<Pair>{
    int first, second;
    Pair(int a, int b){
        first = a;
        second = b;
    }
    @Override
    public boolean equals(Object o){
        if (this == o) return true;
        if (!(o instanceof Pair)) return false;
        Pair p = (Pair) o;
        return first == p.first && second == p.second;
    }
    @Override
    public int compareTo(Pair p){
        return first == p.first ? second - p.second : first - p.first; //firstで昇順にソート
        //return (first == p.first ? second - p.second : first - p.first) * -1; //firstで降順にソート
        //return second == p.second ? first - p.first : second - p.second;//secondで昇順にソート
        //return (second == p.second ? first - p.first : second - p.second)*-1;//secondで降順にソート
		    //return first * 1.0 / second > p.first * 1.0 / p.second ? 1 : -1; // first/secondの昇順にソート
		    //return first * 1.0 / second < p.first * 1.0 / p.second ? 1 : -1; // first/secondの降順にソート
				//return second * 1.0 / first > p.second * 1.0 / p.first ? 1 : -1; // second/firstの昇順にソート
		    //return second * 1.0 / first < p.second * 1.0 / p.first ? 1 : -1; // second/firstの降順にソート
				//return Math.atan2(second, first) > Math.atan2(p.second, p.first) ? 1 : -1; // second/firstの昇順にソート
				//return first + second > p.first + p.second ? 1 : -1; //first+secondの昇順にソート
				//return first + second < p.first + p.second ? 1 : -1; //first+secondの降順にソート
				//return first - second < p.first - p.second ? 1 : -1; //first-secondの降順にソート
		}
  }

	private 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());}
	}
}


/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static long factorial[],invFactorial[];
    static ArrayList<Pair> graph[];
    static boolean oj = System.getProperty("ONLINE_JUDGE") != null;
/****************************************Solutions Begins***************************************/
    static int n,m;
    static long cost[][],dp[];
    public static void main(String[] args) throws Exception{
        String st[]=nl();
        n=pi(st[0]);
        m=pi(st[1]);
        st=nl();
        String str=st[0];
        int mn=10000;
        for(int i=0;i<n;i++){
            mn=Math.min(mn,str.charAt(i));
        }
        cost=new long[m][m];
        for(int i=1;i<n;i++){
            int a1=str.charAt(i-1)-mn;
            int a2=str.charAt(i)-mn;
            cost[a1][a2]++;
            cost[a2][a1]++;
        }
        int mm=1<<m;
        dp=new long[mm];
        Arrays.fill(dp,Long.MAX_VALUE/2);
        dp[0]=0;
        //debug(cost);
        for(int mask=0;mask<mm;mask++){
            long cnt=countBit(mask);
            for(int i=0;i<m;i++){
                if(((mask>>i)&1)!=0){
                    long ans=0;
                    for(int j=0;j<m;j++){
                        if(i==j)continue;
                        if(((mask>>j)&1)!=0){
                            ans+=cost[i][j];
                        }
                        else{
                            ans-=cost[i][j];
                        }
                    }
                    ans*=cnt;
                    dp[mask]=Math.min(dp[mask],dp[mask^(1<<i)]+ans);
                }
            }
        }
        out.println(dp[mm-1]);
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }
/****************************************Template Begins************************************************/
    static String[] nl() throws Exception{
        return br.readLine().split(" ");
    }
    static String[] nls() throws Exception{
        return br.readLine().split("");
    }
    static int pi(String str) {
        return Integer.parseInt(str);
    }
    static long pl(String str){
        return Long.parseLong(str);
    }
    static double pd(String str){
        return Double.parseDouble(str);
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.000000000000000000000");
        out.println(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static void printMask(long mask){
        System.out.println(Long.toBinaryString(mask));
    }
    static int countBit(long mask){
        int ans=0;
        while(mask!=0){
            if(mask%2==1){
                ans++;
            }
            mask/=2;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new ArrayList[n];
        for(int i=0;i<n;i++){
            graph[i]=new ArrayList<>();
        }
    }
    static void addEdge(int a,int b){
        graph[a].add(new Pair(b,1));
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            return p1.u-p2.u;
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            long a=p1.u*p2.v;
            long b=p2.u*p1.v;
            if(a>b){
                return -1;
            }
            else if(a<b){
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    static class Pairl implements Comparable<Pairl> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pairl other = (Pairl) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pairl other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        if(!oj)
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a%c;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}


/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static long factorial[],invFactorial[];
    static ArrayList<Pair> graph[];
    static boolean oj = System.getProperty("ONLINE_JUDGE") != null;
/****************************************Solutions Begins***************************************/
    static int n,m;
    static long cost[][],dp[];
    public static void main(String[] args) throws Exception{
        String st[]=nl();
        n=pi(st[0]);
        m=pi(st[1]);
        st=nl();
        String str=st[0];
        int mn=10000;
        for(int i=0;i<n;i++){
            mn=Math.min(mn,str.charAt(i));
        }
        cost=new long[m][m];
        for(int i=1;i<n;i++){
            int a1=str.charAt(i-1)-mn;
            int a2=str.charAt(i)-mn;
            if(a1==a2)continue;
            cost[a1][a2]++;
            cost[a2][a1]++;
        }
        int mm=1<<m;
        dp=new long[mm];
        Arrays.fill(dp,Long.MAX_VALUE/2);
        dp[0]=0;
        //debug(cost);
        long cntbit[]=new long[mm];
        int minbit[]=new int[mm];

        for(int mask=1;mask<mm;mask++){
            cntbit[mask]=1+cntbit[(mask&(mask-1))];
            for(int i=0;i<m;i++){
                if(((mask>>i)&1)!=0){
                    minbit[mask]=i;
                    break;
                }
            }
        }
        long cntcost[][]=new long[mm][m];
        for(int mask=0;mask<mm;mask++){
            for(int i=0;i<m;i++){
                int b=minbit[mask];
                cntcost[mask][i]=cntcost[mask^(1<<b)][i]+cost[i][b];
            }
        }
        int yy=mm-1;
        for(int mask=0;mask<mm;mask++){
            long cnt=cntbit[mask];
            for(int i=0;i<m;i++){
                if(((mask>>i)&1)!=0){
                    long ans=cnt*(cntcost[mask][i]-cntcost[yy^mask][i]);
                    dp[mask]=Math.min(dp[mask],dp[mask^(1<<i)]+ans);
                }
            }
        }
        out.println(dp[mm-1]);
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }
/****************************************Template Begins************************************************/
    static String[] nl() throws Exception{
        return br.readLine().split(" ");
    }
    static String[] nls() throws Exception{
        return br.readLine().split("");
    }
    static int pi(String str) {
        return Integer.parseInt(str);
    }
    static long pl(String str){
        return Long.parseLong(str);
    }
    static double pd(String str){
        return Double.parseDouble(str);
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.000000000000000000000");
        out.println(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static void printMask(long mask){
        System.out.println(Long.toBinaryString(mask));
    }
    static int countBit(long mask){
        int ans=0;
        while(mask!=0){
            if(mask%2==1){
                ans++;
            }
            mask/=2;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new ArrayList[n];
        for(int i=0;i<n;i++){
            graph[i]=new ArrayList<>();
        }
    }
    static void addEdge(int a,int b){
        graph[a].add(new Pair(b,1));
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            return p1.u-p2.u;
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            long a=p1.u*p2.v;
            long b=p2.u*p1.v;
            if(a>b){
                return -1;
            }
            else if(a<b){
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    static class Pairl implements Comparable<Pairl> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pairl other = (Pairl) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pairl other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        if(!oj)
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a%c;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}


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++) {
                for(int k=0;k<m;k++) {
                    if(j!=k && (i&(1<<j))>0 && (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() );
    }
}


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() );
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n, m;
	char[] str;
	int[][] occs, cost;
	int[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		//where's my 420???? :(
		long tot = 0;
		for(int i = 0; i < 19999; i++) tot += i;
		System.err.println(tot);

		n = fs.nextInt(); m = fs.nextInt();
		byte[] str = fs.next().getBytes();
		int[] occs = new int[1<<m];
		for(int i = 0; i < n-1; i++) {
			int l1 = str[i] - 'a';
			int l2 = str[i+1] - 'a';
			occs[(1<<l1) | (1<<l2)]++;
			occs[(1<<l2) | (1<<l1)]++;
		}
		//cost[mask][v] = numPairs with v for some all bits on in mask
		int all = (1<<m)-1;
		cost = new int[m][1<<m];
		for(int i = 0; i < m; i++) {
			for(int mask = 1; mask < all; mask++) {
				if(((1<<i)&mask) > 0) continue;
				int lb = mask & (-mask);
				int trail = Integer.numberOfTrailingZeros(lb);
				int nmask = mask ^ lb;
				cost[i][mask] = cost[i][nmask]+occs[1<<i | 1<<trail];
			}
		}

		dp = new int[1<<m];
		for(int mask = dp.length-2; mask >= 0; mask--) {
			int addOn = 0;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				addOn += cost[nxt][mask];
			}
			int res = oo;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				int ret = addOn+dp[mask | (1<<nxt)];
				res = min(res, ret);
			}
			dp[mask] = res;
		}

		System.out.println(dp[0]>>1);

		out.close();
	}

	int oo = (int)1e9;
	int min(int a, int b) {
		if(a < b) return a;
		return b;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n, m;
	char[] str;
	int[][] occs, cost;
	int[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		//where's my 420???? :(
		long tot = 0;
		for(int i = 0; i < 20000; i++) tot += i;

		n = fs.nextInt(); m = fs.nextInt();
		byte[] str = fs.next().getBytes();
		int[] occs = new int[1<<m];
		for(int i = 0; i < n-1; i++) {
			int l1 = str[i] - 'a';
			int l2 = str[i+1] - 'a';
			occs[(1<<l1) | (1<<l2)]++;
			occs[(1<<l2) | (1<<l1)]++;
		}
		//cost[mask][v] = numPairs with v for some all bits on in mask
		int all = (1<<m)-1;
		cost = new int[m][1<<m];
		for(int i = 0; i < m; i++) {
			for(int mask = 1; mask < all; mask++) {
				if(((1<<i)&mask) > 0) continue;
				int lb = mask & (-mask);
				int trail = Integer.numberOfTrailingZeros(lb);
				int nmask = mask ^ lb;
				cost[i][mask] = cost[i][nmask]+occs[1<<i | 1<<trail];
			}
		}

		dp = new int[1<<m];
		for(int mask = dp.length-2; mask >= 0; mask--) {
			int addOn = 0;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				addOn += cost[nxt][mask];
			}
			int res = oo;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				int ret = addOn+dp[mask | (1<<nxt)];
				res = min(res, ret);
			}
			dp[mask] = res;
		}

		System.out.println(dp[0]>>1);

		out.close();
	}

	int oo = (int)1e9;
	int min(int a, int b) {
		if(a < b) return a;
		return b;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n, m;
	char[] str;
	int[][] occs, cost;
	int[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		n = fs.nextInt(); m = fs.nextInt();
		byte[] str = fs.next().getBytes();
		int[] occs = new int[1<<m];
		for(int i = 0; i < n-1; i++) {
			int l1 = str[i] - 'a';
			int l2 = str[i+1] - 'a';
			occs[(1<<l1) | (1<<l2)]++;
			occs[(1<<l2) | (1<<l1)]++;
		}
		//cost[mask][v] = numPairs with v for some all bits on in mask
		int all = (1<<m)-1;
		cost = new int[m][1<<m];
		for(int i = 0; i < m; i++) {
			for(int mask = 1; mask < all; mask++) {
				if(((1<<i)&mask) > 0) continue;
				int lb = mask & (-mask);
				int trail = Integer.numberOfTrailingZeros(lb);
				int nmask = mask ^ lb;
				cost[i][mask] = cost[i][nmask]+occs[1<<i | 1<<trail];
			}
		}

		dp = new int[1<<m];
		for(int mask = dp.length-2; mask >= 0; mask--) {
			int addOn = 0;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				addOn += cost[nxt][mask];
			}
			int res = oo;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				int ret = addOn+dp[mask | (1<<nxt)];
				res = min(res, ret);
			}
			dp[mask] = res;
		}

		System.out.println(dp[0]>>1);

		out.close();
	}

	int oo = (int)1e9;
	int min(int a, int b) {
		if(a < b) return a;
		return b;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n, m;
	char[] str;
	int[][] occs, cost;
	int[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		n = fs.nextInt(); m = fs.nextInt();
		str = fs.next().toCharArray();
		occs = new int[m][m];
		for(int i = 0; i < n-1; i++) {
			occs[str[i]-'a'][str[i+1]-'a']++;
			occs[str[i+1]-'a'][str[i]-'a']++;
		}
		//cost[mask][v] = numPairs with v for some all bits on in mask
		int all = (1<<m)-1;
		cost = new int[m][1<<m];
		for(int i = 0; i < m; i++) {
			for(int mask = 1; mask < all; mask++) {
				if(((1<<i)&mask) > 0) continue;
				int lb = mask & (-mask);
				int trail = Integer.numberOfTrailingZeros(lb);
				int nmask = mask ^ lb;
				cost[i][mask] = cost[i][nmask]+occs[i][trail];
			}
		}

		dp = new int[1<<m];
		for(int mask = dp.length-2; mask >= 0; mask--) {
			int addOn = 0;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				addOn += cost[nxt][mask];
			}
			int res = oo;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				int ret = addOn+dp[mask | (1<<nxt)];
				res = min(res, ret);
			}
			dp[mask] = res;
		}

		System.out.println(dp[0]);

		out.close();
	}

	int oo = (int)1e9;
	int min(int a, int b) {
		if(a < b) return a;
		return b;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n, m;
	char[] str;
	int[][] occs, cost;
	int[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		//where's my 420???? :(
		long tot = 0;
		for(int i = 0; i < 20000; i++) tot += i;
		System.err.println(tot);

		n = fs.nextInt(); m = fs.nextInt();
		byte[] str = fs.next().getBytes();
		int[] occs = new int[1<<m];
		for(int i = 0; i < n-1; i++) {
			int l1 = str[i] - 'a';
			int l2 = str[i+1] - 'a';
			occs[(1<<l1) | (1<<l2)]++;
			occs[(1<<l2) | (1<<l1)]++;
		}
		//cost[mask][v] = numPairs with v for some all bits on in mask
		int all = (1<<m)-1;
		cost = new int[m][1<<m];
		for(int i = 0; i < m; i++) {
			for(int mask = 1; mask < all; mask++) {
				if(((1<<i)&mask) > 0) continue;
				int lb = mask & (-mask);
				int trail = Integer.numberOfTrailingZeros(lb);
				int nmask = mask ^ lb;
				cost[i][mask] = cost[i][nmask]+occs[1<<i | 1<<trail];
			}
		}

		dp = new int[1<<m];
		for(int mask = dp.length-2; mask >= 0; mask--) {
			int addOn = 0;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				addOn += cost[nxt][mask];
			}
			int res = oo;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				int ret = addOn+dp[mask | (1<<nxt)];
				res = min(res, ret);
			}
			dp[mask] = res;
		}

		System.out.println(dp[0]>>1);

		out.close();
	}

	int oo = (int)1e9;
	int min(int a, int b) {
		if(a < b) return a;
		return b;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n, m;
	char[] str;
	int[][] occs, cost;
	int[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("");

		//where's my 420???? :(

		n = fs.nextInt(); m = fs.nextInt();
		byte[] str = fs.next().getBytes();
		int[] occs = new int[1<<m];
		for(int i = 0; i < n-1; i++) {
			int l1 = str[i] - 'a';
			int l2 = str[i+1] - 'a';
			occs[(1<<l1) | (1<<l2)]++;
			occs[(1<<l2) | (1<<l1)]++;
		}
		//cost[mask][v] = numPairs with v for some all bits on in mask
		int all = (1<<m)-1;
		cost = new int[m][1<<m];
		for(int i = 0; i < m; i++) {
			for(int mask = 1; mask < all; mask++) {
				if(((1<<i)&mask) > 0) continue;
				int lb = mask & (-mask);
				int trail = Integer.numberOfTrailingZeros(lb);
				int nmask = mask ^ lb;
				cost[i][mask] = cost[i][nmask]+occs[1<<i | 1<<trail];
			}
		}

		dp = new int[1<<m];
		for(int mask = dp.length-2; mask >= 0; mask--) {
			int addOn = 0;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				addOn += cost[nxt][mask];
			}
			int res = oo;
			for(int nxt = 0; nxt < m; nxt++) {
				if(((1<<nxt)&mask) > 0) continue;
				int ret = addOn+dp[mask | (1<<nxt)];
				res = min(res, ret);
			}
			dp[mask] = res;
		}

		System.out.println(dp[0]>>1);

		out.close();
	}

	int oo = (int)1e9;
	int min(int a, int b) {
		if(a < b) return a;
		return b;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) {
			try {
				in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
			}
			catch (Exception e) {
				in = new BufferedInputStream(System.in, BS);
			}
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}