#include <bits/stdc++.h>
using namespace std;
vector<string> split(const string& s, const string ®)
{ //分割函数,分离ip中的"."
vector<string> res;
string token, str = s;
size_t pos;
while((pos = str.find(reg)) != string::npos){
token = str.substr(0, pos);
res.push_back(token);
str = str.substr(pos + reg.size());
}
if(!str.empty()) res.push_back(str);
return res;
}
vector<int> getNet(vector<string> &net)
{
vector<int> res;
for(int i = 0; i < net.size(); ++i) {
res.push_back(stoi(net[i]));
}
return res;
}
bool judgeNetLegal(vector<int> &net)
{
if(net.size() != 4) return false;
if(net[0] == 0) return false;
for(int i = 0; i < 4; ++i) {
if(net[i] > 0 && net[i] < 256) continue;
return false;
}
return true;
}
string getBinaryString(int n)
{
string res = "";
while(n > 0) {
res.push_back(n % 2 + '0');
n = n / 2;
}
while(res.size() < 8) res.push_back('0');
reverse(res.begin(), res.end());
return res;
}
bool judgeMarsk(vector<int> &marsk)
{
if(marsk.size() != 4) return false;
string netBinary = "";
for(int i = 0; i < 4; ++i) {
if(marsk[i] < 0 || marsk[i] >= 256) return false;
netBinary.append(getBinaryString(marsk[i]));
}
int i = 0;
for(; i < netBinary.size(); ++i) {
if(netBinary[i] == '0') break;
}
for(; i < netBinary.size(); ++i) {
if(netBinary[i] == '1') return false;
}
return true;
}
int main() {
string marsk;
string net1;
string net2;
getline(cin, marsk);
getline(cin, net1);
getline(cin, net2);
vector<string> vsmarsk = split(marsk, ".");
vector<string> vsnet1 = split(net1, ".");
vector<string> vsnet2 = split(net2, ".");
vector<int> vimarsk = getNet(vsmarsk);
vector<int> vinet1 = getNet(vsnet1);
vector<int> vinet2 = getNet(vsnet2);
if(judgeNetLegal(vinet1) && judgeNetLegal(vinet2) && judgeMarsk(vimarsk)) {
vector<int> vi1;
vector<int> vi2;
for(int i = 0; i < 4; ++i) {
if((vimarsk[i] & vinet1[i]) == (vimarsk[i] & vinet2[i])) continue;
cout << 2;
return 0;
}
cout << 0;
return 0;
}
cout << 1;
}