#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cmath>
#include <cstring>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

template<class T, class Compare = greater<T> >
using MinHeap = priority_queue<T, vector<T>, Compare>;
template<class T, class Compare = less<T> >
using MaxHeap = priority_queue<T, vector<T>, Compare>;
using llong = long long;

//===
template<typename Monoid, typename OP = function<Monoid(Monoid, Monoid)> >
struct SegmentTree {
    
    vector<Monoid> tree;
    int size;
    const OP f; // bin' operation
    const Monoid e; // neutral element
                                           
    SegmentTree(int nmemb, const Monoid &e, const OP &f):
        size(nmemb),
        f(f),
        e(e)
    {
        tree.assign(2 * size, e);
    }

    void update(int k, Monoid dat) {
        k += size;
        tree[k] = dat;
        
        while(k > 1) {
            k /= 2;
            tree[k] = f(tree[2 * k], tree[2 * k + 1]);
        }
    }

    // [l, r)
    Monoid query(int l, int r) {
        l += size; //points leaf
        r += size;

        Monoid vl = e;
        Monoid vr = e;
        while (l < r) {
            if (l & 1) {
                vl = f(vl, tree[l]);
                l++;
            }
            if (r & 1) {
                r--;
                vr = f(tree[r], vr);
            }

            l /= 2;
            r /= 2;
        }

        return f(vl, vr);
    }

    Monoid operator[] (const int k) { return query(k, k + 1); }
};
//===
template<uint64_t mod, uint64_t base>
struct RollingHashMonoid {
    using rh = RollingHashMonoid<mod, base>;
        
    int sz;
    uint64_t h;

    static vector<uint64_t> p;

    RollingHashMonoid() {};
    RollingHashMonoid(char ch): sz(1), h(ch % mod) {};
    
    static rh neutral() {
        RollingHashMonoid res;
        res.sz = 0, res.h = 0;
        return res;
    };

    rh operator + (const rh &r) const {
        const rh &l = *this;
        rh res = neutral();

        while (p.size() <= r.sz) p.push_back(p.back() * base % mod);

        res.sz = l.sz + r.sz;
        res.h = (l.h * p[r.sz] % mod + r.h) % mod;
        return res;
    };
};
template<uint64_t mod, uint64_t base>
vector<uint64_t> RollingHashMonoid<mod, base>::p = vector<uint64_t>(1, 1);
//===

const llong mod = (llong)(1e9) + 7;
const llong rad[3] = {3, 1709, 1999};
llong radt[3][100005];
llong loopt[3][100005];

using Rhash1 = RollingHashMonoid<(llong)(1e9) + 7, 3>;
using Rhash2 = RollingHashMonoid<(llong)(1e9) + 7, 1709>;
using Rhash3 = RollingHashMonoid<(llong)(1e9) + 7, 1999>;
auto concat = [](auto l, auto r){ return l + r; };
SegmentTree<Rhash1> seg1(131072, Rhash1::neutral(), concat);
SegmentTree<Rhash2> seg2(131072, Rhash2::neutral(), concat);
SegmentTree<Rhash3> seg3(131072, Rhash3::neutral(), concat);

llong n, q;
string s;
llong p;
char c;
vector<llong> divisor;

void init() {
    radt[0][0] = radt[1][0] = radt[2][0] = 1;

    for (llong i = 0; i < 100003; i++) {
        radt[0][i + 1] = (radt[0][i] * rad[0]) % mod;
        radt[1][i + 1] = (radt[1][i] * rad[1]) % mod;
        radt[2][i + 1] = (radt[2][i] * rad[2]) % mod;
    }

    for (llong k = 0; k < 3; k++) {
        for (llong i = 0; i < divisor.size(); i++) {
            llong idx = divisor[i];

            llong j = 0;
            while (j < n) {
                loopt[k][n / idx] += radt[k][j];
                loopt[k][n / idx] %= mod;
                j += idx;
            }
        }
    }
}

bool same(llong idx) {
    llong v;

    v = seg1.query(0, idx).h * loopt[0][n / idx] % mod;
    if (v != seg1.tree[1].h) {
        return false;
    }

    v = seg2.query(0, idx).h * loopt[1][n / idx] % mod;
    if (v != seg2.tree[1].h) {
        return false;
    }

    v = seg3.query(0, idx).h * loopt[2][n / idx] % mod;
    if (v != seg3.tree[1].h) {
        return false;
    }

    return true;
}

int main() {
    cin >> n >> q;
    cin >> s;

    for (int i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            divisor.push_back(i);

            if (n / i != i) divisor.push_back(n / i);
        }
    }
    
    sort(divisor.begin(), divisor.end());
    init();

    for (int i = 0; i < s.size(); i++) {
        seg1.update(i, Rhash1(s[i]));
        seg2.update(i, Rhash2(s[i]));
        seg3.update(i, Rhash3(s[i]));
    }

    for (int i = 0; i < q; i++) {
        cin >> p >> c;
        p--;
        s[p] = c;
        
        seg1.update(p, Rhash1(s[p]));
        seg2.update(p, Rhash2(s[p]));
        seg3.update(p, Rhash3(s[p]));

        llong ans = n;
        for (llong i = 0; i < divisor.size(); i++) {
            llong idx = divisor[i];

            if (same(idx)) {
                ans = idx;
                break;
            }
        }
        
#ifdef DEBUG
        cout << s << endl;
#endif
        cout << ans << endl;
    }

    return 0;
}



Measured memory_bytes: 20512