Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	table := [6][5]string{
		{"a", "b", "c", "d", "e"},
		{"f", "g", "h", "i", "j"},
		{"k", "l", "m", "n", "o"},
		{"p", "q", "r", "s", "t"},
		{"u", "v", "w", "x", "y"},
		{"z", ".", "?", "!", " "},
	}
	for scanner.Scan() {
		input := strings.Split(scanner.Text(), "")
		if len(input)%2 != 0 {
			fmt.Println("NA")
			continue
		}
		ret := make([]string, 0)
		for i := 0; i < len(input); i += 2 {
			row, _ := strconv.Atoi(input[i])
			col, _ := strconv.Atoi(input[i+1])
			ret = append(ret, table[row-1][col-1])
		}
		fmt.Println(strings.Join(ret, ""))
	}
}

C++: #include <iostream>

using namespace std;

char table[6][5] = {

{'a','b','c','d','e'},
{'f','g','h','i','j'},
{'k','l','m','n','o'},
{'p','q','r','s','t'},
{'u','v','w','x','y'},
{'z','.','?','!',' '}
};
int temp[2];

int main() {

    string mes;

    while (cin>>mes) {

        if (mes.length()%2!=0) cout << "NA" << endl;

        else {

            string temp="", res="";

            bool flag=false;
            for (int i=0; i<mes.length(); i++) {

                if (i%2!=0) {

                    temp[1] = mes[i] - '0';

                    if (temp[0]<1||temp[1]<1||temp[0]>6||temp[1]>6) {
                        flag = true;
                        break;
                    } else {
                        res += table[temp[0]-1][temp[1]-1];
                    }

                } else temp[0] = mes[i] - '0';

            }
            if (flag) cout << "NA" << endl;

            else cout << res << endl;

        }

    }

}

C++: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <numeric>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#include <sstream>
#include <complex>

using namespace std;

#define FOR(i,a,b) for(long long i=(a);i<(b);i++)
#define REP(i,N) for(long long i=0;i<(N);i++)
#define ALL(s) (s).begin(),(s).end()
#define fi first
#define se second

#define PI acos(-1.0)
#define INF 1000000007

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<double, double> PD;
typedef pair<string, ll> PS;
typedef vector<ll> V;

string ans, s;
string table[] = { "@@@@@@@", "@afkpuz", "@bglqv.",
"@chmrw?", "@dinsx!", "@ejoty " };

int main(){
	while (cin >> s){
		bool f = 0;
		ans = "";
		if (s.size() % 2 != 0){
			cout << "NA" << endl;
			continue;
		}
		if (s.size() == 0)cout << "NA" << endl;
		for (int i = 0; i < s.size(); i += 2){
			if (s[i]>'6' || s[i]<'0' || s[i + 1]>'6' || s[i] < '0')f = 1;
			ans += table[s[i + 1] - '0'][s[i] - '0'];
		}
		if (f)cout << "NA" << endl;
		else cout << ans << endl;
		ans.clear();
	}
}

C++: #include <iostream>

#include <vector>

#include <algorithm>

#include <sstream>

#include <string>

#include <cmath>

#include <list>

#include <set>
#include <cstdlib>
using namespace std;

int in() {int x; cin >> x; return x;}

template <typename T> class SegTree

{

public:

	int n;

	T T_max;

	vector<T> dat;

	SegTree(int n_, T t_max)

	{

		int n = 1;

		T_max = t_max;

		while (n < n_)n *= 2;

		for (int i = 0; i < 2 * n - 1; i++)dat.push_back(t_max);

	}

	void update(int k, T a)

	{

		k += n - 1;

		dat[k] = a;

		while (k > 0)

		{

			k = (k - 1) / 2;

			dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);

		}

	}



	//[a,b)

	T query(int a, int b)

	{

		return _query(a, b, 0, 0, n);

	}



private:

	T _query(int a, int b, int k, int l, int r)

	{

		if (r <= a || b <= l)return T_max;

		if (a <= l && r <= b)return dat[k];

		else

		{

			T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2);

			T vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);

			return min(vr, vl);

		}

	}

};

int main()
{
	string a = " abcdefghijklmnopqrstuvwxyz.?! ";
	string b;
	while (cin >> b)
	{
		string ans;
		if (b.size() % 2)
		{
			cout << "NA" << endl;
			continue;
		}
		for (int i = 0; i < b.size(); i += 2)
		{
			int A = b[i] - '0';
			int B = b[i + 1] - '0';
			if (A >= 7)
			{
				ans = "NA";
				break;
			}
			if (B >= 6)
			{
				ans = "NA";
				break;
			}
			A--;
			int C = A * 5 + B;
			if (C > 30)
			{
				ans = "NA";
				break;
			}
			ans += a[C];
		}
		cout << ans << endl;
	}
}

C++: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cassert>
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<utility>
#include<numeric>
#include<algorithm>
#include<bitset>
#include<complex>

using namespace std;

typedef long long Int;
typedef vector<int> vint;
typedef pair<int,int> pint;
#define mp make_pair

template<class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cout << *i << " "; cout << endl; }
template<class T> void chmin(T &t, T f) { if (t > f) t = f; }
template<class T> void chmax(T &t, T f) { if (t < f) t = f; }
int in() { int x; scanf("%d", &x); return x; }

int main() {
	string str;
	while(getline(cin,str)){
		string res="";
		int i;
		if(str.size()%2==0){
			cout<<"NA"<<endl;
			continue;
		}
		for(i=0;i<str.size()-2;i+=2){
			if(str[i]<'1'||'6'<str[i]||str[i+1]<'1'||'5'<str[i+1]){
				cout<<"NA"<<endl;
				goto a;
			}
			if(str[i]!='6'){
				res+='a'+(str[i]-'1')*5+str[i+1]-'1';
			}else{
				switch(str[i+1]){
				case '1':
					res+="z";
					break;
				case '2':
					res+=".";
					break;
				case '3':
					res+="?";
					break;
				case '4':
					res+="!";
					break;
				case '5':
					res+=" ";
					break;
				}
			}
		}
		cout<<res<<endl;
		a:;
	}
	return 0;
}

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

char table[6][5] = {
    {'a', 'b', 'c', 'd', 'e'},
    {'f', 'g', 'h', 'i', 'j'},
    {'k', 'l', 'm', 'n', 'o'},
    {'p', 'q', 'r', 's', 't'},
    {'u', 'v', 'w', 'x', 'y'},
    {'z', '.', '?', '!', ' '},
};



int main(){
    string str;
    bool na;
    string result;

    while(cin >> str){
        result = "";
        na = false;
        if(str.size() % 2){
            na = true;
        }else{
            for(int i=0; i<str.size(); i+=2){
                int col = str.at(i) - '0' - 1;
                int row = str.at(i+1) - '0' - 1;
                if(col < 0 || col >= 6 || row < 0 || row >= 5){
                    na = true;
                }else{
                    result += table[col][row];
                }
            }
        }
        if(na == true){
            cout << "NA" <<endl;
        }else{
            cout << result << endl;
        }
    }


    return 0;
}

C++: #include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < j; ++i)
#define FOR(i, j, k) for(int i = j; i < k; ++i)
#define P pair<int, int>

map<string, char> m;

void set_m(){
  m["11"] = 'a';
  m["12"] = 'b';
  m["13"] = 'c';
  m["14"] = 'd';
  m["15"] = 'e';
  m["21"] = 'f';
  m["22"] = 'g';
  m["23"] = 'h';
  m["24"] = 'i';
  m["25"] = 'j';
  m["31"] = 'k';
  m["32"] = 'l';
  m["33"] = 'm';
  m["34"] = 'n';
  m["35"] = 'o';
  m["41"] = 'p';
  m["42"] = 'q';
  m["43"] = 'r';
  m["44"] = 's';
  m["45"] = 't';
  m["51"] = 'u';
  m["52"] = 'v';
  m["53"] = 'w';
  m["54"] = 'x';
  m["55"] = 'y';
  m["61"] = 'z';
  m["62"] = '.';
  m["63"] = '?';
  m["64"] = '!';
  m["65"] = ' ';
}

bool has_key(string s){
  return ((m.find(s) == m.end()) ? false : true);
}

int main() {
  set_m();
  string str;
  while(cin >>str){
    string ans = "";
    if(str.length() % 2 != 0) ans = "NA";
    for(int i = 0; ans != "NA" && i < str.size(); i += 2){
      string now = str.substr(i, 2);
      if(!has_key(now)) ans = "NA";
      else ans += m[now];
    }
    cout <<ans <<endl;
  }
  return 0;
}