#include <bits/stdc++.h>   using namespace std;   const int mx = 1e9;   struct Data {     int p1, p2, p3, p4;     Data(int a = mx, int b = mx, int c = mx, int d = mx) {       p1 = a, p2 = b, p3 = c, p4 = d;     }   };   inline Data UN(Data a, Data b) {     Data c;     c.p1 = min(a.p1 + b.p1, a.p2 + b.p3), c.p2 = min(a.p1 + b.p2, a.p2 + b.p4);     c.p3 = min(a.p3 + b.p1, a.p4 + b.p3), c.p4 = min(a.p3 + b.p2, a.p4 + b.p4);     c.p1 = min(c.p1, mx), c.p2 = min(c.p2, mx), c.p3 = min(c.p3, mx),     c.p4 = min(c.p4, mx);     return c;   }   struct node {     int l, r;     Data s;   } T[200010 << 2];   char G[3][200010];   void build(int rt, int l, int r) {     T[rt].l = l, T[rt].r = r;     int mid = (l + r) >> 1;     if (l == r) {       if (G[1][l] ==  . ) T[rt].s.p1 = 1;       if (G[2][l] ==  . ) T[rt].s.p4 = 1;       if (G[1][l] ==  .  && G[2][l] ==  . ) T[rt].s.p2 = T[rt].s.p3 = 2;       return;     }     build(rt << 1, l, mid), build(rt << 1 | 1, mid + 1, r);     T[rt].s = UN(T[rt << 1].s, T[rt << 1 | 1].s);   }   Data query(int rt, int start, int end) {     int l = T[rt].l, r = T[rt].r, mid = (l + r) >> 1;     if (start <= l && r <= end) return T[rt].s;     if (end <= mid) return query(rt << 1, start, end);     if (start > mid) return query(rt << 1 | 1, start, end);     return UN(query(rt << 1, start, end), query(rt << 1 | 1, start, end));   }   int main() {     int n, q;     scanf( %d%d , &n, &q);     scanf( %s%s , G[1] + 1, G[2] + 1);     build(1, 1, n);     while (q--) {       int a, b;       scanf( %d%d , &a, &b);       int l = a > n ? a - n : a, r = b > n ? b - n : b, res;       if (l > r) swap(l, r), swap(a, b);       Data tmp = query(1, l, r);       if (a <= n && b <= n) res = tmp.p1;       if (a <= n && b > n) res = tmp.p2;       if (a > n && b <= n) res = tmp.p3;       if (a > n && b > n) res = tmp.p4;       if (res < 1e8)         printf( %d n , res - 1);       else         printf( -1 n );     }     return 0;   }   