///-----Bismillahir Rahmanir Rahim-----///

#include<bits/stdc++.h>
using namespace std;

///---FAST I/O---///
#define Boost() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

///---DATA TYPE---///
typedef long long ll;
typedef long long int lli;
///vector
typedef vector<int> vi;
typedef vector<ll> vl;
///pair
typedef pair<int,int> pii;
typedef pair<double, double> pdd;
typedef pair<ll, ll> pll;

///---LOOP---///
#define rep0(i,n) for(i=0;i<n;i++)
#define rep1(i,n) for(i=1;i<=n;i++)

///---I/O---///
#define sf scanf
#define pf printf

///---OTHERS---///
#define pb push_back
#define all(c)		c.begin(),c.end()
#define MK make_pair
#define F first
#define S second
#define endl '\n'

///---INITIALIZATION---//
#define mem(a,b) memset(a, b, sizeof(a) )

///---CALCULATE---///
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) (a*(b/gcd(a,b)))
#define sqr(a) ((a) * (a))

///---BIT OPERATION---///
inline bool checkBit(ll n, int i) { return n&(1LL<<i); }
inline ll setBit(ll n, int i) { return n|(1LL<<i);; }
inline ll resetBit(ll n, int i) { return n&(~(1LL<<i)); }

///---CONSTANT---///
const double PI = acos(-1);
const double eps = 1e-9;
const int inf = 2000000000;
const ll infLL = 9000000000000000000;
#define MOD 1000000007

int main()
{
    Boost();

    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
        int n,candyBag;
        cin>>n;
        candyBag=n*n;
        for(int i=1;i<=n;i++)
        {
           cout<<i<<" "<<candyBag--<<endl;
        }

    }
    return 0;
}


///-----Bismillahir Rahmanir Rahim-----///

#include<bits/stdc++.h>
using namespace std;

///---FAST I/O---///
#define Boost() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

///---DATA TYPE---///
typedef long long ll;
typedef long long int lli;
///vector
typedef vector<int> vi;
typedef vector<ll> vl;
///pair
typedef pair<int,int> pii;
typedef pair<double, double> pdd;
typedef pair<ll, ll> pll;

///---LOOP---///
#define rep0(i,n) for(i=0;i<n;i++)
#define rep1(i,n) for(i=1;i<=n;i++)

///---I/O---///
#define sf scanf
#define pf printf

///---OTHERS---///
#define pb push_back
#define all(c)		c.begin(),c.end()
#define MK make_pair
#define F first
#define S second
#define endl '\n'

///---INITIALIZATION---//
#define mem(a,b) memset(a, b, sizeof(a) )

///---CALCULATE---///
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) (a*(b/gcd(a,b)))
#define sqr(a) ((a) * (a))

///---BIT OPERATION---///
inline bool checkBit(ll n, int i)
{
    return n&(1LL<<i);
}
inline ll setBit(ll n, int i)
{
    return n|(1LL<<i);;
}
inline ll resetBit(ll n, int i)
{
    return n&(~(1LL<<i));
}

///---CONSTANT---///
const double PI = acos(-1);
const double eps = 1e-9;
const int inf = 2000000000;
const ll infLL = 9000000000000000000;
#define MOD 1000000007

int main()
{
    Boost();

    int t;
    t=1;
    //cin>>t;
    while(t--)
    {
        int n,last,first,ekjonPai;
        cin>>n;
        ekjonPai=n/2;
        last=n*n;
        first=1;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=ekjonPai; j++)
            {
                if(j==ekjonPai)cout<<first++<<" "<<last--<<endl;
                else cout<<first++<<" "<<last--<<" ";
            }
        }

    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
 int n;
 cin>>n;
 int arr1[n],arr2[n];
 for(int i=0;i<n;i++)
  arr1[i]=i+1;
 for(int i=n*n,j=0;i>n && j<n;i--,j++)
  arr2[j]=i;
 for(int i=0;i<n;i++)
 {
  cout<<arr1[i]<<" "<<arr2[i];
  if(i<n-1)
   cout<<'\n';
 }
 return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
 int n;
 cin>>n;
 int arr[n][n];
 int a=1;
 int b=n*n;
 for(int i=0;i<n;i++)
 {
  for(int j=0;j<n;j++)
  {
   if(j<n/2)
   {
   	arr[i][j]=a;
   	a++;
   }
   else
   {
   	arr[i][j]=b;
   	b--;
   }
  }
}
 for(int i=0;i<n;i++)
 {
  if(i!=0)
   cout<<'\n';
  for(int j=0;j<n;j++)
  {
   cout<<arr[i][j];
   if(j<n-1)
    cout<<" ";
  }
 }
 return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main()
{
 int n;
 cin>>n;
 int arr[n][n];
 int temp=n+1;
 int k=1;
 for(int i=0;i<n;i++)
 {
  int add=0;
  for(int j=0;j<n;j++)
  {
   if(j==0)
    arr[i][j]=i+1;
   else
    arr[i][j]=k+add;
   add+=temp;
  }
  k--;
 }
 for(int i=0;i<n;i++)
 {
  if(i!=0)
   cout<<'\n';
  for(int j=0;j<n;j++)
  {
   cout<<arr[i][j];
   if(j<n-1)
    cout<<" ";
  }
 }
 return 0;
}


//Solution By SlavicG
#include <bits/stdc++.h>
using namespace std;

#define ll                          long long

#define forn(i,n)                   for(int i=0;i<n;i++)
#define all(v)                      v.begin(), v.end()
#define rall(v)                     v.rbegin(),v.rend()

#define pb                          push_back
#define sz(a)                       (int)a.size()

#define   endl                       "\n"
#define fastio                       ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

int  main()
{
	int n;
	cin >> n;
	vector<int> v[n];
	for(int i =  1;i<= n ;i++)
	{
		v[i-1].pb(i);
		v[i-1].pb( n * n - (i-1));
	}
	for(int i = 0;i<n;i++)
	{
		for(auto u : v[i])
		{
			cout << u << " ";
		}
		cout << endl;
	}
}


//Solution By SlavicG
#include <bits/stdc++.h>
using namespace std;

#define ll                          long long

#define forn(i,n)                   for(int i=0;i<n;i++)
#define all(v)                      v.begin(), v.end()
#define rall(v)                     v.rbegin(),v.rend()

#define pb                          push_back
#define sz(a)                       (int)a.size()

#define   endl                       "\n"
#define fastio                       ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

int  main()
{
	int n;
	cin >> n;
	for(int i =  1;i<=(n*n) / 2 ;i++)
	{
		cout << i << " " << ((n*n+1) - i);
		if(i%(n/2)==0)
			cout << endl;
	}
}


//Solution By SlavicG
#include <bits/stdc++.h>
using namespace std;

#define ll                          long long

#define forn(i,n)                   for(int i=0;i<n;i++)
#define all(v)                      v.begin(), v.end()
#define rall(v)                     v.rbegin(),v.rend()

#define pb                          push_back
#define sz(a)                       (int)a.size()

#define   endl                       "\n"
#define fastio                       ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);

int  main()
{
	int n;
	cin >> n;
	for(int i =  1;i<=(n*n) / 2 ;i++)
	{
		cout << i << " " << ((n*n+1) - i) << " ";
		if(i%(n/2)==0)
			cout << endl;
	}
}


#include<bits/stdc++.h>
using namespace std;
int n,i,k,j=1;
main(){
    for(cin>>n;i<n;i++,cout<<endl){
        k=n/2;
        while(k--)cout<<j<<" "<<n*n+1-j<<" ",j++;
    }
}


#include<bits/stdc++.h>
using namespace std;
int n,i=1;
main(){
    for(cin>>n;i<=n;i++)cout<<i<<" "<<n*n+1-i<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int n,i;
int main(){
    for(cin>>n;i<n*n/2;i++)cout<<i+1<<" "<<n*n-i<<endl;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,a,i,s=0,c=0,d=0;
    cin>>n;
    a=n*n;
    for(i=1;i<=(n*n)/2;i++)
    {
        cout<<i<<" "<<a<<endl;
        a--;
    }

}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
   int a=n*n;
    int b=1;
    for(int i=1;i<=n*2;i++)
    {
        cout<<i<<" "<<a<<" ";
        a--;
        if(b==n/2){cout<<endl;b=0;}
        b++;
    }
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,a,i,s=0,c=0,d=0;
    cin>>n;
    a=n*n;
    for(i=1;i<=n;i++)
    {
        cout<<i<<" "<<a<<endl;
        a--;
    }

}


#include<bits/stdc++.h>
using namespace std;
  int main()
  {
      int n,i=1;
      std::cin >> n;
      for(int j=1;j<=n;j++)
      {
          i=j;
          while(i<=n*n)
         {
             cout<<i;
             if(i%n==0)
            i+=1;
            else
             i+=n+1;
         }
           std::cout <<  << std::endl;     }
     return 0;
 }


#include<cstdio>
  int main()
  {
      int n,i=1;
      std::cin >> n;
      for(int j=1;j<=n;j++)
      {
          i=j;
          while(i<=n*n)
         {
             cout<<i;
             if(i%n==0)
            i+=1;
            else
             i+=n+1;
         }
           std::cout <<  << std::endl;     }
     return 0;
 }


#include<bits/stdc++.h>
using namespace std;
  int main()
  {
      int n,i=1;
      std::cin >> n;
      for(int j=1;j<=n;j++)
      {
          i=j;
          while(i<=n*n)
         {
             cout<<i<<" ";
             if(i%n==0)
            i+=1;
            else
             i+=n+1;
         }
           cout<<endl;
         }
     return 0;
 }


#include<bits/stdc++.h>
using namespace std;
  int main()
  {
      int n,i=1;
      std::cin >> n;
      for(int j=1;j<=n;j++)
      {
          i=j;
          while(i<=n*n)
         {
             cout<<i;
             if(i%n==0)
            i+=1;
            else
             i+=n+1;
         }
           cout<<endl;
         }
     return 0;
 }


#include<bits/stdc++.h>

using namespace std;

int main()
{
    int c,m,n,i,j;
    cin>>c;
    m=c*c;
    n=m-c;

    for(i=1,j=m;i<c,j>n;i++,j--)
    {
        cout<<i<<" "<<j<<endl;
    }

}


#include<bits/stdc++.h>

using namespace std;

int main()
{
    long long c,m,n,i,j;
    cin>>c;
    m=c*c;

    for(i=1,j=m; i<m/2,j>m/2; i++,j--)
    {
        if(i+j==m+1)
        {
            cout<<i<<" "<<j<<endl;
        }
    }

}


#include<bits/stdc++.h>

using namespace std;

int main()
{
    int c,m,n,i,j;
    cin>>c;
    m=c*c;
    cout<<m<<endl;
    n=m-c;

    for(i=1,j=m;i<c,j>n;i++,j--)
    {
        cout<<i<<" "<<j<<endl;
    }

}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    cin.tie(0); ios_base::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i=1;i<=n*n/2;i+=n/2){
        for(int j=i;j<i+n/2;j++){
            cout << j << ' ' << n*n-j+1 << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    cin.tie(0); ios_base::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i=1;i<=n;i++){
        cout << i << ' ' << 2*n+1-i << '\n';
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
    cin.tie(0); ios_base::sync_with_stdio(0);
    int n;
    cin >> n;
    for(int i=1;i<=n;i+=n/2){
        for(int j=i;j<i+n/2;j++){
            cout << j << ' ' << n*n-j+1 << ' ';
        }
        cout << '\n';
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    ll n;
    cin>>n;
    ll m=n*n;
    for(int i=1; i<=m/2; i++){
        if(i%2==1) cout<<i<<" ";
    }
    for(int i=m/2+1; i<=m; i++){
        if(i%2==0) cout<<i<<" ";
    }
    cout<<endl;
    for(int i=1; i<=m/2; i++){
        if(i%2==0) cout<<i<<" ";
    }
    for(int i=m/2; i<=m; i++){
        if(i%2==1) cout<<i<<" ";
    }
    cout<<endl;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    ll t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        ll m=n*n;
        for(int i=1; i<=m/2; i++){
            if(i%2==1) cout<<i<<" ";
        }
        for(int i=m/2+1; i<=m; i++){
            if(i%2==0) cout<<i<<" ";
        }
        cout<<endl;
        for(int i=1; i<=m/2; i++){
            if(i%2==0) cout<<i<<" ";
        }
        for(int i=m/2; i<=m; i++){
            if(i%2==1) cout<<i<<" ";
        }
        cout<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main()
{
    ll n, count=0;
    cin>>n;
    ll m=n*n;
    ll p=m+1;
    for(int i=1; i<=m; i++){
        for(int j=i+1; j<=m; j++){
            if(i+j==p){
                cout<<i<<" "<<j<<" ";
                count++;
            }
            if(count==n/2){
                cout<<endl;
                count=0;
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define f first
#define s second

int main()
{
	int n , i;
	cin >> n;
	int sum = (((n*n)*((n*n)+1))/2)/n;
	int p = 0;
	p = n*n;
	vector<vector<int>> vec;
	vector<vector<int>> ::iterator it;
	vector<int> ::iterator it1;

	map<int,int>m;
	for(i = 1; i <=n*n ;i++)
		m[i] = 0;
	for(i = 1 ; i <= n;i++)
	{
		int temp_sum = sum;
		vector<int> v;
		p = n*n;
		while(temp_sum != 0)
		{
			if(m[p] == 0)
			{
				if(temp_sum >= p)
				{
					temp_sum -= p;
					v.pb(p);
					m[p] = 1;
					p--;
				}
				else if(m[temp_sum] == 0)
				{
					v.pb(temp_sum);
					m[temp_sum] = 1;
					temp_sum = 0;
				}
				else
					p--;
			}
			else
				p--;
		}
		vec.pb(v);
	}
	for(it = vec.begin() ; it != vec.end();it++)
	{
		for(it1 = (*it).begin();it1 != (*it).end();it1++)
			cout << *it1 << " ";
		 cout << "\n";
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define f first
#define s second

int main()
{
	int n , i;
	cin >> n;
	int sum = (((2*n)*((2*n)+1))/2)/n;
	int p = 0;
	p = 2*n;
	vector<pair<int,int>> vec;
	vector<pair<int,int>> ::iterator it;
	for(i = 1 ; i <= n;i++)
	{
		int elem = sum - p;
		vec.pb(pair<int,int>(elem,p));
		p--;
	}
	for(it = vec.begin() ; it != vec.end();it++)
		cout << it->f << " " << it->s << "\n";

	return 0;
}

/*
cout << "\n";
	for(i = 1 ; i <= 2*n;i++)
	{
		if(m[i] == 0)
			cout << i << " ";
	}
	cout << "\n";

while(sum != 0)
	{
		sum -= p;
		m[p] = 1;
		if(sum < p)
			p = sum;
		else
		{
			p--;
		}
	}
	while(sum != 0)
	{

		sum -= p;
		m[p] = 1;
		if(sum < p)
			p = sum;
		else
		{
			p--;
		}
	}
	*/


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define f first
#define s second

int main()
{
	int n , i;
	cin >> n;
	int sum = (((n*n)*((n*n)+1))/2)/n;
	int p = 0;
	p = n*n;
	vector<vector<int>> vec;
	vector<vector<int>> ::iterator it;
	vector<int> ::iterator it1;

	map<int,int>m;
	for(i = 1; i <=n*n ;i++)
		m[i] = 0;
	for(i = 1 ; i <= n;i++)
	{
		int temp_sum = sum;
		vector<int> v;
		p = n*n;
		while(temp_sum != 0)
		{
			if(m[p] == 0)
			{
				if(temp_sum >= p)
				{
					temp_sum -= p;
					v.pb(p);
					m[p] = 1;

				}
				else
				{
					v.pb(temp_sum);
					m[temp_sum] = 1;
					temp_sum = 0;
				}
				if(temp_sum > p)
					p--;
			}
			else
				p--;
		}
		vec.pb(v);
	}
	for(it = vec.begin() ; it != vec.end();it++)
	{
		for(it1 = (*it).begin();it1 != (*it).end();it1++)
			cout << *it1 << " ";
		 cout << "\n";
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define f first
#define s second

int main()
{
	int n , i;
	cin >> n;
	int sum = (((n*n)*((n*n)+1))/2)/n;
	int p = 0 , k = 0 , j = 0;
	p = 0;

	for(i = 1 ; i <= n;i++)
	{
		for(j = 0; j <= n-2;j += 2,p++)
			cout << p+1 << " " << (n*n)-p << " " ;
		cout << "\n";
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define f first
#define s second

int main()
{
	int n , i;
	cin >> n;
	int sum = (((n*n)*((n*n)+1))/2)/n;
	int p = 0 , k = 0 , j = 0;
	p = 0;

	for(i = 1 ; i <= n;i++)
	{
		for(j = 0; j <= n-2;j += 2,p++)
			cout << p+1 << " " << (n*n)-p << " " ;
		cout << "\n";
	}

	return 0;
}
/*vector<vector<int>> vec;
	vector<vector<int>> ::iterator it;
	vector<int> ::iterator it1;

	map<int,int>m;
	for(i = 1; i <=n*n ;i++)
		m[i] = 0;

	for(i = 1 ; i <= n;i++)
	{
		int temp_sum = sum;
		vector<int> v;
		p = n*n-(i-1);
		v.pb(i);
		v.pb(p);
		m[i] = 1;
		m[p] = 1;
		int flag = -1;
		for(j = 1; j <= n*n && flag != 1;j++)
		{
			for(k = n*n; k >= 1 && flag != 1;k--)
			{
				if(k != j && m[k] != 1 && m[j] != 1 && k + j == sum / 2 )
				{
					v.pb(k);
					v.pb(j);
					m[k] = 1;
					m[j] = 1;
					flag = 1;
					break;
				}
			}
		}

		vec.pb(v);
	}
	for(it = vec.begin() ; it != vec.end();it++)
	{
		for(it1 = (*it).begin();it1 != (*it).end();it1++)
			cout << *it1 << " ";
		 cout << "\n";
	}
	*/


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define f first
#define s second

int main()
{
	int n , i;
	cin >> n;
	int sum = (((n*n)*((n*n)+1))/2)/n;
	int p = 0;
	p = n*n;
	vector<pair<int,int>> vec;
	vector<pair<int,int>> ::iterator it;
	for(i = 1 ; i <= n;i++)
	{
		int elem = sum - p;
		vec.pb(pair<int,int>(elem,p));
		p--;
	}
	for(it = vec.begin() ; it != vec.end();it++)
		cout << it->f << " " << it->s << "\n";

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
  int n;
  cin>>n;
  int m = n*n;
  int j=1;
  int times = n/2;
  while(n--)
  {
    for(int i=0;i<times;i++)
    {
    cout<<j<<" "<<m-j+1<<" ";
    j++;
    }
    cout<<"\n";
  }
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
  int n;
  cin>>n;
  int m = n*n;
  int j=1;
  float pw = (1.0*log(n))/log(2);
  int times = int(pw);
  while(n--)
  {
    for(int i=0;i<times;i++)
    {
    cout<<j<<" "<<m-j+1<<" ";
    j++;
    }
    cout<<"\n";
  }
}


#include <bits/stdc++.h>
using namespace std;

int main()
{
  int n;
  cin>>n;
  int m = n*n;
  int i=1;
  while(n--)
  {
    cout<<i<<" "<<m-i+1<<"\n";
    i++;
  }
}


// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#ifdef on_linux
#include <sys/resource.h>
#endif

using namespace std;
using namespace __gnu_pbds;

template<typename T, typename U> std::istream& operator>>(std::istream& in, pair<T, U> &a) {in >> a.first >> a.second; return in;}
template<typename T, typename U> std::ostream& operator<<(std::ostream& out, pair<T, U> a) {out << "{" << a.first << ", " << a.second << "}"; return out;}
template<typename T, typename U> static inline void remin(T &x, U y) {if (y < x) {x = y;}}
template<typename T, typename U> static inline void remax(T &x, U y) {if (x < y) {x = y;}}
template<typename T> T allmin(T t) {return t;}
template<typename T, typename... Args> T allmin(T t, Args... args) {return min(t, allmin(args...));}
template<typename T> T allmax(T t) {return t;}
template<typename T, typename... Args> T allmax(T t, Args... args) {return max(t, allmax(args...));}

inline long long toint(const string &s) {stringstream ss; ss << s; long long x; ss >> x; return x;}
inline string tostring(long long number) {stringstream ss; ss << number; return ss.str();}
inline string tobin(long long x) {return bitset<63>(x).to_string();}

#define sz(x)                   (int)((x).size())
#define all(x)                  (x).begin(), (x).end()
#define mem0(x)                 memset(x, 0, sizeof (x))
#define mem1(x)                 memset(x, -1, sizeof (x))
#define sleep(x)                std::this_thread::sleep_for(std::chrono::milliseconds(x))
#define DECIMAL(n)              std::cout << std::fixed << std::setprecision(n);
#define rep(i,a,b)              for(int32_t i = (a); i < (b); ++i)
#define between(i,x,y)          (i >= x && i <= y)
// #define clamp(i,x,y)         clamp(i, x, y)
#define sqr(a)                  ((a) * (a))
#define pii                     pair<int32_t, int32_t>
#define pll                     pair<long long, long long>
#define mp                      make_pair
#define fi                      first
#define sc                      second
#define pb                      push_back
#define ppb                     pop_back
#define pf                      push_front
#define ppf                     pop_front
#define lbd                     lower_bound
#define ubd                     upper_bound
#define int                     long long
#define ll                      long long

template <typename T>
using min_pq = priority_queue<T, vector<T>, greater<T>>;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
// erase, insert same as normal set

const long long INF = 1e18;
const long long MOD = 1e9 + 7;
const long long fftmod = 998244353;
const long double PI = 3.14159265358979323846264338;
const long double eps = 1e-12;
const int32_t N = 1e5 + 10;
const int32_t NN = 1e6 + 10;
// big mod and primitive root for NTT:
// #define MOD 2305843009255636993          // a bit larger than 2^61 (2e18)
// #define RT 5

inline void dobbysolver(int testcase)
{
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i)
		cout << i + 1 << ' ' << 2 * n - i << '\n';

	return;
}

int32_t main()
{
#ifdef on_linux
	rlimit cpu_time {.rlim_cur = 2, .rlim_max = RLIM_INFINITY};
	setrlimit(RLIMIT_CPU, &cpu_time);
#endif
	ios_base::sync_with_stdio(false);   // using both C and C++ streams will now mix up the outputs (also inputs)
	cin.tie(nullptr);
	cout.tie(nullptr);
	int TESTS = 1;
	//cin >> TESTS;
	for (int i = 1; i <= TESTS; ++i) {dobbysolver(i); if (i != TESTS) cout << '\n';}
	return 0;
}


// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#ifdef on_linux
#include <sys/resource.h>
#endif

using namespace std;
using namespace __gnu_pbds;

template<typename T, typename U> std::istream& operator>>(std::istream& in, pair<T, U> &a) {in >> a.first >> a.second; return in;}
template<typename T, typename U> std::ostream& operator<<(std::ostream& out, pair<T, U> a) {out << "{" << a.first << ", " << a.second << "}"; return out;}
template<typename T, typename U> static inline void remin(T &x, U y) {if (y < x) {x = y;}}
template<typename T, typename U> static inline void remax(T &x, U y) {if (x < y) {x = y;}}
template<typename T> T allmin(T t) {return t;}
template<typename T, typename... Args> T allmin(T t, Args... args) {return min(t, allmin(args...));}
template<typename T> T allmax(T t) {return t;}
template<typename T, typename... Args> T allmax(T t, Args... args) {return max(t, allmax(args...));}

inline long long toint(const string &s) {stringstream ss; ss << s; long long x; ss >> x; return x;}
inline string tostring(long long number) {stringstream ss; ss << number; return ss.str();}
inline string tobin(long long x) {return bitset<63>(x).to_string();}

#define sz(x)                   (int)((x).size())
#define all(x)                  (x).begin(), (x).end()
#define mem0(x)                 memset(x, 0, sizeof (x))
#define mem1(x)                 memset(x, -1, sizeof (x))
#define sleep(x)                std::this_thread::sleep_for(std::chrono::milliseconds(x))
#define DECIMAL(n)              std::cout << std::fixed << std::setprecision(n);
#define rep(i,a,b)              for(int32_t i = (a); i < (b); ++i)
#define between(i,x,y)          (i >= x && i <= y)
// #define clamp(i,x,y)         clamp(i, x, y)
#define sqr(a)                  ((a) * (a))
#define pii                     pair<int32_t, int32_t>
#define pll                     pair<long long, long long>
#define mp                      make_pair
#define fi                      first
#define sc                      second
#define pb                      push_back
#define ppb                     pop_back
#define pf                      push_front
#define ppf                     pop_front
#define lbd                     lower_bound
#define ubd                     upper_bound
#define int                     long long
#define ll                      long long

template <typename T>
using min_pq = priority_queue<T, vector<T>, greater<T>>;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
// erase, insert same as normal set

const long long INF = 1e18;
const long long MOD = 1e9 + 7;
const long long fftmod = 998244353;
const long double PI = 3.14159265358979323846264338;
const long double eps = 1e-12;
const int32_t N = 1e5 + 10;
const int32_t NN = 1e6 + 10;
// big mod and primitive root for NTT:
// #define MOD 2305843009255636993          // a bit larger than 2^61 (2e18)
// #define RT 5

inline void dobbysolver(int testcase)
{
	int n;
	cin >> n;
	if (n == 1)
		cout << 1;
	else
		for (int i = 0; i < n; ++i)
			cout << i + 1 << ' ' << 2 * n - i << '\n';

	return;
}

int32_t main()
{
#ifdef on_linux
	rlimit cpu_time {.rlim_cur = 2, .rlim_max = RLIM_INFINITY};
	setrlimit(RLIMIT_CPU, &cpu_time);
#endif
	ios_base::sync_with_stdio(false);   // using both C and C++ streams will now mix up the outputs (also inputs)
	cin.tie(nullptr);
	cout.tie(nullptr);
	int TESTS = 1;
	//cin >> TESTS;
	for (int i = 1; i <= TESTS; ++i) {dobbysolver(i); if (i != TESTS) cout << '\n';}
	return 0;
}


// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#ifdef on_linux
#include <sys/resource.h>
#endif

using namespace std;
using namespace __gnu_pbds;

template<typename T, typename U> std::istream& operator>>(std::istream& in, pair<T, U> &a) {in >> a.first >> a.second; return in;}
template<typename T, typename U> std::ostream& operator<<(std::ostream& out, pair<T, U> a) {out << "{" << a.first << ", " << a.second << "}"; return out;}
template<typename T, typename U> static inline void remin(T &x, U y) {if (y < x) {x = y;}}
template<typename T, typename U> static inline void remax(T &x, U y) {if (x < y) {x = y;}}
template<typename T> T allmin(T t) {return t;}
template<typename T, typename... Args> T allmin(T t, Args... args) {return min(t, allmin(args...));}
template<typename T> T allmax(T t) {return t;}
template<typename T, typename... Args> T allmax(T t, Args... args) {return max(t, allmax(args...));}

inline long long toint(const string &s) {stringstream ss; ss << s; long long x; ss >> x; return x;}
inline string tostring(long long number) {stringstream ss; ss << number; return ss.str();}
inline string tobin(long long x) {return bitset<63>(x).to_string();}

#define sz(x)                   (int)((x).size())
#define all(x)                  (x).begin(), (x).end()
#define mem0(x)                 memset(x, 0, sizeof (x))
#define mem1(x)                 memset(x, -1, sizeof (x))
#define sleep(x)                std::this_thread::sleep_for(std::chrono::milliseconds(x))
#define DECIMAL(n)              std::cout << std::fixed << std::setprecision(n);
#define rep(i,a,b)              for(int32_t i = (a); i < (b); ++i)
#define between(i,x,y)          (i >= x && i <= y)
// #define clamp(i,x,y)         clamp(i, x, y)
#define sqr(a)                  ((a) * (a))
#define pii                     pair<int32_t, int32_t>
#define pll                     pair<long long, long long>
#define mp                      make_pair
#define fi                      first
#define sc                      second
#define pb                      push_back
#define ppb                     pop_back
#define pf                      push_front
#define ppf                     pop_front
#define lbd                     lower_bound
#define ubd                     upper_bound
#define int                     long long
#define ll                      long long

template <typename T>
using min_pq = priority_queue<T, vector<T>, greater<T>>;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
// erase, insert same as normal set

const long long INF = 1e18;
const long long MOD = 1e9 + 7;
const long long fftmod = 998244353;
const long double PI = 3.14159265358979323846264338;
const long double eps = 1e-12;
const int32_t N = 1e5 + 10;
const int32_t NN = 1e6 + 10;
// big mod and primitive root for NTT:
// #define MOD 2305843009255636993          // a bit larger than 2^61 (2e18)
// #define RT 5

inline void dobbysolver(int testcase)
{
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; j += 2)
			cout << j * n + i + 1 << ' ' << (j + 2) * n - i << " \n"[j == n - 2];

	return;
}

int32_t main()
{
#ifdef on_linux
	rlimit cpu_time {.rlim_cur = 2, .rlim_max = RLIM_INFINITY};
	setrlimit(RLIMIT_CPU, &cpu_time);
#endif
	ios_base::sync_with_stdio(false);   // using both C and C++ streams will now mix up the outputs (also inputs)
	cin.tie(nullptr);
	cout.tie(nullptr);
	int TESTS = 1;
	//cin >> TESTS;
	for (int i = 1; i <= TESTS; ++i) {dobbysolver(i); if (i != TESTS) cout << '\n';}
	return 0;
}


#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    int n,z=0,y=1,x;
    cin >> n;
    int a[n][n];
    while(y<pow(n,2))
    {
        for(x=0;x<n;x++,y++)
        a[x][z]=y;
        z++;
        for(x=n-1;x>=0;x--,y++)
        a[x][z]=y;
        z++;
    }
    for(x=0;x<n;x++)
    {
        for(y=0;y<n;y++)
        cout <<a[x][y]<<" ";
        cout <<"\n";
    }
}


#include <iostream>
using namespace std;
int main()
{
    int n,x,y;
    cin >> n;
    int a[n][2];
    for(x=0;x<n;x++)
    a[x][0]=x+1;
    y=x+1;
    for(x=n-1;x>=0;x--)
    {
        a[x][1]=y;
        y++;
    }
    for(x=0;x<n;x++)
    cout << a[x][0] <<" " << a[x][1] <<endl;

}


#include <iostream>
#include <cmath>
#include <bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n,z=0,y=1,x;
    cin >> n;
    int a[n][n];
    while(y<pow(n,2))
    {
        for(x=0;x<n;x++,y++)
        a[x][z]=y;
        z++;
        for(x=n-1;x>=0;x--,y++)
        a[x][z]=y;
        z++;
    }
    for(x=0;x<n;x++)
    {
        for(y=0;y<n;y++)
        cout <<a[x][y]<<" ";
        cout <<"\n";
    }
}


#include<bits/stdc++.h>
using namespace std;
 #define lli long long int

 int main()
 {
     ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;
    int arr[n*n];
    for(int i=0;i<n*n;i++){
        arr[i]=0;
    }
    for(int i=0;i<n*n;i++){
        arr[i]=i+1;
    }

    int k=0;
    for(int i=1;i<=n;i++){
    int r=0;
        for(int j=0;j<n/2;j++){
                r+=j+k;
            cout<<arr[r]<<" "<<arr[n*n-r-1]<<" ";
        }
        cout<<"\n";
        k+=n/2;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
 #define lli long long int

 int main()
 {
     ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;

    int a[(n*n)/2];
    int b[(n*n)/2];
    for(int i=1;i<=(n*n/2);i++){
        a[i]=b[i]=0;
    }
    int p=1;
    int k=1;
    for(int i=1;i<=(n*n/2);i++){
        if(i%2==0){
            a[p++]=i;
        }
        else{
            b[k++]=i;
        }
    }
    for(int i=(n*n/2)+1;i<=(n*n);i++){
        if(i%2==0){
            b[k++]=i;
        }
        else{
            a[p++]=i;
        }
    }
for(int i=1;i<=(n*n/2);i++){
        cout<<a[i]<<" ";
    }
    cout<<"\n";
    for(int i=1;i<=(n*n/2);i++){
        cout<<b[i]<<" ";
    }
    cout<<"\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
 #define lli long long int

 int main()
 {
     ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;
    int arr[n*n];
    for(int i=0;i<n*n;i++){
        arr[i]=0;
    }
    for(int i=0;i<n*n;i++){
        arr[i]=i+1;
    }

    int k=0;
    for(int i=1;i<=n;i++){
    int r=0;
     r+=k;
        for(int j=0;j<n/2;j++){
                r+=j;
            cout<<arr[r]<<" "<<arr[n*n-r-1]<<" ";
        }
        cout<<"\n";
        k+=n/2;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
 #define lli long long int

 int main()
 {
     ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;
    int arr[n*n];
    for(int i=0;i<n*n;i++){
        arr[i]=0;
    }
    for(int i=0;i<n*n;i++){
        arr[i]=i+1;
    }

    int k=0;
    for(int i=1;i<=n;i++){
    int r=0;
     r+=k;
        for(int j=0;j<n/2;j++){
            r+=j;
            cout<<arr[r]<<" "<<arr[n*n-r-1]<<" ";
        }
        cout<<"\n";
        k+=n/2;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
 #define lli long long int

 int main()
 {
     ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;
    int arr[n*n];
    for(int i=0;i<n*n;i++){
        arr[i]=0;
    }
    for(int i=0;i<n*n;i++){
        arr[i]=i+1;
    }

    int k=0;
    for(int i=1;i<=n;i++){
    int r=0;
     r+=k;
        for(int j=0;j<n/2;j++){

            cout<<arr[r]<<" "<<arr[n*n-r-1]<<" ";
            r++;
        }
        cout<<"\n";
        k+=n/2;
    }

    return 0;
}


/*	MASTER HAS FAILED MORE TIMES
	THAN BEGINNER HAS EVER TRIED
*/

#include <bits/stdc++.h>

using namespace std;

#define endl             '\n'
#define all(a)           a.begin(), a.end()
#define mem(a, n)        memset(a, n, sizeof(a))
#define Unique(n)        (n).erase(unique(all(n)), (n).end())
#define NumofDigits(n)   ((long long)log10(n)+1)
#define repeat(i, a, n)  for(int i=a; i<n; i++)
#define isPowerOfTwo(n)  (n && !(n & (n - 1)))

typedef long long ll;
typedef long double ld;

int sieve(int n);
unsigned long long pow(long long base, long long power);
long long gcd(long long a, long long b){ return a%b ? gcd(b, a%b) : b; }
long long lcm(long long a, long long b){ return a*b/gcd(a, b); }

void quicken(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
void file(){
    #ifdef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif /*ONLINE_JUDGE*/
}

int arr[102][102];
int main(){
    quicken();

    int n, start, r, c; cin >> n;

    start = 1, r = c = 0;
    while(start<=n*n){
        repeat(i, 0, n) arr[r++][c] = start, start++; /// down
        c++;                                          /// right
        repeat(i, 0, n) arr[--r][c] = start, start++; /// up
        c++;                                          /// right
    }

    repeat(i, 0, n) repeat(j, 0, n)
        cout << arr[i][j] << " \n"[j==n-1];

    return 0;
}

unsigned long long pow(long long base, long long power){ /// mod?
    if(power==0) return 1;
    if(power==1) return base;

    unsigned long long ans = pow(base, power/2); /// mod?
    ans *= ans; /// ((ans%mod)*(ans%mod))%mod;

    if(power&1) return ans*base; /// ((ans%mod)*(base%mod))%mod;
    return ans;
}

int sieve(int n){
    int c = 0;
    vector<bool> isPrime(n+1, true);
    isPrime[0] = isPrime[1] = 0;

    for(long long i=2; i*i<=n; i++)
        if(isPrime[i])
            for(long long j=i*2; j<=n; j+=i)
                isPrime[j] = 0;
    repeat(i, 0, n+1)
        if(isPrime[i]) c++;
    return c; /// primeCount [1:n]
}


/*	MASTER HAS FAILED MORE TIMES
	THAN BEGINNER HAS EVER TRIED
*/

#include <bits/stdc++.h>

using namespace std;

#define endl             '\n'
#define all(a)           a.begin(), a.end()
#define mem(a, n)        memset(a, n, sizeof(a))
#define Unique(n)        (n).erase(unique(all(n)), (n).end())
#define NumofDigits(n)   ((long long)log10(n)+1)
#define repeat(i, a, n)  for(int i=a; i<n; i++)
#define isPowerOfTwo(n)  (n && !(n & (n - 1)))

typedef long long ll;
typedef long double ld;

int sieve(int n);
unsigned long long pow(long long base, long long power);
long long gcd(long long a, long long b){ return a%b ? gcd(b, a%b) : b; }
long long lcm(long long a, long long b){ return a*b/gcd(a, b); }

void quicken(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
void file(){
    #ifdef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif /*ONLINE_JUDGE*/
}

int main(){
    quicken();

    int n; cin >> n;
    for(int i=1, j=n*n; i<n*(n+1)/2; i++, j--)
        cout << i << ' ' << j << endl;

    return 0;
}

unsigned long long pow(long long base, long long power){ /// mod?
    if(power==0) return 1;
    if(power==1) return base;

    unsigned long long ans = pow(base, power/2); /// mod?
    ans *= ans; /// ((ans%mod)*(ans%mod))%mod;

    if(power&1) return ans*base; /// ((ans%mod)*(base%mod))%mod;
    return ans;
}

int sieve(int n){
    int c = 0;
    vector<bool> isPrime(n+1, true);
    isPrime[0] = isPrime[1] = 0;

    for(long long i=2; i*i<=n; i++)
        if(isPrime[i])
            for(long long j=i*2; j<=n; j+=i)
                isPrime[j] = 0;
    repeat(i, 0, n+1)
        if(isPrime[i]) c++;
    return c; /// primeCount [1:n]
}


/*	MASTER HAS FAILED MORE TIMES
	THAN BEGINNER HAS EVER TRIED
*/

#include <bits/stdc++.h>

using namespace std;

#define endl             '\n'
#define all(a)           a.begin(), a.end()
#define mem(a, n)        memset(a, n, sizeof(a))
#define Unique(n)        (n).erase(unique(all(n)), (n).end())
#define NumofDigits(n)   ((long long)log10(n)+1)
#define repeat(i, a, n)  for(int i=a; i<n; i++)
#define isPowerOfTwo(n)  (n && !(n & (n - 1)))

typedef long long ll;
typedef long double ld;

int sieve(int n);
unsigned long long pow(long long base, long long power);
long long gcd(long long a, long long b){ return a%b ? gcd(b, a%b) : b; }
long long lcm(long long a, long long b){ return a*b/gcd(a, b); }

void quicken(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); }
void file(){
    #ifdef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif /*ONLINE_JUDGE*/
}

int main(){
    quicken();

    int n; cin >> n;
    for(int i=1, j=n*n; i<=n; i++, j--)
        cout << i << ' ' << j << endl;

    return 0;
}

unsigned long long pow(long long base, long long power){ /// mod?
    if(power==0) return 1;
    if(power==1) return base;

    unsigned long long ans = pow(base, power/2); /// mod?
    ans *= ans; /// ((ans%mod)*(ans%mod))%mod;

    if(power&1) return ans*base; /// ((ans%mod)*(base%mod))%mod;
    return ans;
}

int sieve(int n){
    int c = 0;
    vector<bool> isPrime(n+1, true);
    isPrime[0] = isPrime[1] = 0;

    for(long long i=2; i*i<=n; i++)
        if(isPrime[i])
            for(long long j=i*2; j<=n; j+=i)
                isPrime[j] = 0;
    repeat(i, 0, n+1)
        if(isPrime[i]) c++;
    return c; /// primeCount [1:n]
}


#include<bits/stdc++.h>

using namespace std;

#define ff              first
#define ss              second
#define int             long long
#define pb              push_back
#define pf 				push_front
#define mp              make_pair
#define pii             pair<int,int>
#define MAX 			1000000
#define vi              vector<int>
#define mii             map<int,int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)            int x; cin>>x; while(x--)
#define FIO             ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
mt19937                 rng(chrono::steady_clock::now().time_since_epoch().count());
void c_p_c()
{
#ifndef  ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
}
const int Max = 1e7;
int count(string s)
{
	int i;
	int c = 0;
	for (i = 0; i < s.length(); i++)
	{
		if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u')
			c++;
	}
	return c;
}
int32_t main()
{
	c_p_c();

	int n;
	cin >> n ;
	int i = n * n;
	int j = 1;
	int r = 2 * n;
	while (r--)
	{
		cout << j << " " << i;
		j++;
		i--;
		cout << endl;
	}
}


#include<bits/stdc++.h>

using namespace std;

#define ff              first
#define ss              second
#define int             long long
#define pb              push_back
#define pf 				push_front
#define mp              make_pair
#define pii             pair<int,int>
#define MAX 			1000000
#define vi              vector<int>
#define mii             map<int,int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)            int x; cin>>x; while(x--)
#define FIO             ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
mt19937                 rng(chrono::steady_clock::now().time_since_epoch().count());
void c_p_c()
{
#ifndef  ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
}
const int Max = 1e7;
int count(string s)
{
	int i;
	int c = 0;
	for (i = 0; i < s.length(); i++)
	{
		if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u')
			c++;
	}
	return c;
}
int32_t main()
{
	c_p_c();

	int n;
	cin >> n ;
	int i = n * n;
	int j;
	for (j = 1; j <= n; j++)
	{
		cout << j << " " << i << endl;

		i--;
	}
}


#include<bits/stdc++.h>

using namespace std;

#define ff              first
#define ss              second
#define int             long long
#define pb              push_back
#define pf 				push_front
#define mp              make_pair
#define pii             pair<int,int>
#define MAX 			1000000
#define vi              vector<int>
#define mii             map<int,int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zrobits(x)      __builtin_ctzll(x)
#define mod             1000000007
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define mk(arr,n,type)  type *arr=new type[n];
#define w(x)            int x; cin>>x; while(x--)
#define FIO             ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
mt19937                 rng(chrono::steady_clock::now().time_since_epoch().count());
void c_p_c()
{
#ifndef  ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
}
const int Max = 1e7;
int count(string s)
{
	int i;
	int c = 0;
	for (i = 0; i < s.length(); i++)
	{
		if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u')
			c++;
	}
	return c;
}
int32_t main()
{
	c_p_c();

	int n;
	cin >> n ;
	int i = n * n;
	int j = 1;
	int r = 2 * n;
	while (j < i)
	{
		cout << j << " " << i;
		j++;
		i--;
		cout << endl;
	}
}


#include <bits/stdc++.h>
#define r(i,x) for(int i = 0; i < x; i++)
#define rep(i,a,x) for(int i = a; i <= x; i++)
#define drep(i,a,b) for(int i = a; i >= b; i--)
#define ll long long
#define vi vector<int>
#define vl vector<long long>
#define pii pair<int, int>
#define F first
#define S second
#define pb push_back
#define mk make_pair
using namespace std;
int MAX = 1e9;
int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
	// For getting input from input.txt file
	freopen("input.txt", "r", stdin);
	// Printing the Output to output.txt file
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	rep(i, 1, n) {
		cout << i << n*n + 1 - i << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
#define r(i,x) for(int i = 0; i < x; i++)
#define rep(i,a,x) for(int i = a; i <= x; i++)
#define drep(i,a,b) for(int i = a; i >= b; i--)
#define ll long long
#define vi vector<int>
#define vl vector<long long>
#define pii pair<int, int>
#define F first
#define S second
#define pb push_back
#define mk make_pair
using namespace std;
int MAX = 1e9;
int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
	// For getting input from input.txt file
	freopen("input.txt", "r", stdin);
	// Printing the Output to output.txt file
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	rep(i, 1, n) {
		cout << i << ' ' << n*n + 1 - i << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
#define r(i,x) for(int i = 0; i < x; i++)
#define rep(i,a,x) for(int i = a; i <= x; i++)
#define drep(i,a,b) for(int i = a; i >= b; i--)
#define ll long long
#define vi vector<int>
#define vl vector<long long>
#define pii pair<int, int>
#define F first
#define S second
#define pb push_back
#define mk make_pair
using namespace std;
int MAX = 1e9;
int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifndef ONLINE_JUDGE
	// For getting input from input.txt file
	freopen("input.txt", "r", stdin);
	// Printing the Output to output.txt file
	freopen("output.txt", "w", stdout);
#endif
	int n;
	cin >> n;
	int sq = n * n;
	rep(i, 1, sq / 2) {
		cout << i << ' ' << sq + 1 - i << ' ';
		if (i % (n / 2) == 0)
			cout << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
 {
     int n , k;
     cin>>n;
     k=n*n;
     int odd=0, even =k+1;

     for(int i=1; i<=n; i++)
     {
         for(int i=0; i<n/2 ; i++)
         {
             odd++;
             even --;
             cout<<odd<<" "<<even<<" ";
         }
         cout<<endl;

     }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
 {
     int n , k;
     cin>>n;
     k=n*n;

     for(int i=1; i<=n; i++)
     {
         for(int j=i;j<=i; j++)
         {
            cout<<j<<k;
            k--;

         }
         cout<<endl;
     }

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int main()
 {
     int n , k;
     cin>>n;
     k=n*n;

     for(int i=1; i<=n; i++)
     {
         for(int j=i;j<=i; j++)
         {
            cout<<j<<" "<<k;
            k--;

         }
         cout<<endl;
     }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
    int n;
    cin>>n;
    for(int i=1,j=n*n;i<n*n/2;i+=2,j-=2)
    {
        cout<<i<<' '<<i+1<<' '<<j<<' '<<j-1<<'\n';
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
  ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
  int n;
  cin>>n;
  for(int i=1;i<=n*n;i+=4)
  {
    cout<<i<<" "<<i+3<<" ";
  }
  cout<<"\n";
  for(int i=1;i<=n*n;i+=4)
  {
    cout<<i+1<<" "<<i+2<<" ";
  }
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
    int n;
    cin>>n;
    int nn=n*n;
    for(int i=1;i<=nn/2;i++)
    {
        cout<<i<<" "<<nn-i+1<<" ";
        if(i%(n/2)==0)
        {
            cout<<"\n";
        }
    }
    return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int a[n+1][n+1];
	int t=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			a[i][j]=t++;
	int x=1,y=n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<a[j][x]<<" "<<a[j][y]<<" ";

		}
		x++;y--;
		cout<<endl;
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin>>n;
/*	int a[n+1][n+1];
	int t=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			a[i][j]=t++;
	int x=1,y=n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<a[j][x]<<" "<<a[j][y]<<" ";

		}
		x++;y--;
		cout<<endl;
	}*/
	int t=n*n,w=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n/2;j++)
		{
			cout<<w<<" "<<t<<" ";
			w++,t--;
		}
		cout<<endl;

	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int a[n+1][n+1];
	int t=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			a[i][j]=t++;
	int x=1;int y=n;
	for(int i=1;i<=n;i++)
	{
		cout<<a[i][x]<<" "<<a[i][y]<<" ";
		x++;y--;
	}
	cout<<endl;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int t=n*n;
	for(int i=1;i<=n;i++,t--)
	{
		cout<<i<<" "<<t<<endl;
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int t=1;
	while(n--)
	{
		cout<<n*n<<" "<<t++<<endl;
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<cstring>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int t=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			a[i][j]=t++;
	int x=1;int y=n;
	for(int i=1;i<=n;i++)
	{
		cout<<a[i][x]<<" "<<a[i][y]<<" ";
		x++;y--;
	}
	cout<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long int
#define w(x) ll x;cin>>x; while(x--)
#define f(i,a,n) for(int i=a;i<n;i++)
#define fe(i,a,n) for(int i=a;i<=n;i++)
using namespace std;
int main(){
    ll n;
    cin>>n;
    ll a=n*n;
    ll b=a/2;
    fe(i,1,b){
        cout<<i<<" "<<a<<" "<<endl;
        a--;
    }
}


#include<bits/stdc++.h>
#define ll long long int
#define w(x) ll x;cin>>x; while(x--)
#define f(i,a,n) for(int i=a;i<n;i++)
#define fe(i,a,n) for(int i=a;i<=n;i++)
using namespace std;
int main(){
    ll n;
    cin>>n;
    ll a=n*n;
    fe(i,1,a/2){
        cout<<i<<" "<<a<<" "<<endl;
        a--;
    }
}


#include<bits/stdc++.h>
#define ll long long int
#define w(x) ll x;cin>>x; while(x--)
#define f(i,a,n) for(int i=a;i<n;i++)
#define fe(i,a,n) for(int i=a;i<=n;i++)
using namespace std;
int main(){
    ll n;
    cin>>n;
    ll a=n*n;
    fe(i,1,2*n){
        cout<<i<<" "<<a<<" "<<endl;
        a--;
    }
}


//https://codeforces.com/contest/334/problem/a
//cf submit -f 334a.cpp 334a
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,tune=native")
#define fastIO() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fraction() cout.unsetf(ios::floatfield); cout.precision(10); cout.setf(ios::fixed,ios::floatfield);
#define file() freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef vector<pii> vii;
typedef vector<pll> vll;

const double PI = acos(-1);
const double eps = 1e-9;

#define mem(arr,val) memset(arr,val,sizeof(arr))
#define sqr(a) ((a)*(a))
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) (a*(b/gcd(a,b)))

#define F first
#define S second
#define pb push_back
#define mp make_pair
#define endl "\n"
#define sz(a) (int)a.size()
#define all(a) a.begin(),a.end()
#define allr(a) a.rbegin(),a.rend()

int main()
{
    fastIO();
    int n, i, j, sq, pivot;
    cin >> n;
    sq = sqr(n);
    for(i=1, j=sq; i<=sq/2, j>=sq/2; i++, j--){
        if(i>j) break;
        cout << i << " " << j << " ";
        if(2*i%n==0) cout << endl;
    }

    return 0;
}

/*
******SAMPLE I/O******
in:

out:

*/


//https://codeforces.com/contest/334/problem/a
//cf submit -f 334a.cpp 334a
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,tune=native")
#define fastIO() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fraction() cout.unsetf(ios::floatfield); cout.precision(10); cout.setf(ios::fixed,ios::floatfield);
#define file() freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef vector<pii> vii;
typedef vector<pll> vll;

const double PI = acos(-1);
const double eps = 1e-9;

#define mem(arr,val) memset(arr,val,sizeof(arr))
#define sqr(a) ((a)*(a))
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) (a*(b/gcd(a,b)))

#define F first
#define S second
#define pb push_back
#define mp make_pair
#define endl "\n"
#define sz(a) (int)a.size()
#define all(a) a.begin(),a.end()
#define allr(a) a.rbegin(),a.rend()

int main()
{
    fastIO();
    int n, i, j, sq, pivot;
    cin >> n;
    sq = sqr(n);
    for(i=1, j=sq; i<=sq/2, j>=sq/2; i++, j--){
        if(i>j) break;
        cout << i << " " << j << " ";
        if(2*i%n==0) cout << endl;
    }

    return 0;
}

/*
******SAMPLE I/O******
in:

out:

*/


//https://codeforces.com/contest/334/problem/a
//cf submit -f 334a.cpp 334a
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,tune=native")
#define fastIO() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define fraction() cout.unsetf(ios::floatfield); cout.precision(10); cout.setf(ios::fixed,ios::floatfield);
#define file() freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef vector<pii> vii;
typedef vector<pll> vll;

const double PI = acos(-1);
const double eps = 1e-9;

#define mem(arr,val) memset(arr,val,sizeof(arr))
#define sqr(a) ((a)*(a))
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) (a*(b/gcd(a,b)))

#define F first
#define S second
#define pb push_back
#define mp make_pair
#define endl "\n"
#define sz(a) (int)a.size()
#define all(a) a.begin(),a.end()
#define allr(a) a.rbegin(),a.rend()

int main()
{
    fastIO();
    int n, i, j, sq, pivot;
    cin >> n;
    sq = sqr(n);
    for(i=1, j=sq; i<=sq/2, j>=sq/2; i++, j--){
        if(i>j) break;
        cout << i << " " << j << " ";
        if(2*i%n==0) cout << endl;
    }

    return 0;
}

/*
******SAMPLE I/O******
in:

out:

*/


import java.util.*;
import java.io.*;
import java.text.*;

public class Main{
    long mod = (int)1e9+7, IINF = (long)1e17;
    final int MAX = (int)1e6+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.00000000");
    double PI = 3.141592653589793238462643383279502884197169399375105820974944;
    static boolean multipleTC = false, memory = false;
    FastReader in;PrintWriter out;
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, T= (multipleTC)?ni():1; i<= T; i++)solve(i);
        out.flush();
        out.close();
    }
    long ans = 0;

    void solve(int TC) throws Exception{
        int n = ni(), m=ni();
        int[] set = new int[m*2], map = new int[m*2];
        String s = n();
        boolean[] prev = new boolean[m], cur = new boolean[m];
        for(int i = 0; i< s.length(); i++){
            int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
            for(int j = 0; j< 4; j++){
                prev[i*4+j] = ((v>>(3-j))&1)==1;
                if(prev[i*4+j])ans++;
            }
        }
        for(int i = 0; i< m; i++)set[i] = i;
        for(int i = 1; i< m; i++)if(prev[i] && prev[i-1])union(set,i-1, i);
        for(int t = 1; t< n; t++){
            s = n();
            for(int i = 0; i< s.length(); i++){
                int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
                for(int j = 0; j< 4; j++){
                    cur[i*4+j] = ((v>>(3-j))&1)==1;
                    set[m+i*4+j] = m+i*4+j;
                    if(cur[i*4+j])ans++;
                }
            }
            for(int i = 0; i< m; i++)if(prev[i] && cur[i])union(set,i, i+m);
            for(int i = 1; i< m; i++)if(cur[i-1] && cur[i])union(set,i+m-1, i+m);
//            print(set);
            for(int i = 0; i< map.length; i++)map[i] = -1;
            for(int i = m; i< 2*m; i++)set[i] = find(set, i);
            for(int i = m; i< 2*m; i++)if(map[set[i]] == -1)map[set[i]] = i-m;
            for(int i = 0; i< m; i++)set[i] = map[set[i+m]];
//            print(set);pn("");
            for(int i = 0; i< m; i++)prev[i] = cur[i];
        }
        pn(ans);
    }
    void print(boolean[] b){
        for(boolean c:b)p((c)?1:0);pn("");
    }
    void print(int[] a){
        for(int i:a)p(i+" ");pn("");
    }
    int find(int[] set, int i){
        return set[i]==i?i:(set[i] = find(set,set[i]));
    }
    void union(int[] set, int x, int y){
        x = find(set,x);y=find(set,y);
        if(x==y)return;
        ans--;
        set[y] = x;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.*;

public class Main{
    long mod = (int)1e9+7, IINF = (long)1e17;
    final int MAX = (int)1e6+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.00000000");
    double PI = 3.141592653589793238462643383279502884197169399375105820974944;
    static boolean multipleTC = false, memory = false;
    FastReader in;PrintWriter out;
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, T= (multipleTC)?ni():1; i<= T; i++)solve(i);
        out.flush();
        out.close();
    }
    long ans = 0;

    void solve(int TC) throws Exception{
        int n = ni(), m=ni();
        int[] set = new int[m*2], map = new int[m*2];
        String s = n();
        boolean[] prev = new boolean[m], cur = new boolean[m];
        for(int i = 0; i< s.length(); i++){
            int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
            for(int j = 0; j< 4; j++){
                prev[i*4+j] = ((v>>(3-j))&1)==1;
                if(prev[i*4+j])ans++;
            }
        }
        for(int i = 0; i< m; i++)set[i] = i;
        for(int i = 1; i< m; i++)if(prev[i] && prev[i-1])union(set,i-1, i);
        for(int t = 1; t< n; t++){
            s = n();
            for(int i = 0; i< s.length(); i++){
                int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
                for(int j = 0; j< 4; j++){
                    cur[i*4+j] = ((v>>(3-j))&1)==1;
                    set[m+i*4+j] = m+i*4+j;
                    if(cur[i*4+j])ans++;
                }
            }
            for(int i = 0; i< m; i++){
                if(cur[i]){
                    if(i>0 && cur[i-1])union(set,i+m-1, i+m);
                    if(prev[i])union(set,i, i+m);
                }
            }
//            print(set);
            Arrays.fill(map, -1);
            for(int i = m; i< 2*m; i++)set[i] = find(set, i);
            for(int i = m; i< 2*m; i++)if(map[set[i]] == -1)map[set[i]] = i-m;
            for(int i = 0; i< m; i++){set[i] = map[set[i+m]];prev[i] = cur[i];}
//            print(set);pn("");
        }
        pn(ans);
    }
    void print(boolean[] b){
        for(boolean c:b)p((c)?1:0);pn("");
    }
    void print(int[] a){
        for(int i:a)p(i+" ");pn("");
    }
    int find(int[] set, int i){
        return set[i]==i?i:(set[i] = find(set,set[i]));
    }
    void union(int[] set, int x, int y){
        x = find(set,x);y=find(set,y);
        if(x==y)return;
        ans--;
        set[y] = x;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.DecimalFormat;

public class Main{
    final long mod = (int)1e9+7, IINF = (long)1e19;
    final int MAX = (int)1e4+1, MX = (int)1e7+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.0000000000000");
    double eps = 1e-9, pi = 3.141592653589793238462643383279502884197169399375105820974944;
    FastReader in;
    PrintWriter out;
    static boolean multipleTC = false, memory = false;

    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, t = (multipleTC)?ni():1; i<=t; i++)solve(i);
        out.flush();
        out.close();
    }

    int n, m;
    String[] str;
    StringBuilder[] vis;
    void solve(int TC)throws Exception{
        n = ni(); m = ni();
        str = new String[n];
        for(int i = 0; i< n; i++)str[i] = n();
        vis = new StringBuilder[n];
        for(int i = 0; i< n; i++){
            vis[i] = new StringBuilder();
            for(int j = 0; j< m; j++)vis[i].append('0');
        }
        int ans = 0;
        for(int i = 0; i< n; i++){
            for(int j = 0; j< m; j++){
                if(get(i,j) && !vis(i,j)){
                    dfs(i,j);
                    ans++;
                }
            }
        }
        pn(ans);
    }

    void print(){
        for(int i = 0; i< n; i++){
            for(int j = 0; j< m; j++)p((vis(i,j))?1:0);
            pn("");
        }
    }

    void dfs(int i, int j){
        if(i<0 || i>= n || j< 0 || j>=m || vis(i,j) || !get(i,j))return;
        mark(i,j);
        dfs(i+1,j);
        dfs(i-1,j);
        dfs(i,j-1);
        dfs(i,j+1);
    }

    boolean get(int i, int j){
        int v = val(str[i].charAt(j/4));
        return ((v>>(3-j%4))&1)==1;
    }

    void mark(int i, int j){
        char c = vis[i].charAt(j/4);
        int v = val(c);
        v |= 1<<(3-j%4);
        vis[i].setCharAt(j/4, cha(v));
    }

    boolean vis(int i, int j){
        char c = vis[i].charAt(j/4);
        int v = val(c);
        return ((v>>(3-j%4))&1)==1;
    }

    char cha(int v){
        if(v<=9)return (char)('0'+v);
        return (char)(v+'A'-10);
    }

    int val(char c){
        if(c>='0' && c<='9')return c-'0';
        else return c-'A'+10;
    }

    int[] reverse(int[] a){
        int[] o = new int[a.length];
        for(int i = 0; i< a.length; i++)o[i] = a[a.length-i-1];
        return o;
    }

    int[] sort(int[] a){
        if(a.length==1)return a;
        int mid = a.length/2;
        int[] b = sort(Arrays.copyOfRange(a,0,mid)), c = sort(Arrays.copyOfRange(a,mid,a.length));
        for(int i = 0, j = 0, k = 0; i< a.length; i++){
            if(j<b.length && k<c.length){
                if(b[j]<c[k])a[i] = b[j++];
                else a[i] = c[k++];
            }else if(j<b.length)a[i] = b[j++];
            else a[i] = c[k++];
        }
        return a;
    }

    long[] sort(long[] a){
        if(a.length==1)return a;
        int mid = a.length/2;
        long[] b = sort(Arrays.copyOfRange(a,0,mid)), c = sort(Arrays.copyOfRange(a,mid,a.length));
        for(int i = 0, j = 0, k = 0; i< a.length; i++){
            if(j<b.length && k<c.length){
                if(b[j]<c[k])a[i] = b[j++];
                else a[i] = c[k++];
            }else if(j<b.length)a[i] = b[j++];
            else a[i] = c[k++];
        }
        return a;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.DecimalFormat;

public class Main{
    final long mod = (int)1e9+7, IINF = (long)1e19;
    final int MAX = (int)1e4+1, MX = (int)1e7+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.0000000000000");
    double eps = 1e-9, pi = 3.141592653589793238462643383279502884197169399375105820974944;
    FastReader in;
    PrintWriter out;
    static boolean multipleTC = false, memory = false;

    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, t = (multipleTC)?ni():1; i<=t; i++)solve(i);
        out.flush();
        out.close();
    }

    int n, m;
    BitSet[] str, vis;

    void solve(int TC)throws Exception{
        n = ni(); m = ni();
        str = new BitSet[n];
        vis = new BitSet[n];
        for(int i = 0; i< n; i++){
            String s = n();
            str[i] = new BitSet(m);vis[i] = new BitSet(m);
            for(int j = 0; j< m/4; j++){
                int v = val(s.charAt(j));
                for(int k = 0; k< 4; k++){
                    if(((v>>(3-k))&1)==1)str[i].set(j*4+k);
                }
            }
        }
        int ans = 0;
        for(int i = 0; i< n; i++){
            for(int j = 0; j< m; j++){
                if(get(i,j) && !vis(i,j)){
                    dfs(i,j);
                    ans++;
                }
            }
        }
        pn(ans);
    }

    void print(){
        for(int i = 0; i< n; i++){
            for(int j = 0; j< m; j++)p((vis(i,j))?1:0);
            pn("");
        }
    }

    void dfs(int i, int j){
        if(i<0 || i>= n || j< 0 || j>=m || vis(i,j) || !get(i,j))return;
        mark(i,j);
        dfs(i+1,j);
        dfs(i-1,j);
        dfs(i,j-1);
        dfs(i,j+1);
    }

    boolean get(int i, int j){
        return str[i].get(j);
    }

    void mark(int i, int j){
        vis[i].set(j);
    }

    boolean vis(int i, int j){
        return vis[i].get(j);
    }

    char cha(int v){
        if(v<=9)return (char)('0'+v);
        return (char)(v+'A'-10);
    }

    byte val(char c){
        if(c>='0' && c<='9')return (byte)(c-'0');
        else return (byte)(c-'A'+10);
    }

    int[] reverse(int[] a){
        int[] o = new int[a.length];
        for(int i = 0; i< a.length; i++)o[i] = a[a.length-i-1];
        return o;
    }

    int[] sort(int[] a){
        if(a.length==1)return a;
        int mid = a.length/2;
        int[] b = sort(Arrays.copyOfRange(a,0,mid)), c = sort(Arrays.copyOfRange(a,mid,a.length));
        for(int i = 0, j = 0, k = 0; i< a.length; i++){
            if(j<b.length && k<c.length){
                if(b[j]<c[k])a[i] = b[j++];
                else a[i] = c[k++];
            }else if(j<b.length)a[i] = b[j++];
            else a[i] = c[k++];
        }
        return a;
    }

    long[] sort(long[] a){
        if(a.length==1)return a;
        int mid = a.length/2;
        long[] b = sort(Arrays.copyOfRange(a,0,mid)), c = sort(Arrays.copyOfRange(a,mid,a.length));
        for(int i = 0, j = 0, k = 0; i< a.length; i++){
            if(j<b.length && k<c.length){
                if(b[j]<c[k])a[i] = b[j++];
                else a[i] = c[k++];
            }else if(j<b.length)a[i] = b[j++];
            else a[i] = c[k++];
        }
        return a;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.*;

public class Main{
    long mod = (int)1e9+7, IINF = (long)1e17;
    final int MAX = (int)1e6+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.00000000");
    double PI = 3.141592653589793238462643383279502884197169399375105820974944;
    static boolean multipleTC = false, memory = false;
    FastReader in;PrintWriter out;
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, T= (multipleTC)?ni():1; i<= T; i++)solve(i);
        out.flush();
        out.close();
    }
    long ans = 0;
    void solve(int TC) throws Exception{
        int n = ni(), m=ni();
        int[] set = new int[m*2];HashMap<Integer, Integer> map = new HashMap<>();
        String s = n();
        boolean[] prev = new boolean[m], cur = new boolean[m];
        for(int i = 0; i< s.length(); i++){
            int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
            for(int j = 0; j< 4; j++){
                prev[i*4+j] = ((v>>(3-j))&1)==1;
                if(prev[i*4+j])ans++;
            }
        }
        for(int i = 0; i< m; i++)set[i] = i;
        for(int i = 1; i< m; i++)if(prev[i] && prev[i-1])union(set,i-1, i);
        for(int t = 1; t< n; t++){
            s = n();
            for(int i = 0; i< s.length(); i++){
                int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
                for(int j = 0; j< 4; j++){
                    cur[i*4+j] = ((v>>(3-j))&1)==1;
                    set[m+i*4+j] = m+i*4+j;
                    if(cur[i*4+j])ans++;
                }
            }
            for(int i = 0; i< m; i++)if(prev[i] && cur[i])union(set,i, i+m);
            for(int i = 1; i< m; i++)if(cur[i-1] && cur[i])union(set,i+m-1, i+m);
//            print(set);
            map.clear();
            for(int i = m; i< 2*m; i++)set[i] = find(set, i);
            for(int i = m; i< 2*m; i++)if(!map.containsKey(set[i]))map.put(set[i], i-m);
            for(int i = 0; i< m; i++)set[i] = map.get(set[i+m]);
//            print(set);pn("");
            for(int i = 0; i< m; i++)prev[i] = cur[i];
        }
        pn(ans);
    }
    void print(boolean[] b){
        for(boolean c:b)p((c)?1:0);pn("");
    }
    void print(int[] a){
        for(int i:a)p(i+" ");pn("");
    }
    int find(int[] set, int i){
        return set[i]==i?i:(set[i] = find(set,set[i]));
    }
    void union(int[] set, int x, int y){
        x = find(set,x);y=find(set,y);
        if(x==y)return;
        ans--;
        set[y] = x;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.*;

public class Main{
    long mod = (int)1e9+7, IINF = (long)1e17;
    final int MAX = (int)1e6+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.00000000");
    double PI = 3.141592653589793238462643383279502884197169399375105820974944;
    static boolean multipleTC = false, memory = false;
    FastReader in;PrintWriter out;
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, T= (multipleTC)?ni():1; i<= T; i++)solve(i);
        out.flush();
        out.close();
    }
    long ans = 0;

    void solve(int TC) throws Exception{
        int n = ni(), m=ni();
        int[] set = new int[m*2], map = new int[m*2];
        String s = n();
        boolean[] prev = new boolean[m], cur = new boolean[m];
        for(int i = 0; i< s.length(); i++){
            int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
            for(int j = 0; j< 4; j++){
                prev[i*4+j] = ((v>>(3-j))&1)==1;
                if(prev[i*4+j])ans++;
            }
        }
        for(int i = 0; i< m; i++)set[i] = i;
        for(int i = 1; i< m; i++)if(prev[i] && prev[i-1])union(set,i-1, i);
        for(int t = 1; t< n; t++){
            s = n();
            for(int i = 0; i< s.length(); i++){
                int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
                for(int j = 0; j< 4; j++){
                    cur[i*4+j] = ((v>>(3-j))&1)==1;
                    set[m+i*4+j] = m+i*4+j;
                    if(cur[i*4+j])ans++;
                }
            }
            for(int i = 0; i< m; i++)if(prev[i] && cur[i])union(set,i, i+m);
            for(int i = 1; i< m; i++)if(cur[i-1] && cur[i])union(set,i+m-1, i+m);
//            print(set);
            for(int i = 0; i< map.length; i++)map[i] = -1;
            for(int i = m; i< 2*m; i++)set[i] = find(set, i);
            for(int i = m; i< 2*m; i++)if(map[set[i]] == -1)map[i] = i-m;
            for(int i = 0; i< m; i++)set[i] = map[set[i+m]];
//            print(set);pn("");
            for(int i = 0; i< m; i++)prev[i] = cur[i];
        }
        pn(ans);
    }
    void print(boolean[] b){
        for(boolean c:b)p((c)?1:0);pn("");
    }
    void print(int[] a){
        for(int i:a)p(i+" ");pn("");
    }
    int find(int[] set, int i){
        return set[i]==i?i:(set[i] = find(set,set[i]));
    }
    void union(int[] set, int x, int y){
        x = find(set,x);y=find(set,y);
        if(x==y)return;
        ans--;
        set[y] = x;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.*;

public class Main{
    long mod = (int)1e9+7, IINF = (long)1e17;
    final int MAX = (int)1e6+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.00000000");
    double PI = 3.141592653589793238462643383279502884197169399375105820974944;
    static boolean multipleTC = false, memory = false;
    FastReader in;PrintWriter out;
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, T= (multipleTC)?ni():1; i<= T; i++)solve(i);
        out.flush();
        out.close();
    }
    int ans = 0;
    void solve(int TC) throws Exception{
        int n = ni(), m=ni();
        int[] set = new int[m*2];HashMap<Integer, Integer> map = new HashMap<>();
        String s = n();
        boolean[] prev = new boolean[m], cur = new boolean[m];
        for(int i = 0; i< s.length(); i++){
            int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
            for(int j = 0; j< 4; j++){
                prev[i*4+j] = ((v>>(3-j))&1)==1;
                if(prev[i*4+j])ans++;
            }
        }
        for(int i = 0; i< m; i++)set[i] = i;
        for(int i = 1; i< m; i++)if(prev[i] && prev[i-1])union(set,i-1, i);
        for(int t = 1; t< n; t++){
            s = n();
            for(int i = 0; i< s.length(); i++){
                int v = (Character.isLetter(s.charAt(i)))?(s.charAt(i)-'a'+10):(s.charAt(i)-'0');
                for(int j = 0; j< 4; j++){
                    cur[i*4+j] = ((v>>(3-j))&1)==1;
                    set[m+i*4+j] = m+i*4+j;
                    if(cur[i*4+j])ans++;
                }
            }
            for(int i = 0; i< m; i++)if(prev[i] && cur[i])union(set,i, i+m);
            for(int i = 1; i< m; i++)if(cur[i-1] && cur[i])union(set,i-1, i);
            int c = 0;
            map.clear();
            for(int i = m; i< 2*m; i++)if(!map.containsKey(set[i]))map.put(set[i], c++);
            for(int i = 0; i< m; i++)set[i] = map.get(set[i+m]);
            for(int i = 0; i< m; i++)prev[i] = cur[i];
        }
        pn(ans);
    }
    void print(boolean[] b){
        for(boolean c:b)p((c)?1:0);pn("");
    }
    int find(int[] set, int i){
        return set[i]==i?i:(set[i] = find(set,set[i]));
    }
    void union(int[] set, int x, int y){
        x = find(set,x);y=find(set,y);
        if(x==y)return;
        ans--;
        set[y] = x;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.util.*;
import java.io.*;
import java.text.DecimalFormat;

public class Main{
    final long mod = (int)1e9+7, IINF = (long)1e19;
    final int MAX = (int)1e4+1, MX = (int)1e7+1, INF = (int)1e9, root = 3;
    DecimalFormat df = new DecimalFormat("0.0000000000000");
    double eps = 1e-9, pi = 3.141592653589793238462643383279502884197169399375105820974944;
    FastReader in;
    PrintWriter out;
    static boolean multipleTC = false, memory = false;

    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }

    void run() throws Exception{
        in = new FastReader();
        out = new PrintWriter(System.out);
        for(int i = 1, t = (multipleTC)?ni():1; i<=t; i++)solve(i);
        out.flush();
        out.close();
    }

    int ans = 0;
    void solve(int TC)throws Exception{
        int n = ni(), m = ni();
        map = new int[2*m];
        boolean[] p = new boolean[m], c = new boolean[m];
        int[] set = new int[m*2];
        for(int i = 0; i< m; i++)set[i] = i;
        for(int i = 0; i< n; i++){
            String s = n();
            for(int j = 0; j< m/4; j++){
                int v = val(s.charAt(j));
                for(int k = 0; k< 4; k++){
                    c[j*4+k] = ((v>>(3-k%4))&1) == 1;
                    if(c[j*4+k])ans++;
                    set[m+j*4+k] = m+j*4+k;
                }
            }
            for(int j = 0; j< m; j++)if(p[j] && c[j])union(set,j,j+m);
            for(int j = 0; j< m-1; j++)if(c[j] && c[j+1])union(set,j+m, j+m+1);
            for(int j = 0; j< m; j++)set[j] = set[j+m];
            unique(set, m);
            for(int j = 0; j< m; j++)p[j] = c[j];
        }
        pn(ans);
    }
    int[] map;
    void unique(int[] set, int m){
        for(int i = 0; i< 2*m; i++)map[i] = -1;
        int c = 0;
        for(int i = 0; i< m; i++){
            if(map[set[i]]==-1)map[set[i]] = c++;
        }
        for(int i = 0; i< m; i++)set[i] = map[set[i]];
    }

    int find(int[] set, int i){
        if(set[i]!=i)set[i] = find(set, set[i]);
        return set[i];
    }

    void union(int[] set, int i, int j){
        i = find(set,i);j = find(set,j);
        if(i==j)return;
        set[j] = i;
        ans--;
    }

    int val(char c){
        if(c>='0' && c<='9')return (c-'0');
        return (c-'A'+10);
    }

    int[] reverse(int[] a){
        int[] o = new int[a.length];
        for(int i = 0; i< a.length; i++)o[i] = a[a.length-i-1];
        return o;
    }

    int[] sort(int[] a){
        if(a.length==1)return a;
        int mid = a.length/2;
        int[] b = sort(Arrays.copyOfRange(a,0,mid)), c = sort(Arrays.copyOfRange(a,mid,a.length));
        for(int i = 0, j = 0, k = 0; i< a.length; i++){
            if(j<b.length && k<c.length){
                if(b[j]<c[k])a[i] = b[j++];
                else a[i] = c[k++];
            }else if(j<b.length)a[i] = b[j++];
            else a[i] = c[k++];
        }
        return a;
    }

    long[] sort(long[] a){
        if(a.length==1)return a;
        int mid = a.length/2;
        long[] b = sort(Arrays.copyOfRange(a,0,mid)), c = sort(Arrays.copyOfRange(a,mid,a.length));
        for(int i = 0, j = 0, k = 0; i< a.length; i++){
            if(j<b.length && k<c.length){
                if(b[j]<c[k])a[i] = b[j++];
                else a[i] = c[k++];
            }else if(j<b.length)a[i] = b[j++];
            else a[i] = c[k++];
        }
        return a;
    }

    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bitcount(long n){return (n==0)?0:(1+bitcount(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n(){return in.next();}
    String nln(){return in.nextLine();}
    int ni(){return Integer.parseInt(in.next());}
    long nl(){return Long.parseLong(in.next());}
    double nd(){return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next(){
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        String nextLine(){
            String str = "";
            try{
                str = br.readLine();
            }catch (IOException e){
                e.printStackTrace();
            }
            return str;
        }
    }
}


//package educational.round31;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

// 0516
public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		int[] clus = new int[m];
		Arrays.fill(clus, -1);
		int[] row = new int[m];
		long ans = 0;
		int[] loc = new int[2*m];
		DJSet ds = new DJSet(2*m);
		for(int i = 0;i < n;i++){
			ds.clear();
			char[] line = ns(m/4);
			for(int j = 0;j < m;j++){
				int v = line[j/4] <= '9' ? line[j/4]-'0' : line[j/4]-'A'+10;
				row[j] = v<<~(3-(j&3))<0 ? j : -1;
				if(row[j] >= 0)ans++;
			}
			for(int j = 0;j < m;j++){
				if(row[j] >= 0 && clus[j] >= 0){
					if(!ds.union(row[j], clus[j])){
						ans--;
					}
				}
				if(j > 0 && row[j-1] >= 0 && row[j] >= 0){
					if(!ds.union(row[j-1], row[j])){
						ans--;
					}
				}
			}
			int p = 0;
			for(int j = 0;j < 2*m;j++){
				if(ds.upper[j] < 0){
					loc[j] = p++;
				}
			}
			for(int j = 0;j < m;j++){
				clus[j] = row[j] == -1 ? -1 : loc[ds.root(row[j])] + m;
			}
		}
		out.println(ans);
	}

	public static class DJSet {
		public int[] upper;

		public DJSet(int n) {
			upper = new int[n];
			Arrays.fill(upper, -1);
		}

		public void clear()
		{
			Arrays.fill(upper, -1);
		}

		public int root(int x) {
			return upper[x] < 0 ? x : (upper[x] = root(upper[x]));
		}

		public boolean equiv(int x, int y) {
			return root(x) == root(y);
		}

		public boolean union(int x, int y) {
			x = root(x);
			y = root(y);
			if (x != y) {
				if (upper[y] < upper[x]) {
					int d = x;
					x = y;
					y = d;
				}
				upper[x] += upper[y];
				upper[y] = x;
			}
			return x == y;
		}

		public int count() {
			int ct = 0;
			for (int u : upper)
				if (u < 0)
					ct++;
			return ct;
		}
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package educational.round31;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

// 0516
public class E2 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		int[] clus = new int[m];
		Arrays.fill(clus, -1);
		boolean[] row = new boolean[m];
		long ans = 0;
		int[] loc = new int[2*m];
		DJSet ds = new DJSet(2*m);
		for(int i = 0;i < n;i++){
			ds.clear();
			char[] line = ns(m/4);
			for(int j = 0;j < m;j++){
				int v = line[j/4] <= '9' ? line[j/4]-'0' : line[j/4]-'A'+10;
				row[j] = v<<~(3-(j&3))<0;
				if(row[j])ans++;
			}
			for(int j = 0;j < m;j++){
				if(row[j] && clus[j] >= 0){
					if(!ds.union(j, clus[j])){
						ans--;
					}
				}
				if(j > 0 && row[j-1] && row[j]){
					if(!ds.union(j-1, j)){
						ans--;
					}
				}
			}
			int p = 0;
			for(int j = 0;j < 2*m;j++){
				if(ds.upper[j] < 0){
					loc[j] = p++;
				}
			}
			for(int j = 0;j < m;j++){
				clus[j] = !row[j] ? -1 : loc[ds.root(j)] + m;
			}
		}
		out.println(ans);
	}

	public static class DJSet {
		public int[] upper;

		public DJSet(int n) {
			upper = new int[n];
			Arrays.fill(upper, -1);
		}

		public void clear()
		{
			Arrays.fill(upper, -1);
		}

		public int root(int x) {
			return upper[x] < 0 ? x : (upper[x] = root(upper[x]));
		}

		public boolean equiv(int x, int y) {
			return root(x) == root(y);
		}

		public boolean union(int x, int y) {
			x = root(x);
			y = root(y);
			if (x != y) {
				if (upper[y] < upper[x]) {
					int d = x;
					x = y;
					y = d;
				}
				upper[x] += upper[y];
				upper[y] = x;
			}
			return x == y;
		}

		public int count() {
			int ct = 0;
			for (int u : upper)
				if (u < 0)
					ct++;
			return ct;
		}
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E2().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}