#include <bits/stdc++.h>
using namespace std;
const int P = 1e9 + 7, INF = 0x3f3f3f3f;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
long long qpow(long long a, long long n) {
  long long r = 1 % P;
  for (a %= P; n; a = a * a % P, n >>= 1)
    if (n & 1) r = r * a % P;
  return r;
}
long long inv(long long first) {
  return first <= 1 ? 1 : inv(P % first) * (P - P / first) % P;
}
const int N = 2e5 + 10;
int n, m;
char s[2][N];
struct Mat {
  int v[2][2];
  Mat() { memset(v, 0x3f, sizeof v); }
  Mat operator*(const Mat &rhs) {
    Mat r;
    for (int k = 0; k <= 1; ++k)
      for (int i = 0; i <= 1; ++i)
        for (int j = 0; j <= 1; ++j) {
          r.v[i][j] = min(r.v[i][j], v[i][k] + rhs.v[k][j] + 1);
        }
    return r;
  }
} tr[N << 2];
Mat build(int o, int l, int r) {
  if (l == r) {
    for (int i = 0; i <= 1; ++i)
      if (s[i][l] == '.') {
        for (int j = 0; j <= 1; ++j)
          if (s[j][l] == '.') {
            tr[o].v[i][j] = min(tr[o].v[i][j], abs(i - j));
          }
      }
    return tr[o];
  }
  return tr[o] = build((o << 1), l, ((l + r) >> 1)) *
                 build(((o << 1) | 1), ((l + r) >> 1) + 1, r);
}
Mat query(int o, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr) return tr[o];
  if (((l + r) >> 1) >= qr) return query((o << 1), l, ((l + r) >> 1), ql, qr);
  if (((l + r) >> 1) < ql)
    return query(((o << 1) | 1), ((l + r) >> 1) + 1, r, ql, qr);
  return query((o << 1), l, ((l + r) >> 1), ql, qr) *
         query(((o << 1) | 1), ((l + r) >> 1) + 1, r, ql, qr);
}
int main() {
  scanf("%d%d%s%s", &n, &m, s[0] + 1, s[1] + 1);
  build(1, 1, n);
  for (int i = 1; i <= m; ++i) {
    int first, fx = 0, second, fy = 0;
    scanf("%d%d", &first, &second);
    if (first > n) fx = 1, first -= n;
    if (second > n) fy = 1, second -= n;
    if (first > second) swap(first, second), swap(fx, fy);
    int ans = query(1, 1, n, first, second).v[fx][fy];
    printf("%d\n", ans == INF ? -1 : ans);
  }
}
