#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <queue>
#include <ctime>
#include <cassert>
#include <cstdio>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <bitset>

using namespace std;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define epr(...) fprintf(stderr, __VA_ARGS__)
#define db(x) cerr << #x << " = " << x << endl
#define db2(x, y) cerr << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")\n";
#define all(a) (a).begin(), (a).end()

#define equal equalll
#define less lesss
const int N = 1111;
const long long INF = 1e9 + 19;

int n, m, k;
int board[N][N];
char s[N][N];
pair < int, int > add[N];
int pref[N][N];
int answer[N];
int dp[N][N];
int p[N * N];
int l[N * N];
int r[N * N];
int LUp[N];
int RUp[N];
int LDown[N];
int RDown[N];

void read() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 0; i < n; i++)
        scanf("%s", s[i]);
    for (int i = 0; i < k; i++) {
        scanf("%d%d", &add[i].fr, &add[i].sc);
        add[i].fr--;
        add[i].sc--;
    }

}

int getPos(int x, int y) {
    return x * m + y;
}

int getSum(int x0, int y0, int x1, int y1) {
    return pref[x1][y1] - pref[x0][y1] - pref[x1][y0] + pref[x0][y0];
}

int getId(int v) {
    return (p[v] == v)? v: p[v] = getId(p[v]);
}

void merge(int v, int u) {
    v = getId(v);
    u = getId(u);
    p[v] = u;
    l[u] = min(l[u], l[v]);
    r[u] = max(r[u], r[v]);
}

void getLR(int x, int y, int & L, int & R) {
    if (board[x][y] == 1) {
        L = m;
        R = -1;
        return;
    }
    int v = getPos(x, y);
    v = getId(v);
    L = l[v];
    R = r[v];
}

void solve() {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            board[i][j] = s[i][j] == 'X';

    for (int i = 0; i < k; i++) {
        assert(board[add[i].fr][add[i].sc] == 0);
        board[add[i].fr][add[i].sc] = 1;
    }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            pref[i + 1][j + 1] = pref[i + 1][j] + pref[i][j + 1] - pref[i][j] + board[i][j];

    int mx = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            for (;; ) {
                int r = dp[i][j] + 1;
                if (i + r <= n && j + r <= m && getSum(i, j, i + r, j + r) == 0)
                    dp[i][j]++;
                else
                    break;
            }
            dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] - 1);
            dp[i][j + 1] = max(dp[i][j + 1], dp[i][j] - 1);
            mx = max(dp[i][j], mx);
        }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            int id = getPos(i, j);
            p[id] = id;
            l[id] = j;
            r[id] = j;
        }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m - 1; j++)
            if (board[i][j] == 0 && board[i][j + 1] == 0) {
                merge(getPos(i, j), getPos(i, j + 1));
            }
    //for (int i = 0; i < n; i++, cerr << endl)
        //for (int j = 0; j < m; j++)
            //cerr << board[i][j] << " ";
    //cerr << endl;
    //for (int i = 0; i < n; i++, cerr << endl)
        //for (int j = 0; j < m; j++)
            //cerr << getId(getPos(i, j)) << " ";
    //cerr << endl;
    //for (int i = 0; i < n; i++, cerr << endl)
        //for (int j = 0; j < m; j++)
            //cerr << r[getId(getPos(i, j))] << " ";
    int ll, rr;
    getLR(3, 7, ll, rr);
    //db2(n, m);
    //db2(ll, rr);

    answer[k - 1] = mx;
    for (int t = k - 1; t >= 1; t--) {
        //db(t);
        int x = add[t].fr;
        int y = add[t].sc;
        assert(board[x][y] == 1);
        board[x][y] = 0;
        if (y > 0 && board[x][y - 1] == 0)
            merge(getPos(x, y - 1), getPos(x, y));
        if (y + 1 < m && board[x][y + 1] == 0)
            merge(getPos(x, y + 1), getPos(x, y));

        for (;;) {
            int up = max(0, x - mx);
            int down = min(x + mx, n - 1);
            int mxL = 0;
            int mnR = m;
            //db2(x, y);
            //db2(up, down);
            //db(mx);
            for (int i = x; i >= up; i--) {
                int left, right;
                getLR(i, y, left, right);
                mxL = max(mxL, left);
                mnR = min(mnR, right);
                LUp[i] = mxL;
                RUp[i] = mnR;
            }
            mxL = 0;
            mnR = m;
            for (int i = x; i <= down; i++) {
                int left, right;
                getLR(i, y, left, right);
                mxL = max(mxL, left);
                mnR = min(mnR, right);
                LDown[i] = mxL;
                RDown[i] = mnR;
            }
            //for (int i = 0; i < n; i++)
                //db2(LUp[i], RUp[i]);
            //cerr << endl;
            //for (int i = 0; i < n; i++)
                //db2(LDown[i], RDown[i]);
            bool flag = 0;
            for (int i = x; i >= up; i--) {
                int dd = i + mx;
                //db2(dd, x);
                assert(dd >= x);
                if (dd > down) continue;
                mxL = max(LUp[i], LDown[dd]);
                mnR = min(RUp[i], RDown[dd]);
                if (mnR - mxL >= mx)
                    flag = 1;
            }
            if (!flag) break;
            mx++;
        }

        answer[t - 1] = mx;
    }
    for (int i = 0; i < k; i++)
        printf("%d\n", answer[i]);

}

void printAns() {

}

void stress() {

}

int main(){
#ifdef DEBUG
    freopen("in", "r", stdin);
    //freopen("out", "w", stdout);
#endif
    if (1) {
        int k = 1;
        for (int tt = 0; tt < k; tt++) {
            read();
            solve();
            printAns();
        }
    }
    else {
        stress();
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline int read() {
	int x=0;
	char ch=getchar();
	for(; ch<'0'||ch>'9'; ch=getchar());
	for(; ch>='0'&&ch<='9'; ch=getchar())
		x=(x<<1)+(x<<3)+(ch^48);
	return x;
}
const int maxn=2010;
int c[maxn][maxn],n,m;
char a[maxn][maxn];
inline void add(int x,int y)
{
	for(int i=x;i<=n;i+=i&-i)
		for(int j=y;j<=m;j+=j&-j)
			c[i][j]++;
}
inline int sum(int x,int y)
{
	int ans=0;
	for(int i=x;i;i-=i&-i)
		for(int j=y;j;j-=j&-j)
			ans+=c[i][j];
	return ans;
}
int check(int x)
{
	for(int i=x;i<=n;i++)
		for(int j=x;j<=m;j++)
		{
			int t=sum(i,j)-sum(i-x,j)-sum(i,j-x)+sum(i-x,j-x);
			if(!t)return 1;
		}
	return 0;
}
int main()
{
//	freopen("f.in","r",stdin);
//	freopen("f.out","w",stdin);
	n=read(),m=read();
	int q=read();
	for(int i=1;i<=n;i++)
	{
		scanf("%s",a[i]+1);
		for(int j=1;j<=m;j++)
			if(a[i][j]=='X')
				add(i,j);
	}
	for(int i=1;i<=q;i++)
	{
		int x=read(),y=read();
		if(a[x][y]=='.')
		{
			a[x][y]='X';
			add(x,y);
		}
		int l=1,r=min(m,n);
		while(l<=r)
		{
			int mid=(l+r)>>1;
			if(check(mid))l=mid+1;
			else r=mid-1;
		}
		printf("%d\n",l-1);
	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 6000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(now && (now < l || now > r)
		return ;

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	now = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		now = x;
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		UpTmp = min(UpQueue.top().x, mid - l + 1);
		DownTmp = min(DownQueue.top().x, r - mid + 1);

		while(UpTmp + DownTmp - 1 < R - L + 1) {
			L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			if(UpQueue.empty() || DownQueue.empty())
				break;

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);
		}
		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		do{
			L ++;
			if(L > R)
				break;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	Ans[o] = min(r - l + 1, ans);

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 3000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];

	if(l == r) {
		REP(i, 1, m)
			if(!c[l][i])
				return 1;
		return 0;
	}

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		if(c[mid][R])
			continue;
		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l - 1 || now > r + 1))
		return Ans[o];

	while(++ R <= m) {
		do{
			L ++;
			if(L > R)
				break;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	Ans[o] = ans;

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l - 1 || now > r + 1))
		return Ans[o];

	while(++ R <= m) {
		if(c[mid][R])
			continue;
		do{
			L ++;
			if(L > R)
				break;

			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		if(c[mid][R])
			continue;

		do{
			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			while(UpTmp + DownTmp - 1 < R - L + 1) {
				L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;

				if(UpQueue.top().pos < L)
					UpQueue.pop();
				if(DownQueue.top().pos < L)
					DownQueue.pop();

				if(UpQueue.empty() || DownQueue.empty())
					break;

				UpTmp = min(UpQueue.top().x, mid - l + 1);
				DownTmp = min(DownQueue.top().x, r - mid + 1);
			}

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN];
int n, m, k, ans;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= r & -r; r -= r & -r)
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(int l, int r)
{
	if(l == r)
		return 0;

	int mid = (l + r) >> 1, L = 1, R = ans, tmp;

	while(++ R <= m) {
		if(m - L + 1 <= ans)
			break;
		while(L <= R && R - L + 1 > (tmp = up[mid].Query(L, R) + down[mid + 1].Query(L, R)))
			L ++;
		Chkmax(ans, min(tmp, R - L + 1));
	}

	Work(l, mid);
	Work(mid + 1, r);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		printf("%d\n", Work(1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	while(++ R <= m) {
		if(c[mid][R])
			continue;
		do{
			L ++;
			if(L > R)
				break;

			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		do{
			L ++;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(L < R && R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	Ans[o] = min(r - l + 1, ans);

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(now && (now < l || now > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	now = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		now = x;
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN];
int n, m, k, ans;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= r & -r; r -= r & -r)
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

void Work(int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = ans, tmp;

	while(++ R <= m) {
		if(m - L + 1 <= ans)
			break;
		while(L <= R && R - L + 1 > (tmp = up[mid].Query(L, R) + down[mid + 1].Query(L, R)))
			L ++;
		Chkmax(ans, min(tmp, R - L + 1));
	}

	if(l != r) {
		Work(l, mid);
		Work(mid + 1, r);
	}
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		Work(1, n);
		printf("%d\n", ans);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		UpTmp = min(up[mid].Query(L, R), mid - l + 1);
		DownTmp = min(down[mid].Query(L, R), r - mid + 1);

		while(L < R && R - L + 1 > UpTmp + DownTmp - 1) {
			L ++;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
		}

		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
	}

	Ans[o] = min(r - l + 1, ans);

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		do{
			L ++;
			if(L > R)
				break;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	Ans[o] = ans;

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		UpTmp = min(UpQueue.top().x, mid - l + 1);
		DownTmp = min(DownQueue.top().x, r - mid + 1);
		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));

		do {
			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
			if(UpTmp + DownTmp - 1 < R - L + 1)
				break;

			L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;
			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			if(UpQueue.empty() || DownQueue.empty())
				break;
		}while(UpTmp + DownTmp - 1 < R - L + 1);
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		if(c[mid][R])
			continue;
		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x - i;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = i - x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R], R));

		UpTmp = min(UpQueue.top().x, mid - l + 1);
		DownTmp = min(DownQueue.top().x, r - mid + 1);

		while(UpTmp + DownTmp - 1 < R - L + 1) {
			L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			if(UpQueue.empty() || DownQueue.empty())
				break;

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);
		}
		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 0, m - 1)
			if(s[j] == 'X')
				c[i][j] = true;
	}

	REP(j, 1, m) {
		REP(i, 1, n)
			Up[i][j] = c[i][j]? 0 : Up[i - 1][j] + 1;
		rep(i, n, 1)
			Down[i][j] = c[i][j]? 0 : Down[i + 1][j] + 1;
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 3000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		if(c[mid][R])
			continue;
		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		if(c[mid][R])
			continue;

		do{
			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			while(UpTmp + DownTmp - 1 < R - L + 1) {
				L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;
				if(UpQueue.top().pos < L)
					UpQueue.pop();
				if(DownQueue.top().pos < L)
					DownQueue.pop();

				UpTmp = min(UpQueue.top().x, mid - l + 1);
				DownTmp = min(DownQueue.top().x, r - mid + 1);

				if(L > R)
					break;
			}

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 6000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(now && (now < l || now > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	now = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		now = x;
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 3000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x - i;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = i - x;

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];

	if(l == r) {
		REP(i, 1, m)
			if(!c[l][i])
				return 1;
		return 0;
	}

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R], R));
		if(c[mid][R])
			continue;
		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	scanf("%d%d%d", &n, &m, &k);

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				c[i][j] = true;
	}

	REP(j, 1, m) {
		REP(i, 1, n)
			Up[i][j] = c[i][j]? 0 : Up[i - 1][j] + 1;
		rep(i, n, 1)
			Down[i][j] = c[i][j]? 0 : Down[i + 1][j] + 1;
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		do{
			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			while(UpTmp + DownTmp - 1 < R - L + 1) {
				L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;
				if(UpQueue.top().pos < L)
					UpQueue.pop();
				if(DownQueue.top().pos < L)
					DownQueue.pop();
				if(L > R)
					break;

				UpTmp = min(UpQueue.top().x, mid - l + 1);
				DownTmp = min(DownQueue.top().x, r - mid + 1);
			}

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1);
		R ++;
	} while(R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 3000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];

	if(l == r) {
		REP(i, 1, m)
			if(!c[l][i])
				return 1;
		return 0;
	}

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R], R));
		if(c[mid][R])
			continue;
		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	scanf("%d%d%d", &n, &m, &k);

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				c[i][j] = true;
	}

	REP(j, 1, m) {
		REP(i, 1, n)
			Up[i][j] = c[i][j]? 0 : Up[i - 1][j] + 1;
		rep(i, n, 1)
			Down[i][j] = c[i][j]? 0 : Down[i + 1][j] + 1;
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos < a.pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x - i;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = i - x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R], R));

		UpTmp = min(UpQueue.top().x, mid - l + 1);
		DownTmp = min(DownQueue.top().x, r - mid + 1);

		while(UpTmp + DownTmp - 1 < R - L + 1) {
			L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			if(UpQueue.empty() || DownQueue.empty())
				break;

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);
		}
		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	scanf("%d%d%d", &n, &m, &k);

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				c[i][j] = true;
	}

	REP(j, 1, m) {
		REP(i, 1, n)
			Up[i][j] = c[i][j]? 0 : Up[i - 1][j] + 1;
		rep(i, n, 1)
			Down[i][j] = c[i][j]? 0 : Down[i + 1][j] + 1;
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x - i;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = i - x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R], R));

		UpTmp = min(UpQueue.top().x, mid - l + 1);
		DownTmp = min(DownQueue.top().x, r - mid + 1);

		while(UpTmp + DownTmp - 1 < R - L + 1) {
			L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			if(UpQueue.empty() || DownQueue.empty())
				break;

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);
		}
		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	scanf("%d%d%d", &n, &m, &k);

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				c[i][j] = true;
	}

	REP(j, 1, m) {
		REP(i, 1, n)
			Up[i][j] = c[i][j]? 0 : Up[i - 1][j] + 1;
		rep(i, n, 1)
			Down[i][j] = c[i][j]? 0 : Down[i + 1][j] + 1;
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 6000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top() { return q[head]; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(now && (now < l || now > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));

		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	now = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		now = x;
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		do{
			L ++;
			if(L > R)
				break;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(L < R && R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	Ans[o] = min(r - l + 1, ans);

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		UpTmp = min(up[mid].Query(L, R), mid - l + 1);
		DownTmp = min(down[mid].Query(L, R), r - mid);

		while(L < R && R - L + 1 > UpTmp + DownTmp - 1) {
			L ++;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid);
		}

		Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
	}

	Ans[o] = min(r - l + 1, ans);

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	void Init()
	{
		head = tail = 0;
	}
	void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	Sta top() { return q[head]; }
	void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Chkmin(Down[i][y], x);

	for(int i = x; i <= n && !c[i][y]; i ++)
		Chkmax(Up[i][y], x);

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	if(flag && (now < l || now > r))
		return Ans[o];
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	while(++ R <= m) {
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		do{
			if(L > R)
				break;

			if(UpQueue.top().pos < L)
				UpQueue.pop();
			if(DownQueue.top().pos < L)
				DownQueue.pop();

			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && ++ L);
	}

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid + 1, r));
	}

	return Ans[o] = ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
int min(int x, int y) { return x < y? x : y; }
int max(int x, int y) { return x > y? x : y; }
bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 4000, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, X;

struct Sta{
	int x, pos;
	Sta(){}
	Sta(int x, int pos):
		x(x), pos(pos){}
	bool operator < (const Sta &a) const {
		if(x != a.x)
			return x < a.x;
		return pos;
	}
};

struct SpecialQueue{
	int head, tail;
	Sta q[MAXN];
	inline void Init()
	{
		head = tail = 0;
	}
	inline void push(Sta a)
	{
		while(head <= tail) {
			if(a < q[tail])
				tail --;
			else break;
		}
		q[++ tail] = a;
	}
	inline Sta top()
	{
		if(head > tail)
			puts("error!");
		return q[head];
	}
	bool empty()
	{ return head > tail; }
	inline void pop() { head ++; }
}UpQueue, DownQueue;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --)
		Down[i][y] = x;

	for(int i = x; i <= n && !c[i][y]; i ++)
		Up[i][y] = x;

	c[x][y] = true;
}

void Maintain(int o)
{
	Chkmax(Ans[o], Ans[o << 1]);
	Chkmax(Ans[o], Ans[o << 1|1]);
}

void Work(int o, int l, int r)
{
	if(X && (X < l || X > r))
		return ;

	int mid = (l + r) >> 1, L = 1, R = 1, UpTmp, DownTmp, ans = 0;

	UpQueue.Init();
	DownQueue.Init();

	do{
		UpQueue.push(Sta(mid - Up[mid][R], R));
		DownQueue.push(Sta(Down[mid][R] - mid, R));
		if(c[mid][R])
			continue;

		do{
			UpTmp = min(UpQueue.top().x, mid - l + 1);
			DownTmp = min(DownQueue.top().x, r - mid + 1);

			while(UpTmp + DownTmp - 1 < R - L + 1) {
				L = min(UpQueue.top().pos, DownQueue.top().pos) + 1;

				if(UpQueue.top().pos < L)
					UpQueue.pop();
				if(DownQueue.top().pos < L)
					DownQueue.pop();

				if(UpQueue.empty() || DownQueue.empty())
					break;

				UpTmp = min(UpQueue.top().x, mid - l + 1);
				DownTmp = min(DownQueue.top().x, r - mid + 1);
			}

			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(R - L + 1 > UpTmp + DownTmp - 1 && !UpQueue.empty() && !DownQueue.empty());
	} while(++ R <= m);

	Ans[o] = ans;
	if(l == r)
		return;

	Work(o << 1, l, mid);
	Work(o << 1|1, mid + 1, r);
	Maintain(o);
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	X = 0;
	Work(1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		X = x;
		Update(x, y);
		Work(1, 1, n);
		printf("%d\n", Ans[1]);
	}
}

int main()
{
	Init();
	Solve();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define REP(i, x, y) for(int i = x, _ = y; i <= _; i ++)
#define rep(i, x, y) for(int i = x, _ = y; i >= _; i --)
inline int min(int x, int y) { return x < y? x : y; }
inline int max(int x, int y) { return x > y? x : y; }
inline bool Chkmin(int &x, int y) { return y < x? x = y, true : false; }
inline bool Chkmax(int &x, int y) { return y > x? x = y, true : false; }
const int MAXN = 2000 + 100, oo = 0x3f3f3f3f;
bool c[MAXN][MAXN];
int Up[MAXN][MAXN], Down[MAXN][MAXN], Ans[MAXN * 4];
int n, m, k, ans, now;

void Readin(int &x)
{
	x = 0;
	char c = getchar();
	while(!('0' <= c && c <= '9'))
		c = getchar();
	while('0' <= c && c <= '9') {
		(x *= 10) += c - '0';
		c = getchar();
	}
}

struct Fenwick{
    int a[MAXN], idx[MAXN];

    void Modify(int x, int y)
    {
        a[x] = y;
        for(x; x <= m; x += x & -x){
            idx[x] = a[x];
            for(int j = 1, _ = x & -x; j < _ ;j <<= 1)
                Chkmin(idx[x], idx[x - j]);
        }
    }

    int Query(int l, int r)
    {
        int ans = a[r];
        while(l != r){
            for(r -= 1; r - l >= (r & -r); r -= (r & -r))
                Chkmin(ans, idx[r]);
            Chkmin(ans, a[r]);
        }
        return ans;
    }

    void Init()
    {
        REP(i, 1, m){
            idx[i] = a[i];
            for(int j = 1, _ = i & -i; j < _; j <<= 1)
                Chkmin(idx[i], idx[i - j]);
        }
    }
} up[MAXN], down[MAXN];

void Update(int x, int y)
{
	if(c[x][y])
		return ;

	for(int i = x; i > 0 && !c[i][y]; i --) {
		Chkmin(Down[i][y], x);
		down[i].Modify(y, abs(i - x));
	}

	for(int i = x; i <= n && !c[i][y]; i ++) {
		Chkmax(Up[i][y], x);
		up[i].Modify(y, abs(i - x));
	}

	c[x][y] = true;
}

int Work(bool flag, int o, int l, int r)
{
	int mid = (l + r) >> 1, L = 1, R = 0, UpTmp, DownTmp, ans = 0;
	if(flag && (now < l || now > r))
		return Ans[o];

	while(++ R <= m) {
		do{
			L ++;
			if(L > R)
				break;
			UpTmp = min(up[mid].Query(L, R), mid - l + 1);
			DownTmp = min(down[mid].Query(L, R), r - mid + 1);
			Chkmax(ans, min(UpTmp + DownTmp - 1, R - L + 1));
		} while(L < R && R - L + 1 > UpTmp + DownTmp - 1);
		L --;
	}

	Ans[o] = min(r - l + 1, ans);

	if(l != r) {
		Chkmax(ans, Work(flag, o << 1, l, mid));
		Chkmax(ans, Work(flag, o << 1|1, mid, r));
	}

	return ans;
}

char s[MAXN];
void Init()
{
	Readin(n);
	Readin(m);
	Readin(k);
	REP(i, 1, n) {
		REP(j, 1, m) {
			up[i].a[j] = i;
			down[i].a[j] = n - i + 1;
		}
		up[i].Init();
		down[i].Init();
	}

	REP(i, 1, n)
		REP(j, 1, m) {
			Up[i][j] = 0;
			Down[i][j] = n + 1;
		}

	REP(i, 1, n) {
		scanf("%s", s + 1);
		REP(j, 1, m)
			if(s[j] == 'X')
				Update(i, j);
	}
}

void Solve()
{
	int x, y;

	Work(0, 1, 1, n);
	REP(i, 1, k) {
		Readin(x);
		Readin(y);
		Update(x, y);
		ans = 0;
		now = x;
		printf("%d\n", Work(true, 1, 1, n));
	}
}

int main()
{
	Init();
	Solve();
}