// Subtasks:
// 1: AC
// _: TLE

#include <iostream>
#include <vector>

using namespace std;

#define N 1000

int n, q;
string grid[N+1];
int dist[N+1][N+1];
int seen[N+1][N+1];

int bc;
int bfs(int y1, int x1, int y2, int x2) {
    if (y1 == y2 && x1 == x2) return 0;
    bc++;
    vector<pair<int,int>> queue;
    queue.push_back({y1,x1});
    dist[y1][x1] = 0;
    seen[y1][x1] = bc;
    int dy[4] = {0, 0, 1, -1};
    int dx[4] = {1, -1, 0, 0};
    for (int i = 0; i < queue.size(); i++) {
        int cy = queue[i].first;
        int cx = queue[i].second;
        for (int j = 0; j < 4; j++) {
            int uy = cy + dy[j];
            int ux = cx + dx[j];
            if (grid[uy][ux] == '#' && seen[uy][ux] != bc) {
                seen[uy][ux] = bc;
                dist[uy][ux] = dist[cy][cx] + 1;
                if (uy == y2 && ux == x2) {
                    return dist[uy][ux];
                }
                queue.push_back({uy, ux});
            }
        }
    }
    return -1;
}

int main() {
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> grid[i];
        grid[i] = '.' + grid[i];
    }
    for (int i = 1; i <= q; i++) {
        int y1, x1, y2, x2;
        cin >> y1 >> x1 >> y2 >> x2;
        cout << bfs(y1, x1, y2, x2) << "\n";
    }
}
