#include <bits/stdc++.h>
#include <unordered_set>
using namespace std;
ifstream fin("pirati.in");
ofstream fout("pirati.out");
int n, m, q, c, k;
char s[1005][1005];
int viz[1005][1005];
int dx[] = { 0, 0, 1, 1, 1, -1, -1, -1 };
int dy[] = { 1, -1, -1, 0, 1, -1, 0, 1 };
int e[1000005], niv[1000005], poz[100005], rmq[21][1000005], p2[1000005];
unordered_set <int> a[100005];
bool OK(int i, int j)
{
return (1 <= i and i <= n and 1 <= j and j <= m);
}
void Fill(int x, int y, int col)
{
int i, j;
viz[x][y] = col;
for (int dir = 0; dir <= 7; dir++)
{
i = x + dx[dir];
j = y + dy[dir];
if (OK(i, j))
{
if (viz[i][j] == 0 and s[i][j] == s[x][y])
Fill(i, j, col);
else if (s[i][j] != s[x][y] and viz[i][j])
{
a[viz[i][j]].insert(viz[x][y]);
a[viz[x][y]].insert(viz[i][j]);
}
}
}
}
void Dfs(int x, int lvl, int last)
{
e[++k] = x;
niv[k] = lvl;
poz[x] = k;
for (auto w : a[x])
if (w != last)
{
Dfs(w, lvl + 1, x);
e[++k] = x;
niv[k] = lvl;
poz[x] = k;
}
}
int Query(int i, int j)
{
i = poz[i];
j = poz[j];
if (i > j)
swap(i, j);
int lg = p2[j - i + 1];
//cout << lg << "*";
//cout << rmq[lg][i] << " " << rmq[lg][j - (1 << lg) + 1] << " ";
if (niv[rmq[lg][i]] < niv[rmq[lg][j - (1 << lg) + 1]])
return e[rmq[lg][i]];
return e[rmq[lg][j - (1 << lg) + 1]];
}
int main()
{
int i, j, x1, y1, x2, y2;
fin >> n >> m >> q;
for (i = 1; i <= n; i++)
fin >> (s[i] + 1);
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
if (viz[i][j] == 0)
{
c++;
Fill(i, j, c);
}
Dfs(1, 1, 0);
p2[1] = 0;
for (i = 2; i <= k; i++)
p2[i] = 1 + p2[i / 2];
for (i = 1; i <= k; i++)
rmq[0][i] = i;
for (i = 1; i <= p2[k]; i++)
for (j = 1; j <= k - (1 << i) + 1; j++)
{
rmq[i][j] = rmq[i - 1][j];
if (niv[rmq[i - 1][j]] > niv[rmq[i - 1][j + (1 << (i - 1))]])
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
while (q--)
{
fin >> x1 >> y1 >> x2 >> y2;
i = viz[x1][y1];
j = viz[x2][y2];
fout << (niv[i] + niv[j]) / 2 - niv[Query(i, j)] << "\n";
}
return 0;
}