Problem:
Prayers of Iwashiro
In the ancient nation of Iwashiro, priests offer prayers to appease disasters when they occur.
The priest selects a string $S$ from an ancient text and proceeds with the ritual by repeating the following
Pick one place in the string $S$ and update $S$ by replacing a letter written there with another letter.
Find out what kind of string repetition $S$ can be represented by, and chant the string you find. However, if $S$ cannot be represented by a repetition of the string, chant $S$.
The efficacy of the prayer is maximized when you chant the shortest string repetition that represents the original string. For example, for the string
abababab
, the efficacy of the prayer is maximized when you chant
ab
instead of the string itself or
ababab
.
As a new priest, you need to learn how to quickly find the string that maximizes the efficacy of the prayer from the given string $S$.
You will be given the string $S$ and some information about replacing the letters. Write a program that finds the length of the string that maximizes the efficacy of the prayer for the obtained string each time a letter is replaced.
Input
The input is given in the following form.
$N$ $Q$
$S$
$p_1$ $c_1$
$p_2$ $c_2$
:
$p_Q$ $c_Q$
In the first line, the length of the string $N$ ($2 \leq N \leq 10^5$) and the number of times the characters are replaced $Q$ ($1 \leq Q \leq 10^5$) are given. In the second line, a string $S$ of length $N$ consisting of lowercase letters is given. The following $Q$ line gives the position of the $i$-th character to be replaced, $p_i$ ($1 \leq p_i \leq N$), and the character to be replaced, $c_i$. Note that $p_i$ is expressed as the number of characters counting from the left end of the string. $c_i$ is in lowercase.
Output
Each time a letter is replaced, output the length of the string that maximizes the effectiveness of the prayer for the resulting string in a line.
Sample Input and Output
Sample Input
6 5
ababac
6 b
3 c
4 a
5 b
6 c
Sample Output
2
6
6
6
3

Submitted solutions:

code_snippet: #include<bits/stdc++.h>

using namespace std;

#define rep(i, l, n) for(int i = int(l); i < int(n); i++)
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

template<class T> bool chmin(T &a, T b) {if(a > b) {a = b; return true;} return false;}
template<class T> bool chmax(T &a, T b) {if(a < b) {a = b; return true;} return false;}
template<class T> using spq = priority_queue<T, vector<T>, greater<T>>;

// bool -> Yes/No
string answer(bool b) {return b ? "Yes" : "No";}

void fix(int k) {cout << fixed << setprecision(k);}

const int inf = 2e9;
const long long INF = 2e18;
const long double eps = 1e-12;
int dx[] = {0, -1, 0, 1, -1, -1, 1, 1}, dy[] = {1, 0, -1, 0, 1, -1, -1, 1};

void main_program() {
    int n, q; cin >> n >> q;
    string s; cin >> s;
    vector<int> div;
    for(int i = 1; i * i <= n; i++) {
        if(n % i) continue;
        div.emplace_back(i);
        if(i * i != n) div.emplace_back(n / i);
    }
    sort(all(div));
    int m = div.size();
    int diff_sum[m];
    rep(i, 0, m) {
        diff_sum[i] = 0;
        rep(j, 0, n) {
            if(s[j] != s[(j + div[i]) % n]) {
                diff_sum[i]++;
            }
        }
    }
    while(q--) {
        int x; cin >> x;
        x--;
        char c; cin >> c;
        int ans = -1;
        rep(i, 0, m) {
            int bef1 = 0, bef2 = 0;
            if(s[x] != s[(x + div[i]) % n]) bef1++;
            if(s[x] != s[(x + n - div[i]) % n]) bef2++;
            swap(s[x], c);
            int aft1 = 0, aft2 = 0;
            if(s[x] != s[(x + div[i]) % n]) aft1++;
            if(s[x] != s[(x + n - div[i]) % n]) aft2++;
            swap(s[x], c);
            diff_sum[i] += aft1 + aft2 - bef1 - bef2;
            if(diff_sum[i] == 0 && ans == -1) ans = div[i];
        }
        s[x] = c;
        assert(ans != -1);
        cout << ans << "\n";
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T = 1;
    //cin >> T;
    while(T--) {
        main_program();
    }
}
accuracy: 1
time_ms: 140
memory_kb: 3576
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

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

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N, Q;
    cin >> N >> Q;
    string S;
    cin >> S;

    // 約数を列挙
    vector<int> D;
    for (int i = 1; i * i <= N; i++) {
        if (N % i == 0) {
            D.emplace_back(i);
            if (N / i != i && N / i < N) D.emplace_back(N / i);
        }
    }
    sort(D.begin(), D.end());
    int M = ssize(D);
    // 文字列 S が長さ d で繰り返す
    // 各 i(0 <= i < d) (mod d) 文字目に存在する c の個数が N / d 個存在
    // cnt[i][j][c] := j mod D[i] 文字目に存在する c の個数
    // same[i] := cnt[i][j][c] = N / D[i] となる個数
    vector<vector<vector<int>>> cnt(M);
    vector<int> same(M);
    for (int i = 0; i < M; i++) {
        cnt[i].resize(D[i]);
        for (int j = 0; j < D[i]; j++) {
            cnt[i][j].resize(26);
            for (int cur = j; cur < N; cur += D[i]) cnt[i][j][S[cur] - 'a']++;
            if (cnt[i][j][S[j] - 'a'] == N / D[i]) same[i]++;
        }
    }

    while (Q--) {
        int p;
        char c;
        cin >> p >> c, p--;
        for (int i = 0; i < M; i++) {
            if (cnt[i][p % D[i]][S[p] - 'a']-- == N / D[i]) same[i]--;
            if (++cnt[i][p % D[i]][c - 'a'] == N / D[i]) same[i]++;
        }
        S[p] = c;
        int ans = N;
        for (int i = 0; i < M; i++) {
            if (same[i] == D[i]) {
                ans = D[i];
                break;
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 100
memory_kb: 38400
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main(void){
    int N, Q; cin >> N >> Q;
    string S; cin >> S;

    vector<int> p_mn, p_mx;
    for(int i = 1; i * i <= N; i++){
        if(N % i == 0){
            p_mn.push_back(i);
            if(i * i != N){
                p_mx.push_back(N / i);
            }
        }
    }
    
    int m_mn = p_mn.size();
    int m_mx = p_mx.size();
    
    vector<unordered_map<string, int>> mps(m_mn);
    
    vector<vector<int>> same_cnt(m_mx);
    vector<int> same_cnt_sum(m_mx);
    
    for(int idx = 0; idx < m_mn; idx++){
        int p = p_mn[idx];
        for(int i = 0; i < N; i += p){
            string s;
            
            for(int j = i; j < i + p; j++) s += S[j];
            
            mps[idx][s]++;
        }
    }
    
    for(int idx = 0; idx < m_mx; idx++){
        int p = p_mx[idx];
        
        same_cnt[idx].assign(p, false);
        
        for(int i = 0; i < p; i++){
            char c = S[i];
            int cnt = 0;
            for(int j = i; j < N; j += p){
                if(c != S[j]) cnt++;
            }
            
            same_cnt[idx][i] = cnt;
            same_cnt_sum[idx] += cnt;
        }
    }
    
    for(;Q--;){
        int p; char c; cin >> p >> c;p--;
        
        int ans = 1e9;
        
        //mnの更新
        for(int idx = 0; idx < m_mn; idx++){
            int pp = p_mn[idx];
            
            string s;
            for(int i = (p / pp) * pp; i < (p / pp) * pp + pp; i++){
                s += S[i];
            }
            
            
            mps[idx][s]--;
            if(mps[idx][s] == 0){
                mps[idx].erase(s);
            }
            
            
            
            s[p % pp] = c;
            
            mps[idx][s]++;
            
            if(mps[idx].size() == 1){
                ans = min(ans, pp);
            }
        }
        
        S[p] = c;
        
        //mxの更新
        for(int idx = 0; idx < m_mx; idx++){
            int pp = p_mx[idx];
            
            int i = p % pp;
            int cnt = 0;
            char c = S[i];
            for(int j = i; j < N; j += pp){
                if(c != S[j]) cnt++;    
            }
            
            same_cnt_sum[idx] -= same_cnt[idx][i];
            same_cnt[idx][i] = cnt;
            same_cnt_sum[idx] += cnt;
            
            if(same_cnt_sum[idx] == 0){
                ans = min(ans, pp);
            }
            
        }
        
        
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 2100
memory_kb: 13056
final_rank: 14

code_snippet: // AOJ #414
// Prayer for Iwashiro 2025.2.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

char temp[100005];
string Cins() { // 文字列の入力　スペース以下の文字で入力終了
    char *s = temp;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
    string input(temp); // 文字配列からstringを作成
    return input;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

int main() {
    int N = Cin(), Q = Cin();
    string str = Cins();
    
    string s = str + str;
    int same_l = 0;
    vector<int> p;
    for (int i = 1; i <= N / 2; i++){
        if (N % i == 0) p.push_back(i);
    }
    
    // Q 個のクエリを処理
    for (int i = 0; i < Q; i++){
        int pi = Cin();
        char c = gc(); gc();

        int pos = pi - 1;
        if(i >= 1 && s[pos] == c) {
            Cout(same_l);
            continue;
        } else {
            s[pos] = c;
            s[N + pos] = c;
        }
        
        int iwa = 0;
        bool found = false;
        for (size_t l = 0; l < p.size(); l++){
            iwa = 0;
            for (int m = 0; m < N / 2; m++){
                if ( s[m] != s[m + p[l]] || s[N - m - 1] != s[N - m + p[l] - 1] ) {
                    iwa = 1;
                    break;
                }
            }
            if(iwa == 0){
                Cout(p[l]);
                same_l = p[l];
                found = true;
                break;
            }
        }
        if(!found){
            same_l = N;
            Cout(N);
        }
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3724
final_rank: 1

code_snippet: // AOJ #414
// Prayer for Iwashiro 2025.2.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 
const ll MOD1 = 1000000007LL;
const ll MOD2 = 1000000009LL;
const ll BASE = 137;
 
// --- Fenwick Tree (Binary Indexed Tree) ---
struct Fenw {
    int n;
    vector<ll> fenw;
    ll mod;
    Fenw(int n, ll mod) : n(n), mod(mod) {
        fenw.assign(n+1, 0);
    }
    void update(int i, ll delta) {
        i++;
        while(i <= n) {
            fenw[i] = (fenw[i] + delta) % mod;
            if(fenw[i] < 0) fenw[i] += mod;
            i += i & -i;
        }
    }
    ll query(int i) {
        ll res = 0;
        i++;
        while(i > 0) {
            res = (res + fenw[i]) % mod;
            i -= i & -i;
        }
        return (res % mod + mod) % mod;
    }
    ll rangeQuery(int l, int r) {
        if(l > r) return 0;
        ll res = query(r) - (l==0 ? 0 : query(l-1));
        res %= mod;
        if(res < 0) res += mod;
        return res;
    }
};
 
// --- Candidate structure ---
struct Candidate {
    int d;
    ll series1;
    ll series2;
};
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int N, Q;
    cin >> N >> Q;
    string S;
    cin >> S;
 
    // --- Precompute power arrays for BASE^i mod MOD1 and MOD2 ---
    vector<ll> pow1(N+1), pow2(N+1);
    pow1[0] = 1; pow2[0] = 1;
    for (int i = 1; i <= N; i++){
        pow1[i] = (pow1[i-1] * BASE) % MOD1;
        pow2[i] = (pow2[i-1] * BASE) % MOD2;
    }
 
    Fenw fenw1(N, MOD1), fenw2(N, MOD2);
    vector<int> arr(N);
    for (int i = 0; i < N; i++){
        int val = S[i] - 'a' + 1;
        arr[i] = val;
        ll addVal1 = ( (ll) val * pow1[i] ) % MOD1;
        ll addVal2 = ( (ll) val * pow2[i] ) % MOD2;
        fenw1.update(i, addVal1);
        fenw2.update(i, addVal2);
    }
 
    vector<Candidate> candidates;
    for (int i = 1; i*i <= N; i++){
        if(N % i == 0){
            if(i < N){
                Candidate cand;
                cand.d = i;
                int rep = N / i;
                ll sum1 = 0, sum2 = 0;
                for (int j = 0; j < rep; j++){
                    int pos = j * i;
                    sum1 = (sum1 + pow1[pos]) % MOD1;
                    sum2 = (sum2 + pow2[pos]) % MOD2;
                }
                cand.series1 = sum1;
                cand.series2 = sum2;
                candidates.push_back(cand);
            }
            int d2 = N / i;
            if(d2 != i && d2 < N){
                Candidate cand;
                cand.d = d2;
                int rep = N / d2;
                ll sum1 = 0, sum2 = 0;
                for (int j = 0; j < rep; j++){
                    int pos = j * d2;
                    sum1 = (sum1 + pow1[pos]) % MOD1;
                    sum2 = (sum2 + pow2[pos]) % MOD2;
                }
                cand.series1 = sum1;
                cand.series2 = sum2;
                candidates.push_back(cand);
            }
        }
    }
    sort(candidates.begin(), candidates.end(), [](const Candidate &a, const Candidate &b){
        return a.d < b.d;
    });
 
    while(Q--){
        int pos;
        char c;
        cin >> pos >> c;
        pos--;
        int newVal = c - 'a' + 1;
        int oldVal = arr[pos];
        if(newVal != oldVal) {
            ll diff1 = ((ll)newVal - oldVal) * pow1[pos] % MOD1;
            ll diff2 = ((ll)newVal - oldVal) * pow2[pos] % MOD2;
            if(diff1 < 0) diff1 += MOD1;
            if(diff2 < 0) diff2 += MOD2;
            fenw1.update(pos, diff1);
            fenw2.update(pos, diff2);
            arr[pos] = newVal;
        }
 
        ll fullHash1 = fenw1.rangeQuery(0, N-1);
        ll fullHash2 = fenw2.rangeQuery(0, N-1);
 
        int ans = N;
        for(auto &cand : candidates){
            int d = cand.d;
            ll prefHash1 = fenw1.rangeQuery(0, d-1);
            ll prefHash2 = fenw2.rangeQuery(0, d-1);
 
            ll expected1 = (prefHash1 * cand.series1) % MOD1;
            ll expected2 = (prefHash2 * cand.series2) % MOD2;
 
            if(expected1 == fullHash1 && expected2 == fullHash2) {
                ans = d;
                break;
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1200
memory_kb: 6788
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

using i64 = long long;
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repi(i, a, b) for (int i = a - 1; i >= b; i--)

struct Roliha {
    constexpr static int b = 5;
    constexpr static int modp[5] = {998244353, 1000000007, 1000000009, 1000000021, 1000000033};
    using T = array<i64, b>;
    T table;

    static int base[b];
    static array<vector<i64>, b> pw;

    static void setbase() {
        mt19937_64 rng(time(0));
        rep (i, 0, b) {
            base[i] = rng() % modp[i]; 
            pw[i] = {1, base[i]};
        }
    }

    static void extend_pw(int upper) {
        while (pw[0].size() < upper) {
            rep (i, 0, b) pw[i].push_back(pw[i].back() * base[i] % modp[i]);
        }
    }

    Roliha() = default;
    Roliha(const string& s) {
        int n = s.size();
        extend_pw(n);
        rep (i, 0, b) {
            table[i] = 0;
            rep (j, 0, n) {
                table[i] += s[j] * pw[i][j] % modp[i];
                table[i] %= modp[i];
            }
        }
    }
};
int Roliha::base[5] = {3, 3, 3, 3, 3};
array<vector<i64>, 5> Roliha::pw;

int main() {
    Roliha::setbase();
    int n, q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<int> divisors;
    rep (i, 1, n + 1) if (n % i == 0) divisors.emplace_back(i);
    int dcnt = divisors.size();
    vector<vector<Roliha>> dist(dcnt - 1);
    vector<map<array<i64, 5>, int>> mp(dcnt - 1);
    rep (i, 0, dcnt - 1) {
        dist[i].resize(n / divisors[i]);
        rep (j, 0, n / divisors[i]) {
            dist[i][j] = Roliha(s.substr(divisors[i] * j, divisors[i]));
            mp[i][dist[i][j].table]++;
        }
    }

    rep (_, 0, q) {
        int p;
        char c;
        cin >> p >> c;
        --p;
        int res = n;
        repi (i, dcnt - 1, 0) {
            array<i64, 5> &now = dist[i][p / divisors[i]].table;
            mp[i][now]--;
            if (mp[i][now] == 0) mp[i].erase(now);
            rep (k, 0, 5) {
                now[k] += (int(c) - int(s[p]) + Roliha::modp[k]) * Roliha::pw[k][p % divisors[i]];
                now[k] %= Roliha::modp[k];
            }
            mp[i][now]++;
            if (mp[i].size() == 1) res = divisors[i];
        }
        s[p] = c;
        cout << res << '\n';
    }

    return 0;
}
accuracy: 1
time_ms: 2780
memory_kb: 24144
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

using i64 = long long;
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repi(i, a, b) for (int i = a - 1; i >= b; i--)

struct Roliha {
    constexpr static int b = 5;
    constexpr static int modp[5] = {998244353, 1000000007, 1000000009, 1000000021, 1000000033};
    using T = array<i64, b>;
    T table;

    i64& operator[](int i) {
        return table[i];
    }

    static int base[b];
    static array<vector<i64>, b> pw;

    static void setbase() {
        mt19937_64 rng(time(0));
        rep (i, 0, b) {
            base[i] = rng() % modp[i]; 
            pw[i] = {1, base[i]};
        }
    }

    static void extend_pw(int upper) {
        while (pw[0].size() < upper) {
            rep (i, 0, b) pw[i].push_back(pw[i].back() * base[i] % modp[i]);
        }
    }

    Roliha() = default;
    Roliha(const string& s) {
        int n = s.size();
        extend_pw(n);
        rep (i, 0, b) {
            table[i] = 0;
            rep (j, 0, n) table[i] += s[j] * pw[i][j] % modp[i];
        }
    }
};
int Roliha::base[5] = {3, 3, 3, 3, 3};
array<vector<i64>, 5> Roliha::pw;

int main() {
    Roliha::setbase();
    int n, q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<int> divisors;
    rep (i, 1, n + 1) if (n % i == 0) divisors.emplace_back(i);
    int dcnt = divisors.size();
    vector<vector<Roliha>> dist(dcnt - 1);
    vector<map<array<i64, 5>, int>> mp(dcnt - 1);
    rep (i, 0, dcnt - 1) {
        dist[i].resize(n / divisors[i]);
        rep (j, 0, n / divisors[i]) {
            dist[i][j] = Roliha(s.substr(divisors[i] * j, divisors[i]));
            mp[i][dist[i][j].table]++;
        }
    }

    rep (_, 0, q) {
        int p;
        char c;
        cin >> p >> c;
        --p;
        int res = n;
        rep (i, 0, dcnt - 1) {
            array<i64, 5> &now = dist[i][p / divisors[i]].table;
            mp[i][now]--;
            if (mp[i][now] == 0) mp[i].erase(now);
            rep (k, 0, 5) {
                now[k] += (int(c) - int(s[p]) + Roliha::modp[k]) * Roliha::pw[k][p % divisors[i]];
                now[k] %= Roliha::modp[k];
            }
            mp[i][now]++;
            if (mp[i].size() == 1) res = min(res, divisors[i]);
        }
        s[p] = c;
        cout << res << "\n";
    }

    return 0;
}
accuracy: 0.7272727272727273
time_ms: 1620
memory_kb: 24180
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);++i)
using namespace std;
using ll = long long;

vector<int> yakusu(int n){
    vector<int> res;
    for(int i = 1;i<=n;i++){
        if(n%i==0) res.push_back(i);
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n,q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<int> y = yakusu(n);
    int m = y.size();


    vector<vector<map<char,int>>> a(m);
    rep(i,m) a[i].resize(y[i]);

    vector<int> b(m,0);

    rep(j,n){
        rep(i,m){
            if(a[i][(j+1)%y[i]].size()==1){
                b[i]--;
            }

            a[i][(j+1)%y[i]][s[j]]++;

            if(a[i][(j+1)%y[i]].size()==1){
                b[i]++;
            }
        }
    }
    rep(qi,q){
        int p;
        char c;
        cin >> p >> c;
        
        rep(i,m){
            if(a[i][p%y[i]].size()==1){
                b[i]--;
            }

            a[i][p%y[i]][s[p-1]]--;   
            if(a[i][p%y[i]][s[p-1]]==0) a[i][p%y[i]].erase(s[p-1]);

            if(a[i][p%y[i]].size()==1){
                b[i]++;
            }
        }
        s[p-1] = c;
        rep(i,m){
            if(a[i][p%y[i]].size()==1){
                b[i]--;
            }
            a[i][p%y[i]][s[p-1]]++;
            
            if(a[i][p%y[i]].size()==1){
                b[i]++;
            }
        }
        rep(i,m){
            if(b[i]==y[i]){
                cout << y[i] << endl;
                break;
            }
        }
    }

}
accuracy: 1
time_ms: 1840
memory_kb: 64984
final_rank: 19

code_snippet: #include <bits/stdc++.h>

std::vector<std::array<int, 26>> cnt[150];
std::vector<int> pos[150];
int eval[150];

int main() {
    int N, Q;
    std::cin >> N >> Q;
    std::vector<int> D;
    for (int i{1} ; i < N ; i++) if (N % i == 0) {
        D.push_back(i);
    }
    for (int i{} ; i < (int)D.size() ; i++) {
        cnt[i] = std::vector<std::array<int, 26>>(D[i]);
        pos[i] = std::vector<int>(D[i]);
        for (int j{} ; j < D[i] ; j++) cnt[i][j].fill(0);
    }
    auto add{[&](int i, char c) -> void {
        for (int j{} ; j < (int)D.size() ; j++) {
            int idx{i % D[j]};
            if (cnt[j][idx][c - 'a'] == 0) {
                if (pos[j][idx] == 1) eval[j]--;
                pos[j][idx]++;
                if (pos[j][idx] == 1) eval[j]++;
            }
            cnt[j][idx][c - 'a']++;
        }
    }};
    auto remove{[&](int i, char c) -> void {
        for (int j{} ; j < (int)D.size() ; j++) {
            int idx{i % D[j]};
            cnt[j][idx][c - 'a']--;
            if (cnt[j][idx][c - 'a'] == 0) {
                if (pos[j][idx] == 1) eval[j]--;
                pos[j][idx]--;
                if (pos[j][idx] == 1) eval[j]++;
            }
        }
    }};
    std::string S;
    std::cin >> S;
    for (int i{} ; i < N ; i++) add(i, S[i]);
    while (Q--) {
        int p;
        char c;
        std::cin >> p >> c;
        p--;
        remove(p, S[p]);
        S[p] = c;
        add(p, S[p]);
        int ans{N};
        for (int i{} ; i < (int)D.size() ; i++) if (eval[i] == D[i]) {
            ans = D[i];
            break;
        }
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 240
memory_kb: 31040
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main()
{
	int n,q;
	cin >> n >> q;
	string s;
	cin >> s;
	vector<pair<int,vector<vector<int>>>> t;
	vector<int> p;
	auto f = [&](int x){
		vector<vector<int>> cou(x,vector<int>(26,0));
		p.push_back(0);
		for(int j = 0;j < n;j++){
			cou[j % x][s[j] - 'a']++;
		}
		for(int j = 0;j < x;j++){
			for(int k = 0;k < 26;k++){
				if(cou[j][k] == n / x){
					p.back()++;
				}
			}
		}
		t.push_back({x,cou});
	};
	f(1);
	for(int i = 2;i * i <= n;i++){
		if(n % i != 0) continue;
		f(i);
		f(n / i);
	}
	for(int i = 0;i < q;i++){
		int x;
		cin >> x;
		x--;
		char c;
		cin >> c;
		int ans = n;
		for(int j = 0;j < (int)t.size();j++){
			int l = t[j].first;
			int pos = x % l;
			if(t[j].second[pos][s[x] - 'a'] == n / l){
				p[j]--;
			}
			t[j].second[pos][s[x] - 'a']--;
			t[j].second[pos][c - 'a']++;
			if(t[j].second[pos][c - 'a'] == n / l){
				p[j]++;
			}
			if(p[j] == l){
				ans = min(ans,l);
			}
		}
		s[x] = c;
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 230
memory_kb: 38136
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using V = std::vector<T>;

#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, a, b) for (ll i = (a); i < (b); i++)

bool chmin(ll& x, const ll& y) { if (x > y) { return x = y, 1; } return 0; }
bool chmax(ll& x, const ll& y) { if (x < y) { return x = y, 1; } return 0; }

vector<ll> divisor_list(const ll& n) {
	V<ll> result{};
	for (ll i = 1; i * i <= n; i++) {
		if (n % i == 0) {
			result.emplace_back(i);
			if (i * i != n) result.emplace_back(n / i);
		}
	}
	sort(begin(result), end(result));
	return result;
}

int main()
{
	int n, q; cin >> n >> q;
	string s; cin >> s;
	V<ll> len_list = divisor_list(n);
	ll siz = len_list.size();
	V<V<V<ll>>> count(siz);
	REP(i, siz) {
		count[i] = V<V<ll>>(len_list[i], V<ll>(26, 0));
	}

	V<ll> save(siz, 0);
	REP(i, n) {
		REP(j, siz) {
			count[j][i % len_list[j]][s[i] - 'a']++;
			if (count[j][i % len_list[j]][s[i] - 'a'] == n / len_list[j]) {
				save[j]++;
			}
		}
	}

	REP(_, q) {
		int p; char c; cin >> p >> c; p--;
		REP(i, siz) {
			if (count[i][p % len_list[i]][s[p] - 'a'] == n / len_list[i]) {
				save[i]--;
			}
			count[i][p % len_list[i]][s[p] - 'a']--;
			count[i][p % len_list[i]][c - 'a']++;
			if (count[i][p % len_list[i]][c - 'a'] == n / len_list[i]) {
				save[i]++;
			}
		}
		s[p] = c;
		ll min_len{n};
		REP(i, siz) {
			if (save[i] == len_list[i]) {
				chmin(min_len, len_list[i]);
			}
		}
		cout << min_len << '\n';
	}
}
accuracy: 1
time_ms: 860
memory_kb: 87068
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

#ifdef LOCAL
#include <debug_print.hpp>
#define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (static_cast<void>(0))
#endif

// xの約数を列挙した配列を返す
vector<ll> make_is_divisors(ll N, bool sorted = true) {
    vector<ll> divisors;
    for (ll i = 1; i * i <= N; i++) {
        if (N % i == 0) {
            divisors.emplace_back(i);
            if (N / i != i) divisors.emplace_back(N / i);
        }
    }
    if (sorted) sort(divisors.begin(), divisors.end());
    return divisors;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N, Q;
    cin >> N >> Q;
    string S;
    cin >> S;

    // N の約数を列挙
    auto divs = make_is_divisors(N);
    int M = divs.size();
    // cnt[i][j][c] := N の約数 divs[i] の j mod divs[i] にある c の個数
    vector<vector<vector<int>>> cnt(M);
    for (int i = 0; i < M; i++) {
        cnt[i].resize(divs[i], vector<int>(26));
        for (int j = 0; j < N; j++) {
            cnt[i][j % divs[i]][S[j] - 'a']++;
        }
    }

    // cnt2[i] := N の約数 divs[i] について, N / divs[i] 個ある個数
    vector<int> cnt2(M);
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < divs[i]; j++) {
            bool ok = false;
            for (int c = 0; c < 26; c++) {
                if (cnt[i][j][c] == N / divs[i]) {
                    ok = true;
                    break;
                }
            }
            if (ok) cnt2[i]++;
        }
    }

    while (Q--) {
        int p;
        char c;
        cin >> p >> c, p--;
        for (int i = 0; i < M; i++) {
            // S[p] の個数が N / divs[i] であれば cnt2[i] も更新
            if (cnt[i][p % divs[i]][S[p] - 'a']-- == N / divs[i]) cnt2[i]--;
            // c の個数が N / divs[i] であれば cnt2[i] も更新
            if (++cnt[i][p % divs[i]][c - 'a'] == N / divs[i]) cnt2[i]++;
        }
        S[p] = c;
        // N の i 番目の約数 divs[i] について, cnt2[i] の個数が divs[i] であれば周期 divs[i] となる
        for (int i = 0; i < M; i++) {
            if (cnt2[i] == divs[i]) {
                cout << divs[i] << '\n';
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 410
memory_kb: 49172
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

#ifdef LOCAL
#include <debug_print.hpp>
#define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (static_cast<void>(0))
#endif

// xの約数を列挙した配列を返す
vector<ll> make_is_divisors(ll N, bool sorted = true) {
    vector<ll> divisors;
    for (ll i = 1; i * i <= N; i++) {
        if (N % i == 0) {
            divisors.emplace_back(i);
            if (N / i != i) divisors.emplace_back(N / i);
        }
    }
    if (sorted) sort(divisors.begin(), divisors.end());
    return divisors;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N, Q;
    cin >> N >> Q;
    string S;
    cin >> S;

    // N の約数を列挙
    auto divs = make_is_divisors(N);
    int M = divs.size();
    // cnt[i][j][c] := N の約数 divs[i] の j mod divs[i] にある c の個数
    vector<vector<vector<int>>> cnt(M);
    for (int i = 0; i < M; i++) {
        cnt[i].resize(divs[i], vector<int>(26));
        for (int j = 0; j < N; j++) {
            cnt[i][j % divs[i]][S[j] - 'a']++;
        }
    }

    // flag[i] := N の約数 divs[i] について, N / divs[i] 個ある個数
    vector<int> flag(M);
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < divs[i]; j++) {
            bool ok = false;
            for (int c = 0; c < 26; c++) {
                if (cnt[i][j][c] == N / divs[i]) {
                    ok = true;
                    break;
                }
            }
            if (ok) flag[i]++;
        }
    }

    while (Q--) {
        int p;
        char c;
        cin >> p >> c, p--;
        for (int i = 0; i < M; i++) {
            // S[p] の個数が N / divs[i] であれば flag[i] も更新
            if (cnt[i][p % divs[i]][S[p] - 'a'] == N / divs[i]) flag[i]--;
            cnt[i][p % divs[i]][S[p] - 'a']--;
            cnt[i][p % divs[i]][c - 'a']++;
            // c の個数が N / divs[i] であれば flag[i] も更新
            if (cnt[i][p % divs[i]][c - 'a'] == N / divs[i]) flag[i]++;
        }
        S[p] = c;
        // 各約数について, その約数の mod が同じものを全て見る
        for (int i = 0; i < M; i++) {
            if (flag[i] == divs[i]) {
                cout << divs[i] << '\n';
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 490
memory_kb: 49052
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define REP(i,n)for(int i=0;i<(n);++i)
#define REP1(i,n)for(int i=1;i<=(n);++i)
#define FORE(...)for(auto&&__VA_ARGS__)
#define ALL(x)begin(x),end(x)
#define mset(x,y)memset(x,y,sizeof x)
#define pb push_back
#define eb emplace_back
#define V vector
#define lb(x,y)(lower_bound(begin(x),end(x),y)-begin(x))
#define ub(x,y)(upper_bound(begin(x),end(x),y)-begin(x))
#define NP(x)next_permutation(begin(x),end(x))
#define SORT(x)sort(ALL(x))
#define UNIQ(v)v.erase(unique(begin(v),end(v)),end(v))
#define SORTUNIQ(v)SORT(v),UNIQUE(v)
#define readInt readInt_()
#define readString readString_()
using Int=long long;
using Real=long double;
using PII=pair<int,int>;
using PLL=pair<Int,Int>;
template<class T>using PQMIN=priority_queue<T,V<T>,greater<T>>;
template<class T>using PQMAX=priority_queue<T>;
constexpr int INFI=1001001001;
constexpr Int INFL=2002002002002002002LL;
template<class T,class S>inline bool chmin(T&A,S B){return A>B?A=B,1:0;}
template<class T,class S>inline bool chmax(T&A,S B){return A<B?A=B,1:0;}
Int readInt_(){Int x;cin>>x;return x;}
string readString_(){string s;cin>>s;return s;}
template<class T>V<T>readVector(int N){
	V<T>ret(N);
	REP(i,N)cin>>ret[i];
	return ret;
}
V<V<int>>readGraph(int N,int M,bool directed){
	V<V<int>>G(N);
	REP(i,M){
		int u,v;cin>>u>>v;
		G[--u].pb(--v);
		if(!directed)G[v].pb(u);
	}
	return G;
}
V<V<pair<int,Int>>>readWeightedGraph(int N,int M,bool directed){
	V<V<pair<int,Int>>>G(N);
	REP(i,M){
		int u,v;Int w;cin>>u>>v>>w;
		G[--u].eb(--v,w);
		if(!directed)G[v].eb(u,w);
	}
	return G;
}
template<class T>V<Int>dijkstra(V<V<T>>&G,int S,Int distS=0){
	V<Int>dist(size(G),INFL);
	dist[S]=distS;
	PQMIN<pair<Int,int>>Q;
	Q.push({distS,S});
	while(!empty(Q)){
		auto[c,u]=Q.top();Q.pop();
		if(dist[u]<c)continue;
		FORE([v,w]:G[u])if(chmin(dist[v],c+w)){
			Q.push({dist[v],v});
		}
	}
	return dist;
}
V<PII>dxdy(int x,int y){
	return{{x+1,y},{x-1,y},{x,y+1},{x,y-1}};
}
V<PII>dxdy(int x,int y,int H,int W){
	V<PII>ret;
	if(x+1<H)ret.eb(x+1,y);
	if(x)ret.eb(x-1,y);
	if(y+1<W)ret.eb(x,y+1);
	if(y)ret.eb(x,y-1);
	return ret;
}
V<PII>dxdy8(int x,int y){
	return{{x+1,y},{x-1,y},{x,y+1},{x,y-1},{x-1,y-1},{x-1,y+1},{x+1,y-1},{x+1,y+1}};
}
V<PII>dxdy8(int x,int y,int H,int W){
	V<PII>ret;
	if(x+1<H)ret.eb(x+1,y);
	if(x)ret.eb(x-1,y);
	if(y+1<W)ret.eb(x,y+1);
	if(y)ret.eb(x,y-1);
	if(x+1<H&&y+1<W)ret.eb(x+1,y+1);
	if(x+1<H&&y)ret.eb(x+1,y-1);
	if(x&&y+1<W)ret.eb(x-1,y+1);
	if(x&&y)ret.eb(x-1,y-1);
	return ret;
}
void fastIO(){ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);}

V<int>divisor(int N){
	V<int>ret;
	for(int i=1;i*i<=N;++i)if(N%i==0){
		ret.pb(i);
		if(i*i<N)ret.pb(N/i);
	}
	return ret;
}
signed main(){
	fastIO();
	int N,Q;cin>>N>>Q;
	string S;cin>>S;
	auto d=divisor(N);
	SORT(d);
	int M=d.size();
	V<V<map<char,int>>>mp(M);
	V<int>cnt(M);
	REP(i,M)mp[i].resize(d[i]);
	REP(i,N)REP(j,M)++mp[j][i%d[j]][S[i]];
	REP(i,M)REP(j,d[i])cnt[i]+=mp[i][j].size()>1;
	while(Q--){
		int p;
		char c;
		cin>>p>>c;
		--p;
		int ans;
		for(int i=M;i--;){
			if(!--mp[i][p%d[i]][S[p]]){
				mp[i][p%d[i]].erase(S[p]);
				if(mp[i][p%d[i]].size()==1)--cnt[i];
			}
			if(++mp[i][p%d[i]][c]==1){
				if(mp[i][p%d[i]].size()==2)++cnt[i];
			}
			if(cnt[i]==0){
				ans=d[i];
			}
		}
		S[p]=c;
		cout<<ans<<"\n";
	}
}
accuracy: 1
time_ms: 1490
memory_kb: 64992
final_rank: 17

code_snippet: //line 2 "/home/seekworser/.cpp_lib/competitive_library/competitive/std/std.hpp"
#include <bits/stdc++.h>
#ifndef LOCAL_TEST
#pragma GCC target ("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif // LOCAL_TEST
using namespace std;
using std::cout;
// shorten typenames
using ll = long long;
using pii = pair<int, int>; using pll = pair<ll, ll>;
using vi = vector<int>;  using vvi = vector<vi>; using vvvi = vector<vvi>;
using vl = vector<ll>;  using vvl = vector<vl>; using vvvl = vector<vvl>;
using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>;
using vc = vector<char>; using vvc = vector<vc>; using vvvc = vector<vvc>;
using vd = vector<double>; using vvd = vector<vd>; using vvvd = vector<vvd>;
using vs = vector<string>; using vvs = vector<vector<string>>; using vvvs = vector<vector<vector<string>>>;
template<typename T> vector<vector<T>> vv(int h, int w, T val = T()) { return vector(h, vector<T>(w, val)); }
template<typename T> vector<vector<vector<T>>> vvv(int h1, int h2, int h3, T val = T()) { return vector(h1, vector(h2, vector<T>(h3, val))); }
template<typename T> vector<vector<vector<vector<T>>>> vvvv(int h1, int h2, int h3, int h4, T val = T()) { return vector(h1, vector(h2, vector(h3, vector<T>(h4, val)))); }
template <class T> using priority_queue_min = priority_queue<T, vector<T>, greater<T>>;
// define CONSTANTS
constexpr double PI = 3.14159265358979323;
constexpr int INF = 100100111; constexpr ll INFL = 3300300300300300491LL;
float EPS = 1e-8; double EPSL = 1e-10;
template<typename T> bool eq(const T x, const T y) { return x == y; }
template<> bool eq<double>(const double x, const double y) { return (abs(x - y) < EPSL * x || abs(x - y) < EPSL); }
template<> bool eq<float>(const float x, const float y) { return abs(x - y) < EPS * x; }
template<typename T> bool neq(const T x, const T y) { return !(eq<T>(x, y)); }
template<typename T> bool ge(const T x, const T y) { return (eq<T>(x, y) || (x > y)); }
template<typename T> bool le(const T x, const T y) { return (eq<T>(x, y) || (x < y)); }
template<typename T> bool gt(const T x, const T y) { return !(le<T>(x, y)); }
template<typename T> bool lt(const T x, const T y) { return !(ge<T>(x, y)); }
constexpr int MODINT998244353 = 998244353;
constexpr int MODINT1000000007 = 1000000007;
// fasten io
struct Nyan { Nyan() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } nyan;
// define macros
#define all(a) (a).begin(), (a).end()
#define sz(x) ((ll)(x).size())
#define rep1(n) for(ll dummy_iter = 0LL; dummy_iter < n; ++dummy_iter) // 0,1,...,n-1
#define rep2(i, n) for(ll i = 0LL, i##_counter = 0LL; i##_counter < ll(n); ++(i##_counter), (i) = i##_counter) // i=0,1,...,n-1
#define rep3(i, s, t) for(ll i = ll(s), i##_counter = ll(s); i##_counter < ll(t); ++(i##_counter), (i) = (i##_counter)) // i=s,s+1,...,t-1
#define rep4(i, s, t, step) for(ll i##_counter = step > 0 ? ll(s) : -ll(s), i##_end = step > 0 ? ll(t) : -ll(t), i##_step = abs(step), i = ll(s); i##_counter < i##_end; i##_counter += i##_step, i = step > 0 ? i##_counter : -i##_counter) // i=s,s+step,...,<t
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define repe(a, v) for(auto& a : (v)) // iterate over all elements in v
#define smod(n, m) ((((n) % (m)) + (m)) % (m))
#define sdiv(n, m) (((n) - smod(n, m)) / (m))
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());}
int Yes(bool b=true) { cout << (b ? "Yes\n" : "No\n"); return 0; };
int YES(bool b=true) { cout << (b ? "YES\n" : "NO\n"); return 0; };
int No(bool b=true) {return Yes(!b);};
int NO(bool b=true) {return YES(!b);};
template<typename T, size_t N> T max(array<T, N>& a) { return *max_element(all(a)); };
template<typename T, size_t N> T min(array<T, N>& a) { return *min_element(all(a)); };
template<typename T> T max(vector<T>& a) { return *max_element(all(a)); };
template<typename T> T min(vector<T>& a) { return *min_element(all(a)); };
template<typename T> vector<T> vec_slice(const vector<T>& a, int l, int r) { vector<T> rev; rep(i, l, r) rev.push_back(a[i]); return rev; };
template<typename T> T sum(vector<T>& a, T zero = T(0)) { T rev = zero; rep(i, sz(a)) rev += a[i]; return rev; };
template<typename T> bool in_range(const T& val, const T& s, const T& t) { return s <= val && val < t; };

template <class T> inline vector<T>& operator--(vector<T>& v) { repe(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repe(x, v) ++x; return v; }

ll powm(ll a, ll n, ll mod=INFL) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = (res * a) % mod;
        if (n > 1) a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}
ll sqrtll(ll x) {
    assert(x >= 0);
    ll rev = sqrt(x);
    while(rev * rev > x) --rev;
    while((rev+1) * (rev+1)<=x) ++rev;
    return rev;
}
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; }
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; }
int digit(ll x, int d=10) { int rev=0; while (x > 0) { rev++; x /= d;}; return rev; }
/**
 * @brief std.hpp
 * @docs docs/std/std.md
 */
//line 3 "/home/seekworser/.cpp_lib/competitive_library/competitive/string/rolling_hash.hpp"
using hash_t = unsigned long long;
using hash_vector_t = vector<hash_t>;
constexpr hash_t RHMOD = (1UL << 61) - 1;
constexpr hash_t RHR = 37;

namespace internal {
    const hash_t MASK30 = (1UL << 30) - 1;
    const hash_t MASK31 = (1UL << 31) - 1;
    const hash_t MASK61 = RHMOD;

    //mod 2^61-1を計算する関数
    hash_t CalcMod(hash_t x) {
        hash_t xu = x >> 61;
        hash_t xd = x & MASK61;
        hash_t res = xu + xd;
        if (res >= RHMOD) res -= RHMOD;
        return res;
    }

    //a*b mod 2^61-1を返す関数(最後にModを取る)
    hash_t Mul(hash_t a, hash_t b) {
        hash_t au = a >> 31;
        hash_t ad = a & MASK31;
        hash_t bu = b >> 31;
        hash_t bd = b & MASK31;
        hash_t mid = ad * bu + au * bd;
        hash_t midu = mid >> 30;
        hash_t midd = mid & MASK30;
        return CalcMod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    hash_t Pow(hash_t a, hash_t n) {
        hash_t res = 1;
        while (n > 0) {
            if (n & 1) res = Mul(res, a);
            a = Mul(a, a);
            n >>= 1;
        }
        return res;
    }
}

struct RollingHash {
    private:
    static bool initialized;
    static int hash_size;

    public:
    static vector<hash_t> base;
    static vector<hash_t> base_inv;
    vector<hash_vector_t> cum;
    template<typename T> RollingHash(vector<T> &a, int hash_size=3, ll maxa=1e9) {
        if(!initialized) (*this).init_base(hash_size, maxa);
        (*this).calc(a);
    };
    RollingHash(string &a, int hash_size=3, ll maxa=1e9) {
        if(!initialized) (*this).init_base(hash_size, maxa);
        (*this).calc(a);
    }

    void init_base(int hash_size, ll maxa) {
        (*this).hash_size = hash_size;
        random_device seed_gen;
        mt19937 engine(seed_gen());
        while (sz(base) < hash_size) {
            hash_t k = 0;
            hash_t b = internal::Pow(RHR, k);
            while (b <= maxa || gcd(RHMOD-1, b) != 1) {
                k = engine();
                b = internal::Pow(RHR, k);
            }
            base.push_back(b);
            base_inv.push_back(internal::Pow(b, RHMOD-2));
        }
        initialized = true;
    }

    template<typename T> void calc(vector<T> const &a) {
        cum = vector<hash_vector_t>(sz(a)+1, vector<hash_t>(hash_size, 0));
        rep(i, hash_size) {
            hash_t base_pow = 1;
            rep(j, sz(a)) {
                cum[j+1][i] = internal::CalcMod(cum[j][i] + internal::Mul(a[j], base_pow));
                base_pow = internal::Mul(base_pow, (*this).base[i]);
            }
        }
    }

    void calc(string const &a) {
        vector<char> _a(a.begin(), a.end());
        calc(_a);
    };

    vector<hash_t> query(int l, int r) {
        assert(l <= r);
        assert(0 <= l && r < sz(cum));
        vector<hash_t> rev(hash_size);
        rep(i, hash_size) {
            rev[i] = internal::Mul(cum[r][i] + RHMOD - cum[l][i], internal::Pow((*this).base_inv[i], l));
        }
        return rev;
    }

    template <class T> vector<hash_vector_t> calc_hash(vector<T> const &a, int k){
        assert(sz(a) >= k);
        vector<hash_vector_t> res(sz(a) - k + 1, vector<hash_t>(hash_size));
        vector<hash_t> base_pow(hash_size);
        rep(i, hash_size) base_pow[i] = internal::Pow(this->base[i], k);

        rep(i, hash_size) {
            // 先頭のハッシュ計算
            hash_t b = this->base[i];
            hash_t sh = 0;
            rep(j, k){ sh = internal::CalcMod(internal::Mul(sh, b) + a[j]); }
            res[0][i] = sh;

            // sをずらしてハッシュ値を更新
            rep(j, sz(a) - k){
                sh = internal::CalcMod(internal::Mul(sh, b) + a[j+k] + RHMOD - internal::Mul(a[j], base_pow[i]));
                res[j+1][i] = sh;
            }
        }
        return res;
    }

    vector<hash_vector_t> calc_hash(string const &a, int k) {
        vector<char> _a(a.begin(), a.end());
        return calc_hash(_a, k);
    };
};
bool RollingHash::initialized = false;
int RollingHash::hash_size = 3;
vector<hash_t> RollingHash::base(0);
vector<hash_t> RollingHash::base_inv(0);
/**
 * @brief rolling_hash.hpp
 * @docs docs/string/rolling_hash.md
 */
//line 3 "/home/seekworser/.cpp_lib/competitive_library/competitive/math/prime.hpp"
bool is_prime(ll n) {
    using u128 = __uint128_t;
    vector<u128> a_list = {2, 7, 61, 325, 9375, 28178, 450775, 9780504, 1795265022};
    if (n == 1) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    ll r = 0;
    ll d = n - 1;
    while (!(d & 1)) {
        d >>= 1;
        r++;
    }
    ll cnt = 0;
    repe(a, a_list) {
        if (a >= n) continue;
        u128 res = 1;
        ll di = d;
        while (di > 0) {
            if (di & 1) res = (res * a) % n;
            if (di > 1) a = (a * a) % n;
            di >>= 1;
        }
        if (res == 1) continue;
        bool valid = false;
        rep(i, r) {
            if (res == n - 1) valid = true;
            res = (res * res) % n;
        }
        if (!valid) return false;
    }
    return true;
}

template <class T> vector<T> divisor(T n, bool sorted=true) {
    vector<T> ans(0);
    for (T i = 1; i <= (T)std::sqrt(n); i++) {
        if (n % i == 0) {
            ans.push_back(i);
            if (i * i != n) ans.push_back(n / i);
        }
    }
    if (sorted) sort(ans.begin(), ans.end());
    return ans;
};
template <class T> vector<T> prime_factor(T n) {
    vector<T> ans(0);
    for (T i = 2; i <= (T)std::sqrt(n); i++) {
        while (n % i == 0) {
            ans.push_back(i);
            n /= i;
        }
    }
    if (n != 1) ans.push_back(n);
    return ans;
};
template <class T> map<T, T> prime_factor_c(T n) {
    map<T, T> ans;
    for (T i = 2; i <= (T)std::sqrt(n); i++) {
        while (n % i == 0) {
            ans[i] += 1;
            n /= i;
        }
    }
    if (n != 1) ans[n] += 1;
    return ans;
};
template <class T> vector<T> primes(T n) {
    vector<T> ans(0);
    if (n < 2) return ans;
    vector<bool> is_primev(n+1, true);
    is_primev.at(0) = is_primev.at(1) = false;
    for (T i = 2; i <= (T)std::sqrt(n); i++) {
        if (!is_primev.at(i)) continue;
        for (T j = i*2; j <= n; j+=i) is_primev.at(j) = false;
    }
    for (T i = 2; i <= n; i++) {
        if (is_primev.at(i)) ans.push_back(i);
    }
    return ans;
};
template <class T> vector<T> segment_seive(T s, T t) {
    vector<T> ans(0);
    if (t < 2 || s < 0 || s >= t) return ans;
    vector<bool> is_prime_small((T)std::sqrt(t)+1, true);
    vector<bool> is_prime_large(t-s, true);
    for (T i = 2; i <= (T)std::sqrt(t); i++) {
        if (!is_prime_small.at(i)) continue;
        for (T j = i*2; j*j < t; j+=i) is_prime_small.at(j) = false;
        for (T j = max(2*i, ((s+i-1)/i)*i); j < t; j+=i) is_prime_large.at(j-s) = false;
    }
    for (T i=0; i < t-s; i++) {
        if (is_prime_large.at(i) && s+i != 1) ans.push_back(s+i);
    }
    return ans;
};
/**
 * @brief prime.hpp
 * @docs docs/math/prime.md
 */
//line 3 "/home/seekworser/.cpp_lib/competitive_library/competitive/std/io.hpp"
// overload operators (prototypes)
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p);
template <class T> inline istream& operator>>(istream& is, vector<T>& v);
template <class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& p);
template <class T> inline ostream& operator<<(ostream& os, const vector<T>& v);
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp);
template <typename T> ostream &operator<<(ostream &os, const set<T> &st);
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st);
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &st);
template <typename T> ostream &operator<<(ostream &os, queue<T> q);
template <typename T> ostream &operator<<(ostream &os, deque<T> q);
template <typename T> ostream &operator<<(ostream &os, stack<T> st);
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq);

// overload operators
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repe(x, v) is >> x; return is; }
template <class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& p) { os << p.first << " " << p.second; return os; }
template <class T> inline ostream& operator<<(ostream& os, const vector<T>& v) { rep(i, sz(v)) { os << v.at(i); if (i != sz(v) - 1) os << " "; } return os; }
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp) { for (auto &[key, val] : mp) { os << key << ":" << val << " "; } return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &st) { ll cnt = 0; for (auto &e : st) { os << e << (++cnt != (int)st.size() ? " " : ""); } return os; }
template <typename T> ostream &operator<<(ostream &os, queue<T> q) { while (q.size()) { os << q.front() << " "; q.pop(); } return os; }
template <typename T> ostream &operator<<(ostream &os, deque<T> q) { while (q.size()) { os << q.front(); q.pop_front(); if (q.size()) os << " "; } return os; }
template <typename T> ostream &operator<<(ostream &os, stack<T> st) { while (st.size()) { os << st.top() << " "; st.pop(); } return os; }
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq) { while (pq.size()) { os << pq.top() << " "; pq.pop(); } return os; }

template <typename T> int print_sep_end(string sep, string end, const T& val) { (void)sep; cout << val << end; return 0; };
template <typename T1, typename... T2> int print_sep_end(string sep, string end, const T1 &val, const T2 &...remain) {
    cout << val << sep;
    print_sep_end(sep, end, remain...);
    return 0;
};
template <typename... T> int print(const T &...args) { print_sep_end(" ", "\n", args...); return 0; };
template <typename... T> void flush() { cout << flush; };
template <typename... T> int print_and_flush(const T &...args) { print(args...); flush(); return 0; };
#define debug(...) debug_func(0, #__VA_ARGS__, __VA_ARGS__) // debug print
template <typename T> void input(T &a) { cin >> a; };
template <typename T1, typename... T2> void input(T1&a, T2 &...b) { cin >> a; input(b...); };
#ifdef LOCAL_TEST
template <typename T> void debug_func(int i, const T name) { (void)i; (void)name; cerr << endl; }
template <typename T1, typename T2, typename... T3> void debug_func(int i, const T1 &name, const T2 &a, const T3 &...b) {
    int scope = 0;
    for ( ; (scope != 0 || name[i] != ',') && name[i] != '\0'; i++ ) {
        cerr << name[i];
        if (name[i] == '(' || name[i] == '{') scope++;
        if (name[i] == ')' || name[i] == '}') scope--;
    }
    cerr << ":" << a << " ";
    debug_func(i + 1, name, b...);
}
template <typename T1, typename T2, typename... T3> void debug_func(int i, const T1 &name, T2 &a, T3 &...b) {
    int scope = 0;
    for ( ; (scope != 0 || name[i] != ',') && name[i] != '\0'; i++ ) {
        cerr << name[i];
        if (name[i] == '(' || name[i] == '{') scope++;
        if (name[i] == ')' || name[i] == '}') scope--;
    }
    cerr << ":" << a << " ";
    debug_func(i + 1, name, b...);
}
#endif
#ifndef LOCAL_TEST
template <typename... T>
void debug_func(T &...) {}
template <typename... T>
void debug_func(const T &...) {}
#endif
/**
 * @brief io.hpp
 * @docs docs/std/io.md
 */
//line 5 "answer.cpp"
int main() {
    ll n,q; input(n, q);
    vector<ll> s(n);
    rep(i, n) {
        char c; input(c);
        s[i] = c;
    }
    RollingHash rh(s);
    vl d = divisor(n);
    vector<vector<ll>> hashes;
    repe(di, d) {
        debug(di);
        hashes.push_back(vector<ll>(n / di));
        rep(i, n / di) {
            ll s = i * di;
            hashes.back()[i] = rh.query(s, s+di)[0];
        }
    }
    ll bs = rh.base[0];
    vector<map<ll, ll>> cnt(sz(d));
    set<ll> ok;
    rep(i, sz(d)) {
        repe(sh, hashes[i]) cnt[i][sh]++;
        if (sz(cnt[i]) == 1) ok.insert(i);
    }
    rep(i, q) {
        ll p; char c; input(p, c);
        --p;
        rep(i, sz(d)) {
            ll px = p / d[i];
            ll py = p % d[i];
            ll sh = hashes[i][px];
            ll shn = internal::CalcMod(RHMOD + sh - internal::Mul(s[p], internal::Pow(bs, py)) + internal::Mul(c, internal::Pow(bs, py)));
            cnt[i][sh]--;
            if (cnt[i][sh] == 0) cnt[i].erase(sh);
            cnt[i][shn]++;
            if ((sz(cnt[i])) == 1) ok.insert(i);
            if (ok.count(i) && (sz(cnt[i])) != 1) ok.erase(i);
            hashes[i][px] = shn;
        }
        debug(ok);
        s[p] = c;
        ll ans = *(ok.begin());
        print(d[ans]);
    }
    debug(ok);
}
accuracy: 1
time_ms: 1640
memory_kb: 17308
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
  constexpr int MAXN = 100005;
  constexpr long long MOD = 1000000007;
  constexpr long long BASE = 661525488;
  vector<long long> base_pow(MAXN, 1);
  for(int i = 1; i < MAXN; i++) {
    base_pow[i] = base_pow[i-1]*BASE%MOD;
  }
  int N, Q;
  string S;
  cin >> N >> Q >> S;
  vector<int> div;
  for(int i = 1; i*i <= N; i++) {
    if(N%i == 0) {
      div.push_back(i);
      div.push_back(N/i);
    }
  }
  sort(div.begin(), div.end());
  int ds = div.size();
  vector<vector<long long>> hash(ds);
  vector<multiset<long long>> M(ds);
  for(int i = 0; i < ds; i++) {
    hash[i].resize(N/div[i]);
    for(int j = 0; j < N; j++) {
      hash[i][j/div[i]] += base_pow[j%div[i]]*S[j]%MOD;
      hash[i][j/div[i]] %= MOD;
    }
    M[i] = multiset(hash[i].begin(), hash[i].end());
  }
  for(int q = 0; q < Q; q++) {
    int p;
    char c;
    cin >> p >> c;
    p--;
    for(int i = 0; i < ds; i++) {
      M[i].erase(M[i].find(hash[i][p/div[i]]));
      hash[i][p/div[i]] -= base_pow[p%div[i]]*S[p]%MOD;
      hash[i][p/div[i]] += base_pow[p%div[i]]*c%MOD;
      hash[i][p/div[i]] += MOD;
      hash[i][p/div[i]] %= MOD;
      M[i].insert(hash[i][p/div[i]]);
    }
    for(int i = 0; i < ds; i++) {
      if(*M[i].begin() == *M[i].rbegin()) {
        cout << div[i] << endl;
        break;
      }
    }
    S[p] = c;
  }
}
accuracy: 1
time_ms: 2700
memory_kb: 22876
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using u64 = unsigned long long;

constexpr int N = 100005;
// constexpr int M = 2;
// constexpr std::array<u64, M> MOD = {998244353, 1000000007};
// constexpr std::array<u64, M> BASE = {15029125, 7841253};
constexpr int M = 1;
constexpr std::array<u64, M> MOD = {998244353};
constexpr std::array<u64, M> BASE = {15029125};
std::array<std::array<u64, N>, M> base_table;
std::array<std::array<u64, N>, M> base_inv_table;

void init() {
    for (int i = 0; i < M; i++) {
        base_table[i].fill(1);
        for (int j = 0; j + 1 < N; j++) {
            base_table[i][j + 1] = BASE[i] * base_table[i][j];
            base_table[i][j + 1] %= MOD[i];
        }
    }
    for (int j = 1; j < N; j++) {
        for (int i = 0; i < M; i++) {
            u64 base = base_table[i][j] - 1;
            u64 exp = MOD[i] - 2;
            u64 res = 1;
            while (exp > 0) {
                if (exp & 1) {
                    res *= base;
                    res %= MOD[i];
                }
                base *= base;
                base %= MOD[i];
                exp >>= 1;
            }
            base_inv_table[i][j] = res;
        }
    }
}

struct Hash {
    Hash(): hash({0}), size(0) {}
    Hash(u64 c): hash({c}), size(1) {}
    std::array<u64, M> hash;
    int size;
    Hash repeat(int n) const {
        Hash res;
        res.size = n;
        for (int i = 0; i < M; i++) {
            res.hash[i] = hash[i] * (base_table[i][n] - 1) % MOD[i] * base_inv_table[i][size] % MOD[i];
        }
        return res;
    }
};

std::ostream& operator<<(std::ostream& os, const Hash& hash) {
    os << '(' << hash.hash[0] << ',' << hash.hash[1] << ',' << hash.size << ')';
    return os;
}

bool operator==(const Hash& lhs, const Hash& rhs) {
    return lhs.hash == rhs.hash && lhs.size == rhs.size;
}

Hash op(Hash lhs, const Hash& rhs) {
    for (int i = 0; i < M; i++) {
        lhs.hash[i] *= base_table[i][rhs.size];
        lhs.hash[i] += rhs.hash[i];
        lhs.hash[i] %= MOD[i];
    }
    lhs.size += rhs.size;
    return lhs;
}

struct SegTree {
    std::vector<Hash> data;
    int size;
    SegTree(const std::string& s) {
        size = s.size();
        data.resize(2 * size);
        for (int i = 0; i < size; i++) {
            data[i + size] = Hash(s[i]);
        }
        for (int i = size - 1; i > 0; i--) {
            data[i] = op(data[2 * i], data[2 * i + 1]);
        }
    }
    void set(int pos, char c) {
        pos += size;
        data[pos] = Hash(c);
        for (pos >>= 1; pos > 0; pos >>= 1) {
            data[pos] = op(data[2 * pos], data[2 * pos + 1]);
        }
    }
    Hash prod(int left, int right) {
        Hash lhs;
        Hash rhs;
        for (left += size, right += size; left < right; left >>= 1, right >>= 1) {
            if (left & 1) lhs = op(lhs, data[left++]);
            if (right & 1) rhs = op(data[--right], rhs);
        }
        return op(lhs, rhs);
    }
};

std::vector<int> divisor(int n) {
    std::vector<int> div;
    for (int i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            div.push_back(i);
            if (i * i != n) {
                div.push_back(n / i);
            }
        }
    }
    std::sort(div.begin(), div.end());
    return div;
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    init();
    int n, q;
    std::cin >> n >> q;
    std::string s;
    std::cin >> s;
    auto divs = divisor(n);
    SegTree segtree(s);

    while (q--) {
        int pos;
        char c;
        std::cin >> pos >> c;
        pos--;
        segtree.set(pos, c);
        int ans = -1;
        for (auto div: divs) {
            auto lhs = segtree.prod(0, div).repeat(n);
            auto rhs = segtree.prod(0, n);
            if (lhs == rhs) {
                ans = div;
                break;
            }
        }
        assert(ans != -1);
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 530
memory_kb: 8060
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using u64 = unsigned long long;

constexpr int N = 100005;
constexpr int M = 2;
constexpr std::array<u64, M> MOD = {998244353, 1000000007};
constexpr std::array<u64, M> BASE = {15029125, 7841253};
std::array<std::array<u64, N>, M> base_table;

void init_table() {
    for (int i = 0; i < M; i++) {
        base_table[i].fill(1);
        for (int j = 0; j + 1 < N; j++) {
            base_table[i][j + 1] = BASE[i] * base_table[i][j];
            base_table[i][j + 1] %= MOD[i];
        }
    }
}

struct Hash {
    Hash(): hash({0, 0}), size(0) {}
    Hash(u64 c): hash({c, c}), size(1) {}
    std::array<u64, M> hash;
    int size;

    u64 encode() {
        return hash[0] * MOD[1] + hash[1];
    }
};

std::ostream& operator<<(std::ostream& os, const Hash& hash) {
    os << '(' << hash.hash[0] << ',' << hash.hash[1] << ',' << hash.size << ')';
    return os;
}

bool operator<(const Hash& lhs, const Hash& rhs) {
    if (lhs.hash == rhs.hash) return lhs.size < rhs.size;
    return lhs.hash < rhs.hash;
}

Hash op(Hash lhs, const Hash& rhs) {
    for (int i = 0; i < M; i++) {
        lhs.hash[i] *= base_table[i][rhs.size];
        lhs.hash[i] += rhs.hash[i];
        lhs.hash[i] %= MOD[i];
    }
    lhs.size += rhs.size;
    return lhs;
}

struct SegTree {
    std::vector<Hash> data;
    int size;
    SegTree(const std::string& s) {
        size = s.size();
        data.resize(2 * size);
        for (int i = 0; i < size; i++) {
            data[i + size] = Hash(s[i]);
        }
        for (int i = size - 1; i > 0; i--) {
            data[i] = op(data[2 * i], data[2 * i + 1]);
        }
    }
    void set(int pos, char c) {
        pos += size;
        data[pos] = Hash(c);
        for (pos >>= 1; pos > 0; pos >>= 1) {
            data[pos] = op(data[2 * pos], data[2 * pos + 1]);
        }
    }
    Hash prod(int left, int right) {
        Hash lhs;
        Hash rhs;
        for (left += size, right += size; left < right; left >>= 1, right >>= 1) {
            if (left & 1) lhs = op(lhs, data[left++]);
            if (right & 1) rhs = op(data[--right], rhs);
        }
        return op(lhs, rhs);
    }
};

std::vector<int> divisor(int n) {
    std::vector<int> div;
    for (int i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            div.push_back(i);
            if (i * i != n) {
                div.push_back(n / i);
            }
        }
    }
    std::sort(div.begin(), div.end());
    return div;
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    init_table();
    int n, q;
    std::cin >> n >> q;
    std::string s;
    std::cin >> s;
    auto divs = divisor(n);
    int m = divs.size();
    std::vector<std::unordered_map<u64, int>> hashs(m);
    SegTree segtree(s);

    for (int i = 0; i < m; i++) {
        int div = divs[i];
        assert(n % div == 0);
        for (int l = 0; l < n; l += div) {
            int r = l + div;
            hashs[i][segtree.prod(l, r).encode()]++;
        }
    }

    while (q--) {
        int pos;
        char c;
        std::cin >> pos >> c;
        pos--;
        for (int i = 0; i < m; i++) {
            int l = (pos / divs[i]) * divs[i];
            int r = l + divs[i];
            auto hash = segtree.prod(l, r).encode();
            assert(hashs[i][hash] > 0);
            hashs[i][hash]--;
            if (hashs[i][hash] == 0) {
                hashs[i].erase(hash);
            }
        }
        segtree.set(pos, c);
        for (int i = 0; i < m; i++) {
            int l = (pos / divs[i]) * divs[i];
            int r = l + divs[i];
            hashs[i][segtree.prod(l, r).encode()]++;
        }
        int ans = -1;
        for (int i = 0; i < m; i++) {
            if (hashs[i].size() == 1) {
                ans = divs[i];
                break;
            }
        }
        assert(ans != -1);
        std::cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 1980
memory_kb: 13352
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
using ll = long long;
template<class T> bool chmin(T &a,const T b){if(a>b){a=b;return 1;}return 0;}
template<class T> bool chmax(T &a,const T b){if(a<b){a=b;return 1;}return 0;}
const int INF = (1<<30)-1;
#define all(p) p.begin(),p.end()

int main(){
	int N,Q;
    cin>>N>>Q;
    vector<int> div;
    rep(i,1,N+1) if(N%i==0) div.push_back(i);
    string S;
    cin>>S;
    int L=div.size();
    vector<int> p(L);
    auto f=[&](int ind,int val)->void{
        rep(i,0,L){
            if(div[i]<=ind&&S[ind]!=S[ind-div[i]]) p[i]+=val;
            if(div[i]+ind<N&&S[ind]!=S[ind+div[i]]) p[i]+=val;
        }
    };
    rep(i,0,L){
        rep(j,0,N-div[i]){
            if(S[j]!=S[j+div[i]]) p[i]++;
        }
    }
    rep(i,0,Q){
        int ind;
        char c;
        cin>>ind>>c;
        ind--;
        f(ind,-1);
        S[ind]=c;
        f(ind,1);
        rep(j,0,L){
            if(p[j]==0){
                cout<<div[j]<<"\n";
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 130
memory_kb: 3568
final_rank: 2

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0414.cc: Prayers of Iwashiro
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 100000;

/* typedef */

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;

/* global variables */

char s[MAX_N + 4];

/* subroutines */

/* main */

int main() {
  int n, qn;
  scanf("%d%d%s", &n, &qn, s);

  vi ds(1, 1);
  for (int p = 2; p * p <= n; p++)
    if (n % p == 0) {
      ds.push_back(p);
      int q = n / p;
      if (q != p) ds.push_back(q);
    }
  sort(ds.begin(), ds.end());
  int m = ds.size();
  //printf("m=%d\n", m);

  vvvi scs(m);
  vi fs(m);
  for (int i = 0; i < m; i++) {
    int d = ds[i], l = n / d;
    scs[i].assign(d, vi(26, 0));
    for (int j = 0; j < n; j++)
      if (++scs[i][j % d][s[j] - 'a'] == l) fs[i]++;
  }

  while (qn--) {
    int p;
    char t[4];
    scanf("%d%s", &p, t), p--;

    for (int i = 0; i < m; i++) {
      int d = ds[i], l = n / d;
      if (scs[i][p % d][s[p] - 'a']-- == l) fs[i]--;
    }

    s[p] = t[0];

    for (int i = 0; i < m; i++) {
      int d = ds[i], l = n / d;
      if (++scs[i][p % d][s[p] - 'a'] == l) fs[i]++;
    }

    int mind = n;
    for (int i = 0; i < m; i++)
      if (fs[i] == ds[i]) { mind = ds[i]; break; }

    printf("%d\n", mind);
  }
  return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 37552
final_rank: 7