3 unique solutions
Using Tree DP\n# Code\ncpp []\nclass Solution {\npublic:\n    void dfs1(TreeNode* root,unordered_map<int,int>&maxdepth)\n    {\n        if(root->right==NULL && 
# Using Tree DP\n# Code\n```cpp []\nclass Solution {\npublic:\n    void dfs1(TreeNode* root,unordered_map<int,int>&maxdepth)\n    {\n        if(root->right==NULL && root->left==NULL)\n        {\n            maxdepth[root->val]=1;\n            return;\n        }\n        if(root->left!=NULL)\n        {\n            dfs1(root->left,maxdepth);\n            maxdepth[root->val]=max(maxdepth[root->val],1+maxdepth[root->left->val]);\n        }\n        if(root->right!=NULL)\n        {\n            dfs1(root->right,maxdepth);\n            maxdepth[root->val]=max(maxdepth[root->val],1+maxdepth[root->right->val]);\n        }\n        return;\n    }\n    void dfs2(TreeNode* root,unordered_map<int,int>&maxdepth,int maxoutdepth,int depth,unordered_map<int,int>&ans)\n    {\n        ans[root->val]=max(maxoutdepth,depth-1);\n        if(root->left!=NULL)\n        {\n            if(root->right!=NULL)\n            {\n                dfs2(root->left,maxdepth,max(maxoutdepth,depth+maxdepth[root->right->val]),depth+1,ans);\n            }\n            else\n            {\n                dfs2(root->left,maxdepth,maxoutdepth,depth+1,ans);   \n            }\n        }\n        if(root->right!=NULL)\n        {\n            if(root->left!=NULL)\n            {\n                dfs2(root->right,maxdepth,max(maxoutdepth,depth+maxdepth[root->left->val]),depth+1,ans);\n            }\n            else\n            {\n                dfs2(root->right,maxdepth,maxoutdepth,depth+1,ans);   \n            }\n        }\n        return;\n    }\n    vector<int> treeQueries(TreeNode* root,vector<int>&queries) \n    {\n        // Tree DP\n        vector<int>anstoquery;\n        unordered_map<int,int>querynum,maxdepth,ans;\n        dfs1(root,maxdepth);\n        dfs2(root,maxdepth,0,0,ans);\n        for(auto j:queries)\n        {\n            anstoquery.push_back(ans[j]);\n        }\n        return anstoquery;\n    }\n};\n```\n\n# Using Timer Approach\n# Code\n```cpp []\nclass Solution {\npublic:\n    // Timer Approach + PrefixSuffix Max\n    void assigntime(int& timer,int level,unordered_map<int,int>&in,unordered_map<int,int>&out,unordered_map<int,int>&depth,TreeNode* root)\n    {\n        if(root==NULL)\n        {\n            return;\n        }\n        in[root->val]=timer;\n        depth[timer]=level;\n        timer++;\n        assigntime(timer,level+1,in,out,depth,root->left);\n        assigntime(timer,level+1,in,out,depth,root->right);\n        out[root->val]=timer;\n        return;\n    }\n    vector<int> treeQueries(TreeNode* root, vector<int>& queries) \n    {\n        unordered_map<int,int>in,out,depth;\n        int timer=0,level=0;\n        assigntime(timer,level,in,out,depth,root);\n        vector<int>prefmax(timer),suffmax(timer);\n        for(int i=0;i<timer;i++)\n        {\n            prefmax[i]=depth[i];\n            if(i)\n            {\n                prefmax[i]=max(prefmax[i],prefmax[i-1]);\n            }\n        }\n        for(int i=timer-1;i>=0;i--)\n        {\n            suffmax[i]=depth[i];\n            if(i<(timer-1))\n            {\n                suffmax[i]=max(suffmax[i],suffmax[i+1]);\n            }\n        }\n        vector<int>ans;\n        for(auto j:queries)\n        {\n            int x=INT_MIN;\n            if((in[j]-1)>=0)\n            {\n                x=prefmax[in[j]-1];\n            }\n            if(out[j]<timer)\n            {\n                x=max(x,suffmax[out[j]]);\n            }\n            ans.push_back(x);\n        }\n        return ans;\n    }\n};\n```\n\n# Using Max 2 down-depths at a level\n# Code\n```cpp []\nclass Solution {\npublic:\n    // Consider at any level max two depths available\n    void dfs(TreeNode* root,int level,map<int,int>&depth,map<int,int>&downdepth,map<int,vector<int>>&maxdepths)\n    {\n        depth[root->val]=level;\n        if(root->left!=NULL)\n        {\n            dfs(root->left,level+1,depth,downdepth,maxdepths);\n            downdepth[root->val]=max(downdepth[root->val],1+downdepth[root->left->val]);\n        }\n        if(root->right!=NULL)\n        {\n            dfs(root->right,level+1,depth,downdepth,maxdepths);\n            downdepth[root->val]=max(downdepth[root->val],1+downdepth[root->right->val]);\n        }\n        if(maxdepths[level].size()<2)\n        {\n            maxdepths[level].push_back(downdepth[root->val]);\n            if(maxdepths[level].size()==2)\n            {\n                if(maxdepths[level][0]>maxdepths[level][1])\n                {\n                    swap(maxdepths[level][0],maxdepths[level][1]);\n                }\n            }\n        }\n        else\n        {\n            if(maxdepths[level][0]<downdepth[root->val])\n            {\n                maxdepths[level][0]=downdepth[root->val];\n                if(maxdepths[level][0]>maxdepths[level][1])\n                {\n                    swap(maxdepths[level][0],maxdepths[level][1]);\n                }\n            }\n        }\n        return;\n    }\n    vector<int> treeQueries(TreeNode* root, vector<int>& queries) {\n        map<int,int>depth,downdepth;\n        map<int,vector<int>>maxdepths;\n        dfs(root,0,depth,downdepth,maxdepths);\n        vector<int>ans;\n        for(auto j:queries)\n        {\n            if(maxdepths[depth[j]].size()==2 && maxdepths[depth[j]][1]==downdepth[j])\n            {\n                ans.push_back(depth[j]+maxdepths[depth[j]][0]);\n            }\n            else\n            {\n                if(maxdepths[depth[j]].size()==1)\n                {\n                    ans.push_back(depth[j]-1);\n                }\n                else\n                {\n                    ans.push_back(depth[j]+maxdepths[depth[j]][1]);\n                }\n            }\n        }\n        return ans;\n    }\n};\n```
['C++']