#include <bits/stdc++.h>
using namespace std;
int mmp[3][200001];
int n;
int ans;
char c[300001];
struct data {
  int d1, d2, d3, d4;
};
struct tree {
  int l, r;
  data d;
} t[4 * 200001];
data merge(data a, data b) {
  data s;
  s.d1 = min(500000000, min(a.d1 + b.d1, a.d2 + b.d3) + 1);
  s.d2 = min(500000000, min(a.d1 + b.d2, a.d2 + b.d4) + 1);
  s.d3 = min(500000000, min(a.d3 + b.d1, a.d4 + b.d3) + 1);
  s.d4 = min(500000000, min(a.d3 + b.d2, a.d4 + b.d4) + 1);
  return s;
}
void init(int s, int l, int r) {
  t[s].l = l, t[s].r = r;
  if (l == r) {
    t[s].d.d1 = t[s].d.d2 = t[s].d.d3 = t[s].d.d4 = 500000000;
    if (mmp[1][l]) t[s].d.d1 = 0;
    if (mmp[2][l]) t[s].d.d4 = 0;
    if (mmp[1][l] && mmp[2][l]) t[s].d.d2 = t[s].d.d3 = 1;
    return;
  }
  int m = (l + r) / 2;
  init(2 * s, l, m);
  init(2 * s + 1, m + 1, r);
  t[s].d = merge(t[2 * s].d, t[2 * s + 1].d);
}
data q(int s, int x, int y) {
  int l = t[s].l, r = t[s].r;
  if (x == l && y == r) return t[s].d;
  int m = (l + r) / 2;
  if (m >= y)
    return q(2 * s, x, y);
  else if (m < x)
    return q(2 * s + 1, x, y);
  else
    return merge(q(2 * s, x, m), q(2 * s + 1, m + 1, y));
}
void ask(int x, int y) {
  int a = (x - 1) % n + 1, b = (y - 1) % n + 1;
  if (a > b) {
    swap(x, y);
    swap(a, b);
  }
  data s = q(1, a, b);
  if (x <= n && y <= n) ans = s.d1;
  if (x <= n && y > n) ans = s.d2;
  if (x > n && y <= n) ans = s.d3;
  if (x > n && y > n) ans = s.d4;
}
int main() {
  int m;
  cin >> n >> m;
  int i, j;
  for (i = 1; i <= 2; i++) {
    scanf("%s", c);
    for (j = 1; j <= n; j++)
      if (c[j - 1] == '.') mmp[i][j] = 1;
  }
  init(1, 1, n);
  int x, y;
  for (i = 1; i <= m; i++) {
    cin >> x >> y;
    ask(x, y);
    if (ans < 500000000)
      cout << ans << endl;
    else
      cout << "-1\n";
  }
  return (0 - 0);
}
