Go: package main

import (
	"bufio"
	"fmt"
	"math/big"
	"os"
	"strconv"
)

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

func main() {
	scanner.Split(bufio.ScanWords)

	const maxCapacity = 512 * 1024
	buf := make([]byte, maxCapacity)
	scanner.Buffer(buf, maxCapacity)

	n := nextInt()
	maxint, _ := new(big.Int).SetString("100000000000000000000000000000000000000000000000000000000000000000000000000000000", 10)

	for i := 0; i < n; i++ {
		aStr := nextString()
		bStr := nextString()

		a, _ := new(big.Int).SetString(aStr, 10)
		b, _ := new(big.Int).SetString(bStr, 10)
		c := big.NewInt(0).Add(a, b)

		if c.Cmp(maxint) < 0 {
			fmt.Println(c)
		} else {
			fmt.Println("overflow")
		}
	}
}

C++: #include<iostream>

using namespace std;

#define DATA_MAX 100

int get_length( char str[] );
void initialize_str( char str[] , int size_of_str );
int myatoi( char s );
char myitoa( int s );


int main(void)
{
	char a[DATA_MAX];
	char b[DATA_MAX];
	char ans[DATA_MAX];

	int n;

	cin >> n;

	int size_of_str_a = sizeof(a)/sizeof(a[0]);
	int size_of_str_b = sizeof(b)/sizeof(b[0]);
	int size_of_str_ans = sizeof(ans)/sizeof(ans[0]);

	for( int i = 0 ; i < n ; i++ )
	{
		initialize_str(a , size_of_str_a);
		initialize_str(b , size_of_str_b);
		initialize_str(ans , size_of_str_ans);

		cin >> a >> b;
		int length_a = get_length( a );
		int length_b = get_length( b );
		if( length_a >= 81 || length_b >= 81 ){
			cout << "overflow" << endl;
			continue;
		}
		if( length_a > length_b ){
			while(1){
				for( int j = length_a ; j > 0 ; j-- )
				{
					b[j] = b[j-1];
				}
				b[0] = '0';
				if( b[length_a] == '\0' ) break;
			}
		}
		if( length_b > length_a ){
			while(1){
				for( int j = length_b ; j > 0 ; j-- )
				{
					a[j] = a[j-1];
				}
				a[0] = '0';
				if( a[length_b] == '\0' ) break;
			}
		}
		int length_ans = ( length_a > length_b ? length_a : length_b ) + 1;

		ans[length_ans] = '\0';
		int c[2] = {0};

		for( int j = length_ans-1 ; j >= 1 ; j-- )
		{
			int add = myatoi(a[j-1]) + myatoi(b[j-1]) + c[1];
			c[0] = add%10;
			ans[j] = myitoa(c[0]);
			c[1] = add/10;
		}
		ans[0] = myitoa(c[1]);
		
		if( ans[0] == '0' ){
			for( int i = 0 ; i <= length_ans - 1 ; i++ )
			{
				ans[i] = ans[i+1];
			}
		}
		if( get_length(ans) >= 81 ){
			cout << "overflow" << endl;
		}
		else{
			cout << ans << endl;
		}
	}
}

int get_length( char str[] )
{
	int i;

	for( i = 0 ; str[i] != '\0' ; i++ )
	{
		;
	}

	return i;
}

void initialize_str( char str[] , int size_of_str )
{
	for( int i = 0 ; i < size_of_str ; i++ )
	{
		str[i] = '0';
	}

	return;
}

int myatoi( char s )
{
	return s-48;
}
char myitoa( int s )
{
	return s+48;
}

C++:     #include <iostream>
    #include <vector>
    #include <string>
    #include <sstream>
     
    class BigInteger {
    	// use 18 digit a element
    	std::vector<uint64_t> splited_num_;
    public:
    	BigInteger(std::string str) {
    		set_data(str);
    	}
    	BigInteger(std::vector<uint64_t>&& splited_num) {
    		splited_num_ = std::move(splited_num);
    	}
    	BigInteger operator+(const BigInteger& rhs) {
    		return BigInteger(plus(splited_num_, rhs.get_data()));
    	}
    	std::vector<uint64_t> get_data() const {return splited_num_;}
    	std::string to_string() const {
    		std::string ret;
    		const int size = splited_num_.size();
    		for (int i = 0; i < size; ++i) {
    			const int& n = splited_num_[size - i - 1];
    			ret += n == 0 ? "000000000000000000" : std::to_string(n);
    		}
    		return ret;
    	}
    private:
    	void set_data(const std::string& str) {
    		std::string sub;
    		int length = str.length();
    		while (length >= 18) {
    			int pos = length - 18;
    			sub = str.substr(pos, 18);
    			splited_num_.push_back(to_uint64(sub));
    			length -= 18;
    		}
    		if (length > 0) {
    			sub = str.substr(0, length);
    			splited_num_.push_back(to_uint64(sub));
    		}
		}
    	std::vector<uint64_t> plus(std::vector<uint64_t> lhs,
    						       std::vector<uint64_t> rhs) const {
    		std::vector<uint64_t> ret;
     		uint64_t carry = 0;
     		
     		const int max = std::max(lhs.size(), rhs.size());
     		const int min = std::min(lhs.size(), rhs.size());
     		// ensure that lhs.sizs() is larger than rhs.size()
     		if (lhs.size() < rhs.size()) {
     			std::swap(lhs, rhs);
     		}
     		// fit container size
     		for (int i = 0; i < (max - min); ++i) {
     			rhs.push_back(0);
     		}
     		
     		for (int i = 0; i < max; ++i) {
     			uint64_t sum = lhs.at(i) + rhs.at(i) + carry;
     			std::cout << lhs.at(i) << " " << rhs.at(i) << " " << carry << " " << sum << std::endl;
     			carry = sum / 1000000000000000000;
     			sum = sum % 1000000000000000000;
     			ret.push_back(sum);
     		}
     		if (carry > 0) {
     			ret.push_back(carry);
     		}
     		return ret;
    	}
    	uint64_t to_uint64(const std::string& str) const {
    		std::istringstream iss(str);
    		uint64_t ret = 0;
    		iss >> ret;
    		return ret;
    	}
    };
     
    int main() {
    	std::vector<BigInteger> ans_list;
    	int n;
    	std::cin >> n;
    	for (int i = 0; i < n; ++i) {
    		std::string str1, str2;
    		std::cin >> str1;
    		std::cin >> str2;
    		BigInteger bi1(str1);
    		BigInteger bi2(str2);
    		ans_list.push_back(bi1 + bi2);
    	}
    	
    	for (auto ans : ans_list) {
    		std::cout << ans.to_string() << std::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<string, ll> PS;
typedef vector<ll> V;

int k = 0, n;
string s, t;
vector<string> ans;

int main(){
	cin >> n;
	REP(j,n){
		cin >> s >> t;
		k = 0;
		if (s.size() >= 80 || t.size() >= 80){
			cout << "overflow" << endl;
			continue;
		}
		reverse(ALL(s));
		reverse(ALL(t));
		int a = max(s.size(), t.size()), b = min(s.size(), t.size());
		if (s.size() > t.size()){
			REP(i, a - b){
				t += "0";
			}
		}
		else{
			REP(i, a - b){
				s += "0";
			}
		}		
		reverse(ALL(s));
		reverse(ALL(t));
		REP(i, s.size()){
			int x = (s[s.size()-1-i] - '0') + (t[s.size()-1-i] - '0');
			string q;
			stringstream ss;
			if (i != s.size() - 1){
				ss << ((x + k) % 10);
			}
			else{
				ss << x + k;
			}
			ss >> q;
			ans.push_back(q);
			if (x + k >= 10){
				k = (x + k) / 10;
			}
			else{
				k = 0;
			}
		}
		if (ans.size() >= 79){
			cout << "overflow" << endl;
			continue;
		}
		//cout << ans.size() << endl;
		reverse(ALL(ans));
		REP(i, ans.size()){
			cout << ans[i];
		}
		cout << endl;
		ans.clear();
	}
}

/*int a[110], b[110], ans[110];
string s, t;
int n;

int main(){
	cin >> n;
	while (n--){
		cin >> s >> t;
		if (s.size() > 80 || t.size() > 80)continue;
		REP(i, s.size())a[i] = s[s.size() - 1 - i] - '0';
		REP(i, t.size())b[i] = t[t.size() - 1 - i] - '0';
		ll k = 0;
		REP(i, 101){
			ans[i] = (a[i] + b[i] + k) % 10;
			k = (a[i] + b[i] + k) / 10;
		}
		for (int i = max(s.size(), t.size()); i >= 0; i--){
			if (i == max(s.size(), t.size())){
				if (ans[i] != 0){
					cout << ans[i];
				}
			}
			else{
				cout << ans[i];
			}
		}
		cout << endl;
		REP(i, 101){
			ans[i] = 0;
			a[i] = 0;
			b[i] = 0;
		}
	}
}*/