#include <bits/stdc++.h>
using namespace std;
int n, m, inf = 0x3f3f3f30;
char mp[2][200020];
struct Node {
  int l, r;
  int val[2][2];
  Node *lt, *rt;
  Node() {}
  inline void pullup();
  inline void overflowcheck();
} nodes[400040], *root, nodes2[100010];
int mall = 0, mall2 = 0;
Node* build(int l, int r) {
  Node* res = &nodes[++mall];
  res->l = l;
  res->r = r;
  if (l == r) {
    if (mp[0][l]) {
      res->val[0][0] = inf;
    } else {
      res->val[0][0] = 0;
    }
    if (mp[1][l]) {
      res->val[1][1] = inf;
    } else {
      res->val[1][1] = 0;
    }
    if (mp[0][l] || mp[1][l]) {
      res->val[0][1] = res->val[1][0] = inf;
    } else {
      res->val[0][1] = res->val[1][0] = 1;
    }
    return res;
  }
  int mid = (l + r) >> 1;
  res->lt = build(l, mid);
  res->rt = build(mid + 1, r);
  res->pullup();
  return res;
}
inline void Node::overflowcheck() {
  val[0][0] = (val[0][0] > inf) ? inf : val[0][0];
  val[0][1] = (val[0][1] > inf) ? inf : val[0][1];
  val[1][0] = (val[1][0] > inf) ? inf : val[1][0];
  val[1][1] = (val[1][1] > inf) ? inf : val[1][1];
}
inline void Node::pullup() {
  val[0][0] =
      min(lt->val[0][0] + rt->val[0][0], lt->val[0][1] + rt->val[1][0]) + 1;
  val[0][1] =
      min(lt->val[0][0] + rt->val[0][1], lt->val[0][1] + rt->val[1][1]) + 1;
  val[1][0] =
      min(lt->val[1][0] + rt->val[0][0], lt->val[1][1] + rt->val[1][0]) + 1;
  val[1][1] =
      min(lt->val[1][0] + rt->val[0][1], lt->val[1][1] + rt->val[1][1]) + 1;
  overflowcheck();
}
inline Node* merge(Node* lt, Node* rt) {
  Node* res = &nodes2[++mall2];
  res->val[0][0] =
      min(lt->val[0][0] + rt->val[0][0], lt->val[0][1] + rt->val[1][0]) + 1;
  res->val[0][1] =
      min(lt->val[0][0] + rt->val[0][1], lt->val[0][1] + rt->val[1][1]) + 1;
  res->val[1][0] =
      min(lt->val[1][0] + rt->val[0][0], lt->val[1][1] + rt->val[1][0]) + 1;
  res->val[1][1] =
      min(lt->val[1][0] + rt->val[0][1], lt->val[1][1] + rt->val[1][1]) + 1;
  res->overflowcheck();
  return res;
}
inline Node* query(Node* r, int jl, int jr) {
  if (jl <= r->l && r->r <= jr) {
    return r;
  }
  int mid = (r->l + r->r) >> 1;
  Node* res;
  if (jl <= mid && jr > mid) {
    res = merge(query(r->lt, jl, jr), query(r->rt, jl, jr));
  } else if (jr <= mid) {
    res = query(r->lt, jl, jr);
  } else {
    res = query(r->rt, jl, jr);
  }
  return res;
}
int main() {
  scanf("%d%d\n", &n, &m);
  for (int i = 0; i < 2; i++) {
    for (int j = 1; j <= n; ++j) {
      scanf("%c", &mp[i][j]);
      if (mp[i][j] == 'X') {
        mp[i][j] = 1;
      } else {
        mp[i][j] = 0;
      }
    }
    scanf("\n");
  }
  root = build(1, n);
  for (int i = 1, u, v; i <= m; ++i) {
    mall2 = 0;
    scanf("%d%d", &u, &v);
    int in = (u - 1) / n;
    int out = (v - 1) / n;
    int jl = (u - 1) % n + 1;
    int jr = (v - 1) % n + 1;
    if (jl > jr) swap(jl, jr), swap(in, out);
    Node* res = query(root, jl, jr);
    int ress = res->val[in][out];
    if (ress >= inf)
      puts("-1");
    else
      printf("%d\n", ress);
  }
}
