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