//Name: pku_1753_Flip Game
//Author: longxiaozhi
http://hi.baidu.com/xiehuixb/blog/item/9ce25f10ee8a2e77ca80c4d1.
//Root: 和前面的pku1681一个意思,但是,测试数据加强了!这个题目需要考虑自由元!!也就是我以前的gauss的所在,
//这个问题一直困扰了我两天天。以前的题目的测试数据好像并没有考虑这一点,所以可以水果去,但是这个题目就不行啦。
//但是,还是可以用gauss的算法解决的。如果不存在自由变元,那么说明原方程组只有一组解,也就是我们要求的;
//如果存在自由变元,则说明我们求道的方程的解只是其中的一种情况,但不一定是最优的。
//一次我们还要考虑自由变元因为我们求出来的知识满足条件的一种解,并不是这里要求的最优解。
//我们要考虑自由变元的取值:
//每个自由元我们都枚举她的值(或)让后进行一次深搜就可以把自由元的情况加进去,正如xiehui博客里写的一样。
#include <iostream>
#include <string.h>
using namespace std;
#define eps 1e-10
#define fabs(x) ((x)>0?(x):-(x))
#define zero(x) (fabs(x) < eps)
const int maxn = 16;
int a[maxn][maxn+1], b[maxn][maxn+1];
int n, m, ans;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
inline int isBound(int a, int b) {
return a < 0 || a >= m || b < 0 || b >= m;
}
void pmat(int a[][maxn+1]) {
for (int i = 0, j; i < n; i++) {
for (j = 0; j < n; j++)
printf("%d ", a[i][j]);
printf("%d\n", a[i][j]);
}
}
void pans(int a[][maxn+1]) {
for (int i = 0; i < n; i++)
printf((i+1)%m ? "%d ":"%d\n", a[i][n]);
}
int gans(int a[][maxn+1]) {
int i, j, ret = a[n-1][n];
for (i = n-2; i >= 0; i--) {
for (j = i+1; j < n; j++)
a[i][n] ^= a[i][j] && a[j][n];
ret += b[i][n];
}
return ret;
}
void dfs(int p, int k) {
if (p == k) {
memcpy(b, a, sizeof(b));
int ret = gans(b);
if (ret < ans) ans = ret;
return;
}
a[p][n] = 1; dfs(p-1, k);
a[p][n] = 0; dfs(p-1, k);
}
int getRow(int p, int q, int &row) {
for (int i = p; i < n; i++)
if (!zero(a[i][q])) return a[row=i][q];
return row = 0;
}
void swapRow(int i, int row, int q) {
for (int k = q; k <= n; k++)
swap(a[i][k], a[row][k]);
}
int gauss() {
int i = 0, j = -1, k, p, q, ret, row;
while(i < n && ++j < n) {
ret = getRow(i, j, row);
if (zero(ret)) continue;
if (row != i) swapRow(i, row, j);
for (p = i + 1; p < n; p++) if (a[p][j])
for (q = j; q <= n; q++)
a[p][q] ^= a[i][q];
++i;
}pmat(a);
for (k = i; k < n; k++) if (a[k][n]) return -1;
dfs(n-1, i-1);
return ans;
}
int main() {
//freopen("in.in", "r", stdin);
int i, j, k, x, y, p, q; char s[5][5];
n = 16; m = 4;
for (i = 0; i < m; i++) {
scanf("%s", s[i]);
for (j = 0; j < m; j++) {
a[i*m+j][n] = s[i][j] == 'b';
a[i*m+j][i*m+j] = 1;
for (k = 0; k < 4; k++) {
x = i + dir[k][0];
y = j + dir[k][1];
if (isBound(x, y)) continue;
a[i*m+j][x*m+y] = 1;
}
}
}
ans = 1 << 20;
p = gauss(); // printf("p = %d\n", p);
memset(a, 0, sizeof(a));
for (i = 0; i < m; i++) {
for (j = 0; j < m; j++) {
a[i*m+j][n] = s[i][j] == 'w';
a[i*m+j][i*m+j] = 1;
for (k = 0; k < 4; k++) {
x = i + dir[k][0];
y = j + dir[k][1];
if (isBound(x, y)) continue;
a[i*m+j][x*m+y] = 1;
}
}
}
ans = 1 << 20;
q = gauss(); // printf("q = %d\n", q);
if (p == -1 && q == -1) puts("Impossible");
else if (p == -1) printf("%d\n", q);ac
else if (q == -1) printf("%d\n", p);
else printf("%d\n", p <= q ? p:q);
return 0;
}