#include <bits/stdc++.h>   #pragma GCC optimize( O3 )   #pragma GCC target( sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native )   #pragma GCC optimize( unroll-loops )   #pragma comment(linker,  /stack:200000000 )   using namespace std;   const int GRANDOM =       std::chrono::high_resolution_clock::now().time_since_epoch().count();   namespace vn16 {   template <class T>   struct like_array : is_array<T> {};   template <class T, size_t N>   struct like_array<array<T, N>> : true_type {};   template <class T>   struct like_array<vector<T>> : true_type {};   template <class T>   bool is_like_array(const T& a) {     return like_array<T>::value;   }   template <class T>   void _R(T& x) {     std::cin >> x;   }   inline void _R(int& x) { scanf( %d , &x); }   inline void _R(int64_t& x) { scanf( %  SCNd64, &x); }   inline void _R(double& x) { scanf( %lf , &x); }   inline void _R(char& x) { scanf(  %c , &x); }   inline void _R(char* x) { scanf( %s , x); }   template <typename T>   inline void _R(vector<T>& v, size_t ie) {     for (int i = 0; i < ie; i++) _R(v[i]);   }   template <typename T>   inline void _R(vector<T>& v) {     _R(v, v.size());   }   inline void R() {}   template <class T, class... U>   inline void R(T& head, U&... tail) {     _R(head);     R(tail...);   }   template <class T>   void _W(const T& x) {     cout << x;   }   template <typename T>   inline void _W(vector<T>& v, size_t ie) {     for (int i = 0; i < ie; i++) {       if (i > 0) _W(   );       _W(v[i]);     }     _W(  n );   }   template <typename T>   inline void _W(vector<T>& v) {     _W(v, v.size());   }   template <class T>   inline void _W(const vector<T>& x) {     for (auto i = x.begin(); i != x.end(); _W(*i++))       if (i != x.cbegin()) putchar(   );   }   inline void W() {}   template <class T, class... U>   inline void W(const T& head, const U&... tail) {     _W(head);     if (sizeof...(tail)) putchar(   ), W(tail...);   }   template <class T, class... U>   inline void WL(const T& head, const U&... tail) {     _W(head);     putchar(sizeof...(tail) ?     :   n );     W(tail...);   }   template <class T>   void _RE(T& x) {     cin >> x;   }   template <class Arg, class... Args>   void _RE(Arg& first, Args&... rest);   void _RE(double& x) {     string t;     _RE(t);     x = stod(t);   }   void _RE(long double& x) {     string t;     _RE(t);     x = stold(t);   }   template <class T>   void _RE(complex<T>& x);   template <class T1, class T2>   void _RE(pair<T1, T2>& p);   template <class T>   void _RE(vector<T>& a);   template <class T, size_t SZ>   void _RE(array<T, SZ>& a);   template <class Arg, class... Args>   void _RE(Arg& first, Args&... rest) {     _RE(first);     _RE(rest...);   }   template <class T>   void _RE(complex<T>& x) {     T a, b;     _RE(a, b);     x = cd(a, b);   }   template <class T1, class T2>   void _RE(pair<T1, T2>& p) {     _RE(p.f, p.s);   }   template <class T>   void _RE(vector<T>& a) {     for (int i = 0, ie = sz(a); i < ie; i++) _RE(a[i]);   }   template <class T, size_t SZ>   void _RE(array<T, SZ>& a) {     for (int i = 0; i < SZ; i++) _RE(a[i]);   }   };  // namespace vn16   namespace vn16 {   template <typename T>   T gcd(T m, T n) {     while (n) {       T t = m % n;       m = n;       n = t;     };     return m;   }   template <typename T>   T exgcd(T a, T b, T& sa, T& ta) {     T q, r, sb = 0, tb = 1, sc, tc;     sa = 1, ta = 0;     if (b) do         q = a / b, r = a - q * b, a = b, b = r, sc = sa - q * sb, sa = sb,         sb = sc, tc = ta - q * tb, ta = tb, tb = tc;       while (b);     return a;   }   template <typename T>   T mul_inv(T a, T b) {     T t1 = a, t2 = b, t3;     T v1 = 1, v2 = 0, v3;     T x;     while (t2 != 1)       x = t1 / t2, t3 = t1 - x * t2, v3 = v1 - x * v2, t1 = t2, t2 = t3, v1 = v2,       v2 = v3;     return (v2 + b) % b;   }   template <typename T>   T powmod(T a, T b, T MOD) {     if (b < 0) return 0;     T rv = 1;     while (b) (b % 2) && (rv = (rv * a) % MOD), a = a * a % MOD, b /= 2;     return rv;   }   template <typename T>   inline T isqrt(T k) {     T r = sqrt((double)k) + 1;     while (r * r > k) r--;     while ((r + 1) * (r + 1) <= k) r++;     return r;   }   template <typename T>   inline T icbrt(T k) {     T r = cbrt((double)k) + 1;     while (r * r * r > k) r--;     return r;   }   template <typename T>   bool mul_overflow(T& r, T a, T b) {     return __builtin_mul_overflow(a, b, &r);   }   template <long long n>   struct BitSize {     enum { Size = BitSize<n / 2>::Size + 1 };   };   template <>   struct BitSize<0> {     enum { Size = 1 };   };   template <>   struct BitSize<1> {     enum { Size = 1 };   };   template <typename TH>   void _dbg(const char* sdbg, TH h) {     cerr << sdbg <<  =  << h <<   n ;   }   template <typename TH, typename... TA>   void _dbg(const char* sdbg, TH h, TA... t) {     while (*sdbg !=  , ) cerr << *sdbg++;     cerr <<  =  << h <<  , ;     _dbg(sdbg + 1, t...);   }   }  // namespace vn16   namespace vn16 {   template <typename T>   int min_rotation(vector<T> s) {     int a = 0, N = s.size();     for (int b = 0; b < N; b++)       for (int i = 0; i < N; i++) {         if (a + i == b || s[(a + i) % N] < s[(b + i) % N]) {           b += max(0, i - 1);           break;         }         if (s[(a + i) % N] > s[(b + i) % N]) {           a = b;           break;         }       }     return a;   };   template <typename T>   class StackGuard {    private:     T x;       public:     StackGuard(T x) : x(x) {}     ~StackGuard() { x(); }   };   }  // namespace vn16   namespace vn16 {};   namespace vn16 {   const int maxn = 1e5 + 7;   const int maxm = 23;   int n, m;   char s[maxn];   int cnt2[maxm][maxm];   int cnt[maxm];   long long dp[1 << maxm];   int main() {     srand(GRANDOM);     cin >> n >> m >> s;     memset(cnt, 0, sizeof(cnt));     for (int i = 1; i < n; i++) {       int x = s[i] -  a ;       int y = s[i - 1] -  a ;       cnt2[x][y]++;       cnt2[y][x]++;     }     int maxs = (1 << m);     dp[0] = 0;     for (int x = 1; x < maxs; x++) {       dp[x] = (long long)maxn * maxm * 10;       long long c = 0;       for (int i = 0; i < m; i++) {         for (int j = i + 1; j < m; j++) {           if (((x >> i) ^ (x >> j)) & 1) c += cnt2[i][j];         }       }       for (int i = 0; i < m; i++)         if ((x >> i) & 1) dp[x] = min(dp[x], dp[x ^ (1 << i)] + c);     }     cout << dp[maxs - 1] << endl;     return 0;   }   };  // namespace vn16   int main(int argc, char* argv[]) {     std::cin.sync_with_stdio(false);     std::cin.tie(nullptr);     return vn16::main();   }