#include <bits/stdc++.h>
using namespace std;
const int maxCol = 200010;
const int maxID = 400010;
const int INF = 400010;
typedef struct RangeInfo {
  int dist[2][2];
  int L;
  int R;
  RangeInfo() { L = R = -1; }
  RangeInfo(int idx, const vector<vector<bool> >& isEmpty) {
    L = R = idx;
    dist[0][0] = isEmpty[0][idx] ? 0 : INF;
    dist[1][1] = isEmpty[1][idx] ? 0 : INF;
    dist[0][1] = dist[1][0] = (isEmpty[0][idx] && isEmpty[1][idx]) ? 1 : INF;
  }
  bool operator==(RangeInfo other) { return L == other.L && R == other.R; }
} RangeInfo;
class SegmentTree {
 private:
  vector<RangeInfo> segTree;
  vector<vector<bool> > isEmpty;
  int N;
  RangeInfo nullRange;
  int getLeft(int idx) { return idx << 1; }
  int getRight(int idx) { return (idx << 1) + 1; }
  RangeInfo merge(const RangeInfo& left, const RangeInfo& right) {
    RangeInfo result;
    result.L = left.L;
    result.R = right.R;
    for (int startRow = 0; startRow < 2; startRow++) {
      for (int endRow = 0; endRow < 2; endRow++) {
        result.dist[startRow][endRow] = INF;
        for (int midRow = 0; midRow < 2; midRow++) {
          result.dist[startRow][endRow] =
              min(result.dist[startRow][endRow],
                  left.dist[startRow][midRow] + 1 + right.dist[midRow][endRow]);
        }
      }
    }
    return result;
  }
  void build(int idx, int L, int R) {
    if (L == R) {
      RangeInfo singleRange(L, isEmpty);
      segTree[idx] = singleRange;
    } else {
      build(getLeft(idx), L, (L + R) / 2);
      build(getRight(idx), (L + R) / 2 + 1, R);
      RangeInfo left = segTree[getLeft(idx)], right = segTree[getRight(idx)];
      segTree[idx] = merge(left, right);
    }
  }
  RangeInfo rmq(const int& idx, const int& targetL, const int& targetR) {
    int curL = segTree[idx].L;
    int curR = segTree[idx].R;
    if (targetR < curL || curR < targetL) return nullRange;
    if (targetL <= curL && curR <= targetR) return segTree[idx];
    RangeInfo left = rmq(getLeft(idx), targetL, targetR);
    RangeInfo right = rmq(getRight(idx), targetL, targetR);
    if (left == nullRange) return right;
    if (right == nullRange) return left;
    RangeInfo result = merge(left, right);
    return result;
  }

 public:
  SegmentTree(const vector<vector<bool> >& _isEmpty) {
    isEmpty = _isEmpty;
    N = isEmpty[0].size();
    segTree.resize(8 * N);
    build(1, 0, N - 1);
  }
  RangeInfo rmq(const int& targetL, const int& targetR) {
    return rmq(1, targetL, targetR);
  }
};
typedef struct Coord {
  int row, col;
  Coord(int& id, const int& N) {
    id--;
    row = id / N;
    col = id % N;
  }
} Coord;
int main() {
  int N, M;
  cin >> N >> M;
  vector<vector<bool> > isEmpty(2, vector<bool>(N, false));
  char cur;
  for (int r = 0; r < 2; r++) {
    for (int c = 0; c < N; c++) {
      cin >> cur;
      isEmpty[r][c] = cur == '.';
    }
  }
  SegmentTree segTree(isEmpty);
  int sourceId, targetId;
  for (int i = 0; i < M; i++) {
    cin >> sourceId >> targetId;
    Coord left(sourceId, N);
    Coord right(targetId, N);
    if (left.col > right.col) {
      swap(left, right);
    }
    RangeInfo result = segTree.rmq(left.col, right.col);
    int shortestCost = result.dist[left.row][right.row];
    cout << (shortestCost == INF ? -1 : shortestCost) << endl;
  }
  return 0;
}
