#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
#define EB emplace_back
#define ALL(a) begin(a), end(a)
#define RALL(a) rbegin(a), rend(a)
#define REP(i, a) for (int i(0); i < (a); ++i)
#define FOR(i, a, b) for (int i(a); i <= (b); ++i)

#ifdef LOCAL
#include <mydebug.h>
#else
#define debug(...)
#endif

using namespace std;
using ll = long long;

template <typename T> bool minimize(T &a, const T &b) {
  return (a < b ? 0 : a = b, 1);
}

void solve() {
  int n, k;
  cin >> n >> k;
  string s;
  cin >> s;

  const int m = (1 << k);

  auto ok = [&](int len) {
    vector<vector<int>> good(k, vector<int>(n + 2, n + 1));

    for (int c = 0; c < k; ++c) {
      for (int i = n - 1, cnt = 0; i >= 0; --i) {
        if (s[i] == 'a' + c || s[i] == '?') {
          ++cnt;
        } else {
          cnt = 0;
        }
        good[c][i] = (cnt >= len ? i + len : good[c][i + 1]);
      }
    }

    vector<int> dp(m, n + 1);
    dp[0] = 0;
    for (int mask = 0; mask < m; ++mask) {
      if (dp[mask] > n) {
        continue;
      }
      for (int i = 0; i < k; ++i) {
        if ((mask >> i & 1) == 0) {
          minimize(dp[mask | (1 << i)], good[i][dp[mask]]);
        }
      }
    }
    return dp[m - 1] <= n;
  };

  int low = 0, high = n / k;
  int ans = 0;
  while (low <= high) {
    int mid = (low + high) / 2;
    if (ok(mid)) {
      ans = mid;
      low = mid + 1;
    } else {
      high = mid - 1;
    }
  }
  cout << ans << "\n";
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int T = 1;
  // cin >> T;
  while (T--) {
    solve();
  }
}
