#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <utility>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <iomanip>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
/**Classes and Structs**/
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
/**End**/
                                       /**Definitions**/
                                       const long long int mod1=1000000007;
                                       const int MAX=100005;
                                       #define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
                                       #define pb push_back
                                       #define pp pop_back
                                       #define llv vector<ll>
                                       #define iv vector<int>
                                       #define ff first
                                       #define ss second
                                       #define f(i,a,b) for(int i=a;i<b;i++)
                                       #define fr(i,a,b) for(int i=b;i>=a;i--)
                                       #define asort1(a) sort(a,a+sizeof(a)/sizeof(a[0]))
                                       #define asort2(a,c) sort(a,a+sizeof(a)/sizeof(a[0]),c)
                                       #define vsort1(v) sort(v.begin(),v.end())
                                       #define vsort2(v,c) sort(v.begin(),v.end(),c)
                                       typedef long long int ll;
                                       typedef unsigned long long int ull;
                                       typedef unordered_map<int,int,custom_hash> mii;
                                       typedef unordered_map<ll,int,custom_hash> mli;
                                       typedef unordered_map<int,ll,custom_hash> mil;
                                       typedef unordered_map<ll,ll,custom_hash> mll;
                                       typedef unordered_map<string,int,custom_hash>msi;
                                       typedef unordered_map<string,ll,custom_hash>msl;
                                       mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
                                       /**End**/
/**Custom Functions**/
ll gcd(ll a,ll b){
    ll c;
     while(b){
        c=b;
        b=a%b;
        a=c;
     }
     return a;
}
int power1(int a,int b){
     if(b==0) return 1;
     else if(b%2) return a*power1(a,b-1);
     else {
        int temp=power1(a,b/2);
        return temp*temp;
     }
}
ll power2(ll a,ll b,ll m){
     if(b==0) return 1;
     else if(b%2) return (a*power2(a,b-1,m))%m;
     else{
        ll temp=power2(a,b/2,m);
        return (temp*temp)%m;
     }
}
ll bin_a1(int a[],ll left,ll right,ll val){
     ll mid=(left+right)/2;
     if(left==right&&a[mid]!=val){return -1;}
     else if(a[mid]==val){return mid;}
     else if(a[mid]<val){return bin_a1(a,mid+1,right,val);}
     else{return bin_a1(a,left,mid-1,val);}
}
ll bin_a2(ll a[],ll left,ll right,ll val){
     ll mid=(left+right)/2;
     if(left==right&&a[mid]!=val){return -1;}
     else if(a[mid]==val){return mid;}
     else if(a[mid]<val){return bin_a2(a,mid+1,right,val);}
     else{return bin_a2(a,left,mid-1,val);}
}
ll bin_v1(vector<int>a,ll left,ll right,ll val){
     ll mid=(left+right)/2;
     if(left==right&&a[mid]!=val){return -1;}
     else if(a[mid]==val){return mid;}
     else if(a[mid]<val){return bin_v1(a,mid+1,right,val);}
     else{return bin_v1(a,left,mid-1,val);}
}
ll bin_v2(vector<ll>a,ll left,ll right,ll val){
     ll mid=(left+right)/2;
     if(left==right&&a[mid]!=val){return -1;}
     else if(a[mid]==val){return mid;}
     else if(a[mid]<val){return bin_v2(a,mid+1,right,val);}
     else{return bin_v2(a,left,mid-1,val);}
}
/**End**/
int main()
{
    fast;
    ll t=1;
    //cin>>t;
    while(t--){
        ll n;
        cin>>n;
        ll d;
        cin>>d;
        vector<ll>q[n];
        for(int i=0;i<n;i++){
for(int j=0;j<d;j++){
            ll p;
            cin>>p;
            q[i].pb(p);
        }
    }
    ll cnt=0;
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            ll ans=0;
            for(int k=0;k<d;k++){
                ans+=power1(q[j][k]-q[i][k],(ll)2);
            }

            if((ll)sqrt(ans)*(ll)sqrt(ans)==ans){
                cnt++;

            }
        }

    }
cout<<cnt<<endl;
}
}


Measured memory_bytes: 256