#include <bits/stdc++.h>

using namespace std;

int n, k, longest_streak[200001][17], dp[(1<<17)], pos[200001][17];
// dp[i] represents the earliest position at which we can COMPLETE the subset corresponding to i
// pos[i][j] represents the earliest position we can conclude a block of letter j, starting at i
string s;

bool ok(int num) {
    for(int i = 0; i < k; i++) {
        pos[n][i] = n;
    }
    for(int i = n - 1; i >= 0; i--) {
        for(int j = 0; j < k; j++) {
            if(longest_streak[i][j] >= num) {
                pos[i][j] = i + num - 1;
            } else {
                pos[i][j] = pos[i+1][j];
            }
        }
    }
    dp[0] = -1;
    for(int i = 1; i < (1 << k); i++) {
        dp[i] = n;
        for(int j = 0; j < k; j++) {
            if(i & (1 << j)) {
                if(dp[i ^ (1 << j)] == n) {
                    continue;
                }
                dp[i] = min(dp[i], pos[dp[i ^ (1 << j)]+1][j]);
            }
        }
    }
    return dp[(1 << k) - 1] < n;
}

int main() {
    cin >> n >> k >> s;
    for(int i = n - 1; i >= 0; i--) {
        for(int j = 0; j < k; j++) {
            if(s[i] == '?' || s[i] == char('a' + j)) {
                longest_streak[i][j] = longest_streak[i+1][j] + 1;
            }
        }
    }
    int lb = 0, ub = n;
    while(lb < ub) {
        int mid = (lb + ub + 1) / 2;
        if(ok(mid)) {
            lb = mid;
        } else {
            ub = mid - 1;
        }
    }
    cout << ub << endl;
}
