Go: package main

import (
	"bufio"
	"os"
	"strings"
	"strconv"
	"fmt"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	d := 0
	e := 0
	for scanner.Scan() {
		info := strings.Split(scanner.Text(), ",")
		a, _ := strconv.Atoi(info[0])
		b, _ := strconv.Atoi(info[1])
		c, _ := strconv.Atoi(info[2])
		if a*a + b*b == c*c {
			d++
		}
		if a == b {
			e++
		}
	}
	fmt.Println(d)
	fmt.Println(e)
}

C++: #define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<random>
#include<functional>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<bitset>
#include<unordered_map>
#include<climits>
#include<fstream>
using namespace std;
///////////////////library zone!!!!!!!!!!!!!!!!!!!!!!!!!!!!
typedef long long ll;
typedef long double ld;
#define all(a) (a).begin(),(a).end()
#define EPS (1e-7)
const ll Mod = 1000000007;
const ll mod = 998244353;
struct H {
	ll x, y;
	bool operator<(const H &b) const {
		if (x != b.x) return x < b.x;
		return y < b.y;
	}
	bool operator>(const H &b) const {
		if (x != b.x) return x > b.x;
		return y > b.y;
	}
	bool operator==(const H &b) const { return x == b.x&&y == b.y; }
	bool operator!=(const H &b) const { return (*this) != b; }
};
struct P {
	ll pos, cost;
	bool operator<(const P &b) const { return cost < b.cost; }
	bool operator>(const P &b) const { return cost > b.cost; }
};
struct B {
	ll to, cost;
};
struct E {
	ll from, to, cost;
	bool operator<(const E &b) const { return cost < b.cost; }
	bool operator>(const E &b) const { return cost > b.cost; }
};
template<typename T, typename U>
void chmin(T &a, U b) {
	if (a > b) a = b;
}
template<typename T, typename U>
void chmax(T &a, U b) {
	if (a < b) a = b;
}
template<typename T>
T max_0(T a) {
	if (a < 0) return 0;
	return a;
}
template<typename T>
T min_0(T a) {
	if (a > 0) return 0;
	return a;
}
ll read() {
	ll u;
	ll k = scanf("%lld", &u);
	return u;
}
ll gcd(ll i, ll j) {
	if (i > j) swap(i, j);
	if (i == 0) return j;
	return gcd(j%i, i);
}
ll mod_pow(ll x, ll n, ll p) {
	ll res = 1;
	while (n > 0) {
		if (n & 1) res = res * x % p;
		x = x * x % p;
		n >>= 1;
	}
	return res;
}//x^n%p
vector<string>split(string s, char c = ' ') {
	vector<string>vec;
	string h = "";
	for (int i = 0; i < s.size();) {
		int j = i;
		while (j < s.size() && s[j] != ' ') {
			h += s[j++];
		}
		if (h.size() > 0) vec.push_back(h);
		h = "";
		i = j + 1;
	}
	return vec;
}
template<typename T>
void print_vec(vector<T>a) {
	for (int i = 0; i < a.size(); i++) {
		cout << (i == 0 ? "" : " ") << a[i];
	}
	cout << endl;
}
const ll Inf = 3023372036854775807;
const int inf = 1500000000;
#define int long long
//----------------------------------------------------
class Vec2 {
public:
	ld x, y;
	Vec2() { x = 0, y = 0; }
	Vec2(ld x, ld y) :x(x), y(y) {}
	ld length() {
		return sqrt(x*x + y * y);
	}
	Vec2 normal() {
		ld len = this->length();
		if (len == 0) return Vec2(x, y);
		x /= len, y /= len;
		return *(this);
	}
	Vec2 operator+(Vec2 vec) {
		return Vec2(x + vec.x, y + vec.y);
	}
	Vec2 operator-(Vec2 vec) {
		return Vec2(x - vec.x, y - vec.y);
	}
	template<typename T>
	Vec2 operator*(T cons) {
		return Vec2(x*cons, y*cons);
	}
	ld operator*(Vec2 vec) {
		return x * vec.x + y * vec.y;
	}
	ld operator%(Vec2 vec) {
		return x * vec.y - y * vec.x;
	}
	bool operator==(Vec2 vec) {
		return abs(x - vec.x) < EPS && abs(y - vec.y) < EPS;
	}
};
ld dot(Vec2 a, Vec2 b) {
	return a.x*b.x + a.y*b.y;
}
ld cross(Vec2 a, Vec2 b) {
	return a.x*b.y - a.y*b.x;
}
ld areaIntegral(Vec2 a, Vec2 b) {
	return abs(a.x*b.y - a.y*b.x) / 2.0;
}
class Vec3 {
public:
	ld x, y, z;
	Vec3() { x = 0, y = 0, z = 0; }
	Vec3(ld x, ld y, ld z) :x(x), y(y), z(z) {}
	ld length() {
		return sqrt(x*x + y * y + z * z);
	}
	void normal() {
		ld len = this->length();
		if (len == 0) return;
		x /= len, y /= len, z /= len;
	}
	Vec3 operator+(Vec3 vec) {
		return Vec3(x + vec.x, y + vec.y, z + vec.z);
	}
	Vec3 operator-(Vec3 vec) {
		return Vec3(x - vec.x, y - vec.y, z - vec.z);
	}
	Vec3 operator*(int cons) {
		return Vec3(x*cons, y*cons, z*cons);
	}
	ld operator*(Vec3 vec) {
		return x * vec.x + y * vec.y + z * vec.z;
	}
};
ld dot(Vec3 a, Vec3 b) {
	return a.x*b.x + a.y*b.y + a.z*b.z;
}
class Line {
public:
	Vec2 from, to;
	Line(Vec2 from, Vec2 to) :from(from), to(to) {}
};
Line getPerpendicularBisector(Line line) {
	int cx = (line.from.x + line.to.x) / 2, cy = (line.from.y + line.to.y) / 2;
	Vec2 p = Vec2(cx + (line.from.y - line.to.y), cy + (line.to.x - line.from.x));
	return Line(Vec2(cx, cy), p);
}
signed main() {
	int a, b, c;
	int ans = 0, sum = 0;
	while (~scanf("%lld,%lld,%lld", &a, &b, &c)) {
		if (a*a + b * b == c * c) {
			ans++;
		}
		if (a == b) {
			sum++;
		}
	}
	cout << ans << endl << sum << endl;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int main(){
	int a, b, c, x=0, y=0;
	while( scanf(" %d,%d,%d", &a, &b, &c) != EOF ){
		
		if(c*c == a*a+b*b) ++x;
		else if(a==b) ++y;
	
	}
	
	printf("%d\n%d\n", x, y);

	return 0;
}

C++: #include<iostream>
#include<cstdio>
using namespace std;
int main(){
  int a,b,c,x=0,y=0;
  while(scanf("%d,%d,%d",&a,&b,&c)!=EOF){
    if(a == b) x++;
    else if(a*a+b*b == c*c) y++;
  }
  cout <<y<<endl<<x<<endl;
  return 0;
}

C++:  
 #include<iostream>
 #include<stdio.h>
 #include<string>
 #include<math.h>
 #include<iomanip>
 #include<algorithm>
 #include<string.h>
 #include<cctype>
 #include<map>
 #include<set>
 #include<vector>
 #include<sstream>
 #include<stack>
 #include<queue>
 
 using namespace std;
  
 int main()
 {
   int a,b,c;
   int arr[100005][3];
   int count1=0;
   int count2=0;
   int count=0;
   char temp,temp1;
   bool flag;
   while(cin>>a>>temp>>b>>temp1>>c)
   {
     if(a*a+b*b==c*c) count1++;
     else if(a==b) count2++;                              
   }
   cout<<count1<<endl;
   cout<<count2<<endl;  
   //while(1);     
   return 0;  
 }

C++: #define scanf_s scanf
//#define gets_s gets
#include <stdio.h>
#include <string>
#include <iostream>
#include <math.h>
using namespace std;
#define MAX 10
#define MIN -100001
#define _MAX 10
int main(void)
{
	int a, b, c, s = 0, h = 0;
	while (scanf_s("%d,%d,%d", &a, &b, &c) != EOF) {
		if (a == b) ++h;
		else ++s;
	}
	printf("%d\n%d\n", s, h);
}

C++: #include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
bool slove(int a, int b, int c){ 
		if(a==b) return true;
		if(c*c == a*a + b*b) return true;
	return false;
}
int main(){
	int a,b,c,con_h=0,con_t=0;
	vector<int> n;
	bool flag;
	while(scanf("%d,%d,%d",&a,&b,&c) != EOF){
		n.clear();
		n.push_back(a); n.push_back(b); n.push_back(c);
		vector<int>::iterator it = n.begin();
		flag = slove(*it,*(it+1),0); 
		if(flag == true)
			con_h++;
		else{
			flag = slove(*it,*(it+1),*(it+2)); 
			if(flag == true)
				con_t++;
		}
	}
	cout << con_t << endl << con_h << endl;
}

C++: #include<iostream>
int main()
{
	int cnt[2] = { 0,0 };
	while (true)
	{
		int a, b, c;
		char foo;
		std::cin >> a >> foo >> b >> foo >> c;
		if (std::cin.eof())
		{
			break;
		}
		if (c == hypot(a, b))
		{
			cnt[0]++;
		}
		else if (a == b)
		{
			cnt[1]++;
		}
	}
	std::cout << cnt[0] << std::endl;
	std::cout << cnt[1] << std::endl;
	return 0;
}

C++: #include <cstdio>

using namespace std;

int main() {
	int side[3];
	int iso=0, cho=0;
	while(scanf("%d,%d,%d",&side[0],&side[1],&side[2])){
		if(side[0]==side[1]) iso++;
		else if( (side[0]*side[0]) + (side[1]*side[1]) == (side[2]*side[2]) ) cho++;
	}
	printf("%d\n", cho);
	printf("%d\n", iso);
	return 0;
}