#include <bits/stdc++.h>
using namespace std;
struct wf {
  int l1, l2, k1, k2;
};
struct tree {
  int l, r;
  wf w;
} tree[200005 << 2];
int n, m, x, y, X, Y, que;
char s1[200005], s2[200005];
wf pushup(wf w1, wf w2) {
  wf p;
  p.l1 = min(w1.l1 + w2.l1, w1.k1 + w2.k2) + 1;
  p.l1 = min(p.l1, 99999999);
  p.l2 = min(w1.l2 + w2.l2, w1.k2 + w2.k1) + 1;
  p.l2 = min(p.l2, 99999999);
  p.k1 = min(w1.l1 + w2.k1, w1.k1 + w2.l2) + 1;
  p.k1 = min(p.k1, 99999999);
  p.k2 = min(w1.l2 + w2.k2, w1.k2 + w2.l1) + 1;
  p.k2 = min(p.k2, 99999999);
  return p;
}
void build(int l, int r, int root) {
  tree[root].l = l;
  tree[root].r = r;
  if (l == r) {
    tree[root].w.l1 = tree[root].w.k1 = tree[root].w.k2 = tree[root].w.l2 =
        99999999;
    if (s1[l] == '.') tree[root].w.l1 = 0;
    if (s2[l] == '.') tree[root].w.l2 = 0;
    if (s1[l] == '.' && s2[l] == '.') tree[root].w.k1 = tree[root].w.k2 = 1;
    return;
  }
  build(l, l + r >> 1, root << 1);
  build((l + r >> 1) + 1, r, root << 1 | 1);
  tree[root].w = pushup(tree[root << 1].w, tree[root << 1 | 1].w);
}
wf ask(int l, int r, int root) {
  if (l == tree[root].l && r == tree[root].r) return tree[root].w;
  int mid = tree[root].l + tree[root].r >> 1;
  if (mid >= r)
    return ask(l, r, root << 1);
  else if (mid < l)
    return ask(l, r, root << 1 | 1);
  else
    return pushup(ask(l, mid, root << 1), ask(mid + 1, r, root << 1 | 1));
}
int main() {
  scanf("%d%d", &n, &m);
  scanf("%s", s1 + 1);
  scanf("%s", s2 + 1);
  build(1, n, 1);
  int Q;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &x, &y);
    X = (x - 1) % n + 1;
    Y = (y - 1) % n + 1;
    if (X > Y) {
      swap(X, Y);
      swap(x, y);
    }
    wf ans = ask(X, Y, 1);
    if (x <= n && y <= n) Q = ans.l1;
    if (x <= n && y > n) Q = ans.k1;
    if (x > n && y > n) Q = ans.l2;
    if (x > n && y <= n) Q = ans.k2;
    if (Q >= 99999999)
      printf("-1\n");
    else
      printf("%d\n", Q);
  }
  return 0;
}
